Think of a job as a sandbox, everything you do in this block is temporary, and after completion, the job goes away, and so does the container.
Setting up the test job
For myself, I use composer to install plugins and stuff, but since that’s out of the scope of this how-to let’s setup a basic rsync dry-run.
- eval $(ssh-agent -s)
- echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - > /dev/null
- mkdir -p ~/.ssh
- chmod 700 ~/.ssh
- echo "$SSH_REMOTE" > ~/.ssh/known_hosts
- chmod 644 ~/.ssh/known_hosts
script: 'rsync -vazn -e "ssh -p18765" --exclude-from exclude-list.txt --delete ./* $SSH_USER@$SSH_HOST:/yoursite.com/wp-content/'
The tags parameter in the config tells GitLab to use an available runner that can use docker, nothing special there, but you can add more if you want. More info on tags in the docs.
The script tag says we want to run a script for this job. I realize there is a lot of parameters in the rsync script, so let me break it down:
- v – Makes sure the mode is verbose, give me all the info
- a– Sets rsync to archive mode, does a ton of stuff, just know this is your best option, more details here if you really want to dive in
- z – compresses data before sending ( so much faster )
- n – Dry run mode, short for –dry-run
- -e – sets ssh modes if you need to, in this case, I’m setting the port to the default SiteGround ssh port. This is also where you would add -o StrictHostKeyChecking=no if you skipped the known_hosts step from the SSH setup.
- –exclude-from – this sets a file to look at for excludes ( ie. don’t look at these folders when trying to sync ( more on that in a later section ) – exclude-list.txt is the file in the root of my repo.
- –delete – tells rsync to delete folders/files from the remote which do not exist in our repository, this is where excludes comes in handy; you wouldn’t want to accidentally delete your uploads would ya?
- ./* – This tells rsync to look at my current directory and all files within for pushing to production ( keeping in mind the excludes )
- $SSH_USER@$SSH_HOST:/yoursite.com/wp-content/ – Surely the $SSH_USER and other variable looks familiar by this point? Yep, these are the vars in your config from earlier, separated by a colon. Following that is the absolute path to your deploy directory, ie. where you want the files to go. The path will be different depending on your install.
Geeze, after reading what I’ve just wrote, that’s a ton to take in I’m sure… There is seriously a ton more options for rsync – here’s a quick link to the manual. All parameters are optional, but I suggest you dive into the manual before you decide to roll your own.
Creating your Excludes
This is an absolute must when using the –delete flag for rsync. Without defining excludes you risk losing ALL your uploads, maybe even your cache folders, or any other custom non-version controlled files/folders in your server’s wp-content folder. Seriously do not forget this step or you risk breaking your server.
So, without further bantering, create an exclude-list.txt file in the root of your project. In this case, /wp-content. You can copy my exclude list gist if you’d like.
The exclude list has a similar syntax to the .gitignore file in your repo already ( hopefully you have one ). It uses a pattern-match style to ignore files. In my file, I’m ignoring common non-production related files like composer, npm stuff, and stuff from SiteGround. If you are using a page caching plugin like W3TC you may need to add the db.php file and various other plugin specific custom folders to ensure they’re not deleted.
On the plus side, we’re doing a dry-run, so no harm done.
Running your job
Once you commit the yml file, GitLab will pick up on this and run the jobs defined in the file, in this case, just the test job dry-run.
To see your jobs, it’s on the left under CI / CD:
Clicking on the ‘Passed’ or ‘Failed’ or another status will give you more details on the job:
I’ll admit, there’s a ton of detail here, and it would require a whole other blog post to really detail it all. Simply put, the stuff in the big black square is the result of your job, think of it as a terminal that you can’t interact with. If your job fails, here will tell you why.
I suggest taking the time to dive into the docs on pipelines if you want to learn more. Let’s dive into the final page of this short novel ( apparently ) and get this puppy deployed to production shall we?
On to Page 5, the last leg of your journey, click it below!