Initial commit
This commit is contained in:
168
skills/github-actions-ci-workflow/SKILL.md
Normal file
168
skills/github-actions-ci-workflow/SKILL.md
Normal file
@@ -0,0 +1,168 @@
|
||||
---
|
||||
name: github-actions-ci-workflow
|
||||
description: Sets up comprehensive GitHub Actions CI/CD workflows for modern web applications. This skill should be used when configuring automated lint, test, build, and deploy pipelines, adding preview URL comments on pull requests, or optimizing workflow caching. Use when setting up continuous integration, deployment automation, GitHub Actions, CI/CD pipeline, preview deployments, or workflow optimization.
|
||||
---
|
||||
|
||||
# GitHub Actions CI Workflow
|
||||
|
||||
Set up complete GitHub Actions workflows for continuous integration and deployment of worldbuilding applications.
|
||||
|
||||
## Overview
|
||||
|
||||
To configure comprehensive CI/CD pipelines with GitHub Actions:
|
||||
|
||||
1. Analyze the project structure and dependencies
|
||||
2. Generate workflow files for lint, test, build, and deploy stages
|
||||
3. Configure caching strategies for node_modules, Next.js cache, and build artifacts
|
||||
4. Add preview deployment with automatic URL comments on pull requests
|
||||
5. Set up environment-specific deployment targets
|
||||
|
||||
## Workflow Structure
|
||||
|
||||
Create the following workflow files in `.github/workflows/`:
|
||||
|
||||
### CI Workflow (`ci.yml`)
|
||||
|
||||
To set up continuous integration:
|
||||
|
||||
1. Configure triggers for push to main/master and pull requests
|
||||
2. Set up job matrix for multiple Node.js versions if needed
|
||||
3. Add checkout, dependency installation with caching
|
||||
4. Run linting (ESLint, Prettier, type checking)
|
||||
5. Execute test suites with coverage reporting
|
||||
6. Build the application to verify no build errors
|
||||
7. Upload build artifacts for deployment jobs
|
||||
|
||||
### Deploy Workflow (`deploy.yml`)
|
||||
|
||||
To set up continuous deployment:
|
||||
|
||||
1. Trigger on push to main/master branch
|
||||
2. Download build artifacts from CI workflow
|
||||
3. Deploy to target environment (Vercel, Netlify, AWS, etc.)
|
||||
4. Set environment variables and secrets
|
||||
5. Notify on deployment success/failure
|
||||
|
||||
### Preview Deployment (`preview.yml`)
|
||||
|
||||
To set up preview deployments for pull requests:
|
||||
|
||||
1. Trigger on pull_request events
|
||||
2. Build and deploy to preview environment
|
||||
3. Generate unique preview URL
|
||||
4. Comment preview URL on pull request using GitHub API
|
||||
5. Clean up preview deployments when PR is closed
|
||||
|
||||
## Caching Strategy
|
||||
|
||||
To optimize workflow performance:
|
||||
|
||||
1. Cache `node_modules` with dependency lock file as cache key
|
||||
2. Cache Next.js build cache (`.next/cache`) for faster builds
|
||||
3. Cache testing artifacts and coverage reports
|
||||
4. Use `actions/cache@v3` with appropriate cache keys
|
||||
5. Implement cache restoration fallbacks for partial matches
|
||||
|
||||
## Resources
|
||||
|
||||
Consult `references/github-actions-best-practices.md` for workflow optimization patterns and security best practices.
|
||||
|
||||
Use `scripts/generate_ci_workflow.py` to scaffold workflow files based on detected project configuration.
|
||||
|
||||
Reference `assets/workflow-templates/` for starter templates for common frameworks (Next.js, React, Node.js).
|
||||
|
||||
## Implementation Steps
|
||||
|
||||
To implement complete CI/CD with GitHub Actions:
|
||||
|
||||
1. **Detect Project Configuration**
|
||||
- Identify framework (Next.js, Vite, CRA, etc.)
|
||||
- Detect package manager (npm, yarn, pnpm)
|
||||
- Find test runner (Jest, Vitest, Playwright)
|
||||
- Check for linting configuration
|
||||
|
||||
2. **Generate Workflow Files**
|
||||
- Use `scripts/generate_ci_workflow.py` with detected configuration
|
||||
- Customize jobs based on project requirements
|
||||
- Add matrix builds if testing multiple environments
|
||||
|
||||
3. **Configure Secrets and Variables**
|
||||
- Document required secrets in README or workflow comments
|
||||
- Set up environment-specific variables
|
||||
- Configure deployment credentials
|
||||
|
||||
4. **Add Preview Deployments**
|
||||
- Generate preview workflow with URL commenting
|
||||
- Configure preview environment provider
|
||||
- Set up cleanup automation
|
||||
|
||||
5. **Optimize Caching**
|
||||
- Implement multi-level caching strategy
|
||||
- Use cache keys based on lock files
|
||||
- Add cache restoration logic
|
||||
|
||||
6. **Test and Validate**
|
||||
- Push workflows to repository
|
||||
- Create test PR to verify preview deployments
|
||||
- Check workflow execution times and optimize
|
||||
|
||||
## Advanced Features
|
||||
|
||||
To add advanced CI/CD capabilities:
|
||||
|
||||
- **Parallel Jobs**: Split test suites across multiple jobs for faster execution
|
||||
- **Conditional Deployments**: Deploy only specific paths or when conditions are met
|
||||
- **Status Checks**: Require CI passing before merge
|
||||
- **Deployment Gates**: Add manual approval steps for production deployments
|
||||
- **Performance Monitoring**: Integrate Lighthouse CI or bundle analysis
|
||||
- **Dependency Updates**: Automate dependency updates with Dependabot integration
|
||||
|
||||
## Framework-Specific Configuration
|
||||
|
||||
### Next.js Applications
|
||||
|
||||
To optimize for Next.js:
|
||||
|
||||
1. Cache `.next/cache` directory for faster builds
|
||||
2. Set `NEXT_TELEMETRY_DISABLED=1` to disable telemetry
|
||||
3. Use `next build` and `next export` for static exports
|
||||
4. Configure ISR revalidation for preview deployments
|
||||
|
||||
### Full-Stack Applications
|
||||
|
||||
To handle full-stack deployments:
|
||||
|
||||
1. Set up separate jobs for frontend and backend
|
||||
2. Configure database migrations in deployment workflow
|
||||
3. Run integration tests against preview environment
|
||||
4. Coordinate deployment order (backend first, then frontend)
|
||||
|
||||
## Deployment Providers
|
||||
|
||||
Consult `references/deployment-providers.md` for platform-specific configuration:
|
||||
|
||||
- **Vercel**: Use vercel-action with project configuration
|
||||
- **Netlify**: Use netlify-cli with site ID and auth token
|
||||
- **AWS**: Configure S3/CloudFront or ECS deployment
|
||||
- **Docker**: Build and push container images to registry
|
||||
- **Self-Hosted**: SSH deployment with rsync or git pull
|
||||
|
||||
## Monitoring and Notifications
|
||||
|
||||
To add monitoring and notifications:
|
||||
|
||||
1. Configure Slack/Discord webhooks for deployment notifications
|
||||
2. Add GitHub status checks for required CI jobs
|
||||
3. Set up error tracking integration (Sentry, etc.)
|
||||
4. Monitor workflow execution times and optimize slow jobs
|
||||
5. Track deployment frequency and failure rates
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
Common issues and solutions:
|
||||
|
||||
- **Cache Misses**: Verify cache key includes all dependency files
|
||||
- **Timeout Errors**: Increase timeout or split into parallel jobs
|
||||
- **Permission Errors**: Check repository secrets and permissions
|
||||
- **Build Failures**: Ensure environment variables are set correctly
|
||||
- **Preview URL Not Commented**: Verify PR comment permissions and token scope
|
||||
@@ -0,0 +1,71 @@
|
||||
name: Next.js CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main, master]
|
||||
pull_request:
|
||||
branches: [main, master]
|
||||
|
||||
jobs:
|
||||
lint-and-test:
|
||||
name: Lint and Test
|
||||
runs-on: ubuntu-latest
|
||||
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: Run ESLint
|
||||
run: npm run lint
|
||||
|
||||
- name: Run tests
|
||||
run: npm test -- --coverage
|
||||
|
||||
- name: Upload coverage
|
||||
uses: codecov/codecov-action@v3
|
||||
if: always()
|
||||
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ubuntu-latest
|
||||
needs: lint-and-test
|
||||
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: Cache Next.js build
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
~/.npm
|
||||
${{ github.workspace }}/.next/cache
|
||||
key: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**/*.js', '**/*.jsx', '**/*.ts', '**/*.tsx') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-
|
||||
|
||||
- name: Build Next.js application
|
||||
run: npm run build
|
||||
env:
|
||||
NEXT_TELEMETRY_DISABLED: 1
|
||||
|
||||
- name: Upload build artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: nextjs-build
|
||||
path: .next
|
||||
retention-days: 7
|
||||
@@ -0,0 +1,249 @@
|
||||
# GitHub Actions Best Practices
|
||||
|
||||
## Workflow Optimization
|
||||
|
||||
### Caching Strategies
|
||||
|
||||
1. **Dependency Caching**
|
||||
- Always cache package manager dependencies
|
||||
- Use lock file hashes as cache keys
|
||||
- Include fallback restoration keys for partial matches
|
||||
- Example: `${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }}`
|
||||
|
||||
2. **Build Artifact Caching**
|
||||
- Cache framework-specific build directories (.next/cache, .nuxt, etc.)
|
||||
- Include source file hashes in cache key for invalidation
|
||||
- Use separate caches for different build targets
|
||||
|
||||
3. **Cache Size Management**
|
||||
- Keep cache sizes under 10GB per repository
|
||||
- Regularly clean up unused caches
|
||||
- Split large caches into multiple smaller caches
|
||||
|
||||
### Job Parallelization
|
||||
|
||||
1. **Matrix Builds**
|
||||
- Test across multiple Node.js versions
|
||||
- Run tests in parallel across different OS
|
||||
- Split test suites into separate jobs
|
||||
|
||||
2. **Job Dependencies**
|
||||
- Use `needs` to create job dependency chains
|
||||
- Run independent jobs in parallel
|
||||
- Share artifacts between dependent jobs
|
||||
|
||||
### Performance Tips
|
||||
|
||||
1. **Reduce Checkout Time**
|
||||
- Use shallow clones: `fetch-depth: 1`
|
||||
- Only checkout when necessary
|
||||
- Skip submodules if not needed
|
||||
|
||||
2. **Optimize Installation**
|
||||
- Use frozen lockfiles to skip dependency resolution
|
||||
- Enable package manager caching
|
||||
- Consider using pnpm for faster installs
|
||||
|
||||
3. **Conditional Execution**
|
||||
- Skip jobs based on file changes using `paths` filter
|
||||
- Use `if` conditions to skip unnecessary steps
|
||||
- Exit early when possible
|
||||
|
||||
## Security Best Practices
|
||||
|
||||
### Secrets Management
|
||||
|
||||
1. **Store Sensitive Data Securely**
|
||||
- Use GitHub Secrets for credentials
|
||||
- Never log secrets or expose in URLs
|
||||
- Use environment-specific secrets
|
||||
|
||||
2. **Token Permissions**
|
||||
- Use minimal required permissions
|
||||
- Prefer `GITHUB_TOKEN` over personal access tokens
|
||||
- Set explicit permissions in workflow file
|
||||
|
||||
3. **Dependency Security**
|
||||
- Pin action versions to specific commits
|
||||
- Enable Dependabot for action updates
|
||||
- Review third-party action code
|
||||
|
||||
### Access Control
|
||||
|
||||
1. **Environment Protection**
|
||||
- Use environment protection rules for production
|
||||
- Require manual approval for critical deployments
|
||||
- Limit who can approve deployments
|
||||
|
||||
2. **Branch Protection**
|
||||
- Require status checks before merge
|
||||
- Enable branch protection rules
|
||||
- Prevent force pushes to main branch
|
||||
|
||||
## Deployment Strategies
|
||||
|
||||
### Preview Deployments
|
||||
|
||||
1. **Per-PR Previews**
|
||||
- Deploy each PR to unique preview URL
|
||||
- Comment URL on PR for easy access
|
||||
- Clean up when PR is closed
|
||||
|
||||
2. **Preview Environment Configuration**
|
||||
- Use separate environment variables
|
||||
- Connect to preview database/services
|
||||
- Enable debug logging
|
||||
|
||||
### Production Deployments
|
||||
|
||||
1. **Blue-Green Deployment**
|
||||
- Deploy to new environment
|
||||
- Run smoke tests
|
||||
- Switch traffic when verified
|
||||
|
||||
2. **Rollback Strategy**
|
||||
- Keep previous deployment available
|
||||
- Tag successful deployments
|
||||
- Automate rollback on failure
|
||||
|
||||
3. **Deployment Gates**
|
||||
- Manual approval for production
|
||||
- Require successful CI before deploy
|
||||
- Schedule deployments during maintenance windows
|
||||
|
||||
## Monitoring and Debugging
|
||||
|
||||
### Workflow Monitoring
|
||||
|
||||
1. **Status Badges**
|
||||
- Add status badges to README
|
||||
- Monitor workflow success rates
|
||||
- Track deployment frequency
|
||||
|
||||
2. **Notifications**
|
||||
- Set up Slack/Discord notifications
|
||||
- Alert on deployment failures
|
||||
- Send deployment summaries
|
||||
|
||||
### Debugging Workflows
|
||||
|
||||
1. **Enable Debug Logging**
|
||||
- Set `ACTIONS_STEP_DEBUG` secret to `true`
|
||||
- Use `::debug::` commands in scripts
|
||||
- Review workflow run logs
|
||||
|
||||
2. **Test Locally**
|
||||
- Use `act` to run workflows locally
|
||||
- Test workflow changes in fork
|
||||
- Validate YAML syntax before commit
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### Monorepo Support
|
||||
|
||||
```yaml
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- 'packages/frontend/**'
|
||||
- 'packages/shared/**'
|
||||
```
|
||||
|
||||
### Conditional Steps
|
||||
|
||||
```yaml
|
||||
- name: Deploy to production
|
||||
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
|
||||
run: npm run deploy
|
||||
```
|
||||
|
||||
### Reusable Workflows
|
||||
|
||||
```yaml
|
||||
jobs:
|
||||
call-reusable:
|
||||
uses: org/repo/.github/workflows/reusable.yml@main
|
||||
with:
|
||||
environment: production
|
||||
```
|
||||
|
||||
### Composite Actions
|
||||
|
||||
Create reusable composite actions for common tasks:
|
||||
|
||||
```yaml
|
||||
# .github/actions/setup-node/action.yml
|
||||
name: Setup Node.js
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20'
|
||||
cache: 'npm'
|
||||
- run: npm ci
|
||||
shell: bash
|
||||
```
|
||||
|
||||
## Cost Optimization
|
||||
|
||||
1. **Reduce Workflow Minutes**
|
||||
- Cache aggressively
|
||||
- Skip unnecessary jobs
|
||||
- Use self-hosted runners for high-volume repos
|
||||
|
||||
2. **Efficient Runners**
|
||||
- Use smallest runner size that meets requirements
|
||||
- Self-host runners for private repos
|
||||
- Schedule resource-intensive jobs during off-peak
|
||||
|
||||
3. **Artifact Management**
|
||||
- Set appropriate retention days
|
||||
- Clean up old artifacts
|
||||
- Compress artifacts before upload
|
||||
|
||||
## Framework-Specific Tips
|
||||
|
||||
### Next.js
|
||||
|
||||
- Cache `.next/cache` directory
|
||||
- Set `NEXT_TELEMETRY_DISABLED=1`
|
||||
- Use `next build` output for deployment
|
||||
- Configure ISR revalidation appropriately
|
||||
|
||||
### Vite
|
||||
|
||||
- Cache `node_modules/.vite` directory
|
||||
- Enable build caching
|
||||
- Use `vite build` for production builds
|
||||
|
||||
### Testing
|
||||
|
||||
- Run unit and integration tests in parallel
|
||||
- Upload test results and coverage
|
||||
- Use matrix builds for cross-browser testing
|
||||
- Consider Playwright for E2E tests
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
1. **Cache Not Restoring**
|
||||
- Verify cache key matches
|
||||
- Check cache size limits
|
||||
- Ensure paths are correct
|
||||
|
||||
2. **Permission Errors**
|
||||
- Check GITHUB_TOKEN permissions
|
||||
- Verify repository settings
|
||||
- Review branch protection rules
|
||||
|
||||
3. **Timeout Errors**
|
||||
- Increase job timeout
|
||||
- Split into smaller jobs
|
||||
- Optimize dependencies
|
||||
|
||||
4. **Build Failures**
|
||||
- Check environment variables
|
||||
- Verify Node.js version
|
||||
- Review dependency compatibility
|
||||
@@ -0,0 +1,366 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Generate GitHub Actions CI/CD workflow files based on project configuration.
|
||||
"""
|
||||
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def detect_package_manager(project_root):
|
||||
"""Detect package manager from lock files."""
|
||||
if (project_root / "pnpm-lock.yaml").exists():
|
||||
return "pnpm"
|
||||
elif (project_root / "yarn.lock").exists():
|
||||
return "yarn"
|
||||
elif (project_root / "package-lock.json").exists():
|
||||
return "npm"
|
||||
return "npm"
|
||||
|
||||
|
||||
def detect_framework(package_json):
|
||||
"""Detect framework from package.json dependencies."""
|
||||
deps = {**package_json.get("dependencies", {}), **package_json.get("devDependencies", {})}
|
||||
|
||||
if "next" in deps:
|
||||
return "nextjs"
|
||||
elif "vite" in deps:
|
||||
return "vite"
|
||||
elif "react-scripts" in deps:
|
||||
return "cra"
|
||||
elif "vue" in deps:
|
||||
return "vue"
|
||||
return "generic"
|
||||
|
||||
|
||||
def detect_test_runner(package_json):
|
||||
"""Detect test runner from package.json."""
|
||||
deps = {**package_json.get("dependencies", {}), **package_json.get("devDependencies", {})}
|
||||
|
||||
if "vitest" in deps:
|
||||
return "vitest"
|
||||
elif "@playwright/test" in deps:
|
||||
return "playwright"
|
||||
elif "jest" in deps:
|
||||
return "jest"
|
||||
return None
|
||||
|
||||
|
||||
def generate_ci_workflow(config):
|
||||
"""Generate CI workflow YAML content."""
|
||||
pm = config["package_manager"]
|
||||
install_cmd = {
|
||||
"npm": "npm ci",
|
||||
"yarn": "yarn install --frozen-lockfile",
|
||||
"pnpm": "pnpm install --frozen-lockfile"
|
||||
}[pm]
|
||||
|
||||
cache_path = {
|
||||
"npm": "~/.npm",
|
||||
"yarn": "~/.yarn/cache",
|
||||
"pnpm": "~/.pnpm-store"
|
||||
}[pm]
|
||||
|
||||
lock_file = {
|
||||
"npm": "package-lock.json",
|
||||
"yarn": "yarn.lock",
|
||||
"pnpm": "pnpm-lock.yaml"
|
||||
}[pm]
|
||||
|
||||
test_cmd = config.get("test_command", "npm test")
|
||||
build_cmd = config.get("build_command", "npm run build")
|
||||
|
||||
workflow = f"""name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main, master]
|
||||
pull_request:
|
||||
branches: [main, master]
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
name: Lint
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20'
|
||||
cache: '{pm}'
|
||||
|
||||
- name: Install dependencies
|
||||
run: {install_cmd}
|
||||
|
||||
- name: Run linter
|
||||
run: npm run lint
|
||||
|
||||
- name: Check formatting
|
||||
run: npm run format:check
|
||||
continue-on-error: true
|
||||
|
||||
- name: Type check
|
||||
run: npm run type-check
|
||||
continue-on-error: true
|
||||
|
||||
test:
|
||||
name: Test
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20'
|
||||
cache: '{pm}'
|
||||
|
||||
- name: Install dependencies
|
||||
run: {install_cmd}
|
||||
|
||||
- name: Run tests
|
||||
run: {test_cmd}
|
||||
|
||||
- name: Upload coverage
|
||||
uses: codecov/codecov-action@v3
|
||||
if: always()
|
||||
with:
|
||||
files: ./coverage/coverage-final.json
|
||||
fail_ci_if_error: false
|
||||
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20'
|
||||
cache: '{pm}'
|
||||
|
||||
- name: Install dependencies
|
||||
run: {install_cmd}
|
||||
|
||||
- name: Cache Next.js build
|
||||
uses: actions/cache@v3
|
||||
if: contains('{config["framework"]}', 'next')
|
||||
with:
|
||||
path: |
|
||||
.next/cache
|
||||
key: ${{{{ runner.os }}}}-nextjs-${{{{ hashFiles('{lock_file}') }}}}-${{{{ hashFiles('**/*.js', '**/*.jsx', '**/*.ts', '**/*.tsx') }}}}
|
||||
restore-keys: |
|
||||
${{{{ runner.os }}}}-nextjs-${{{{ hashFiles('{lock_file}') }}}}-
|
||||
|
||||
- name: Build application
|
||||
run: {build_cmd}
|
||||
env:
|
||||
NEXT_TELEMETRY_DISABLED: 1
|
||||
|
||||
- name: Upload build artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: build
|
||||
path: |
|
||||
.next
|
||||
out
|
||||
dist
|
||||
build
|
||||
retention-days: 7
|
||||
"""
|
||||
|
||||
return workflow
|
||||
|
||||
|
||||
def generate_preview_workflow(config):
|
||||
"""Generate preview deployment workflow."""
|
||||
pm = config["package_manager"]
|
||||
install_cmd = {
|
||||
"npm": "npm ci",
|
||||
"yarn": "yarn install --frozen-lockfile",
|
||||
"pnpm": "pnpm install --frozen-lockfile"
|
||||
}[pm]
|
||||
|
||||
workflow = f"""name: Preview Deployment
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened, closed]
|
||||
|
||||
jobs:
|
||||
preview:
|
||||
name: Deploy Preview
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event.action != 'closed'
|
||||
permissions:
|
||||
pull-requests: write
|
||||
contents: read
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20'
|
||||
cache: '{pm}'
|
||||
|
||||
- name: Install dependencies
|
||||
run: {install_cmd}
|
||||
|
||||
- name: Build for preview
|
||||
run: npm run build
|
||||
env:
|
||||
NEXT_TELEMETRY_DISABLED: 1
|
||||
|
||||
- name: Deploy to Vercel
|
||||
id: deploy
|
||||
run: |
|
||||
npx vercel --token ${{{{ secrets.VERCEL_TOKEN }}}} --yes --env ENVIRONMENT=preview > deployment-url.txt
|
||||
echo "url=$(cat deployment-url.txt)" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Comment preview URL
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
const url = '${{{{ steps.deploy.outputs.url }}}}';
|
||||
const comment = `## Preview Deployment
|
||||
|
||||
:rocket: Your preview deployment is ready!
|
||||
|
||||
**URL**: ${{url}}
|
||||
|
||||
Built from commit: ${{{{ github.event.pull_request.head.sha }}}}`;
|
||||
|
||||
github.rest.issues.createComment({{
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
body: comment
|
||||
}});
|
||||
|
||||
cleanup:
|
||||
name: Cleanup Preview
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event.action == 'closed'
|
||||
steps:
|
||||
- name: Delete preview deployment
|
||||
run: |
|
||||
echo "Cleaning up preview deployment for PR #${{{{ github.event.pull_request.number }}}}"
|
||||
# Add cleanup logic for your deployment provider
|
||||
"""
|
||||
|
||||
return workflow
|
||||
|
||||
|
||||
def generate_deploy_workflow(config):
|
||||
"""Generate production deployment workflow."""
|
||||
workflow = """name: Deploy Production
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main, master]
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
name: Deploy to Production
|
||||
runs-on: ubuntu-latest
|
||||
environment:
|
||||
name: production
|
||||
url: https://your-app-url.com
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Download build artifacts
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: build
|
||||
|
||||
- name: Deploy to production
|
||||
run: |
|
||||
echo "Add your deployment commands here"
|
||||
# Example: npx vercel --prod --token ${{ secrets.VERCEL_TOKEN }}
|
||||
|
||||
- name: Notify on success
|
||||
if: success()
|
||||
run: |
|
||||
echo "Deployment successful"
|
||||
# Add notification logic (Slack, Discord, etc.)
|
||||
|
||||
- name: Notify on failure
|
||||
if: failure()
|
||||
run: |
|
||||
echo "Deployment failed"
|
||||
# Add failure notification logic
|
||||
"""
|
||||
|
||||
return workflow
|
||||
|
||||
|
||||
def main():
|
||||
if len(sys.argv) < 2:
|
||||
print("Usage: generate_ci_workflow.py <project_root>")
|
||||
sys.exit(1)
|
||||
|
||||
project_root = Path(sys.argv[1]).resolve()
|
||||
|
||||
if not project_root.exists():
|
||||
print(f"Error: Project root not found: {project_root}")
|
||||
sys.exit(1)
|
||||
|
||||
# Read package.json
|
||||
package_json_path = project_root / "package.json"
|
||||
if not package_json_path.exists():
|
||||
print("Error: package.json not found")
|
||||
sys.exit(1)
|
||||
|
||||
with open(package_json_path) as f:
|
||||
package_json = json.load(f)
|
||||
|
||||
# Detect configuration
|
||||
config = {
|
||||
"package_manager": detect_package_manager(project_root),
|
||||
"framework": detect_framework(package_json),
|
||||
"test_runner": detect_test_runner(package_json),
|
||||
"test_command": package_json.get("scripts", {}).get("test", "npm test"),
|
||||
"build_command": package_json.get("scripts", {}).get("build", "npm run build"),
|
||||
}
|
||||
|
||||
print(f"Detected configuration:")
|
||||
print(f" Package manager: {config['package_manager']}")
|
||||
print(f" Framework: {config['framework']}")
|
||||
print(f" Test runner: {config['test_runner']}")
|
||||
print()
|
||||
|
||||
# Create workflows directory
|
||||
workflows_dir = project_root / ".github" / "workflows"
|
||||
workflows_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# Generate workflow files
|
||||
workflows = {
|
||||
"ci.yml": generate_ci_workflow(config),
|
||||
"preview.yml": generate_preview_workflow(config),
|
||||
"deploy.yml": generate_deploy_workflow(config),
|
||||
}
|
||||
|
||||
for filename, content in workflows.items():
|
||||
filepath = workflows_dir / filename
|
||||
with open(filepath, "w") as f:
|
||||
f.write(content)
|
||||
print(f"Created: {filepath}")
|
||||
|
||||
print()
|
||||
print("GitHub Actions workflows generated successfully!")
|
||||
print()
|
||||
print("Next steps:")
|
||||
print("1. Review and customize the generated workflow files")
|
||||
print("2. Add required secrets to your GitHub repository settings")
|
||||
print("3. Commit and push the workflows to trigger CI/CD")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user