Skip to content

Refactor: Move CI workflow generation from cmd/ci to pkg/ci/github.#3572

Draft
twoGiants wants to merge 1 commit intoknative:mainfrom
twoGiants:issue-784-migration-to-pkg
Draft

Refactor: Move CI workflow generation from cmd/ci to pkg/ci/github.#3572
twoGiants wants to merge 1 commit intoknative:mainfrom
twoGiants:issue-784-migration-to-pkg

Conversation

@twoGiants
Copy link
Copy Markdown
Contributor

Changes

  • 🧹 Move CI workflow generation, printing, and writing from cmd/ci/ to pkg/ci/github/ as a self-contained, reusable package
  • 🎁 Introduce CI and PathWriter interfaces in pkg/functions/client.go so the client can orchestrate workflow generation without depending on the command layer
  • 🎁 Add GenerateCIWorkflow method to the client, routing func config ci through client.GenerateCIWorkflow() instead of calling the generator directly from the command
  • 🐛 Fix typos: --patform -> --platform, functionl -> function, proivdes -> provides, precldes -> precedes, sevices -> services, suppot -> support, Desribe -> Describe, pipilines -> pipelines, intance -> instance
  • 🧹 CIConfig now uses exported struct fields instead of getter methods, loaded upfront with runtime and root path encapsulated

/kind enhancement

Relates to #3256

Release Note


Docs


@knative-prow
Copy link
Copy Markdown

knative-prow bot commented Apr 2, 2026

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@knative-prow knative-prow bot added do-not-merge/work-in-progress 🤖 PR should not merge because it is a work in progress. kind/enhancement Feature additions or improvements to existing labels Apr 2, 2026
@knative-prow
Copy link
Copy Markdown

knative-prow bot commented Apr 2, 2026

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: twoGiants
Once this PR has been reviewed and has the lgtm label, please assign matzew for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@knative-prow knative-prow bot requested review from dsimansk and jrangelramos April 2, 2026 10:13
@knative-prow knative-prow bot added the size/XXL 🤖 PR changes 1000+ lines, ignoring generated files. label Apr 2, 2026
@knative-prow-robot knative-prow-robot added needs-rebase Cannot be merged due to conflicts with HEAD. labels Apr 2, 2026
@twoGiants twoGiants force-pushed the issue-784-migration-to-pkg branch from 293736b to 9ea2b6e Compare April 2, 2026 10:24
@knative-prow-robot knative-prow-robot removed the needs-rebase Cannot be merged due to conflicts with HEAD. label Apr 2, 2026
The CI workflow generation lived in cmd/ci/, tightly coupled to
the command layer via viper flag reads and direct file I/O. This
made it impossible to reuse or test the generator independently.

Move workflow generation, printing, and writing into
pkg/ci/github/ as a self-contained package. Introduce CI and
PathWriter interfaces in pkg/functions/client.go so the client
can orchestrate workflow generation without depending on the
cmd layer. The cmd/config_ci.go command now resolves flags and
delegates to client.GenerateCIWorkflow().

Also fix typos: --patform → --platform, functionl → function,
proivdes → provides, precldes → precedes, sevices → services,
suppot → support, Desribe → Describe, pipilines → pipelines,
intance → instance.

Issue knative#3256

Signed-off-by: Stanislav Jakuschevskij <sjakusch@redhat.com>
@twoGiants twoGiants force-pushed the issue-784-migration-to-pkg branch from 9ea2b6e to 2a954f6 Compare April 2, 2026 10:28
@codecov
Copy link
Copy Markdown

codecov bot commented Apr 2, 2026

Codecov Report

❌ Patch coverage is 86.49635% with 37 lines in your changes missing coverage. Please review.
✅ Project coverage is 56.37%. Comparing base (67c3fd2) to head (2a954f6).

Files with missing lines Patch % Lines
pkg/ci/github/workflow.go 63.15% 9 Missing and 5 partials ⚠️
pkg/ci/github/generator.go 38.09% 10 Missing and 3 partials ⚠️
pkg/ci/github/common.go 62.50% 4 Missing and 2 partials ⚠️
pkg/functions/client.go 82.35% 3 Missing ⚠️
cmd/build.go 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3572      +/-   ##
==========================================
+ Coverage   56.13%   56.37%   +0.24%     
==========================================
  Files         180      181       +1     
  Lines       20465    20486      +21     
