Skip to content

Add a typed step-injection pipeline to the GitHub Actions generator#475

Open
avidenic wants to merge 3 commits into
Fallout-build:mainfrom
avidenic:features/456-github-actions-step-injection
Open

Add a typed step-injection pipeline to the GitHub Actions generator#475
avidenic wants to merge 3 commits into
Fallout-build:mainfrom
avidenic:features/456-github-actions-step-injection

Conversation

@avidenic

Copy link
Copy Markdown
Collaborator

Closes #456.

Problem

GitHubActionsAttribute.GetSteps() yields a fixed, closed step sequence with no hook points and is private. No way to inject a marketplace action or custom shell step at a chosen position.

Outcome

A build implements IConfigureGitHubActions.ConfigureSteps(GitHubActionsStepPipeline) to inject typed uses:/run: steps at four named positions — compile-checked, no reflection.

partial class Build : NukeBuild, IConfigureGitHubActions
{
    public void ConfigureSteps(GitHubActionsStepPipeline pipeline)
    {
        if (pipeline.WorkflowName != "security") return;   // scope by workflow / runner
        pipeline.Insert(GitHubActionsStepPosition.PostRun, new GitHubActionsCustomStep
        {
            Name = "Perform CodeQL Analysis",
            Uses = "github/codeql-action/analyze@v3",
            If = "github.ref == 'refs/heads/main'",
        });
    }
}

New public types: GitHubActionsCustomStep, GitHubActionsStepPosition (PostCheckout/PreRun/PostRun/JobEnd), IConfigureGitHubActions, GitHubActionsStepPipeline.

Notes

Acceptance criteria

  • Inject uses:/run: at each of the four positions; multiple inserts at one position render in call order.
  • Positions resolve correctly with cache/artifacts absent.
  • Invalid steps fail generation with a clear ArgumentException.
  • Steps scope to a workflow/runner via WorkflowName/Image (no per-step scoping arrays).
  • No churn on existing snapshots.

Verification

Full Fallout.Common.Specs suite: 114 passed, 7 skipped, 0 failed. Zero snapshot churn. Full-solution build clean.

avidenic added 2 commits July 10, 2026 15:12
Introduce the public surface a build uses to inject custom workflow steps:
GitHubActionsCustomStep (uses:/run: with fixed-order YAML rendering),
GitHubActionsStepPosition (PostCheckout/PreRun/PostRun/JobEnd), the
IConfigureGitHubActions hook interface, and GitHubActionsStepPipeline (per-job
context + Insert + read-only BuiltInSteps view). Expose Fallout.Common internals
to Fallout.Common.Specs so the pipeline's generator-only surface stays internal
but testable.
Refactor GitHubActionsAttribute.GetSteps to assemble the base step sequence,
hand it to a per-job GitHubActionsStepPipeline as read-only BuiltInSteps, query
Build for IConfigureGitHubActions, validate the collected inserts, then splice
them in at their anchor positions (call order preserved). Validation fails the
build on an invalid step: exactly one of Uses/Run, With requires Uses, Shell
only on a run step. A build not implementing the interface, or one that inserts
nothing, yields byte-identical YAML.
@avidenic avidenic self-assigned this Jul 10, 2026
@avidenic avidenic added target/2026 Targets the 2026 calendar-version line (current). See ADR-0004. enhancement New feature or request labels Jul 10, 2026
Read the Write flow top-down; the Scalar/MapBlock local functions that close
over the list-marker flag now sit at the end. Behaviour is unchanged.
@avidenic avidenic marked this pull request as ready for review July 10, 2026 13:26
@avidenic avidenic requested a review from a team as a code owner July 10, 2026 13:26
Comment on lines +34 to +38
yaml.Should().Be(
"- name: Setup Node\n" +
" uses: actions/setup-node@v4\n" +
" with:\n" +
" node-version: 20\n");

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
yaml.Should().Be(
"- name: Setup Node\n" +
" uses: actions/setup-node@v4\n" +
" with:\n" +
" node-version: 20\n");
yaml.Should().Be(
"""
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20
""");

I vote for string literal in general, like so

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request target/2026 Targets the 2026 calendar-version line (current). See ADR-0004.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[GitHubActions] generator: a typed step-injection pipeline (custom steps at named positions)

2 participants