Choosing Between Semaphore Promotion Blocks and Separate Pipelines for Multi‑Stage Deployments
When building a multi‑environment workflow in Semaphore CI/CD, you can chain stages with promotion blocks or use distinct pipelines. This guide weighs the trade‑offs, shows side‑by‑side tables, and gives concrete YAML snippets for each approach.
10 Oct 2025, 15:07 UTC

Problem Statement
You need to deploy code to multiple environments (e.g., staging, production) with a clear audit trail, controlled promotion, and minimal configuration duplication. Semaphore CI/CD offers two main ways to model this flow:
- Promotion blocks – a built‑in feature that triggers a downstream pipeline after a successful build.
- Separate pipelines – independent YAML files that represent each environment and are chained via API calls or manual triggers.
Choosing the right pattern affects how secrets are shared, how artifacts are passed, how retries are handled, and how cost‑effective your workflow is.
Decision Context and Constraints
Before diving into options, answer these three constraints that will guide your choice:
- Environment isolation – Do you need strict isolation between environments (e.g., separate secrets, independent retry loops)?
- Operational overhead – How much manual or external orchestration can you afford?
- Pipeline complexity – Are you willing to maintain multiple YAML files or prefer a single, shared pipeline definition?
Option Comparison
| Feature | Promotion Block | Separate Pipelines |
|---|---|---|
| Secret Sharing | Inherits all secrets from the source pipeline unless overridden. | Each pipeline defines its own secrets; you must duplicate or reference shared ones. |
| Artifact Handling | Passes artifacts implicitly via the promotion trigger; cache scopes are inherited. | Artifacts must be explicitly published (e.g., to a registry) and then fetched by the downstream pipeline. |
| Retry Semantics | Failure in the downstream pipeline does not automatically retry the upstream build. | Each pipeline can be retried independently; a failure in one does not affect the others. |
| Concurrency Control | All stages run in a single queue; promotion blocks serialize the flow. | Independent pipelines can run in parallel unless you add explicit queue limits. |
| Configuration Duplication | Single pipeline definition; promotion block keeps context. | Multiple YAML files; duplication of common steps may be required. |
| Trigger Granularity | Automatic (branch/tag match, manual approval) or time‑based within the same pipeline. | Requires external triggers (API call, webhook) or manual start per environment. |
| Cost Implications | Fewer pipeline runs, potentially lower agent minutes. | More pipeline runs; cost depends on the number of environments and concurrency. |
Trade‑Off Analysis
- Isolation vs. Simplicity – Separate pipelines give clean boundaries but add maintenance overhead.
- Retry Flexibility – Standalone pipelines let you retry a failed environment without re‑building the entire code base.
- Secret Leakage Risk – Promotion blocks inherit all secrets, which may expose sensitive data to downstream stages if not carefully scoped.
- Cache Efficiency – Promotion blocks inherit cache scopes, reducing build time; separate pipelines need explicit cache restoration.
- Operational Footprint – Promotion blocks reduce the need for external orchestration tools or scripts.
Concrete Implementation: Promotion Block
Below is a minimal example that builds, tests, and then promotes to a staging pipeline. Replace placeholders with your project specifics.
# semaphore.yml
version: "2"
build:
image: node:18
commands:
- npm install
- npm test
promotion:
name: "Promote to Staging"
pipeline: staging
# Optional gating conditions
# branch: "main"
# manual: true
staging:
image: node:18
commands:
- echo "Deploying to staging"
- ./deploy.sh --env=staging
Key points:
- The
promotionblock references thestagingpipeline defined below. - Secrets available in the
buildstage are automatically available tostagingunless you explicitly override them. - Artifacts built in
buildare passed implicitly; if you need a specific artifact, add apublishstep.
Concrete Implementation: Separate Pipelines
Here we define two independent pipelines, one for build/test and another for staging deployment. The downstream pipeline is triggered via the Semaphore API.
# semaphore-build.yml
version: "2"
build:
image: node:18
commands:
- npm install
- npm test
- echo "Build succeeded, publishing artifact"
- semaphore publish artifact.zip
# semaphore-staging.yml
version: "2"
staging:
image: node:18
commands:
- echo "Fetching artifact"
- semaphore download artifact.zip
- ./deploy.sh --env=staging
Triggering the staging pipeline from the build pipeline via API:
# Run after successful build
semaphore trigger --pipeline-id <staging-pipeline-id> \
--branch main \
--token <YOUR_API_TOKEN>
Replace <staging-pipeline-id> with the ID shown in the Semaphore UI and <YOUR_API_TOKEN> with a personal access token that has trigger permissions.
Validation Checklist
- Run both workflows in a test project. Verify that the promotion block triggers the downstream stage automatically.
- Inspect logs. For promotion blocks, ensure the downstream stage receives the correct Git revision and cache key.
- Check secret propagation. In the downstream stage, echo a known secret to confirm inheritance (use
echo $SECRET_NAME). - Retry behavior. Fail the downstream stage intentionally and confirm that the upstream build is not retried automatically.
- Cost audit. Compare agent minutes consumed by promotion blocks vs. separate pipelines over a week.
Limitations and Caveats
- Promotion blocks are only available on Semaphore plans that support multi‑pipeline promotion. Verify your account tier before using the feature.
- The promotion block does not automatically preserve environment variables unless they are defined as secrets. Explicitly declare any required environment variables in the downstream pipeline.
- Long‑running promotion chains can lead to queue buildup; consider adding explicit
queuelimits if you anticipate high concurrency. - Artifact size limits apply to the built artifact; if you exceed the limit, the promotion will fail. Use external storage (e.g., S3) if necessary.
- When using separate pipelines, ensure the API token used for triggering has the minimal required scope to reduce security risk.
By evaluating the constraints above and weighing the trade‑offs, you can decide whether a promotion block or separate pipelines best fit your team’s deployment workflow in Semaphore CI/CD.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.