Skip to content

Publish a daily GPU Operator chart and OLM bundle with main-branch operand images - #3087

Open
abrarshivani wants to merge 4 commits into
NVIDIA:mainfrom
abrarshivani:oci-chart-operands-main
Open

abrarshivani wants to merge 4 commits into
NVIDIA:mainfrom
abrarshivani:oci-chart-operands-main

Conversation

@abrarshivani

@abrarshivani abrarshivani commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Description

Publish a daily Helm chart and OLM bundle with main-branch operand images for CI and QA, and run forward compatibility against them.

  • publish-main-chart.yaml (daily) resolves the newest main image of each operand, prepares the chart values once, and publishes the chart, the bundle and a build record (chart, bundle and image digests), all tagged 0.0.0-main.<timestamp>.g<sha>. The record is pushed only when both chart and bundle were published. DCGM, DCGM exporter, GDS, GDRCopy, the driver and the DRA driver stay on released versions.
  • The bundle CSV is updated with the RC workflow's update-csv-images.py. Its name and version are unchanged, so a main bundle is installed on its own, not through a catalog.
  • forward-compatibility.yaml (Mondays) installs the chart of the newest recorded build, and fails if it is older than 48 hours or its digest changed. e2e-tests.yaml can now install a published chart via chart_reference and chart_version.

Using a main build

VERSION=$(regctl tag ls ghcr.io/nvidia/gpu-operator/main-builds | sort | tail -n 1)   # e.g. 0.0.0-main.20261016021703.gdbb11e85
regctl artifact get ghcr.io/nvidia/gpu-operator/main-builds:${VERSION} | jq .
helm install gpu-operator oci://ghcr.io/nvidia/gpu-operator/charts/gpu-operator --version ${VERSION}
operator-sdk run bundle ghcr.io/nvidia/gpu-operator/gpu-operator-bundle:${VERSION}

Checklist

  • No secrets, sensitive information, or unrelated changes
  • Lint checks passing (make lint): no Go changes; shellcheck and actionlint are clean on the changed scripts and workflows apart from findings that already exist on main
  • Generated assets in-sync (make validate-generated-assets): no generated assets touched
  • Go mod artifacts in-sync (make validate-modules): no module changes
  • Test cases are added for new code paths: the repo has no shell test framework, so the scripts were tested with local harnesses (below)

Testing

  • Script tests with stubbed curl, regctl, helm and sleep.
  • Packaged a main chart and bundle with real main images: overrides render in the ClusterPolicy, and operator-sdk bundle validate and make validate-csv pass.
  • Ran the daily workflow on a fork: chart, bundle and record were published, and the record was read back as forward compatibility reads it.

@abrarshivani
abrarshivani requested a review from a team as a code owner October 16, 2026 21:26
@abrarshivani abrarshivani self-assigned this Oct 16, 2026
@coderabbitai

coderabbitai Bot commented Oct 16, 2026

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: NVIDIA/gpu-operator/.coderabbit.yaml
  • Review profile: QUIET
  • Plan: Enterprise
  • Run ID: e17dd4a6-a211-4aef-9a45-782499c1974d
📥 Commits

Reviewing files that changed from the base of the PR and between dbb11e8 and eceece4.

📒 Files selected for processing: 8
  • .github/scripts/apply-values-overrides.sh
  • .github/scripts/generate-values-overrides.sh
  • .github/scripts/get-latest-images.sh
  • .github/scripts/get-latest-main-build.sh
  • .github/workflows/e2e-tests.yaml
  • .github/workflows/forward-compatibility.yaml
  • .github/workflows/publish-helm-oci-chart.yaml
  • .github/workflows/publish-main-chart.yaml

Included review availability: This review used your included allowance. Your plan provides up to 12 included reviews per hour; 11 remain after this review.

📝 Walkthrough

The changes add scripts to generate and apply chart image overrides and to locate recent main builds. A new workflow publishes a main Helm chart and OLM bundle and records their digests. The Helm publishing workflow can package a specified main chart version. E2E workflows accept an optional chart reference and version. The forward-compatibility workflow discovers a recent complete main build and supplies its chart and operator versions to E2E testing.

Priority: ➖ Normal

Merge Risk: ⚪ Minimal · up to eceec

The published chart, build record, and E2E chart selection have no identified merge-blocking mismatch. The change is ready for normal checks.

- [ ] Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

@rahulait

Copy link
Copy Markdown
Contributor

Instead of oci://ghcr.io/nvidia/gpu-operator/charts/gpu-operator:0.0.0-main.20261016021703.gdbb11e85, my preference would be oci://ghcr.io/nvidia/gpu-operator/charts/gpu-operator:0.0.0-main-20261016 as we expect to have one build per day for now, and commit id used is already there in the gpu-operator image in the chart. The URL remains fixed with a set pattern, so a user can simply specify the date to get oci helm chart for that date. They don't need to go back to the repo and also figure out the commit id and timestamp to pull the helm bundle. We could also use daily or something else instead of main if we want to.
@tariq1890 @rajathagasthya @kvalliyurnatt @cdesiniotis thoughts on this.

@abrarshivani
abrarshivani force-pushed the oci-chart-operands-main branch 3 times, most recently from b5d66fe to 11afc6b Compare October 16, 2026 22:46
get-latest-images.sh only knew toolkit, device-plugin and mig-manager,
always read the main branch and looked up one component per call.

Add driver-manager, vgpu-device-manager, the kata and kubevirt sandbox
device plugins and cc-manager. Each component names the branch to read
(main, or master for kubevirt-gpu-device-plugin) and an optional tag
suffix, since k8s-cc-manager publishes only <sha>-distroless commit
images.

The script now takes one or more components and resolves them
concurrently. Each lookup can still wait up to 7.5 minutes for its
component's CI to publish the image, so a caller no longer waits for
them one after another. Progress is streamed with the component name as
a prefix, results are printed as component=image lines, and when any
lookup fails every failed component is named in one error.
forward-compatibility.yaml resolves its three images with one call.

Signed-off-by: Abrar Shivani <ashivani@nvidia.com>
release-rc-assets.yaml installs Python, Go, PyYAML, regctl and
operator-sdk, then validates the OLM bundle and builds and pushes it
for amd64 and arm64. Move those steps into two composite actions so the
daily main bundle can use them as well:

- setup-olm-bundle-tools installs the tools.
- validate-and-push-olm-bundle validates the release metadata (when a
  release tag is given) and the bundle, logs in to GHCR, builds and
  pushes the image and returns its reference.

The RC workflow runs the same commands as before. The operator-sdk
download now uses curl -f, so a missing release fails at the download
instead of at the first operator-sdk call, the Docker login and Buildx
setup now run right before the build, and the build prints the pushed
image.

Signed-off-by: Abrar Shivani <ashivani@nvidia.com>
@abrarshivani
abrarshivani force-pushed the oci-chart-operands-main branch from 11afc6b to dca1d9c Compare October 16, 2026 22:53
Add publish-main-chart.yaml, which runs daily and can be started by hand
on the default branch only, so non-main code is never published as a
main build. Only scheduled failures alert Slack.

prepare-main-values checks that the operator image for the commit
exists and runs prepare-main-values.sh, which resolves the newest main
image of every operand that publishes per-commit images and prepares the
chart values once:

- generate-values-overrides.sh now takes VALUES_PATH=IMAGE pairs, so one
  image can fill several values, and splits each reference into
  repository, image and version, because driver-manager.fullimage joins
  the three fields itself.
- apply-values-overrides.sh merges them into values.yaml. It rejects
  paths that are not image values in the chart and checks that every
  image renders unchanged into the ClusterPolicy.
- The operator, validator and node status exporter use the operator
  image of the same commit.

dcgm, dcgm-exporter, gds, gdrcopy, the driver and the DRA driver stay on
their released versions: the first four have no per-commit builds, and
the driver and DRA driver use different tag schemes.

The prepared values are shared with two publish jobs, both using the
version 0.0.0-main.<UTC timestamp>.g<operator sha>. The timestamp keeps
each build unique because operand images change without new operator
commits, and makes the newest one sort last.

- The chart goes into the existing charts/gpu-operator package through a
  new main_chart_version input of publish-helm-oci-chart.yaml, so it
  keeps the access the e2e hosts rely on. The per-commit chart is built
  exactly as before.
- The bundle CSV is updated with update-csv-images.py, which pins each
  image by digest, checked to contain every override image, and
  validated and pushed with the shared OLM actions. Its CSV name and
  version are unchanged, so a main bundle is installed on its own.

When both are published, push-main-build-record.sh pushes a record of
the chart, bundle and image digests to gpu-operator/main-builds under
the same version, so a night where only one of them was published never
counts as a build. forward-compatibility.yaml moves to the new
generator arguments.

Signed-off-by: Abrar Shivani <ashivani@nvidia.com>
Forward compatibility resolved three operand images itself, published a
chart with released operands and copied a values file onto the test
host, so the published chart never contained what was tested.

It now finds the newest build record with get-latest-main-build.sh and
runs e2e against that build's chart, with the operator version taken
from its tag. The script fails if the newest record is older than 48
hours or the chart's digest no longer matches the record. The limit
leaves a failed Monday publish, which the publish workflow reports
itself, with Sunday's build to test. The workflow runs on Mondays at
04:17 UTC, two hours after the daily publish, and logs in to GHCR so
reading records does not depend on the package's visibility.

e2e-tests.yaml gets chart_reference and chart_version inputs. Given
both, it skips publishing a chart from the current commit and installs
the given one; the e2e jobs carry an explicit condition because the
skipped publish would otherwise skip them too. Either input alone is
rejected, and the jobs check that operator_version matches the chart's
appVersion, since install-operator.sh sets operator.version. Callers
that pass no chart publish and test exactly as before. The values-file
input and its copy steps are removed.

Signed-off-by: Abrar Shivani <ashivani@nvidia.com>
@abrarshivani
abrarshivani force-pushed the oci-chart-operands-main branch from dca1d9c to 101e1ce Compare October 16, 2026 23:16
set -euo pipefail

readonly IMAGE_REFERENCE_EXPRESSION='eval(strenv(VALUES_PATH)) | (.repository // "") + "/" + (.image // "") + ":" + (.version // "")'

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can we re-use .github/scripts/merge-yaml.py instead of this additional bash script to merge yamls?

This branch has not been deployed

No deployments
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.

2 participants