Back to skills
extension
Category: Development & EngineeringNo API key required

ci-cd-reviewer

WHEN: CI/CD pipeline review, GitHub Actions, GitLab CI, Jenkins, build optimization WHAT: Pipeline structure + Job optimization + Security scanning + Caching strategy + Deployment patterns WHEN NOT: Kubernetes → k8s-reviewer, Terraform → terraform-reviewer

personAuthor: jakexiaohubgithub

CI/CD Reviewer Skill

Purpose

Reviews CI/CD pipelines for structure, security, optimization, and best practices.

When to Use

  • GitHub Actions workflow review
  • GitLab CI pipeline review
  • Jenkins pipeline review
  • Build optimization
  • Deployment strategy review

Project Detection

  • .github/workflows/*.yml
  • .gitlab-ci.yml
  • Jenkinsfile
  • azure-pipelines.yml
  • .circleci/config.yml

Workflow

Step 1: Analyze Project

**Platform**: GitHub Actions
**Triggers**: push, pull_request
**Jobs**: build, test, deploy
**Environments**: staging, production

Step 2: Select Review Areas

AskUserQuestion:

"Which areas to review?"
Options:
- Full CI/CD review (recommended)
- Pipeline structure
- Security and secrets
- Caching and optimization
- Deployment strategy
multiSelect: true

Detection Rules

GitHub Actions

Workflow Structure

| Check | Recommendation | Severity | |-------|----------------|----------| | All jobs sequential | Parallelize independent jobs | MEDIUM | | No job dependencies | Add needs for proper order | HIGH | | Duplicate steps | Extract to composite action | MEDIUM | | No concurrency control | Add concurrency group | MEDIUM |

# BAD: Sequential, no optimization
name: CI
on: push

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm install
      - run: npm run build
      - run: npm test
      - run: npm run lint
      - run: docker build .
      - run: docker push

# GOOD: Parallel jobs with dependencies
name: CI

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

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

jobs:
  lint:
    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

  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 test

  build:
    needs: [lint, test]  # Run after lint and test pass
    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: actions/upload-artifact@v4
        with:
          name: build
          path: dist/

  deploy:
    needs: build
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    environment: production
    steps:
      - uses: actions/download-artifact@v4
        with:
          name: build
      - run: ./deploy.sh

Security

| Check | Recommendation | Severity | |-------|----------------|----------| | Secrets in plain text | Use secrets context | CRITICAL | | No permissions defined | Add explicit permissions | HIGH | | Third-party actions unpinned | Pin to SHA | HIGH | | No environment protection | Use environments | MEDIUM |

# BAD: Security issues
name: Deploy
on: push

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - run: |
          curl -X POST https://api.example.com \
            -H "Authorization: Bearer ${{ secrets.API_KEY }}"
      - uses: some-org/some-action@main  # Unpinned!

# GOOD: Secure workflow
name: Deploy

on:
  push:
    branches: [main]

permissions:
  contents: read
  id-token: write  # For OIDC

jobs:
  deploy:
    runs-on: ubuntu-latest
    environment: production  # Requires approval
    steps:
      - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1

      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502 # v4.0.2
        with:
          role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
          aws-region: us-east-1

      - name: Deploy
        run: ./deploy.sh
        env:
          DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }}

Caching

| Check | Recommendation | Severity | |-------|----------------|----------| | No dependency caching | Add cache action | HIGH | | No Docker layer cache | Use buildx cache | MEDIUM | | Cache key not specific | Include lockfile hash | MEDIUM |

# GOOD: Comprehensive caching
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

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

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

      # Docker layer caching
      - uses: docker/setup-buildx-action@v3

      - uses: docker/build-push-action@v5
        with:
          context: .
          push: true
          tags: myapp:latest
          cache-from: type=gha
          cache-to: type=gha,mode=max

GitLab CI

# .gitlab-ci.yml
stages:
  - lint
  - test
  - build
  - deploy

variables:
  NODE_VERSION: "20"

.node_template: &node_template
  image: node:${NODE_VERSION}-alpine
  cache:
    key:
      files:
        - package-lock.json
    paths:
      - node_modules/
  before_script:
    - npm ci --cache .npm --prefer-offline

lint:
  <<: *node_template
  stage: lint
  script:
    - npm run lint

test:
  <<: *node_template
  stage: test
  script:
    - npm test
  coverage: '/Coverage: \d+\.\d+%/'
  artifacts:
    reports:
      junit: junit.xml
      coverage_report:
        coverage_format: cobertura
        path: coverage/cobertura-coverage.xml

build:
  <<: *node_template
  stage: build
  script:
    - npm run build
  artifacts:
    paths:
      - dist/
    expire_in: 1 week

deploy_staging:
  stage: deploy
  environment:
    name: staging
    url: https://staging.example.com
  script:
    - ./deploy.sh staging
  only:
    - main

deploy_production:
  stage: deploy
  environment:
    name: production
    url: https://example.com
  script:
    - ./deploy.sh production
  when: manual
  only:
    - main

Deployment Strategies

| Check | Recommendation | Severity | |-------|----------------|----------| | Direct to production | Add staging environment | HIGH | | No rollback plan | Add rollback mechanism | HIGH | | No health checks | Add post-deploy verification | MEDIUM |

# Blue-Green / Canary with GitHub Actions
deploy:
  runs-on: ubuntu-latest
  environment: production
  steps:
    - name: Deploy canary (10%)
      run: |
        kubectl set image deployment/app app=myapp:${{ github.sha }}
        kubectl rollout status deployment/app --timeout=5m

    - name: Verify canary
      run: |
        sleep 60
        ./verify-deployment.sh

    - name: Promote to 100%
      if: success()
      run: kubectl scale deployment/app --replicas=10

    - name: Rollback on failure
      if: failure()
      run: kubectl rollout undo deployment/app

Response Template

## CI/CD Review Results

**Project**: [name]
**Platform**: GitHub Actions
**Jobs**: 4 | **Workflows**: 2

### Pipeline Structure
| Status | File | Issue |
|--------|------|-------|
| MEDIUM | ci.yml | All jobs run sequentially |

### Security
| Status | File | Issue |
|--------|------|-------|
| HIGH | deploy.yml | Actions not pinned to SHA |

### Caching
| Status | File | Issue |
|--------|------|-------|
| HIGH | ci.yml | No dependency caching |

### Deployment
| Status | File | Issue |
|--------|------|-------|
| HIGH | deploy.yml | No staging environment |

### Recommended Actions
1. [ ] Parallelize lint and test jobs
2. [ ] Pin all actions to commit SHA
3. [ ] Add npm caching
4. [ ] Add staging deployment step

Best Practices

  1. Structure: Parallel jobs, proper dependencies
  2. Security: Pin actions, use OIDC, minimal permissions
  3. Caching: Cache dependencies and Docker layers
  4. Deployment: Staging → Production with approvals
  5. Monitoring: Add status checks and notifications

Integration

  • docker-reviewer: Container build steps
  • k8s-reviewer: Kubernetes deployments
  • security-scanner: SAST/DAST in pipeline