Skip to content

feat(cigen): config-derived Jenkins + CircleCI renderers + wfctl four-platform support (#804)#810

Merged
intel352 merged 12 commits into
mainfrom
feat/cigen-jenkins-circleci-804
May 31, 2026
Merged

feat(cigen): config-derived Jenkins + CircleCI renderers + wfctl four-platform support (#804)#810
intel352 merged 12 commits into
mainfrom
feat/cigen-jenkins-circleci-804

Conversation

@intel352
Copy link
Copy Markdown
Contributor

Summary

PR 1 of 3 for #804. Adds config-derived cigen.RenderJenkins + cigen.RenderCircleCI (mechanical emitters from the existing CIPlan, mirroring the GHA renderer's plan/apply/smoke job set) and wires all four platforms into wfctl ci generate. No Analyze change, no new CIPlan field, no GHA/GitLab output change.

Refs #804 (acceptance #1: wfctl ci generate --platform jenkins|circleci config-derived). PR2 rewires the ci-generator plugin (acceptance #2); PR3 adds the workflow-scenarios proof.

Design / Plan / ADR

  • Design: docs/plans/2026-05-31-cigen-jenkins-circleci-design.md (adversarial design review PASS at cycle 3)
  • Plan: docs/plans/2026-05-31-cigen-jenkins-circleci.md (plan-phase PASS cycle 2; alignment PASS; scope locked)
  • ADR 0044: cigen Jenkins/CircleCI renderers omit the legacy docker-build/deploy stages (config-derived parity with GHA/GitLab).

Changes

  • cigen/render_jenkins.go — declarative Jenkinsfile: single linear stages{}; per-phase plan stages gated when { changeRequest() }; per-phase apply stages gated when { branch 'main' } with per-stage environment { NAME = credentials('NAME') } (scoped via phase.Scoped), plan-guard, last-phase migrations (wfctl migrations up), smoke. Header comment surfaces the Multibranch Pipeline requirement + the sorted required-credentials union.
  • cigen/render_circleci.go — CircleCI 2.1: per-phase plan/apply jobs + a workflows: graph (requires: chain, branch filters); auto-injected project env vars (no redundant re-declare); plan-guard; last-phase migrations; smoke.
  • cmd/wfctl/ci.go + ci_wizard.gojenkins/circleci cases in both render switches; all usage/flag text + both error strings list four platforms; wizard platformOptions extended.
  • docs/WFCTL.md — four-platform ci generate reference + examples.

Verification

  • go test ./cigen/ — PASS (Jenkins + CircleCI: config-derived markers, valid YAML/structure, scoped-phase binding, nil-plan, single-phase, absence of legacy go test/wfctl deploy --image/docker build per ADR 0044).
  • go test ./cmd/wfctl/ — PASS (four-platform switch dispatch).
  • golangci-lint run --new-from-rev=origin/main ./cigen/... ./cmd/wfctl/... — 0 issues.
  • Runtime-launch (real wfctl built from this branch):
    wfctl ci generate --platform jenkins  --config app.yaml --write  → wrote out/Jenkinsfile (pipeline {)
    wfctl ci generate --platform circleci --config app.yaml --write  → wrote out/.circleci/config.yml (version: 2.1)
    

Post-merge

Tag v0.68.0 (the prerequisite for PR2's go.mod bump). Version is ldflag-injected at release.

Note

Copilot review intentionally not requested (Copilot review broken). Merge gate = adversarial-review clean + two-stage code review APPROVED + CI green.

🤖 Generated with Claude Code

@codecov
Copy link
Copy Markdown

codecov Bot commented May 31, 2026

Codecov Report

❌ Patch coverage is 92.23301% with 16 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
cigen/render_circleci.go 93.10% 3 Missing and 3 partials ⚠️
cmd/wfctl/ci.go 68.42% 6 Missing ⚠️
cigen/render_jenkins.go 96.00% 2 Missing and 2 partials ⚠️

📢 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:307: parsing iteration count: invalid syntax
baseline-bench.txt:275054: parsing iteration count: invalid syntax
baseline-bench.txt:576537: parsing iteration count: invalid syntax
baseline-bench.txt:912391: parsing iteration count: invalid syntax
baseline-bench.txt:1241210: parsing iteration count: invalid syntax
baseline-bench.txt:1550667: parsing iteration count: invalid syntax
benchmark-results.txt:307: parsing iteration count: invalid syntax
benchmark-results.txt:310118: parsing iteration count: invalid syntax
benchmark-results.txt:644262: parsing iteration count: invalid syntax
benchmark-results.txt:966334: parsing iteration count: invalid syntax
benchmark-results.txt:1282472: parsing iteration count: invalid syntax
benchmark-results.txt:1587279: parsing iteration count: invalid syntax
goos: linux
goarch: amd64
pkg: github.com/GoCodeAlone/workflow/dynamic
cpu: AMD EPYC 7763 64-Core Processor                
                            │ benchmark-results.txt │
                            │        sec/op         │
InterpreterCreation-4                  9.828m ± 64%
ComponentLoad-4                        3.668m ±  3%
ComponentExecute-4                     1.935µ ±  2%
PoolContention/workers-1-4             1.084µ ±  3%
PoolContention/workers-2-4             1.082µ ±  1%
PoolContention/workers-4-4             1.077µ ±  2%
PoolContention/workers-8-4             1.080µ ±  1%
PoolContention/workers-16-4            1.121µ ±  2%
ComponentLifecycle-4                   3.755m ±  1%
SourceValidation-4                     2.442µ ±  1%
RegistryConcurrent-4                   870.9n ±  3%
LoaderLoadFromString-4                 3.797m ±  2%
geomean                                19.61µ

                            │ 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

cpu: AMD EPYC 9V74 80-Core Processor                
                            │ baseline-bench.txt │
                            │       sec/op       │
InterpreterCreation-4               9.437m ± 63%
ComponentLoad-4                     3.638m ± 10%
ComponentExecute-4                  1.852µ ±  2%
PoolContention/workers-1-4          1.034µ ±  2%
PoolContention/workers-2-4          1.056µ ±  2%
PoolContention/workers-4-4          1.045µ ±  5%
PoolContention/workers-8-4          1.022µ ±  1%
PoolContention/workers-16-4         1.046µ ±  2%
ComponentLifecycle-4                3.608m ±  1%
SourceValidation-4                  2.143µ ±  1%
RegistryConcurrent-4                779.1n ±  3%
LoaderLoadFromString-4              3.682m ±  1%
geomean                             18.60µ

                            │ 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

pkg: github.com/GoCodeAlone/workflow/middleware
cpu: AMD EPYC 7763 64-Core Processor                
                                  │ benchmark-results.txt │
                                  │        sec/op         │
CircuitBreakerDetection-4                     286.7n ± 1%
CircuitBreakerExecution_Success-4             21.55n ± 0%
CircuitBreakerExecution_Failure-4             67.43n ± 0%
geomean                                       74.68n

                                  │ 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

cpu: AMD EPYC 9V74 80-Core Processor                
                                  │ baseline-bench.txt │
                                  │       sec/op       │
CircuitBreakerDetection-4                  301.6n ± 5%
CircuitBreakerExecution_Success-4          22.65n ± 0%
CircuitBreakerExecution_Failure-4          70.91n ± 1%
geomean                                    78.54n

                                  │ 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

pkg: github.com/GoCodeAlone/workflow/module
cpu: AMD EPYC 7763 64-Core Processor                
                                 │ benchmark-results.txt │
                                 │        sec/op         │
IaCStateBackend_InProcess-4                 347.5n ± 17%
IaCStateBackend_GRPC-4                      9.625m ±  3%
JQTransform_Simple-4                        707.0n ± 38%
JQTransform_ObjectConstruction-4            1.595µ ±  1%
JQTransform_ArraySelect-4                   3.652µ ±  1%
JQTransform_Complex-4                       40.62µ ± 14%
JQTransform_Throughput-4                    1.976µ ±  1%
SSEPublishDelivery-4                        64.84n ±  5%
geomean                                     4.045µ

                                 │ benchmark-results.txt │
                                 │         B/op          │
IaCStateBackend_InProcess-4                 416.0 ± 0%
IaCStateBackend_GRPC-4                    5.933Mi ± 8%
JQTransform_Simple-4                      1.273Ki ± 0%
JQTransform_ObjectConstruction-4          1.773Ki ± 0%
JQTransform_ArraySelect-4                 2.625Ki ± 0%
JQTransform_Complex-4                     16.31Ki ± 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.841k ± 0%
JQTransform_Simple-4                        10.00 ± 0%
JQTransform_ObjectConstruction-4            15.00 ± 0%
JQTransform_ArraySelect-4                   30.00 ± 0%
JQTransform_Complex-4                       328.0 ± 0%
JQTransform_Throughput-4                    17.00 ± 0%
SSEPublishDelivery-4                        0.000 ± 0%
geomean                                                ¹
¹ summaries must be >0 to compute geomean

cpu: AMD EPYC 9V74 80-Core Processor                
                                 │ baseline-bench.txt │
                                 │       sec/op       │
IaCStateBackend_InProcess-4              301.8n ± 26%
IaCStateBackend_GRPC-4                   10.32m ± 19%
JQTransform_Simple-4                     679.5n ± 29%
JQTransform_ObjectConstruction-4         1.476µ ±  2%
JQTransform_ArraySelect-4                3.589µ ±  2%
JQTransform_Complex-4                    42.82µ ±  0%
JQTransform_Throughput-4                 1.802µ ±  6%
SSEPublishDelivery-4                     64.69n ±  1%
geomean                                  3.921µ

                                 │ baseline-bench.txt │
                                 │        B/op        │
IaCStateBackend_InProcess-4              416.0 ± 0%
IaCStateBackend_GRPC-4                 5.852Mi ± 7%
JQTransform_Simple-4                   1.273Ki ± 0%
JQTransform_ObjectConstruction-4       1.773Ki ± 0%
JQTransform_ArraySelect-4              2.625Ki ± 0%
JQTransform_Complex-4                  16.31Ki ± 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.862k ± 0%
JQTransform_Simple-4                     10.00 ± 0%
JQTransform_ObjectConstruction-4         15.00 ± 0%
JQTransform_ArraySelect-4                30.00 ± 0%
JQTransform_Complex-4                    328.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                
                                    │ benchmark-results.txt │
                                    │        sec/op         │
SchemaValidation_Simple-4                      1.111µ ± 13%
SchemaValidation_AllFields-4                   1.684µ ±  2%
SchemaValidation_FormatValidation-4            1.595µ ±  1%
SchemaValidation_ManySchemas-4                 1.817µ ±  4%
geomean                                        1.526µ

                                    │ 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

cpu: AMD EPYC 9V74 80-Core Processor                
                                    │ baseline-bench.txt │
                                    │       sec/op       │
SchemaValidation_Simple-4                   1.078µ ± 14%
SchemaValidation_AllFields-4                1.640µ ±  2%
SchemaValidation_FormatValidation-4         1.576µ ±  1%
SchemaValidation_ManySchemas-4              1.603µ ±  2%
geomean                                     1.454µ

                                    │ 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

pkg: github.com/GoCodeAlone/workflow/store
cpu: AMD EPYC 7763 64-Core Processor                
                                   │ benchmark-results.txt │
                                   │        sec/op         │
EventStoreAppend_InMemory-4                   1.240µ ± 16%
EventStoreAppend_SQLite-4                     1.324m ± 11%
GetTimeline_InMemory/events-10-4              14.16µ ±  6%
GetTimeline_InMemory/events-50-4              78.99µ ±  2%
GetTimeline_InMemory/events-100-4             159.8µ ±  5%
GetTimeline_InMemory/events-500-4             626.7µ ± 30%
GetTimeline_InMemory/events-1000-4            1.279m ±  1%
GetTimeline_SQLite/events-10-4                115.9µ ±  1%
GetTimeline_SQLite/events-50-4                258.1µ ±  0%
GetTimeline_SQLite/events-100-4               425.2µ ±  1%
GetTimeline_SQLite/events-500-4               1.826m ±  2%
GetTimeline_SQLite/events-1000-4              3.485m ±  3%
geomean                                       227.3µ

                                   │ benchmark-results.txt │
                                   │         B/op          │
EventStoreAppend_InMemory-4                     802.0 ± 4%
EventStoreAppend_SQLite-4                     1.982Ki ± 4%
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.42Ki

                                   │ 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

cpu: AMD EPYC 9V74 80-Core Processor                
                                   │ baseline-bench.txt │
                                   │       sec/op       │
EventStoreAppend_InMemory-4                1.093µ ± 18%
EventStoreAppend_SQLite-4                  1.070m ±  8%
GetTimeline_InMemory/events-10-4           13.18µ ±  5%
GetTimeline_InMemory/events-50-4           72.41µ ±  2%
GetTimeline_InMemory/events-100-4          109.9µ ± 35%
GetTimeline_InMemory/events-500-4          561.4µ ±  1%
GetTimeline_InMemory/events-1000-4         1.136m ±  1%
GetTimeline_SQLite/events-10-4             86.70µ ±  2%
GetTimeline_SQLite/events-50-4             224.0µ ±  1%
GetTimeline_SQLite/events-100-4            388.7µ ±  2%
GetTimeline_SQLite/events-500-4            1.701m ±  3%
GetTimeline_SQLite/events-1000-4           3.281m ±  0%
geomean                                    196.4µ

                                   │ baseline-bench.txt │
                                   │        B/op        │
EventStoreAppend_InMemory-4                  774.0 ± 6%
EventStoreAppend_SQLite-4                  1.984Ki ± 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.23Ki

                                   │ 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

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

@intel352 intel352 merged commit 9fcdc6c into main May 31, 2026
22 checks passed
@intel352 intel352 deleted the feat/cigen-jenkins-circleci-804 branch May 31, 2026 23:26
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.

1 participant