Skip to content

chore(deps): Update testing-tools - abandoned#10

Open
github-actions[bot] wants to merge 9 commits into
mainfrom
renovate/testing-tools
Open

chore(deps): Update testing-tools - abandoned#10
github-actions[bot] wants to merge 9 commits into
mainfrom
renovate/testing-tools

Conversation

@github-actions

@github-actions github-actions Bot commented May 4, 2026

Copy link
Copy Markdown

ℹ️ Note

This PR body was truncated due to platform limits.

This PR contains the following updates:

Package Type Update Change
helm/helm testing_tools patch v4.1.1v4.1.4
kubernetes-sigs/karpenter testing_tools minor v1.8.0v1.12.0
kubernetes/kubernetes testing_tools minor v1.35.0v1.36.0
mikefarah/yq testing_tools minor v4.52.4v4.53.2
nvkind testing_tools digest 78a0a5156db9be
tilt-dev/ctlptl testing_tools patch 0.9.00.9.3
tilt-dev/tilt testing_tools patch 0.37.00.37.3

Release Notes

helm/helm (helm/helm)

v4.1.4: Helm v4.1.4

Compare Source

Helm v4.1.4 is a security fix patch release. Users are encouraged to upgrade for the best experience.

The community keeps growing, and we'd love to see you there!

  • Join the discussion in Kubernetes Slack:
    • for questions and just to hang out
    • for discussing PRs, code, and bugs
  • Hang out at the Public Developer Call: Thursday, 9:30 Pacific via Zoom
  • Test, debug, and contribute charts: ArtifactHub/packages

Security fixes

  • GHSA-hr2v-4r36-88hr Helm Chart extraction output directory collapse via Chart.yaml name dot-segment
  • GHSA-q5jf-9vfq-h4h7 Plugin verification fails open when .prov is missing, allowing unsigned plugin install
  • GHSA-vmx8-mqv2-9gmg Path traversal in plugin metadata version enables arbitrary file write outside Helm plugin directory

A big thank you to the reporters of these issues (@​maru1009, @​1seal).

Installation and Upgrading

Download Helm v4.1.4. The common platform binaries are here:

The Quickstart Guide will get you going from there. For upgrade instructions or detailed installation notes, check the install guide. You can also use a script to install on any system with bash.

What's Next

  • 4.1.5 and 3.20.3 are the next patch (bug fix) releases and will be on April 8, 2026
  • 4.2.0 and 3.21.0 are the next minor (feature) releases and will be on May 13, 2026

Changelog

  • fix: Plugin missing provenance bypass 05fa379 (George Jenkins)
  • fix: Chart dot-name path bug 4e7994d (George Jenkins)
  • ignore error plugin loads (cli, getter) 2581943 (George Jenkins)
  • fix: Plugin version path traversal 36c8539 (George Jenkins)
  • fix: pin codeql-action/upload-sarif to commit SHA in scorecards workflow c61e086 (Terry Howe)

v4.1.3: Helm v4.1.3

Compare Source

Helm v4.1.3 is a patch release. Users are encouraged to upgrade for the best experience.

Note there was no 4.1.2 release due to a release automation issue.

The community keeps growing, and we'd love to see you there!

  • Join the discussion in Kubernetes Slack:
    • for questions and just to hang out
    • for discussing PRs, code, and bugs
  • Hang out at the Public Developer Call: Thursday, 9:30 Pacific via Zoom
  • Test, debug, and contribute charts: ArtifactHub/packages

