Skip to main content
JobCannon
All skills

GitHub Actions (Advanced CI/CD)

Automate workflows: build, test, deploy via YAML

⬢ TIER 3Tools
+$15k-
Salary impact
4 months
Time to learn
Medium
Difficulty
8
Careers
TL;DR

GitHub Actions is GitHub-native CI/CD: define build/test/deploy workflows in YAML, trigger on push/PR/schedule, scale from free public minutes to self-hosted enterprise runners. Career path: Practitioner (basic workflows, $110-145k) → Advanced (matrix builds, caching, secrets, deployment, $145-190k) → Expert (custom actions, OIDC federation, monorepo patterns, $180-240k) over 3-5 months. Every workflow is parallelizable, supports 20+ languages out of the box, integrates GitHub's native OIDC for keyless cloud auth. Competes with Jenkins, GitLab CI, CircleCI, Harness.

What is GitHub Actions (Advanced CI/CD)

GitHub Actions is CI/CD built into GitHub. Automate testing, deployment, releases. Free for public repos, essential for modern development. L1: Basic workflows (build, test on PR)

🔧 TOOLS & ECOSYSTEM
GitHub Actions (core)Reusable workflowsComposite actionsGitHub Enterprise Server (GHES) self-hosted runnersGitHub OIDC (OpenID Connect)GitHub Appsactions/checkoutactions/cacheMatrix buildsGitHub Container Registry (GHCR)DependabotCodeQL (SAST)RenovateAct (local testing)Rhysd actionlint

💰 Salary by region

RegionJuniorMidSenior
USA$110k$155k$210k
UK£65k£90k£135k
EU€70k€100k€145k
CANADAC$115kC$160kC$220k

❓ FAQ

