What's best way to clone a GIT project into a Web application with existing and non-GIT files? - wordpress

Want to cut to the chase? Jump down to QUESTIONS below. Cheers.
BACKGROUND
I am changing my web development workflow to include GIT for version
control. GIT is new to me, although I have a technical background, so
it's not a complete mystery. :-)
I have a GIT repository on Bitbucket (BB), which I use as the central project container.
I use my local web server (on Mac OS X) for development.
That's my dev server.
Once tested locally, I push changes from my dev server to Bitbucket.
I have two remote servers. One is a staging server, the other is the production/live server.
I've learnt (sufficiently, for now) how to manage the files between dev and Bitbucket. I have everything set up to run over password-less SSH (using rsa keys).
THE ISSUE
I am not sure what the proper or recommended way is to manage the workflow between BitBucket (or whatever system one uses) and the staging server, and production server.
Here's an example:
I am working on a site with the following structure (in part): (those with ++ around them are the folders I with files I must track/manage in GIT)
- www_root/images/...
www_root/etc/...
www_root/extras/themes/...
www_root/extras/plugins/...
++ www_root/extras/plugins/my-plugin-1 ++
++ www_root/extras/plugins/my-plugin-2 ++
++ www_root/extras/themes/my-theme-1 ++
www_root/extras/theme/someothertheme
The approach I took on my dev server (localhost) was to have a repository for the entire www_root/, and a gitignore that excludes everything except those folders with the ++ next to them (in the above example), AND their parents. So in this case, the ../plugins/.. and ../themes/.. folders are both included in full.
When it comes time to set up the staging server, this is where I came unstuck. What I did was install the application on there (WordPress, in my present case). But then I can't add the GIT project, because I run into the issue that git init aborts due to the folder not being empty.
As mentioned, on my local server I'd set up the site root as the root of my project, and with gitignore all files except the various folders I am working in, are excluded.
WHAT I TRIED
I attempted setting up a project.git folder above the web_root, and then adding a work-tree for the /extras/ folder in the web root. I ran into issues. Could not git init (non-empty folders issue) and could not git pull, git fetch, etc.
I also attempted creating a GIT project within the www_root, and with the worktree being the /extras/ folder, but again, struck the non-empty folder issue.
QUESTIONS
1) Is there a way I can incorporate a GIT project, and pull down the files from Bitbucket/Github, into a an existing folder structure (such as would exist in any situation where one is developing components of a larger application, with its broader folder structure)?
2) OR, is it necessary to either have a completely empty /wp-content/themes/ (in my example) folder on the staging and production server, and manage the entire content through GIT, and then GIT INIT and GIT CLONE into that folder, and then have a separate project for /wp-content/plugins/ where all content of that folder is handled through GIT, etc., and do the same for that?
3) OR, is the best approach to have separate projects for each sub-folder? Hypothetically, www_root/extras/themes/my-theme-1 and, let's say, www_root/extras/themes/my-theme-2, and perhaps www_root/extras/plugins/my-plugin-1
4) Or have I completely overlooked another way of going about this?

If this is an option, can you create a new folder, create a GIT repo in it and then move files into the repo?
Then the usual - in case of fire:
git commit
git push
leave the building

Related

How to update WordPress + Plugins in Elastic Beanstalk

