5.9 KiB
5.9 KiB
GitHub Actions Best Practices
Workflow Optimization
Caching Strategies
-
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') }}
-
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
-
Cache Size Management
- Keep cache sizes under 10GB per repository
- Regularly clean up unused caches
- Split large caches into multiple smaller caches
Job Parallelization
-
Matrix Builds
- Test across multiple Node.js versions
- Run tests in parallel across different OS
- Split test suites into separate jobs
-
Job Dependencies
- Use
needsto create job dependency chains - Run independent jobs in parallel
- Share artifacts between dependent jobs
- Use
Performance Tips
-
Reduce Checkout Time
- Use shallow clones:
fetch-depth: 1 - Only checkout when necessary
- Skip submodules if not needed
- Use shallow clones:
-
Optimize Installation
- Use frozen lockfiles to skip dependency resolution
- Enable package manager caching
- Consider using pnpm for faster installs
-
Conditional Execution
- Skip jobs based on file changes using
pathsfilter - Use
ifconditions to skip unnecessary steps - Exit early when possible
- Skip jobs based on file changes using
Security Best Practices
Secrets Management
-
Store Sensitive Data Securely
- Use GitHub Secrets for credentials
- Never log secrets or expose in URLs
- Use environment-specific secrets
-
Token Permissions
- Use minimal required permissions
- Prefer
GITHUB_TOKENover personal access tokens - Set explicit permissions in workflow file
-
Dependency Security
- Pin action versions to specific commits
- Enable Dependabot for action updates
- Review third-party action code
Access Control
-
Environment Protection
- Use environment protection rules for production
- Require manual approval for critical deployments
- Limit who can approve deployments
-
Branch Protection
- Require status checks before merge
- Enable branch protection rules
- Prevent force pushes to main branch
Deployment Strategies
Preview Deployments
-
Per-PR Previews
- Deploy each PR to unique preview URL
- Comment URL on PR for easy access
- Clean up when PR is closed
-
Preview Environment Configuration
- Use separate environment variables
- Connect to preview database/services
- Enable debug logging
Production Deployments
-
Blue-Green Deployment
- Deploy to new environment
- Run smoke tests
- Switch traffic when verified
-
Rollback Strategy
- Keep previous deployment available
- Tag successful deployments
- Automate rollback on failure
-
Deployment Gates
- Manual approval for production
- Require successful CI before deploy
- Schedule deployments during maintenance windows
Monitoring and Debugging
Workflow Monitoring
-
Status Badges
- Add status badges to README
- Monitor workflow success rates
- Track deployment frequency
-
Notifications
- Set up Slack/Discord notifications
- Alert on deployment failures
- Send deployment summaries
Debugging Workflows
-
Enable Debug Logging
- Set
ACTIONS_STEP_DEBUGsecret totrue - Use
::debug::commands in scripts - Review workflow run logs
- Set
-
Test Locally
- Use
actto run workflows locally - Test workflow changes in fork
- Validate YAML syntax before commit
- Use
Common Patterns
Monorepo Support
on:
push:
paths:
- 'packages/frontend/**'
- 'packages/shared/**'
Conditional Steps
- name: Deploy to production
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
run: npm run deploy
Reusable Workflows
jobs:
call-reusable:
uses: org/repo/.github/workflows/reusable.yml@main
with:
environment: production
Composite Actions
Create reusable composite actions for common tasks:
# .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
-
Reduce Workflow Minutes
- Cache aggressively
- Skip unnecessary jobs
- Use self-hosted runners for high-volume repos
-
Efficient Runners
- Use smallest runner size that meets requirements
- Self-host runners for private repos
- Schedule resource-intensive jobs during off-peak
-
Artifact Management
- Set appropriate retention days
- Clean up old artifacts
- Compress artifacts before upload
Framework-Specific Tips
Next.js
- Cache
.next/cachedirectory - Set
NEXT_TELEMETRY_DISABLED=1 - Use
next buildoutput for deployment - Configure ISR revalidation appropriately
Vite
- Cache
node_modules/.vitedirectory - Enable build caching
- Use
vite buildfor 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
-
Cache Not Restoring
- Verify cache key matches
- Check cache size limits
- Ensure paths are correct
-
Permission Errors
- Check GITHUB_TOKEN permissions
- Verify repository settings
- Review branch protection rules
-
Timeout Errors
- Increase job timeout
- Split into smaller jobs
- Optimize dependencies
-
Build Failures
- Check environment variables
- Verify Node.js version
- Review dependency compatibility