A GitHub Actions workflow is a YAML file in .github/workflows/ that defines when automation runs (on: triggers), what runs (jobs), and how each step works — either calling a reusable action (uses:) or running a shell command (run:).
The on: key defines triggers: push, pull_request, schedule (cron), workflow_dispatch (manual), and others. Each job specifies a runs-on runner and a list of steps. A step is one of two things: uses: invokes a pre-built, versioned action from the marketplace (e.g. actions/checkout@v4 to clone the repo, actions/setup-node@v4 to install Node), while run: executes shell commands directly. Because runners start empty, almost every workflow begins by checking out the code and setting up the language runtime. Understanding this structure lets a QA engineer read, review and modify pipelines confidently rather than treating CI as a black box owned by DevOps.
A QA engineer wants tests to run on every PR and also every night. They add on: [pull_request] plus on: schedule with a cron of '0 2 * * *', so the suite guards PRs during the day and runs a fuller nightly pass at 2 AM — all in one readable YAML file they authored themselves without waiting on DevOps.
# .github/workflows/test.yml
name: test
on:
pull_request:
push:
branches: [main]
schedule:
- cron: '0 2 * * *' # nightly at 02:00 UTC
workflow_dispatch: {} # manual 'Run workflow' button
jobs:
unit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4 # reusable action
- uses: actions/setup-node@v4
with: { node-version: 20, cache: 'npm' }
- run: npm ci # shell command
- run: npm testScenario: You're asked to make the test workflow run on every pull request, on merges to main, and be manually triggerable for hotfix verification — without duplicating the job. How do you structure the triggers?
workflow_dispatch is the cheapest way to give QA a manual 'run the suite now' button — great for verifying hotfixes or flaky reruns.