Inside a reusable workflow, github.event_name is the caller's event, never the literal string workflow_call. GitHub documents this:
"When a reusable workflow is triggered by a caller workflow, the github context is always associated with the caller workflow."
deploy-azure.yml's prepare job branches on it:
case "$EVENT_NAME" in
workflow_dispatch|workflow_call) ENVIRONMENT="$INPUT_ENVIRONMENT" ;;
*) ENVIRONMENT=dev ;;
esac
The workflow_call arm is dead code. The consequence is a silent environment downgrade on one path:
deploy-all.yml triggered by the release event sets environment=prod and passes it to deploy-azure.yml. Inside the called workflow github.event_name is release, so prepare takes the *) arm and returns dev. A release-triggered multi-cloud production deploy would deploy Azure to dev, with no error and a summary that says prod.
The workflow_dispatch path survives by luck: dispatching deploy-all.yml makes the caller's event workflow_dispatch, which the first arm happens to match.
The repo already knows about this
deploy-aws-lambda.yml:110-118 documents the behaviour and handles it, including an explicit release) TARGET_ENVIRONMENT=prod ;; arm. That is the pattern to copy.
Affected
deploy-azure.yml:88-91 (prepare)
deploy-gcp.yml:75-78
deploy-aws-fargate.yml:83-86
deploy-aws-lambda.yml:110-118 is already correct and is the reference implementation.
Because deploy-all.yml fans out to all of them, a release-triggered multi-cloud deploy silently targets dev on three clouds while the summary reports prod. That is the real blast radius, and it is why this is worth fixing rather than just documenting.
Evidence status
Documentation plus the existing in-repo comment. No empirical run: gh run list --workflow deploy-all.yml returns [], so deploy-all.yml has never executed and the release path has never been exercised. That is also why this has not bitten anyone yet.
Not a concurrency bug
Found while reviewing #1801 / #1803. It does not affect that fix: the concurrency group and the state key both derive from the same needs.prepare.outputs.environment, so whatever prepare decides, the group always names the blob that actually gets written. This changes which environment is deployed, never whether two writers of one blob serialize.
Inside a reusable workflow,
github.event_nameis the caller's event, never the literal stringworkflow_call. GitHub documents this:deploy-azure.yml'spreparejob branches on it:The
workflow_callarm is dead code. The consequence is a silent environment downgrade on one path:deploy-all.ymltriggered by thereleaseevent setsenvironment=prodand passes it todeploy-azure.yml. Inside the called workflowgithub.event_nameisrelease, sopreparetakes the*)arm and returns dev. A release-triggered multi-cloud production deploy would deploy Azure to dev, with no error and a summary that says prod.The
workflow_dispatchpath survives by luck: dispatchingdeploy-all.ymlmakes the caller's eventworkflow_dispatch, which the first arm happens to match.The repo already knows about this
deploy-aws-lambda.yml:110-118documents the behaviour and handles it, including an explicitrelease) TARGET_ENVIRONMENT=prod ;;arm. That is the pattern to copy.Affected
deploy-azure.yml:88-91(prepare)deploy-gcp.yml:75-78deploy-aws-fargate.yml:83-86deploy-aws-lambda.yml:110-118is already correct and is the reference implementation.Because
deploy-all.ymlfans out to all of them, a release-triggered multi-cloud deploy silently targets dev on three clouds while the summary reports prod. That is the real blast radius, and it is why this is worth fixing rather than just documenting.Evidence status
Documentation plus the existing in-repo comment. No empirical run:
gh run list --workflow deploy-all.ymlreturns[], sodeploy-all.ymlhas never executed and thereleasepath has never been exercised. That is also why this has not bitten anyone yet.Not a concurrency bug
Found while reviewing #1801 / #1803. It does not affect that fix: the concurrency group and the state key both derive from the same
needs.prepare.outputs.environment, so whateverpreparedecides, the group always names the blob that actually gets written. This changes which environment is deployed, never whether two writers of one blob serialize.