One of the advantages that I found of GitLab versus GitHub was their GitLab CI/CD tool (https://docs.gitlab.com/ee/ci/). But I have always used GitHub, so I have used another ways to perform those CI/CD actions. But then GitHub Actions appeared (https://github.blog/2019-08-08-github-actions-now-supports-ci-cd/) and caught my attention.
Basically, it allows us to automate all our workflow actions easily, such as running the tests suite or deploying the app. Whatever you want. You can find all the information here: https://github.com/features/actions.
I recently used it for the first time in a project and I really liked it. This project is a Docker-based Symfony app and it is deployed in a DigitalOcean droplet. So, when I am developing this project, my workflow is the following:
Continous Integration tasks when a pull request is made.
Those actions are running some quality checks in order to mantain the quality of the code. For that, I use the following tools:
- PHP CS (https://github.com/squizlabs/PHP_CodeSniffer)
- PHP Stan (https://github.com/phpstan/phpstan)
- PHP Mess Detector (https://phpmd.org/)
- PHP Unit tests.
I usually run this script for that: https://github.com/JorgeHRJ/qualitify.
Until the checks have not passed, the pull request is not going to be merged.
Continous Deployment tasks when commits are pushed/merged to master.
Finally, we have our pull requests merged into our ‘master’ branch, so we need to deploy our app with the new changes. And we do it in this step.
Let’s get into the practical part, and you will see how easy is it to implement in your project:
First of all, you need to create a .github/workflows directory in your repo. This will tell GitHub that we have some GitHub Actions workflow to be performed. Then, we create a .yml file for every workflow explained before. Here there are the ones I am using:
continuous-integration.yml
name: Continuous Integration
on: [pull_request]
jobs:
quality:
name: Quality checks
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Install dependencies
run: composer install --prefer-dist --no-progress --no-suggest
- name: PHP Code Sniffer
if: ${{ always() }}
run: vendor/bin/phpcs --standard=PSR2 src
- name: PHP Mess Detector
if: ${{ always() }}
run: vendor/bin/phpmd src/ text codesize,controversial,phpmd.xml
- name: PHP Stan
if: ${{ always() }}
run: vendor/bin/phpstan analyse -c phpstan.neon
- name: PHP Unit tests
if: ${{ always() }}
run: bin/phpunit
As you can see, this workflow is named ‘Continuous Integration’. It has only one job named ‘quality’, which is labeled as ‘Quality checks’. It will use a ‘ubuntu-latest’ Docker image for running the steps we are declaring then:
- Checkout the code
- Install our composer dependencies. So notice we need to have added there our quality tools. You can have them globally installed, so notice you will need to change the ‘run’ part in the following steps.
- Run every tool. Here you can see there are some ‘if’s. They are there because I want every tool step to be runned, despite some of them have failed before.
continuous-deployment.yml
name: Continuous Deployment
on:
push:
branches:
- master
jobs:
deploy:
name: Deploy
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Deploy
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.HOST }}
port: ${{ secrets.PORT }}
username: ${{ secrets.USER }}
key: ${{ secrets.KEY }}
script: |
cd /home/app/bielatv
bin/deploy.sh
And here you have the ‘Continuous Deployment’ one. Basically, it is declared that when some commits are pushed (or merged) into the ‘master’ branch, we will run our ‘deploy’ job. In my case, I only have one production environment, buy maybe you have some development or staging environment. In that case, you could define another job for when commits are merged into other branch.
Anyway, this job will checkout our code, and uses a nice GitHub action: https://github.com/appleboy/ssh-action. It allow us to run some ssh actions. We will have to set some GitHub Secrets (https://help.github.com/en/actions/configuring-and-managing-workflows/creating-and-storing-encrypted-secrets) so the ssh connection is able to be done. Then, in the ‘script’ part, we define the actions to perform the deploy. In my case, getting into the project directory and running a deploy script.
And that’s it. We have our new feature developed and deployed in a moment!
Discussion
Hi,
Thanks for the nice post. Can you please share
phpmd.xml
?TIA
Sorry, I didn't see this message. I am using this one:
Actually, it is a modification of this one that you can use from the PHPMD people: github.com/phpmd/phpmd/blob/master...
I deleted some of them, I do not remember now which ones.