Skip to content

✨ feat(olm): validate the bundle locally with the modern validator set - #312

Merged
konih merged 2 commits into
mainfrom
lane/dist-oh-02-bundle-validation
Aug 18, 2026
Merged

✨ feat(olm): validate the bundle locally with the modern validator set#312
konih merged 2 commits into
mainfrom
lane/dist-oh-02-bundle-validation

Conversation

@konih

@konih konih commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator

Headline discovery — why this design looks unusual

operator-sdk's --select-optional is a plain string flag, not a slice. Passing it three times in one bundle validate invocation silently keeps only the last selector. The obvious one-liner therefore exits 0 on a bundle with a real defect — it looks like it validates three things and validates one.

Verified in both directions by the author and independently reproduced by the reviewer. Hence three separate bundle validate invocations, plus a shape gate asserting count(bundle validate) == count(--select-optional) so nobody "simplifies" it back into a silently-vacuous single call.

Second trap: the AC's names (operatorhub/v2, standardcapabilities, standardcategories) are Go identities in operator-framework/api, not CLI selectors. --select-optional name=operatorhub/v2 is a fatal parse error. The working CLI names are operatorhubv2, capabilities, categories.

What this lands

DIST-OH-02 — local OLM bundle validation with the modern validator set

  • hack/install-operator-sdk.sh — new, installs a checksum-verified pinned operator-sdk v1.42.3 into ./bin.
  • make validate-olm-bundle runs the three validators as three invocations; gate asserts the 1:1 shape.
  • No skip path. The gate hard-fails with an actionable message when operator-sdk is absent, rather than degrading to green-but-vacuous coverage. The reviewer attempted to defeat this and could not.
  • The release path fails closed. hack/operatorhub-pr.sh runs under set -Eeuo pipefail with the validate call unwrapped and upstream of every push, so a failed installer aborts before any bytes reach the third-party repo.
  • CI installs operator-sdk in the lint job, upstream of the dist_* glob that consumes it.

GATE-OWNED-01 (folded in)owned[]config/crd/bases set comparison, bidirectional, both directions perturbation-verified.

CSV template unchanged. Monitoring, Integration & Delivery, Full Lifecycle were verified standard against the pinned binary, not modified.

Verification

Full gate matrix re-run on this exact SHA with operator-sdk present:

  • all 7 hack/test/dist_*_test.sh — pass (incl. the real 3-validator run against a generated bundle)
  • task verify, task lint, task test, task lint:shell — rc=0
  • pre-commit run --files <8 changed> — pass

task changelog:verify is red because this lane's own commits are the drift; the changelog-sync bot self-heals post-merge.

Follow-ups

Independent review: APPROVE, no P0/P1. One P2 and six P3, all explicitly non-blocking, captured as story GATE-HARDEN-01 — notably the CI-wiring gate compares file-global line numbers rather than steps within the lint job, so it can pass vacuously if the install step is moved to another job. Verified by eye on this diff that the step is genuinely inside lint and upstream of the glob.

konih added 2 commits August 18, 2026 15:42
The bundle gate proved each config/crd/bases file is COPIED into the bundle
and that alm-examples matches spec.customresourcedefinitions.owned, but
nothing asserted owned[] itself covers config/crd/bases. A synthetic 12th CRD
base added without touching owned[] kept the gate green: OLM would install the
CRD while the console never lists the API, and the alm-examples check still
passes because it compares against the very list that is missing the kind.

Add a third set comparison between the CRD base kinds and owned[], on both the
CSV template and the generated CSV, with both sides asserted non-empty so a
mistyped yq path cannot make it pass vacuously.
Bundle defects were only discovered after pushing to community-operators and
reading their pipeline output -- which is how the missing alm-examples were
found. Add `make validate-olm-bundle`, running the validator set that upstream
now recommends in place of the deprecated `operatorhub` validator, and wire it
into the dist_* gate glob and the OperatorHub submission path.

Two findings worth recording:

* The CLI selector names differ from the deprecation message. `operatorhub/v2`
  is a fatal label-parse error; operator-sdk registers the three validators as
  `operatorhubv2`, `capabilities` and `categories`
  (`bundle validate --list-optional`). They map to OperatorHubV2Validator,
  StandardCapabilitiesValidator and StandardCategoriesValidator.
* `--select-optional` is a plain string flag, not a repeatable slice. Passing
  it three times in ONE invocation silently keeps only the LAST selector, so
  the obvious one-liner would exit 0 on a green bundle while running a single
  validator. Each validator therefore gets its own invocation, and the gate
  asserts one selector per invocation so the shape cannot be "simplified" back.

operator-sdk is installed from the checksum-verified release binary
(hack/install-operator-sdk.sh) rather than `go install`, which needs cgo and
pkg-config for gpgme. CI installs it in both the lint and release jobs so the
gate genuinely runs; absent locally it fails with an install hint rather than
skipping. Validation reads an on-disk bundle directory, so no cluster or
registry is contacted.

The declared `categories: Monitoring,Integration & Delivery` and
`capabilities: Full Lifecycle` were verified against the upstream standard
lists and are unchanged.
@codecov

codecov Bot commented Aug 18, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@konih
konih merged commit 3a21a0f into main Aug 18, 2026
31 checks passed
@konih
konih deleted the lane/dist-oh-02-bundle-validation branch August 18, 2026 14:13
@sonarqubecloud

Copy link
Copy Markdown

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.

1 participant