Agent skill

github-actions

Stars 0
Forks 0

Install this agent skill to your Project

npx add-skill https://github.com/jaredlander/freshbooks-speed/tree/main/.claude/skills/github-actions

SKILL.md

GitHub Actions Workflow Expert

Purpose

Expert GitHub Actions workflow creation and editing. Use when asked to (1) create or modify GitHub Actions workflows (.github/workflows/*.yml), (2) set up CI/CD pipelines, (3) configure automated testing, deployment, or release workflows, (4) troubleshoot workflow syntax or behavior, (5) implement workflow best practices, or when phrases like "GitHub Actions", "CI/CD pipeline", "workflow", "automated deployment", "continuous integration" appear.

Core Principles

1. Workflow Structure

  • Place workflows in .github/workflows/ directory
  • Use clear, descriptive workflow names
  • Organize complex workflows with reusable components
  • Leverage workflow_call for DRY patterns
  • Keep workflows focused and single-purpose when possible

2. Trigger Configuration

yaml
# Common trigger patterns
on:
  push:
    branches: [main, develop]
    paths:
      - 'src/**'
      - '!docs/**'  # Exclude paths
  pull_request:
    branches: [main]
    types: [opened, synchronize, reopened]
  workflow_dispatch:  # Manual trigger
    inputs:
      environment:
        description: 'Deployment environment'
        required: true
        type: choice
        options: [dev, staging, prod]
  schedule:
    - cron: '0 2 * * *'  # Daily at 2 AM UTC
  workflow_call:  # Reusable workflow
    inputs:
      config-path:
        required: true
        type: string
    secrets:
      token:
        required: true

3. Environment and Secrets

yaml
env:
  # Workflow-level environment variables
  NODE_VERSION: '20'
  CACHE_KEY_PREFIX: 'npm-cache'

jobs:
  deploy:
    environment:
      name: production
      url: https://example.com
    env:
      # Job-level environment variables
      DEPLOYMENT_REGION: us-east-1
    steps:
      - name: Deploy
        env:
          # Step-level environment variables (highest precedence)
          API_KEY: ${{ secrets.API_KEY }}
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}  # Auto-provided

Secret Management:

  • Use repository/organization/environment secrets
  • Never hardcode sensitive values
  • Reference with ${{ secrets.SECRET_NAME }}
  • GITHUB_TOKEN is automatically available
  • Use environments for deployment protection rules

Job Configuration Best Practices

Concurrency Control

yaml
concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true  # Cancel old runs on new push

Matrix Strategies

yaml
strategy:
  fail-fast: false  # Continue other jobs if one fails
  matrix:
    os: [ubuntu-latest, windows-latest, macos-latest]
    node-version: [18, 20, 22]
    include:
      - os: ubuntu-latest
        node-version: 20
        coverage: true
    exclude:
      - os: macos-latest
        node-version: 18

Conditional Execution

yaml
jobs:
  test:
    if: github.event_name == 'pull_request'
    steps:
      - name: Run tests
        if: success() || failure()  # Run even if previous step failed
      
      - name: Deploy
        if: github.ref == 'refs/heads/main' && github.event_name == 'push'

Common Workflow Patterns

Node.js CI/CD

yaml
name: Node.js CI

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

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [18, 20, 22]
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
          cache: 'npm'
      
      - name: Install dependencies
        run: npm ci
      
      - name: Run linter
        run: npm run lint
      
      - name: Run tests
        run: npm test
      
      - name: Upload coverage
        if: matrix.node-version == '20'
        uses: codecov/codecov-action@v4
        with:
          token: ${{ secrets.CODECOV_TOKEN }}

Docker Build and Push

yaml
name: Docker Build

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

env:
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ github.repository }}

jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write
    steps:
      - uses: actions/checkout@v4
      
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3
      
      - name: Log in to registry
        uses: docker/login-action@v3
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}
      
      - name: Extract metadata
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
          tags: |
            type=ref,event=branch
            type=ref,event=pr
            type=semver,pattern={{version}}
            type=semver,pattern={{major}}.{{minor}}
      
      - name: Build and push
        uses: docker/build-push-action@v5
        with:
          context: .
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
          cache-from: type=gha
          cache-to: type=gha,mode=max

R Package CI

yaml
name: R-CMD-check

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

jobs:
  check:
    runs-on: ${{ matrix.config.os }}
    strategy:
      fail-fast: false
      matrix:
        config:
          - {os: ubuntu-latest, r: 'release'}
          - {os: ubuntu-latest, r: 'devel'}
          - {os: macos-latest, r: 'release'}
          - {os: windows-latest, r: 'release'}
    steps:
      - uses: actions/checkout@v4
      
      - uses: r-lib/actions/setup-r@v2
        with:
          r-version: ${{ matrix.config.r }}
          use-public-rspm: true
      
      - uses: r-lib/actions/setup-r-dependencies@v2
        with:
          extra-packages: any::rcmdcheck
          needs: check
      
      - uses: r-lib/actions/check-r-package@v2
        with:
          upload-snapshots: true

Deployment with Environments

yaml
name: Deploy

on:
  push:
    branches: [main]

jobs:
  deploy-staging:
    runs-on: ubuntu-latest
    environment:
      name: staging
      url: https://staging.example.com
    steps:
      - uses: actions/checkout@v4
      - name: Deploy to staging
        run: ./deploy.sh staging
        env:
          DEPLOY_KEY: ${{ secrets.STAGING_DEPLOY_KEY }}
  
  deploy-production:
    needs: deploy-staging
    runs-on: ubuntu-latest
    environment:
      name: production
      url: https://example.com
    steps:
      - uses: actions/checkout@v4
      - name: Deploy to production
        run: ./deploy.sh production
        env:
          DEPLOY_KEY: ${{ secrets.PRODUCTION_DEPLOY_KEY }}

Reusable Workflow

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

on:
  workflow_call:
    inputs:
      node-version:
        required: false
        type: string
        default: '20'
      coverage:
        required: false
        type: boolean
        default: false
    secrets:
      codecov-token:
        required: false

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ inputs.node-version }}
          cache: 'npm'
      - run: npm ci
      - run: npm test
      - name: Upload coverage
        if: inputs.coverage
        uses: codecov/codecov-action@v4
        with:
          token: ${{ secrets.codecov-token }}

# Usage in another workflow:
# jobs:
#   test:
#     uses: ./.github/workflows/reusable-test.yml
#     with:
#       node-version: '22'
#       coverage: true
#     secrets:
#       codecov-token: ${{ secrets.CODECOV_TOKEN }}

Advanced Features

Caching Strategies

yaml
- name: Cache dependencies
  uses: actions/cache@v4
  with:
    path: |
      ~/.npm
      ~/.cache/pip
      vendor/bundle
    key: ${{ runner.os }}-deps-${{ hashFiles('**/package-lock.json', '**/requirements.txt') }}
    restore-keys: |
      ${{ runner.os }}-deps-

# Action-specific caching (preferred when available)
- uses: actions/setup-node@v4
  with:
    cache: 'npm'  # Handles caching automatically

- uses: actions/setup-python@v5
  with:
    cache: 'pip'

Artifacts and Outputs

yaml
jobs:
  build:
    runs-on: ubuntu-latest
    outputs:
      version: ${{ steps.version.outputs.version }}
    steps:
      - name: Get version
        id: version
        run: echo "version=$(cat VERSION)" >> $GITHUB_OUTPUT
      
      - name: Upload build artifacts
        uses: actions/upload-artifact@v4
        with:
          name: build-artifacts
          path: |
            dist/
            build/
          retention-days: 7

  deploy:
    needs: build
    runs-on: ubuntu-latest
    steps:
      - name: Download artifacts
        uses: actions/download-artifact@v4
        with:
          name: build-artifacts
      
      - name: Deploy version
        run: echo "Deploying ${{ needs.build.outputs.version }}"

Composite Actions (Custom Actions)

yaml
# .github/actions/setup-environment/action.yml
name: 'Setup Environment'
description: 'Setup common environment for all jobs'
inputs:
  node-version:
    description: 'Node.js version'
    required: false
    default: '20'
runs:
  using: 'composite'
  steps:
    - uses: actions/setup-node@v4
      with:
        node-version: ${{ inputs.node-version }}
        cache: 'npm'
    - run: npm ci
      shell: bash
    - run: npm run build
      shell: bash

# Usage:
# - uses: ./.github/actions/setup-environment
#   with:
#     node-version: '22'

Matrix with Dynamic Values

yaml
jobs:
  prepare:
    runs-on: ubuntu-latest
    outputs:
      matrix: ${{ steps.set-matrix.outputs.matrix }}
    steps:
      - id: set-matrix
        run: |
          # Generate matrix dynamically
          echo "matrix={\"include\":[{\"env\":\"dev\"},{\"env\":\"staging\"}]}" >> $GITHUB_OUTPUT
  
  deploy:
    needs: prepare
    strategy:
      matrix: ${{ fromJSON(needs.prepare.outputs.matrix) }}
    runs-on: ubuntu-latest
    steps:
      - run: echo "Deploying to ${{ matrix.env }}"

Security Best Practices

1. Permission Management

yaml
# Workflow-level (most restrictive)
permissions:
  contents: read
  pull-requests: write

jobs:
  job-with-specific-perms:
    permissions:
      contents: write
      packages: write

2. Pull Request Security

yaml
# Use pull_request_target carefully - it has write access
on:
  pull_request:  # Safer for external contributions
    types: [opened, synchronize]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      # Don't check out untrusted code directly
      - uses: actions/checkout@v4
        with:
          ref: ${{ github.event.pull_request.head.sha }}

3. Script Injection Prevention

yaml
# BAD: Script injection vulnerability
- run: echo "Hello ${{ github.event.issue.title }}"

# GOOD: Use environment variables
- run: echo "Hello $TITLE"
  env:
    TITLE: ${{ github.event.issue.title }}

4. Third-Party Actions

yaml
# Pin to specific SHA for security
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11  # v4.1.1

# Or use tags with verification
- uses: actions/checkout@v4

Performance Optimization

1. Reduce Checkout Time

yaml
- uses: actions/checkout@v4
  with:
    fetch-depth: 1  # Shallow clone
    sparse-checkout: |  # Only checkout needed paths
      src/
      tests/

2. Parallel Jobs

yaml
jobs:
  lint:
    runs-on: ubuntu-latest
    steps: [...]
  
  test:
    runs-on: ubuntu-latest
    steps: [...]
  
  build:
    needs: [lint, test]  # Only run after both complete
    runs-on: ubuntu-latest
    steps: [...]

3. Self-Hosted Runners

yaml
jobs:
  build:
    runs-on: [self-hosted, linux, x64, gpu]
    steps: [...]

Debugging and Troubleshooting

Enable Debug Logging

yaml
# Set repository secrets:
# ACTIONS_STEP_DEBUG: true
# ACTIONS_RUNNER_DEBUG: true

# Or in workflow:
- name: Debug step
  run: |
    echo "::debug::This is a debug message"
    echo "::warning::This is a warning"
    echo "::error::This is an error"

Job Summaries

yaml
- name: Generate summary
  run: |
    echo "### Test Results :rocket:" >> $GITHUB_STEP_SUMMARY
    echo "" >> $GITHUB_STEP_SUMMARY
    echo "- Tests passed: 42" >> $GITHUB_STEP_SUMMARY
    echo "- Coverage: 87%" >> $GITHUB_STEP_SUMMARY

Annotations

yaml
- name: Create annotation
  run: |
    echo "::notice file=app.js,line=1,col=5::This is a notice"
    echo "::warning file=app.js,line=10::This is a warning"
    echo "::error file=app.js,line=20,col=15::This is an error"

Common Context Variables

yaml
# GitHub context
${{ github.repository }}         # owner/repo
${{ github.ref }}                # refs/heads/main
${{ github.sha }}                # commit SHA
${{ github.actor }}              # user who triggered
${{ github.event_name }}         # push, pull_request, etc.
${{ github.run_id }}             # unique run ID
${{ github.run_number }}         # sequential run number

# Runner context
${{ runner.os }}                 # Linux, Windows, macOS
${{ runner.arch }}               # X64, ARM64
${{ runner.temp }}               # temp directory path

# Job context
${{ job.status }}                # success, failure, cancelled

# Steps context
${{ steps.step_id.outputs.name }}

# Needs context (from dependent jobs)
${{ needs.build.outputs.version }}

# Environment files
echo "KEY=value" >> $GITHUB_ENV
echo "name=value" >> $GITHUB_OUTPUT
echo "/custom/path" >> $GITHUB_PATH

Testing Workflows Locally

Use act for local testing:

bash
# Install act
brew install act  # macOS
# or download from https://github.com/nektos/act

# Run workflow
act push
act pull_request
act -j test  # Run specific job

# Use specific event
act -e event.json

Anti-Patterns to Avoid

  1. Don't hardcode secrets: Always use ${{ secrets.NAME }}
  2. Don't use if: always() without thought: Can mask real failures
  3. Don't mix concerns: Keep workflows focused on single purposes
  4. Avoid deep nesting: Use reusable workflows or composite actions
  5. Don't ignore caching: Speeds up workflows significantly
  6. Avoid checkout@v1: Always use latest stable versions
  7. Don't run untrusted code in pull_request_target without sandboxing

Workflow Templates

Claude Code should offer to create complete, working workflows based on common patterns:

  • CI for multiple languages (Node.js, Python, Go, Rust, R, etc.)
  • Docker build and push to registries (GitHub, Docker Hub, AWS ECR)
  • Deployment workflows (staging/production with approval)
  • Release automation (semantic versioning, changelog generation)
  • Scheduled tasks (cleanup, backups, reports)
  • Monorepo workflows with path filtering

Output Format

When creating workflows:

  1. Generate complete, runnable YAML files
  2. Include comments explaining complex sections
  3. Suggest relevant repository settings (branch protection, environments)
  4. Provide example secret configuration instructions
  5. Mention any required repository permissions

When editing workflows:

  1. Preserve existing structure and comments
  2. Explain changes made
  3. Highlight potential breaking changes
  4. Suggest testing approach (act, workflow_dispatch)

Integration Points

  • Posit Products: Deploy R Shiny apps, build R packages, publish to Posit Connect
  • Docker: Build and push containers with proper caching
  • R/Python: Matrix testing across versions, dependency caching
  • Ansible: Deploy infrastructure, run playbooks with secrets
  • Kubernetes: Deploy with kubectl, Helm, or Kustomize
  • AWS/Azure/GCP: Deploy to cloud platforms with OIDC authentication

Resources

Expand your agent's capabilities with these related and highly-rated skills.

jaredlander/freshbooks-speed

unit-testing

Write comprehensive unit tests for code. Use when asked to (1) write tests for new or existing code, (2) add unit tests, (3) test a function/module/class, (4) verify code still works after changes, (5) create test coverage, or when phrases like "write tests", "add tests", "test this", "make sure this works" appear. Supports Python, JavaScript, R, Rust, Go, C++, SQL, Bash, Ansible, Kubernetes/Kustomize, Docker, and Docker Compose.

0 0
Explore
jaredlander/freshbooks-speed

javascript-react

Expert-level JavaScript and React development. Use when asked to (1) write JavaScript code requiring advanced patterns like closures, proxies, generators, or async iterators, (2) build React applications with hooks, context, suspense, or server components, (3) optimize JavaScript/React performance, (4) implement complex state management, (5) write TypeScript with advanced type patterns, or when phrases like "React component", "JavaScript function", "TypeScript", "hooks", "state management", "frontend", "web app" appear.

0 0
Explore
jaredlander/freshbooks-speed

code-review

Review code written by Claude Code or humans across multiple languages. Use when asked to review, audit, critique, or analyze code quality. Supports R, Python, JavaScript, SQL, C++, Rust, Go, Ansible, Kustomize/Kubernetes, Dockerfiles, Docker Compose, and Bash. Covers correctness, security, performance, testing, documentation, and architecture. Produces actionable output for Claude Code to fix issues plus human-readable REVIEW.md summaries.

0 0
Explore
jaredlander/freshbooks-speed

html

Write semantic, accessible, performant HTML with modern best practices. Use when asked to (1) create HTML pages or documents, (2) write semantic markup, (3) improve accessibility, (4) optimize HTML structure and performance, (5) implement forms, tables, or complex layouts, or when phrases like "HTML page", "web page", "markup", "semantic HTML", "accessibility" appear.

0 0
Explore
jaredlander/freshbooks-speed

css

Expert-level CSS development with modern features and best practices. Use when asked to (1) write or debug CSS, (2) implement layouts with flexbox, grid, or container queries, (3) create animations and transitions, (4) optimize CSS performance, (5) work with CSS preprocessors or CSS-in-JS, (6) implement responsive design, or when phrases like "style", "CSS", "stylesheet", "design", "layout", "animation" appear.

0 0
Explore
jaredlander/freshbooks-speed

javascript-ember

Expert-level Ember.js development. Use when asked to (1) write Ember.js applications with components, services, routes, or controllers, (2) implement Ember Data models and adapters, (3) work with Ember Octane patterns (Glimmer components, tracked properties, modifiers), (4) optimize Ember application performance, (5) write Ember tests with QUnit or testing-library, or when phrases like "Ember component", "Ember route", "Glimmer", "tracked property", "Ember addon" appear.

0 0
Explore

Didn't find tool you were looking for?

Be as detailed as possible for better results