Skip to content

NO-JIRA: Add feature gate changes to changelog JSON output#2247

Open
stbenjam wants to merge 3 commits intoopenshift:mainfrom
stbenjam:fg-diff
Open

NO-JIRA: Add feature gate changes to changelog JSON output#2247
stbenjam wants to merge 3 commits intoopenshift:mainfrom
stbenjam:fg-diff

Conversation

@stbenjam
Copy link
Copy Markdown
Member

Summary

  • The changelog JSON output (oc adm release info --changelog --output=json) was missing feature gate change data that was only available in the markdown output
  • Adds a featureGates field to the ChangeLog JSON struct using the existing calculateFeatureSetDiff() logic
  • This enables downstream consumers (e.g. release-controller API) to access structured feature gate data without parsing markdown

Sample JSON output

{
  "featureGates": [
    {
      "name": "GatewayAPI",
      "status": {
        "Hypershift": {
          "Default": "Unconditionally Enabled (Changed)",
          "DevPreviewNoUpgrade": "Unconditionally Enabled (Changed)",
          "TechPreviewNoUpgrade": "Unconditionally Enabled (Changed)"
        },
        "SelfManagedHA": {
          "Default": "Unconditionally Enabled (Changed)",
          "DevPreviewNoUpgrade": "Unconditionally Enabled (Changed)",
          "TechPreviewNoUpgrade": "Unconditionally Enabled (Changed)"
        }
      }
    },
    {
      "name": "MachineConfigNodes",
      "status": {
        "Hypershift": {
          "Default": "Unconditionally Enabled (Changed)"
        },
        "SelfManagedHA": {
          "Default": "Unconditionally Enabled (Changed)"
        }
      }
    }
  ]
}

🤖 Generated with Claude Code

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 31, 2026

Important

Review skipped

Auto reviews are limited based on label configuration.

🚫 Review skipped — only excluded labels are configured. (1)
  • do-not-merge/work-in-progress

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: 4192c127-c113-4981-b2f5-b05dc3aed6a3

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

describeChangelog now computes feature-set diffs for JSON output, reports diff errors to errOut and sets hasError, and populates ChangeLog.FeatureGates with per-feature-gate status keyed by cluster-profile and feature-set; a new ChangeLogFeatureGateInfo type and FeatureGates field were added.

Changes

Cohort / File(s) Summary
Feature Gate Changelog Enhancement
pkg/cli/admin/release/info.go
When format == "json", call calculateFeatureSetDiff(diff) and on error write to errOut and set hasError. On success, build ChangeLog.FeatureGates as a slice of ChangeLogFeatureGateInfo containing Name and Status maps (cluster-profile → feature-set → status). Remove "LatencySensitive" from feature-set iteration. Added exported ChangeLogFeatureGateInfo type and FeatureGates []ChangeLogFeatureGateInfo field on ChangeLog.
Changelog JSON tests
pkg/cli/admin/release/info_changelog_test.go
Added tests for JSON changelog feature-gate reporting: TestDescribeChangelogFeatureGatesJSON verifies a gate changing from disabled→enabled is reported as Enabled (Changed) for the expected cluster-profile/feature-set; TestDescribeChangelogNoFeatureGatesJSON verifies empty featureGates when no manifests are present. Added helper featureGateManifest.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@openshift-ci openshift-ci bot requested review from ingvagabund and tchap March 31, 2026 12:47
@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci bot commented Mar 31, 2026

[APPROVALNOTIFIER] This PR is NOT APPROVED

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

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

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 the current code and only fix it if needed.

Inline comments:
In `@pkg/cli/admin/release/info.go`:
- Around line 1780-1802: The code silently ignores errors from
calculateFeatureSetDiff (the if uses err == nil) which can drop FeatureGates
without warning; change the block around calculateFeatureSetDiff so failures are
surfaced instead of ignored — e.g., if calculateFeatureSetDiff returns an error,
propagate or return that error (or log it and attach the error to the response)
rather than skipping population of changeLog.FeatureGates; adjust the
surrounding function (the caller that currently uses
featureSetDiff/GetOrderedFeatureGates/AllFeatureSets/AllClusterProfiles/FeatureInfoFor
and appends to changeLog.FeatureGates) to handle and return the error so callers
receive a clear failure instead of incomplete JSON.
🪄 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), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: 4a00f493-a878-419b-be9d-d5a2720ca23a

