Repository navigation
CI/CD pipeline design #2259
|
What's a common pattern for deploying to staging first, running integration tests, and then promoting to production only if those tests pass — without re-building the code at each stage? |
Replies: 1 comment
This is a build-once, deploy-many pattern, and it's a best practice for CI/CD pipelines. The key insight is to pass the build artifact (or container image) through the stages without rebuilding. Here's the common pattern using GitHub Actions: name: Build and promote across environments
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- run: npm ci
- run: npm run build
- uses: actions/upload-artifact@v4
with:
name: build-output
path: dist/
# Keep it around for promotion later
retention-days: 7
deploy-staging:
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/download-artifact@v4
with:
name: build-output
path: dist/
- run: ./deploy.sh staging
test-staging:
needs: deploy-staging
runs-on: ubuntu-latest
steps:
- run: npm run test:integration -- --base-url=${{ secrets.STAGING_URL }}
promote-to-production:
needs: test-staging
runs-on: ubuntu-latest
if: success() # Only if integration tests passed
steps:
- uses: actions/download-artifact@v4
with:
name: build-output
path: dist/
- run: ./deploy.sh productionCore mechanics:
Variations of this pattern:
The critical rule is: never rebuild. If you rebuild at each stage, you risk shipping a different artifact than what was tested. |
This is a build-once, deploy-many pattern, and it's a best practice for CI/CD pipelines. The key insight is to pass the build artifact (or container image) through the stages without rebuilding.
Here's the common pattern using GitHub Actions: