Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions scripts/ci/_common.sh
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,15 @@ use_xcode_toolchain() {
done < <(env)

configure_reproducible_native_paths

export SDKROOT="${SDKROOT:-${macos_sdkroot}}"
export CMAKE_OSX_SYSROOT="${CMAKE_OSX_SYSROOT:-${macos_sdkroot}}"
for name in \
CFLAGS CXXFLAGS OBJCFLAGS OBJCXXFLAGS \
CFLAGS_aarch64_apple_darwin CXXFLAGS_aarch64_apple_darwin \
CFLAGS_x86_64_apple_darwin CXXFLAGS_x86_64_apple_darwin; do
append_env_words_once "${name}" "-isysroot ${macos_sdkroot}"
done
}

require_ios_simulator_runtime_for_xcode() {
Expand Down
10 changes: 10 additions & 0 deletions scripts/ci/canonical-windows-nsis-payload-hash.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@
"VCRUNTIME140.dll",
"VCRUNTIME140_1.dll",
)
GENERATED_NSIS_PAYLOAD_FILES = frozenset(
{
"uninstall.exe",
}
)
Comment on lines +22 to +26

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔍 NSIS payload exclusion only matches root-level files by design

The GENERATED_NSIS_PAYLOAD_FILES frozenset contains bare filenames like "uninstall.exe", and the check at line 160 compares against rel.lower() where rel is a full relative path from the extraction root. This means only a root-level uninstall.exe is excluded — if the same filename appeared in a subdirectory (e.g. $PLUGINSDIR/uninstall.exe), it would NOT be excluded. This appears intentional since the comment explains that makensis generates the root-level uninstaller, but it's worth confirming that NSIS never places additional uninstall.exe copies in subdirectories that would also need exclusion for reproducibility.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.



def sha256_bytes(data):
Expand Down Expand Up @@ -149,6 +154,11 @@ def canonical_tree_entries(root):
for name in sorted(files):
path = os.path.join(current_root, name)
rel = os.path.relpath(path, root).replace(os.sep, "/")
# makensis generates uninstall.exe from a temporary helper during
# packaging and signs that helper in signed builds. It is not part
# of Maple's reproducible app/runtime payload.
if rel.lower() in GENERATED_NSIS_PAYLOAD_FILES:
continue
with open(path, "rb") as f:
canonical = canonical_pe_bytes(f.read(), rel)
entries.append((rel, len(canonical), sha256_bytes(canonical)))
Expand Down
5 changes: 3 additions & 2 deletions scripts/ci/release-verification-guide.sh
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ This guide was generated by release CI after Maple's release artifact verifier p

## What The Proofs Cover

The release contains final SHA-256 manifests, canonical payload manifests, Tauri updater signatures, and GitHub artifact attestations. Together they let you check that downloaded bytes match the release, that updater signatures match \`latest.json\`, and that signed Android, macOS, and iOS payloads strip back to the reproducible unsigned build products where that platform supports the check. Windows release proofs cover the final Authenticode-signed NSIS installer, its final Tauri updater signature, and the pinned app-local runtime DLLs used during bundling. Windows verification does not yet canonicalize Authenticode-signed binaries back to an unsigned baseline.
The release contains final SHA-256 manifests, canonical payload manifests, Tauri updater signatures, and GitHub artifact attestations. Together they let you check that downloaded bytes match the release, that updater signatures match \`latest.json\`, and that signed Android, macOS, and iOS payloads strip back to the reproducible unsigned build products where that platform supports the check. Windows release proofs cover the final Authenticode-signed NSIS installer, its final Tauri updater signature, the pinned app-local runtime DLLs used during bundling, and the signed installer's canonical app/runtime payload after excluding the NSIS-generated uninstaller helper.

GitHub attestations prove that release CI produced the published bytes for this tag. The Maple verifier then recomputes the local hashes and canonical payload proofs from the files you downloaded.

Expand Down Expand Up @@ -106,7 +106,8 @@ nix develop .#desktop-linux -c ./scripts/ci/verify-release-artifacts.sh artifact
nix develop .#ci -c ./scripts/ci/verify-release-artifacts.sh artifacts macos

# Windows desktop installer: verifies final hashes, pinned runtime DLL proofs,
# and the Tauri updater signature for the signed NSIS installer.
# canonical app/runtime payload proofs, and the Tauri updater signature for the
# signed NSIS installer.
nix develop .#ci -c ./scripts/ci/verify-release-artifacts.sh artifacts windows

# iOS IPA: run on macOS with Xcode selected.
Expand Down
Loading