📥 Commits

Reviewing files that changed from the base of the PR and between 12f8fce and a6b76f4.

📒 Files selected for processing (1)
  • pkg/cli/admin/release/info.go

@stbenjam stbenjam force-pushed the fg-diff branch 2 times, most recently from b0bd727 to edce8fb Compare March 31, 2026 13:16
@tchap
Copy link
Copy Markdown
Contributor

tchap commented Mar 31, 2026

It would be lovely to also add some tests, please.

@stbenjam stbenjam force-pushed the fg-diff branch 2 times, most recently from 17a150b to 17e54ca Compare March 31, 2026 14:38
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
pkg/cli/admin/release/info_changelog_test.go (1)

45-186: Please cover the new failure path too.

These tests hit the success and empty-input cases, but not the new error branch at Line 1780. One malformed-manifest case should assert that describeChangelog(..., "json") returns ErrExit and reports the feature-gate diff failure on stderr, so this behavior doesn't regress.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/cli/admin/release/info_changelog_test.go` around lines 45 - 186, Add a
new unit test (e.g., TestDescribeChangelogFeatureGatesJSONMalformed) that
exercises the error branch in describeChangelog when parsing a malformed
manifest: build a ReleaseDiff where To or From.ManifestFiles contains an invalid
feature-gate YAML byte slice, call describeChangelog(out, errOut,
&ReleaseInfo{}, diff, "", "json"), assert the returned error equals ErrExit, and
assert errOut.String() contains a short identifying substring like
"feature-gate" or "feature gate" (to verify the feature-gate diff failure was
reported). Use the same helpers/structures from the file (featureGateManifest
pattern, ReleaseDiff, ReleaseInfo, ChangeLog) to locate relevant code paths and
keep the test style consistent with TestDescribeChangelogFeatureGatesJSON and
TestDescribeChangelogNoFeatureGatesJSON.
pkg/cli/admin/release/info.go (1)

1786-1803: Prune empty profile buckets and gates before appending to FeatureGates.

AllClusterProfiles() aggregates the union of all cluster profiles in the diff, so the loop at line 1794 eagerly allocates a status map for every profile. If a gate has no actual changes for a cluster profile (or only changes in the filtered LatencySensitive feature set), it creates empty {} entries. Worse, if a gate ends up with no statuses at all after filtering, it still gets appended, making the JSON unnecessarily noisy for downstream consumers.

Collect statuses conditionally—only add a profile's bucket if it contains changes, and only append the gate entry if it has at least one profile with changes.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/cli/admin/release/info.go` around lines 1786 - 1803, The loop building
ChangeLogFeatureGateInfo for each gate (involving orderedFeatureGates,
allClusterProfiles, allFeatureSets and featureSetDiff.FeatureInfoFor) eagerly
creates empty profile buckets and appends gates with no actual statuses to
changeLog.FeatureGates; fix by only creating fgInfo.Status[cp] when you find at
least one change for that profile (i.e., add cp only when
diffInfo.ChangedFeatureGates[fg] exists and produces a non-empty value), and
after scanning all profiles, append fgInfo to changeLog.FeatureGates only if
fgInfo.Status is non-empty (has >=1 profile key). Ensure you still skip the
"LatencySensitive" featureset as before when evaluating allFeatureSets.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@pkg/cli/admin/release/info_changelog_test.go`:
- Around line 45-186: Add a new unit test (e.g.,
TestDescribeChangelogFeatureGatesJSONMalformed) that exercises the error branch
in describeChangelog when parsing a malformed manifest: build a ReleaseDiff
where To or From.ManifestFiles contains an invalid feature-gate YAML byte slice,
call describeChangelog(out, errOut, &ReleaseInfo{}, diff, "", "json"), assert
the returned error equals ErrExit, and assert errOut.String() contains a short
identifying substring like "feature-gate" or "feature gate" (to verify the
feature-gate diff failure was reported). Use the same helpers/structures from
the file (featureGateManifest pattern, ReleaseDiff, ReleaseInfo, ChangeLog) to
locate relevant code paths and keep the test style consistent with
TestDescribeChangelogFeatureGatesJSON and
TestDescribeChangelogNoFeatureGatesJSON.

In `@pkg/cli/admin/release/info.go`:
- Around line 1786-1803: The loop building ChangeLogFeatureGateInfo for each
gate (involving orderedFeatureGates, allClusterProfiles, allFeatureSets and
featureSetDiff.FeatureInfoFor) eagerly creates empty profile buckets and appends
gates with no actual statuses to changeLog.FeatureGates; fix by only creating
fgInfo.Status[cp] when you find at least one change for that profile (i.e., add
cp only when diffInfo.ChangedFeatureGates[fg] exists and produces a non-empty
value), and after scanning all profiles, append fgInfo to changeLog.FeatureGates
only if fgInfo.Status is non-empty (has >=1 profile key). Ensure you still skip
the "LatencySensitive" featureset as before when evaluating allFeatureSets.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: d3f3d351-4294-47af-a5c4-76fc87557555

📥 Commits

Reviewing files that changed from the base of the PR and between d6a4a66 and 17a150b.

📒 Files selected for processing (2)
  • pkg/cli/admin/release/info.go
  • pkg/cli/admin/release/info_changelog_test.go

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

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 the current code and only fix it if needed.

Inline comments:
In `@pkg/cli/admin/release/info.go`:
- Around line 1784-1803: The code currently preallocates cluster-profile buckets
and may append empty ChangeLogFeatureGateInfo entries; modify the loop over
orderedFeatureGates so you first skip or remove the "LatencySensitive" gate (or
filter orderedFeatureGates) and then only create fgInfo.Status[cp] inside the
inner loop when you actually observe a change (i.e. when
featureSetDiff.FeatureInfoFor(cp, fs) yields a diff and
diffInfo.ChangedFeatureGates[fg] exists); after processing all profiles, only
append fgInfo to changeLog.FeatureGates if fgInfo.Status is non-empty (has at
least one profile key). This uses orderedFeatureGates, allFeatureSets (after
Delete), allClusterProfiles, FeatureInfoFor and ChangeLogFeatureGateInfo to
locate and fix the logic.
🪄 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), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: ff300291-ea3f-4e6f-920c-02d0562c6069

📥 Commits

Reviewing files that changed from the base of the PR and between 17a150b and 17e54ca.

📒 Files selected for processing (2)
  • pkg/cli/admin/release/info.go
  • pkg/cli/admin/release/info_changelog_test.go
✅ Files skipped from review due to trivial changes (1)
  • pkg/cli/admin/release/info_changelog_test.go

The changelog JSON output (`oc adm release info --changelog --output=json`)
was missing feature gate change data that was only available in the
markdown output. This adds a `featureGates` field to the ChangeLog JSON
struct, populated using the existing `calculateFeatureSetDiff()` logic.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@stbenjam
Copy link
Copy Markdown
Member Author

@tchap I added some tests and pulled out the shared Latency feature set into a helper, with a comment explaining it.

@tchap
Copy link
Copy Markdown
Contributor

tchap commented Apr 1, 2026

/retitle NO-JIRA: Add feature gate changes to changelog JSON output

@openshift-ci openshift-ci bot changed the title Add feature gate changes to changelog JSON output NO-JIRA: Add feature gate changes to changelog JSON output Apr 1, 2026
@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Apr 1, 2026
@openshift-ci-robot
Copy link
Copy Markdown

@stbenjam: This pull request explicitly references no jira issue.

Details

In response to this:

Summary

  • The changelog JSON output (oc adm release info --changelog --output=json) was missing feature gate change data that was only available in the markdown output
  • Adds a featureGates field to the ChangeLog JSON struct using the existing calculateFeatureSetDiff() logic
  • This enables downstream consumers (e.g. release-controller API) to access structured feature gate data without parsing markdown

Sample JSON output

{
 "featureGates": [
   {
     "name": "GatewayAPI",
     "status": {
       "Hypershift": {
         "Default": "Unconditionally Enabled (Changed)",
         "DevPreviewNoUpgrade": "Unconditionally Enabled (Changed)",
         "TechPreviewNoUpgrade": "Unconditionally Enabled (Changed)"
       },
       "SelfManagedHA": {
         "Default": "Unconditionally Enabled (Changed)",
         "DevPreviewNoUpgrade": "Unconditionally Enabled (Changed)",
         "TechPreviewNoUpgrade": "Unconditionally Enabled (Changed)"
       }
     }
   },
   {
     "name": "MachineConfigNodes",
     "status": {
       "Hypershift": {
         "Default": "Unconditionally Enabled (Changed)"
       },
       "SelfManagedHA": {
         "Default": "Unconditionally Enabled (Changed)"
       }
     }
   }
 ]
}

🤖 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.

@stbenjam
Copy link
Copy Markdown
Member Author

stbenjam commented Apr 1, 2026

/label tide/merge-method-squash

@openshift-ci openshift-ci bot added the tide/merge-method-squash Denotes a PR that should be squashed by tide when it merges. label Apr 1, 2026
@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci bot commented Apr 1, 2026

@stbenjam: The following test 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/e2e-agnostic-ovn-cmd b5cec64 link true /test e2e-agnostic-ovn-cmd

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.

- Use json.NewDecoder instead of json.Unmarshal
- Remove unused featureSet parameter from featureGateManifest
- Use cmp.Diff with expected objects instead of manual assertions
@stbenjam
Copy link
Copy Markdown
Member Author

stbenjam commented Apr 1, 2026

Updated.

@stbenjam
Copy link
Copy Markdown
Member Author

stbenjam commented Apr 1, 2026

/verified by stbenjam

$ /tmp/oc-test adm release info quay.io/openshift-release-dev/ocp-release:4.22.0-ec.4-x86_64 \
      --changes-from=quay.io/openshift-release-dev/ocp-release:4.22.0-ec.1-x86_64 \
      --changelog=/tmp/git/ --output=json | jq '.featureGates' | head -n 10
[
  {
    "name": "AdditionalRoutingCapabilities",
    "status": {
      "Hypershift": {
        "Default": "Unconditionally Enabled (Changed)",
        "DevPreviewNoUpgrade": "Unconditionally Enabled (Changed)",
        "OKD": "Unconditionally Enabled (Changed)",
        "TechPreviewNoUpgrade": "Unconditionally Enabled (Changed)"
      },

@openshift-ci-robot openshift-ci-robot added the verified Signifies that the PR passed pre-merge verification criteria label Apr 1, 2026
@openshift-ci-robot
Copy link
Copy Markdown

@stbenjam: This PR has been marked as verified by stbenjam.

Details

In response to this:

/verified by stbenjam

$ /tmp/oc-test adm release info quay.io/openshift-release-dev/ocp-release:4.22.0-ec.4-x86_64 \
     --changes-from=quay.io/openshift-release-dev/ocp-release:4.22.0-ec.1-x86_64 \
     --changelog=/tmp/git/ --output=json | jq '.featureGates' | head -n 10
[
 {
   "name": "AdditionalRoutingCapabilities",
   "status": {
     "Hypershift": {
       "Default": "Unconditionally Enabled (Changed)",
       "DevPreviewNoUpgrade": "Unconditionally Enabled (Changed)",
       "OKD": "Unconditionally Enabled (Changed)",
       "TechPreviewNoUpgrade": "Unconditionally Enabled (Changed)"
     },

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.

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

Labels

jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. tide/merge-method-squash Denotes a PR that should be squashed by tide when it merges. verified Signifies that the PR passed pre-merge verification criteria

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants