Problem
publish-plan-task.yml decides the release gate for a push by string-matching the actor against an allowlist:
if [[ "$REF" == "main" ]] && { [[ "$ACTOR" == "ptr727-codegen[bot]" ]] || [[ "$ACTOR" == "dependabot[bot]" ]]; }; then
publish=true
fi
The allowlist is correct today - verified on ptr727/ESPHome-NonRoot, where every push-triggered publish run carries actor=ptr727-codegen[bot].
The concern is the failure mode, not the current value. If the App is ever renamed, replaced, or its installation reissued under a different slug, the comparison silently evaluates false, publish=false, and the publish job is skipped. Nothing errors, no annotation is emitted, and the run is green. Releases simply stop happening on pin pushes.
It is worse than a normal silent failure because the weekly schedule keeps publishing, so main still produces releases and the symptom is only a loss of timeliness - a new upstream version waits up to seven days instead of landing the same day. That is easy to miss for a long time, and it defeats the tracker's entire purpose, which is same-day upstream publishing.
The same shape applies to dependabot[bot], though GitHub is unlikely to rename that one.
Recommendation
Two options, cheapest first.
1. Annotate a non-publishing pin push (minimal, recommended). The push trigger is already path-scoped to the pin file, so the only legitimate non-publishing case is a human editing the pin by hand - rare, and worth surfacing anyway. Emit a warning instead of skipping quietly:
push)
if [[ "$REF" == "main" ]] && { [[ "$ACTOR" == "ptr727-codegen[bot]" ]] || [[ "$ACTOR" == "dependabot[bot]" ]]; }; then
publish=true
elif [[ "$REF" == "main" ]]; then
echo "::warning::Pin push on main by unrecognized actor '$ACTOR'; not publishing. If this is the codegen App under a new identity, update the allowlist in publish-plan-task.yml."
fi
;;
This keeps the gate's behavior identical and costs one line, but the run is visibly annotated rather than silently inert.
2. Resolve the identity instead of hardcoding it. Mint an App token with actions/create-github-app-token and read the App's own slug (GET /app), then compare against that. This removes the hardcoded string entirely, at the cost of a token mint per run and a heavier task. Worth it only if the allowlist proves fragile in practice.
Generalization
The transferable rule for the fleet: an identity allowlist used as a gate should fail loud, not open or closed in silence. A gate that can quietly stop gating - or quietly stop passing - looks identical to a healthy one in the Actions UI, and the tools that would normally catch a regression (status checks, lint) all stay green.
Context
Raised while reviewing ptr727/ESPHome-NonRoot#138, which adopts this task. Filing here because the task is shared, so the fix belongs upstream rather than in one consumer.
Problem
publish-plan-task.ymldecides the release gate for apushby string-matching the actor against an allowlist:The allowlist is correct today - verified on ptr727/ESPHome-NonRoot, where every push-triggered publish run carries
actor=ptr727-codegen[bot].The concern is the failure mode, not the current value. If the App is ever renamed, replaced, or its installation reissued under a different slug, the comparison silently evaluates false,
publish=false, and the publish job is skipped. Nothing errors, no annotation is emitted, and the run is green. Releases simply stop happening on pin pushes.It is worse than a normal silent failure because the weekly schedule keeps publishing, so
mainstill produces releases and the symptom is only a loss of timeliness - a new upstream version waits up to seven days instead of landing the same day. That is easy to miss for a long time, and it defeats the tracker's entire purpose, which is same-day upstream publishing.The same shape applies to
dependabot[bot], though GitHub is unlikely to rename that one.Recommendation
Two options, cheapest first.
1. Annotate a non-publishing pin push (minimal, recommended). The
pushtrigger is already path-scoped to the pin file, so the only legitimate non-publishing case is a human editing the pin by hand - rare, and worth surfacing anyway. Emit a warning instead of skipping quietly:This keeps the gate's behavior identical and costs one line, but the run is visibly annotated rather than silently inert.
2. Resolve the identity instead of hardcoding it. Mint an App token with
actions/create-github-app-tokenand read the App's own slug (GET /app), then compare against that. This removes the hardcoded string entirely, at the cost of a token mint per run and a heavier task. Worth it only if the allowlist proves fragile in practice.Generalization
The transferable rule for the fleet: an identity allowlist used as a gate should fail loud, not open or closed in silence. A gate that can quietly stop gating - or quietly stop passing - looks identical to a healthy one in the Actions UI, and the tools that would normally catch a regression (status checks, lint) all stay green.
Context
Raised while reviewing ptr727/ESPHome-NonRoot#138, which adopts this task. Filing here because the task is shared, so the fix belongs upstream rather than in one consumer.