Back to Skills

github-actions

sgcarstrends
Updated Today
20 views
9
1
9
View on GitHub
Metaaitestingautomation

About

This skill enables developers to create and maintain GitHub Actions workflows for CI/CD, testing, deployment, and automation. It helps set up pipelines, automate tasks like builds and releases, and configure continuous integration processes. The skill provides capabilities for reading, editing, and writing workflow files to streamline development operations.

Documentation

GitHub Actions Skill

This skill helps you create and maintain GitHub Actions workflows for continuous integration and deployment.

When to Use This Skill

  • Setting up CI/CD pipelines
  • Automating tests and builds
  • Configuring deployment workflows
  • Creating release automation
  • Running scheduled jobs
  • Automating dependency updates
  • Setting up code quality checks

Workflow Structure

.github/
├── workflows/
│   ├── test.yml              # Run tests on PR/push
│   ├── deploy-staging.yml    # Deploy to staging
│   ├── deploy-prod.yml       # Deploy to production
│   ├── release.yml           # Create releases
│   ├── security.yml          # Security audits
│   └── cron-jobs.yml         # Scheduled tasks
├── actions/
│   └── setup/                # Reusable actions
│       └── action.yml
└── dependabot.yml            # Dependency updates

Basic Workflow

Test Workflow

# .github/workflows/test.yml
name: Test

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

jobs:
  test:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Setup pnpm
        uses: pnpm/action-setup@v2

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

      - name: Install dependencies
        run: pnpm install

      - name: Run linter
        run: pnpm biome check .

      - name: Type check
        run: pnpm tsc --noEmit

      - name: Run tests
        run: pnpm test

      - name: Upload coverage
        uses: codecov/codecov-action@v3
        with:
          files: ./coverage/lcov.info

Deployment Workflows

Deploy to Staging

# .github/workflows/deploy-staging.yml
name: Deploy to Staging

on:
  push:
    branches: [develop]
  workflow_dispatch:

jobs:
  deploy:
    runs-on: ubuntu-latest
    environment:
      name: staging
      url: https://staging.sgcarstrends.com

    steps:
      - uses: actions/checkout@v4
      - uses: pnpm/action-setup@v2
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: "pnpm"

      - name: Install dependencies
        run: pnpm install

      - name: Run tests
        run: pnpm test

      - name: Build
        run: pnpm build

      - name: Deploy API
        run: pnpm -F @sgcarstrends/api deploy:staging
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

      - name: Deploy Web
        run: pnpm -F @sgcarstrends/web deploy:staging
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

      - name: Run migrations
        run: pnpm db:migrate
        env:
          DATABASE_URL: ${{ secrets.STAGING_DATABASE_URL }}

      - name: Notify Slack
        if: always()
        uses: slackapi/slack-github-action@v1
        with:
          webhook-url: ${{ secrets.SLACK_WEBHOOK_URL }}
          payload: |
            {
              "text": "Staging deployment ${{ job.status }}"
            }

Deploy to Production

# .github/workflows/deploy-prod.yml
name: Deploy to Production

on:
  push:
    branches: [main]
  workflow_dispatch:
    inputs:
      confirm:
        description: "Type 'deploy' to confirm"
        required: true

jobs:
  confirm:
    if: github.event_name == 'workflow_dispatch'
    runs-on: ubuntu-latest
    steps:
      - name: Confirm deployment
        run: |
          if [ "${{ github.event.inputs.confirm }}" != "deploy" ]; then
            echo "Deployment not confirmed"
            exit 1
          fi

  deploy:
    needs: [confirm]
    if: always() && (needs.confirm.result == 'success' || github.event_name == 'push')
    runs-on: ubuntu-latest
    environment:
      name: production
      url: https://sgcarstrends.com

    steps:
      - uses: actions/checkout@v4
      - uses: pnpm/action-setup@v2
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: "pnpm"

      - name: Install dependencies
        run: pnpm install

      - name: Run tests
        run: pnpm test

      - name: Run security audit
        run: pnpm audit --audit-level=high

      - name: Build
        run: pnpm build

      - name: Deploy API
        run: pnpm -F @sgcarstrends/api deploy:prod
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

      - name: Deploy Web
        run: pnpm -F @sgcarstrends/web deploy:prod
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

      - name: Run migrations
        run: pnpm db:migrate
        env:
          DATABASE_URL: ${{ secrets.PRODUCTION_DATABASE_URL }}

      - name: Create deployment
        uses: chrnorm/deployment-action@v2
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
          environment: production
          state: success

      - name: Notify team
        if: always()
        uses: slackapi/slack-github-action@v1
        with:
          webhook-url: ${{ secrets.SLACK_WEBHOOK_URL }}
          payload: |
            {
              "text": "🚀 Production deployment ${{ job.status }}",
              "blocks": [
                {
                  "type": "section",
                  "text": {
                    "type": "mrkdwn",
                    "text": "*Production Deployment*\nStatus: ${{ job.status }}\nCommit: ${{ github.sha }}\nAuthor: ${{ github.actor }}"
                  }
                }
              ]
            }

