Skip to content

fix(action): publish-ghcr re-derives from-version independently of generate-ghcr #40

Description

@BYK

Problem

binpatch/action/action.yml has the same divergence bug that
getsentry/cli#1327 just fixed in
its hand-rolled CI shell: publish-ghcr re-derives the previous version
tag from oras repo tags independently, instead of accepting the value
that generate-ghcr already computed.

action/action.yml:448-460 (in publish-ghcrpush_patches):

# Find from-version by listing versioned nightly tags.
local TAGS PREV_TAG="" tag PREV_VERSION
TAGS=$(oras repo tags "${FULL_REPO}" 2>/dev/null | grep "^${NIGHTLY_TAG_PREFIX}[0-9]" | sort -V || echo "")
for tag in $TAGS; do
  if [ "$tag" = "${NIGHTLY_TAG_PREFIX}${VERSION}" ]; then break; fi
  PREV_TAG="$tag"
done

If the registry state changes between the consumer's generate-ghcr step
and its publish-ghcr step (e.g. a concurrent push, a freshly-added
0.41 nightly that sorts after a 0.40 nightly), the two invocations can
disagree. The patch bytes were generated against one source; the
from-version annotation on the published manifest gets stamped with a
different value. binpatch verifies only the final output SHA, not the
source binary identity — so this propagates a silent SHA mismatch to
every consumer of the action.

The action already exposes outputs.from-version from generate-ghcr
(collected at line 507 from the prev-ghcr step's from-version
output). The fix is to thread it through publish-ghcr as an input.

Repro

Identical pattern to getsentry/cli's bug:

  1. Have a 0.40.0-dev.X nightly and a 0.41.0-dev.Y nightly where Y < X
    (chronologically), so sort -V orders 0.41 after 0.40.
  2. Build a new 0.40.0-dev.Z nightly where Z > X, Y.
  3. generate-ghcr picks PREV = 0.41.0-dev.Y (semver-previous in
    sort -V order) and generates patch bytes from that.
  4. Between generate-ghcr and publish-ghcr, the registry state changes
    (another push adds a tag that shifts ordering, or whatever).
  5. publish-ghcr re-derives PREV = 0.40.0-dev.X and stamps it in
    the annotation.
  6. Downstream consumer at 0.40.0-dev.X receives
    from-version: 0.40.0-dev.X but the patch bytes are against
    0.41.0-dev.Y. SHA mismatch on apply → fallback to full download
    or hard failure.

Proposed fix

  1. Add a from-version input to publish-ghcr:

    from-version:
      description: >
        The previous version the patches diff against (from
        generate-ghcr.outputs.from-version). When empty, falls back to
        re-deriving from the registry (current behavior).
      required: false
      default: ""
  2. In push_patches (line 427), use the input when present, else fall
    back to re-derive:

    if [ -n "${FROM_VERSION:-}" ]; then
      PREV_VERSION="${FROM_VERSION}"
      echo "Using from-version from generate step: ${PREV_VERSION}"
    else
      # existing re-derive logic
    fi
  3. Update the action's README to document the input and recommend
    wiring it from generate-ghcr.outputs.from-version.

The consumer-side wiring change is trivial: needs.generate.outputs.from-version
from-version: input on publish-ghcr.

Related

Fix should target a 0.4.x patch release.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions