Skip to content

ci(native): add force input to rebuild a drifted artifact key#11

Merged
lxm7 merged 1 commit into
mainfrom
fix/native-artifacts-force
Jul 16, 2026
Merged

ci(native): add force input to rebuild a drifted artifact key#11
lxm7 merged 1 commit into
mainfrom
fix/native-artifacts-force

Conversation

@lxm7

@lxm7 lxm7 commented Jul 16, 2026

Copy link
Copy Markdown
Owner

Why

The iOS EAS build has been failing in eas-build-pre-install, before any compile:

native(ios): CHECKSUM MISMATCH — chat_mls_coreFFI-ios-7e4fdcc9abc3f190.tar.gz does not match committed chat_mls_coreFFI.xcframework.sha256

The key is correct and the fetch succeeds — the published asset just doesn't match the committed manifest. In the tarball, headers/plists/modulemaps verify OK; only the two Mach-O binaries and the top-level Info.plist fail. Same source, different compile.

What happened: CI run 28983282244 built, uploaded, and committed the manifest in b8bf0fa on Jul 8 23:54. The R2 object's Last-Modified is Jul 9 09:50 — ten hours later, with no workflow run in between. A locally built xcframework was uploaded over the CI-published one (confirmed: the local ios-arm64 binary hashes 2a2f899c76e8dc…, byte-identical to what R2 serves, and both fail the committed manifest).

Because the binaries are non-reproducible, the same source key yields different bytes per compile — so the consumer can never verify, and every iOS EAS build fails until the two sides are realigned.

The trap

Already published? only checks existence (curl -fsI). Once a key drifts, it's unrepairable by dispatch: the guard sees the object, skips the build, and nothing republishes. The only escape was deleting the R2 object by hand.

What this does

Adds a force boolean to workflow_dispatch that bypasses the guard on both jobs. aws s3 cp overwrites in place, and the commit step refreshes the manifest back into lockstep with the asset.

inputs.force is null on push/PR events, so those paths are unchanged. Passed via env: rather than interpolated into run:.

Follow-up (not in this PR)

Two things would stop this recurring:

  1. Make R2 writes non-clobberingaws s3api put-object --if-none-match "*" so an upload against an existing key fails loudly instead of poisoning it.
  2. Make the guard verify, not just exist — fetch and check against the committed manifest, so drift surfaces in CI rather than in an EAS hook hours later.

Local build:ios rewriting the committed manifest is the mechanism the drift travels through; worth a guard there too.

The `Already published?` guard only checks that the asset exists, so once a
key's published asset drifts from the committed manifest there is no way to
republish it: every dispatch sees the object, skips the build, and the EAS
`eas-build-pre-install` hook keeps failing its checksum verify.

That drift happened for chat_mls_coreFFI-ios-7e4fdcc9abc3f190: a locally built
xcframework was uploaded over the CI-published one. Same source key, different
bytes (the binaries are non-reproducible), so the consumer can never verify.

Dispatch with force=true to bypass the guard and rebuild + republish, which
also refreshes the committed manifest back into lockstep with the asset.
Non-dispatch events leave `inputs.force` null, so push/PR behaviour is
unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018bbPAiJXZSrCaGTMZERmKX
@lxm7
lxm7 merged commit 0111060 into main Jul 16, 2026
6 checks passed
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