Skip to content

Use prefix matching for dependent bug target version validation - #190

Merged
openshift-merge-bot[bot] merged 1 commit into
openshift-eng:mainfrom
redhat-chai-bot:fix-dependent-target-version-prefix-match
Aug 11, 2026
Merged

openshift-merge-bot[bot] merged 1 commit into
openshift-eng:mainfrom
redhat-chai-bot:fix-dependent-target-version-prefix-match

Conversation

@redhat-chai-bot

@redhat-chai-bot redhat-chai-bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Summary

Fix dependent bug target version validation to use prefix matching (major.minor) instead of strict set membership. This aligns the dependent bug check with how validateTargetVersion() already handles primary bug versions.

Problem

When validating backport cherry-pick PRs, the plugin checks that dependent bugs target a version listed in DependentBugTargetVersions. This check uses strict string equality:

sets.NewString(*options.DependentBugTargetVersions...).Has(*depBug.targetVersion)

Once a release goes GA, Jira target versions change from X.Y.0 to X.Y.z (e.g. 4.22.04.22.z). The strict equality check rejects 4.22.z when the config specifies 4.22.0, even though they refer to the same release stream.

Meanwhile, the primary bug's target version is validated using prefix matching in validateTargetVersion(), which truncates to major.minor and uses strings.HasPrefix() — so both 4.22.0 and 4.22.z pass.

This inconsistency causes false negatives for any backport PR once the parent version goes GA. For example: openshift/hypershift#9263 (comment)

Fix

  • Add truncateVersionToMajorMinor() helper that truncates 4.22.04.22
  • Add dependentTargetVersionMatch() that truncates both the actual and configured versions to major.minor before comparing
  • DFBUGS projects retain exact matching, consistent with validateTargetVersion()

Testing

7 new test cases in TestValidateBug:

  • 4.22.z matches configured 4.22.0
  • 4.22.0 matches configured 4.22.z
  • 4.23.0 does NOT match 4.22.0
  • Exact match 4.22.0 = 4.22.0 still works ✅
  • DFBUGS: z-stream does NOT match GA (exact matching enforced) ✅
  • DFBUGS: exact match works ✅
  • Multi-version config works correctly ✅

All existing tests continue to pass.


AI-generated. Review for accuracy.

@bryan-cox requested in Slack thread

Summary by CodeRabbit

  • Bug Fixes
    • Improved dependent-bug target-version validation with project-specific matching rules.
    • OCPBUGS versions now match by normalized major and minor versions, including GA, z-stream, and openshift- prefixed variants.
    • DFBUGS versions require an exact configured-version match.
    • Added support for multiple configured target versions and direct target-version validation.
    • Improved handling for issues with missing or incomplete version information.

@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 17f88138-f613-4646-ab98-89f136ba4cf1

📥 Commits

Reviewing files that changed from the base of the PR and between 9581b8b and cd03cc1.

📒 Files selected for processing (1)
  • cmd/jira-lifecycle-plugin/server.go

📝 Walkthrough

Walkthrough

Dependent and direct target-version validation now use project-specific matching. DFBUGS requires exact configured-version equality. Other projects compare normalized major/minor versions and support an optional openshift- prefix.

Changes

Target-version validation

Layer / File(s) Summary
Project-specific version matching
cmd/jira-lifecycle-plugin/server.go
Dependent and direct target-version validation use shared matching helpers. DFBUGS uses exact matching. Other projects use normalized major/minor matching and handle optional openshift- prefixes.
Matching rule test coverage
cmd/jira-lifecycle-plugin/server_test.go
Tests cover GA and z-stream matching, exact matches, minor-version mismatches, multiple configured versions, DFBUGS exact matching, normalization, error text, and missing fields.

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

Suggested reviewers: bradmwilliams, hoxhaeris

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change to dependent bug target version validation.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@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

🤖 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 `@cmd/jira-lifecycle-plugin/server.go`:
- Around line 1688-1690: Update validateTargetVersion and its version-comparison
flow to remove the optional openshift- prefix from non-DFBUGS target versions
before applying truncateVersionToMajorMinor, preserving matches such as
openshift-4.22.z with configured 4.22.0. Add a regression test covering this
alias for a non-DFBUGS project.
🪄 Autofix

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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: b0b14f18-83b3-4524-bf5a-86ecfdb93e51

📥 Commits

Reviewing files that changed from the base of the PR and between 88ea3fc and b1cecf5.

📒 Files selected for processing (2)
  • cmd/jira-lifecycle-plugin/server.go
  • cmd/jira-lifecycle-plugin/server_test.go

Comment thread cmd/jira-lifecycle-plugin/server.go
}
}

func strPtr(s string) *string {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Can we use the k8s library function for this instead of making our own here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good question — I checked the vendored dependencies and there isn't a suitable k8s library function for this:

  • k8s.io/apimachinery/pkg/version handles Kubernetes API group versions (v1, v2beta1), not product semver versions like 4.22.0.
  • There's no pkg/util/version package vendored in this project.
  • No other semver/version parsing libraries are in the dependency tree.

Since all we need is to split on . and take the first two segments (a 5-line function), a custom helper seemed more appropriate than pulling in a new dependency. Happy to revisit if you know of a specific library that would fit.


AI-generated. Review for accuracy.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Are the new functions unit tested?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes! Added in the latest push (commit ff61559):

  • TestTruncateVersionToMajorMinor — 8 test cases covering: normal version (4.22.04.22), z-stream, openshift- prefix variants (3 cases), two-segment, single segment, and empty string.
  • TestDependentTargetVersionMatch — 9 test cases covering: exact match, prefix match, no match, openshift- prefix (both directions), DFBUGS exact matching, multiple configured versions, and nil field edge cases.
  • Also added an integration test in TestValidateBug for openshift-4.22.z matching configured 4.22.0 through the full validation flow.

AI-generated. Review for accuracy.

@redhat-chai-bot
redhat-chai-bot force-pushed the fix-dependent-target-version-prefix-match branch from ff61559 to 393e58f Compare August 10, 2026 15:35
@hoxhaeris

Copy link
Copy Markdown

/cc @AlexNPavel

@openshift-ci
openshift-ci Bot requested a review from AlexNPavel August 11, 2026 16:46
Comment on lines +1665 to +1698
// truncateVersionToMajorMinor truncates a version string like "4.22.0" to "4.22".
// It strips the "openshift-" prefix if present (e.g. "openshift-4.22.z" becomes "4.22").
// If the version has fewer than 2 dot-separated segments, it is returned as-is
// (with the prefix still stripped).
func truncateVersionToMajorMinor(version string) string {
version = strings.TrimPrefix(version, "openshift-")
pieces := strings.Split(version, ".")
if len(pieces) >= 2 {
return fmt.Sprintf("%s.%s", pieces[0], pieces[1])
}
return version
}

// dependentTargetVersionMatch checks whether the dependent bug's target version
// matches any of the configured valid target versions. For DFBUGS projects, an
// exact match is required (consistent with validateTargetVersion). For all other
// projects, versions are truncated to major.minor before comparison so that e.g.
// "4.22.z" matches a configured "4.22.0" (both truncate to "4.22").
func dependentTargetVersionMatch(actualVersion string, configuredVersions []string, parentBug *jira.Issue) bool {
projectKey := ""
if parentBug.Fields != nil {
projectKey = parentBug.Fields.Project.Key
}
if projectKey == "DFBUGS" {
return sets.NewString(configuredVersions...).Has(actualVersion)
}
truncatedActual := truncateVersionToMajorMinor(actualVersion)
for _, configured := range configuredVersions {
if truncateVersionToMajorMinor(configured) == truncatedActual {
return true
}
}
return false
}

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.

A lot of this code is shared with validateTargetVersion (such as the truncation and DFBUGS project check). We should have dependentTargetVersionMatch and validateTargetVersion share the validation code instead of duplicating it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good call — refactored in the latest push (commit 97dd2f0):

  • Extracted isExactVersionMatchProject() — shared helper that encapsulates the DFBUGS project check with nil-safe Fields access, now used by both validateTargetVersion and dependentTargetVersionMatch.
  • validateTargetVersion now reuses truncateVersionToMajorMinor() instead of manually inlining the strings.Split + fmt.Sprintf truncation logic.
  • Behavioral differences preserved: validateTargetVersion still uses strings.HasPrefix (single primary bug), while dependentTargetVersionMatch uses equality on truncated versions (checking against a list).
  • All existing tests pass unchanged — pure refactor, no behavior change.

AI-generated. Review for accuracy.

@redhat-chai-bot
redhat-chai-bot force-pushed the fix-dependent-target-version-prefix-match branch from 393e58f to 97dd2f0 Compare August 11, 2026 17:03

@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

🤖 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 `@cmd/jira-lifecycle-plugin/server.go`:
- Around line 1725-1729: Update the target-version validation around
isExactVersionMatchProject(issue) so DFBUGS compares targetVersion[0].Name
directly to requiredTargetVersion with equality, rejecting suffix and openshift-
variants before the existing non-DFBUGS prefix checks. Preserve the current
prefix-based behavior for non-DFBUGS projects and add rejection tests for both
invalid variants.
🪄 Autofix

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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: e088cbc1-e092-40a8-93e9-0a832d191f79

📥 Commits

Reviewing files that changed from the base of the PR and between b1cecf5 and 97dd2f0.

📒 Files selected for processing (2)
  • cmd/jira-lifecycle-plugin/server.go
  • cmd/jira-lifecycle-plugin/server_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • cmd/jira-lifecycle-plugin/server_test.go

Comment thread cmd/jira-lifecycle-plugin/server.go Outdated
Comment thread cmd/jira-lifecycle-plugin/server.go Outdated
@redhat-chai-bot
redhat-chai-bot force-pushed the fix-dependent-target-version-prefix-match branch from 97dd2f0 to 9581b8b Compare August 11, 2026 18:37
Comment thread cmd/jira-lifecycle-plugin/server.go Outdated
Comment on lines 1733 to 1736
truncatedRequiredTargetVersion := truncateVersionToMajorMinor(requiredTargetVersion)
truncatedPrefixedRequiredTargetVersion := fmt.Sprintf("openshift-%s", truncatedRequiredTargetVersion)
if !strings.HasPrefix(targetVersion[0].Name, truncatedRequiredTargetVersion) && !strings.HasPrefix(targetVersion[0].Name, truncatedPrefixedRequiredTargetVersion) {
return fmt.Errorf("expected the %s to target either version %q or %q, but it targets %q instead", issueType, fmt.Sprintf("%s.*", truncatedRequiredTargetVersion), fmt.Sprintf("%s.*", truncatedPrefixedRequiredTargetVersion), targetVersion[0].Name)

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 can be simplified to

if truncateVersionToMajorMinor(requiredTargetVersion) != truncateVersionMajorToMinor(targetVersion[0].name) {
	return fmt.Errorf("expected the %s to target either version %s.* or openshift-%s.*, but it targets %q instead", issueType, requiredTargetVersion, requiredTargetVersion, targetVersion[0].Name)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done — simplified in the latest push. The non-DFBUGS path now uses:

if truncateVersionToMajorMinor(requiredTargetVersion) != truncateVersionToMajorMinor(targetVersion[0].Name) {
    return fmt.Errorf("expected the %s to target either version %s.* or openshift-%s.*, but it targets %q instead",
        issueType, requiredTargetVersion, requiredTargetVersion, targetVersion[0].Name)
}
return nil

Replaced the multi-line HasPrefix + openshift- prefix block with a two-line truncate-both-sides comparison. All tests pass.


AI-generated. Review for accuracy.

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.

Put the "%s." and "openshift-%s." in quotes for clarity and so that the message matches the previous behavior.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done — quoted the version patterns in the latest push: "%s.*" and "openshift-%s.*". Updated the matching test expectations as well.


AI-generated. Review for accuracy.

@redhat-chai-bot

Copy link
Copy Markdown
Contributor Author

/retest-required


AI-generated. Review for accuracy.

@redhat-chai-bot
redhat-chai-bot force-pushed the fix-dependent-target-version-prefix-match branch from 9581b8b to bba6a19 Compare August 11, 2026 19:12
@redhat-chai-bot

Copy link
Copy Markdown
Contributor Author

/retest


AI-generated. Review for accuracy.

The dependent bug target version check used strict set membership,
requiring an exact match against DependentBugTargetVersions. This
caused false negatives once a release went GA and Jira target versions
changed from X.Y.0 to X.Y.z (e.g. 4.22.0 → 4.22.z).

Align with validateTargetVersion() by truncating both the configured
and actual versions to major.minor before comparing. The openshift-
prefix is also stripped for consistency. DFBUGS projects retain exact
matching.
@redhat-chai-bot
redhat-chai-bot force-pushed the fix-dependent-target-version-prefix-match branch from bba6a19 to cd03cc1 Compare August 11, 2026 20:26
@AlexNPavel

Copy link
Copy Markdown
Member

/lgtm

@openshift-ci openshift-ci Bot added the lgtm Indicates that a PR is ready to be merged. label Aug 11, 2026
@AlexNPavel

Copy link
Copy Markdown
Member

/approve

@openshift-ci

openshift-ci Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: AlexNPavel, redhat-chai-bot

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

The pull request process is described 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

@openshift-ci openshift-ci Bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Aug 11, 2026
@openshift-merge-bot
openshift-merge-bot Bot merged commit 95d8457 into openshift-eng:main Aug 11, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. lgtm Indicates that a PR is ready to be merged.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants