Day 5 of 5

Secrets, Caching, and Optimization

Slow pipelines kill developer velocity. Today you will store secrets safely, cache dependencies between runs, and use concurrency controls to avoid wasted compute.

yaml
# Secrets — set in GitHub Settings → Secrets and Variables
      - name: Use a secret
        run: echo "API key length: ${#API_KEY}"
        env:
          API_KEY: ${{ secrets.MY_API_KEY }}

# Never print secrets — GitHub masks them but avoid it anyway
yaml
# Caching node_modules
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'   # built-in cache by setup-node

# Manual cache (for tools not covered by setup-*)
      - uses: actions/cache@v4
        with:
          path: ~/.cache/pip
          key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
          restore-keys: |
            ${{ runner.os }}-pip-
yaml
# Concurrency — cancel stale runs on same PR
concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

# Conditional steps — skip deploy on forks
      - name: Deploy
        if: github.repository == 'yourname/repo' && github.ref == 'refs/heads/main'
        run: ./deploy.sh

# Reusable workflow — call from another workflow
jobs:
  call-test:
    uses: ./.github/workflows/test.yml
    with:
      node-version: '20'
    secrets: inherit

Exercise: Optimize Your Pipeline

  1. Measure current pipeline time in the Actions tab
  2. Add cache: npm to setup-node and check time savings
  3. Add concurrency: group to cancel stale PR runs
  4. Move secrets to GitHub Environments (not repo-level)
  5. Split a slow job into parallel jobs using needs:

Day 5 Summary

Finished this lesson?