Skip to main content

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

  • Docs

  • 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.