Skip to content

feat(wfctl): route infra output secrets#711

Merged
intel352 merged 1 commit into
mainfrom
fix/github-env-secret-routing
May 18, 2026
Merged

feat(wfctl): route infra output secrets#711
intel352 merged 1 commit into
mainfrom
fix/github-env-secret-routing

Conversation

@intel352
Copy link
Copy Markdown
Contributor

Summary

  • add GitHub Actions environment-secret scope to the wfctl GitHub secrets provider
  • add secrets.generate[].store routing for infra_output sync so provisioning outputs can write to named secret stores
  • document GitHub environment store config and add regression coverage

Verification

  • GOWORK=off go test ./config ./secrets ./cmd/wfctl -count=1

Copilot AI review requested due to automatic review settings May 18, 2026 18:50
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds support for routing infra_output secret generators to specific named secret stores and enables the GitHub secrets provider to target GitHub Actions environment-scoped secrets, so wfctl infra apply can pipe provisioning outputs (e.g. a database URL) directly into a per-environment secret destination.

Changes:

  • Extend GitHubSecretsProvider with SetEnvironment/Environment and centralized URL builders that switch between repo-level and environment-scoped Actions secret endpoints.
  • Add SecretGen.Store field and wire syncInfraOutputSecrets to resolve a per-generator provider from secretStores, with ${WORKFLOW_ENV} expansion in store config.
  • Update docs (docs/dsl-reference.md, embedded copy), CHANGELOG, and add tests covering environment scoping and store routing.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
secrets/github_provider.go Adds environment scope state and URL builders for Actions environment secret endpoints
secrets/github_provider_test.go Verifies environment-scoped endpoints for Set/List/public-key
config/secrets_config.go Adds Store field on SecretGen
config/secrets_multistore_test.go Asserts generate[].store round-trips through config
cmd/wfctl/infra.go Loads workflow config when any infra_output generator has env or store set
cmd/wfctl/infra_secrets.go Adds resolveSecretsProviderForEnv, WORKFLOW_ENV expansion, github environment wiring, and secretsConfigFromStore helper
cmd/wfctl/infra_secrets_test.go Covers env-scoped GitHub provider resolution
cmd/wfctl/infra_output_secrets.go Per-generator provider resolution + per-provider list cache refactor
cmd/wfctl/infra_output_secrets_test.go Asserts routing to a named store bypasses fallback provider
docs/dsl-reference.md, cmd/wfctl/dsl-reference-embedded.md Documents github provider config and generate[].store
CHANGELOG.md Notes the two new capabilities

Comment on lines +149 to +165
listLookups := map[secrets.Provider]*providerListLookup{}

stateOutputs := buildStateOutputsMap(states)

for _, gen := range gens {
genProvider, err := providerForSecretGen(wfCfg, provider, gen, envName)
if err != nil {
return err
}
lookupViaList := func(key string) (bool, error) {
lookup, ok := listLookups[genProvider]
if !ok {
lookup = &providerListLookup{provider: genProvider}
listLookups[genProvider] = lookup
}
return lookup.exists(ctx, key)
}
@codecov
Copy link
Copy Markdown

codecov Bot commented May 18, 2026

Codecov Report

❌ Patch coverage is 70.29703% with 30 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
cmd/wfctl/infra_secrets.go 61.36% 15 Missing and 2 partials ⚠️
cmd/wfctl/infra_output_secrets.go 68.42% 5 Missing and 7 partials ⚠️
cmd/wfctl/infra.go 66.66% 0 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

@github-actions
Copy link
Copy Markdown

⏱ Benchmark Results

No significant performance regressions detected.

benchstat comparison (baseline → PR)
## benchstat: baseline → PR
baseline-bench.txt:274: parsing iteration count: invalid syntax
baseline-bench.txt:529667: parsing iteration count: invalid syntax
baseline-bench.txt:865551: parsing iteration count: invalid syntax
baseline-bench.txt:1162114: parsing iteration count: invalid syntax
baseline-bench.txt:1481990: parsing iteration count: invalid syntax
baseline-bench.txt:1777650: parsing iteration count: invalid syntax
benchmark-results.txt:274: parsing iteration count: invalid syntax
benchmark-results.txt:294710: parsing iteration count: invalid syntax
benchmark-results.txt:562872: parsing iteration count: invalid syntax
benchmark-results.txt:893860: parsing iteration count: invalid syntax
benchmark-results.txt:1277558: parsing iteration count: invalid syntax
benchmark-results.txt:1623708: parsing iteration count: invalid syntax
goos: linux
goarch: amd64
pkg: github.com/GoCodeAlone/workflow/dynamic
cpu: AMD EPYC 7763 64-Core Processor                
                            │ baseline-bench.txt │
                            │       sec/op       │
InterpreterCreation-4               6.851m ± 55%
ComponentLoad-4                     3.581m ±  9%
ComponentExecute-4                  1.934µ ±  1%
PoolContention/workers-1-4          1.075µ ±  2%
PoolContention/workers-2-4          1.083µ ±  1%
PoolContention/workers-4-4          1.073µ ±  0%
PoolContention/workers-8-4          1.085µ ±  1%
PoolContention/workers-16-4         1.080µ ±  1%
ComponentLifecycle-4                3.613m ±  1%
SourceValidation-4                  2.304µ ±  0%
RegistryConcurrent-4                773.5n ±  6%
LoaderLoadFromString-4              3.633m ±  3%
geomean                             18.52µ

                            │ baseline-bench.txt │
                            │        B/op        │
InterpreterCreation-4               2.027Mi ± 0%
ComponentLoad-4                     2.180Mi ± 0%
ComponentExecute-4                  1.203Ki ± 0%
PoolContention/workers-1-4          1.203Ki ± 0%
PoolContention/workers-2-4          1.203Ki ± 0%
PoolContention/workers-4-4          1.203Ki ± 0%
PoolContention/workers-8-4          1.203Ki ± 0%
PoolContention/workers-16-4         1.203Ki ± 0%
ComponentLifecycle-4                2.183Mi ± 0%
SourceValidation-4                  1.984Ki ± 0%
RegistryConcurrent-4                1.133Ki ± 0%
LoaderLoadFromString-4              2.182Mi ± 0%
geomean                             15.25Ki

                            │ baseline-bench.txt │
                            │     allocs/op      │
InterpreterCreation-4                15.68k ± 0%
ComponentLoad-4                      18.02k ± 0%
ComponentExecute-4                    25.00 ± 0%
PoolContention/workers-1-4            25.00 ± 0%
PoolContention/workers-2-4            25.00 ± 0%
PoolContention/workers-4-4            25.00 ± 0%
PoolContention/workers-8-4            25.00 ± 0%
PoolContention/workers-16-4           25.00 ± 0%
ComponentLifecycle-4                 18.07k ± 0%
SourceValidation-4                    32.00 ± 0%
RegistryConcurrent-4                  2.000 ± 0%
LoaderLoadFromString-4               18.06k ± 0%
geomean                               183.3

cpu: Intel(R) Xeon(R) Platinum 8370C CPU @ 2.80GHz
                            │ benchmark-results.txt │
                            │        sec/op         │
InterpreterCreation-4                  7.674m ± 60%
ComponentLoad-4                        3.501m ± 13%
ComponentExecute-4                     1.856µ ±  1%
PoolContention/workers-1-4             1.208µ ±  1%
PoolContention/workers-2-4             1.207µ ±  2%
PoolContention/workers-4-4             1.187µ ±  3%
PoolContention/workers-8-4             1.192µ ±  1%
PoolContention/workers-16-4            1.203µ ±  1%
ComponentLifecycle-4                   3.533m ±  1%
SourceValidation-4                     2.223µ ±  1%
RegistryConcurrent-4                   895.8n ±  7%
LoaderLoadFromString-4                 3.596m ±  3%
geomean                                19.56µ

                            │ benchmark-results.txt │
                            │         B/op          │
InterpreterCreation-4                  2.027Mi ± 0%
ComponentLoad-4                        2.180Mi ± 0%
ComponentExecute-4                     1.203Ki ± 0%
PoolContention/workers-1-4             1.203Ki ± 0%
PoolContention/workers-2-4             1.203Ki ± 0%
PoolContention/workers-4-4             1.203Ki ± 0%
PoolContention/workers-8-4             1.203Ki ± 0%
PoolContention/workers-16-4            1.203Ki ± 0%
ComponentLifecycle-4                   2.183Mi ± 0%
SourceValidation-4                     1.984Ki ± 0%
RegistryConcurrent-4                   1.133Ki ± 0%
LoaderLoadFromString-4                 2.182Mi ± 0%
geomean                                15.25Ki

                            │ benchmark-results.txt │
                            │       allocs/op       │
InterpreterCreation-4                   15.68k ± 0%
ComponentLoad-4                         18.02k ± 0%
ComponentExecute-4                       25.00 ± 0%
PoolContention/workers-1-4               25.00 ± 0%
PoolContention/workers-2-4               25.00 ± 0%
PoolContention/workers-4-4               25.00 ± 0%
PoolContention/workers-8-4               25.00 ± 0%
PoolContention/workers-16-4              25.00 ± 0%
ComponentLifecycle-4                    18.07k ± 0%
SourceValidation-4                       32.00 ± 0%
RegistryConcurrent-4                     2.000 ± 0%
LoaderLoadFromString-4                  18.06k ± 0%
geomean                                  183.3

pkg: github.com/GoCodeAlone/workflow/middleware
cpu: AMD EPYC 7763 64-Core Processor                
                                  │ baseline-bench.txt │
                                  │       sec/op       │
CircuitBreakerDetection-4                  286.7n ± 4%
CircuitBreakerExecution_Success-4          21.50n ± 0%
CircuitBreakerExecution_Failure-4          66.34n ± 0%
geomean                                    74.23n

                                  │ baseline-bench.txt │
                                  │        B/op        │
CircuitBreakerDetection-4                 144.0 ± 0%
CircuitBreakerExecution_Success-4         0.000 ± 0%
CircuitBreakerExecution_Failure-4         0.000 ± 0%
geomean                                              ¹
¹ summaries must be >0 to compute geomean

                                  │ baseline-bench.txt │
                                  │     allocs/op      │
CircuitBreakerDetection-4                 1.000 ± 0%
CircuitBreakerExecution_Success-4         0.000 ± 0%
CircuitBreakerExecution_Failure-4         0.000 ± 0%
geomean                                              ¹
¹ summaries must be >0 to compute geomean

cpu: Intel(R) Xeon(R) Platinum 8370C CPU @ 2.80GHz
                                  │ benchmark-results.txt │
                                  │        sec/op         │
CircuitBreakerDetection-4                     455.0n ± 2%
CircuitBreakerExecution_Success-4             59.78n ± 0%
CircuitBreakerExecution_Failure-4             65.49n ± 0%
geomean                                       121.2n

                                  │ benchmark-results.txt │
                                  │         B/op          │
CircuitBreakerDetection-4                    144.0 ± 0%
CircuitBreakerExecution_Success-4            0.000 ± 0%
CircuitBreakerExecution_Failure-4            0.000 ± 0%
geomean                                                 ¹
¹ summaries must be >0 to compute geomean

                                  │ benchmark-results.txt │
                                  │       allocs/op       │
CircuitBreakerDetection-4                    1.000 ± 0%
CircuitBreakerExecution_Success-4            0.000 ± 0%
CircuitBreakerExecution_Failure-4            0.000 ± 0%
geomean                                                 ¹
¹ summaries must be >0 to compute geomean

pkg: github.com/GoCodeAlone/workflow/module
cpu: AMD EPYC 7763 64-Core Processor                
                                 │ baseline-bench.txt │
                                 │       sec/op       │
IaCStateBackend_InProcess-4              318.7n ±  2%
IaCStateBackend_GRPC-4                   9.599m ± 14%
JQTransform_Simple-4                     663.8n ± 35%
JQTransform_ObjectConstruction-4         1.503µ ±  0%
JQTransform_ArraySelect-4                3.463µ ±  5%
JQTransform_Complex-4                    39.45µ ±  1%
JQTransform_Throughput-4                 1.836µ ±  1%
SSEPublishDelivery-4                     63.88n ±  1%
geomean                                  3.856µ

                                 │ baseline-bench.txt │
                                 │        B/op        │
IaCStateBackend_InProcess-4             416.0 ±  0%
IaCStateBackend_GRPC-4                5.830Mi ± 12%
JQTransform_Simple-4                  1.273Ki ±  0%
JQTransform_ObjectConstruction-4      1.773Ki ±  0%
JQTransform_ArraySelect-4             2.625Ki ±  0%
JQTransform_Complex-4                 16.22Ki ±  0%
JQTransform_Throughput-4              1.984Ki ±  0%
SSEPublishDelivery-4                    0.000 ±  0%
geomean                                             ¹
¹ summaries must be >0 to compute geomean

                                 │ baseline-bench.txt │
                                 │     allocs/op      │
IaCStateBackend_InProcess-4              2.000 ± 0%
IaCStateBackend_GRPC-4                  6.841k ± 0%
JQTransform_Simple-4                     10.00 ± 0%
JQTransform_ObjectConstruction-4         15.00 ± 0%
JQTransform_ArraySelect-4                30.00 ± 0%
JQTransform_Complex-4                    324.0 ± 0%
JQTransform_Throughput-4                 17.00 ± 0%
SSEPublishDelivery-4                     0.000 ± 0%
geomean                                             ¹
¹ summaries must be >0 to compute geomean

cpu: Intel(R) Xeon(R) Platinum 8370C CPU @ 2.80GHz
                                 │ benchmark-results.txt │
                                 │        sec/op         │
IaCStateBackend_InProcess-4                 356.0n ± 28%
IaCStateBackend_GRPC-4                      10.03m ±  6%
JQTransform_Simple-4                        703.0n ± 32%
JQTransform_ObjectConstruction-4            1.538µ ±  1%
JQTransform_ArraySelect-4                   3.352µ ±  3%
JQTransform_Complex-4                       36.39µ ±  1%
JQTransform_Throughput-4                    1.875µ ±  2%
SSEPublishDelivery-4                        75.92n ±  1%
geomean                                     4.011µ

                                 │ benchmark-results.txt │
                                 │         B/op          │
IaCStateBackend_InProcess-4                416.0 ±  0%
IaCStateBackend_GRPC-4                   5.872Mi ± 13%
JQTransform_Simple-4                     1.273Ki ±  0%
JQTransform_ObjectConstruction-4         1.773Ki ±  0%
JQTransform_ArraySelect-4                2.625Ki ±  0%
JQTransform_Complex-4                    16.22Ki ±  0%
JQTransform_Throughput-4                 1.984Ki ±  0%
SSEPublishDelivery-4                       0.000 ±  0%
geomean                                                ¹
¹ summaries must be >0 to compute geomean

                                 │ benchmark-results.txt │
                                 │       allocs/op       │
IaCStateBackend_InProcess-4                 2.000 ± 0%
IaCStateBackend_GRPC-4                     6.878k ± 0%
JQTransform_Simple-4                        10.00 ± 0%
JQTransform_ObjectConstruction-4            15.00 ± 0%
JQTransform_ArraySelect-4                   30.00 ± 0%
JQTransform_Complex-4                       324.0 ± 0%
JQTransform_Throughput-4                    17.00 ± 0%
SSEPublishDelivery-4                        0.000 ± 0%
geomean                                                ¹
¹ summaries must be >0 to compute geomean

pkg: github.com/GoCodeAlone/workflow/schema
cpu: AMD EPYC 7763 64-Core Processor                
                                    │ baseline-bench.txt │
                                    │       sec/op       │
SchemaValidation_Simple-4                   1.098µ ±  5%
SchemaValidation_AllFields-4                1.678µ ± 15%
SchemaValidation_FormatValidation-4         1.578µ ±  3%
SchemaValidation_ManySchemas-4              1.803µ ±  1%
geomean                                     1.513µ

                                    │ baseline-bench.txt │
                                    │        B/op        │
SchemaValidation_Simple-4                   0.000 ± 0%
SchemaValidation_AllFields-4                0.000 ± 0%
SchemaValidation_FormatValidation-4         0.000 ± 0%
SchemaValidation_ManySchemas-4              0.000 ± 0%
geomean                                                ¹
¹ summaries must be >0 to compute geomean

                                    │ baseline-bench.txt │
                                    │     allocs/op      │
SchemaValidation_Simple-4                   0.000 ± 0%
SchemaValidation_AllFields-4                0.000 ± 0%
SchemaValidation_FormatValidation-4         0.000 ± 0%
SchemaValidation_ManySchemas-4              0.000 ± 0%
geomean                                                ¹
¹ summaries must be >0 to compute geomean

cpu: Intel(R) Xeon(R) Platinum 8370C CPU @ 2.80GHz
                                    │ benchmark-results.txt │
                                    │        sec/op         │
SchemaValidation_Simple-4                      1.031µ ± 32%
SchemaValidation_AllFields-4                   1.543µ ±  2%
SchemaValidation_FormatValidation-4            1.502µ ±  2%
SchemaValidation_ManySchemas-4                 1.498µ ±  2%
geomean                                        1.375µ

                                    │ benchmark-results.txt │
                                    │         B/op          │
SchemaValidation_Simple-4                      0.000 ± 0%
SchemaValidation_AllFields-4                   0.000 ± 0%
SchemaValidation_FormatValidation-4            0.000 ± 0%
SchemaValidation_ManySchemas-4                 0.000 ± 0%
geomean                                                   ¹
¹ summaries must be >0 to compute geomean

                                    │ benchmark-results.txt │
                                    │       allocs/op       │
SchemaValidation_Simple-4                      0.000 ± 0%
SchemaValidation_AllFields-4                   0.000 ± 0%
SchemaValidation_FormatValidation-4            0.000 ± 0%
SchemaValidation_ManySchemas-4                 0.000 ± 0%
geomean                                                   ¹
¹ summaries must be >0 to compute geomean

pkg: github.com/GoCodeAlone/workflow/store
cpu: AMD EPYC 7763 64-Core Processor                
                                   │ baseline-bench.txt │
                                   │       sec/op       │
EventStoreAppend_InMemory-4                1.221µ ± 14%
EventStoreAppend_SQLite-4                  1.581m ±  5%
GetTimeline_InMemory/events-10-4           13.12µ ±  4%
GetTimeline_InMemory/events-50-4           73.36µ ±  2%
GetTimeline_InMemory/events-100-4          147.5µ ±  7%
GetTimeline_InMemory/events-500-4          630.7µ ± 26%
GetTimeline_InMemory/events-1000-4         1.284m ±  1%
GetTimeline_SQLite/events-10-4             107.0µ ±  1%
GetTimeline_SQLite/events-50-4             248.2µ ±  1%
GetTimeline_SQLite/events-100-4            419.7µ ±  1%
GetTimeline_SQLite/events-500-4            1.768m ±  0%
GetTimeline_SQLite/events-1000-4           3.465m ±  0%
geomean                                    223.0µ

                                   │ baseline-bench.txt │
                                   │        B/op        │
EventStoreAppend_InMemory-4                  778.0 ± 4%
EventStoreAppend_SQLite-4                  1.983Ki ± 2%
GetTimeline_InMemory/events-10-4           7.953Ki ± 0%
GetTimeline_InMemory/events-50-4           46.62Ki ± 0%
GetTimeline_InMemory/events-100-4          94.48Ki ± 0%
GetTimeline_InMemory/events-500-4          472.8Ki ± 0%
GetTimeline_InMemory/events-1000-4         944.3Ki ± 0%
GetTimeline_SQLite/events-10-4             16.74Ki ± 0%
GetTimeline_SQLite/events-50-4             87.14Ki ± 0%
GetTimeline_SQLite/events-100-4            175.4Ki ± 0%
GetTimeline_SQLite/events-500-4            846.1Ki ± 0%
GetTimeline_SQLite/events-1000-4           1.639Mi ± 0%
geomean                                    67.26Ki

                                   │ baseline-bench.txt │
                                   │     allocs/op      │
EventStoreAppend_InMemory-4                  7.000 ± 0%
EventStoreAppend_SQLite-4                    53.00 ± 0%
GetTimeline_InMemory/events-10-4             125.0 ± 0%
GetTimeline_InMemory/events-50-4             653.0 ± 0%
GetTimeline_InMemory/events-100-4           1.306k ± 0%
GetTimeline_InMemory/events-500-4           6.514k ± 0%
GetTimeline_InMemory/events-1000-4          13.02k ± 0%
GetTimeline_SQLite/events-10-4               382.0 ± 0%
GetTimeline_SQLite/events-50-4              1.852k ± 0%
GetTimeline_SQLite/events-100-4             3.681k ± 0%
GetTimeline_SQLite/events-500-4             18.54k ± 0%
GetTimeline_SQLite/events-1000-4            37.29k ± 0%
geomean                                     1.162k

cpu: Intel(R) Xeon(R) Platinum 8370C CPU @ 2.80GHz
                                   │ benchmark-results.txt │
                                   │        sec/op         │
EventStoreAppend_InMemory-4                   1.153µ ± 15%
EventStoreAppend_SQLite-4                     929.1µ ±  5%
GetTimeline_InMemory/events-10-4              13.51µ ±  3%
GetTimeline_InMemory/events-50-4              74.10µ ±  2%
GetTimeline_InMemory/events-100-4             151.8µ ±  4%
GetTimeline_InMemory/events-500-4             760.3µ ±  3%
GetTimeline_InMemory/events-1000-4            1.515m ± 19%
GetTimeline_SQLite/events-10-4                82.33µ ±  2%
GetTimeline_SQLite/events-50-4                237.9µ ±  1%
GetTimeline_SQLite/events-100-4               425.7µ ±  2%
GetTimeline_SQLite/events-500-4               1.907m ±  2%
GetTimeline_SQLite/events-1000-4              3.686m ±  2%
geomean                                       217.1µ

                                   │ benchmark-results.txt │
                                   │         B/op          │
EventStoreAppend_InMemory-4                     769.0 ± 9%
EventStoreAppend_SQLite-4                     1.987Ki ± 1%
GetTimeline_InMemory/events-10-4              7.953Ki ± 0%
GetTimeline_InMemory/events-50-4              46.62Ki ± 0%
GetTimeline_InMemory/events-100-4             94.48Ki ± 0%
GetTimeline_InMemory/events-500-4             472.8Ki ± 0%
GetTimeline_InMemory/events-1000-4            944.3Ki ± 0%
GetTimeline_SQLite/events-10-4                16.74Ki ± 0%
GetTimeline_SQLite/events-50-4                87.14Ki ± 0%
GetTimeline_SQLite/events-100-4               175.4Ki ± 0%
GetTimeline_SQLite/events-500-4               846.1Ki ± 0%
GetTimeline_SQLite/events-1000-4              1.639Mi ± 0%
geomean                                       67.20Ki

                                   │ benchmark-results.txt │
                                   │       allocs/op       │
EventStoreAppend_InMemory-4                     7.000 ± 0%
EventStoreAppend_SQLite-4                       53.00 ± 0%
GetTimeline_InMemory/events-10-4                125.0 ± 0%
GetTimeline_InMemory/events-50-4                653.0 ± 0%
GetTimeline_InMemory/events-100-4              1.306k ± 0%
GetTimeline_InMemory/events-500-4              6.514k ± 0%
GetTimeline_InMemory/events-1000-4             13.02k ± 0%
GetTimeline_SQLite/events-10-4                  382.0 ± 0%
GetTimeline_SQLite/events-50-4                 1.852k ± 0%
GetTimeline_SQLite/events-100-4                3.681k ± 0%
GetTimeline_SQLite/events-500-4                18.54k ± 0%
GetTimeline_SQLite/events-1000-4               37.29k ± 0%
geomean                                        1.162k

Benchmarks run with go test -bench=. -benchmem -count=6.
Regressions ≥ 20% are flagged. Results compared via benchstat.

@intel352 intel352 merged commit 0affa24 into main May 18, 2026
28 checks passed
@intel352 intel352 deleted the fix/github-env-secret-routing branch May 18, 2026 19:05
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.

2 participants