Skip to content

[GitHubActions] generator: typed workflow_dispatch inputs (string, boolean, number, choice, environment)#440

Merged
avidenic merged 8 commits into
Fallout-build:mainfrom
avidenic:features/386-github-actions-typed-dispatch-inputs
Jul 10, 2026
Merged

[GitHubActions] generator: typed workflow_dispatch inputs (string, boolean, number, choice, environment)#440
avidenic merged 8 commits into
Fallout-build:mainfrom
avidenic:features/386-github-actions-typed-dispatch-inputs

Conversation

@avidenic

@avidenic avidenic commented Jun 29, 2026

Copy link
Copy Markdown
Collaborator

Closes #386.

Adds a typed, compile-checked way to declare workflow_dispatch inputs via a new repeatable [GitHubActionsInput] attribute — replacing the untyped OnWorkflowDispatch*Inputs string arrays. Supports string/boolean/number/choice/environment, per-input default:, choice options:, and per-workflow scoping.

[GitHubActions("publish", GitHubActionsImage.UbuntuLatest, InvokedTargets = [nameof(Publish)])]
[GitHubActionsInput("DryRun", Type = GitHubActionsInputType.Boolean, Default = "false")]
[GitHubActionsInput("Channel", Type = GitHubActionsInputType.Choice, Options = ["alpha", "beta", "stable"], Default = "beta")]
on:
  workflow_dispatch:
    inputs:
      DryRun:
        description: "Dry Run"
        required: false
        type: boolean
        default: false
      Channel:
        description: "Channel"
        required: false
        type: choice
        default: beta
        options:
          - "alpha"
          - "beta"
          - "stable"

How it works

  • Collected off the build class via Build.GetType().GetCustomAttributes<…>(), mirroring the existing [AppVeyorSecret]/[TeamCityToken] pattern. Scoped per workflow by Workflows (empty = every dispatch workflow).
  • string inputs omit type:, so untyped output stays byte-identical. default: is emitted verbatim (per the issue; consistent with Env/CheckoutWith).
  • GetImports() still feeds every input, so each stays importable as env: NAME: ${{ github.event.inputs.NAME }}.

Misconfiguration is loud

Generation throws ArgumentException (not silent) for: choice without options, default outside options, non-numeric/non-boolean default, options on a non-choice, an unknown Workflows target, and duplicate/blank input names.

Backward compatibility

  • Legacy OnWorkflowDispatchOptionalInputs/RequiredInputs keep working, folded into the same model (emit first, untyped). Existing 9 snapshots are byte-identical.
  • Both legacy arrays are now [Obsolete]"Use [GitHubActionsInputAttribute] instead. Removed in 2027.x.x." Strictly additive; the removal is the future breaking change, batched to the year cut.

Tests

  • GitHubActionsInputValidationTest.cs — every loud check.
  • 3 Verify snapshot cases: dispatch-typed-inputs (all kinds), dispatch-input-scoping (Workflows filtering), dispatch-legacy-plus-typed (coexistence). The existing detailed-triggers case is now the regression guard for the obsolete legacy path.

@avidenic avidenic force-pushed the features/386-github-actions-typed-dispatch-inputs branch 2 times, most recently from e7dfff3 to 515326f Compare June 29, 2026 06:35
@avidenic avidenic marked this pull request as ready for review June 29, 2026 07:16
@avidenic avidenic requested a review from a team as a code owner June 29, 2026 07:16
@avidenic avidenic force-pushed the features/386-github-actions-typed-dispatch-inputs branch from be778e8 to 392af0f Compare June 30, 2026 07:37
@ITaluone

Copy link
Copy Markdown
Collaborator

What are the opinions regarding [Obsolete] since this attribute can be a breaking change as well?

@avidenic avidenic force-pushed the features/386-github-actions-typed-dispatch-inputs branch from 392af0f to 0a8ed8f Compare June 30, 2026 08:15
@avidenic

avidenic commented Jun 30, 2026

Copy link
Copy Markdown
Collaborator Author

What are the opinions regarding [Obsolete] since this attribute can be a breaking change as well?

Yeah, with TreatWarningsAsErrors it can. I Kept it warning-level as per AGENTS.md rule #2 a non-error [Obsolete] is the sanctioned deprecation; the removal (2027 major) is the actual break.

I can add a DiagnosticId so it's individually NoWarn-able if you'd prefer. I would probably need to add docs/obsolete-apis.md to mirror docs/experimental-apis.md. I think that route would warrant a separate issue / PR.

@ChrisonSimtian

Copy link
Copy Markdown
Collaborator

I'll try to look into this as soon as possible, promised. Just a bit busy at the moment :-(
To add to the discussion, I appreciate [Obsolete] and the DiagnosticId is a good idea!

@ChrisonSimtian ChrisonSimtian requested a review from a team July 1, 2026 02:22
@ChrisonSimtian

Copy link
Copy Markdown
Collaborator

@dennisdoomen this one please, I keep wanting to have a look but no spare time at the moment. This has been sitting here for a while now

@avidenic

avidenic commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator Author

@ChrisonSimtian No rush, TYT =)

@avidenic

avidenic commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator Author

@ChrisonSimtian I added #472 as a suggestion how to handle this.

@ITaluone ITaluone requested a review from ChrisonSimtian July 8, 2026 19:57
avidenic added 8 commits July 10, 2026 10:52
Typed, compile-checked declaration surface for workflow_dispatch inputs
(string/boolean/number/choice/environment), repeatable on the build class
and scoped by workflow. Pure data carriers; not yet consumed.
Collect [GitHubActionsInput] off the build class, scope by workflow name, and
fold the legacy OnWorkflowDispatch*Inputs arrays into one model. The trigger
writer emits type:/default:/options: (string omits type:, keeping existing
output byte-identical). Misconfiguration fails generation loudly via
ArgumentException (choice without options, default outside options/non-numeric/
non-boolean, unknown workflow name, options on a non-choice, duplicate or blank
names). The legacy arrays are marked [Obsolete] (removal 2027.x.x).
Covers every loud check: choice without options, default outside options,
options on a non-choice, non-numeric/non-boolean defaults, unknown workflow
name, duplicate names, and blank names.
Three Verify cases: every input kind (dispatch-typed-inputs), Workflows scoping
(dispatch-input-scoping), and legacy + typed coexistence (dispatch-legacy-plus-typed).
TestGitHubActionsAttribute gains a named-workflow ctor and Inputs/WorkflowNames
seams so cases vary inputs without static class-level attributes.
Workflow names are spaces-to-underscores normalized in the ctor, so an input's
Workflows scope must be normalized the same way. Without this, scoping to a
workflow declared with a space (e.g. "My Workflow") silently dropped the input
and validation threw "unknown workflow" for a correctly-spelled name.
Direct trigger-layer tests for the restored obsolete OptionalInputs/RequiredInputs
arrays (the attribute path only ever sets Inputs), plus equivalence guards proving
the obsolete and new APIs emit byte-identical YAML, and a regression test for
spaced-workflow scoping.
Trim the new inline comments to explain why (the test-injection seam, the
backward-compatible legacy fold, the spaced-name normalization) rather than
restating the code, matching the repo's concise comment style.
Give the four obsolete workflow_dispatch input arrays a DiagnosticId and
UrlFormat so consumers building with TreatWarningsAsErrors can NoWarn this one
deprecation instead of blanket-disabling CS0618.

A custom DiagnosticId replaces CS0618, so the internal bridge and test
suppressions are flipped to disable FALLOUTOBS001. Generated YAML is unchanged
(compile-time consumer diagnostic only), so no snapshots move.

Register FALLOUTOBS001 in the docs/obsolete_apis.md registry.
@avidenic avidenic force-pushed the features/386-github-actions-typed-dispatch-inputs branch from 5716a9d to 92bb537 Compare July 10, 2026 08:57
@avidenic avidenic merged commit 344de85 into Fallout-build:main Jul 10, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[GitHubActions] generator: typed workflow_dispatch inputs (string, boolean, number, choice, environment)

3 participants