Self-hosted vs GitHub-hosted runners — when do I choose each?
GitHub-hosted: fast setup, free 2k-3k min/month per account, 10min job limit, fresh ephemeral VMs each run, ideal for public repos + OSS. Cost: $0.008/min Linux, $0.016/min Windows, $0.016/min macOS. Self-hosted: zero incremental cost after setup, no minute limits, persistent caches, supports custom hardware (GPU/ARM), firewall isolation, compliance. Use GitHub-hosted for small teams/public. Self-hosted for 10k+min/month, private infrastructure, GPU workloads, or compliance. Hybrid: use both — GitHub for quick CI, self-hosted for slow builds.
OIDC federation — why not long-lived secrets for cloud auth?
OIDC (OpenID Connect) makes GitHub issue short-lived tokens that your cloud provider (AWS/Azure/GCP) trusts without storing credentials in GitHub. Actions/aws-actions@aws-actions/configure-aws-credentials with OIDC trades your AWS access key for a temporary STS token. Eliminates: (1) secret rotation burden, (2) key sprawl in GitHub (3) accidental exposure (the token is only good for 1 action run). AWS costs ~$0.02/OIDC call — negligible. GCP/Azure support OIDC too. Always use OIDC for cloud access; secrets only for 3rd-party APIs (Slack, npm, Docker Hub).
Reusable workflows vs composite actions — what's the pattern?
Reusable workflows: orchestrate multiple jobs (run in parallel), define inputs/secrets/outputs, trigger external repos. Example: /.github/workflows/deploy-reusable.yml → called via 'uses' in another workflow. Can call other reusable workflows (chaining). Composite actions: single job, sequential steps, small utils (build, lint, test, notify). Composite is lighter. Use: reusable workflows for complex multi-job logic (deploy-staging, deploy-prod, smoke-test flow); composite for single-responsibility helpers (setup-node-cache, post-results-to-slack). Reusable is newer (2021), composite is older. Both avoid copy-paste across repos.
How do I optimize CI costs on GitHub Actions?
Three levers: (1) Runner efficiency: use matrix to parallelize, cache deps (actions/cache saves 30-60% time), use smaller runners (2-core Linux is $0.008/min vs 4-core). (2) Job pruning: skip CI on doc-only changes ([skip ci], skip-ci: true in commit), cancel in-flight jobs on new push (concurrency groups). (3) Runner type: self-hosted if you run >10k min/month (ROI ~1-2mo for $5k hardware). (4) Conditional steps: only run heavy jobs on main or on PR review. Benchmarked: monorepo with 8 parallel matrix jobs + caching = ~2min, cost = $0.016. Same without caching = 8min, cost = $0.064.
Monorepo CI patterns — how do I avoid testing everything on every commit?
Use path filters + change detection: (1) paths: [services/api/**, services/web/**] in on.push = only trigger if those dirs changed. (2) tj-actions/changed-files output = list changed files in workflow, skip jobs if only docs/changelog changed. (3) turbo --filter=[packages/...] = only rebuild touched packages + dependents. Composite pattern: one base workflow with change detection → calls conditional reusable workflows for api-test, web-test, etc. Monorepo worst case: 50 packages, fire all 50 tests on one-line change = 30min waste. With filters + turbo: fire only affected (3-5 packages) = 5min. ~6x speedup.
Third-party action risks — how do I vet and secure them?
Danger: supply chain attacks (malicious action steals secrets), bloat (action with 100MB of junk deps), abandonment (unmaintained, no security patches). Vetting: (1) use official actions (actions/*, github/*, aws-actions/*, azure/*). (2) pin to commit hash (uses: foo/bar@a1b2c3d), NOT @v1 tag (tag can be force-pushed). (3) audit action source on GitHub (check stars, recent commits, typos in name). (4) use Dependabot (version-updates: allow-list for approved actions). (5) enable CodeQL on your repo + audit your action's deps. Red flags: no README, 0 stars, typo-squatting (actions/checkout vs actions/check0ut). Safe: stick to official GitHub org + well-known projects (peter-evans/*, crazy-max/*). Best: write your own composite for internal logic.
How do I debug failing actions locally before pushing?
Act (local GitHub Actions runner) simulates the GitHub runner on your machine. Install act, run 'act push' in repo root = runs all on.push workflows locally. Limitations: Act uses Docker, so nested containers fail; secrets must be set in .actrc (not synced); can't perfectly match GitHub's Ubuntu version. For quick feedback: use Act. For final verification: push to branch, watch Actions tab. Act saves 10-15 min per debugging cycle (no push overhead). Also: add workflow_dispatch to workflow.yml = manual trigger button in GitHub web UI = fast iteration without commits.
What languages work best in GitHub Actions? Any to avoid?
Node.js / TypeScript (fastest cold start, best ecosystem of pre-built actions), Python (clear logic, great for scripting), Bash (simple, no deps). All 20+ languages work via docker:// images. Avoid: Java (slow startup, mem-heavy for CI), C++ (compilation time). Actions themselves should be JavaScript (node_modules cached) or Bash — compiled languages slow down every action invocation. Use containers (docker://) if you need compiled runtime (Go, Rust). JavaScript actions popular because actions/ ecosystem is all JS.
When should I push secret rotation to GitHub Actions? Any gotchas?
GitHub Actions secrets are encrypted at rest, scoped per repo/org, masked in logs (can't see them in action output even if leaked). But: (1) if GitHub is breached, secrets are at risk. (2) Dependabot can see secrets only if explicitly enabled per job. (3) Fork PRs do NOT get secrets (security feature, but breaks forked contributor workflows). Better: store secrets in vault (AWS Secrets Manager, HashiCorp Vault, 1Password), fetch at runtime via OIDC. Rotate: GitHub doesn't auto-rotate; you must manually update if a service key is revoked. OIDC removes this burden (no key to rotate, cloud provider issues new token each run).

Not sure this skill is for you?

Take a 10-min Career Match — we'll suggest the right tracks.

Find my best-fit skills →

Find your ideal career path

Skill-based matching across 2,536 careers. Free, ~10 minutes.

Take Career Match — free →