You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maka.apache.org by as...@apache.org on 2026/09/02 14:34:39 UTC

(maka) 01/01: test(release): probe Windows rebuild differences on demand

This is an automated email from the ASF dual-hosted git repository.

Astro-Han pushed a commit to branch test/windows-repro-probe
in repository https://gitbox.apache.org/repos/asf/maka.git

commit 48b0408003edcf9594c38e2cb1bfc79beb4283b5
Author: AstroHan <le...@outlook.com>
AuthorDate: Wed Sep 2 22:34:28 2026 +0800

    test(release): probe Windows rebuild differences on demand
    
    Run the existing unsigned Windows packaging path on two fresh runners at the same commit and the release Node/npm versions. Retain raw artifact hashes, build environments, and payloads to diagnose differences without normalizing them away. This branch-only experiment neither signs nor publishes artifacts and is not trusted-hardware release validation.
    
    Generated-by: Codex
---
 .github/workflows/release-windows-check.yml | 135 ++++++++++++++++++++++++++++
 1 file changed, 135 insertions(+)

diff --git a/.github/workflows/release-windows-check.yml b/.github/workflows/release-windows-check.yml
index a13b76556d..5a58427ba8 100644
--- a/.github/workflows/release-windows-check.yml
+++ b/.github/workflows/release-windows-check.yml
@@ -102,6 +102,11 @@ on:
   schedule:
     - cron: '17 5 * * *'
   workflow_dispatch:
+    inputs:
+      reproducibility_probe:
+        description: Compare two clean unsigned builds without publishing or signing
+        type: boolean
+        default: false
 
 permissions:
   contents: read
@@ -116,6 +121,7 @@ concurrency:
 
 jobs:
   package:
+    if: ${{ !inputs.reproducibility_probe }}
     runs-on: windows-2025
     timeout-minutes: 45
     defaults:
@@ -208,3 +214,132 @@ jobs:
           npm run verify:windows-installer-rollback -- \
             "${{ steps.installer.outputs.exe }}" \
             apps/desktop/release-autoupdate-next
