Skip to content

Discover a collection of GitHub Actions workflow examples that will supercharge your development process. Level up your projects with the efficiency and reliability of GitHub Actions, saving time and ensuring high-quality code

License

Alliedium/awesome-github-actions

Repository files navigation

Awesome GitHub Actions

This repository serves as a comprehensive collection of GitHub Actions workflow examples. It provides a variety of workflow configurations that demonstrate different use cases and best practices for automating CI/CD processes using GitHub Actions. Each example includes a name for the workflow, a list of trigger events, and a set of jobs. Each job contains a list of steps that execute in order when the job runs. These steps may access environment variables, conditions, expressions, and secrets to perform various actions, such as checking out the source repository, running scripts, and setting up a tmate session for debugging purposes. Examples cover different areas of functionality, such as job matrix, parallel jobs, job ordering, context variables, expression evaluation, outputting variables, and event triggers.

GitHub Actions

GitHub Actions is a CI/CD platform for automatic build, test, and deployment. GitHub Actions allows you to run workflows when a push, pull request, or other event happens in your repository. You can use virtual machines provided by GitHub or manage your own runners in your own infrastructure. Workflow is a process that runs one or more jobs. They can be run either in parallel or in sequential order. Workflow basics:

  • One or more events that will trigger the workflow. Event is a specific activity in a repository.
  • One or more jobs, each of which will execute on a runner machine and run a series of one or more steps. By default, every job is independent
  • Each step can either run a script that you define or run an action, which is a reusable extension that can simplify your workflow
  • Each Runner is a newly-provisioned virtual machine. GitHub provides Ubuntu Linux, MS Windows, and macOS runners. You can host your runner as well. Every runner executes a single job.

Workflow files are yaml files and are placed in the .github/workflows directory in your repository on GitHub.

Examples

Note By default, all workflows will be executed on the ubuntu-latest image unless otherwise specified

Example 01: Hello world!

Get familiar with basic workflow syntax

This example workflow prints current path, Hello world, followed by Step 1…, Step 2…, Step 3…, and finally Goodbye.

Elements of current workflow:

  1. Name of workflow (optional element)

    name: hello-world-example
  2. The on section defines what event triggers the workflow. Here, the trigger event is push. The optional parameter paths allows to run a workflow based on what files or directories are changed.

     on:
       push:
         paths:
           - '.github/workflows/01-hello-world.yml'
  3. Job. The job name is say-hello. The keyword runs-on configures the job to run on the latest version of an Ubuntu Linux runner.

     jobs:
       say-hello:
         runs-on: ubuntu-latest
  4. Steps are a list of commands to run. The uses keyword specifies the action used in this job: actions/checkout versionv2. This is an action that checks out your repository onto the runner. You should use the checkout action any time your workflow will run against the repository's code. The Next step sets the option working-directory to the indicated path and prints the current path.

             steps:
               - uses: actions/checkout@v3
        
               - name: Print current path
                 working-directory: ./01-hello-world
                 run: pwd
  5. Pipe | is used to start multiple strings in a yaml file

       - name: Do stuff
         run: |
           echo "Step 1..."
           echo "Step 2..."
           echo "Step 3..."
           echo "Step 4..."

Example 02: Event triggers

This example demonstrates how to trigger workflow on different events

The on section defines what event triggers the workflow. List of events you can see here. Optionally, you may include/exclude branches, tags, or paths that trigger workflow by indicating their name or pattern to match. You may define multiple events and options for them to customize your workflow run. Also, it is possible to set a schedule to run your workflow, specified with POSIX cron syntax.

on: 
  push:
     branches: 
       - '02-develop'
       - '02-foo/*'
       - '02-foo/**'
       - '!02-foo/*/456' #except
     tags:
       - '*'
     paths:
       - '.github/workflows/02-event-triggers.yml'
  pull_request:
    branches:
      - '02-develop'
    paths:
      - '.github/workflows/02-event-triggers.yml'
  schedule:
    - cron: '*/15 * * * *'

Step prints the event name that triggered it.:

      - name: Event
        run: echo "Triggered by $GITHUB_EVENT_NAME"

Example 03: Actions

This example demonstrates the usage of different actions type in one workflow

Actions reduce number of steps by providing reusable code for common tasks, such as checkout to gitHub repository or installing node. To run an action include keyword uses pointing to a GitHub repo with the pattern {owner}/{repo}@{ref} or {owner}/{repo}/{path}@{ref}. A ref can be a branch, tag or SHA. Some actions have required or optional parameters. GitHub officially supports many common actions.

Example of usage of the different actions in workflow:

 steps:
   - uses: actions/checkout@v3
   - uses: actions/setup-node@v3
     with:
       node-version: '15.8.0'

In these steps :

  • actions/checkout checks out your repo into the working directory at the event that triggered workflow (e.g., branch push)
  • actions/setup-node sets up your workflow with a specific node version, and makes node and npm available in the following steps.

Example 04: Environment variables

Using environment variables in different contexts

Environment variables can be:

  • default. Find the list of default variables here and defined by the user.
  • or custom for:
    • a single workflow. Use the env key within the workflow file to create a variable for a single workflow. The scope of the variables can be: the entire workflow, job, or a specific step. The variable's scope is limited to the element in which it is defined.
    • multiple workflows. Variables and secrets can be created at different levels: organization, repository and environment levels.

Job:

jobs:
  use-env-vars:
    runs-on: ubuntu-latest
    env:
      VIDI: 'I saw'

Step:

    steps:
   ...
      - name: Show me the vars
        run: echo "$VENI, $VIDI, $VICI"
        env:
          VICI: 'I conquered'

Also, you can set new environment variables by adding it to GITHUB_ENV. The variable will be available in next steps.

      - name: Create env var
        run: echo "foo=bar" >> $GITHUB_ENV

Get values of the environment variables:

      - name: Useful default vars
        run: |
          echo "Workflow name:  $GITHUB_WORKFLOW"
          echo "Workspace:      $GITHUB_WORKSPACE"
          echo "Event:          $GITHUB_EVENT_NAME"
          echo "SHA:            $GITHUB_SHA"
          echo "Ref:            $GITHUB_REF"

Get list of all environment variables:

      - name: Show env variables list
        run: env

Example 05: Parallel jobs

Running jobs in parallel

Multiple jobs are running in parallel by default and have a particular runner:

jobs:
  job-a:
    runs-on: ubuntu-latest
    steps:
      - run: echo "Doing work"
  job-b:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

Example 06: Job ordering

By default, all jobs are running in parallel. To force job ordering use the needs keyword

It is possible to wait for one or more jobs:

  job3:
    runs-on: ubuntu-latest
    needs: job1
    steps:
      - run: echo "job1 done, running job3"
  job4:
    runs-on: ubuntu-latest
    needs: [job2, job3]
    steps:
      - run: echo "job2 & job3 done, running job4"

job5 will run even if job1 will fail

  job5:
    runs-on: ubuntu-latest
    if: ${{ always() }}
    needs: job1
    steps:
      - run: echo "job1 completed with status ${{ needs.job1.result }}, running job5

The diagram of the job running sequence is provided

%%{init: {'flowchart': {"curve":"linear"} } }%%
graph LR
A[job1] --> |on success| C[job3]
B[job2] & C[job3] --> |on success| D[job4]
A[job1] --> |always| E[job5]

Example 07: Job matrix

You can run multiple jobs with different configurations by using a job matrix. Jobs defined by matrix run in parallel by default

The matrix keyword is how you define a job matrix. Each user-defined key is a matrix parameter. Here we’ve defined two parameters: os, for the runner's OS, and node, to indicate the node version. Each value of the parameters from the list is used in a cartesian product to create jobs. This section defines a 2 x 3 matrix of 6 jobs, each with a different combination of os and node. The exclude keyword prevents jobs with specific configurations from running. The include allows you to add new jobs to the matrix. Note that the include rules are always evaluated after the exclude rules.

  my-job:
    strategy:
      matrix:
        os: [ubuntu-18.04, ubuntu-22.04]
        node: [14, 16, 18]
        exclude:
        - os: ubuntu-18.04
          node: 14

A runner is a server that runs your workflows when they're triggered. Each runner can run a single job at a time. GitHub provides Ubuntu Linux, Microsoft Windows, and macOS runners to run your workflows; each workflow run executes in a fresh, newly-provisioned virtual machine. If you need a different operating system or require a specific hardware configuration, you can host your own runners. A self-hosted runner is a system that you deploy and manage to execute jobs from GitHub Actions on GitHub.com.

Example 08: Outputs

Output data can be shared between jobs and steps. Create outputs for a step by writing to stdout in the format of =:

   - name: Do Work
     run: |
       echo "FAV_NUMBER=3" >> $GITHUB_OUTPUT
       echo "FAV_COLOR=blue" >> $GITHUB_OUTPUT
     id: abc

A step can have multiple outputs. Steps that create outputs must have a unique id. Use the steps context variable and step id to get the value ${{steps.<step_id>.outputs.<step_output_name>}}:

      - name: Read output
        run: |
          echo "${{steps.abc.outputs.FAV_NUMBER}}"
          echo "${{steps.abc.outputs.FAV_COLOR}}"

Create outputs for a job that will be available to other jobs that need it (see Job Ordering). You can include output from steps that ran for the job.

    job1:
    outputs:
      fav-animal: tiger
      fav-number: ${{steps.abc.outputs.FAV_NUMBER}}

Use context expressions to grab outputs from a job included in needs needs: <job_name>, to address output ${{needs.<job_name>.outputs.<job_output_name>}}:

   job2:
     runs-on: ubuntu-latest
     needs: job1
     steps:
       - run: |
          echo "${{needs.job1.outputs.fav-animal}}"
          echo "${{needs.job1.outputs.fav-number}}"

Example 09: Context

Contexts are a way to access information about workflow runs, variables, runner environments, jobs, and steps. Each context is an object that contains properties, which can be strings or other objects. Context variables are accessible outside the run commands.

Using values of the matrix context:

        env:
          GREETING: ${{ matrix.greeting }}

Accessing value of the secret USERNAME defined in the GitHub:

        env:
          A_SECRET: ${{ secrets.USERNAME }}

Using event name in expression:

        if: ${{ github.event_name == 'pull_request' }}

Example 10: Expressions

Workflows support evaluating expressions,comparisons and simple functions.

String comparison:

      - name: Print if 'Hello'
        if: ${{ matrix.greeting == 'Hello' }}
        run: echo "greeting is Hello"
      - name: Print if starts with 'He'
        if: ${{ startsWith(matrix.greeting, 'He') }}
        run: echo "greeting starts with He"
      - name: Print if ends with 'y'
        if: ${{ endsWith(matrix.greeting, 'y') }}
        run: echo "greeting ends with y"
      - name: Print if contains 'ow'
        if: ${{ contains(matrix.greeting, 'ow') }}
        run: echo "greeting contains ow"

Formatting:

      - name: Print formatted greeting
        run: |
          echo "${{ format('{0} says {1}', github.actor, matrix.greeting) }}"

Working with JSON:

      - name: To JSON
        run: echo 'Job context is ${{ toJSON(job) }}'
      - name: From JSON
        env: ${{ fromJSON('{"FAVORITE_FRUIT":"APPLE", "FAVORITE_COLOR":"BLUE"}') }}
        run: echo "I would like a ${FAVORITE_COLOR} ${FAVORITE_FRUIT}"

