By Fatskills Exam Guides Team — the exam nerds behind 28,500+ quizzes and 2.1M practice questions across 500+ global exams.
Your hyper-practical guide to automating workflows, deployments, and tests—without the fluff.
GitHub Actions is GitHub’s built-in CI/CD (Continuous Integration/Continuous Deployment) engine. It lets you define automated workflows in YAML files that run when events happen in your repo (e.g., a git push, a pull request, or a scheduled cron job).
git push
You’re a DevOps engineer at a startup. Your team merges 20+ pull requests daily. Without GitHub Actions: - A developer pushes broken code → production crashes → customers complain → you scramble to roll back.- A security vulnerability slips through → you get hacked → compliance fines.
With GitHub Actions: - Every git push runs unit tests → if tests fail, the PR can’t merge.- Every merge to main auto-deploys to staging → QA tests before production.- Every night, a scheduled job runs security scans → vulnerabilities are caught early.
main
Superpower: You ship code faster, safer, and with less manual work.
.github/workflows/*.yml
.github/workflows/
push
pull_request
schedule
needs: job1
run: npm test
continue-on-error: true
actions/checkout@v4
@v4
staging
production
AWS_ACCESS_KEY_ID
${{ secrets.MY_SECRET }}
node: [14, 16, 18]
Goal: Create a workflow that: 1. Runs on every push to main.2. Installs dependencies.3. Runs tests.4. Uploads test results as an artifact.
.github/workflows/ci.yml
name: CI Pipeline on: push: branches: [ "main" ] pull_request: branches: [ "main" ] jobs: test: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: Set up Node.js uses: actions/setup-node@v4 with: node-version: 20 - name: Install dependencies run: npm install - name: Run tests run: npm test - name: Upload test results uses: actions/upload-artifact@v3 if: always() # Upload even if tests fail with: name: test-results path: test-results/
git add .github/workflows/ci.yml git commit -m "Add CI pipeline" git push
Add this to your README.md to show CI status:
README.md

permissions:
contents: read
actions/cache@v3
@latest
if: always()
name:
description:
echo "::debug::Debug message"
needs:
❌ push (triggers on commits, not PRs)
"How do you run a job only if another job succeeds?"
❌ depends_on: job1 (not valid in GitHub Actions)
depends_on: job1
"Where do you store secrets for a workflow?"
❌ In the YAML file (security risk)
"How do you cache Node.js dependencies?"
path: node_modules
npm install
on: push
on: pull_request
pull_request: Runs only when a PR is opened/updated (saves minutes).
runs-on: ubuntu-latest vs self-hosted runners
runs-on: ubuntu-latest
Challenge: Modify your CI pipeline to: 1. Run tests on Node.js 18 and 20 (matrix strategy).2. Upload test results as an artifact only if tests fail.
Solution:
jobs: test: strategy: matrix: node-version: [18, 20] runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} - run: npm install - run: npm test - uses: actions/upload-artifact@v3 if: failure() # Only upload if tests fail with: name: test-results-node-${{ matrix.node-version }} path: test-results/
Why It Works:- matrix runs the job for each Node.js version.- if: failure() ensures artifacts are uploaded only on test failures.
matrix
if: failure()
job1
strategy.matrix
node-version: [18, 20]
env:
env: NODE_ENV: test
Start small. Automate one thing (e.g., tests on PRs). Then expand (e.g., deploy to staging on merge). GitHub Actions scales with your needs—no need to over-engineer Day 1. ?
Join 4M+ learners. Unlock unlimited quizzes, wrong-answer tracking, flashcards + reminders, study guides, and 1-on-1 challenges.