There are many wonderful tutorials describing in great detail how to set up a horizontally scaled WordPress install in AWS' Elastic Beanstalk - that part is no problem. But I haven't found any follow-up advice yet on how to manage plugin updates after the initial setup, let alone updating wordpress-core itself. Does anybody know the most optimal way to do this?
This is the methodology I'm using so far, but I'm not sure if it is the best way:
Download the plugin's update file and unzip it. Remove and replace the relevant folder in /wp-content/plugins (local git repo)
Run the update in the live site like normal - to ensure that any database changes get pushed up to the RDS
eb deploy from the local repo to commit the file changes and make the update persistent
Is that a sane method? Could anything get corrupted down the line?
For updating wp-core, the tutorials I've read seem overcomplicated - basically rebuild the site from scratch every time an update comes out. Below is what I have been using (used it successfully for WP 5.0.2). Is there any chance of files and databases getting out of sync using this method?
Download and unzip the new wordpress version locally
Replace wp-admin, wp-includes, and the root files except for wp-config.php (local git repo)
Run the update in the live environment, so that any database changes get pushed up to RDS.
eb deploy
I've been running with the above methods for a while and feel pretty confident that they are sound. I only have a couple of tweaks thus far.
The following assumes an environment where there is one staging server outside of the horizontally scaling live environment. This could be further improved for a multi-developer environment using AWS Code Commit.
For Plugins:
Run the plugin update normally on the staging server (in wp-admin). Test everything to make sure the update is sound.
Remove the plugin's old folder from your local git repo and download the updated folder from the staging server using SFTP.
In the local repo, run git add -A && git commit -m "updated Plugin Name" && eb deploy
Run the same update in Live (in wp-admin). It will only apply to one server, but should guarantee that any database changes get pushed up to the single RDS.
Roll out the change to the live environment using the Software Versions page in the AWS Console (in Elastic Beanstalk)
Updating WP Core is almost identical except that instead of removing and replacing a single plugin directory, you will need to remove and replace /wp-admin/, /wp-includes/ and all of the files in the root folder except for wp-config.php

Use Git in SSH to pull specific directories

