CI/CD and tools
GitHub Actions
Workflows, jobs, triggers, secrets and artifacts.
Learn: GitHub Actions for test automation: workflows, triggers, secrets and artifacts8 minute read
GitHub Actions is the CI service built into GitHub (CI means a server runs your build and tests automatically): YAML files in the repository (YAML is a simple text format that uses indentation) describe which jobs run when something happens, such as a push or a pull request. Many teams have moved their test pipelines there from Jenkins, so interviewers ask you to read or write a workflow file (the YAML file that describes the automation) and explain triggers, jobs, secrets and reports. This article walks through a real workflow that passes actionlint, a checker for workflow files.
Where workflows live and how they are built
Each workflow is a YAML file in .github/workflows/. Its main keys:
onlists the events (triggers) that start it:push,pull_request,schedule,workflow_dispatch(manual) and many more.jobsholds one or more jobs. Each runs on a fresh runner, a new temporary computer chosen withruns-on(for exampleubuntu-latest). Jobs run in parallel unlessneedsorders them.stepsrun in order on that job's runner. A step eitherusesa ready-made action (a reusable step written by someone else) orruns shell commands.
A Python UI test workflow
name: ui-tests
on:
push:
branches: [main]
pull_request:
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.11", "3.12"]
steps:
- uses: actions/checkout@v7
- uses: actions/setup-python@v7
with:
python-version: ${{ matrix.python-version }}
- run: pip install -r requirements.txt
- run: pytest -n 4 --junitxml=report.xml
env:
TEST_PASSWORD: ${{ secrets.TEST_PASSWORD }}
- uses: actions/upload-artifact@v7
if: always()
with:
name: report-${{ matrix.python-version }}
path: report.xml
What happens on a push to main:
- The matrix (a list of values to try) creates two jobs, one per Python version, running in parallel. By default
fail-fastis true: if one matrix job fails, GitHub cancels the others still running. Setfail-fast: falseto see every result. actions/checkoutfetches the code andactions/setup-pythoninstalls Python. A fresh runner has none of your packages, sopip installmust come first.- The test step gets the password from a secret, as an environment variable. Secrets are stored encrypted, masked in logs and never in the repository.
- Steps after a failed step are normally skipped.
if: always()makes the upload run anyway, so the report exists exactly when tests fail. An artifact is a file that a run saves so you can download it later. Artifact names must be unique within a run, which is why the name includes the Python version.
For Java, actions/setup-java with distribution: temurin, java-version: "21" and cache: maven prepares the JDK and caches dependencies, and the test step runs mvn -B test.
Schedules and manual runs
on:
schedule:
- cron: "30 1 * * *"
workflow_dispatch:
inputs:
groups:
description: TestNG groups to run
type: choice
options: [smoke, regression]
default: smoke
A schedule uses cron, a standard way to write times (the five fields are minute, hour, day of month, month and day of week; the Jenkins topic explains them). Scheduled workflows run on the latest commit of the default branch (usually main) and use UTC, the world time standard, by default, so 30 1 * * * is 07:00 in India. Runs can start late when GitHub Actions is busy, and the shortest interval is every five minutes. workflow_dispatch adds a "Run workflow" button with inputs, GitHub's version of Jenkins parameters, read as ${{ inputs.groups }}. On other events the input is empty, so a fallback such as ${{ inputs.groups || 'smoke' }} keeps the command valid.
Ordering jobs with needs
A common shape is a build job, then api-tests and ui-tests in parallel (both needs: build), then a report job with needs: [api-tests, ui-tests] and if: always(). If a job fails, the jobs that need it are skipped unless they have such a condition.
Secrets and other settings
Secrets cannot be used directly in if: conditions, so put them in an environment variable and test that. Workflows started by pull requests from forks (copies of the repository made by other people) do not receive repository secrets (only a read-only GITHUB_TOKEN, a temporary key that GitHub creates for each run), so tests that need secrets fail there by design. Environments such as staging can hold their own secrets and require approval. timeout-minutes on a job stops runs that never end (the default is 360 minutes), and jobs that must reach internal systems can run on self-hosted runners, which are your own machines inside your network instead of GitHub's.
How to answer in an interview
Read a workflow aloud from the top: the triggers, the jobs and their runners, each step, where secrets come from, and what happens to the report when tests fail. When asked about moving from Jenkins, map the parts: webhooks to on: push and pull_request, cron to schedule (in UTC), parameters to workflow_dispatch inputs, credentials to secrets, and junit plus archiveArtifacts to artifact uploads.
Common mistakes
- Uploading reports without
if: always(), so they vanish when tests fail. - Forgetting that schedules use UTC.
- Expecting jobs to share files; use artifacts to pass them.
- Writing a password in the YAML instead of a secret.
Recap
A workflow lists triggers in on, jobs that run on fresh runners, and steps that use actions or run commands. A matrix multiplies jobs, needs orders them, secrets arrive as environment variables, and if: always() keeps reports when tests fail.
11 questions0/11 solved
| Status | Question | Difficulty | Asked in |
|---|---|---|---|
| Not started | Where do GitHub Actions workflow files live? | Easy | |
| Not started | The parts of a GitHub Actions workflow | Easy | |
| Pro+ | Where does the test password go in GitHub Actions? | Easy-Medium | |
| Pro+ | Read the workflow: how many test jobs run? | Easy-Medium | |
| Pro+ | Read the workflow: is the report uploaded after failures? | Easy-Medium | |
| Pro+ | Read the workflow: when does the nightly run start? | Medium | |
| Pro+ | Read the workflow: start it by hand with a choice | Medium | |
| Pro+ | Read the workflow: in what order do the jobs run? | Medium | |
| Pro+ | Why do tests fail only on pull requests from forks? | Medium-Hard | |
| Pro+ | Move a test pipeline from Jenkins to GitHub Actions | Medium-Hard | |
| Pro+ | Manage test environments and keep secrets out of test code | Medium |
The first 2 questions of each topic are free. Pro+ opens every question.