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.

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