Awesome-claude-skills github-actions

GitHub Actions for CI/CD workflows. Use for automated testing, building, and deployment pipelines.

install
source · Clone the upstream repo
git clone https://github.com/itsnex1s/awesome-claude-skills
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/itsnex1s/awesome-claude-skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/github-actions" ~/.claude/skills/itsnex1s-awesome-claude-skills-github-actions && rm -rf "$T"
manifest: skills/github-actions/SKILL.md
source content

github-actions

GitHub Actions for CI/CD - automated testing, building, and deployment.

Workflow Basics

Location

.github/workflows/
├── ci.yml
├── deploy.yml
└── release.yml

Basic Structure

name: CI

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
      - run: npm ci
      - run: npm run build
      - run: npm test

Triggers

Push/PR

on:
  push:
    branches: [main, develop]
    paths:
      - 'src/**'
      - 'package.json'
    paths-ignore:
      - '**.md'
      - 'docs/**'
  pull_request:
    branches: [main]
    types: [opened, synchronize, reopened]

Schedule (Cron)

on:
  schedule:
    - cron: '0 0 * * *'  # Daily at midnight UTC

Manual

on:
  workflow_dispatch:
    inputs:
      environment:
        description: 'Deploy environment'
        required: true
        default: 'staging'
        type: choice
        options:
          - staging
          - production

Release

on:
  release:
    types: [published]

Common Workflows

CI (Test + Build)

name: CI

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: '20'
          cache: 'npm'

      - run: npm ci
      - run: npm run lint
      - run: npm run test:coverage

      - uses: actions/upload-artifact@v4
        with:
          name: coverage
          path: coverage/

  build:
    runs-on: ubuntu-latest
    needs: test
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'

      - run: npm ci
      - run: npm run build

      - uses: actions/upload-artifact@v4
        with:
          name: build
          path: dist/

Deploy to Vercel

name: Deploy

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'

      - run: npm ci
      - run: npm run build

      - uses: amondnet/vercel-action@v25
        with:
          vercel-token: ${{ secrets.VERCEL_TOKEN }}
          vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
          vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
          vercel-args: '--prod'

Docker Build & Push

name: Docker

on:
  push:
    branches: [main]
    tags: ['v*']

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - uses: docker/metadata-action@v5
        id: meta
        with:
          images: ghcr.io/${{ github.repository }}
          tags: |
            type=ref,event=branch
            type=semver,pattern={{version}}
            type=sha

      - uses: docker/build-push-action@v5
        with:
          context: .
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}

E2E Tests with Playwright

name: E2E

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  e2e:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'

      - run: npm ci
      - run: npx playwright install --with-deps

      - run: npm run test:e2e

      - uses: actions/upload-artifact@v4
        if: failure()
        with:
          name: playwright-report
          path: playwright-report/

Release with Changelog

name: Release

on:
  push:
    tags: ['v*']

jobs:
  release:
    runs-on: ubuntu-latest
    permissions:
      contents: write
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Generate changelog
        id: changelog
        uses: orhun/git-cliff-action@v3
        with:
          args: --latest --strip header

      - uses: softprops/action-gh-release@v1
        with:
          body: ${{ steps.changelog.outputs.content }}
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Matrix Builds

jobs:
  test:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]
        node: [18, 20, 22]
      fail-fast: false
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node }}
      - run: npm ci
      - run: npm test

Secrets & Variables

Using Secrets

env:
  DATABASE_URL: ${{ secrets.DATABASE_URL }}
  API_KEY: ${{ secrets.API_KEY }}

steps:
  - run: echo "Deploying to ${{ vars.ENVIRONMENT }}"

Setting via CLI

gh secret set API_KEY --body "secret-value"
gh secret list
gh variable set ENVIRONMENT --body "production"

Caching

npm

- uses: actions/setup-node@v4
  with:
    node-version: '20'
    cache: 'npm'

pnpm

- uses: pnpm/action-setup@v2
  with:
    version: 8
- uses: actions/setup-node@v4
  with:
    node-version: '20'
    cache: 'pnpm'

Custom Cache

- uses: actions/cache@v4
  with:
    path: |
      ~/.npm
      node_modules
    key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
    restore-keys: |
      ${{ runner.os }}-node-

Conditions

steps:
  - run: npm run deploy
    if: github.ref == 'refs/heads/main'

  - run: npm run test
    if: github.event_name == 'pull_request'

  - run: npm run notify
    if: always()  # Run even if previous steps failed

  - run: npm run cleanup
    if: failure()  # Run only if previous steps failed

  - run: npm run report
    if: success()  # Run only if all previous steps succeeded

Outputs & Artifacts

Job Outputs

jobs:
  build:
    outputs:
      version: ${{ steps.version.outputs.version }}
    steps:
      - id: version
        run: echo "version=$(cat package.json | jq -r .version)" >> $GITHUB_OUTPUT

  deploy:
    needs: build
    steps:
      - run: echo "Deploying version ${{ needs.build.outputs.version }}"

Upload/Download Artifacts

# Upload
- uses: actions/upload-artifact@v4
  with:
    name: build-output
    path: dist/
    retention-days: 7

# Download
- uses: actions/download-artifact@v4
  with:
    name: build-output
    path: dist/

Environment Protection

jobs:
  deploy:
    runs-on: ubuntu-latest
    environment:
      name: production
      url: https://myapp.com
    steps:
      - run: npm run deploy

Reusable Workflows

Define (.github/workflows/reusable-build.yml)

name: Reusable Build

on:
  workflow_call:
    inputs:
      node-version:
        required: false
        type: string
        default: '20'
    secrets:
      NPM_TOKEN:
        required: false

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ inputs.node-version }}
      - run: npm ci
      - run: npm run build

Use

jobs:
  build:
    uses: ./.github/workflows/reusable-build.yml
    with:
      node-version: '20'
    secrets:
      NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

Useful Actions

ActionPurpose
actions/checkout@v4
Clone repo
actions/setup-node@v4
Setup Node.js
actions/cache@v4
Cache dependencies
actions/upload-artifact@v4
Upload files
actions/download-artifact@v4
Download files
docker/build-push-action@v5
Build & push Docker
softprops/action-gh-release@v1
Create GitHub release
peaceiris/actions-gh-pages@v4
Deploy to GitHub Pages

Debugging

steps:
  - run: echo "${{ toJson(github) }}"  # Print context

  - run: npm run build
    env:
      ACTIONS_STEP_DEBUG: true  # Enable debug logging

Re-run with Debug

gh run rerun <run-id> --debug

Best Practices

  1. Use specific action versions (
    @v4
    not
    @main
    )
  2. Cache dependencies for faster builds
  3. Use matrix for cross-platform testing
  4. Protect secrets with environments
  5. Fail fast in PRs, retry in main
  6. Use reusable workflows to reduce duplication
  7. Set timeouts to prevent hanging jobs