Repository navigation
feat(benchmark): show source-bound retained outcome improvement #1640
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Desktop Release Artifacts | |
| on: | |
| pull_request: | |
| paths: | |
| - ".github/workflows/desktop-release-artifacts.yml" | |
| - "apps/desktop/loopx-control-plane/**" | |
| - "apps/presentation/dashboard/**" | |
| - "examples/desktop-icon-alpha-smoke.py" | |
| - "examples/desktop-release-workflow-smoke.py" | |
| - "scripts/desktop_release_artifacts.py" | |
| release: | |
| types: [published] | |
| workflow_dispatch: | |
| inputs: | |
| tag: | |
| description: "Existing GitHub Release tag to attach desktop artifacts to" | |
| required: false | |
| type: string | |
| publication_probe: | |
| description: "Read-only builder publication preflight; never attaches Release assets" | |
| required: false | |
| type: boolean | |
| default: false | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: desktop-release-artifacts-${{ github.event.release.tag_name || inputs.tag || github.ref }} | |
| # Superseded PR validation may stop; publication retains its serialized lane. | |
| cancel-in-progress: ${{ github.event_name == 'pull_request' }} | |
| jobs: | |
| build: | |
| if: github.repository == 'loopx-project/loopx' | |
| name: ${{ matrix.name }} | |
| runs-on: ${{ matrix.runner }} | |
| timeout-minutes: 30 | |
| permissions: | |
| contents: read | |
| id-token: write | |
| attestations: write | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - name: macOS desktop | |
| runner: macos-15 | |
| bundles: dmg app | |
| artifact-name: loopx-macos | |
| artifact-path: dist/desktop/* | |
| - name: Windows desktop | |
| runner: windows-latest | |
| bundles: msi nsis | |
| artifact-name: loopx-windows | |
| artifact-path: dist/desktop/* | |
| steps: | |
| - name: Check out release source | |
| uses: actions/checkout@v7 | |
| with: | |
| ref: ${{ github.event.release.tag_name || inputs.tag || github.sha }} | |
| - name: Resolve release identity | |
| id: identity | |
| shell: bash | |
| env: | |
| EVENT_RELEASE_TAG: ${{ github.event.release.tag_name }} | |
| INPUT_RELEASE_TAG: ${{ inputs.tag }} | |
| run: | | |
| set -euo pipefail | |
| release_tag="${EVENT_RELEASE_TAG:-${INPUT_RELEASE_TAG:-}}" | |
| if [[ -z "${release_tag}" ]]; then | |
| release_tag="$(git describe --tags --exact-match 2>/dev/null || echo "preview-${GITHUB_SHA::12}")" | |
| fi | |
| echo "release-tag=${release_tag}" >> "${GITHUB_OUTPUT}" | |
| - name: Set up Node | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: "24" | |
| cache: npm | |
| cache-dependency-path: | | |
| apps/desktop/loopx-control-plane/package-lock.json | |
| apps/presentation/dashboard/package-lock.json | |
| - name: Check out immutable preflight tooling | |
| if: github.event_name == 'workflow_dispatch' && inputs.publication_probe == true | |
| uses: actions/checkout@v7 | |
| with: | |
| ref: ${{ github.workflow_sha }} | |
| path: .release-tooling | |
| persist-credentials: false | |
| - name: Capture read-only release source | |
| if: github.event_name == 'workflow_dispatch' && inputs.publication_probe == true | |
| timeout-minutes: 2 | |
| env: | |
| PUBLICATION_PROBE: "true" | |
| RELEASE_TAG: ${{ steps.identity.outputs.release-tag }} | |
| run: node .release-tooling/scripts/ci/desktop_release_preflight.ts capture | |
| - name: Set up Rust | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Cache Rust build | |
| uses: Swatinem/rust-cache@v2 | |
| with: | |
| workspaces: apps/desktop/loopx-control-plane/src-tauri -> target | |
| key: desktop-${{ matrix.runner }} | |
| - name: Install desktop dependencies | |
| working-directory: apps/desktop/loopx-control-plane | |
| run: npm ci | |
| - name: Validate desktop icon background | |
| run: python examples/desktop-icon-alpha-smoke.py | |
| - name: Validate desktop release workflow | |
| if: github.event_name == 'pull_request' | |
| run: python examples/desktop-release-workflow-smoke.py | |
| - name: Build unsigned desktop preview bundles | |
| if: github.event_name == 'pull_request' | |
| working-directory: apps/desktop/loopx-control-plane | |
| run: npm run build -- --bundles ${{ matrix.bundles }} --no-sign | |
| - name: Build integrity-signed macOS release bundles | |
| if: github.event_name != 'pull_request' && runner.os == 'macOS' | |
| working-directory: apps/desktop/loopx-control-plane | |
| env: | |
| RELEASE_TAG: ${{ steps.identity.outputs.release-tag }} | |
| run: | | |
| set -euo pipefail | |
| release_version="${RELEASE_TAG#v}" | |
| if [[ ! "${release_version}" =~ ^[0-9]+\.[0-9]+\.[0-9]+([+-][0-9A-Za-z.-]+)?$ ]]; then | |
| echo "::error title=Invalid desktop release version::${RELEASE_TAG} is not a supported release tag" | |
| exit 1 | |
| fi | |
| npm run build -- --bundles ${{ matrix.bundles }} \ | |
| --config "{\"version\":\"${release_version}\",\"bundle\":{\"macOS\":{\"signingIdentity\":\"-\"}}}" | |
| - name: Build Windows release bundles | |
| if: github.event_name != 'pull_request' && runner.os == 'Windows' | |
| working-directory: apps/desktop/loopx-control-plane | |
| shell: bash | |
| env: | |
| RELEASE_TAG: ${{ steps.identity.outputs.release-tag }} | |
| run: | | |
| set -euo pipefail | |
| release_version="${RELEASE_TAG#v}" | |
| if [[ ! "${release_version}" =~ ^[0-9]+\.[0-9]+\.[0-9]+([+-][0-9A-Za-z.-]+)?$ ]]; then | |
| echo "::error title=Invalid desktop release version::${RELEASE_TAG} is not a supported release tag" | |
| exit 1 | |
| fi | |
| npm run build -- --bundles ${{ matrix.bundles }} --no-sign \ | |
| --config "{\"version\":\"${release_version}\"}" | |
| - name: Verify macOS desktop bundles | |
| if: github.event_name != 'pull_request' && runner.os == 'macOS' | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| app_path="apps/desktop/loopx-control-plane/src-tauri/target/release/bundle/macos/LoopX.app" | |
| dmg_path="$(find apps/desktop/loopx-control-plane/src-tauri/target/release/bundle/dmg -maxdepth 1 -name '*.dmg' -print -quit)" | |
| test -n "${dmg_path}" | |
| codesign --verify --deep --strict --verbose=2 "${app_path}" | |
| codesign --display --verbose=4 "${app_path}" 2>&1 \ | |
| | grep -q '^Signature=adhoc$' | |
| hdiutil verify "${dmg_path}" | |
| - name: Collect macOS desktop bundles | |
| if: runner.os == 'macOS' | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| mkdir -p dist/desktop | |
| cp apps/desktop/loopx-control-plane/src-tauri/target/release/bundle/dmg/*.dmg dist/desktop/ | |
| ditto -c -k --keepParent \ | |
| "apps/desktop/loopx-control-plane/src-tauri/target/release/bundle/macos/LoopX.app" \ | |
| "dist/desktop/LoopX.app.zip" | |
| - name: Collect Windows desktop bundles | |
| if: runner.os == 'Windows' | |
| shell: pwsh | |
| run: | | |
| New-Item -ItemType Directory -Force -Path dist/desktop | Out-Null | |
| Copy-Item apps/desktop/loopx-control-plane/src-tauri/target/release/bundle/msi/*.msi dist/desktop/ | |
| Copy-Item apps/desktop/loopx-control-plane/src-tauri/target/release/bundle/nsis/*.exe dist/desktop/ | |
| - name: Attest desktop artifacts | |
| id: binary-attestation | |
| if: github.event_name != 'pull_request' | |
| uses: actions/attest@v4 | |
| with: | |
| subject-path: ${{ matrix.artifact-path }} | |
| - name: Record preflight source subjects | |
| if: github.event_name == 'workflow_dispatch' && inputs.publication_probe == true | |
| timeout-minutes: 2 | |
| env: | |
| PUBLICATION_PROBE: "true" | |
| RELEASE_TAG: ${{ steps.identity.outputs.release-tag }} | |
| run: node .release-tooling/scripts/ci/desktop_release_preflight.ts record | |
| - name: Attest preflight source record | |
| if: github.event_name == 'workflow_dispatch' && inputs.publication_probe == true | |
| id: source-attestation | |
| timeout-minutes: 2 | |
| uses: actions/attest@v4 | |
| with: | |
| subject-path: .desktop-preflight/source/source.json | |
| - name: Preserve preflight attestation bundles | |
| if: github.event_name == 'workflow_dispatch' && inputs.publication_probe == true | |
| env: | |
| PUBLICATION_PROBE: "true" | |
| RELEASE_TAG: ${{ steps.identity.outputs.release-tag }} | |
| SOURCE_BUNDLE: ${{ steps.source-attestation.outputs.bundle-path }} | |
| BINARY_BUNDLE: ${{ steps.binary-attestation.outputs.bundle-path }} | |
| run: node .release-tooling/scripts/ci/desktop_release_preflight.ts bundles | |
| - name: Upload isolated preflight source | |
| if: github.event_name == 'workflow_dispatch' && inputs.publication_probe == true | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: desktop-source-${{ runner.os == 'macOS' && 'macos' || 'windows' }}-${{ github.run_attempt }} | |
| path: .desktop-preflight/source | |
| include-hidden-files: true | |
| if-no-files-found: error | |
| retention-days: 30 | |
| - name: Upload desktop artifact | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: ${{ matrix.artifact-name }}-${{ steps.identity.outputs.release-tag }} | |
| path: ${{ matrix.artifact-path }} | |
| if-no-files-found: error | |
| retention-days: 30 | |
| - name: Check peer success and publication budget | |
| if: github.event_name == 'workflow_dispatch' && inputs.publication_probe == true && runner.os == 'Windows' | |
| id: preflight | |
| timeout-minutes: 2 | |
| env: | |
| PUBLICATION_PROBE: "true" | |
| RELEASE_TAG: ${{ steps.identity.outputs.release-tag }} | |
| run: node .release-tooling/scripts/ci/desktop_release_preflight.ts admit | |
| - name: Download same-run Mac desktop artifact | |
| id: mac-desktop | |
| if: github.event_name == 'workflow_dispatch' && inputs.publication_probe == true && runner.os == 'Windows' && steps.preflight.outputs.eligible == 'true' | |
| timeout-minutes: 2 | |
| uses: actions/download-artifact@v7 | |
| with: | |
| name: loopx-macos-${{ steps.identity.outputs.release-tag }} | |
| path: dist/desktop | |
| - name: Download same-run Mac source proof | |
| id: mac-source | |
| if: github.event_name == 'workflow_dispatch' && inputs.publication_probe == true && runner.os == 'Windows' && steps.preflight.outputs.eligible == 'true' | |
| timeout-minutes: 2 | |
| uses: actions/download-artifact@v7 | |
| with: | |
| name: ${{ steps.preflight.outputs.mac-source }} | |
| path: .desktop-preflight/mac-source | |
| - name: Verify read-only publication preflight | |
| if: always() && github.event_name == 'workflow_dispatch' && inputs.publication_probe == true && runner.os == 'Windows' && steps.preflight.outputs.eligible == 'true' | |
| timeout-minutes: 5 | |
| env: | |
| PUBLICATION_PROBE: "true" | |
| RELEASE_TAG: ${{ steps.identity.outputs.release-tag }} | |
| GH_TOKEN: ${{ github.token }} | |
| PEER_ARTIFACT_DOWNLOAD: ${{ steps.mac-desktop.outcome }} | |
| PEER_SOURCE_DOWNLOAD: ${{ steps.mac-source.outcome }} | |
| run: node .release-tooling/scripts/ci/desktop_release_preflight.ts verify | |
| - name: Preserve read-only preflight result | |
| if: always() && github.event_name == 'workflow_dispatch' && inputs.publication_probe == true && runner.os == 'Windows' | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: desktop-publication-preflight-${{ github.run_attempt }} | |
| path: .desktop-preflight/report.json | |
| include-hidden-files: true | |
| if-no-files-found: error | |
| retention-days: 30 | |
| upload-release: | |
| if: github.event_name != 'pull_request' && !(github.event_name == 'workflow_dispatch' && inputs.publication_probe == true) | |
| needs: build | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| permissions: | |
| contents: write | |
| steps: | |
| - name: Check out release workflow source | |
| uses: actions/checkout@v7 | |
| - name: Download desktop artifacts | |
| uses: actions/download-artifact@v7 | |
| with: | |
| pattern: loopx-* | |
| path: dist/desktop | |
| merge-multiple: true | |
| - name: Resolve release identity | |
| id: identity | |
| env: | |
| EVENT_RELEASE_TAG: ${{ github.event.release.tag_name }} | |
| INPUT_RELEASE_TAG: ${{ inputs.tag }} | |
| run: | | |
| set -euo pipefail | |
| release_tag="${EVENT_RELEASE_TAG:-${INPUT_RELEASE_TAG:-}}" | |
| if [[ -z "${release_tag}" ]]; then | |
| echo "::error title=Missing release tag::release uploads require a release event or workflow_dispatch tag" | |
| exit 1 | |
| fi | |
| echo "release-tag=${release_tag}" >> "${GITHUB_OUTPUT}" | |
| echo "release-version=${release_tag#v}" >> "${GITHUB_OUTPUT}" | |
| - name: Validate target release | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| RELEASE_TAG: ${{ steps.identity.outputs.release-tag }} | |
| run: gh release view "${RELEASE_TAG}" --repo "${GITHUB_REPOSITORY}" >/dev/null | |
| - name: Back up existing desktop release assets | |
| if: github.event_name == 'workflow_dispatch' | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| RELEASE_TAG: ${{ steps.identity.outputs.release-tag }} | |
| run: | | |
| set -euo pipefail | |
| mkdir -p dist/previous-desktop | |
| mapfile -t assets < <( | |
| gh release view "${RELEASE_TAG}" \ | |
| --repo "${GITHUB_REPOSITORY}" \ | |
| --json assets \ | |
| --jq '.assets[].name | select(. == "DESKTOP-SHA256SUMS" or (startswith("LoopX") and (endswith(".dmg") or endswith(".zip") or endswith(".exe") or endswith(".msi"))))' | |
| ) | |
| for asset in "${assets[@]}"; do | |
| gh release download "${RELEASE_TAG}" \ | |
| --repo "${GITHUB_REPOSITORY}" \ | |
| --pattern "${asset}" \ | |
| --dir dist/previous-desktop | |
| done | |
| { | |
| echo "release_tag=${RELEASE_TAG}" | |
| echo "asset_count=${#assets[@]}" | |
| printf '%s\n' "${assets[@]}" | |
| } > dist/previous-desktop/ASSET-INVENTORY.txt | |
| cd dist/previous-desktop | |
| find . -maxdepth 1 -type f \ | |
| ! -name PREVIOUS-DESKTOP-SHA256SUMS \ | |
| -printf '%f\n' \ | |
| | LC_ALL=C sort \ | |
| | while IFS= read -r artifact; do | |
| sha256sum "${artifact}" | |
| done \ | |
| > PREVIOUS-DESKTOP-SHA256SUMS | |
| - name: Preserve previous desktop release assets | |
| if: github.event_name == 'workflow_dispatch' | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: previous-desktop-${{ steps.identity.outputs.release-tag }}-${{ github.run_id }} | |
| path: dist/previous-desktop | |
| if-no-files-found: error | |
| retention-days: 30 | |
| - name: Validate complete rebuild and generate desktop checksums | |
| env: | |
| RELEASE_VERSION: ${{ steps.identity.outputs.release-version }} | |
| run: | | |
| set -euo pipefail | |
| python scripts/desktop_release_artifacts.py write-checksums \ | |
| --dist-dir dist/desktop \ | |
| --version "${RELEASE_VERSION}" \ | |
| --output dist/desktop/DESKTOP-SHA256SUMS | |
| python scripts/desktop_release_artifacts.py verify-checksums \ | |
| --dist-dir dist/desktop \ | |
| --version "${RELEASE_VERSION}" \ | |
| --checksum-file dist/desktop/DESKTOP-SHA256SUMS | |
| cd dist/desktop | |
| sha256sum --check DESKTOP-SHA256SUMS | |
| - name: Replace complete desktop binary set | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| RELEASE_TAG: ${{ steps.identity.outputs.release-tag }} | |
| run: | | |
| set -euo pipefail | |
| if gh release view "${RELEASE_TAG}" \ | |
| --repo "${GITHUB_REPOSITORY}" \ | |
| --json assets \ | |
| --jq 'any(.assets[]; .name == "DESKTOP-SHA256SUMS")' \ | |
| | grep -qx true | |
| then | |
| gh release delete-asset "${RELEASE_TAG}" DESKTOP-SHA256SUMS \ | |
| --repo "${GITHUB_REPOSITORY}" \ | |
| --yes | |
| fi | |
| gh release upload "${RELEASE_TAG}" \ | |
| dist/desktop/*.dmg \ | |
| dist/desktop/*.zip \ | |
| dist/desktop/*.exe \ | |
| dist/desktop/*.msi \ | |
| --repo "${GITHUB_REPOSITORY}" \ | |
| --clobber | |
| - name: Replace desktop checksum manifest last | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| RELEASE_TAG: ${{ steps.identity.outputs.release-tag }} | |
| run: | | |
| gh release upload "${RELEASE_TAG}" \ | |
| dist/desktop/DESKTOP-SHA256SUMS \ | |
| --repo "${GITHUB_REPOSITORY}" \ | |
| --clobber | |
| - name: Verify published desktop release | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| RELEASE_TAG: ${{ steps.identity.outputs.release-tag }} | |
| RELEASE_VERSION: ${{ steps.identity.outputs.release-version }} | |
| run: | | |
| set -euo pipefail | |
| mkdir -p dist/published-desktop | |
| for asset in \ | |
| LoopX.app.zip \ | |
| "LoopX_${RELEASE_VERSION}_aarch64.dmg" \ | |
| "LoopX_${RELEASE_VERSION}_x64-setup.exe" \ | |
| "LoopX_${RELEASE_VERSION}_x64_en-US.msi" \ | |
| DESKTOP-SHA256SUMS | |
| do | |
| gh release download "${RELEASE_TAG}" \ | |
| --repo "${GITHUB_REPOSITORY}" \ | |
| --pattern "${asset}" \ | |
| --dir dist/published-desktop | |
| done | |
| python scripts/desktop_release_artifacts.py verify-checksums \ | |
| --dist-dir dist/published-desktop \ | |
| --version "${RELEASE_VERSION}" \ | |
| --checksum-file dist/published-desktop/DESKTOP-SHA256SUMS |