GitHub Actions Introduction
GitHub Actions is a feature that allows you to automate your software development workflows. You can write individual tasks, called actions, and combine them to create a custom workflow. Workflows are custom automated processes that you can set up in your repository to build, test, package, release, or deploy any code project on GitHub.
Overview
-
Workflow - A workflow is a configurable automated process made up of one or more jobs. Workflows are defined in
.yml
files in the.github/workflows
directory of your repository. -
Jobs - A job is a set of steps that execute on the same runner. Runner is a server that has the GitHub Actions runner application installed.
-
Steps - A step is an individual task that can run commands or actions like
actions/checkout@v2
. Each step in a job executes on the same runner, allowing for direct file sharing.
Summary: The workflow is a set of jobs and each job is a set of steps. Each step can be an action or a shell command.
Basic worflow file.
name: CI # name of the workflow
on: [push] # triggers the workflow on push or pull request events but only for the master branch
jobs:
build: # name of the job
runs-on: ubuntu-latest # runs-on is the type of machine to run the job on - runner
steps: # steps are the individual tasks that make up a job
- uses: actions/checkout@v2
- name: Run a one-line script # name is the name of the step
run: echo Hello, world!
-
Action - An action is a custom application for the GitHub Actions platform that performs a complex but frequently repeated task.
-
Event - An event is a specific activity that triggers a workflow. For example, activity that occurs on GitHub, such as opening a pull request or pushing a commit.
Triggers
The on
keyword is used to trigger the workflow. It can be triggered by a push, pull request, or a schedule.
on:
push:
branches: [main]
pull_request:
branches: [main]
Trigger Filters
- We can trigger the workflow when only when certain files are changed.
on:
push:
paths:
- "src/index.js"
- We can trigger the workflow when only when certain files with an extension are changed.
on:
push:
paths:
- "**.js"
- "**.css"
pull_request:
paths:
- "**.js"
- We can trigger the workflow when only when certain files in a directory are changed.
on:
push:
paths:
- "src/**"
- Manual trigger
on:
workflow_dispatch:
Services
Services are external resources that can be used in a workflow. We can use services like redis
or postgres
in our workflow. We can run a service in a container and use it in our workflow. We can also use custom images.
services:
redis:
image: redis # Docker image
ports:
- 6379:6379 # port mapping
mongodb:
image: mongo
ports:
- 27017:27017
sqlite:
image: sqlite
ports:
- 3306:3306
Using ouput from one step in another step
We can use the output from one step in another step using the id
keyword.
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Get the version
id: get_version
run: echo ::set-output name=version::1.0.0
- name: Use the version
run: echo ${{ steps.get_version.outputs.version }} # {{ steps.<step_id>.outputs.<output_name> }}
Jobs
We can have multiple jobs in a workflow. Each job runs in parallel by default. We can also run jobs sequentially using the needs
keyword. Each step in a job runs on the same runner.
We can run a job when a job passes or fails using the needs
keyword.
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Get the version
run: echo "Hello World"
test:
needs: build
runs-on: ubuntu-latest
steps:
- name: Get the version
run: echo "Hello World"
GitHub context
The github
context is available to you in any workflow or action you create on GitHub. You can use the context to get information about the workflow run, the repository, the event that triggered the workflow like pull request number, etc.
Some useful properties of the github
context are:
github.event_name
- The name of the webhook event that triggered the workflow.github.sha
- The commit SHA that triggered the workflow.github.ref
- The branch or tag ref that triggered the workflow.github.repository
- The owner and repository name. For example,Pradumnasaraf/DevOps
.github.actor
- The name of the person or app that initiated the workflow.github.job
- The name of the job that's currently running.github.run_number
- A unique number for each run of a particular workflow in a repository. This number begins at 1 for the workflow's first run, and increments with each new run. This number does not change if you re-run the workflow run.github.run_id
- A unique number for each run of any workflow in a repository. This number begins at 1 for the workflow's first run, and increments with each new run. This number does not change if you re-run the workflow run.github.workflow
- The name of the workflow.github.action
- The unique identifier (id) of the action.github.event
- The event payload. For example, the issue or pull request object that triggered the workflow run.
Environment variables
We can set environment variables in the workflow file using the env
keyword. WE
env:
MY_NAME: "Pradumna"
Secrets
We can store sensitive data like API keys, passwords, etc. in the repository settings. We can access the secrets using the secrets
context.
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Get the version
run: echo ${{ secrets.MY_SECRET }}
Matrix
Matrix is helpful when we want to run a job on multiple versions of a tool.For eg. we want to run a job on multiple versions of Node.js. We can use the matrix
keyword to run a job on multiple versions of a tool. We can also use the matrix
keyword to run a job on multiple operating systems.
jobs:
example_matrix:
strategy:
matrix:
os: [ubuntu-22.04, ubuntu-20.04]
version: [14, 16, 18]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/setup-node@v3
with:
node-version: ${{ matrix.version }}
Outputs
We can use the outputs
keyword to output data from a job. We can use the output from one job in another job using the needs
keyword.
jobs:
deploy:
runs-on: ubuntu-latest
outputs:
url: ${{ steps.deploy-preview.outputs.url }}
steps:
- uses: actions/checkout@v3
- id: deploy-preview
run: echo "url=preview_url" >> $GITHUB_OUTPUT
data:
runs-on: ubuntu-latest
needs: deploy
steps:
- name: load json files
run: echo ${{ needs.deploy.outputs.url }}
Artifacts
It allows you to share data between jobs in a workflow and store data once the workflow has been completed. We can use the upload-artifact
and download-artifact
actions to upload and download artifacts.
name: Share data between jobs
on: [push]
jobs:
job_1:
name: Generate Random Number
runs-on: ubuntu-latest
steps:
- shell: bash
run: |
echo $((RANDOM % 100)) > random-number.txt
- name: Upload random number for job 1
uses: actions/upload-artifact@v4
with:
name: random_number
path: random-number.txt
job_2:
name: Echo Random Number
needs: job_1
runs-on: ubuntu-latest
steps:
- name: Download random number from job 1
uses: actions/download-artifact@v4
with:
name: random_number
- shell: bash
run: |
number=$(cat random-number.txt)
echo The random number is $number
What's next?
- Scenarios - A collection of GitHub Actions workflow files I use and created to help you understand the concepts better.
- Learning Resources - A list of resources to learn more about GitHub Actions.
- other Resources - A list of other resources that you can refer to learn more about GitHub Actions.