Total newbie question but what is the best practice when it comes to using SSH with Git? I'm working on a WordPress project. In the root I have gulp and other dev files/folders like SASS and Scripts that I don't need on the server and in the same project I have my WordPress folder that contains a theme and a few custom plugins. As you can imagine when the theme or any of the plugins are ready to be deployed I don't want to pull everything in my repository on the server. So far as a newbie I've always just pull and pushed the entire repository and used FTP to upload what I need to the server, so how is this done with SSH and Git and is there a better way to have my setup?
EDIT: To make my question a little bit more clear let me give you an example of what I think my issue is. In my main project folder, I have a SASS folder next to my WordPress folder. All I really need to deploy to the server is the WordPress folder. My build process that happens on my dev machine combines all of the SASS files into a single CSS that is then placed into the WordPress folder. I need the SASS folder to be tracked by Git so that any other developer can pull them and continue developing so I can't have git ignore it. However none of those SASS files need to be on the server for WordPress to work either. I just simply need to deploy the WordPress folder and everything that's in it.
I understand the idea of creating a bare repository on the server and using post-receive hook to point the git folder sitting outside your web root to point to where the web root is. But that's basically how GIT and SSH work and that's not answering my concern.
Not with Git
Git is not designed to pull specific files or directories only. It's a directed acyclic graph with binary blobs as objects and sometimes multiple objects get compacted into a single larger object.
Due to Git design, your specific request is not possible.
Alternatives
post-receive hook
If your website only contains simple static files then it's okay to push to a git repository over SSH. In reality, it's unlikely your repository will be large as long as you don't have non-text files.
Take for example the following setup.
/var/lib/www - apache web dir which is the cloned copy of www.git
/var/lib/www.git - a bare git repository.
/var/lib/www.git/hooks/post-recieve - A server side git hook. It can be a shell script that pulls the www repository when this repository is updated.
Sample post-recieve hook script:
#!/bin/bash
cd /home/sam/sandbox/git-hooks/www
unset GIT_DIR
git fetch origin master
git reset --hard origin/master
Zip up build in a tar.gz
At the end of your build you can zip up your files in a tar.gz. This file should be hosted somewhere (perhaps GitHub releases if you're using GitHub). Some enterprises use on premise artifact hosting like Nexus or Artifactory.
The idea being: you have a tested artifact that has a specific sha256sum. The artifact you test is the exact same artifact which eventually goes to production.
Diving into more detail such as continuous integration, continuous delivery, and the software development life cycle might be out of scope for your question.
No best practice.
Git is for source control, not for deployment. There is no best practice for using git this way because git is not a deployment tool. You also don't need git history on your server. In fact, you don't need git at all unless you insist on using it for deployment. You are welcome to use it this way but it's not ideal because of exactly the kind of problem you're asking about.
What is the best practice?
There are a number of tools you could use to handle your deployments. Most of the tools generally let you set up a series of steps that let you deploy the code you want into the environment you want. You could go with simple tools such as Phing or Deployer in the PHP world, or something more sophisticated like Puppet or Chef if you have more complex needs. You could just write your own bash scripts if what you need is really very simple. I recommend Phing or Deployer given the info you've provided. https://deployer.org/ https://www.phing.info/
You'll just configure whichever tool you want to ssh into your target box and copy over only the files you want into the directory you want on the server, in whatever way you would like to do that. Usually, you have the script copy files into a temp dir, tarball them up, ssh them over and untar them. After that, you'll usually do some additional work on the server to move files around, change symlinks, whatever else you might need to do.
What about compiled SASS, ES6 js files, or modern static stuff?
All you need to do is add steps to the handle the static files and where you want them to go. Include the generated static files in your tarball when you push stuff up, and put them in the right directories in the server once you untar it.
When you configured your SASS compiler, and whatever other pre-compiled static code you may have - you configured it to create a destination file. That is, the file(s) of actual CSS and JS that they generate. That's all you need to bring along - and if you have the destination directory set to be inside your wordpress theme, you may not even have to pay all that much special attention to it's handling. You may need to move them somewhere else once they are on the server but that all depends on the specific setup in your server, which I think is outside the scope of this question.
Additional Notes:
You didn't ask about this but I thought it was worth mentioning, that you shouldn't be sending the entire wordpress repository every time you update. Just like you don't need the uncompiled SASS code, you also don't need to be repackaging core WordPress. You don't even need to be commiting core WordPress, its a dependency and you don't need to be changing it.
All that should be getting committed by you is your theme and plugin code, and the uncompiled static files. Compiled static files and external dependencies like the WordPress core don't belong in your git history. For deployment purposes, WordPress should already be installed. The stuff in your tarballs should just be plugins and themes, and additional static files if they aren't already in there for some reason.
TLDR;
Don't use git for this. Use a tool like Phing or Deployer. Build your static files into your theme, and create phing/deployer scripts that tarball up only the code you want, SSH's it over to your server, and untars it into the directories you want. If you have some special location on the server for your static files, just make sure to add steps in your script for that.
So, based on your question and comment, there are three computers involved. There is a web server (when you say "server", I take it as a Web server in this scenario, or the server computer that runs a Web server program). There is another server where your git repo is hosted. And, there is your dev workstation. Is this correct?
It seems like, you have a cloned git repo on your Web server. Your current practice/workflow appears to be (1) (based on your expression "SSH'ed into my server") you log into the web server via SSH (just like Telnet) from your workstation (SSH is just a protocol, which can be used for different purposes). (2) you pull from your repo on hosted service (e.g., github), and (3) deploy it to your "www" directory on the same server. Is this correct?
(I can think of an alternative scenario based on your use of the word "FTP", etc., but let's focus on the above scenario, for now.)
Now, your question is, whenever you "pull" (on your Web server), you feel like you are pulling everything from your repo on your hosted service. And, is there a better way? Am I understanding your question correctly?
If so, as another commenter suggested, git (and, any version control system, in general) is very good at fetching "deltas" only. If you are worried about "fetching everything" every time you pull (the step (2) above), then your worry is unfounded.
Now, the question is, why do you have a git repo on your Web server, if that is indeed the case? This is a pretty legit setup and I've done this before (e.g., on EC2). But, as a best practice, people generally don't do that on "production" servers. It's because you have to "build" your web app, and you really don't want to do that on production servers.
The next question is, what do you exactly do in Step (3)? The build process (whatever process you use) typically generates an "output" which can be directly deployed to the web server. (The convention is the output is generally a single folder, "public", "www", "dist", or whatever, or a single file (e.g., tar.gz, zip, jar, war), etc.) Regardless of whether you build the deployable output on your dev workstation (or, a build machine) or on your Web server, you don't generally do "deltas" in this context. Even if you've only changed a single file (say, a CSS file), you generally build the whole output again (instead of, say, just replacing the changed CSS file only). When you use FTP to upload files, etc., you can selectively upload certain files and/or directories, etc., but as a general practice, we don't do that. We always build the complete output from scratch and deploy it to the Web server. (This is mainly to reduce the potential deployment errors and increase the reliability.)
So, to answer your question, (A) If you are pulling git repo on your Web server, you should really change that practice, and move the build process to your dev computer or a dedicated build machine. (BTW, services like github, gitlab, TFS, ... provide the build service for you.) (B) If you are currently selectively FTP'ing your web app files to your Web server, then you should really consider adopting some kind of formal build, and deployment, process moving forward.
After your SASS build process is done use scp or rsync to move the files to the prod server:
scp -r /[local wordpress dir]/wp-content/themes/your-theme/ username#your.prod.server.com:/path/to/dir/wordpress/wp-content/themes/
scp -r /[local wordpress dir]/wp-content/plugins/* username#your.prod.server.com:/path/to/dir/wordpress/wp-content/plugins/
I am working in a project and using git ssh with bitbucket following is the process i am using it may work for you also if not please correct me :
Step 1 ->I have setup git and create repo in bit-bucket.
Step 2 ->And setup project with my local and linked with my repo.
Step 3 ->connect my server using ssh.
Step 4 ->Work in my local and commit and push all changes in my git repo.
Step 5 ->Run git pull on ssh so all changes deployed in my server.
I am using above process and i love this process.i have used .gitignore file that is not required for push on my repo.
Thanks

Trouble designing grunt workflow, with rev and usemin, for webdev

I'm going to start using grunt-rev & grunt-usemin with grunt-watch for my web development needs (a RESTful Web App specifically).
I have a local development machine which will run grunt-watch to attach revision identifiers on my JS files. I git commit and git push my tree to a git repo, and then ask the production server to git pull the changes from the git repo to show them to the web visitors.
The problem is that I don't want my git repo to store different filenames (due to grunt-rev) on each commit. That would be bad, because then I wouldn't be able to do git diff between commits without having my screen get flooded with the contents of files that appear and disappear, and also it could (sometimes) take up a lot more storage than if it only stored the small diffs of the files.
The only solution I see is to add the build directory containing the versioned filenames in my .gitignore, so as to not store those files (with the constantly changing filenames) in git. But wouldn't that mean that I would have to run grunt-watch on my production server as well, in order to produce the build directory with the versioned filenames there as well? But that gets complicated: a new process has to run on the remote server, maybe with its small chances of error in processing the files. Not the solution I was hoping for.
Do you people have another solution? What would you suggest I did?
What I do to solve this, is to remove previous "build" files before committing and deploying a new file. There is no need to keep older files that have been generated, because you can always rebuild them with the source files (which are in git).

creating git repositories from live [wordpress,magento] sites, ignoring core php files, but be able to clone the repository on multiple local servers

So I have a lot of websites, 150+. Starting with the bigger sites I am beginning to set up git repositories for tracking the changes to these sites. I can create a localserver version of a site and set up the repository and everything is running fine.
I have set up a .gitignore file to ignore all the core files and plugin folders etc. Again this is fine, the files are still on my local machine and have been deleted from my repository.
What I want to do is set up this repository on multiple computers (my colleagues who do less development work but will still need access to the repository). I imagine cloning won't work as all the core files are no longer in repository. How do I get around this?
Thanks all!
EDIT:
I should have mentioned we're using BitBucket to act as a central repository if that makes any difference.
There are few ways you can do that.
You can set local environment in one location, and keep git repository in other location.
After cloning or pulling the repository you can then run script which will copy the files from repository to the local environment.
You can add all files to the repository ignoring only var/, .htaccess, app/etc/local.xml and .gitignore. Bare in mind that you can break a website by changing files which should not have been changed. Debugging then becomes a nightmare. Having all in git, you know instantly what went wrong.
We've managed to set up great workflow using beanstalk.com. They've got option to share repositories (like github) and then deploying them on different server through SSH. Works like a charm - highly recommended.

How do I sync production sub folders with a git repository?

I'm using asp.net and WebDeploy to publish the latest bits of my website. The production site has a couple folders that I would like to keep in sync, though.
Since it's an asp.net site, I would rather not have my entire repository on the server when I can get by with just the views and dll. Additionally, I would rather not add the extra clutter of additional class projects & files to my production server file system.
How do I keep the folders in production in sync with the master branch in git? An automated solution would be optimal.
you could create a git hook that will export your files using git archive to create a zip (or tar) to a tmp folder. Then, uncompress the files to the given tmp folder, finally, transfer them to your server.
Also, check this answer Do a "git export" (like "svn export")?
Setting up a scheduled task to commit those files to their respective git repositories will work. It's not ideal, but it will make sure those repositories are relatively up to date with the assets on the live site.

Resources