==========================================
+ Hits        11489    11550      +61     
+ Misses       7781     7744      -37     
+ Partials     1195     1192       -3     
Flag Coverage Δ
e2e 36.11% <3.28%> (+<0.01%) ⬆️
e2e go 32.57% <3.25%> (+0.01%) ⬆️
e2e node 28.38% <3.25%> (+0.02%) ⬆️
e2e python 32.93% <3.25%> (+0.01%) ⬆️
e2e quarkus 28.50% <3.25%> (+0.02%) ⬆️
e2e rust 27.94% <3.25%> (+0.03%) ⬆️
e2e springboot 26.38% <3.25%> (+0.02%) ⬆️
e2e typescript 28.49% <3.25%> (+<0.01%) ⬆️
e2e-config-ci 18.19% <71.54%> (?)
integration 17.39% <0.40%> (-0.03%) ⬇️
unit macos-14 43.42% <79.67%> (+0.05%) ⬆️
unit macos-latest 43.42% <79.67%> (+0.05%) ⬆️
unit ubuntu-24.04-arm 43.64% <77.37%> (+0.07%) ⬆️
unit ubuntu-latest 44.30% <79.67%> (+0.04%) ⬆️
unit windows-latest 43.44% <79.67%> (+0.05%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Comment on lines +193 to +194
fn.WithPathWriter(pathWriter),
fn.WithStdout(cmd.OutOrStdout()),
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

These could be constructor arguments on the CI generator implementation.

DefaultForce = false
)

type Config struct {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Perhaps turn these all (except FnRuntime and FnRoot) into members of the Generator, set as part of construction, and add verbose. Then, for example, if this struct is renamed WorkflowGeneratorOptions, then the constructor becomes simply: NewWorkflowGenerator(opts WorkflowGeneratorOptions) *WorkflowGenerator and the CI interface in client becomes:
Generate(ctx context.Context, f Function)

The implementation then pulls the FnRuntime and FnRoot from f, and everything else from it's WorkflowGeneratorOptions struct.

}

type CI interface {
Generate(context.Context, any, PathWriter, io.Writer) error
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is definitely the right pattern; keeping everything neatly gated behind an interface, and dependencies held at bay.
Simply moving most of the config to the concrete implementation's constructor (as well as the writers), and we can keep only the universal settings here. That could yield an actualy gramatically correct interface:
"Generate a CI Workflow for function X" == Generate(context.Context, Function) error

Start(context.Context, bool) error
}

type CI interface {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

While I know it's not nearly as pretty, the Go idiom is to use something like "CIGenerator" here. That way it flows rather nicely:

generator := github.CIGenerator(...)
generator.Generate(ctx, f)

assert.NilError(t, result.executeErr)
}

func TestNewConfigCICmd_WritesWorkflowFile(t *testing.T) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The CLI's job is to translate a request into an API call, so if you use a mock CIGenerator here to ensure flags show up in that struct's constructor as-expected, and that it's Generate method is invoked when expected, then the testing here in the CLI is complete!

Then, you can rely on the tests in the github package to ensure that the implementation is correct (writes a workflow file, and writes it with the correct structure). That might simplify things here.

@@ -362,7 +362,7 @@
func TestNewConfigCICmd_ForceFlagOverwritesExistingWorkflow(t *testing.T) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Here's a concrete example! Notice how the behavior is : the GitHub CI Generator overwrites an existing workflow file when force is enabled.

That's a test for the implementation itself. The CLI needs to make sure that that force is set to true if --force is provided, and leave the rest up to the implementation.

This tests actually looks a lot like an E2E. Where you'd actually call the cli command twice and confirm it overwrote interstital changes.

Branch: %s
Builder: %s
Remote build: %s
Remote build %s
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This looks like an inadvertent change

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

Labels

do-not-merge/work-in-progress 🤖 PR should not merge because it is a work in progress. kind/enhancement Feature additions or improvements to existing size/XXL 🤖 PR changes 1000+ lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants