GitHub Actions
The de facto standard for CI/CD in NZ. Define your pipelines as YAML, automate your tests on every push, and deploy with confidence.
1 The Hook — The Midnight Manual Deployment
A developer in Auckland had to stay up until midnight to manually run a full regression suite and deploy a critical hotfix to their production server. Exhausted, they accidentally skipped one important test file. The hotfix passed the other tests but broke the checkout page for 20% of users. The company lost thousands in sales before the mistake was noticed the next morning.
GitHub Actions prevents this. By defining your tests in a workflow, they run automatically on every single commit. No one has to stay up late, no one has to remember which tests to run, and no code is deployed unless every single test is green. Automation is your 24/7 quality guard.
2 The Rule — Automate Everything
If a task is performed more than once, it should be a workflow. No manual deployments; no manual test runs.
From linting your code to running E2E tests and deploying to AWS, every step of your development lifecycle should be codified in a YAML file and triggered automatically.
Senior engineer insight
The biggest shift in how I think about GitHub Actions is treating the workflow file as a first-class deliverable — not a config file someone hacked together in an afternoon. On a Wellington-based SaaS project we inherited from a previous team, every PR was taking 22 minutes to pass CI. When we finally read the workflow carefully, we found Playwright browsers being reinstalled from scratch on every run, and the full E2E suite firing on documentation-only changes. Splitting into targeted jobs with path filters cut that to under 6 minutes and made developers actually wait for CI instead of force-merging.
The most common mistake: writing one enormous job that runs every check sequentially, then wondering why CI takes 30 minutes and teams start bypassing it.
From the field
A team at a NZ government digital services agency assumed their GitHub Actions workflows were production-ready because they'd been passing green for months. Then a dependency update landed and CI stayed green — but the deployment step was silently using a cached build artifact from three days earlier. The newly introduced vulnerability shipped to production while every check said "passed". The root cause: they'd never configured if: always() on their artifact upload step, and the cache key hadn't been invalidated. After the incident, they rebuilt the pipeline with explicit cache busting on every dependency change and added a deployment verification step that confirmed the artifact SHA matched the triggering commit. The lesson that generalises: a green tick only means "the workflow ran without error" — it does not mean "the right code got deployed".
3 The Analogy — The Factory Assembly Line
The Assembly Line.
Building software is like building a car. In a modern factory, the car moves down an assembly line. At one station, it's painted; at the next, the engine is added; at the final station, a robot tests the brakes. If the brakes fail, the line stops, and the car never leaves the factory. GitHub Actions is that assembly line for your code.
4 Watch Me Do It — A Playwright CI Workflow
Scenario: Automatically running Playwright tests every time code is pushed to the main branch or a Pull Request is opened.
name: Playwright Tests
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 18
cache: 'npm' # THE RULE: Always cache dependencies
- name: Install dependencies
run: npm ci
- name: Install Playwright Browsers
run: npx playwright install --with-deps
- name: Run Playwright tests
run: npx playwright test
- uses: actions/upload-artifact@v4
if: always() # Upload report even if tests fail
with:
name: playwright-report
path: playwright-report/
5 Decision Tool — Why GitHub Actions?
✅ Choose GitHub Actions for...
- Projects already hosted on GitHub
- Fast setup with zero server management
- Deep integration with Pull Requests
- Using pre-built community "Actions"
❌ Choose Others for...
- GitLab CI: If your code is on GitLab
- Jenkins: If you need extreme customization on-premise
- Azure Pipelines: If you're deep in the Azure ecosystem
6 Common Mistakes
🚫 Hardcoding Secrets
Don't: run: my-tool --api-key 12345-abc
Do: Use GitHub Secrets and reference them: run: my-tool --api-key ${{ secrets.MY_API_KEY }}. This keeps keys out of your logs and code.
🚫 Not Caching Dependencies
Don't: Re-download 500MB of node_modules on every run.
Do: Use cache: 'npm' in setup-node. This can cut your workflow time in half.
7 Now You Try — Setup
In your local repository, create a directory called .github/workflows/ and inside it, create a file named main.yml. Paste the Playwright example above into it, commit, and push. Then, navigate to the "Actions" tab on your GitHub repository to watch it run live!
Why teams fail here
- Secrets sprawl: API keys and environment credentials end up duplicated across a dozen workflow files instead of centralised in GitHub Secrets or an environment — so when a key rotates, half the workflows break silently.
- No matrix strategy for browser/OS coverage: Teams run E2E tests on
ubuntu-latestonly, then get Chromium-passes-Safari-fails production bugs that a matrix build across two browsers would have caught in minutes. - Flaky tests masked by re-run-on-failure: Adding
retry: 3to hide intermittent failures instead of fixing them means the test suite loses all diagnostic value — a real regression gets buried in noise and the team stops trusting CI. - No artifact retention strategy: Test reports, screenshots, and traces are uploaded on failure but never on success — so when a test degrades gradually over 20 builds (rather than fails suddenly), there's no historical record to diff against.
Key takeaway
A CI pipeline that developers route around because it's slow, noisy, or untrustworthy isn't a safety net — it's a bureaucratic tax; the job of a QA engineer is to make automation so fast and reliable that bypassing it never crosses anyone's mind.
8 Self-Check
Q1. What is a "Runner" in GitHub Actions?
A virtual machine (Ubuntu, Windows, or macOS) that GitHub spins up to execute the steps in your workflow. It's destroyed immediately after the job finishes.
Q2. Can I run multiple jobs at the same time?
Yes. By default, jobs in a workflow run in parallel. If you want Job B to wait for Job A (e.g., Deploy only after Test passes), you use the needs: [jobA] property.
9 Interview Prep
"What are the benefits of CI/CD for a testing team?"
Answer: "CI/CD ensures short feedback loops. Instead of waiting days for a manual regression report, developers know within minutes if their change broke a test. It also provides a single source of truth for quality; if the build is green, we know the code meets our automated standards. Finally, it eliminates 'human error' during deployments, making the whole process more predictable and reliable."
10 Next Step
Workflows need a consistent environment to run in. Let's look at the tool that ensures your code runs exactly the same on your laptop as it does in CI: Docker.