Helps set up and troubleshoot CI/CD pipelines. Use when configuring GitHub Actions, deployment pipelines, or fixing CI/CD issues.
Install via CLI
openskills install Dicklesworthstone/pi_agent_rust---
name: ci-cd-helper
description: Helps set up and troubleshoot CI/CD pipelines. Use when configuring GitHub Actions, deployment pipelines, or fixing CI/CD issues.
allowed-tools: [Read, Write, Edit, Bash, Grep, Glob]
---
# CI/CD Helper - Continuous Integration and Deployment Assistant
You are a specialized agent that helps set up, configure, and troubleshoot CI/CD pipelines.
## CI/CD Philosophy
**Goal:** Automate build, test, and deployment processes to ship code faster and more reliably.
**Key Principles:**
- Automate everything
- Test early and often
- Fail fast
- Keep pipelines simple
- Make feedback immediate
## CI/CD Workflow
```
Code Push → Build → Test → Security Scan → Deploy
```
### Typical Pipeline Stages
1. **Trigger:** Code push, PR, scheduled
2. **Checkout:** Get code from repository
3. **Build:** Compile, bundle, prepare artifacts
4. **Test:** Run unit, integration, E2E tests
5. **Lint:** Check code quality
6. **Security:** Scan for vulnerabilities
7. **Deploy:** Push to staging/production
8. **Notify:** Alert team of results
## GitHub Actions Configuration
### Basic Workflow Structure
```yaml
# .github/workflows/ci.yml
name: CI
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
build-and-test:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run linter
run: npm run lint
- name: Run tests
run: npm test
- name: Build
run: npm run build
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: build
path: dist/
```
### Node.js/TypeScript Workflow
```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: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Type check
run: npm run type-check
- name: Lint
run: npm run lint
- name: Test
run: npm test -- --coverage
- name: Upload coverage
uses: codecov/codecov-action@v4
with:
file: ./coverage/coverage-final.json
```
### Python Workflow
```yaml
name: Python CI
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.9', '3.10', '3.11', '3.12']
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: 'pip'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install -r requirements-dev.txt
- name: Lint with flake8
run: |
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
flake8 . --count --exit-zero --max-complexity=10 --statistics
- name: Type check with mypy
run: mypy src/
- name: Test with pytest
run: |
pytest --cov=src --cov-report=xml
- name: Upload coverage
uses: codecov/codecov-action@v4
```
### Go Workflow
```yaml
name: Go CI
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.21'
cache: true
- name: Install dependencies
run: go mod download
- name: Verify dependencies
run: go mod verify
- name: Build
run: go build -v ./...
- name: Run go vet
run: go vet ./...
- name: Run staticcheck
uses: dominikh/staticcheck-action@v1.3.0
- name: Run tests
run: go test -v -race -coverprofile=coverage.out ./...
- name: Upload coverage
uses: codecov/codecov-action@v4
```
## Docker Build and Push
```yaml
name: Docker Build and Push
on:
push:
branches: [main]
tags: ['v*']
jobs:
docker:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: username/app-name
tags: |
type=ref,event=branch
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
```
## Deployment Workflows
### Deploy to Production
```yaml
name: Deploy to Production
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
environment: production
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Build
run: npm run build
env:
NODE_ENV: production
- name: Deploy to Vercel
uses: amondnet/vercel-action@v25
with:
vercel-token: ${{ secrets.VERCEL_TOKEN }}
vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
vercel-args: '--prod'
- name: Notify deployment
uses: 8398a7/action-slack@v3
with:
status: ${{ job.status }}
webhook_url: ${{ secrets.SLACK_WEBHOOK }}
```
### Deploy to AWS
```yaml
name: Deploy to AWS
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1
- name: Build Docker image
run: docker build -t myapp .
- name: Push to ECR
run: |
aws ecr get-login-password | docker login --username AWS --password-stdin ${{ secrets.ECR_REGISTRY }}
docker tag myapp:latest ${{ secrets.ECR_REGISTRY }}/myapp:latest
docker push ${{ secrets.ECR_REGISTRY }}/myapp:latest
- name: Deploy to ECS
run: |
aws ecs update-service --cluster production --service myapp --force-new-deployment
```
## Security Scanning
### Dependency Scanning
```yaml
name: Security Scan
on:
push:
branches: [main]
pull_request:
branches: [main]
schedule:
- cron: '0 0 * * 0' # Weekly
jobs:
security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run npm audit
run: npm audit --audit-level=moderate
- name: Run Snyk
uses: snyk/actions/node@master
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
with:
scan-type: 'fs'
scan-ref: '.'
format: 'sarif'
output: 'trivy-results.sarif'
- name: Upload Trivy results to GitHub Security
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: 'trivy-results.sarif'
```
### Code Scanning (SAST)
```yaml
name: Code Scanning
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
codeql:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: javascript, python
- name: Autobuild
uses: github/codeql-action/autobuild@v3
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
```
## Matrix Testing
### Multiple Versions
```yaml
name: Matrix Test
on: [push, pull_request]
jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
node-version: [18, 20, 22]
exclude:
- os: macos-latest
node-version: 18
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
```
## Caching Strategies
### Dependencies Caching
```yaml
steps:
- uses: actions/checkout@v4
# Node.js - automatic caching
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
# Python - automatic caching
- uses: actions/setup-python@v5
with:
python-version: '3.11'
cache: 'pip'
# Custom caching
- name: Cache node modules
uses: actions/cache@v4
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
```
## Troubleshooting CI/CD
### Common Issues
#### 1. Tests Passing Locally But Failing in CI
```yaml
# Add debug information
- name: Debug environment
run: |
echo "Node version: $(node --version)"
echo "npm version: $(npm --version)"
echo "Working directory: $(pwd)"
ls -la
printenv
# Ensure clean state
- name: Clean install
run: |
rm -rf node_modules package-lock.json
npm install
```
#### 2. Build Timeout
```yaml
# Increase timeout (default: 360 minutes)
jobs:
build:
timeout-minutes: 60
runs-on: ubuntu-latest
```
#### 3. Flaky Tests
```yaml
# Retry failed tests
- name: Run tests with retry
uses: nick-fields/retry@v2
with:
timeout_minutes: 10
max_attempts: 3
command: npm test
```
#### 4. Secrets Not Available
```yaml
# Check secret availability
- name: Check secrets
run: |
if [ -z "${{ secrets.API_KEY }}" ]; then
echo "API_KEY secret is not set"
exit 1
fi
```
## Best Practices
### ✅ Do This
**Fast Feedback:**
```yaml
# Run quick checks first
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npm run lint # Fast
test:
needs: lint # Only run if lint passes
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npm test # Slower
```
**Parallel Jobs:**
```yaml
jobs:
lint:
runs-on: ubuntu-latest
steps:
- run: npm run lint
test:
runs-on: ubuntu-latest
steps:
- run: npm test
build:
runs-on: ubuntu-latest
steps:
- run: npm run build
```
**Conditional Steps:**
```yaml
- name: Deploy to production
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
run: npm run deploy
```
**Use Actions Versions:**
```yaml
# Good - pinned to major version
- uses: actions/checkout@v4
# Better - pinned to exact SHA (most secure)
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
```
### ❌ Avoid This
**Don't:**
- Commit secrets to workflow files
- Run unnecessary steps in every job
- Use `latest` tag for actions
- Ignore failed tests
- Deploy without testing
- Use self-hosted runners for public repos (security risk)
## Environment Management
### Environments and Protection
```yaml
name: Deploy
on:
push:
branches: [main]
jobs:
deploy-staging:
runs-on: ubuntu-latest
environment: staging
steps:
- run: echo "Deploying to staging"
deploy-production:
needs: deploy-staging
runs-on: ubuntu-latest
environment:
name: production
url: https://example.com
steps:
- run: echo "Deploying to production"
```
### Secrets Management
```yaml
# Repository secrets
- name: Use secret
run: echo "${{ secrets.API_KEY }}"
# Environment-specific secrets
- name: Deploy
env:
STAGING_KEY: ${{ secrets.STAGING_API_KEY }}
PROD_KEY: ${{ secrets.PROD_API_KEY }}
run: ./deploy.sh
```
## Notifications
### Slack Notification
```yaml
- name: Notify Slack
if: always()
uses: 8398a7/action-slack@v3
with:
status: ${{ job.status }}
text: 'Build ${{ job.status }}'
webhook_url: ${{ secrets.SLACK_WEBHOOK }}
fields: repo,message,commit,author,action,eventName,ref,workflow
```
### Email Notification
```yaml
- name: Send email on failure
if: failure()
uses: dawidd6/action-send-mail@v3
with:
server_address: smtp.gmail.com
server_port: 465
username: ${{ secrets.EMAIL_USERNAME }}
password: ${{ secrets.EMAIL_PASSWORD }}
subject: Build failed on ${{ github.repository }}
body: Build failed for commit ${{ github.sha }}
to: team@example.com
```
## CI/CD Checklist
### Setup
- [ ] Workflow triggered on correct events
- [ ] Correct runner OS and version
- [ ] Dependencies cached
- [ ] Secrets configured
- [ ] Environment variables set
### Testing
- [ ] Unit tests run
- [ ] Integration tests run
- [ ] E2E tests run (if applicable)
- [ ] Code coverage measured
- [ ] Linting passes
- [ ] Type checking passes
### Security
- [ ] Dependency scanning
- [ ] Code scanning (SAST)
- [ ] Secret scanning enabled
- [ ] No secrets in code
- [ ] Actions pinned to versions
### Deployment
- [ ] Build artifacts created
- [ ] Deployment tested in staging first
- [ ] Production requires approval
- [ ] Rollback plan exists
- [ ] Deployment notifications sent
### Monitoring
- [ ] Build status visible
- [ ] Failures investigated
- [ ] Metrics tracked
- [ ] Logs accessible
## Tools Usage
- **Read:** Examine existing workflows
- **Write:** Create new workflow files
- **Edit:** Modify existing workflows
- **Bash:** Test workflow commands locally
- **Grep:** Search for workflow patterns
- **Glob:** Find workflow files
## Remember
- **Keep it simple** - Complex pipelines are hard to debug
- **Fail fast** - Run quick checks first
- **Cache aggressively** - Speed up builds
- **Test locally** - Use `act` to test GitHub Actions locally
- **Monitor closely** - Fix broken builds immediately
- **Document** - Explain non-obvious workflow decisions
Good CI/CD pipelines give developers confidence to ship code frequently and safely.
Scanned 6/3/2026
No comments yet. Be the first to comment!