Notable Changes

  • Fixed a bug where --dry-run=server was not respecting generateName #​31563
  • Fixed a bug where empty CRD resources caused a crash. Now it prints an error #​31578
  • Fixed a bug where OCI references with tag+digest failed with "invalid byte" error #​31601
  • Fixed a bug where user-provided nil value was not preserved when chart has an empty map or no default for a key #​31644
  • Fixed a regression since Helm 3.18.0 where Pulling charts from OCI repositories that use an index to store both Container Images and Helm Charts under the same tag failed #​31776
  • Fixed a Helm 4 regression where gotemplate white space trimming directly after YAML doc separators, when present after postrendering, caused YAML file corruption #​31868
  • Fixed a bug where FailedStatus is treated as a terminal state, causing upgrades to fail prematurely when cluster autoscalers needed time to provision nodes, or when pods were being deleted during rolling updates #​31897
  • Fixed broken backwards compatibility for deprecated --atomic flag on install command #​31901
  • SDK: Fixed a Windows 'Access Deined' error if multiple processes try to download the same chart version concurrently #​31128
  • SDK: Fixed a bug where users did not receive any logs from the waiter, causing confusion as several minutes could pass with no user feedback #​31717
  • SDK: Fixed a bug where server-side apply defaults did not always match the CLI defaults #​31732
  • SDK: Fixed a Go import issue when downstream tooling attempted to vendor helm.sh/helm/v4/pkg/kube #​31852

Installation and Upgrading

Download Helm v4.1.3. The common platform binaries are here:

This release was signed with 208D D36E D5BB 3745 A167 43A4 C7C6 FBB5 B91C 1155 and can be found at @​scottrigby keybase account. Please use the attached signatures for verifying this release using gpg.

The Quickstart Guide will get you going from there. For upgrade instructions or detailed installation notes, check the install guide. You can also use a script to install on any system with bash.

What's Next

  • 4.2.0 and 3.21.0 are the next minor releases and will be on May 13, 2026
  • 4.1.4 and 3.20.2 are the next patch releases and will be on April 8, 2026

Changelog

  • chore(defaults): server-side apply SDK defaults should always match the CLI defaults c94d381 (Matheus Pimenta)
  • whitespace b36d660 (Austin Abro)
  • use logger with waiter 04a91af (Austin Abro)
  • Remove refactorring changes from coalesce_test.go c3c57db (Evans Mungai)
  • Fix import d47cb2b (Evans Mungai)
  • Update pkg/chart/common/util/coalesce_test.go 790bf92 (Evans Mungai)
  • Fix lint warning f7cec12 (Evans Mungai)
  • Preserve nil values in chart already d94a5c9 (Evans Mungai)
  • fix(values): preserve nil values when chart default is empty map 8c5fe4e (Evans Mungai)
  • chore(deps): bump github.com/cloudflare/circl from 1.6.1 to 1.6.3 217db28 (dependabot[bot])
  • Restored --atomic flag on install command 7cb43e0 (Travis Leeden)
  • fix: bump go.opentelemetry.io/otel/sdk to v1.40.0 for GO-2026-4394 5b26d4f (Terry Howe)
  • fix: bump fluxcd/cli-utils to v0.37.2-flux.1 360c131 (Terry Howe)
  • chore(deps): bump sigs.k8s.io/kustomize/kyaml from 0.21.0 to 0.21.1 69a0a92 (dependabot[bot])
  • fix: insert newline after doc separators glued to content by template trimming b868e6a (Matheus Pimenta)
  • fix: correct import comment in statuswait.go from v3 to v4 dbfbea9 (rohansood10)
  • chore(deps): bump the k8s-io group with 7 updates 099192c (dependabot[bot])
  • add image index test 4967ead (Pedro Tôrres)
  • fix pulling charts from OCI indices 2fe6b10 (Pedro Tôrres)
  • fix: handle OCI digest algorithm prefix in chart downloader (#​31601) e3e2d01 (Evans Mungai)
  • fix(install): check nil for restClientGetter and fix tests c15e711 (Manuel Alonso)
  • chore(refactor): better testing and functionality for installing crd df82e68 (Manuel Alonso)
  • fix(test): fix tests and check nil for restclient 4b896ca (Manuel Alonso)
  • fix(test): merge fix correctly 3fc7939 (Manuel Alonso Gonzalez)
  • fix(install): add more tests and check nil file data 6017d2b (Manuel Alonso)
  • fix(test): no check empty resources f451967 (Manuel Alonso)
  • fix(install): check lenght and file nil, add tests fdadff5 (Manuel Alonso)
  • fix(action): crd resources can be empty 10d6067 (Manuel Alonso)
  • fix: casing issue fixed 0fec40f (Mujib Ahasan)
  • fix: error handled correctly 2637498 (Mujib Ahasan)
  • fix: doc string added 961d7d7 (Mujib Ahasan)
  • update: test coverage added for helper function validateNameAndGenerateName 29e4506 (Mujib Ahasan)
  • update: helper function added for the business logic d55b0b9 (Mujib Ahasan)
  • generateName is also considered in logic c1c090e (Mujib Ahasan)
  • update: business logic respected for skipping object missing name 5e09313 (Mujib Ahasan)
  • fixed: --dry-run=server now respect generateName f289d16 (Mujib Ahasan)
  • fix(downloader): safely handle concurrent file writes on Windows bfac739 (Orgad Shaneh)
kubernetes-sigs/karpenter (kubernetes-sigs/karpenter)

v1.12.0

Compare Source

Features

Bug Fixes

Documentation

Tests

Chores

v1.11.1

Compare Source

Bug Fixes

v1.11.0

Compare Source

Features

Bug Fixes

Documentation

Tests

v1.10.0

Compare Source

Features

Bug Fixes

Documentation

Tests

Chores

v1.9.0

Compare Source

Features

Bug Fixes

Documentation

Code Refactoring

Tests

Continuous Integration

Chores

Note

PR body was truncated to here.


Configuration

📅 Schedule: (UTC)

  • Branch creation
    • At any time (no schedule defined)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.

👻 Immortal: This PR will be recreated if closed unmerged. Get config help if that's undesired.


  • If you want to rebase/retry this PR, check this box

This PR has been generated by Mend Renovate.

njhensley added 6 commits May 1, 2026 16:10
Introduces a self-hosted Renovate runner that shadows dependabot during a
soft-launch phase. Renovate replaces and extends dependabot's coverage by
also tracking the tool versions pinned in .settings.yaml (the project's
single source of truth) — something dependabot cannot do.

Coverage delta over dependabot: gomod, github-actions, dockerfile, and
terraform are all preserved (with the kubernetes/golang-x/opencontainers
gomod groups carried forward verbatim). New: npm (site/), helm-values
(partial), the .settings.yaml tool set via a custom regex manager (28
annotated entries), and an automated chainsaw-checksum refresh hook.

Key design decisions:

- Self-hosted via renovatebot/github-action with the built-in
  GITHUB_TOKEN. The repo's /ok reviewer-comment policy re-fires CI on
  bot PRs, sidestepping GitHub's "GITHUB_TOKEN cannot trigger workflows"
  limitation. No PAT or App needed.
- The `configurationFile:` action input is intentionally NOT passed:
  passing it would load .github/renovate.json5 as both the global config
  AND the auto-discovered repo config, doubling every customManager and
  duplicating PRs.
- .settings.yaml entries are grouped by top-level YAML section via
  `depType=<section>` annotations + matchDepTypes packageRules.
  Branches read cleanly: `renovate/build-tools`, `renovate/test-images`,
  `renovate/major-site`, etc.
- nvkind (pinned by main-branch SHA) gets a dedicated git-refs digest
  customManager with a distinct `# renovate-digest:` annotation prefix
  so the broad regex doesn't double-extract it.
- Auto-merge is positive-listed (build/lint/security tooling, plus
  github-actions/gomod/npm patches). Cluster-impacting pins (helm,
  kubectl, kind, kwok, chainsaw, karpenter, gpu-operator, kindest/node,
  CUDA, Go toolchain, node, hugo, nvkind) require human review on every
  bump, even patches.
- Schedule is `before 6am every weekday` since self-hosted Renovate
  cannot consume GitHub vulnerability alerts (Mend-only); weekday
  cadence narrows the CVE-to-PR window.
- Both image references (Makefile validator + workflow runner) are
  digest-pinned to `sha256:00185c0d...` for supply-chain consistency
  with the project's GitHub Actions pinning policy.

Verified end-to-end:

- make lint-renovate validates against ghcr.io/renovatebot/renovate:43
  cleanly.
- merge-gate.yaml gains a path-filtered verify-renovate job that runs
  the same validator only when .github/renovate.json5 changes.
- Local docker dry-run with the live config produces 6 distinct PR
  branches (down from 10 ungrouped) covering vue/vite/mermaid/esbuild
  bundled in renovate/site, kindest/node + cuda bundled in
  renovate/test-images, and 3 majors split into renovate/major-* for
  isolated review.
- The chainsaw post-upgrade hook is wired and idempotent: rerun against
  the currently-pinned v0.2.14 produces zero diff.

Soft-launch plan in .github/RENOVATE.md (Phases A-E). dependabot.yml
and dependabot-auto-merge.yaml remain in place until Phase D confirms
Renovate is healthy; Phase E is a follow-up PR removing them.
* fix(ci): make workflow cron the single Renovate schedule

The previous setup had two scheduling layers that didn't overlap: the
workflow cron fired Mondays at 09:00 UTC, while renovate.json5's
`schedule: ["before 6am every weekday"]` only created PRs before 06:00
UTC. Every cron-triggered run landed three hours after the window
closed and Renovate held all PRs in "Awaiting Schedule" — including the
manually-dispatched runs we used during the soft-launch exercise.

For self-hosted Renovate, the config-side `schedule:` field is
redundant: Renovate only runs when the workflow fires, so the workflow
cron already controls cadence. Removing the second layer:

- Eliminates the alignment trap (the failure mode is silent — runs
  "succeed" while creating zero PRs).
- Makes `workflow_dispatch` actually useful — manual triggers now
  create PRs immediately, regardless of clock time.
- Removes the dependency on Dependency-Dashboard checkbox ticking to
  bypass the schedule for ad-hoc runs.

Cron moved from `0 9 * * 1` (Mon 09:00) to `0 5 * * 1-5` (Mon-Fri
05:00) so PRs land before standup. RENOVATE.md updated to document
the single-source-of-truth design and call out the rationale.

* fix(ci): add release cooldown to renovate config

Adds `minimumReleaseAge: "3 days"` globally and raises it to 7 days for
the two auto-merge rules. Defends against malicious-publish ratchet
attacks where a poisoned version goes live for hours then gets yanked
(event-stream, colors.js, node-ipc, etc.). Trade-off: legitimate CVE
patches land 3 days later than they would otherwise; for a project
whose security-relevant deps come entirely from upstream tooling we
don't write ourselves, the marginal protection is worth it.

`internalChecksFilter: "strict"` excludes too-young releases rather
than parking them in the Dependency Dashboard as "pending", keeping
the dashboard signal clean — it shows what's about to land, not
what's blocked behind cooldown.

Auto-merge rules carry the higher 7-day cooldown because those
updates skip human review; the cooldown is the only defense layer
left if an attacker pushes a malicious patch.
…te) (#4)

* fix(ci): merge anchore + sigstore into single supply-chain group

Both Anchore (grype/syft/sbom-action/scan-action) and Sigstore (cosign/
cosign-installer) are supply-chain hardening tools. Their bumps tend to
be reviewed by the same eyes for the same reasons. Bundling them into a
single `supply-chain` group reduces 2 PRs/cycle to 1 without coupling
unrelated tooling.

The cross-manager behavior is preserved — the matchPackageNames glob
still picks up both .settings.yaml entries (via the regex manager:
anchore/grype, anchore/syft, sigstore/cosign) and GitHub Actions
entries (anchore/sbom-action, anchore/scan-action,
sigstore/cosign-installer). Branch slug becomes `renovate/supply-chain`.

* fix(ci): merge docs-tools + site into single docs group

The docs build chain has two halves: hugo (.settings.yaml docs_tools,
used by .github/actions/build-versioned-site for versioned landing
pages) and site/package.json (vitepress + vue + mermaid + esbuild +
vite, the main docs site). They're parts of one pipeline; reviewing
their bumps together is the natural workflow.

Both packageRules now share `groupName: "docs"` — Renovate uses the
group slug to determine the branch, so deps from either manager
(custom.regex on .settings.yaml + npm on site/package.json) land in
the single `renovate/docs` PR. Major bumps still split into
`renovate/major-docs` per Renovate's default behavior.
The `actions/checkout` step was modeled on NVIDIA/gpu-operator's
renovate workflow, but our setup deliberately does not pass
`configurationFile:` (to avoid customManager doubling — see PR #3).
Without that input, the renovatebot/github-action clones the repo
itself inside Docker and has no need for an outer working tree.

Observed failure: every Renovate run since the practice exercise
started would create the first eligible branch (e.g.
`renovate/build-tools`) and then abort 0.3s later with
"Repository has changed during renovation" — even though no commit
to main happened during the run window. The credentials and working
tree planted at /home/runner/work by `actions/checkout` are the
suspect: Renovate's container-internal git operations and the
runner-side git state cross-contaminate, and Renovate misinterprets
its own branch push as a base-branch advance.

Removing the step removes the cross-contamination surface. The action
documents that checkout is not required when using its default
internal-clone mode.
…kflow (#6)

Reverts toward the known-working NVIDIA/gpu-operator pattern after PRs
#5 (drop checkout) and earlier failed to clear the persistent
"Repository has changed during renovation" abort. Three concrete
changes:

1. **Add back actions/checkout.** The action documents that it clones
   internally, but the host-side git state planted by checkout
   appears to keep Renovate's pre/post hooks consistent. Removing it
   in PR #5 did not fix the abort, suggesting checkout was never the
   culprit.

2. **Pass configurationFile: .github/renovate.json5.** The earlier
   concern about customManager doubling came from
   `RENOVATE_PLATFORM=local` dry-runs; in production (platform=github)
   Renovate dedupes by manager identity, so the same-file case is
   benign. Without configurationFile, the action runs Renovate without
   a global config — and that mode is associated with mid-run race
   conditions that surface as "repository-changed" aborts right after
   a successful branch push.

3. **Set RENOVATE_DRY_RUN conditionally.** Previously the env var was
   emitted on every run as `''` (empty string when dryRun=false).
   Renovate's option parser may treat the *presence* of the env var
   differently from its unset state. The new "Configure dry-run mode"
   step writes the var to GITHUB_ENV only when explicitly requested,
   keeping the env clean for the common case.

Verified end-to-end via actionlint. Soft-launch loop continues — once
this lands, dispatch Renovate manually and check whether
`renovate/build-tools` (the only bundle past the cooldown filter)
finally produces a PR alongside its branch.
#7)

Root cause of the persistent "Repository has changed during renovation"
aborts since PR #4 — Renovate was calling POST /repos/{owner}/{repo}/
statuses/{sha} after each branch creation to write a stability status
check (tied to the cooldown / merge-confidence flow). The workflow's
permissions block had contents:write, pull-requests:write, issues:write
but not statuses:write, so the call 403'd with "integration-
unauthorized". Renovate's error handler maps that internally to
"repository-changed", which is why every prior debugging attempt
(checkout, configurationFile, dry-run env, digest pin) chased the
wrong symptom.

Confirmed via debug log on run 25346172853:
  Request failed with status code 403 (Forbidden):
  POST .../statuses/cf3dc7d1...
  "x-accepted-github-permissions": "statuses=write"
  DEBUG: Caught error setting branch status - aborting
  Error: integration-unauthorized
  DEBUG: Passing repository-changed error up

The earlier hypothesis fixes in PRs #5 and #6 weren't wrong per se
(actions/checkout and configurationFile aren't the cause, and
RENOVATE_DRY_RUN='' isn't either) — they just couldn't have fixed the
underlying permission gap. With statuses:write added, Renovate's
post-branch status-check call should succeed and the run should
complete normally.
Confirmed in production run 25346453345: the regex manager stats
showed `"regex": {"fileCount": 4, "depCount": 56}` instead of the
expected 2/28. With `configurationFile: .github/renovate.json5`
passed, the action mounts the file as Renovate's global config AND
Renovate auto-discovers the same file from the cloned working tree;
both loads register the customManagers and every annotation gets
extracted twice. The doubling produced 14 "Cannot find replaceString
in current file content. Was it already updated?" warnings across
the four created branches — Renovate's first pass applied the
replacement, the second pass tried to re-apply but the content no
longer matched.

PR #6 added `configurationFile:` chasing the "repository-changed"
aborts under the wrong hypothesis; PR #7 found and fixed the actual
cause (missing `statuses: write` permission). With #7 in place we
can drop `configurationFile:` cleanly. Earlier dry-run experiments in
RENOVATE_PLATFORM=local mode had already shown this doubling, but I
mis-attributed it to local-mode specifics. Production confirms the
behavior is the same.

`actions/checkout` stays — it's not the cause of any issue we've
seen, and the upstream gpu-operator pattern keeps it.
@github-actions github-actions Bot force-pushed the renovate/testing-tools branch from 86e4dcf to c2ffad0 Compare May 4, 2026 22:27
njhensley and others added 2 commits May 4, 2026 15:38
After the first successful production Renovate run on the practice
fork created PRs #8#11, the next 8 eligible bundles all landed in
the dashboard's Rate-Limited section instead of as PRs:

  - renovate/github-actions, linting, python-3.x, supply-chain
  - renovate/major-linting, major-docs, major-github-actions,
    major-test-images

Reason: prHourlyLimit was 4 and we'd already created 4 in the run.
Renovate's hourly cap is a per-repo rolling-window throttle whose
default (2) is tuned for Mend's hosted service serving many repos
against the same upstream registries — for our self-hosted single
repo, the constraint is purely "don't flood reviewers", which is
already what prConcurrentLimit handles.

Setting prHourlyLimit to 10 (matching prConcurrentLimit) means the
hourly cap never holds back updates that the concurrent-PR cap would
otherwise allow through. With cooldown filtering (3 days global,
7 days for auto-merge) plus group consolidation already in place,
even a backlog-clearing run will rarely produce more than 10 PRs at
once. Patch auto-merge drains the safe ones without human attention.
@github-actions

github-actions Bot commented May 7, 2026

Copy link
Copy Markdown
Author

Edited/Blocked Notification

Renovate will not automatically rebase this PR, because it does not recognize the last commit author and assumes somebody else may have edited the PR.

You can manually request rebase by checking the rebase/retry box above.

⚠️ Warning: custom changes will be lost.

@github-actions github-actions Bot changed the title chore(deps): Update testing-tools chore(deps): Update testing-tools - abandoned May 12, 2026
@github-actions

Copy link
Copy Markdown
Author

Autoclosing Skipped

This PR has been flagged for autoclosing. However, it is being skipped due to the branch being already modified. Please close/delete it manually or report a bug if you think this is in error.

njhensley added a commit that referenced this pull request May 13, 2026
Audit findings #2, #3, #4 against generated evidence bundles:
predicate.validatorImages was always null, predicate.validatorCatalogVersion
was always empty, and the pointer's signer block emitted zero-valued
identity/issuer + rekorLogIndex:0 for unsigned bundles — making a real
Rekor log index 0 indistinguishable from 'no Rekor entry' and an
unsigned bundle indistinguishable from one whose signer fields failed
to extract.

Changes:

  - emitRecipeEvidence loads the validator catalog once and feeds it
    to both the BOM (chart refs + validator images) and the
    predicate's ValidatorCatalogVersion + ValidatorImages fields.
    Shared dedupValidatorImages helper collapses the catalog's
    one-entry-per-check duplication (deployment/perf/conformance all
    share images).

  - PointerAttestation.Signer becomes *PointerSigner, omitempty.
    Unsigned bundles emit the attestation entry with no signer block
    at all; signed bundles always carry non-nil Signer with populated
    Identity and Issuer.

  - PointerSigner.RekorLogIndex becomes *int64, omitempty. nil = no
    Rekor entry created (--no-rekor signing path); non-nil = real
    Rekor log index, even when zero (Rekor's first-ever entry occupies
    index 0 and that's a legitimate position a consumer should be
    able to verify).

  - signAndPushBundle's no-push path returns signPushOutcome{} rather
    than signPushOutcome{Sign: &SignResult{}}, matching its existing
    'All fields are nil when --push is absent' comment and letting
    buildPointerInputs do the right nil-check.

Test coverage:

  - pkg/evidence/attestation/pointer_test.go: unsigned bundles MUST
    omit the signer YAML block; signed-without-rekor bundles MUST
    omit rekorLogIndex. Both assertions check rendered YAML, not just
    the struct.

  - pkg/cli/validate_evidence_test.go (new): catalogVersion,
    dedupValidatorImages, validatorImagesForPredicate helpers; and
    buildPointerInputs covers the three outcome shapes (unsigned,
    signed-with-rekor, signed-without-rekor).

Notes:

  - ValidatorImages.Digest remains blank in this PR. The catalog
    records image refs by tag, not by digest; resolving each ref to a
    digest needs a registry round-trip per image, which validate's
    hot path avoids. Audit item #10 (BOM image digests) tracks the
    longer-term resolver path; the same resolver will populate this
    field when it lands.
njhensley added a commit that referenced this pull request May 13, 2026
Audit findings #2, #3, #4 against generated evidence bundles:
predicate.validatorImages was always null, predicate.validatorCatalogVersion
was always empty, and the pointer's signer block emitted zero-valued
identity/issuer + rekorLogIndex:0 for unsigned bundles — making a real
Rekor log index 0 indistinguishable from 'no Rekor entry' and an
unsigned bundle indistinguishable from one whose signer fields failed
to extract.

Changes:

  - emitRecipeEvidence loads the validator catalog once and feeds it
    to both the BOM (chart refs + validator images) and the
    predicate's ValidatorCatalogVersion + ValidatorImages fields.
    Shared dedupValidatorImages helper collapses the catalog's
    one-entry-per-check duplication (deployment/perf/conformance all
    share images).

  - PointerAttestation.Signer becomes *PointerSigner, omitempty.
    Unsigned bundles emit the attestation entry with no signer block
    at all; signed bundles always carry non-nil Signer with populated
    Identity and Issuer.

  - PointerSigner.RekorLogIndex becomes *int64, omitempty. nil = no
    Rekor entry created (--no-rekor signing path); non-nil = real
    Rekor log index, even when zero (Rekor's first-ever entry occupies
    index 0 and that's a legitimate position a consumer should be
    able to verify).

  - signAndPushBundle's no-push path returns signPushOutcome{} rather
    than signPushOutcome{Sign: &SignResult{}}, matching its existing
    'All fields are nil when --push is absent' comment and letting
    buildPointerInputs do the right nil-check.

Test coverage:

  - pkg/evidence/attestation/pointer_test.go: unsigned bundles MUST
    omit the signer YAML block; signed-without-rekor bundles MUST
    omit rekorLogIndex. Both assertions check rendered YAML, not just
    the struct.

  - pkg/cli/validate_evidence_test.go (new): catalogVersion,
    dedupValidatorImages, validatorImagesForPredicate helpers; and
    buildPointerInputs covers the three outcome shapes (unsigned,
    signed-with-rekor, signed-without-rekor).

Notes:

  - ValidatorImages.Digest remains blank in this PR. The catalog
    records image refs by tag, not by digest; resolving each ref to a
    digest needs a registry round-trip per image, which validate's
    hot path avoids. Audit item #10 (BOM image digests) tracks the
    longer-term resolver path; the same resolver will populate this
    field when it lands.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant