Build a CI/CD workflow with GitHub Actions
Table of contents
Introduction
In this article, I will introduce how to build a CI/CD workflow (pipeline) with GitHub Actions
. It enables you to automate build testing, and deployment pipelines.
I will set up the workflow for an automation testing project. And this workflow will make the tests run on browsers corresponding to platforms:
Safari
andEdge
onmacOS
machineChrome
andFirefox
onWindows
machine
Before we explore how to set up GitHub Actions, we need to understand how it works. All GitHub Actions automations are handled using workflows. Every workflow consists of several core concepts: events
, jobs
, steps
, actions
, and runners
.
Workflow
A workflow is an automated process made up of several jobs that are carried out when triggered by events. Workflows are defined in YAML files and stored in a
.github/workflows
directory in the repository.
Events
Events are defined triggers that start a workflow, such as creating a branch, opening a pull request, or commenting on an issue.
Jobs
Jobs are a set of steps that are executed in a workflow when an event is triggered. A workflow can have multiple jobs running in parallel.
Steps
Steps are individual tasks that run commands in a job. These can be an action or a shell command. All steps in a job execute on the same runner.
Actions
An action is a command that executed on a runner, and the core element of GitHub Actions, which is named after it.
Runners
A runner is a GitHub Actions server. It listens for available jobs, runs each in parallel, and reports back progress, logs and results. Each runner can be hosted by GitHub or self-hosted on a localized server. GitHub Hosted runners are based on Ubuntu Linux, Windows, and macOS.
Prerequisite
Repository
- Create a repository at GitHub
- Push your source codes of project to GitHub
If you don’t have an automation testing project yet, you can refer selenide-junit5-allure-example to try creating your own.
Access Token
- Go to GitHub Personal Access Tokens and generate a new token
- Make sure you select both
repo
andworkflow
access scope
Workflow File
Create
.github/workflows/example.yml
at root project├── .github │ └── workflows │ └── example.yml ├── gradle ├── src/test ├── build.gradle ├── gradle.properties ├── gradlew ├── gradlew.bat └── settings.gradle
Workflow
GitHub Docs: Actions
GitHub Marketplace: Actions to improve your workflow
Names
# The name of your workflow. # GitHub displays the names of your workflows on your repository's actions page. # If you omit this field, GitHub sets the name to the workflow's filename. name: Multiple browsers and platforms workflow # The name for workflow runs generated from the workflow. # GitHub displays the workflow run name in the list of workflow runs on your repository's 'Actions' tab. run-name: Build and Test
Events
on: # Runs your workflow when someone pushes to a repository branch, # which triggers the push event. push: # Configure this workflow to run # when someone pushed to 'github-actions' branch. branches: - github-actions
Jobs
Now we declare a specified job, in our case we named
build_and_test
.# A workflow run is made up of one or more jobs. # Jobs run in parallel by default. jobs: # You can name it as you like. build_and_test:
Settings
jobs: build_and_test: # A map of default settings # that will apply to all steps in this job. defaults: run: shell: bash
Strategy
A strategy creates a build matrix for your jobs. You can define different variations of an environment to run each job in.
jobs: build_and_test: strategy: # The maximum number of jobs that can run simultaneously # when using a matrix job strategy. max-parallel: 2 # Set of different configurations of # the virtual environment for this build matrix. matrix: os: [macos-latest, windows-latest] browser: [safari, edge, chrome, firefox] java_version: [17] # Remove specific configurations defined in the matrix. exclude: - os: macos-latest browser: chrome - os: macos-latest browser: firefox - os: windows-latest browser: safari - os: windows-latest browser: edge
Runner
The type of machine to run the job on. The machine can be either a GitHub-hosted runner, or a self-hosted runner.
We expect GitHub-hosted runner which selected atjobs.build_and_test.strategy.matrix.os
.
jobs: build_and_test: runs-on: ${{ matrix.os }}
Name
Set name of this job displayed on GitHub.
The name will be likedmacos-latest_safari_17
by pattern{os}_{browser}_{java_version}
.
jobs: build_and_test: name: ${{ join(matrix.*, '_') }}
Env
A map of environment variables that are available to all steps in the job.
jobs: build_and_test: env: MATRIX_JOB_NAME: ${{ join(matrix.*, '_') }}
Steps
A job contains a sequence of tasks called steps. Steps can run commands, run setup tasks, or run an action.
- Checkout your repository
jobs: build_and_test: steps: - name: "[Prepare] Checkout" uses: actions/checkout@v4
- Setup JDK
jobs: build_and_test: steps: - name: "[Prepare] Setup JDK 17" uses: actions/setup-java@v4 with: distribution: temurin java-version: ${{ matrix.java_version }}
- Execute the test
jobs: build_and_test: steps: - name: "[Test] Execute" id: test_execution run: | ./gradlew clean test --tests ExampleTest $VM_ARGS allureReport env: VM_ARGS: -Dselenide.browser=${{ matrix.browser }}
- Publish JUnit XML
jobs: build_and_test: steps: # Always run even if the previous step fails. - if: success() || failure() name: "[Report] JUnit report" uses: mikepenz/action-junit-report@v4 with: check_name: JUnit ${{ env.MATRIX_JOB_NAME }} report_paths: build/reports/test/TEST-*.xml
- Upload Gradle test result
jobs: build_and_test: steps: # Run only when 'test_execution' step has failed. - if: steps.test_execution.conclusion == 'failure' name: "[Artifact] Gradle result" uses: actions/upload-artifact@v4 with: name: report-gradle-${{ env.MATRIX_JOB_NAME }} path: build/reports/tests/test
- Upload Allure report
jobs: build_and_test: steps: # Always run even if the previous step fails. - if: always() name: "[Artifact] Allure report" uses: actions/upload-artifact@v4 with: name: report-allure-${{ env.MATRIX_JOB_NAME }} path: build/allure/allureReport
Now you can modify somewhere in your project, and push it to repository.
Actions
Workflows
Jobs
Job Details
Recapitulation
Here is full workflow which you can refer or reuse!
ngoanh2n/selenide-junit5-allure-example/.github/workflows/example.yml