Skip to content

fix(dockerdigest): include HideTag in ReportConfig to prevent source cache collision#8927

Merged
olblak merged 3 commits into
updatecli:mainfrom
max-chaban:fix/dockerdigest-hidetag-reportconfig
May 19, 2026
Merged

fix(dockerdigest): include HideTag in ReportConfig to prevent source cache collision#8927
olblak merged 3 commits into
updatecli:mainfrom
max-chaban:fix/dockerdigest-hidetag-reportconfig

Conversation

@max-chaban

@max-chaban max-chaban commented May 18, 2026

Copy link
Copy Markdown
Contributor

It's common to pair two dockerdigest sources against the same image and tag: one with hidetag: false for image.tag and one with hidetag: true for appVersion. This worked correctly for years until the source cache introduced in v0.116.0 started treating them as identical — ReportConfig() omits HideTag from its output, so both sources hash to the same cache key. Whichever runs first populates the cache; the other receives a stale hit and produces the wrong result without any error — updatecli reports for both.

This PR adds HideTag to the struct returned by ReportConfig() so each source gets a distinct cache key and executes independently.

Because source execution order is non-deterministic, the failure shows up differently depending on which source wins the race:

Ordering Source v0.115.x v0.116.0+
version first version (hidetag=false) tag@sha256:… tag@sha256:…
version first appversion (hidetag=true) short hash ✓ "" ✗ — transformer receives tag@sha256:…; trimprefix is a no-op
appversion first appversion (hidetag=true) short hash ✓ short hash ✓
appversion first version (hidetag=false) tag@sha256:… @sha256:… ✗ — cache hit, no transformer on version source

Test

To test this pull request, you can run the following commands:

cd pkg/plugins/resources/dockerdigest
go test -run TestReportConfig_HideTagIncluded -v

The test calls ReportConfig() on a source with hidetag: true and asserts the returned JSON contains "HideTag":true — confirming the field is present and carries the correct value.

To reproduce against a live registry, save as reproduce.yaml and run updatecli apply -c reproduce.yaml:

reproduce.yaml
sources:

  # ── Ordering A: version runs first ──────────────────────────────────────
  # v0.116.0+: version caches "stable@sha256:…"; appversion gets stale hit.

  ord_a_version:
    name: "[Ord A] version — runs first — v0.115 ✓  v0.116 ✓"
    kind: dockerdigest
    spec:
      image: "nginx"
      tag: "stable"

  ord_a_appversion:
    name: "[Ord A] appversion — cache hit → trimprefix no-op → regex fails — v0.115 ✓  v0.116 ✗ (empty)"
    kind: dockerdigest
    spec:
      image: "nginx"
      tag: "stable"
      hidetag: true
    dependson:
      - ord_a_version
    transformers:
      - trimprefix: "@sha256:"
      - findsubmatch:
          pattern: "^([0-9a-f]{8})"

  # ── Ordering B: appversion runs first ───────────────────────────────────
  # v0.116.0+: appversion caches "@sha256:…"; version gets stale hit.
  # Uses a different tag to isolate this pair's cache key from Ordering A.

  ord_b_appversion:
    name: "[Ord B] appversion — runs first — v0.115 ✓  v0.116 ✓"
    kind: dockerdigest
    spec:
      image: "nginx"
      tag: "mainline"
      hidetag: true
    transformers:
      - trimprefix: "@sha256:"
      - findsubmatch:
          pattern: "^([0-9a-f]{8})"

  ord_b_version:
    name: "[Ord B] version — cache hit → @sha256:… with no transformer — v0.115 ✓  v0.116 ✗ (wrong format)"
    kind: dockerdigest
    spec:
      image: "nginx"
      tag: "mainline"
    dependson:
      - ord_b_appversion

On v0.116.0: ord_a_appversion"", ord_b_version@sha256:…. On a patched build all four sources resolve correctly.

Additional Information

Checklist

  • I have updated the documentation via pull request in website repository.

Tradeoff

HideTag: false (the default) now serializes as "HideTag":false in the cache key JSON where it was previously absent. Users with hidetag unset will see a one-time cache miss on first run after upgrade — a fresh registry call with the correct result. No functional regression.

Potential improvement

Other fields that affect the dockerdigest output format, and any plugin added after #8291, should be audited to confirm ReportConfig() is a complete identity function for the source's output.

@olblak

olblak commented May 19, 2026

Copy link
Copy Markdown
Member

Sorry for the issue, and thank you for the pull request. I definitely need to revamp the e2e tests to better catch this kind of regression

@olblak olblak merged commit 966e325 into updatecli:main May 19, 2026
7 checks passed
@olblak olblak added the bug Something isn't working label May 19, 2026
@max-chaban max-chaban deleted the fix/dockerdigest-hidetag-reportconfig branch May 21, 2026 08:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants