Skip to content

CNTRLPLANE-3780: feat(prowgen): add pipeline_run_if_dockerfile_changed annotation#5300

Open
celebdor wants to merge 1 commit into
openshift:mainfrom
celebdor:CNTRLPLANE-3780-pipeline-run-if-dockerfile-changed
Open

CNTRLPLANE-3780: feat(prowgen): add pipeline_run_if_dockerfile_changed annotation#5300
celebdor wants to merge 1 commit into
openshift:mainfrom
celebdor:CNTRLPLANE-3780-pipeline-run-if-dockerfile-changed

Conversation

@celebdor

@celebdor celebdor commented Jul 8, 2026

Copy link
Copy Markdown

Summary

  • Adds DockerfileEntry type and PipelineRunIfDockerfileChanged field to TestStepConfiguration
  • Prowgen serializes the field as a JSON pipeline_run_if_dockerfile_changed annotation on presubmit jobs
  • Validates mutual exclusivity with existing run_if_changed, skip_if_only_changed, pipeline_run_if_changed, and pipeline_skip_if_only_changed fields
  • Validates that each DockerfileEntry.Path is non-empty

This is the schema/prowgen half of CNTRLPLANE-3780 (first story under OCPSTRAT-3060). The pipeline-controller half that evaluates the annotation lives in openshift/ci-tools-standalone.

Test plan

  • go test ./pkg/api/... passes
  • go test ./pkg/prowgen/... passes (2 new test cases + fixtures)
  • go test ./pkg/validation/... passes (2 new test cases, updated error messages)
  • make ci-operator-reference regenerated zz_generated.ci_operator_reference.go

🤖 Generated with Claude Code

Added Dockerfile-aware change filtering to the CI config schema and presubmit job generation.

For CI users/operators, tests can now set pipeline_run_if_dockerfile_changed on TestStepConfiguration to have presubmit jobs carry a pipeline_run_if_dockerfile_changed JSON annotation. prowgen serializes this into the generated presubmit job annotations, enabling downstream controller logic (in openshift/ci-tools-standalone) to decide whether the pipeline “second stage” should run based on Dockerfile-referenced container image inputs.

The API introduces a new DockerfileEntry type (path plus optional go_binary_targets) and documents that Dockerfile impacts are resolved by parsing COPY/ADD instructions; go_binary_targets supports Go-dependency-aware filtering for Dockerfile COPY-all patterns.

Validation was updated to:

  • enforce mutual exclusivity between pipeline_run_if_dockerfile_changed and the existing change-filter fields (run_if_changed, skip_if_only_changed, pipeline_run_if_changed, pipeline_skip_if_only_changed)
  • require every DockerfileEntry.path to be non-empty

ci-operator reference docs and prowgen tests/fixtures were regenerated to cover the new annotation behavior.

@openshift-merge-bot

Copy link
Copy Markdown
Contributor

Pipeline controller notification
This repo is configured to use the pipeline controller. Second-stage tests will be triggered either automatically or after lgtm label is added, depending on the repository configuration. The pipeline controller will automatically detect which contexts are required and will utilize /test Prow commands to trigger the second stage.

For optional jobs, comment /test ? to see a list of all defined jobs. To trigger manually all jobs from second stage use /pipeline required command.

This repository is configured in: automatic mode

@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Jul 8, 2026
@openshift-ci-robot

openshift-ci-robot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

@celebdor: This pull request references CNTRLPLANE-3780 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "5.0.0" version, but no target version was set.

Details

In response to this:

Summary

  • Adds DockerfileEntry type and PipelineRunIfDockerfileChanged field to TestStepConfiguration
  • Prowgen serializes the field as a JSON pipeline_run_if_dockerfile_changed annotation on presubmit jobs
  • Validates mutual exclusivity with existing run_if_changed, skip_if_only_changed, pipeline_run_if_changed, and pipeline_skip_if_only_changed fields
  • Validates that each DockerfileEntry.Path is non-empty

This is the schema/prowgen half of CNTRLPLANE-3780 (first story under OCPSTRAT-3060). The pipeline-controller half that evaluates the annotation lives in openshift/ci-tools-standalone.

Test plan

  • go test ./pkg/api/... passes
  • go test ./pkg/prowgen/... passes (2 new test cases + fixtures)
  • go test ./pkg/validation/... passes (2 new test cases, updated error messages)
  • make ci-operator-reference regenerated zz_generated.ci_operator_reference.go

🤖 Generated with Claude Code

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: 81d4e14f-f1c6-4407-88d0-f9070dac169a

📥 Commits

Reviewing files that changed from the base of the PR and between 669ef54 and 2ecc245.

⛔ Files ignored due to path filters (2)
  • pkg/api/zz_generated.deepcopy.go is excluded by !**/zz_generated*
  • pkg/webreg/zz_generated.ci_operator_reference.go is excluded by !**/zz_generated*
📒 Files selected for processing (9)
  • pkg/api/types.go
  • pkg/prowgen/prowgen.go
  • pkg/prowgen/prowgen_test.go
  • pkg/prowgen/testdata/zz_fixture_TestGeneratePresubmitForTest_presubmit_with_always_run_but_pipeline_run_if_dockerfile_changed_set.yaml
  • pkg/prowgen/testdata/zz_fixture_TestGeneratePresubmitForTest_presubmit_with_always_run_false_and_pipeline_run_if_dockerfile_changed.yaml
  • pkg/validation/config.go
  • pkg/validation/config_test.go
  • pkg/validation/test.go
  • pkg/validation/test_test.go
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • openshift/release (manual)
  • openshift/ci-docs (manual)
  • openshift/release-controller (manual)
  • openshift/ci-chat-bot (manual)
✅ Files skipped from review due to trivial changes (1)
  • pkg/validation/config_test.go
🚧 Files skipped from review as they are similar to previous changes (8)
  • pkg/prowgen/testdata/zz_fixture_TestGeneratePresubmitForTest_presubmit_with_always_run_but_pipeline_run_if_dockerfile_changed_set.yaml
  • pkg/validation/test.go
  • pkg/api/types.go
  • pkg/validation/config.go
  • pkg/prowgen/testdata/zz_fixture_TestGeneratePresubmitForTest_presubmit_with_always_run_false_and_pipeline_run_if_dockerfile_changed.yaml
  • pkg/prowgen/prowgen.go
  • pkg/validation/test_test.go
  • pkg/prowgen/prowgen_test.go

📝 Walkthrough

Walkthrough

This PR adds a Dockerfile-aware pipeline trigger to test step configuration, propagates it into presubmit generation, and extends validation and tests for exclusivity and path checks.

Changes

Dockerfile-aware pipeline trigger

Layer / File(s) Summary
API contract
pkg/api/types.go
Adds DockerfileEntry and TestStepConfiguration.PipelineRunIfDockerfileChanged.
Presubmit generation
pkg/prowgen/prowgen.go, pkg/prowgen/prowgen_test.go, pkg/prowgen/testdata/zz_fixture_*pipeline_run_if_dockerfile_changed*.yaml
Threads the new field into presubmit generation, updates always-run handling, and adds fixture coverage for the emitted annotation.
Validation
pkg/validation/config.go, pkg/validation/config_test.go, pkg/validation/test.go, pkg/validation/test_test.go
Extends exclusivity validation to include the Dockerfile condition, enforces non-empty paths, and updates validation tests and messages.

Estimated code review effort: 3 (Moderate) | ~25 minutes

🚥 Pre-merge checks | ✅ 15 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Go Error Handling ⚠️ Warning pkg/prowgen/prowgen.go ignores json.Marshal error for pipeline_run_if_dockerfile_changed without justification. Handle marshal failure explicitly or document why it is impossible and safe to ignore; avoid bare _ on returned errors.
✅ Passed checks (15 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change by adding support for the pipeline_run_if_dockerfile_changed annotation in prowgen.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Test Coverage For New Features ✅ Passed Yes—new prowgen and validation logic has table-driven tests, plus fixtures cover annotation serialization and regression checks for exclusivity and empty Dockerfile paths.
Stable And Deterministic Test Names ✅ Passed No dynamic or runtime-derived test titles found; the added test names are static literals and use fixed case descriptions.
Test Structure And Quality ✅ Passed The changed tests are table-driven unit tests with fixtures and explicit error messages; no Ginkgo specs, cluster resources, or timeout risks were introduced.
Microshift Test Compatibility ✅ Passed Only unit tests and fixtures changed; no new Ginkgo e2e tests or MicroShift-unsafe APIs were added.
Single Node Openshift (Sno) Test Compatibility ✅ Passed PASS: The PR only adds API/prowgen/validation code plus Go unit tests; no new Ginkgo e2e specs or multi-node/HA assumptions were introduced.
Topology-Aware Scheduling Compatibility ✅ Passed Only schema/prowgen/validation plumbing changed; no manifests, controllers, replicas, affinity, nodeSelectors, or topology-aware scheduling logic were introduced.
Ote Binary Stdout Contract ✅ Passed No process-level stdout writes were added: the changed files only add schema/validation logic, and searches found no main/init/TestMain, fmt.Print*, klog, log.SetOutput, or os.Stdout usage.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed PASS: The PR only adds unit tests in pkg/*; no new Ginkgo e2e tests or external-network calls were introduced, so this check is not applicable.
No-Weak-Crypto ✅ Passed The changed code only adds Dockerfile-entry plumbing and validation; no weak crypto primitives, custom crypto, or secret/token comparisons were introduced.
Container-Privileges ✅ Passed No added privileged/root/host* or allowPrivilegeEscalation:true settings appear in the changed manifests; the new fixtures only add a JSON annotation.
No-Sensitive-Data-In-Logs ✅ Passed PASS: The diff adds schema/validation and annotation serialization only; no logging APIs or secret-bearing values were introduced in touched files.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@openshift-ci openshift-ci Bot requested review from Prucek and psalajova July 8, 2026 12:27
@openshift-ci

openshift-ci Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: celebdor
Once this PR has been reviewed and has the lgtm label, please assign psalajova 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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
pkg/api/types.go (1)

795-804: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Consider guarding Path against traversal.

DockerfileEntry.Path is a user-supplied relative path with no documented constraint against ../ segments. Since the value is later serialized into a job annotation and consumed by an external controller (per PR description), validation closer to the schema (e.g., in pkg/validation) should reject paths that escape the repo root, similar to canonicalization checks recommended for path-like fields.

As per path instructions, "Path traversal: canonicalize paths, reject ../" for **/*.{py,js,ts,go,rs,java,rb,php,kt,swift,cs}.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/api/types.go` around lines 795 - 804, Guard DockerfileEntry.Path against
path traversal by adding validation near the schema/validation layer instead of
trusting the raw field. Update the DockerfileEntry handling in pkg/api/types.go
and the corresponding validation path in pkg/validation so user-supplied paths
are canonicalized and any value containing ../ or otherwise escaping the repo
root is rejected before serialization into the job annotation. Use
DockerfileEntry and Path as the main symbols to locate the field and its
validation.

Source: Path instructions

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@pkg/prowgen/prowgen.go`:
- Around line 312-319: In the prowgen annotation setup, stop ignoring the
json.Marshal result for opts.pipelineRunIfDockerfileChanged and handle any
serialization failure explicitly. Update the block that writes
base.Annotations["pipeline_run_if_dockerfile_changed"] so it checks the marshal
error and returns it wrapped with fmt.Errorf, rather than silently continuing
with empty or invalid annotation data. Use the surrounding prowgen generation
logic and the pipelineOpt path to locate the fix.

---

Nitpick comments:
In `@pkg/api/types.go`:
- Around line 795-804: Guard DockerfileEntry.Path against path traversal by
adding validation near the schema/validation layer instead of trusting the raw
field. Update the DockerfileEntry handling in pkg/api/types.go and the
corresponding validation path in pkg/validation so user-supplied paths are
canonicalized and any value containing ../ or otherwise escaping the repo root
is rejected before serialization into the job annotation. Use DockerfileEntry
and Path as the main symbols to locate the field and its validation.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: 2cd67e85-3c8f-42a1-9588-ca261d0e4863

📥 Commits

Reviewing files that changed from the base of the PR and between 20f4909 and 9372c42.

⛔ Files ignored due to path filters (1)
  • pkg/webreg/zz_generated.ci_operator_reference.go is excluded by !**/zz_generated*
📒 Files selected for processing (9)
  • pkg/api/types.go
  • pkg/prowgen/prowgen.go
  • pkg/prowgen/prowgen_test.go
  • pkg/prowgen/testdata/zz_fixture_TestGeneratePresubmitForTest_presubmit_with_always_run_but_pipeline_run_if_dockerfile_changed_set.yaml
  • pkg/prowgen/testdata/zz_fixture_TestGeneratePresubmitForTest_presubmit_with_always_run_false_and_pipeline_run_if_dockerfile_changed.yaml
  • pkg/validation/config.go
  • pkg/validation/config_test.go
  • pkg/validation/test.go
  • pkg/validation/test_test.go
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • openshift/release (manual)
  • openshift/ci-docs (manual)
  • openshift/release-controller (manual)
  • openshift/ci-chat-bot (manual)

Comment thread pkg/prowgen/prowgen.go
Comment on lines +312 to +319
if len(opts.pipelineRunIfDockerfileChanged) > 0 {
if base.Annotations == nil {
base.Annotations = make(map[string]string)
}
data, _ := json.Marshal(opts.pipelineRunIfDockerfileChanged)
base.Annotations["pipeline_run_if_dockerfile_changed"] = string(data)
pipelineOpt = true
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Don't discard the json.Marshal error.

data, _ := json.Marshal(opts.pipelineRunIfDockerfileChanged) swallows the error entirely. DockerfileEntry currently only holds strings, so this can't fail today, but silently ignoring it hides any future serialization break (e.g., if the type gains a non-marshalable field) — the annotation would just come out empty/wrong with no diagnostic.

As per path instructions, "Wrap errors with fmt.Errorf(...)"/error handling requirements for **/*.go files.

🐛 Proposed fix
 	if len(opts.pipelineRunIfDockerfileChanged) > 0 {
 		if base.Annotations == nil {
 			base.Annotations = make(map[string]string)
 		}
-		data, _ := json.Marshal(opts.pipelineRunIfDockerfileChanged)
-		base.Annotations["pipeline_run_if_dockerfile_changed"] = string(data)
-		pipelineOpt = true
+		data, err := json.Marshal(opts.pipelineRunIfDockerfileChanged)
+		if err != nil {
+			logrus.WithError(err).Error("failed to marshal pipeline_run_if_dockerfile_changed")
+		} else {
+			base.Annotations["pipeline_run_if_dockerfile_changed"] = string(data)
+			pipelineOpt = true
+		}
 	}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if len(opts.pipelineRunIfDockerfileChanged) > 0 {
if base.Annotations == nil {
base.Annotations = make(map[string]string)
}
data, _ := json.Marshal(opts.pipelineRunIfDockerfileChanged)
base.Annotations["pipeline_run_if_dockerfile_changed"] = string(data)
pipelineOpt = true
}
if len(opts.pipelineRunIfDockerfileChanged) > 0 {
if base.Annotations == nil {
base.Annotations = make(map[string]string)
}
data, err := json.Marshal(opts.pipelineRunIfDockerfileChanged)
if err != nil {
logrus.WithError(err).Error("failed to marshal pipeline_run_if_dockerfile_changed")
} else {
base.Annotations["pipeline_run_if_dockerfile_changed"] = string(data)
pipelineOpt = true
}
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/prowgen/prowgen.go` around lines 312 - 319, In the prowgen annotation
setup, stop ignoring the json.Marshal result for
opts.pipelineRunIfDockerfileChanged and handle any serialization failure
explicitly. Update the block that writes
base.Annotations["pipeline_run_if_dockerfile_changed"] so it checks the marshal
error and returns it wrapped with fmt.Errorf, rather than silently continuing
with empty or invalid annotation data. Use the surrounding prowgen generation
logic and the pipelineOpt path to locate the fix.

Source: Path instructions

@celebdor celebdor force-pushed the CNTRLPLANE-3780-pipeline-run-if-dockerfile-changed branch from 9372c42 to 669ef54 Compare July 8, 2026 13:04
CNTRLPLANE-3780

Add a new `pipeline_run_if_dockerfile_changed` field to
TestStepConfiguration that allows tests to be conditionally run based
on whether files feeding into specified Dockerfiles have changed.

This is the first part of OCPSTRAT-3060 (dependency-aware CI job
filtering). The new field is mutually exclusive with the existing
run_if_changed, skip_if_only_changed, pipeline_run_if_changed, and
pipeline_skip_if_only_changed fields.

The prowgen serializes the field as a JSON annotation on the generated
presubmit job, which the pipeline-controller (in ci-tools-standalone)
will consume.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@celebdor celebdor force-pushed the CNTRLPLANE-3780-pipeline-run-if-dockerfile-changed branch from 669ef54 to 2ecc245 Compare July 9, 2026 10:23
@celebdor

Copy link
Copy Markdown
Author

/retest

@openshift-ci

openshift-ci Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

@celebdor: The following tests failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
ci/prow/integration 2ecc245 link true /test integration
ci/prow/frontend-checks 2ecc245 link true /test frontend-checks

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

@jmguzik

jmguzik commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

This might be interesting but we
/hold
for the time of onboarding repos on pipeline ctrl

@openshift-ci openshift-ci Bot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Jul 10, 2026
@jmguzik

jmguzik commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

/hold

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

Labels

do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants