GitHub Actions Tutorial and Examples

What is GitHub Actions?

GitHub Actions is a continuous integration and continuous delivery (CI/CD) platform that automates build, test, and deployment pipelines. It also allows you to execute code in the repository when certain events occur, making it easy to extend and customize.

In GitHub Actions, “Actions” run by executing code bundles inside Docker containers. These code packages run on GitHub servers and are compatible with any programming language, meaning they can run on local servers or in the public cloud.

GitHub Actions Tutorial: Creating Your First GitHub Actions Workflow

A workflow is a series of actions initiated once a triggering event occurs. For example, the triggering event can be some commit pushed to a GitHub repository, the creation of a pull request, or another workflow completed successfully. 

The set of instructions for a workflow is kept in a workflow file and written in YAML. The workflow file specifies what commands or scripts to run, the default settings, the environment for the commands, etc. 

The workflow is divided into jobs, and each job performs a set of steps. Each step runs one or more commands and can also call self-contained units of commands called actions. Each step runs on computational resources called runners, and the default settings can specify it to be Windows or Linux.

Create Workflow

To create a workflow and add it to a workflow file:

  1. Create a repository and name it .github/workflows inside the GitHub repository.
  2. Create a file and name it demo-workflow-file.yml.
  3. Paste the following code inside the demo-workflow-file.yml file.
on: [push]

jobs:
  build:
  name: Hello world
  runs-on: ubuntu-latest
  steps:
  - uses: actions/checkout@v2
  - name: Write a multi-line message
  	run: |
    	echo This demo file shows a 
    	echo very basic and easy-to-understand workflow.

Test Workflow

To test the workflow in the committed workflow file:

  1. Since our workflow’s trigger is a push event, push a commit on any repository branch and attach Triggering Push as the commit message.
  2. Go to the repository’s page on GitHub and click the Actions tab under the repository’s name.
  3. At the top, the commit message for the push that triggered the workflow will be visible.
  4. Once the workflow is complete, click on the tab with the commit message. In this case, click on Triggering Push
  5. The job name and status will appear on the left. In this case, it will be Hello World.  
  6. Clicking on the job will show the output from each step in the workflow.

Related content: Read our guide to GitHub Actions Workflows (coming soon)

GitHub Actions Examples

The following code examples are adapted from the official GitHub documentation.

Building And Testing Python Projects

Runners hosted by GitHub have Python and PyPy built-in. There is also a Python starter workflow that works for most Python projects.The user can paste the starter workflow in a file in the .github/workflows directory and add configuration per the project requirements.

Here is a Python starter workflow that can get the user started with building and testing their project:

name: Demo Python Workflow
on: [push]
jobs:
  build:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: ["3.8", "3.10"]

    steps:
      - uses: actions/checkout@v3
      - name: Set up Python for Demo
        uses: actions/setup-python@v4
        with:
          python-version: ${{ matrix.python-version }}
      - name: Install dependencies for demo Python project	
        run: |
          python -m pip install --upgrade pip
          pip install flake8 pytest
          if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
      - name: Linting project with flake8
        run: |
          flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
          flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
      - name: Testing the project using pytest
   run: |
     pip install pytest
     pip install pytest-cov
     pytest tests.py --doctest-modules --junitxml=junit/test-results.xml --cov=com --cov-report=xml --cov-report=html

The onstatement specifies the event that will trigger the workflow. For this example, a push to any branch from the repository will run the workflow. The strategy.matrix.python-version syntax specifies the version of the Python project this workflow builds and tests.

There are five steps of the workflow:

  1. Check out the code from the repository.
  2. Set up the correct Python version for the workflow runner, depending on the project’s version.
  3. Install the right project dependencies on the runner. In this case, the workflow runs these actions:
    • upgrade the Python package installer pip
    • install the flake8library for linting and PyTest for testing the project
    • look for a requirements.txt, and if present, install dependencies in the file
  4. Run flake8 and catch any linting errors.
  5. Run the tests in tests.py with pytest and pytest-cov and store results in JUnit format.

The workflow can be customized in different ways.

  • To configure the workflow for a semantic version range of Python automatically, remove the strategy.matrix.python-version from the above workflow. Next, replace the python-version line in the Set up Set up Python for Demo step with the following line:
python-version: '3.x'
  • To cache the dependencies, add the following line below the python-version line in the Set up Python for Demo step:
cache: 'pip'
  • To prevent the workflow from stopping because of a linting error, add the following line after the runaction in the Linting project with flake8step:
continue-on-error: true

Building And Pushing Docker Images

Here is an example GitHub Actions workflow for building and pushing Docker images:

name: ci

on:
  push:
    branches:
      - 'main'

jobs:
  docker:
    runs-on: ubuntu-latest
    steps:
      -
        name: Checkout
        uses: actions/checkout@v3
      -
        name: Set up QEMU for demo
        uses: docker/setup-qemu-action@v2
      -
        name: Set up Docker Buildx for demo
        uses: docker/setup-buildx-action@v2
      -
        name: Login to DockerHub
        uses: docker/login-action@v2
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}
      -
        name: Build and push
        uses: docker/build-push-action@v3
        with:
          context: .
          push: true
          tags: user/app:latest

The workflow above uses the Buildx Docker CLI plugin that gives users extended container build options with the BuildKit toolkit. The docker job has five steps:

  1. Check out the repository code.
  2. Use setup-qemu-action to add support for emulation and enable building against a wider range of platforms.
  3. Use setup-buildx-action to install and set up Buildx
  4. Login to DockerHub with login-action and fetch the login username and password from the secrets created in the Dockerfile
  5. Build and push the Docker image while showing the output in the registry.

Testing Code with Scripts on Runner

GitHub Actions workflows can run external scripts on their runners. This example shows a workflow that runs scripts to check for broken links on the GitHub Docs website:

name: 'Demo Broken Link Checker'
on:
  workflow_dispatch:
  push:
    branches:
      - main
  pull-requests:

permissions:
  contents: read
  pull-requests: read

concurrency:
  group: '${{ github.workflow }} @ ${{ github.event.pull_request.head.label || github.head_ref || github.ref }}'
  cancel-in-progress: true

jobs:
  check-links:
    runs-on: ${{ fromJSON('["ubuntu-latest", "self-hosted"]')[github.repository == 'github/docs-internal'] }}
    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Setup node
        uses: actions/setup-node@v3
        with:
          node-version: 16.13.x
          cache: npm

      - name: Install
        run: npm ci

      - name: Gather files changed
        uses: trilom/file-changes-action@a6ca26c14274c33b15e6499323aac178af06ad4b
        with:
          fileOutput: 'json'

      - name: Show files changed
        run: cat $HOME/files.json

      - name: Run demo link checker (warnings, changed files)
        run: |
          ./script/demo-link-checker-script.mjs \
            --language en \
            --max 100 \
            --check-anchors \
            --check-images \
            --verbose \
            --list $HOME/files.json

      - name: Link check (critical, all files)
        run: |
          ./script/demo-link-checker-script.mjs \
            --language en \
            --exit \
            --verbose \
            --check-images \
            --level critical

The on code block specifies that this workflow should run on the following events: 

  • workflow_dispatch: when manually triggered from the Actions UI
  • push.branches.main: when a commit gets pushed to the mainbranch
  • pull_request: when any event related to a pull request occurs  

The permissions code block specifies that the workflow has file reading permissions. The concurrency code block specifies the concurrency group and uses cancel-in-progress to terminate any other workflows or jobs using the concurrency group.

The check-links job runs in seven steps:

  1. Check out the repository code
  2. Set up and install Node.js while caching npm’s dependencies
  3. Use npm to install the ci library
  4. Use a specific version of file-changes-action to log exact changes in a JSON file named files.json after a push or pull request
  5. Print the contents of files.json for the user’s review
  6. Run the demo-link-checker-script.mjs file and pass it all the parameters listed
  7. Run the demo-link-checker-script.mjs file and pass it different parameters

Combine GitHub Actions with Codefresh to Support GitOps and Kubernetes Deployments

GitHub actions is a very powerful platform but it is focused mostly on CI and does not support GitOps and native Kubernetes deployments. Codefresh is created specifically for GitOps and Cloud native applications and includes native support for using GitHub Actions for the CI part of the Software lifecycle.

This means that you can get the best of both worlds by keeping all your CI workflows in GitHub Actions, while using Codefresh for advanced features such as:

  • Application dashboards
  • Git source managements
  • Configuration drift management
  • Kubernetes environment dashboards
  • Topology views

In case you are new to Codefresh – we have made it our mission since 2014 to help teams accelerate their pace of innovation. Codefresh recently released a completely rebuilt GitOps CI/CD toolset. Powered by Argo, Codefresh now combines the best of open source with an enterprise-grade runtime allowing you to fully tap the power of Argo Workflows, Events, CD, and Rollouts. It provides teams with a unified GitOps experience to build, test, deploy, and scale their applications.

The World’s Most Modern CI/CD Platform

A next generation CI/CD platform designed for cloud-native applications, offering dynamic builds, progressive delivery, and much more.

Check It Out