Skip to content

chore(release): verify SHA512 against actual archive (Part of #674)#676

Merged
kcenon merged 1 commit intodevelopfrom
chore/issue-675-verify-sha512-archive
May 3, 2026
Merged

chore(release): verify SHA512 against actual archive (Part of #674)#676
kcenon merged 1 commit intodevelopfrom
chore/issue-675-verify-sha512-archive

Conversation

@kcenon
Copy link
Copy Markdown
Owner

@kcenon kcenon commented May 3, 2026

Closes #675

Part of #674.

What

Adds an independent SHA512 verification step to .github/workflows/sync-vcpkg-registry.yml that re-downloads the release archive from GitHub and compares the recomputed digest against the value the workflow is about to write to portfile.cmake. On mismatch, the step prints both SHAs and exits 1 before any registry commit happens.

Why

Detected via microsoft/vcpkg#51511 and kcenon/vcpkg-registry#87 - every kcenon port shipped a mismatched SHA512 because the release workflow never compared its computed value against the actual archive. Cold-cache vcpkg consumers (new CI runners, fresh users) hit 100% install failure when the SHA in vcpkg-registry/ports/kcenon-common-system/portfile.cmake does not match the bytes at https://github.com/kcenon/common_system/archive/refs/tags/v<version>.tar.gz. This PR closes the detection gap for common_system.

Where

File Change
.github/workflows/sync-vcpkg-registry.yml New step Verify SHA512 against actual GitHub archive inserted between the existing sha step (id: sha) and Update portfile.cmake with new SHA512 and REF

Audit summary (other workflows considered)

Workflow Touches portfile SHA? Action
sync-vcpkg-registry.yml Yes (computes steps.sha.outputs.sha512, writes to portfile) Hardened (this PR)
release.yml No (build/test/GitHub Release only) No change needed
release-template.yml No (reusable build/test template) No change needed
on-release-sync-registry.yml No (thin caller of sync-vcpkg-registry.yml) Inherits hardening automatically
port-sync-check.yml Compares git-blob SHAs for drift detection, not archive SHA512 Out of scope

Only sync-vcpkg-registry.yml actually computes a SHA512, so an inline step in that single workflow is more appropriate than extracting a composite action.

How

The new step runs immediately after the existing Download release archive and compute SHA512 step and before Update portfile.cmake with new SHA512 and REF. It re-fetches the archive with curl -fsSL --retry 3 to a file (not piped) so a 404 cannot silently produce the empty-input hash cf83e1357eefb8bdf.... The exit-1 error message includes both the workflow-computed SHA and the archive's actual SHA so debug logs are immediately useful.

Runtime: ~1-2s on a typical common_system archive (~200 KB).

Test Plan

How a reviewer can validate the new step fires

  1. Cut a release tag (v0.x.y) - the existing Sync Registry on Release workflow triggers sync-vcpkg-registry.yml
  2. Inspect the run log for the new step Verify SHA512 against actual GitHub archive. On a healthy release, the step prints:
    Re-fetching https://github.com/kcenon/common_system/archive/refs/tags/v0.x.y.tar.gz for independent verification...
    SHA512 verified against https://github.com/kcenon/common_system/archive/refs/tags/v0.x.y.tar.gz
      <128-char hex digest>
    

How to simulate a mismatch

Locally executed and confirmed before push:

  • Match path (real v0.2.0 archive, real workflow-computed SHA): step exits 0, prints verification line.
  • Mismatch path (real archive SHA, workflow SHA replaced with all-zero digest): step exits 1 with annotations SHA512 mismatch detected for v0.2.0 / Workflow computed: 000... / GitHub archive: ac4588... / Refusing to commit a portfile that would not install.
  • Bad URL path (nonexistent tag v999.999.999): curl -fsSL returns RC=22, the if ! branch fires exit 1 with Failed to download release archive for verification: <URL>. The download-to-file pattern (rather than a pipe) is required to make this work - piping into sha512sum would otherwise mask the curl failure with the empty-input hash.

YAML structure validated with js-yaml; step ordering confirmed (Verify is step 5 of 12, after sha and before portfile update).

Breaking Changes

None. The new step is additive; on a successful release it adds ~1-2s and one log line. On a SHA mismatch (the failure mode this PR is designed to detect) it short-circuits the existing run before any vcpkg-registry commit, which is the desired behavior.

Add an independent SHA512 verification step in sync-vcpkg-registry.yml
that re-downloads the release archive from GitHub and compares the
recomputed SHA against the value the workflow is about to write to
portfile.cmake. On mismatch the step prints both SHAs and exits 1
before any registry commit happens.

Mitigates the failure mode found in microsoft/vcpkg#51511 and
kcenon/vcpkg-registry#87, where every kcenon port shipped a SHA that
did not match the actual archive and cold-cache vcpkg installs failed.

The audit confirmed sync-vcpkg-registry.yml is the only workflow in
this repo that computes SHA512; release.yml and release-template.yml
build/test/publish but do not write portfile SHAs, so no changes were
needed there. on-release-sync-registry.yml is a thin caller that
inherits the new step automatically.

Implementation notes:
- New step runs between 'Download release archive and compute SHA512'
  (id: sha) and 'Update portfile.cmake with new SHA512 and REF', so a
  mismatch fails the run before any portfile mutation
- Downloads to a file (not pipe) so curl's --fail exit code is not
  masked by sha512sum producing the empty-input hash on fetch error
- curl uses --retry 3 --retry-delay 2 for transient network blips
- Runtime cost ~1-2s for a kcenon archive

Part of #674.
@kcenon kcenon merged commit c90d4b8 into develop May 3, 2026
7 checks passed
@kcenon kcenon deleted the chore/issue-675-verify-sha512-archive branch May 3, 2026 12:37
kcenon added a commit to kcenon/logger_system that referenced this pull request May 3, 2026
Add an independent SHA512 verification job to on-release-sync-registry.yml
that re-downloads the release archive from GitHub and recomputes its digest
after the reusable sync workflow completes. Provides repo-local
defense-in-depth on top of the verify step inside
kcenon/common_system/.github/workflows/sync-vcpkg-registry.yml that was
added in kcenon/common_system#676.

The job uses file-based hashing (curl -fsSL --retry 3 -o file, then
sha512sum file) rather than a pipe so a fetch failure cannot silently
produce the empty-input hash cf83e1357eefb8bdf... A minimum-size sanity
check rejects suspiciously small archives.

Closes #634

Part of kcenon/common_system#674.
kcenon added a commit to kcenon/database_system that referenced this pull request May 3, 2026
Add a defense-in-depth pre-verification job to on-release-sync-registry.yml
that downloads the published GitHub release archive and computes its SHA512
before delegating to the shared sync workflow that writes the SHA into
portfile.cmake.

The downstream reusable workflow
(kcenon/common_system/.github/workflows/sync-vcpkg-registry.yml) was hardened
in kcenon/common_system#676 to compare its computed SHA against the actual
archive. This change adds an independent check in this repo so a release
that produces an unfetchable or empty archive fails fast in this repo's
release run, with a clear log line, before the sync workflow ever runs.

The check uses file-based hashing (curl -fsSL --retry 3 ... -o tmpfile)
rather than piping curl into sha512sum, so a fetch failure cannot silently
produce the empty-input SHA512 (cf83e1357eefb8bdf...). The empty-input
hash is also explicitly rejected as a final safety net.

Audit:
  - on-release-sync-registry.yml: thin caller of common_system reusable
    workflow; this PR adds an independent pre-verification job here.
  - release.yml: builds and publishes platform artifacts, no SHA write.
  - vcpkg-overlay.yml: local overlay-port build/test, no SHA write.
  - All other workflows (ci, sanitizers, coverage, integration, etc.):
    no portfile SHA computation.

Closes #588
Part of kcenon/common_system#674
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