---
name: "GitHub Actions CI/CD"
description: "Skill for GitHub Actions CI/CD — auto-generated from documentation"
version: "1.0.0"
author: "skynet"
category: "dev"
agents: ["claude-code", "codex", "gemini"]
tags: ["github-actions", "dev", "auto-generated"]
---

# GitHub Actions CI/CD

---
name: GitHub Actions CI/CD
description: Use GitHub Actions for continuous integration, deployment, and automation workflows when you need to build, test, and deploy code automatically on GitHub events
metadata:
  author: skynet
  version: 1.0.0
category: dev
---

# GitHub Actions CI/CD

## Core Concepts

GitHub Actions automates workflows triggered by repository events (push, PR, release, etc.). Workflows are YAML files in `.github/workflows/` containing jobs that run on virtual machines.

Key components:
- **Workflow**: Automated process defined in YAML
- **Job**: Set of steps that execute on the same runner
- **Step**: Individual task (run command or action)
- **Action**: Reusable unit of code
- **Runner**: Server that runs workflows

## Essential Commands

### GitHub CLI for Actions
```bash
# View workflow runs
gh run list

# View specific run details
gh run view <run-id>

# Re-run failed jobs
gh run rerun <run-id>

# Cancel running workflow
gh run cancel <run-id>

# View workflow logs
gh run view <run-id> --log

# List repository secrets
gh secret list

# Set repository secret
gh secret set SECRET_NAME --body "secret-value"
```

## Basic Workflow Structure

### Simple CI Workflow
```yaml
# .github/workflows/ci.yml
name: CI
on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main ]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '18'
          cache: 'npm'
      - run: npm ci
      - run: npm test
      - run: npm run build
```

### Multi-Environment Matrix
```yaml
jobs:
  test:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest, macos-latest]
        node-version: [16, 18, 20]
    steps:
      - uses: actions/checkout@v4
      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
      - run: npm ci
      - run: npm test
```

## Advanced Workflow Patterns

### Conditional Deployment
```yaml
jobs:
  deploy:
    if: github.ref == 'refs/heads/main' && github.event_name == 'push'
    needs: test
    runs-on: ubuntu-latest
    environment: production
    steps:
      - uses: actions/checkout@v4
      - name: Deploy to production
        run: |
          echo "Deploying to production"
          # Add deployment commands
        env:
          DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }}
```

### Docker Build and Push
```yaml
jobs:
  docker:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3
      - name: Login to DockerHub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}
      - name: Build and push
        uses: docker/build-push-action@v5
        with:
          context: .
          push: true
          tags: user/app:latest,user/app:${{ github.sha }}
```

### Artifact Upload/Download
```yaml
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm run build
      - name: Upload artifacts
        uses: actions/upload-artifact@v3
        with:
          name: build-files
          path: dist/

  deploy:
    needs: build
    runs-on: ubuntu-latest
    steps:
      - name: Download artifacts
        uses: actions/download-artifact@v3
        with:
          name: build-files
          path: ./dist
```

## Decision Trees

### Choosing Trigger Events
```
Repository Event?
├── Code Changes → push, pull_request
├── Releases → release (published, created)
├── Issues → issues (opened, closed, labeled)
├── Scheduled → schedule (cron)
└── Manual → workflow_dispatch

Deployment Strategy?
├── Every Push → on: push (branches: main)
├── PR Preview → on: pull_request + environment
├── Tagged Releases → on: push (tags: 'v*')
└── Manual Deploy → workflow_dispatch + inputs
```

### Runner Selection
```
Workload Type?
├── Basic CI/CD → ubuntu-latest (fastest, cheapest)
├── Windows Apps → windows-latest
├── macOS/iOS → macos-latest
├── GPU/Large → self-hosted
└── Containers → ubuntu-latest + Docker
```

## Security Best Practices

### Secret Management
```yaml
# Use repository/environment secrets
env:
  API_KEY: ${{ secrets.API_KEY }}

# Limit secret scope to specific steps
steps:
  - name: Deploy
    run: ./deploy.sh
    env:
      DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }}
```

### Permission Restrictions
```yaml
permissions:
  contents: read
  packages: write
  security-events: write
```

## Troubleshooting

### Common Errors and Fixes

**Error**: `Resource not accessible by integration`
```yaml
# Fix: Add required permissions
permissions:
  contents: read
  pull-requests: write
```

**Error**: `Input required and not supplied: node-version`
```yaml
# Fix: Specify required inputs
- uses: actions/setup-node@v4
  with:
    node-version: '18'  # Add missing input
```

**Error**: `Process completed with exit code 1`
```bash
# Debug: Add verbose logging
- run: npm test --verbose
- run: set -x && npm test  # Enable bash debugging
```

**Error**: `The runner has received a shutdown signal`
```yaml
# Fix: Reduce job timeout or optimize steps
jobs:
  test:
    timeout-minutes: 10  # Default is 360
```

### Debugging Strategies
```yaml
# Enable debug logging
- name: Debug
  run: |
    echo "Event: ${{ github.event_name }}"
    echo "Ref: ${{ github.ref }}"
    echo "SHA: ${{ github.sha }}"
    env
  env:
    ACTIONS_STEP_DEBUG: true
```

### Performance Optimization
```yaml
# Cache dependencies
- uses: actions/cache@v3
  with:
    path: ~/.npm
    key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}

# Parallel jobs
jobs:
  test:
    strategy:
      matrix:
        shard: [1, 2, 3, 4]
    steps:
      - run: npm test -- --shard=${{ matrix.shard }}
```

## Integration Examples

### Slack Notifications
```yaml
- name: Slack Notification
  if: failure()
  uses: 8398a7/action-slack@v3
  with:
    status: failure
    text: "Build failed on ${{ github.ref }}"
  env:
    SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }}
```

### Code Quality Gates
```yaml
- name: SonarCloud Scan
  uses: SonarSource/sonarcloud-github-action@master
  env:
    GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
    SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
```
