diff --git a/.github/reproducibility/create-scai-predicate.sh b/.github/reproducibility/create-scai-predicate.sh new file mode 100644 index 0000000..318456a --- /dev/null +++ b/.github/reproducibility/create-scai-predicate.sh @@ -0,0 +1,103 @@ +#!/usr/bin/env bash + +set -euo pipefail + +: "${SCAI_ARCHIVE:?SCAI_ARCHIVE must name the verified release archive}" +: "${SCAI_PUBLISHED:?SCAI_PUBLISHED must point to the downloaded release archive}" +: "${SCAI_REBUILT:?SCAI_REBUILT must point to the independently rebuilt archive}" +: "${SCAI_TAG:?SCAI_TAG is required}" +: "${SCAI_COMMIT:?SCAI_COMMIT is required}" +: "${SCAI_TARGET:?SCAI_TARGET is required}" +: "${SCAI_RELEASE_HOST:?SCAI_RELEASE_HOST is required}" +: "${SCAI_RELEASE_TOOLS:?SCAI_RELEASE_TOOLS is required}" +: "${SCAI_BUILD_EVIDENCE:?SCAI_BUILD_EVIDENCE must point to build evidence JSON}" +: "${SCAI_BUILD_WORKFLOW:?SCAI_BUILD_WORKFLOW is required}" +: "${SCAI_BUILD_COMMAND:?SCAI_BUILD_COMMAND is required}" + +if command -v sha256sum >/dev/null 2>&1; then + published_digest=$(sha256sum "$SCAI_PUBLISHED" | cut -d ' ' -f 1) + rebuilt_digest=$(sha256sum "$SCAI_REBUILT" | cut -d ' ' -f 1) +else + published_digest=$(shasum -a 256 "$SCAI_PUBLISHED" | cut -d ' ' -f 1) + rebuilt_digest=$(shasum -a 256 "$SCAI_REBUILT" | cut -d ' ' -f 1) +fi + +if [[ "$published_digest" != "$rebuilt_digest" ]]; then + echo "The rebuilt archive does not match the published release archive" >&2 + exit 1 +fi + +release_uri="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/releases/download/${SCAI_TAG}/${SCAI_ARCHIVE}" +run_uri="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}/attempts/${GITHUB_RUN_ATTEMPT}" +workflow_path=".github/workflows/release_reproducible_build.yml" +workflow_uri="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/blob/${GITHUB_WORKFLOW_SHA}/${workflow_path}" +release_workflow_uri="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/blob/${SCAI_COMMIT}/.github/workflows/release_github.yml" + +npx -y celq@0.6.0 \ + --arg="archive:string=$SCAI_ARCHIVE" \ + --arg="digest:string=$published_digest" \ + --arg="release_uri:string=$release_uri" \ + --arg="repository:string=${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}" \ + --arg="tag:string=$SCAI_TAG" \ + --arg="commit:string=$SCAI_COMMIT" \ + --arg="target:string=$SCAI_TARGET" \ + --arg="release_host:string=$SCAI_RELEASE_HOST" \ + --arg="release_tools:string=$SCAI_RELEASE_TOOLS" \ + --arg="release_workflow_uri:string=$release_workflow_uri" \ + --arg="build_workflow:string=$SCAI_BUILD_WORKFLOW" \ + --arg="build_command:string=$SCAI_BUILD_COMMAND" \ + --arg="workflow_name:string=$GITHUB_WORKFLOW" \ + --arg="workflow_path:string=$workflow_path" \ + --arg="workflow_ref:string=$GITHUB_WORKFLOW_REF" \ + --arg="workflow_sha:string=$GITHUB_WORKFLOW_SHA" \ + --arg="run_uri:string=$run_uri" \ + --arg="workflow_uri:string=$workflow_uri" \ + '{ + "attributes": [{ + "attribute": "REPRODUCIBLE", + "target": { + "name": archive, + "uri": release_uri, + "digest": {"sha256": digest}, + "mediaType": archive.endsWith(".zip") ? "application/zip" : "application/gzip" + }, + "conditions": { + "source": { + "repository": repository, + "tag": tag, + "commit": commit + }, + "comparison": { + "algorithm": "sha256", + "publishedDigest": digest, + "rebuiltDigest": digest, + "result": "identical" + }, + "releaseBuild": { + "workflow": release_workflow_uri, + "host": release_host, + "toolchain": release_tools + }, + "reproductionBuild": { + "workflow": build_workflow, + "attestationWorkflow": workflow_path, + "workflowRef": workflow_ref, + "workflowCommit": workflow_sha, + "host": this.host, + "target": target, + "command": build_command, + "toolchain": this.toolchain, + "predicateGenerator": "npx -y celq@0.6.0" + } + }, + "evidence": { + "name": "GitHub Actions reproducible-build workflow run", + "uri": run_uri, + "mediaType": "text/html" + } + }], + "producer": { + "name": workflow_name, + "uri": workflow_uri + } + }' < "$SCAI_BUILD_EVIDENCE" > scai-predicate.json diff --git a/.github/workflows/manual_reproducible.yml b/.github/workflows/manual_reproducible.yml index 295d9c4..15a0b87 100644 --- a/.github/workflows/manual_reproducible.yml +++ b/.github/workflows/manual_reproducible.yml @@ -6,596 +6,137 @@ on: permissions: contents: read -env: - CARGO_TERM_COLOR: always - jobs: - patched_cargo: - name: Patched Cargo (${{ matrix.target }}) - runs-on: ubuntu-24.04 - strategy: - fail-fast: false - matrix: - target: [aarch64-unknown-linux-gnu, x86_64-unknown-freebsd] - env: - TARGET: ${{ matrix.target }} - steps: - - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 - with: - ref: ${{ github.sha }} - persist-credentials: false - - - name: Setup Zigbuild - uses: $/.github/actions/setup-zigbuild - with: - target: ${{ matrix.target }} - rust_components: rust-src - install_target: "true" - use_cache: "false" - - - name: Setup patched Cargo - uses: $/.github/actions/setup-patched-cargo - with: - ref: 29ea6fb6a5db279426f4cc4e17aa385f05a0cfbc - target: ${{ matrix.target }} - patch-file: .github/reproducibility/patches/cargo-linux-x86_64-metadata.patch - build-command: zigbuild - env: - CFG_VER_DESCRIPTION: linux-x86_64-metadata-patch - LIBZ_SYS_STATIC: "1" - - freebsd_tools: - name: Build FreeBSD tools - uses: $/.github/workflows/sub_reproducible_freebsd_tooling.yml - - zigbuild: - name: Zigbuild (${{ matrix.runner }}, ${{ matrix.build.target }}${{ matrix.build.zigtargetsuffix }}) - needs: patched_cargo - runs-on: ${{ matrix.runner }} - strategy: - fail-fast: false - matrix: - runner: [ubuntu-24.04, ubuntu-24.04-arm] - build: - - target: x86_64-unknown-linux-gnu - zigtargetsuffix: .2.28 - - target: x86_64-unknown-linux-musl - zigtargetsuffix: "" - - target: aarch64-unknown-linux-gnu - zigtargetsuffix: .2.28 - - target: aarch64-unknown-linux-musl - zigtargetsuffix: "" - exclude: - - runner: ubuntu-24.04-arm - build: - target: aarch64-unknown-linux-gnu - zigtargetsuffix: .2.28 - - runner: ubuntu-24.04-arm - build: - target: aarch64-unknown-linux-musl - zigtargetsuffix: "" - env: - TARGET: ${{ matrix.build.target }} - ZIGTARGETSUFFIX: ${{ matrix.build.zigtargetsuffix }} - steps: - # Every host builds the same HEAD captured by the manual dispatch. - - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 - with: - ref: ${{ github.sha }} - persist-credentials: false - - - name: Download patched Cargo - if: matrix.runner == 'ubuntu-24.04-arm' - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 - with: - name: patched-cargo-aarch64-unknown-linux-gnu - path: patched-cargo - - - name: Setup Zigbuild - uses: $/.github/actions/setup-zigbuild - with: - target: ${{ matrix.build.target }} - rust_components: rust-src - install_target: "true" - use_cache: "false" - - - name: Select patched Cargo - if: matrix.runner == 'ubuntu-24.04-arm' - run: | - chmod +x "$GITHUB_WORKSPACE/patched-cargo/cargo" - echo "$GITHUB_WORKSPACE/patched-cargo" >> "$GITHUB_PATH" - echo "CARGO=$GITHUB_WORKSPACE/patched-cargo/cargo" >> "$GITHUB_ENV" - - - name: Verify patched Cargo selection - if: matrix.runner == 'ubuntu-24.04-arm' - run: | - test "$(command -v cargo)" = "$CARGO" - echo "Using patched Cargo: $CARGO" - - - name: Configure reproducible builds - run: | - echo "SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct)" >> "$GITHUB_ENV" - echo "TZ=UTC" >> "$GITHUB_ENV" - echo "LC_ALL=C" >> "$GITHUB_ENV" - RUST_SYSROOT=$(rustc --print sysroot) - echo "RUSTFLAGS=--remap-path-prefix=${CARGO_HOME:-$HOME/.cargo}=/cargo --remap-path-prefix=${RUST_SYSROOT}=/rust-toolchain --remap-path-prefix=${GITHUB_WORKSPACE}=/src" >> "$GITHUB_ENV" - - - name: Build with Zig - run: | - cargo auditable zigbuild --locked --release --target "${TARGET}${ZIGTARGETSUFFIX}" - - - name: Create release archive - run: | - mkdir -p artifacts - cp "target/${TARGET}/release/celq" artifacts/celq - tar --format=gnu --sort=name --mtime="@${SOURCE_DATE_EPOCH}" \ - --owner=0 --group=0 --numeric-owner --mode=0755 \ - -cf artifacts/celq.tar -C "target/${TARGET}/release" celq - gzip -n -9 artifacts/celq.tar - - - name: Upload archive and binary - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 - with: - name: reproducible-${{ matrix.build.target }}${{ matrix.build.zigtargetsuffix }}-${{ matrix.runner }} - retention-days: 1 - path: | - artifacts/celq - artifacts/celq.tar.gz - if-no-files-found: error - compression-level: 0 + linux_native: + name: Build from Linux x86-64 + uses: $/.github/workflows/sub_reproducible_from_linux.yml + with: + source_ref: ${{ github.sha }} + runner: ubuntu-24.04 + use_cache: true + + linux_arm: + name: Build from Linux ARM64 + uses: $/.github/workflows/sub_reproducible_from_linux.yml + with: + source_ref: ${{ github.sha }} + runner: ubuntu-24.04-arm + use_cache: true freebsd: - name: Zigbuild (FreeBSD x86-64, ${{ matrix.build.target }}${{ matrix.build.zigtargetsuffix }}) - needs: [patched_cargo, freebsd_tools] - runs-on: ubuntu-24.04 - strategy: - fail-fast: false - matrix: - build: - - target: aarch64-unknown-linux-gnu - zigtargetsuffix: .2.28 - - target: aarch64-unknown-linux-musl - zigtargetsuffix: "" - env: - TARGET: ${{ matrix.build.target }} - ZIGTARGETSUFFIX: ${{ matrix.build.zigtargetsuffix }} - steps: - - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 - with: - ref: ${{ github.sha }} - persist-credentials: false - - - name: Capture commit timestamp - run: echo "SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct)" >> "$GITHUB_ENV" - - - name: Download patched Cargo - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 - with: - name: patched-cargo-x86_64-unknown-freebsd - path: patched-cargo - - - name: Download FreeBSD tools - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 - with: - name: freebsd-tools-x86_64 - path: freebsd-tools - - - name: Build on FreeBSD - uses: vmactions/freebsd-vm@f0552d3b69211736abd97f02ff3d4674c56b73b1 # v1.5.5 - with: - release: "14.4" - arch: x86_64 - sync: rsync - copyback: true - envs: TARGET ZIGTARGETSUFFIX SOURCE_DATE_EPOCH - prepare: | - set -eu - pkg install -y ca_root_nss git devel/rustup-init archivers/gtar archivers/gzip - - # Install the official FreeBSD Zig archive directly from ziglang.org. - cd /tmp - fetch https://ziglang.org/download/0.15.2/zig-x86_64-freebsd-0.15.2.tar.xz - test "$(sha256 -q zig-x86_64-freebsd-0.15.2.tar.xz)" = \ - "5509ff57cd3f219165caed0da10221739af82742b9edfcda3f7bfaf4da7212dd" - tar -xf zig-x86_64-freebsd-0.15.2.tar.xz - - rustup-init -y --profile minimal --default-toolchain 1.94.1 - . "$HOME/.cargo/env" - rustup component add rust-src --toolchain 1.94.1 - - run: | - set -eu - . "$HOME/.cargo/env" - install -m 755 freebsd-tools/cargo-zigbuild "$HOME/.cargo/bin/" - mkdir -p /home/runner/.cargo/bin - install -m 755 freebsd-tools/cargo-auditable /home/runner/.cargo/bin/cargo-auditable - export PATH="/home/runner/.cargo/bin:/tmp/zig-x86_64-freebsd-0.15.2:$PATH" - test "$(command -v cargo-auditable)" = /home/runner/.cargo/bin/cargo-auditable - rustup target add --toolchain 1.94.1 "$TARGET" - - # Host job environment variables are not inherited by the VM. - export RUSTUP_TOOLCHAIN=1.94.1 - export CARGO_TERM_COLOR=always TZ=UTC LC_ALL=C - export SOURCE_DATE_EPOCH - RUST_SYSROOT=$(rustc --print sysroot) - export RUSTFLAGS="--remap-path-prefix=${CARGO_HOME:-$HOME/.cargo}=/cargo --remap-path-prefix=${RUST_SYSROOT}=/rust-toolchain --remap-path-prefix=$(pwd -P)=/src" - export CARGO="$(pwd -P)/patched-cargo/cargo" - chmod +x "$CARGO" - export PATH="$(pwd -P)/patched-cargo:$PATH" - test "$(command -v cargo)" = "$CARGO" - echo "Using patched Cargo: $CARGO" - "$CARGO" auditable zigbuild --locked --release --target "${TARGET}${ZIGTARGETSUFFIX}" - - mkdir -p artifacts - cp "target/${TARGET}/release/celq" artifacts/celq - gtar --format=gnu --sort=name --mtime="@${SOURCE_DATE_EPOCH}" \ - --owner=0 --group=0 --numeric-owner --mode=0755 \ - -cf artifacts/celq.tar -C "target/${TARGET}/release" celq - /usr/local/bin/gzip -n -9 artifacts/celq.tar - - - name: Upload archive and binary - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 - with: - name: reproducible-${{ matrix.build.target }}${{ matrix.build.zigtargetsuffix }}-freebsd-x86_64 - retention-days: 1 - path: | - artifacts/celq - artifacts/celq.tar.gz - if-no-files-found: error - compression-level: 0 - - hashes: - name: SHA-256 (${{ matrix.pair.target }}, ${{ matrix.original }} vs ${{ matrix.pair.verify }}) - needs: [zigbuild, freebsd] - if: ${{ !cancelled() }} + name: Build from FreeBSD x86-64 + uses: $/.github/workflows/sub_reproducible_from_freebsd.yml + with: + source_ref: ${{ github.sha }} + use_cache: true + + windows_native: + name: Build from Windows x86-64 + uses: $/.github/workflows/sub_reproducible_from_windows.yml + with: + source_ref: ${{ github.sha }} + runner: windows-2025 + use_cache: true + + windows_arm: + name: Build from Windows ARM64 + uses: $/.github/workflows/sub_reproducible_from_windows.yml + with: + source_ref: ${{ github.sha }} + runner: windows-11-vs2026-arm + use_cache: true + + macos_native: + name: Build from macOS ARM64 + uses: $/.github/workflows/sub_reproducible_from_mac.yml + with: + source_ref: ${{ github.sha }} + runner: macos-15 + + macos_intel: + name: Build from Intel macOS + uses: $/.github/workflows/sub_reproducible_from_mac.yml + with: + source_ref: ${{ github.sha }} + runner: macos-15-intel + + linux_hashes: + name: SHA-256 (${{ matrix.pretty_target }}, Linux x86-64 vs ${{ matrix.verify_host }}) + needs: [linux_native, linux_arm, freebsd] runs-on: ubuntu-24.04 strategy: fail-fast: false matrix: - original: [ubuntu-24.04] - pair: - - target: x86_64-unknown-linux-gnu.2.28 - verify: ubuntu-24.04-arm - - target: x86_64-unknown-linux-musl - verify: ubuntu-24.04-arm - - target: aarch64-unknown-linux-gnu.2.28 - verify: freebsd-x86_64 - - target: aarch64-unknown-linux-musl - verify: freebsd-x86_64 + include: + - pretty_target: linux-x86_64-gnu + verify_host: ubuntu-24.04-arm + - pretty_target: linux-x86_64-musl + verify_host: ubuntu-24.04-arm + - pretty_target: linux-aarch64-gnu + verify_host: freebsd-14.4-x86_64 + - pretty_target: linux-aarch64-musl + verify_host: freebsd-14.4-x86_64 steps: - - name: Download original artifacts + - name: Download Linux x86-64-host artifact uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 with: - name: reproducible-${{ matrix.pair.target }}-${{ matrix.original }} - path: artifacts/${{ matrix.original }} + name: reproducible-${{ matrix.pretty_target }}-ubuntu-24.04 + path: artifacts/original - - name: Download verification artifacts + - name: Download alternative-host artifact uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 with: - name: reproducible-${{ matrix.pair.target }}-${{ matrix.pair.verify }} - path: artifacts/${{ matrix.pair.verify }} + name: reproducible-${{ matrix.pretty_target }}-${{ matrix.verify_host }} + path: artifacts/verification - - name: Print and compare SHA-256 hashes - env: - ORIGINAL: ${{ matrix.original }} - VERIFY: ${{ matrix.pair.verify }} + - name: Compare binary and archive SHA-256 hashes run: | - find artifacts -type f -exec sha256sum {} + - (cd "artifacts/$ORIGINAL" && sha256sum celq celq.tar.gz) > original.sha256 - (cd "artifacts/$VERIFY" && sha256sum celq celq.tar.gz) > verification.sha256 + (cd artifacts/original && sha256sum binary archive) > original.sha256 + (cd artifacts/verification && sha256sum binary archive) > verification.sha256 diff -u original.sha256 verification.sha256 - patched_cargo_windows: - name: Patched Cargo (Windows ARM64) - runs-on: windows-2025 - defaults: - run: - shell: bash - steps: - - name: Preserve LF line endings for Cargo patching - run: git config --global core.autocrlf false - - - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 - with: - ref: ${{ github.sha }} - persist-credentials: false - - - name: Install Rust 1.94.1 with Windows ARM64 target - uses: dtolnay/rust-toolchain@9376cdc5a5e25b16da71af47712785cf06b0d6d4 # 1.94.1 - with: - targets: aarch64-pc-windows-msvc - - - name: Setup patched Cargo - uses: $/.github/actions/setup-patched-cargo - with: - ref: 29ea6fb6a5db279426f4cc4e17aa385f05a0cfbc - target: aarch64-pc-windows-msvc - patch-file: .github/reproducibility/patches/cargo-windows-x86_64-metadata.patch - env: - CFG_VER_DESCRIPTION: windows-x86_64-metadata-patch - LIBZ_SYS_STATIC: "1" - - xwin: - name: Xwin (${{ matrix.runner }}, ${{ matrix.target }}) - needs: patched_cargo_windows - runs-on: ${{ matrix.runner }} - defaults: - run: - shell: bash - strategy: - fail-fast: false - matrix: - runner: [windows-2025, windows-11-vs2026-arm] - target: &xwin_targets - - x86_64-pc-windows-msvc - steps: - - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 - with: - ref: ${{ github.sha }} - persist-credentials: false - - - name: Select native Windows ARM64 Rust host - if: runner.arch == 'ARM64' - run: | - rustup set default-host aarch64-pc-windows-msvc - echo "RUSTUP_TOOLCHAIN=1.94.1-aarch64-pc-windows-msvc" >> "$GITHUB_ENV" - - - name: Setup Xwin - id: setup-xwin - uses: $/.github/actions/setup-xwin - with: - target: ${{ matrix.target }} - rust_components: llvm-tools - cache_directory: ${{ github.workspace }}/.xwin-cache - use_cache: "true" - - - name: Verify native Windows ARM64 compiler - if: runner.arch == 'ARM64' - run: | - test "$(rustc -vV | sed -n 's/^host: //p' | tr -d '\r')" = aarch64-pc-windows-msvc - - - name: Download patched Cargo - if: runner.arch == 'ARM64' - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 - with: - name: patched-cargo-aarch64-pc-windows-msvc - path: patched-cargo - - - name: Select patched Cargo - if: runner.arch == 'ARM64' - run: | - echo "$(cygpath -aw "$GITHUB_WORKSPACE/patched-cargo")" >> "$GITHUB_PATH" - echo "CARGO=$(cygpath -aw "$GITHUB_WORKSPACE/patched-cargo/cargo.exe")" >> "$GITHUB_ENV" - - - name: Verify patched Cargo selection - if: runner.arch == 'ARM64' - run: | - test "$(cygpath -aw "$(command -v cargo)")" = "$CARGO" - echo "Using patched Cargo: $CARGO" - - - name: Configure reproducible builds - run: | - echo "SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct)" >> "$GITHUB_ENV" - echo "TZ=UTC" >> "$GITHUB_ENV" - echo "LC_ALL=C" >> "$GITHUB_ENV" - RUST_SYSROOT=$(rustc --print sysroot) - echo "RUSTFLAGS=--remap-path-prefix=${CARGO_HOME:-$HOME/.cargo}=/cargo --remap-path-prefix=${RUST_SYSROOT}=/rust-toolchain --remap-path-prefix=${GITHUB_WORKSPACE}=/src -C link-arg=/DEBUG:NONE" >> "$GITHUB_ENV" - - - name: Build with Xwin - env: - TARGET: ${{ matrix.target }} - XWIN_CACHE_DIR: ${{ steps.setup-xwin.outputs.cache_directory }} - XWIN_CRT_VERSION: ${{ steps.setup-xwin.outputs.xwin_crt_version }} - XWIN_SDK_VERSION: ${{ steps.setup-xwin.outputs.xwin_sdk_version }} - XWIN_VERSION: ${{ steps.setup-xwin.outputs.xwin_version }} - run: >- - cargo auditable xwin build --locked --release --target "${TARGET}" - --xwin-version "${XWIN_VERSION}" - --xwin-sdk-version "${XWIN_SDK_VERSION}" - --xwin-crt-version "${XWIN_CRT_VERSION}" - - - name: Create release archive - env: - NAME: celq - PRETTY_TARGET: windows-x86_64 - TARGET: ${{ matrix.target }} - run: | - BIN_PATH="target/${TARGET}/release/${NAME}.exe" - ARCHIVE_NAME="${NAME}-${PRETTY_TARGET}.zip" - 7z a -mtm=off -mtc=off -mta=off "${ARCHIVE_NAME}" "./${BIN_PATH}" - 7z rn "${ARCHIVE_NAME}" "target/${TARGET}/release/${NAME}.exe" "${NAME}.exe" - - mkdir -p artifacts - cp "${BIN_PATH}" "${ARCHIVE_NAME}" artifacts/ - - - name: Upload Windows binary and archive - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 - with: - name: reproducible-xwin-${{ matrix.target }}-${{ matrix.runner }} - path: | - artifacts/celq.exe - artifacts/celq-windows-x86_64.zip - retention-days: 1 - if-no-files-found: error - compression-level: 0 - - xwin_hashes: - name: Xwin SHA-256 (${{ matrix.target }}, Windows x86-64 vs ARM64) - needs: xwin - if: ${{ !cancelled() }} + windows_hashes: + name: SHA-256 (Windows x86-64 vs ARM64 hosts) + needs: [windows_native, windows_arm] runs-on: ubuntu-24.04 - strategy: - fail-fast: false - matrix: - target: *xwin_targets steps: - - name: Download Windows x86-64 artifacts + - name: Download Windows x86-64-host artifact uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 with: - name: reproducible-xwin-${{ matrix.target }}-windows-2025 - path: artifacts/windows-2025 + name: reproducible-windows-x86_64-windows-2025 + path: artifacts/original - - name: Download Windows ARM64 artifacts + - name: Download Windows ARM64-host artifact uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 with: - name: reproducible-xwin-${{ matrix.target }}-windows-11-vs2026-arm - path: artifacts/windows-11-vs2026-arm + name: reproducible-windows-x86_64-windows-11-vs2026-arm + path: artifacts/verification - - name: Print and compare SHA-256 hashes + - name: Compare binary and archive SHA-256 hashes run: | - find artifacts -type f -exec sha256sum {} + - (cd artifacts/windows-2025 && sha256sum celq.exe celq-windows-x86_64.zip) > original.sha256 - (cd artifacts/windows-11-vs2026-arm && sha256sum celq.exe celq-windows-x86_64.zip) > verification.sha256 + (cd artifacts/original && sha256sum binary archive) > original.sha256 + (cd artifacts/verification && sha256sum binary archive) > verification.sha256 diff -u original.sha256 verification.sha256 - patched_cargo_mac: - name: Patched Cargo (x86_64-apple-darwin) - runs-on: macos-15 - defaults: - run: - shell: bash - env: - DEVELOPER_DIR: /Applications/Xcode_16.4.app/Contents/Developer - MACOSX_DEPLOYMENT_TARGET: "11.0" - TARGET: x86_64-apple-darwin - steps: - - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 - with: - ref: ${{ github.sha }} - persist-credentials: false - - - name: Select pinned macOS SDK - run: echo "SDKROOT=$(xcrun --sdk macosx15.5 --show-sdk-path)" >> "$GITHUB_ENV" - - - name: Install Rust toolchain - uses: dtolnay/rust-toolchain@9376cdc5a5e25b16da71af47712785cf06b0d6d4 # 1.94.1 - with: - targets: ${{ env.TARGET }} - - - name: Setup patched Cargo - uses: $/.github/actions/setup-patched-cargo - with: - ref: 29ea6fb6a5db279426f4cc4e17aa385f05a0cfbc - target: ${{ env.TARGET }} - patch-file: .github/reproducibility/patches/cargo-macos-aarch64-metadata.patch - env: - CFG_VER_DESCRIPTION: macos-aarch64-metadata-patch - - macos: - name: macOS (${{ matrix.runner }}, ${{ matrix.target }}) - needs: patched_cargo_mac - runs-on: ${{ matrix.runner }} - defaults: - run: - shell: bash - strategy: - fail-fast: false - matrix: - runner: [macos-15, macos-15-intel] - target: [aarch64-apple-darwin] - env: - DEVELOPER_DIR: /Applications/Xcode_16.4.app/Contents/Developer - MACOSX_DEPLOYMENT_TARGET: "11.0" - NAME: celq - steps: - - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 - with: - ref: ${{ github.sha }} - persist-credentials: false - - - name: Select pinned macOS SDK - run: | - xcodebuild -version - echo "SDKROOT=$(xcrun --sdk macosx15.5 --show-sdk-path)" >> "$GITHUB_ENV" - - - name: Install Rust toolchain - uses: dtolnay/rust-toolchain@9376cdc5a5e25b16da71af47712785cf06b0d6d4 # 1.94.1 - with: - targets: ${{ matrix.target }} - - - name: Install cargo-auditable - uses: taiki-e/install-action@1ed6d7be6168f6c9046541087ff549b6bc581fdf # v2.87.2 - with: - tool: cargo-auditable@0.7.5 - fallback: none - - - name: Download patched Cargo - if: matrix.runner == 'macos-15-intel' - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 - with: - name: patched-cargo-x86_64-apple-darwin - path: patched-cargo - - - name: Select patched Cargo - if: matrix.runner == 'macos-15-intel' - run: | - chmod +x "$GITHUB_WORKSPACE/patched-cargo/cargo" - echo "$GITHUB_WORKSPACE/patched-cargo" >> "$GITHUB_PATH" - echo "CARGO=$GITHUB_WORKSPACE/patched-cargo/cargo" >> "$GITHUB_ENV" - echo "RUSTC=$(rustup which rustc)" >> "$GITHUB_ENV" - echo "RUSTDOC=$(rustup which rustdoc)" >> "$GITHUB_ENV" - - - name: Configure reproducible builds - run: | - echo "SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct)" >> "$GITHUB_ENV" - echo "TZ=UTC" >> "$GITHUB_ENV" - echo "LC_ALL=C" >> "$GITHUB_ENV" - RUST_SYSROOT=$(rustc --print sysroot) - echo "RUSTFLAGS=--remap-path-prefix=${CARGO_HOME:-$HOME/.cargo}=/cargo --remap-path-prefix=${RUST_SYSROOT}=/rust-toolchain --remap-path-prefix=${GITHUB_WORKSPACE}=/src" >> "$GITHUB_ENV" - - - name: Build - run: cargo auditable build --locked --release --target ${{ matrix.target }} - - - name: Install GNU tar - run: brew install gnu-tar - - - name: Create release archive - env: - TARGET: ${{ matrix.target }} - PRETTY_TARGET: macos-aarch64 - run: | - BIN_PATH="target/${TARGET}/release/${NAME}" - ARCHIVE_NAME="${NAME}-${PRETTY_TARGET}.tar.gz" - gtar --format=gnu --sort=name --mtime="@${SOURCE_DATE_EPOCH}" \ - --owner=0 --group=0 --numeric-owner --mode=0755 \ - -cf "${ARCHIVE_NAME%.gz}" -C "target/${TARGET}/release" "${NAME}" - gzip -n -9 "${ARCHIVE_NAME%.gz}" - - mkdir -p artifacts - cp "${BIN_PATH}" "${ARCHIVE_NAME}" artifacts/ - - - name: Upload archive and binary - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 - with: - name: reproducible-aarch64-apple-darwin-${{ matrix.runner }} - path: | - artifacts/celq - artifacts/celq-macos-aarch64.tar.gz - retention-days: 1 - if-no-files-found: error - compression-level: 0 - macos_hashes: name: SHA-256 (macOS ARM64 vs Intel hosts) - needs: macos - if: ${{ !cancelled() }} + needs: [macos_native, macos_intel] runs-on: ubuntu-24.04 steps: - - name: Download ARM64-host artifacts + - name: Download macOS ARM64-host artifact uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 with: - name: reproducible-aarch64-apple-darwin-macos-15 - path: artifacts/macos-15 + name: reproducible-macos-aarch64-macos-15 + path: artifacts/original - - name: Download Intel-host artifacts + - name: Download Intel macOS-host artifact uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 with: - name: reproducible-aarch64-apple-darwin-macos-15-intel - path: artifacts/macos-15-intel + name: reproducible-macos-aarch64-macos-15-intel + path: artifacts/verification - - name: Print and compare SHA-256 hashes + - name: Compare binary and archive SHA-256 hashes run: | - find artifacts -type f -exec sha256sum {} + - (cd artifacts/macos-15 && sha256sum celq celq-macos-aarch64.tar.gz) > original.sha256 - (cd artifacts/macos-15-intel && sha256sum celq celq-macos-aarch64.tar.gz) > verification.sha256 + (cd artifacts/original && sha256sum binary archive) > original.sha256 + (cd artifacts/verification && sha256sum binary archive) > verification.sha256 diff -u original.sha256 verification.sha256 diff --git a/.github/workflows/release_reproducible_build.yml b/.github/workflows/release_reproducible_build.yml new file mode 100644 index 0000000..e10ecc5 --- /dev/null +++ b/.github/workflows/release_reproducible_build.yml @@ -0,0 +1,192 @@ +name: Attest reproducible release builds + +on: + workflow_dispatch: + inputs: + tag: + description: Existing non-draft GitHub release tag to reproduce + required: true + type: string + +permissions: + contents: read + +defaults: + run: + shell: bash + +env: + RELEASE_TAG: ${{ inputs.tag }} + +jobs: + resolve_tag: + name: Resolve release tag + runs-on: ubuntu-24.04 + outputs: + commit: ${{ steps.tag.outputs.commit }} + steps: + - name: Check out celq at release tag + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + with: + ref: ${{ env.RELEASE_TAG }} + persist-credentials: false + + - name: Install Node.js for pinned celq + uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6 + with: + node-version: "24" + package-manager-cache: false + + - name: Verify tag and published release + id: tag + env: + GH_TOKEN: ${{ github.token }} + run: | + tag_commit=$(git rev-parse --verify "refs/tags/${RELEASE_TAG}^{commit}") + test "$(git rev-parse HEAD)" = "$tag_commit" + release=$(gh release view "$RELEASE_TAG" --repo "$GITHUB_REPOSITORY" --json tagName,isDraft) + printf '%s\n' "$release" | npx -y celq@0.6.0 \ + --arg="tag:string=$RELEASE_TAG" \ + 'this.tagName == tag && !this.isDraft' --boolean --void + echo "commit=$tag_commit" >> "$GITHUB_OUTPUT" + + linux: + name: Rebuild from Linux ARM64 + needs: resolve_tag + uses: $/.github/workflows/sub_reproducible_from_linux.yml + with: + source_ref: ${{ needs.resolve_tag.outputs.commit }} + runner: ubuntu-24.04-arm + use_cache: false + + freebsd: + name: Rebuild from FreeBSD x86-64 + needs: resolve_tag + uses: $/.github/workflows/sub_reproducible_from_freebsd.yml + with: + source_ref: ${{ needs.resolve_tag.outputs.commit }} + use_cache: false + + windows: + name: Rebuild from Windows ARM64 + needs: resolve_tag + uses: $/.github/workflows/sub_reproducible_from_windows.yml + with: + source_ref: ${{ needs.resolve_tag.outputs.commit }} + runner: windows-11-vs2026-arm + use_cache: false + + macos: + name: Rebuild from Intel macOS + needs: resolve_tag + uses: $/.github/workflows/sub_reproducible_from_mac.yml + with: + source_ref: ${{ needs.resolve_tag.outputs.commit }} + runner: macos-15-intel + + attest: + name: Attest ${{ matrix.archive }} + needs: [resolve_tag, linux, freebsd, windows, macos] + if: ${{ !cancelled() && needs.resolve_tag.result == 'success' }} + runs-on: ubuntu-24.04 + permissions: + contents: read + id-token: write + attestations: write + artifact-metadata: write + strategy: + fail-fast: false + matrix: + include: + - archive: celq-linux-x86_64-gnu.tar.gz + artifact: reproducible-linux-x86_64-gnu-ubuntu-24.04-arm + target: x86_64-unknown-linux-gnu.2.28 + build_workflow: .github/workflows/sub_reproducible_from_linux.yml + build_command: cargo auditable zigbuild --locked --release + release_host: ubuntu-24.04 (X64) + release_tools: rustc/cargo 1.94.1; Zig 0.15.2; cargo-zigbuild 0.23.2; cargo-auditable 0.7.5 + - archive: celq-linux-x86_64-musl.tar.gz + artifact: reproducible-linux-x86_64-musl-ubuntu-24.04-arm + target: x86_64-unknown-linux-musl + build_workflow: .github/workflows/sub_reproducible_from_linux.yml + build_command: cargo auditable zigbuild --locked --release + release_host: ubuntu-24.04 (X64) + release_tools: rustc/cargo 1.94.1; Zig 0.15.2; cargo-zigbuild 0.23.2; cargo-auditable 0.7.5 + - archive: celq-linux-aarch64-gnu.tar.gz + artifact: reproducible-linux-aarch64-gnu-freebsd-14.4-x86_64 + target: aarch64-unknown-linux-gnu.2.28 + build_workflow: .github/workflows/sub_reproducible_from_freebsd.yml + build_command: cargo auditable zigbuild --locked --release + release_host: ubuntu-24.04 (X64) + release_tools: rustc/cargo 1.94.1; Zig 0.15.2; cargo-zigbuild 0.23.2; cargo-auditable 0.7.5 + - archive: celq-linux-aarch64-musl.tar.gz + artifact: reproducible-linux-aarch64-musl-freebsd-14.4-x86_64 + target: aarch64-unknown-linux-musl + build_workflow: .github/workflows/sub_reproducible_from_freebsd.yml + build_command: cargo auditable zigbuild --locked --release + release_host: ubuntu-24.04 (X64) + release_tools: rustc/cargo 1.94.1; Zig 0.15.2; cargo-zigbuild 0.23.2; cargo-auditable 0.7.5 + - archive: celq-windows-x86_64.zip + artifact: reproducible-windows-x86_64-windows-11-vs2026-arm + target: x86_64-pc-windows-msvc + build_workflow: .github/workflows/sub_reproducible_from_windows.yml + build_command: cargo auditable xwin build --locked --release + release_host: windows-2025 (X64) + release_tools: rustc/cargo 1.94.1; cargo-xwin 0.23.1; cargo-auditable 0.7.5; LLVM 21.1.8; MSVC 17; SDK 10.0.26100; CRT 14.44.17.14 + - archive: celq-macos-aarch64.tar.gz + artifact: reproducible-macos-aarch64-macos-15-intel + target: aarch64-apple-darwin + build_workflow: .github/workflows/sub_reproducible_from_mac.yml + build_command: cargo auditable build --locked --release + release_host: macos-15 (ARM64) + release_tools: rustc/cargo 1.94.1; cargo-auditable 0.7.5; Xcode 16.4; macOS SDK 15.5 + steps: + - name: Check out attestation workflow + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + with: + ref: ${{ github.sha }} + persist-credentials: false + + - name: Install Node.js for pinned celq + uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6 + with: + node-version: "24" + package-manager-cache: false + + - name: Download independent rebuild + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 + with: + name: ${{ matrix.artifact }} + path: rebuilt + + - name: Download published release archive + env: + ARCHIVE: ${{ matrix.archive }} + GH_TOKEN: ${{ github.token }} + run: | + mkdir -p published + gh release download "$RELEASE_TAG" --repo "$GITHUB_REPOSITORY" \ + --pattern "$ARCHIVE" --dir published + + - name: Compare and create SCAI predicate + env: + SCAI_ARCHIVE: ${{ matrix.archive }} + SCAI_PUBLISHED: published/${{ matrix.archive }} + SCAI_REBUILT: rebuilt/archive + SCAI_TAG: ${{ env.RELEASE_TAG }} + SCAI_COMMIT: ${{ needs.resolve_tag.outputs.commit }} + SCAI_TARGET: ${{ matrix.target }} + SCAI_RELEASE_HOST: ${{ matrix.release_host }} + SCAI_RELEASE_TOOLS: ${{ matrix.release_tools }} + SCAI_BUILD_EVIDENCE: rebuilt/evidence.json + SCAI_BUILD_WORKFLOW: ${{ matrix.build_workflow }} + SCAI_BUILD_COMMAND: ${{ matrix.build_command }} + run: | + bash .github/reproducibility/create-scai-predicate.sh + + - name: Attest reproducible release archive + uses: actions/attest@1e69f48acb82d1966a394da916b4c1698aa569d6 # v4.2.2 + with: + subject-path: published/${{ matrix.archive }} + predicate-type: https://in-toto.io/attestation/scai/v0.3 + predicate-path: scai-predicate.json diff --git a/.github/workflows/sub_reproducible_freebsd_tooling.yml b/.github/workflows/sub_reproducible_freebsd_tooling.yml index 6a398cf..86f9c98 100644 --- a/.github/workflows/sub_reproducible_freebsd_tooling.yml +++ b/.github/workflows/sub_reproducible_freebsd_tooling.yml @@ -2,6 +2,12 @@ name: Reproducible FreeBSD tooling (Subworkflow) on: workflow_call: + inputs: + use_cache: + description: Whether setup-zig may use its download cache + required: false + type: boolean + default: false permissions: contents: read @@ -25,7 +31,7 @@ jobs: target: x86_64-unknown-freebsd rust_components: rust-src install_target: "true" - use_cache: "false" + use_cache: ${{ inputs.use_cache }} - name: Install cargo-clone run: | diff --git a/.github/workflows/sub_reproducible_from_freebsd.yml b/.github/workflows/sub_reproducible_from_freebsd.yml new file mode 100644 index 0000000..e3c84d2 --- /dev/null +++ b/.github/workflows/sub_reproducible_from_freebsd.yml @@ -0,0 +1,167 @@ +name: Reproducible builds from FreeBSD (Subworkflow) + +on: + workflow_call: + inputs: + source_ref: + description: Commit or tag to build + required: true + type: string + use_cache: + description: Whether tool setup actions may use caches + required: false + type: boolean + default: false + +permissions: + contents: read + +env: + CARGO_TERM_COLOR: always + +jobs: + patched_cargo: + name: Patched Cargo for FreeBSD x86-64 + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + with: + ref: ${{ inputs.source_ref }} + persist-credentials: false + + - name: Setup Zigbuild + uses: $/.github/actions/setup-zigbuild + with: + target: x86_64-unknown-freebsd + rust_components: rust-src + install_target: "true" + use_cache: ${{ inputs.use_cache }} + + - name: Setup patched Cargo + uses: $/.github/actions/setup-patched-cargo + with: + ref: 29ea6fb6a5db279426f4cc4e17aa385f05a0cfbc + target: x86_64-unknown-freebsd + patch-file: .github/reproducibility/patches/cargo-linux-x86_64-metadata.patch + build-command: zigbuild + env: + CFG_VER_DESCRIPTION: linux-x86_64-metadata-patch + LIBZ_SYS_STATIC: "1" + + tools: + name: Build FreeBSD tools + uses: $/.github/workflows/sub_reproducible_freebsd_tooling.yml + with: + use_cache: ${{ inputs.use_cache }} + + build: + name: FreeBSD x86-64 host (${{ matrix.pretty_target }}) + needs: [patched_cargo, tools] + runs-on: ubuntu-24.04 + strategy: + fail-fast: false + matrix: + include: + - target: aarch64-unknown-linux-gnu + target_suffix: .2.28 + pretty_target: linux-aarch64-gnu + - target: aarch64-unknown-linux-musl + target_suffix: "" + pretty_target: linux-aarch64-musl + env: + TARGET: ${{ matrix.target }} + TARGET_SUFFIX: ${{ matrix.target_suffix }} + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + with: + ref: ${{ inputs.source_ref }} + persist-credentials: false + + - name: Capture source timestamp + run: echo "SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct)" >> "$GITHUB_ENV" + + - name: Download patched Cargo + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 + with: + name: patched-cargo-x86_64-unknown-freebsd + path: patched-cargo + + - name: Download FreeBSD tools + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 + with: + name: freebsd-tools-x86_64 + path: freebsd-tools + + - name: Build from source on FreeBSD + uses: vmactions/freebsd-vm@f0552d3b69211736abd97f02ff3d4674c56b73b1 # v1.5.5 + with: + release: "14.4" + arch: x86_64 + sync: rsync + copyback: true + envs: TARGET TARGET_SUFFIX SOURCE_DATE_EPOCH + prepare: | + set -eu + pkg install -y ca_root_nss git sysutils/mise devel/rustup-init archivers/gtar archivers/gzip + mise use --global zig@0.15.2 + + cd /tmp + mkdir -p /tmp/celq-evidence + fetch https://github.com/IvanIsCoding/celq/releases/download/v0.6.0/celq-freebsd-x86_64.tar.gz + test "$(sha256 -q celq-freebsd-x86_64.tar.gz)" = \ + "77a65b6a848f7db1da48975598dd6e903030dc62e8c909bcd77944ca8a8f6fe7" + tar -xzf celq-freebsd-x86_64.tar.gz -C /tmp/celq-evidence + install -m 755 /tmp/celq-evidence/celq /usr/local/bin/celq + + rustup-init -y --profile minimal --default-toolchain 1.94.1 + . "$HOME/.cargo/env" + rustup component add rust-src --toolchain 1.94.1 + + run: | + set -eu + ROOT=$(pwd -P) + . "$HOME/.cargo/env" + install -m 755 freebsd-tools/cargo-zigbuild "$HOME/.cargo/bin/" + mkdir -p /home/runner/.cargo/bin + install -m 755 freebsd-tools/cargo-auditable /home/runner/.cargo/bin/ + export PATH="/home/runner/.cargo/bin:$PATH" + test "$(mise exec -- zig version)" = 0.15.2 + rustup target add --toolchain 1.94.1 "$TARGET" + export RUSTUP_TOOLCHAIN=1.94.1 + export CARGO_TERM_COLOR=always TZ=UTC LC_ALL=C SOURCE_DATE_EPOCH + RUST_SYSROOT=$(rustc --print sysroot) + export RUSTFLAGS="--remap-path-prefix=${CARGO_HOME:-$HOME/.cargo}=/cargo --remap-path-prefix=${RUST_SYSROOT}=/rust-toolchain --remap-path-prefix=${ROOT}=/src" + export CARGO="$ROOT/patched-cargo/cargo" + chmod +x "$CARGO" + export PATH="$ROOT/patched-cargo:$PATH" + test "$(command -v cargo)" = "$CARGO" + mise exec -- "$CARGO" auditable zigbuild --locked --release --target "${TARGET}${TARGET_SUFFIX}" + + mkdir -p artifacts + cp "target/${TARGET}/release/celq" artifacts/binary + gtar --format=gnu --sort=name --mtime="@${SOURCE_DATE_EPOCH}" \ + --owner=0 --group=0 --numeric-owner --mode=0755 \ + -cf artifacts/celq.tar -C "target/${TARGET}/release" celq + /usr/local/bin/gzip -n -9 artifacts/celq.tar + mv artifacts/celq.tar.gz artifacts/archive + + export EVIDENCE_HOST='FreeBSD 14.4 VM (x86_64) on ubuntu-24.04' + export EVIDENCE_RUSTC='1.94.1' + export EVIDENCE_CARGO='1.94.1 (patched host metadata)' + export EVIDENCE_AUXILIARY="zig $(mise exec -- zig version); cargo-zigbuild 0.23.2; cargo-auditable 0.7.5; celq 0.6.0" + celq -n \ + --arg="host:string=$EVIDENCE_HOST" \ + --arg="rustc:string=$EVIDENCE_RUSTC" \ + --arg="cargo:string=$EVIDENCE_CARGO" \ + --arg="auxiliary:string=$EVIDENCE_AUXILIARY" \ + '{"host": host, "toolchain": {"rustc": rustc, "cargo": cargo, "auxiliary": auxiliary}}' \ + > artifacts/evidence.json + + - name: Upload reproducible build + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 + with: + name: reproducible-${{ matrix.pretty_target }}-freebsd-14.4-x86_64 + path: artifacts + retention-days: 1 + if-no-files-found: error + compression-level: 0 diff --git a/.github/workflows/sub_reproducible_from_linux.yml b/.github/workflows/sub_reproducible_from_linux.yml new file mode 100644 index 0000000..e357271 --- /dev/null +++ b/.github/workflows/sub_reproducible_from_linux.yml @@ -0,0 +1,210 @@ +name: Reproducible builds from Linux (Subworkflow) + +on: + workflow_call: + inputs: + source_ref: + description: Commit or tag to build + required: true + type: string + runner: + description: Linux runner label + required: true + type: string + use_cache: + description: Whether tool setup actions may use caches + required: false + type: boolean + default: false + +permissions: + contents: read + +env: + CARGO_TERM_COLOR: always + +jobs: + patched_cargo: + name: Patched Cargo for Linux ARM64 + if: inputs.runner == 'ubuntu-24.04-arm' + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + with: + ref: ${{ inputs.source_ref }} + persist-credentials: false + + - name: Setup Zigbuild + uses: $/.github/actions/setup-zigbuild + with: + target: aarch64-unknown-linux-gnu + rust_components: rust-src + install_target: "true" + use_cache: ${{ inputs.use_cache }} + + - name: Setup patched Cargo + uses: $/.github/actions/setup-patched-cargo + with: + ref: 29ea6fb6a5db279426f4cc4e17aa385f05a0cfbc + target: aarch64-unknown-linux-gnu + patch-file: .github/reproducibility/patches/cargo-linux-x86_64-metadata.patch + build-command: zigbuild + env: + CFG_VER_DESCRIPTION: linux-x86_64-metadata-patch + LIBZ_SYS_STATIC: "1" + + native: + name: Linux x86-64 (${{ matrix.pretty_target }}) + if: inputs.runner == 'ubuntu-24.04' + runs-on: ubuntu-24.04 + strategy: + fail-fast: false + matrix: + include: + - target: x86_64-unknown-linux-gnu + target_suffix: .2.28 + pretty_target: linux-x86_64-gnu + - target: x86_64-unknown-linux-musl + target_suffix: "" + pretty_target: linux-x86_64-musl + - target: aarch64-unknown-linux-gnu + target_suffix: .2.28 + pretty_target: linux-aarch64-gnu + - target: aarch64-unknown-linux-musl + target_suffix: "" + pretty_target: linux-aarch64-musl + env: + TARGET: ${{ matrix.target }} + TARGET_SUFFIX: ${{ matrix.target_suffix }} + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + with: + ref: ${{ inputs.source_ref }} + persist-credentials: false + + - name: Setup Zigbuild + uses: $/.github/actions/setup-zigbuild + with: + target: ${{ matrix.target }} + rust_components: rust-src + install_target: "true" + use_cache: ${{ inputs.use_cache }} + + - name: Configure reproducible build + run: | + echo "SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct)" >> "$GITHUB_ENV" + echo "TZ=UTC" >> "$GITHUB_ENV" + echo "LC_ALL=C" >> "$GITHUB_ENV" + RUST_SYSROOT=$(rustc --print sysroot) + echo "RUSTFLAGS=--remap-path-prefix=${CARGO_HOME:-$HOME/.cargo}=/cargo --remap-path-prefix=${RUST_SYSROOT}=/rust-toolchain --remap-path-prefix=${GITHUB_WORKSPACE}=/src" >> "$GITHUB_ENV" + + - name: Build from source + run: cargo auditable zigbuild --locked --release --target "${TARGET}${TARGET_SUFFIX}" + + - name: Package build + run: | + mkdir -p artifacts + cp "target/${TARGET}/release/celq" artifacts/binary + tar --format=gnu --sort=name --mtime="@${SOURCE_DATE_EPOCH}" \ + --owner=0 --group=0 --numeric-owner --mode=0755 \ + -cf artifacts/celq.tar -C "target/${TARGET}/release" celq + gzip -n -9 artifacts/celq.tar + mv artifacts/celq.tar.gz artifacts/archive + + - name: Upload reproducible build + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 + with: + name: reproducible-${{ matrix.pretty_target }}-ubuntu-24.04 + path: artifacts + retention-days: 1 + if-no-files-found: error + compression-level: 0 + + arm_host: + name: Linux ARM64 host (${{ matrix.pretty_target }}) + if: inputs.runner == 'ubuntu-24.04-arm' + needs: patched_cargo + runs-on: ubuntu-24.04-arm + strategy: + fail-fast: false + matrix: + include: + - target: x86_64-unknown-linux-gnu + target_suffix: .2.28 + pretty_target: linux-x86_64-gnu + - target: x86_64-unknown-linux-musl + target_suffix: "" + pretty_target: linux-x86_64-musl + env: + TARGET: ${{ matrix.target }} + TARGET_SUFFIX: ${{ matrix.target_suffix }} + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + with: + ref: ${{ inputs.source_ref }} + persist-credentials: false + + - name: Download patched Cargo + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 + with: + name: patched-cargo-aarch64-unknown-linux-gnu + path: patched-cargo + + - name: Setup Zigbuild + uses: $/.github/actions/setup-zigbuild + with: + target: ${{ matrix.target }} + rust_components: rust-src + install_target: "true" + use_cache: ${{ inputs.use_cache }} + + - name: Select patched Cargo + run: | + chmod +x "$GITHUB_WORKSPACE/patched-cargo/cargo" + echo "$GITHUB_WORKSPACE/patched-cargo" >> "$GITHUB_PATH" + echo "CARGO=$GITHUB_WORKSPACE/patched-cargo/cargo" >> "$GITHUB_ENV" + + - name: Configure reproducible build + run: | + test "$(command -v cargo)" = "$CARGO" + echo "SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct)" >> "$GITHUB_ENV" + echo "TZ=UTC" >> "$GITHUB_ENV" + echo "LC_ALL=C" >> "$GITHUB_ENV" + RUST_SYSROOT=$(rustc --print sysroot) + echo "RUSTFLAGS=--remap-path-prefix=${CARGO_HOME:-$HOME/.cargo}=/cargo --remap-path-prefix=${RUST_SYSROOT}=/rust-toolchain --remap-path-prefix=${GITHUB_WORKSPACE}=/src" >> "$GITHUB_ENV" + + - name: Build from source + run: cargo auditable zigbuild --locked --release --target "${TARGET}${TARGET_SUFFIX}" + + - name: Package build + run: | + mkdir -p artifacts + cp "target/${TARGET}/release/celq" artifacts/binary + tar --format=gnu --sort=name --mtime="@${SOURCE_DATE_EPOCH}" \ + --owner=0 --group=0 --numeric-owner --mode=0755 \ + -cf artifacts/celq.tar -C "target/${TARGET}/release" celq + gzip -n -9 artifacts/celq.tar + mv artifacts/celq.tar.gz artifacts/archive + + - name: Capture build evidence + run: | + export EVIDENCE_HOST='ubuntu-24.04-arm (ARM64)' + export EVIDENCE_RUSTC='1.94.1' + export EVIDENCE_CARGO='1.94.1 (patched host metadata)' + export EVIDENCE_AUXILIARY="zig $(zig version); cargo-zigbuild 0.23.2; cargo-auditable 0.7.5" + npx -y celq@0.6.0 -n \ + --arg="host:string=$EVIDENCE_HOST" \ + --arg="rustc:string=$EVIDENCE_RUSTC" \ + --arg="cargo:string=$EVIDENCE_CARGO" \ + --arg="auxiliary:string=$EVIDENCE_AUXILIARY" \ + '{"host": host, "toolchain": {"rustc": rustc, "cargo": cargo, "auxiliary": auxiliary}}' \ + > artifacts/evidence.json + + - name: Upload reproducible build + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 + with: + name: reproducible-${{ matrix.pretty_target }}-ubuntu-24.04-arm + path: artifacts + retention-days: 1 + if-no-files-found: error + compression-level: 0 diff --git a/.github/workflows/sub_reproducible_from_mac.yml b/.github/workflows/sub_reproducible_from_mac.yml new file mode 100644 index 0000000..2c38031 --- /dev/null +++ b/.github/workflows/sub_reproducible_from_mac.yml @@ -0,0 +1,194 @@ +name: Reproducible builds from macOS (Subworkflow) + +on: + workflow_call: + inputs: + source_ref: + description: Commit or tag to build + required: true + type: string + runner: + description: macOS runner label + required: true + type: string + +permissions: + contents: read + +env: + CARGO_TERM_COLOR: always + DEVELOPER_DIR: /Applications/Xcode_16.4.app/Contents/Developer + MACOSX_DEPLOYMENT_TARGET: "11.0" + TARGET: aarch64-apple-darwin + +jobs: + patched_cargo: + name: Patched Cargo for Intel macOS + if: inputs.runner == 'macos-15-intel' + runs-on: macos-15 + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + with: + ref: ${{ inputs.source_ref }} + persist-credentials: false + + - name: Select pinned macOS SDK + run: echo "SDKROOT=$(xcrun --sdk macosx15.5 --show-sdk-path)" >> "$GITHUB_ENV" + + - name: Install Rust 1.94.1 + uses: dtolnay/rust-toolchain@9376cdc5a5e25b16da71af47712785cf06b0d6d4 # 1.94.1 + with: + targets: x86_64-apple-darwin + + - name: Setup patched Cargo + uses: $/.github/actions/setup-patched-cargo + with: + ref: 29ea6fb6a5db279426f4cc4e17aa385f05a0cfbc + target: x86_64-apple-darwin + patch-file: .github/reproducibility/patches/cargo-macos-aarch64-metadata.patch + env: + CFG_VER_DESCRIPTION: macos-aarch64-metadata-patch + + native: + name: macOS ARM64 host + if: inputs.runner == 'macos-15' + runs-on: macos-15 + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + with: + ref: ${{ inputs.source_ref }} + persist-credentials: false + + - name: Select pinned macOS SDK + run: | + xcodebuild -version + echo "SDKROOT=$(xcrun --sdk macosx15.5 --show-sdk-path)" >> "$GITHUB_ENV" + + - name: Install Rust 1.94.1 + uses: dtolnay/rust-toolchain@9376cdc5a5e25b16da71af47712785cf06b0d6d4 # 1.94.1 + with: + targets: ${{ env.TARGET }} + + - name: Install cargo-auditable + uses: taiki-e/install-action@1ed6d7be6168f6c9046541087ff549b6bc581fdf # v2.87.2 + with: + tool: cargo-auditable@0.7.5 + fallback: none + + - name: Configure reproducible build + run: | + echo "SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct)" >> "$GITHUB_ENV" + echo "TZ=UTC" >> "$GITHUB_ENV" + echo "LC_ALL=C" >> "$GITHUB_ENV" + RUST_SYSROOT=$(rustc --print sysroot) + echo "RUSTFLAGS=--remap-path-prefix=${CARGO_HOME:-$HOME/.cargo}=/cargo --remap-path-prefix=${RUST_SYSROOT}=/rust-toolchain --remap-path-prefix=${GITHUB_WORKSPACE}=/src" >> "$GITHUB_ENV" + + - name: Build from source + run: cargo auditable build --locked --release --target "$TARGET" + + - name: Package build + run: | + brew install gnu-tar + mkdir -p artifacts + cp "target/${TARGET}/release/celq" artifacts/binary + gtar --format=gnu --sort=name --mtime="@${SOURCE_DATE_EPOCH}" \ + --owner=0 --group=0 --numeric-owner --mode=0755 \ + -cf artifacts/celq.tar -C "target/${TARGET}/release" celq + gzip -n -9 artifacts/celq.tar + mv artifacts/celq.tar.gz artifacts/archive + + - name: Upload reproducible build + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 + with: + name: reproducible-macos-aarch64-macos-15 + path: artifacts + retention-days: 1 + if-no-files-found: error + compression-level: 0 + + intel: + name: Intel macOS host + if: inputs.runner == 'macos-15-intel' + needs: patched_cargo + runs-on: macos-15-intel + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + with: + ref: ${{ inputs.source_ref }} + persist-credentials: false + + - name: Select pinned macOS SDK + run: | + xcodebuild -version + echo "SDKROOT=$(xcrun --sdk macosx15.5 --show-sdk-path)" >> "$GITHUB_ENV" + + - name: Install Rust 1.94.1 + uses: dtolnay/rust-toolchain@9376cdc5a5e25b16da71af47712785cf06b0d6d4 # 1.94.1 + with: + targets: ${{ env.TARGET }} + + - name: Install cargo-auditable + uses: taiki-e/install-action@1ed6d7be6168f6c9046541087ff549b6bc581fdf # v2.87.2 + with: + tool: cargo-auditable@0.7.5 + fallback: none + + - name: Download patched Cargo + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 + with: + name: patched-cargo-x86_64-apple-darwin + path: patched-cargo + + - name: Select patched Cargo + run: | + chmod +x "$GITHUB_WORKSPACE/patched-cargo/cargo" + echo "$GITHUB_WORKSPACE/patched-cargo" >> "$GITHUB_PATH" + echo "CARGO=$GITHUB_WORKSPACE/patched-cargo/cargo" >> "$GITHUB_ENV" + echo "RUSTC=$(rustup which rustc)" >> "$GITHUB_ENV" + echo "RUSTDOC=$(rustup which rustdoc)" >> "$GITHUB_ENV" + + - name: Configure reproducible build + run: | + test "$(command -v cargo)" = "$CARGO" + echo "SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct)" >> "$GITHUB_ENV" + echo "TZ=UTC" >> "$GITHUB_ENV" + echo "LC_ALL=C" >> "$GITHUB_ENV" + RUST_SYSROOT=$(rustc --print sysroot) + echo "RUSTFLAGS=--remap-path-prefix=${CARGO_HOME:-$HOME/.cargo}=/cargo --remap-path-prefix=${RUST_SYSROOT}=/rust-toolchain --remap-path-prefix=${GITHUB_WORKSPACE}=/src" >> "$GITHUB_ENV" + + - name: Build from source + run: cargo auditable build --locked --release --target "$TARGET" + + - name: Package build + run: | + brew install gnu-tar + mkdir -p artifacts + cp "target/${TARGET}/release/celq" artifacts/binary + gtar --format=gnu --sort=name --mtime="@${SOURCE_DATE_EPOCH}" \ + --owner=0 --group=0 --numeric-owner --mode=0755 \ + -cf artifacts/celq.tar -C "target/${TARGET}/release" celq + gzip -n -9 artifacts/celq.tar + mv artifacts/celq.tar.gz artifacts/archive + + - name: Capture build evidence + run: | + export EVIDENCE_HOST='macos-15-intel (X64)' + export EVIDENCE_RUSTC='1.94.1' + export EVIDENCE_CARGO='1.94.1 (patched host metadata)' + export EVIDENCE_AUXILIARY='cargo-auditable 0.7.5; Xcode 16.4; macOS SDK 15.5' + npx -y celq@0.6.0 -n \ + --arg="host:string=$EVIDENCE_HOST" \ + --arg="rustc:string=$EVIDENCE_RUSTC" \ + --arg="cargo:string=$EVIDENCE_CARGO" \ + --arg="auxiliary:string=$EVIDENCE_AUXILIARY" \ + '{"host": host, "toolchain": {"rustc": rustc, "cargo": cargo, "auxiliary": auxiliary}}' \ + > artifacts/evidence.json + + - name: Upload reproducible build + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 + with: + name: reproducible-macos-aarch64-macos-15-intel + path: artifacts + retention-days: 1 + if-no-files-found: error + compression-level: 0 diff --git a/.github/workflows/sub_reproducible_from_windows.yml b/.github/workflows/sub_reproducible_from_windows.yml new file mode 100644 index 0000000..ae9b02b --- /dev/null +++ b/.github/workflows/sub_reproducible_from_windows.yml @@ -0,0 +1,206 @@ +name: Reproducible builds from Windows (Subworkflow) + +on: + workflow_call: + inputs: + source_ref: + description: Commit or tag to build + required: true + type: string + runner: + description: Windows runner label + required: true + type: string + use_cache: + description: Whether tool setup actions may use caches + required: false + type: boolean + default: false + +permissions: + contents: read + +defaults: + run: + shell: bash + +env: + CARGO_TERM_COLOR: always + TARGET: x86_64-pc-windows-msvc + +jobs: + patched_cargo: + name: Patched Cargo for Windows ARM64 + if: inputs.runner == 'windows-11-vs2026-arm' + runs-on: windows-2025 + steps: + - name: Preserve LF line endings for Cargo patching + run: git config --global core.autocrlf false + + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + with: + ref: ${{ inputs.source_ref }} + persist-credentials: false + + - name: Install Rust 1.94.1 with Windows ARM64 target + uses: dtolnay/rust-toolchain@9376cdc5a5e25b16da71af47712785cf06b0d6d4 # 1.94.1 + with: + targets: aarch64-pc-windows-msvc + + - name: Setup patched Cargo + uses: $/.github/actions/setup-patched-cargo + with: + ref: 29ea6fb6a5db279426f4cc4e17aa385f05a0cfbc + target: aarch64-pc-windows-msvc + patch-file: .github/reproducibility/patches/cargo-windows-x86_64-metadata.patch + env: + CFG_VER_DESCRIPTION: windows-x86_64-metadata-patch + LIBZ_SYS_STATIC: "1" + + native: + name: Windows x86-64 host + if: inputs.runner == 'windows-2025' + runs-on: windows-2025 + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + with: + ref: ${{ inputs.source_ref }} + persist-credentials: false + + - name: Setup Xwin + id: setup-xwin + uses: $/.github/actions/setup-xwin + with: + target: ${{ env.TARGET }} + rust_components: llvm-tools + cache_directory: ${{ github.workspace }}/.xwin-cache + use_cache: ${{ inputs.use_cache }} + + - name: Configure reproducible build + run: | + echo "SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct)" >> "$GITHUB_ENV" + echo "TZ=UTC" >> "$GITHUB_ENV" + echo "LC_ALL=C" >> "$GITHUB_ENV" + RUST_SYSROOT=$(rustc --print sysroot) + echo "RUSTFLAGS=--remap-path-prefix=${CARGO_HOME:-$HOME/.cargo}=/cargo --remap-path-prefix=${RUST_SYSROOT}=/rust-toolchain --remap-path-prefix=${GITHUB_WORKSPACE}=/src -C link-arg=/DEBUG:NONE" >> "$GITHUB_ENV" + + - name: Build from source + env: + XWIN_CACHE_DIR: ${{ steps.setup-xwin.outputs.cache_directory }} + XWIN_CRT_VERSION: ${{ steps.setup-xwin.outputs.xwin_crt_version }} + XWIN_SDK_VERSION: ${{ steps.setup-xwin.outputs.xwin_sdk_version }} + XWIN_VERSION: ${{ steps.setup-xwin.outputs.xwin_version }} + run: >- + cargo auditable xwin build --locked --release --target "${TARGET}" + --xwin-version "${XWIN_VERSION}" + --xwin-sdk-version "${XWIN_SDK_VERSION}" + --xwin-crt-version "${XWIN_CRT_VERSION}" + + - name: Package build + run: | + 7z a -mtm=off -mtc=off -mta=off archive.zip "./target/${TARGET}/release/celq.exe" + 7z rn archive.zip "target/${TARGET}/release/celq.exe" celq.exe + mkdir -p artifacts + cp "target/${TARGET}/release/celq.exe" artifacts/binary + mv archive.zip artifacts/archive + + - name: Upload reproducible build + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 + with: + name: reproducible-windows-x86_64-windows-2025 + path: artifacts + retention-days: 1 + if-no-files-found: error + compression-level: 0 + + arm: + name: Windows ARM64 host + if: inputs.runner == 'windows-11-vs2026-arm' + needs: patched_cargo + runs-on: windows-11-vs2026-arm + steps: + - name: Select native Windows ARM64 Rust host + run: | + rustup set default-host aarch64-pc-windows-msvc + echo "RUSTUP_TOOLCHAIN=1.94.1-aarch64-pc-windows-msvc" >> "$GITHUB_ENV" + + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + with: + ref: ${{ inputs.source_ref }} + persist-credentials: false + + - name: Setup Xwin + id: setup-xwin + uses: $/.github/actions/setup-xwin + with: + target: ${{ env.TARGET }} + rust_components: llvm-tools + cache_directory: ${{ github.workspace }}/.xwin-cache + use_cache: ${{ inputs.use_cache }} + + - name: Verify native compiler + run: | + test "$(rustc -vV | sed -n 's/^host: //p' | tr -d '\r')" = aarch64-pc-windows-msvc + + - name: Download patched Cargo + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 + with: + name: patched-cargo-aarch64-pc-windows-msvc + path: patched-cargo + + - name: Select patched Cargo + run: | + echo "$(cygpath -aw "$GITHUB_WORKSPACE/patched-cargo")" >> "$GITHUB_PATH" + echo "CARGO=$(cygpath -aw "$GITHUB_WORKSPACE/patched-cargo/cargo.exe")" >> "$GITHUB_ENV" + + - name: Configure reproducible build + run: | + test "$(cygpath -aw "$(command -v cargo)")" = "$CARGO" + echo "SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct)" >> "$GITHUB_ENV" + echo "TZ=UTC" >> "$GITHUB_ENV" + echo "LC_ALL=C" >> "$GITHUB_ENV" + RUST_SYSROOT=$(rustc --print sysroot) + echo "RUSTFLAGS=--remap-path-prefix=${CARGO_HOME:-$HOME/.cargo}=/cargo --remap-path-prefix=${RUST_SYSROOT}=/rust-toolchain --remap-path-prefix=${GITHUB_WORKSPACE}=/src -C link-arg=/DEBUG:NONE" >> "$GITHUB_ENV" + + - name: Build from source + env: + XWIN_CACHE_DIR: ${{ steps.setup-xwin.outputs.cache_directory }} + XWIN_CRT_VERSION: ${{ steps.setup-xwin.outputs.xwin_crt_version }} + XWIN_SDK_VERSION: ${{ steps.setup-xwin.outputs.xwin_sdk_version }} + XWIN_VERSION: ${{ steps.setup-xwin.outputs.xwin_version }} + run: >- + cargo auditable xwin build --locked --release --target "${TARGET}" + --xwin-version "${XWIN_VERSION}" + --xwin-sdk-version "${XWIN_SDK_VERSION}" + --xwin-crt-version "${XWIN_CRT_VERSION}" + + - name: Package build + run: | + 7z a -mtm=off -mtc=off -mta=off archive.zip "./target/${TARGET}/release/celq.exe" + 7z rn archive.zip "target/${TARGET}/release/celq.exe" celq.exe + mkdir -p artifacts + cp "target/${TARGET}/release/celq.exe" artifacts/binary + mv archive.zip artifacts/archive + + - name: Capture build evidence + run: | + export EVIDENCE_HOST='windows-11-vs2026-arm (ARM64)' + export EVIDENCE_RUSTC='1.94.1' + export EVIDENCE_CARGO='1.94.1 (patched host metadata)' + export EVIDENCE_AUXILIARY='cargo-xwin 0.23.1; cargo-auditable 0.7.5; LLVM 21.1.8; MSVC 17; SDK 10.0.26100; CRT 14.44.17.14' + npx -y celq@0.6.0 -n \ + --arg="host:string=$EVIDENCE_HOST" \ + --arg="rustc:string=$EVIDENCE_RUSTC" \ + --arg="cargo:string=$EVIDENCE_CARGO" \ + --arg="auxiliary:string=$EVIDENCE_AUXILIARY" \ + '{"host": host, "toolchain": {"rustc": rustc, "cargo": cargo, "auxiliary": auxiliary}}' \ + > artifacts/evidence.json + + - name: Upload reproducible build + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 + with: + name: reproducible-windows-x86_64-windows-11-vs2026-arm + path: artifacts + retention-days: 1 + if-no-files-found: error + compression-level: 0