In this blog post, I will show you how Github Actions work and how you can use it to spend less time deploying and more time coding.
Hi 👋 I'm Dawson. I daily tweet about web dev tips and write long-form content like this. So if you like it, please consider giving me a follow on Twitter.
What is Github Actions?
Github Actions is another feature on Github. It relies on the GitHub webhooks API to detect commits and pull requests, allows you to build and deploy your code.
You're able to create pipelines with customizable actions per stage, monitor your repository for changes, and run the appropriate pipeline for the event that happened. For example, if new code is pushed, then run some tests.
You can specify conditions that need to be fulfilled before running actions. You can create your custom scripts or use ready-to-use workflow templates.
What are the Advantages of GitHub Actions?
No more Re-deploying
Deploying your application once you make changes to your code manually could be exhausting, and repetitive.
On a personal use case, let's say you deploy your apps manually. You write some code; you push to GitHub, ssh into your VPS, pull the changes from Github, build and deploy, and forget to add something? REPEAT. Exhausting right?
With Github Actions, you can create a CI/CD pipeline that does all of those things for you, what you have to do is push to GitHub, and GitHub will take care of your workflow.
Automating your open-source workflow
Open source projects take outstanding advantage of this service; it makes everything much more straightforward.
Imagine maintaining an extensive open source project, and contributors send pull requests all the time, some of those pull requests might break your code if you merge it into your main branch.
What can you do? You can set up a workflow with Github Actions and build and test the app every time someone creates a pull request so that before you even try to consider reading a pull request, you already see that this pull request breaks some part of your code.
No third party tool
The best thing about GitHub Actions is that you probably already use GitHub.
So it's much better to use GitHub Actions than to use some other third-party tool to manage your CI/CD pipeline and build high-performing, secure pipelines.
A large variety of already set up workflows
You don't need to manage your workflows; you can use already made environments to run your pipeline workflow.
It is easy
Github CI/CD pipeline is also more accessible than other CI/CD tools and does not require you to have a full-time DevOps team that is cost-intensive and not ideal for startups. Instead, you can quickly learn how to use it and create workflows with your development team.
You don't need a server to run actions
All these actions will be happening on Github servers. This means you save resources because you don't have to run them on your server.
How it works?
These Github actions that we talked about will only trigger when specific events happen, like push
and pull request
. Let's say that we only want a particular action to happen only when the event is push
, meaning that every time some new changes are being pushed to the Github repository.
So basically, GitHub will listen to an event and trigger the actions given by the developer.
Each job will run on a different server, for example, any job in the job
tag is run by a server, and another job
has another server.
Sometimes we want jobs to run one after another. If we decide to do so, we need to use the needs
tag in the other job and include the other jobs` name. More of this later
The CI/CD pipeline
Today, one of the most common workflows is the CI/CD pipeline, which runs some actions in order.
- Commit: you commit your changes to GitHub.
- Test: Workflow starts running tests.
- Build: Build starts if the test ran successfully.
- Deploy: Deploys the latest changes to the server.
Code is pushed from development to a testing environment and finally to production for end-users to access.
The Github workflow syntax
Github Actions use the .yml
language to define workflows. So if you don't have a basic understanding of reading YML, I recommend reading some articles about it.
There are many syntaxes that Github uses to define workflows, I will talk about the most used and common ones, and later in this article, we will write our workflow for a node.js application, test it and then deploy it to our own VPS.
Here are some of the most essential .yml
syntaxes of Github workflow:
- name: is the name of your workflow file.
- on: contains the list of events in which we want to trigger the action.
- jobs: The list of jobs we want to run after the event happens.
- runs-on: is the operating system in which you want to run the workflow.
- steps: a list of actions you want to run after the event happens.
- uses: you can import other people's written actions and re-use them.
- with: a list of variables. Think of it as environment variables.
Secrets
Sometimes you want to add a password or a private key inside your workflow file.
But you don't want other people to see it, and you still want to run the actions.
In this case, you can put your repository secrets from your repository settings; you can specify the name of your key and the value of your key.
Later you can use these secrets in your .yml
file by using the ${{ secrets.YOUR_SECRET }}
syntax.
Writing a sample Github workflow
In this tutorial, I'll show you how to set up a GitHub workflow so that when we push some changes to our main branch on GitHub, our website will automatically build, test, and host itself again. which will save us a lot of time & effort.
So, in summary:
- We push some changes to Github.
- Event triggers.
- Github will download our code and test it on their server.
- If the test is successful, Github will access our VPS using SSH keys.
- Fetches the latest changes.
- Builds the app.
- Restarts the app.
The following code shows the Github workflow code for testing, building, and hosting a node.js app on a VPS using SSH keys:
`
name: Node.js CI
on:
push:
branches: [ master ]
jobs:
build-and-test:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [16.x]
steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- run: npm i
- run: npm run build
- run: npm run test
deploy:
needs: build-and-test
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [16.x]
steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.IP }}
username: ${{ secrets.USERNAME }}
key: ${{ secrets.KEY }}
script: cd path/to/your/app/directory && git checkout . && git pull && npm run build && pm2 restart MyApp
The first job we have created is to build and test the app on the Github servers.
If the first action was successful, the second one will be executed. We specified this by using needs
syntax and adding the previous job name.
Great, now your server hosts itself again without you having to worry about build fails or errors in your code. Now, you can spend more time coding and less time re-deploying.
Thank you for taking the time to read my blog post. If you found it helpful, please feel free to follow me on Twitter, where I post daily web development tips.
website: https://dawsoncodes.com
Twitter: https://twitter.com/dawsoncodes
Top comments (0)