Promote
Reusable workflow that prepares a promotion between long-lived branches as a pull request: it cuts a branch from a base, merges one or more source branches into it and opens a pull request into the target. One mechanism covers story promotion, release bundles and the sync of environment branches after a release. Merge conflicts are never resolved automatically - the run fails and its summary lists the files and the commands to finish the promotion locally.
Reusable workflow - call it from your own repository with
uses:. View source
Inputs
| Input | Description | Type | Required | Default |
|---|---|---|---|---|
target | Branch the pull request goes into, e.g. "uat". | string | yes | - |
sources | Comma-separated or multi-line list of branches to merge, in order, e.g. "feature/story-123". Leave empty to open the pull request from the base branch itself, e.g. a release branch into main. | string | no | - |
base | Branch to cut the promotion branch from. Leave empty to use the target - right for story promotion and the sync after a release. | string | no | - |
branch | Name of the branch to create, e.g. "release/2026-11". Leave empty for "promotion/<source>-<target>" with one source, or "promotion/<target>-<run number>" with several. | string | no | - |
title | Title of the pull request. Leave empty for "Promote <sources> to <target>". | string | no | - |
Secrets
| Secret | Description | Required |
|---|---|---|
PROMOTION_APP_ID | ID of a GitHub App with contents and pull request write access. Pull requests opened with the default GITHUB_TOKEN do not trigger other workflows, so without an app the pull request validation never starts on the promotion pull request. | no |
PROMOTION_APP_PRIVATE_KEY | Private key of that GitHub App. | no |
Outputs
| Output | Description |
|---|---|
pull-request | URL of the opened pull request; empty when there was nothing to promote. |
branch | Name of the branch the pull request was opened from. |
Example usage
Copy this caller into your project's .github/workflows/ directory (source):
yaml
# Example: call the reusable promote workflow.
# Copy this file into your project's .github/workflows/ directory.
#
# Adds a "Run workflow" form to the Actions tab that prepares a promotion as a
# pull request - for environment-branch models with story promotion or release
# bundles (see the B2 blueprint):
#
# - story promotion: target uat, sources feature/story-123
# - release bundle: target preprod, sources = the signed-off stories,
# base main, branch release/2026-11
# then: target main, base release/2026-11, no sources
# - sync after release: target uat, sources main
name: Promote
on:
workflow_dispatch:
inputs:
target:
description: Environment branch to promote into
type: choice
options: [integration, uat, preprod, main]
sources:
description: Branches to merge, comma-separated (empty = open a pull request from base)
type: string
base:
description: Branch to start from (empty = the target)
type: string
branch:
description: Name of the branch to create (empty = promotion/<source>-<target>)
type: string
# The called workflow pushes the promotion branch and opens the pull request. A
# reusable workflow can never get more permissions than the caller grants here.
permissions:
contents: write
pull-requests: write
jobs:
promote:
uses: svierk/salesforce-devops-starter-kit/.github/workflows/promote.yml@v1.5.0
with:
target: ${{ inputs.target }}
sources: ${{ inputs.sources }}
base: ${{ inputs.base }}
branch: ${{ inputs.branch }}
# A GitHub App with contents and pull request write access, installed on this
# repository. Without it the pull request is opened with the GITHUB_TOKEN and
# the PR validation never starts on it.
secrets:
PROMOTION_APP_ID: ${{ secrets.PROMOTION_APP_ID }}
PROMOTION_APP_PRIVATE_KEY: ${{ secrets.PROMOTION_APP_PRIVATE_KEY }}
# To open the sync pull requests automatically after every production
# deployment, add a second workflow triggered on push to main:
#
# on:
# push:
# branches: [main]
# jobs:
# sync:
# strategy:
# fail-fast: false
# matrix:
# target: [integration, uat, preprod]
# uses: svierk/salesforce-devops-starter-kit/.github/workflows/promote.yml@v1.5.0
# with:
# target: ${{ matrix.target }}
# sources: main
# secrets: inherit