Proof statement v1 (#236) #74
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
| # release.yml — first public release-prep draft artifact workflow. | ||
| # | ||
| # This workflow creates CI draft artifacts only. It does not create GitHub Releases, | ||
| # publish PyPI distributions, publish npm packages, or approve launch wording. | ||
| name: release | ||
| on: | ||
| workflow_dispatch: {} | ||
| push: | ||
| tags: ["v*"] | ||
| jobs: | ||
| preflight: | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - name: public surface posture tests | ||
| run: python3 .github/scripts/test_public_surface_posture.py | ||
| - name: claims gate | ||
| run: python3 .github/scripts/claims_gate.py | ||
| - name: Python public API policy tests | ||
| run: python3 .github/scripts/test_python_public_api_policy.py | ||
| - name: npm binary package scaffold tests | ||
| run: python3 .github/scripts/test_npm_binary_package_scaffold.py | ||
| - name: PDFium manual setup contract tests | ||
| run: python3 .github/scripts/test_pdfium_manual_setup_contract.py | ||
| - name: deterministic CLI archive tests | ||
| run: python3 .github/scripts/test_build_release_cli_archive.py | ||
| - name: Windows verify-only candidate contract tests | ||
| run: python3 .github/scripts/test_windows_verify_candidate.py | ||
| - name: ethos-full candidate contract tests | ||
| run: python3 .github/scripts/test_ethos_full_candidate.py | ||
| - name: ethos-full smoke helper tests | ||
| run: python3 .github/scripts/test_smoke_ethos_full_candidate.py | ||
| cli-draft-artifacts: | ||
| needs: preflight | ||
| strategy: | ||
| fail-fast: false | ||
| matrix: | ||
| include: | ||
| - artifact_target: macos-arm64 | ||
| os: macos-14 | ||
| archive_ext: tar.gz | ||
| - artifact_target: linux-x64 | ||
| os: ubuntu-latest | ||
| archive_ext: tar.gz | ||
| runs-on: ${{ matrix.os }} | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - run: rustup show | ||
| - name: build CLI | ||
| run: cargo build --locked --release -p ethos-cli | ||
| - name: derive candidate version | ||
| id: version | ||
| shell: bash | ||
| run: echo "value=$(python3 -c \"import tomllib; print(tomllib.load(open('Cargo.toml','rb'))['workspace']['package']['version'])\")" >> "$GITHUB_OUTPUT" | ||
| - name: assemble draft artifact | ||
| shell: bash | ||
| run: | | ||
| set -euo pipefail | ||
| out="target/release-artifacts/ethos-${{ matrix.artifact_target }}" | ||
| mkdir -p "$out" | ||
| cp target/release/ethos "$out/ethos" | ||
| cp LICENSE NOTICE "$out/" | ||
| cp docs/pdfium-manual-setup.md "$out/" | ||
| python3 .github/scripts/build_release_cli_archive.py \ | ||
| --artifact-dir "$out" \ | ||
| --out "$out.${{ matrix.archive_ext }}" | ||
| shasum -a 256 "$out.${{ matrix.archive_ext }}" > "$out.${{ matrix.archive_ext }}.sha256" | ||
| python3 .github/scripts/write_release_artifact_inventory.py \ | ||
| --artifact "$out.${{ matrix.archive_ext }}" \ | ||
| --checksum "$out.${{ matrix.archive_ext }}.sha256" \ | ||
| --target "${{ matrix.artifact_target }}" \ | ||
| --out "$out.inventory.json" | ||
| - name: smoke draft artifact | ||
| run: | | ||
| python3 .github/scripts/smoke_release_cli_artifact.py \ | ||
| --artifact-dir "target/release-artifacts/ethos-${{ matrix.artifact_target }}" \ | ||
| --expected-version "ethos ${{ steps.version.outputs.value }}" \ | ||
| --target "${{ matrix.artifact_target }}" \ | ||
| --out "target/release-artifacts/ethos-${{ matrix.artifact_target }}.smoke.json" | ||
| - uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: ethos-cli-draft-${{ matrix.artifact_target }} | ||
| path: | | ||
| target/release-artifacts/*.tar.gz | ||
| target/release-artifacts/*.sha256 | ||
| target/release-artifacts/*.inventory.json | ||
| target/release-artifacts/*.smoke.json | ||
| ethos-full-release-candidate: | ||
| needs: preflight | ||
| strategy: | ||
| fail-fast: false | ||
| matrix: | ||
| include: | ||
| - artifact_target: macos-arm64 | ||
| os: macos-14 | ||
| - artifact_target: linux-x64 | ||
| os: ubuntu-latest | ||
| runs-on: ${{ matrix.os }} | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - run: rustup show | ||
| - name: build CLI | ||
| run: cargo build --locked --release -p ethos-cli | ||
| - name: download profile-pinned PDFium and build candidates twice | ||
| shell: bash | ||
| run: | | ||
| set -euo pipefail | ||
| version=$(python3 -c "import tomllib; print(tomllib.load(open('Cargo.toml','rb'))['workspace']['package']['version'])") | ||
| pdfium_archive="target/release-artifacts/pdfium-${{ matrix.artifact_target }}.tgz" | ||
| url=$(python3 -c "import json, urllib.parse; p=json.load(open('profiles/ethos-deterministic-v1.json')); b=p['backend']; base,tag=b['distribution']['release_url'].rsplit('/tag/',1); print(f\"{base}/download/{urllib.parse.quote(tag, safe='')}/{b['platform_artifacts']['${{ matrix.artifact_target }}']['name']}\")") | ||
| mkdir -p target/release-artifacts/run1 target/release-artifacts/run2 | ||
| curl -fL --retry 3 --output "$pdfium_archive" "$url" | ||
| for run in run1 run2; do | ||
| python3 scripts/build-ethos-full-candidate.py --target "${{ matrix.artifact_target }}" --version "$version" --ethos-binary target/release/ethos --pdfium-archive "$pdfium_archive" --out-dir "target/release-artifacts/$run" | ||
| done | ||
| cmp target/release-artifacts/run1/ethos-full-"$version"-"${{ matrix.artifact_target }}".tar.gz target/release-artifacts/run2/ethos-full-"$version"-"${{ matrix.artifact_target }}".tar.gz | ||
| cmp target/release-artifacts/run1/ethos-full-"$version"-"${{ matrix.artifact_target }}".tar.gz.sha256 target/release-artifacts/run2/ethos-full-"$version"-"${{ matrix.artifact_target }}".tar.gz.sha256 | ||
| cmp target/release-artifacts/run1/ethos-full-"$version"-"${{ matrix.artifact_target }}".inventory.json target/release-artifacts/run2/ethos-full-"$version"-"${{ matrix.artifact_target }}".inventory.json | ||
| python3 .github/scripts/smoke_ethos_full_candidate.py --archive target/release-artifacts/run1/ethos-full-"$version"-"${{ matrix.artifact_target }}".tar.gz --checksum target/release-artifacts/run1/ethos-full-"$version"-"${{ matrix.artifact_target }}".tar.gz.sha256 --inventory target/release-artifacts/run1/ethos-full-"$version"-"${{ matrix.artifact_target }}".inventory.json --extract-dir target/release-artifacts/extracted --expected-version "ethos $version" --fixture fixtures/synthetic/simple-text/document.pdf --out target/release-artifacts/run1/ethos-full-"$version"-"${{ matrix.artifact_target }}".smoke.json | ||
| - uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: ethos-full-candidate-${{ matrix.artifact_target }} | ||
| path: | | ||
| target/release-artifacts/run1/*.tar.gz | ||
| target/release-artifacts/run1/*.sha256 | ||
| target/release-artifacts/run1/*.inventory.json | ||
| target/release-artifacts/run1/*.smoke.json | ||
| windows-verify-draft-artifact: | ||
| needs: preflight | ||
| runs-on: windows-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - run: rustup show | ||
| - name: build Windows x64 CLI | ||
| run: cargo build --locked --release -p ethos-cli | ||
| - name: derive candidate version | ||
| id: version | ||
| shell: pwsh | ||
| run: '"value=$(python -c \"import tomllib; print(tomllib.load(open(''Cargo.toml'',''rb''))[''workspace''][''package''][''version'])\")" | Out-File -FilePath $env:GITHUB_OUTPUT -Append' | ||
| - name: assemble deterministic verify-only candidates twice | ||
| run: | | ||
| python scripts/build-windows-verify-candidate.py --ethos-binary target/release/ethos.exe --version ${{ steps.version.outputs.value }} --out-dir target/release-artifacts/run1 | ||
| python scripts/build-windows-verify-candidate.py --ethos-binary target/release/ethos.exe --version ${{ steps.version.outputs.value }} --out-dir target/release-artifacts/run2 | ||
| python -c "from pathlib import Path; a=Path('target/release-artifacts/run1/ethos-windows-x64.zip').read_bytes(); b=Path('target/release-artifacts/run2/ethos-windows-x64.zip').read_bytes(); assert a == b, 'Windows candidate archives differ'" | ||
| - name: extract Windows candidate for smoke | ||
| run: python -m zipfile -e target/release-artifacts/run1/ethos-windows-x64.zip target/release-artifacts/extracted | ||
| - name: write Windows draft inventory | ||
| run: | | ||
| python .github/scripts/write_release_artifact_inventory.py --artifact target/release-artifacts/run1/ethos-windows-x64.zip --checksum target/release-artifacts/run1/ethos-windows-x64.zip.sha256 --target windows-x64 --out target/release-artifacts/run1/ethos-windows-x64.inventory.json | ||
| - name: smoke Windows verify-only artifact | ||
| run: | | ||
| python .github/scripts/smoke_release_cli_artifact.py --artifact-dir target/release-artifacts/extracted/ethos-windows-x64 --expected-version "ethos ${{ steps.version.outputs.value }}" --target windows-x64 --out target/release-artifacts/run1/ethos-windows-x64.smoke.json | ||
| - name: validate Windows draft inventory | ||
| run: python .github/scripts/validate_release_artifact_inventory.py target/release-artifacts/run1/ethos-windows-x64.inventory.json | ||
| - uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: ethos-cli-draft-windows-x64 | ||
| path: | | ||
| target/release-artifacts/run1/*.zip | ||
| target/release-artifacts/run1/*.sha256 | ||
| target/release-artifacts/run1/*.inventory.json | ||
| target/release-artifacts/run1/*.smoke.json | ||