+
+  # Temporary experiment on this branch; not an independent release approval.
+  reproducibility-build:
+    if: ${{ github.event_name == 'workflow_dispatch' && inputs.reproducibility_probe }}
+    runs-on: windows-2025
+    timeout-minutes: 45
+    strategy:
+      fail-fast: false
+      matrix:
+        sample: [a, b]
+    defaults:
+      run:
+        shell: bash
+        working-directory: sample-${{ matrix.sample }}
+    steps:
+      - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
+        with:
+          ref: ${{ github.sha }}
+          path: sample-${{ matrix.sample }}
+          persist-credentials: false
+
+      - name: Read the release toolchain authority
+        id: toolchain
+        run: |
+          echo "node=$(node -p 'require("./package.json").releaseToolchain.node')" >> "$GITHUB_OUTPUT"
+          echo "npm=$(node -p 'require("./package.json").packageManager.slice(4)')" >> "$GITHUB_OUTPUT"
+
+      - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
+        with:
+          node-version: ${{ steps.toolchain.outputs.node }}
+          package-manager-cache: false
+
+      - name: Install the release toolchain and clean dependencies
+        env:
+          NPM_VERSION: ${{ steps.toolchain.outputs.npm }}
+        run: |
+          npm install --global --no-audit --no-fund "npm@$NPM_VERSION"
+          test "$(npm --version)" = "$NPM_VERSION"
+          npm ci
+          rustup update stable --no-self-update
+
+      - name: Record the actual build environment
+        shell: pwsh
+        run: |
+          New-Item -ItemType Directory -Path evidence | Out-Null
+          [ordered]@{
+            sourceCommit = (git rev-parse HEAD)
+            productVersion = (Get-Content package.json -Raw | ConvertFrom-Json).version
+            node = (node --version)
+            npm = (npm --version)
+            rust = (rustc -Vv) -join "`n"
+            cargo = (cargo --version)
+            imageOS = $env:ImageOS
+            imageVersion = $env:ImageVersion
+            os = [System.Environment]::OSVersion.VersionString
+            checkout = (Get-Location).Path
+          } | ConvertTo-Json | Set-Content evidence/environment.json -Encoding utf8
+
+      - name: Package through the existing unsigned Windows path
+        run: npm run package:windows-x64
+
+      - name: Hash packaged files and unpacked payload without normalization
+        shell: pwsh
+        run: |
+          $releaseRoot = (Resolve-Path apps/desktop/release).Path
+          $files = @(Get-ChildItem $releaseRoot -Recurse -File | ForEach-Object {
+            [ordered]@{
+              path = [System.IO.Path]::GetRelativePath($releaseRoot, $_.FullName).Replace('\', '/')
+              size = $_.Length
+              sha256 = (Get-FileHash -LiteralPath $_.FullName -Algorithm SHA256).Hash.ToLowerInvariant()
+            }
+          } | Sort-Object { $_.path })
+          if ($files.Count -eq 0) { throw 'No release files found' }
+          ConvertTo-Json -InputObject $files -Depth 4 | Set-Content evidence/files.json -Encoding utf8
+
+      - name: Retain evidence even when packaging fails
+        if: always()
+        uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
+        with:
+          name: windows-repro-evidence-${{ matrix.sample }}
+          path: sample-${{ matrix.sample }}/evidence
+          if-no-files-found: error
+          retention-days: 7
+
+      - name: Retain unsigned artifacts for byte-level diagnosis
+        uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
+        with:
+          name: windows-repro-payload-${{ matrix.sample }}
+          path: sample-${{ matrix.sample }}/apps/desktop/release
+          if-no-files-found: error
+          retention-days: 7
+
+  reproducibility-compare:
+    needs: reproducibility-build
+    runs-on: ubuntu-24.04
+    timeout-minutes: 45
+    steps:
+      - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+        with:
+          pattern: windows-repro-evidence-*
+          path: evidence
+
+      - name: Compare raw hashes and report every difference
+        run: |
+          node --input-type=module <<'NODE'
+          import { readFileSync, appendFileSync } from 'node:fs';
+          const read = (sample, name) => JSON.parse(readFileSync(`evidence/windows-repro-evidence-${sample}/${name}.json`, 'utf8'));
+          const environments = ['a', 'b'].map(sample => read(sample, 'environment'));
+          const environmentKeys = ['sourceCommit', 'productVersion', 'node', 'npm', 'rust', 'cargo', 'imageOS', 'imageVersion', 'os'];
+          const environmentDifferences = environmentKeys.filter(key => environments[0][key] !== environments[1][key]);
+          const files = ['a', 'b'].map(sample => new Map(read(sample, 'files').map(file => [file.path, file])));
+          const differences = [...new Set([...files[0].keys(), ...files[1].keys()])].sort().filter(path => {
+            const [a, b] = files.map(sample => sample.get(path));
+            return !a || !b || a.size !== b.size || a.sha256 !== b.sha256;
+          });
+          const payloadDifferences = differences.filter(path => path.startsWith('win-unpacked/'));
+          const summary = [
+            '# Windows reproducibility probe',
+            'Engineering experiment only; not trusted-hardware release validation.',
+            `Source: ${environments[0].sourceCommit}`,
+            `Environment differences: ${environmentDifferences.join(', ') || 'none'}`,
+            `Files: ${files[0].size} / ${files[1].size}`,
+            `Different files: ${differences.length}; unpacked payload: ${payloadDifferences.length}`,
+            '```', ...differences, '```',
+          ].join('\n');
+          console.log(summary);
+          appendFileSync(process.env.GITHUB_STEP_SUMMARY, summary);
+          if (environmentDifferences.length || differences.length) process.exitCode = 1;
+          NODE


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org
For additional commands, e-mail: commits-help@maka.apache.org