Context
Reported in #27670. When a built-in job name (activation, agent, safe_outputs, conclusion) appears as a key under jobs: in frontmatter (for pre-steps customization per ADR-27138), the dependency-addition loop in compiler_main_job.go incorrectly adds the built-in job to another job's needs: list — causing duplicates or self-cycles that GitHub Actions rejects.
Specific bugs:
jobs.activation.pre-steps → activation gets added twice to agent.needs
jobs.agent.pre-steps → agent added to agent.needs (self-cycle)
jobs.safe_outputs.pre-steps → safe_outputs added to agent.needs, but safe_outputs already needs agent (cycle)
jobs.conclusion.pre-steps → similar cycle
Root Cause
In pkg/workflow/compiler_main_job.go, the loop that builds dependency lists only skips pre_activation / pre-activation, but data.Jobs now also contains entries for other built-in job names used as customization targets. The skip-list was never extended to cover activation, agent, safe_outputs, conclusion.
Objective
Extend the skip logic to exclude all built-in job names from being treated as custom dependencies when iterating data.Jobs.
Approach
- Add or update an
isBuiltInJobName(jobName string) bool helper function (or similar) in pkg/workflow/compiler_main_job.go (or pkg/constants) that covers at minimum:
pre_activation, pre-activation
activation
agent
safe_outputs, safe-outputs
conclusion
- Replace the existing
pre_activation-only skip check with isBuiltInJobName(jobName) in the dependency-addition loop.
Files to Modify
pkg/workflow/compiler_main_job.go — extend skip-list / add isBuiltInJobName helper
pkg/constants/ — consider adding built-in job name constants if not already present
pkg/workflow/compiler_main_job_test.go — add regression tests for each built-in job name
Acceptance Criteria
Generated by Plan Command for issue #27670 · ● 242.8K · ◷
Context
Reported in #27670. When a built-in job name (
activation,agent,safe_outputs,conclusion) appears as a key underjobs:in frontmatter (forpre-stepscustomization per ADR-27138), the dependency-addition loop incompiler_main_job.goincorrectly adds the built-in job to another job'sneeds:list — causing duplicates or self-cycles that GitHub Actions rejects.Specific bugs:
jobs.activation.pre-steps→activationgets added twice toagent.needsjobs.agent.pre-steps→agentadded toagent.needs(self-cycle)jobs.safe_outputs.pre-steps→safe_outputsadded toagent.needs, butsafe_outputsalready needsagent(cycle)jobs.conclusion.pre-steps→ similar cycleRoot Cause
In
pkg/workflow/compiler_main_job.go, the loop that builds dependency lists only skipspre_activation/pre-activation, butdata.Jobsnow also contains entries for other built-in job names used as customization targets. The skip-list was never extended to coveractivation,agent,safe_outputs,conclusion.Objective
Extend the skip logic to exclude all built-in job names from being treated as custom dependencies when iterating
data.Jobs.Approach
isBuiltInJobName(jobName string) boolhelper function (or similar) inpkg/workflow/compiler_main_job.go(orpkg/constants) that covers at minimum:pre_activation,pre-activationactivationagentsafe_outputs,safe-outputsconclusionpre_activation-only skip check withisBuiltInJobName(jobName)in the dependency-addition loop.Files to Modify
pkg/workflow/compiler_main_job.go— extend skip-list / addisBuiltInJobNamehelperpkg/constants/— consider adding built-in job name constants if not already presentpkg/workflow/compiler_main_job_test.go— add regression tests for each built-in job nameAcceptance Criteria
jobs.activation.pre-stepsdoes not produce duplicateneeds: [activation, activation]inagentjobs.agent.pre-stepsdoes not produce a self-cycleneeds: [agent]jobs.safe_outputs.pre-stepsdoes not create a dependency cyclejobs.conclusion.pre-stepsdoes not create a dependency cyclepre-stepsscenariomake agent-finishpassesRelated to on.github-app credentials cannot be sourced from a custom job's outputs (jobs.{pre_activation,activation}.pre-steps splicing/needs bugs + missing on.needs API) #27670