When automating CI/CD releases, make “release vs non-release” and downstream publishing deterministic by (1) gating on explicit signals and (2) explicitly triggering the next workflow step.
Apply these rules:
release) rather than parsing PR titles to decide exemptions.workflow_dispatch with tag=).Example pattern (Bash label gating + explicit downstream dispatch):
LABELS="$(gh api "repos/${GITHUB_REPOSITORY}/issues/$PR_NUMBER/labels" --jq '.[].name')"
IS_RELEASE=0
if printf '%s\n' "$LABELS" | grep -qx 'release'; then
IS_RELEASE=1
fi
# ... later after creating/pushing tag ...
# Trigger publish workflow deterministically
gh workflow run release.yml -f tag="${TAG}" --ref "${DEFAULT_BRANCH}"
This reduces accidental bypasses and makes release pipelines predictable and auditable.