Release Workflow

Automated Release

# .github/workflows/release.yml
name: Release

on:
  push:
    branches: [main]

permissions:
  contents: write
  issues: write
  pull-requests: write

jobs:
  release:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
          persist-credentials: false

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

      - name: Install dependencies
        run: pnpm install

      - name: Release
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
        run: npx semantic-release

      - name: Get new version
        id: version
        run: |
          VERSION=$(node -p "require('./package.json').version")
          echo "version=$VERSION" >> $GITHUB_OUTPUT

      - name: Create GitHub Release
        uses: actions/create-release@v1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          tag_name: v${{ steps.version.outputs.version }}
          release_name: Release v${{ steps.version.outputs.version }}
          draft: false
          prerelease: false

Reusable Workflows

Shared Setup Action

# .github/actions/setup/action.yml
name: "Setup Project"
description: "Setup Node.js, pnpm, and install dependencies"

inputs:
  node-version:
    description: "Node.js version"
    required: false
    default: "20"

runs:
  using: "composite"
  steps:
    - name: Setup pnpm
      uses: pnpm/action-setup@v2
      with:
        version: 8

    - name: Setup Node.js
      uses: actions/setup-node@v4
      with:
        node-version: ${{ inputs.node-version }}
        cache: "pnpm"

    - name: Install dependencies
      shell: bash
      run: pnpm install --frozen-lockfile

    - name: Cache Turbo
      uses: actions/cache@v3
      with:
        path: .turbo
        key: ${{ runner.os }}-turbo-${{ github.sha }}
        restore-keys: |
          ${{ runner.os }}-turbo-

Use Reusable Workflow

# .github/workflows/test.yml
name: Test

on: [push, pull_request]

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

      - name: Setup project
        uses: ./.github/actions/setup

      - name: Run tests
        run: pnpm test

Matrix Strategy

Test Multiple Versions

name: Test Matrix

on: [push, pull_request]

jobs:
  test:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest, macos-latest]
        node: [18, 20, 21]
        exclude:
          - os: windows-latest
            node: 18

    steps:
      - uses: actions/checkout@v4
      - uses: pnpm/action-setup@v2
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node }}
          cache: "pnpm"

      - run: pnpm install
      - run: pnpm test

Conditional Execution

Run Jobs Conditionally

name: Deploy

on:
  push:
    branches: [main]

jobs:
  deploy-api:
    if: contains(github.event.head_commit.message, '[deploy-api]')
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: pnpm -F @sgcarstrends/api deploy:prod

  deploy-web:
    if: contains(github.event.head_commit.message, '[deploy-web]')
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: pnpm -F @sgcarstrends/web deploy:prod

  deploy-all:
    if: |
      !contains(github.event.head_commit.message, '[deploy-api]') &&
      !contains(github.event.head_commit.message, '[deploy-web]')
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: pnpm deploy:prod

Caching

Cache Dependencies

- name: Cache pnpm store
  uses: actions/cache@v3
  with:
    path: ~/.pnpm-store
    key: ${{ runner.os }}-pnpm-${{ hashFiles('**/pnpm-lock.yaml') }}
    restore-keys: |
      ${{ runner.os }}-pnpm-

- name: Cache Turbo
  uses: actions/cache@v3
  with:
    path: .turbo
    key: ${{ runner.os }}-turbo-${{ github.sha }}
    restore-keys: |
      ${{ runner.os }}-turbo-

- name: Cache Next.js
  uses: actions/cache@v3
  with:
    path: apps/web/.next/cache
    key: ${{ runner.os }}-nextjs-${{ hashFiles('**/pnpm-lock.yaml') }}

Secrets Management

Using Secrets

- name: Deploy
  env:
    AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
    AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
    DATABASE_URL: ${{ secrets.DATABASE_URL }}
    REDIS_URL: ${{ secrets.REDIS_URL }}
  run: pnpm deploy:prod

Environment-Specific Secrets

jobs:
  deploy:
    environment: production
    steps:
      - name: Deploy
        env:
          DATABASE_URL: ${{ secrets.PRODUCTION_DATABASE_URL }}
        run: pnpm deploy:prod

Scheduled Workflows

Cron Jobs

# .github/workflows/cron-jobs.yml
name: Scheduled Jobs

on:
  schedule:
    # Run every day at 2 AM UTC
    - cron: "0 2 * * *"
  workflow_dispatch:

jobs:
  update-data:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: ./.github/actions/setup

      - name: Update car data
        run: pnpm -F @sgcarstrends/api run-workflow update-car-data
        env:
          DATABASE_URL: ${{ secrets.DATABASE_URL }}
          LTA_API_KEY: ${{ secrets.LTA_API_KEY }}

  cleanup:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: ./.github/actions/setup

      - name: Clean old data
        run: pnpm -F @sgcarstrends/api run-script cleanup-old-data
        env:
          DATABASE_URL: ${{ secrets.DATABASE_URL }}

Notifications

Slack Notifications

- name: Notify Slack on success
  if: success()
  uses: slackapi/slack-github-action@v1
  with:
    webhook-url: ${{ secrets.SLACK_WEBHOOK_URL }}
    payload: |
      {
        "text": "✅ Deployment successful",
        "blocks": [
          {
            "type": "section",
            "text": {
              "type": "mrkdwn",
              "text": "*Deployment Successful*\nCommit: ${{ github.sha }}\nAuthor: ${{ github.actor }}"
            }
          }
        ]
      }

- name: Notify Slack on failure
  if: failure()
  uses: slackapi/slack-github-action@v1
  with:
    webhook-url: ${{ secrets.SLACK_WEBHOOK_URL }}
    payload: |
      {
        "text": "❌ Deployment failed",
        "blocks": [
          {
            "type": "section",
            "text": {
              "type": "mrkdwn",
              "text": "*Deployment Failed*\nCommit: ${{ github.sha }}\nAuthor: ${{ github.actor }}\nWorkflow: ${{ github.workflow }}"
            }
          }
        ]
      }

Artifacts

Upload and Download

# Upload artifacts
- name: Upload build artifacts
  uses: actions/upload-artifact@v3
  with:
    name: build-output
    path: |
      dist/
      .next/
    retention-days: 7

# Download artifacts in another job
- name: Download build artifacts
  uses: actions/download-artifact@v3
  with:
    name: build-output

Best Practices

1. Use Specific Versions

# ❌ Using latest
- uses: actions/checkout@latest

# ✅ Using specific version
- uses: actions/checkout@v4

2. Pin Action Versions

# ✅ Good: Pinned to major version
- uses: actions/checkout@v4
- uses: actions/setup-node@v4

# ✅ Better: Pinned to commit SHA (most secure)
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11  # v4.1.1

3. Use Concurrency Controls

name: Deploy

on:
  push:
    branches: [main]

concurrency:
  group: deploy-${{ github.ref }}
  cancel-in-progress: false  # Don't cancel in-progress deployments

4. Fail Fast

jobs:
  test:
    strategy:
      fail-fast: true  # Stop all jobs if one fails
      matrix:
        node: [18, 20, 21]

Troubleshooting

Workflow Not Triggering

# Issue: Workflow not running
# Solution: Check triggers and permissions

on:
  push:
    branches: [main]  # Ensure branch name matches
  pull_request:
    branches: [main]

permissions:
  contents: read
  pull-requests: write

Secret Not Found

# Issue: Secret not available
# Solution: Check secret name and environment

- name: Deploy
  environment: production  # Ensure environment exists
  env:
    SECRET: ${{ secrets.MY_SECRET }}  # Check secret name

Cache Not Working

# Issue: Cache not restoring
# Solution: Verify cache key

- uses: actions/cache@v3
  with:
    path: ~/.pnpm-store
    key: ${{ runner.os }}-pnpm-${{ hashFiles('**/pnpm-lock.yaml') }}
    # Ensure lockfile exists and path is correct

References

Best Practices Summary

  1. Pin Versions: Use specific action versions
  2. Cache Dependencies: Cache pnpm, Turbo, Next.js
  3. Parallel Jobs: Run independent jobs in parallel
  4. Fail Fast: Stop on first failure in matrix
  5. Secrets Management: Use GitHub Secrets for sensitive data
  6. Notifications: Alert team on deployment status
  7. Reusable Workflows: Share common setup steps
  8. Environment Protection: Use environment rules for production

Quick Install

/plugin add https://github.com/sgcarstrends/sgcarstrends/tree/main/github-actions

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

GitHub 仓库

sgcarstrends/sgcarstrends
Path: .claude/skills/github-actions
apiaws-lambdabackendhonojob-schedulerneon-postgres

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

evaluating-llms-harness

Testing

This Claude Skill runs the lm-evaluation-harness to benchmark LLMs across 60+ standardized academic tasks like MMLU and GSM8K. It's designed for developers to compare model quality, track training progress, or report academic results. The tool supports various backends including HuggingFace and vLLM models.

View skill

llamaguard

Other

LlamaGuard is Meta's 7-8B parameter model for moderating LLM inputs and outputs across six safety categories like violence and hate speech. It offers 94-95% accuracy and can be deployed using vLLM, Hugging Face, or Amazon SageMaker. Use this skill to easily integrate content filtering and safety guardrails into your AI applications.

View skill

langchain

Meta

LangChain is a framework for building LLM applications using agents, chains, and RAG pipelines. It supports multiple LLM providers, offers 500+ integrations, and includes features like tool calling and memory management. Use it for rapid prototyping and deploying production systems like chatbots, autonomous agents, and question-answering services.

View skill