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:
- Create a repository and name it
.github/workflows
inside the GitHub repository. - Create a file and name it
demo-workflow-file.yml
. - 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:
- Since our workflow’s trigger is a push event, push a commit on any repository branch and attach Triggering Push as the commit message.
- Go to the repository’s page on GitHub and click the Actions tab under the repository’s name.
- At the top, the commit message for the push that triggered the workflow will be visible.
- Once the workflow is complete, click on the tab with the commit message. In this case, click on Triggering Push.
- The job name and status will appear on the left. In this case, it will be Hello World.
- 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 on
statement 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:
- Check out the code from the repository.
- Set up the correct Python version for the workflow runner, depending on the project’s version.
- Install the right project dependencies on the runner. In this case, the workflow runs these actions:
- upgrade the Python package installer pip
- install the
flake8
library for linting and PyTest for testing the project - look for a
requirements.txt
, and if present, install dependencies in the file
- Run flake8 and catch any linting errors.
- Run the tests in
tests.py
withpytest
andpytest-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 thepython-version
line in the Set upSet 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
run
action in theLinting project with flake8
step:
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:
- Check out the repository code.
- Use
setup-qemu-action
to add support for emulation and enable building against a wider range of platforms. - Use
setup-buildx-action
to install and set up Buildx - Login to DockerHub with
login-action
and fetch the login username and password from the secrets created in the Dockerfile - 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
main
branch - 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:
- Check out the repository code
- Set up and install Node.js while caching npm’s dependencies
- Use npm to install the
ci
library - Use a specific version of
file-changes-action
to log exact changes in a JSON file namedfiles.json
after a push or pull request - Print the contents of
files.json
for the user’s review - Run the
demo-link-checker-script.mjs
file and pass it all the parameters listed - 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