This blog post introduces the GitHub actions for CI/CD.

So far, we have discussed the basic functionalities of Git and GitHub as a distributed version control system and hosting service for Git remote repositories, which are fundamental to working on projects possibly with others. However, GitHub offers additional features that facilitate DevOps practices. In this article, we will discuss one such feature: GitHub Actions, and how it is useful for CI/CD.
YAML Files
With GitHub Actions, you can run arbitrary commands using a virtual runner at any event trigger, such as push, pull,
or merge of a pull request. The environment configurations and commands to be executed can be specified in a YAML file
with yml
or yaml
extensions. YAML is a human-readable and computationally powerful data serialization language
often used for configuration files. It serves as an alternative to JSON by storing key-value pairs but with different syntax.
key1: value1 # String
key2: 2 # Number
key3: true # boolean
key4: on # boolean (true & false, on & off, yes & no)
key5: >
When > symbol is used, this long sentence is
merged into one sentence.
key6: |
When | symbol is used, the new lines and whitespaces
are preserved.
The example above shows key-value pairs in strings, numbers, and booleans. YAML automatically infers the type, though you can use
double quotes if necessary. Long strings can be broken into multiple lines using >
or |
, as shown above. Arrays and objects
can also be expressed as follows:
# Array
array1:
- value1
- value2
- value3
array2: [value1, value2, value3]
# Object
object:
key1: value1
key2: value2
key3: value3
# Array of Objects
array3:
- key1: value1
key2: value2
- key1: value3
key2: value4
Arrays and objects can be combined, allowing the expression of complex object types. To set up a GitHub action,
create a .github
directory at the root level, add a workflows
subdirectory, and place a corresponding YAML file
with configurations inside it.
Continuous Integration
Continuous integration (CI) is a practice where developers should push valuable and small code changes incrementally to improve software. To achieve CI, any breaking changes need to be detected before being applied, ideally automatically. GitHub Actions allow you to run testing scripts upon events like pushes or pull requests to facilitate CI. Below is an example workflow for running tests:
name: "Testing"
# When to trigger workflow
on:
pull_request:
branches:
- main
# Workflows
jobs:
test: # name of a workflow
runs-on: ubuntu-latest # OS (mac, windows, ubuntu)
steps:
- uses: actions/checkout@v4 # preset action for accessing source code
- uses: actions/setup-node@v4 # preset action for setting up NodeJS
with:
node-version: 20
- name: Install Dependencies
run: npm ci # clean isntall
- name: Run Test
run: npm test # defined in the source code
- run: npm run build # test if the source code compiles
The above YAML file configures a workflow that tests the source code using test scripts defined in the codebase on NodeJS
installed on Ubuntu when a pull request is made on the main
branch. You can use preset actions like actions/checkout
and
actions/setup-node
to simplify environment configuration. Names can optionally be assigned to each command, which will
be displayed on the GitHub interface (otherwise, it defaults to "Run <command>
"). If any command fails, it is flagged
on GitHub with an error message automatically, aiding in debugging without needing to download the code and run tests manually.
jobs:
test:
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
node-version: [18, 20]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
To test and build across different OS and versions, you can use strategy: matrix:
. The example above tests
six combinations of OS and Node.js versions using this strategy, which is beneficial for software that needs
cross-platform compatibility.
Continuous Delivery
Continuous delivery (CD) is a concept where developers can release software continuously without manually configuring the server each time. This can also be achieved using GitHub Actions, as demonstrated in the following workflow example for deploying software on AWS with SSH keys:
name: "Deployment"
on:
push: # When pushing directly to main or merge pull request
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- name: Install Dependencies
run: npm ci
- run: npm run build
- name: Get SSH key and sort permissions out
run: |
mkdir -p ~/.ssh
echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa && chmod 600 ~/.ssh/id_rsa
- name: Deploy using SCP
run: >
scp -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa
-r ./dist/*${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }}:~node-app
- name: Restart the server
run: >
ssh -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }}
"cd ~/node-app && npm install && pm2 restart 0"
Secrets like SSH keys and API keys that do not belong to the repository can be stored in the "Action secrets" section
under "Settings," which workflows can access via secrets.
The above workflow sets up the SSH key and permissions,
sends files using SCP (a networking protocol for sending files), and restarts the server with pm2
. The details of the scripts
depend on remote server architectures, but once you set up the workflow, delivery can be automated, which is highly convenient.
(Many paid hosting services automatically perform this too.)
Conclusion
In this article, we introduced YAML files, CI/CD, and GitHub Actions, all of which are essential for DevOps. YAML files are used across multiple DevOps tools, and CI/CD is at the core of DevOps practices. For more information on GitHub Actions (preset actions, example actions, events, etc.), refer to the official documentation cited below.
Resources
- Fireship. 2021. 5 Ways to DevOps-ify your App - Github Actions Tutorial. YouTube.
- GitHub. n.d. GitHub Actions documentation. GitHub Docs.
- Shaw, T. 2024. CI/CD Tutorial using GitHub Actions - Automated Testing & Automated Deployments. YouTube.