GitHub Actions
This page provides introduction to github actions.
Overview
GitHub action is github integrated tool, allowing automation. It is triggered by events in github such as pull_request, push etc.
Core Concepts
- Actions: Actions are the smallest portable building block of a workflow and can be combined as step to create a job.
- Events: Events are activity which can trigger a workflow run. For e.g. pull_request, push etc. Events can also be configured to listen to external events using webhooks.
- Runner: A Runner is a machine with github action runner application is installed. Runners can be host on github or self-hosted.
- Job: Job is made up of multiple steps and runs in an instance of virtual environment.
- Step: A Step is set of tasks that can be executed by a job. Step can run commands or actions.
- Workflow: Workflow is automated process that is made up of multiple jobs and can be triggered by an event. Workflows are defined in .github/workflows directory using yaml file.
Hello GitHub Action Demo
Click here to view the repository.
Let's start by creating an empty github repo.
On your local create a folder for project repo as below:
mkdir hello-github-action && cd hello-github-action
Create script.sh in root directoy with below content:
#!/bin/sh
echo "Hello GitHub Actions!!!"
Create github action under folder .github/workflows/print-github-actions.yaml
name: Print Action
on:
push:
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Run a Script
run: sh script.sh
Check in the changes to github repo
git add .
git commit -m "first commit"
git branch -M main
git remote add origin https://github.com/vchoudhari45/hello-github-action.git
git push -u origin main
After you check in the changes, a github Actions workflow will automatically start. You can monitor its progress under the Actions tab in the repository.
Handling Secrets
Sensitive data such as password, credentials, tokens or certificates can be stored as github secrets. You can define your secrets either at org, repository, or environment level.
Secret Github Action Demo
Click here to view the repository.
Let's start by creating an empty github repo.
On your local create a folder for project repo as below:
mkdir github-action-secret && cd github-action-secret
Create github action under folder .github/workflows/main.yaml
name: Getting Secret within Actions
on:
push:
branches:
- main
jobs:
get-repo-secret:
runs-on: ubuntu-latest
steps:
- name: Retrieve Secret
env:
repo_secret: ${{ secret.MY_SECRET }}
run: |
if [[ $repo_secret == "repo secret" ]]; then
echo "Sucessfully got repo secret value: $repo_secret"
fi
get-env-secret:
environment: dev
runs-on: ubuntu-latest
steps:
- name: Retrieve Secret
env:
env_secret: ${{ secret.MY_SECRET }}
run: |
if [[ $env_secret == "env secret" ]]; then
echo "Sucessfully got repo secret value: $env_secret"
fi
Check in the changes to github repo
git add .
git commit -m "first commit"
git branch -M main
git remote add origin https://github.com/vchoudhari45/github-action-secret.git
git push -u origin main
Once repo is created add repo secret and env secret as below:
After creating the secrets, make a small change to the README.md file to trigger a GitHub Actions workflow. If the workflow completes successfully and shows the expected output, your secret export setup is working correctly.
Handling Dependencies
By default all the jobs run in parallel at the same time, but you can use "needs" keyword to define a dependency. If dependency fails, all the remaining jobs will be skipped.
Here’s an example of how to define a dependency:
jobs:
setup:
runs-on: ubuntu-latest
steps:
- run: ./setup_server.sh
build:
needs: setup # this add setup step as pre-requisite for build step
runs-on: ubuntu-latest
steps:
- run: ./build_server.sh
Reusing Workflows
Let's first define the reusable workflow called workflow-A
name: workflow-A
on:
workflow_call # this makes workflow callable from other workflow
inputs:
my_input_value:
description: 'An optional input with a default value'
required: false
default: 'Default value'
jobs:
setup:
name: Print Hello Reusable Workflow
runs-on: ubuntu-latest
steps:
- name: Echo Reusable Message
run: echo "Input value is: ${{ inputs.my_input_value }}"
Now, let's call reusable workflow from caller workflow as below:
jobs:
# example of calling workflow-A with default value
call-workflow:
uses: org/repo-name/.github/workflows/workflow-A.yaml@v1
# example of calling workflow-A with abc
call-workflow-passing-data:
uses: org/repo-name/.github/workflows/workflow-B.yaml@v1
with:
my_input_value: abc
Defining Environment
Here’s an example of how to define environment:
jobs:
deployment:
runs-on: ubuntu-latest
environment: prod # defining environment
steps:
- name: deploy
# ... deployment specific steps.
Defining Environment Variables
Here's an example of how to define environment variables:
env:
# defining a variable at global level
GLOBALENV: Available for all jobs in this workflow
jobs:
sample-job-1:
runs-on: ubuntu-latest
env:
# defining a variable at job level
JOBENV: Available for all jobs in this workflow
steps:
- name: step-1
run: echo "${GLOBALENV}"
- name: step-2
run: echo "${JOBENV}"
sample-job-2:
runs-on: ubuntu-latest
steps:
run: echo "${GLOBALENV}"