Running basing on previous results:

      - name: Success
        if: ${{ success() }}
        run: echo "Still running..."
      - name: Always
        if: ${{ always() }}
        run: echo "You will always see this"
      - name: Cancelled
        if: ${{ cancelled() }}
        run: echo "You canceled the workflow"
      - name: Failure
        if: ${{ failure() }}
        run: echo "Something went wrong..."

Example 11: Tmate terminal

The Tmate session will be started after fail on the previous step. Use this failing workflow for training

The workflow will fail on the following step because npm is not installed and no node action is used in this workflow.

      - name: Run tests
        working-directory: ./11-tmate
        run: npm test

Open the tmate session using the HTTP link from your workflow logs. If tmate is installed on your machine you may also connect to the session throw terminal. The command is provided in your logs as well.

tmate.png

Run npm install:

   npm ci

and check if tests will pass:

   npm test

continue workflow run by creating a file:

touch /continue

Example 12: Postgres service

This example workflow configures a PostgreSQL service container, and automatically maps port 5432 in the service container to a randomly chosen available port on the host. The job context is used to access the number of the port that was assigned on the host.
Create a secret at the repository level with the name POSTGRES_PASSWORD

jobs:
  postgres-job:
    runs-on: ubuntu-latest
    services:
      postgres:
        image: postgres
        env:
          POSTGRES_PASSWORD: postgres
        options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
        ports:
          # Maps TCP port 5432 in the service container to a randomly chosen available port on the host.
          - 5432

Example 13: Get secret value

Get a value of the secret with the name NEW_SECRET. If the secret does not exist value will be empty. Please create a secret with the same name or replace name with the one of an existing secret

    steps:
      - name: Echo secret's value
        run: |
          echo "Masked: "
          echo ${{ secrets.NEW_SECRET }}    
          echo "Unmasked: "
          echo ${{ secrets.NEW_SECRET }} | sed 's/./& /g'

Nektos Act

Install Nektos Act on Ubuntu Jammy

sudo apt install act

To install Nektos Act on other OS follow the instructions from section

To run the following commands you should clone a GitHub project with existing GitHub Actions workflows and go to its directory. You can use the current project, too.

  1. View all jobs that are triggered by pull_request event
act -l
  1. View all jobs triggered by events, e.g. by the pull_request
act <event-name> -l
act pull_request -l

or in the certain workflow file, e.g. in main.yaml

act <file-name> -l
act main.yaml -l
  1. Run a job with a specific name:
act -j <job-name> 
  1. You may also explicitly indicate the workflow and job to run using flags --workflowand --job, respectively, flag --verbosity enables additional logging.
act --workflows .github/workflows/main.yml --verbose --job my-job
  1. Use an alternative environment to run your workflows. runner-image-name - should be the same as in the workflow yaml file
act -P <runner-image-name>=<image-to-be-used>
act -P ubuntu-latest=catthehacker/ubuntu:act-20.04
  1. If your workflow file has a tmate section (See Example 11) you may access it using docker commands
watch docker ps

copy the first three symbols of the container's ID and run the command

docker exec -it <XYZ> sh
  1. About project
  2. Apache Ignite Migration Tool CI/CD
  3. Apache Ignite Migration Tool CI/CD GPG

References

GitHub Actions

  1. GitHub Actions workflows
  2. GitHub Actions workflows basics, examples and a quick tutorial
  3. Trigger a workflow
  4. Job environments
  5. Expressions in GitHub Actions
  6. GitHub Actions contexts
  7. GitHub Actions variables
  8. GitHub Actions common actions
  9. Good security practices for using GitHub Actions features
  10. Encrypted secrets
  11. Outputs for jobs
  12. Output commands
  13. Tmate actions
  14. Job services

Act

  1. Act
  2. GitHub Actions on your local machine
  3. Debug GitHub Actions locally with act

Tools

  1. Lastversion tool

About

Discover a collection of GitHub Actions workflow examples that will supercharge your development process. Level up your projects with the efficiency and reliability of GitHub Actions, saving time and ensuring high-quality code

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published