Back to Skills

github-workflows

vinnie357
Updated 3 days ago
23 views
0
View on GitHub
Designautomation

About

This skill helps developers create, configure, and optimize GitHub Actions workflows. Use it when writing YAML files to define triggers, jobs, steps, and CI/CD pipelines. It covers syntax, expressions, contexts, and best practices for debugging and performance.

Quick Install

Claude Code

Recommended
Plugin CommandRecommended
/plugin add https://github.com/vinnie357/claude-skills
Git CloneAlternative
git clone https://github.com/vinnie357/claude-skills.git ~/.claude/skills/github-workflows

Copy and paste this command in Claude Code to install this skill

Documentation

GitHub Workflows

Activate when creating, modifying, debugging, or optimizing GitHub Actions workflow files. This skill covers workflow syntax, structure, best practices, and common CI/CD patterns.

When to Use This Skill

Activate when:

  • Writing .github/workflows/*.yml files
  • Configuring workflow triggers and events
  • Defining jobs, steps, and dependencies
  • Using expressions and contexts
  • Managing secrets and environment variables
  • Implementing CI/CD pipelines
  • Optimizing workflow performance
  • Debugging workflow failures

Workflow File Structure

Basic Anatomy

name: CI                              # Workflow name (optional)

on:                                   # Trigger events
  push:
    branches: [main, develop]
  pull_request:

env:                                  # Global environment variables
  NODE_VERSION: '20'

jobs:                                 # Job definitions
  build:
    name: Build and Test            # Job name (optional)
    runs-on: ubuntu-latest          # Runner environment

    steps:
      - name: Checkout code         # Step name (optional)
        uses: actions/checkout@v4   # Use an action

      - name: Run tests
        run: npm test               # Run command

File Location

Workflows must be in .github/workflows/ directory:

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

Trigger Events (on:)

Push Events

on:
  push:
    branches:
      - main
      - 'release/**'        # Glob patterns
    tags:
      - 'v*'                # Version tags
    paths:
      - 'src/**'            # Only when these paths change
      - '!docs/**'          # Ignore docs changes

Pull Request Events

on:
  pull_request:
    types:
      - opened
      - synchronize       # New commits pushed
      - reopened
    branches:
      - main
    paths-ignore:
      - '**.md'

Schedule (Cron)

on:
  schedule:
    # Every day at 2am UTC
    - cron: '0 2 * * *'
    # Every Monday at 9am UTC
    - cron: '0 9 * * 1'

Manual Trigger (workflow_dispatch)

on:
  workflow_dispatch:
    inputs:
      environment:
        description: 'Deployment environment'
        required: true
        type: choice
        options:
          - development
          - staging
          - production
      debug:
        description: 'Enable debug logging'
        required: false
        type: boolean
        default: false

Multiple Events

on:
  push:
    branches: [main]
  pull_request:
  workflow_dispatch:
  schedule:
    - cron: '0 0 * * 0'  # Weekly

Jobs

Basic Job Configuration

jobs:
  build:
    name: Build Application
    runs-on: ubuntu-latest
    timeout-minutes: 30

    steps:
      - uses: actions/checkout@v4
      - run: npm ci
      - run: npm run build

Runner Selection

jobs:
  test:
    runs-on: ubuntu-latest        # Ubuntu (fastest, most common)

  test-macos:
    runs-on: macos-latest         # macOS

  test-windows:
    runs-on: windows-latest       # Windows

  test-specific:
    runs-on: ubuntu-22.04         # Specific version

Matrix Strategy

jobs:
  test:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]
        node: [18, 20, 21]
        exclude:
          - os: macos-latest
            node: 18
      fail-fast: false            # Continue on failure
      max-parallel: 4             # Concurrent jobs limit

    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node }}
      - run: npm test

Job Dependencies

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - run: npm run build

  test:
    needs: build                  # Wait for build
    runs-on: ubuntu-latest
    steps:
      - run: npm test

  deploy:
    needs: [build, test]          # Wait for multiple jobs
    runs-on: ubuntu-latest
    steps:
      - run: npm run deploy

Conditional Execution

jobs:
  deploy:
    if: github.ref == 'refs/heads/main' && github.event_name == 'push'
    runs-on: ubuntu-latest
    steps:
      - run: npm run deploy

  notify:
    if: failure()                 # Run only if previous jobs failed
    needs: [build, test]
    runs-on: ubuntu-latest
    steps:
      - run: echo "Build failed"

Steps

Using Actions

steps:
  - name: Checkout repository
    uses: actions/checkout@v4
    with:
      fetch-depth: 0              # Full history
      submodules: recursive       # Include submodules

  - name: Setup Node.js
    uses: actions/setup-node@v4
    with:
      node-version: '20'
      cache: 'npm'

Running Commands

steps:
  - name: Single command
    run: npm install

  - name: Multi-line script
    run: |
      echo "Installing dependencies"
      npm ci
      npm run build

  - name: Shell selection
    shell: bash
    run: echo "Using bash"

Conditional Steps

steps:
  - name: Run on main branch only
    if: github.ref == 'refs/heads/main'
    run: npm run deploy

  - name: Run on PR only
    if: github.event_name == 'pull_request'
    run: npm run test:pr

Continue on Error

steps:
  - name: Lint (optional)
    continue-on-error: true
    run: npm run lint

  - name: Test (required)
    run: npm test

Environment Variables and Secrets

Global Variables

env:
  NODE_ENV: production
  API_URL: https://api.example.com

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - run: echo $NODE_ENV

Job-Level Variables

jobs:
  build:
    env:
      BUILD_TYPE: release
    steps:
      - run: echo $BUILD_TYPE

Step-Level Variables

steps:
  - name: Configure
    env:
      CONFIG_PATH: ./config.json
    run: cat $CONFIG_PATH

Using Secrets

steps:
  - name: Deploy
    env:
      API_KEY: ${{ secrets.API_KEY }}
      DB_PASSWORD: ${{ secrets.DB_PASSWORD }}
    run: ./deploy.sh

Setting Variables Between Steps

steps:
  - name: Set version
    id: version
    run: echo "VERSION=$(cat version.txt)" >> $GITHUB_OUTPUT

  - name: Use version
    run: echo "Version is ${{ steps.version.outputs.VERSION }}"

Contexts

github Context

steps:
  - name: Context information
    run: |
      echo "Repository: ${{ github.repository }}"
      echo "Branch: ${{ github.ref_name }}"
      echo "SHA: ${{ github.sha }}"
      echo "Actor: ${{ github.actor }}"
      echo "Event: ${{ github.event_name }}"
      echo "Run ID: ${{ github.run_id }}"

env Context

env:
  MY_VAR: value

steps:
  - run: echo "${{ env.MY_VAR }}"

job Context

steps:
  - name: Job status
    if: job.status == 'success'
    run: echo "Job succeeded"

steps Context

steps:
  - id: first-step
    run: echo "output=hello" >> $GITHUB_OUTPUT

  - run: echo "${{ steps.first-step.outputs.output }}"

runner Context

steps:
  - run: |
      echo "OS: ${{ runner.os }}"
      echo "Arch: ${{ runner.arch }}"
      echo "Temp: ${{ runner.temp }}"

matrix Context

strategy:
  matrix:
    version: [18, 20]

steps:
  - run: echo "Node ${{ matrix.version }}"

Expressions

Operators

steps:
  # Comparison
  - if: github.ref == 'refs/heads/main'

  # Logical
  - if: github.event_name == 'push' && github.ref == 'refs/heads/main'
  - if: github.event_name == 'pull_request' || github.event_name == 'push'

  # Negation
  - if: "!cancelled()"

  # Contains
  - if: contains(github.event.head_commit.message, '[skip ci]')

  # StartsWith/EndsWith
  - if: startsWith(github.ref, 'refs/tags/v')
  - if: endsWith(github.ref, '-beta')

Functions

steps:
  # Status functions
  - if: success()        # Previous steps succeeded
  - if: failure()        # Any previous step failed
  - if: always()         # Always run
  - if: cancelled()      # Workflow cancelled

  # String functions
  - run: echo "${{ format('Hello {0}', github.actor) }}"
  - if: contains(github.event.pull_request.labels.*.name, 'deploy')

  # JSON functions
  - run: echo '${{ toJSON(github.event) }}'
  - run: echo '${{ fromJSON(env.CONFIG).database.host }}'

  # Hash function
  - run: echo "${{ hashFiles('**/package-lock.json') }}"

Artifacts

Upload Artifacts

steps:
  - name: Build
    run: npm run build

  - name: Upload artifacts
    uses: actions/upload-artifact@v4
    with:
      name: build-files
      path: |
        dist/
        build/
      retention-days: 7
      if-no-files-found: error

Download Artifacts

jobs:
  build:
    steps:
      - run: npm run build
      - uses: actions/upload-artifact@v4
        with:
          name: dist
          path: dist/

  test:
    needs: build
    steps:
      - uses: actions/download-artifact@v4
        with:
          name: dist
          path: dist/
      - run: npm test

Caching

npm Cache

steps:
  - uses: actions/checkout@v4
  - uses: actions/setup-node@v4
    with:
      node-version: '20'
      cache: 'npm'
  - run: npm ci

Manual Cache

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

Permissions

Repository Token Permissions

permissions:
  contents: read              # Repository content
  pull-requests: write        # PR comments
  issues: write              # Issue creation/comments
  checks: write              # Check runs
  statuses: write            # Commit statuses
  deployments: write         # Deployments
  packages: write            # Package registry

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

Job-Level Permissions

jobs:
  build:
    permissions:
      contents: read
      pull-requests: write
    steps:
      - uses: actions/checkout@v4

Concurrency

Prevent Concurrent Runs

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true    # Cancel running workflows

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - run: ./deploy.sh

Job-Level Concurrency

jobs:
  deploy:
    concurrency:
      group: deploy-${{ github.ref }}
      cancel-in-progress: false
    steps:
      - run: ./deploy.sh

Reusable Workflows

Define Reusable Workflow

# .github/workflows/reusable-test.yml
name: Reusable Test Workflow

on:
  workflow_call:
    inputs:
      node-version:
        required: true
        type: string
      coverage:
        required: false
        type: boolean
        default: false
    outputs:
      test-result:
        description: "Test execution result"
        value: ${{ jobs.test.outputs.result }}
    secrets:
      token:
        required: true

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

Call Reusable Workflow

jobs:
  test:
    uses: ./.github/workflows/reusable-test.yml
    with:
      node-version: '20'
      coverage: true
    secrets:
      token: ${{ secrets.GITHUB_TOKEN }}

Common CI/CD Patterns

Node.js CI

name: Node.js CI

on:
  push:
    branches: [main]
  pull_request:

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [18, 20, 21]

    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
          cache: 'npm'
      - run: npm ci
      - run: npm run lint
      - run: npm test
      - run: npm run build

Docker Build and Push

name: Docker

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

jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write

    steps:
      - uses: actions/checkout@v4

      - name: Login to GitHub Container Registry
        uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

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

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

Deploy on Release

name: Deploy

on:
  release:
    types: [published]

jobs:
  deploy:
    runs-on: ubuntu-latest
    environment:
      name: production
      url: https://example.com

    steps:
      - uses: actions/checkout@v4
      - name: Deploy to production
        env:
          DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }}
        run: ./deploy.sh

Monorepo with Path Filtering

name: Monorepo CI

on:
  pull_request:
    paths:
      - 'packages/**'

jobs:
  detect-changes:
    runs-on: ubuntu-latest
    outputs:
      frontend: ${{ steps.filter.outputs.frontend }}
      backend: ${{ steps.filter.outputs.backend }}
    steps:
      - uses: actions/checkout@v4
      - uses: dorny/paths-filter@v3
        id: filter
        with:
          filters: |
            frontend:
              - 'packages/frontend/**'
            backend:
              - 'packages/backend/**'

  test-frontend:
    needs: detect-changes
    if: needs.detect-changes.outputs.frontend == 'true'
    runs-on: ubuntu-latest
    steps:
      - run: npm test --workspace=frontend

  test-backend:
    needs: detect-changes
    if: needs.detect-changes.outputs.backend == 'true'
    runs-on: ubuntu-latest
    steps:
      - run: npm test --workspace=backend

Debugging Workflows

Enable Debug Logging

Set repository secrets:

  • ACTIONS_RUNNER_DEBUG: true
  • ACTIONS_STEP_DEBUG: true

Debug Steps

steps:
  - name: Debug context
    run: |
      echo "Event: ${{ github.event_name }}"
      echo "Ref: ${{ github.ref }}"
      echo "SHA: ${{ github.sha }}"
      echo "Actor: ${{ github.actor }}"

  - name: Dump GitHub context
    run: echo '${{ toJSON(github) }}'

  - name: Dump runner context
    run: echo '${{ toJSON(runner) }}'

Tmate Debugging

steps:
  - name: Setup tmate session
    if: failure()
    uses: mxschmitt/action-tmate@v3
    timeout-minutes: 30

Performance Optimization

Use Caching

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

Optimize Checkout

- uses: actions/checkout@v4
  with:
    fetch-depth: 1              # Shallow clone
    sparse-checkout: |          # Partial checkout
      src/
      tests/

Concurrent Jobs

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - run: npm run lint

  test:
    runs-on: ubuntu-latest
    steps:
      - run: npm test

  build:
    needs: [lint, test]         # Parallel lint and test
    runs-on: ubuntu-latest
    steps:
      - run: npm run build

Anti-Fabrication Requirements

  • Execute Read tool to verify workflow files exist before claiming structure
  • Use Bash with gh workflow list to confirm actual workflow names before referencing them
  • Execute gh workflow view <workflow> to verify trigger configuration before documenting it
  • Use Glob to find actual workflow files before claiming their presence
  • Execute gh run list to verify actual workflow runs before discussing execution patterns
  • Never claim workflow success rates without actual run history analysis
  • Validate YAML syntax using yamllint or similar tools via Bash before claiming correctness
  • Report actual permission errors from workflow runs, not fabricated authorization issues
  • Execute actual cache operations before claiming cache hit/miss percentages
  • Use Read tool on action.yml files to verify action inputs/outputs before documenting usage

GitHub Repository

vinnie357/claude-skills
Path: github/skills/workflows

Related Skills

sglang

Meta

SGLang is a high-performance LLM serving framework that specializes in fast, structured generation for JSON, regex, and agentic workflows using its RadixAttention prefix caching. It delivers significantly faster inference, especially for tasks with repeated prefixes, making it ideal for complex, structured outputs and multi-turn conversations. Choose SGLang over alternatives like vLLM when you need constrained decoding or are building applications with extensive prefix sharing.

View skill

content-collections

Meta

This skill provides a production-tested setup for Content Collections, a TypeScript-first tool that transforms Markdown/MDX files into type-safe data collections with Zod validation. Use it when building blogs, documentation sites, or content-heavy Vite + React applications to ensure type safety and automatic content validation. It covers everything from Vite plugin configuration and MDX compilation to deployment optimization and schema validation.

View skill

Algorithmic Art Generation

Meta

This skill helps developers create algorithmic art using p5.js, focusing on generative art, computational aesthetics, and interactive visualizations. It automatically activates for topics like "generative art" or "p5.js visualization" and guides you through creating unique algorithms with features like seeded randomness, flow fields, and particle systems. Use it when you need to build reproducible, code-driven artistic patterns.

View skill

business-rule-documentation

Meta

This skill provides standardized templates for systematically documenting business logic and domain knowledge following Domain-Driven Design principles. It helps developers capture business rules, process flows, decision trees, and terminology glossaries to maintain consistency between requirements and implementation. Use it when documenting domain models, creating business rule repositories, or bridging communication between business and technical teams.

View skill