237 lines
11 KiB
YAML
237 lines
11 KiB
YAML
name: Build and release
|
|
|
|
on:
|
|
push:
|
|
branches: ['**']
|
|
tags: ['v*']
|
|
pull_request:
|
|
workflow_dispatch:
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
concurrency:
|
|
group: build-${{ github.ref }}
|
|
cancel-in-progress: false
|
|
|
|
jobs:
|
|
metadata:
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
app_version: ${{ steps.release.outputs.app_version }}
|
|
release_tag: ${{ steps.release.outputs.release_tag }}
|
|
publish: ${{ steps.release.outputs.publish }}
|
|
prerelease: ${{ steps.release.outputs.prerelease }}
|
|
steps:
|
|
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
|
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
|
|
with:
|
|
python-version: '3.12'
|
|
- name: Validate release contracts
|
|
run: bash scripts/tests/run-release-tests.sh
|
|
- name: Resolve release metadata
|
|
id: release
|
|
run: python3 scripts/release/metadata.py --github-output "$GITHUB_OUTPUT"
|
|
|
|
macos:
|
|
needs: metadata
|
|
runs-on: macos-15
|
|
env:
|
|
MACOSX_DEPLOYMENT_TARGET: '11.0'
|
|
steps:
|
|
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
|
- name: Verify signing identity before compiling
|
|
if: github.event_name != 'pull_request' && github.repository == 'ZASENJC/ttree'
|
|
env:
|
|
MACOS_COMMUNITY_CERTIFICATE: ${{ secrets.MACOS_COMMUNITY_CERTIFICATE }}
|
|
MACOS_COMMUNITY_CERTIFICATE_PASSWORD: ${{ secrets.MACOS_COMMUNITY_CERTIFICATE_PASSWORD }}
|
|
run: scripts/macos/preflight.sh
|
|
- uses: dtolnay/rust-toolchain@4be7066ada62dd38de10e7b70166bc74ed198c30 # stable
|
|
with:
|
|
targets: aarch64-apple-darwin,x86_64-apple-darwin
|
|
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
|
|
with:
|
|
python-version: '3.12'
|
|
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
|
with:
|
|
node-version: '22'
|
|
- name: Prepare Metal compiler
|
|
run: xcrun -f metal >/dev/null 2>&1 || xcodebuild -downloadComponent MetalToolchain
|
|
- uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
|
|
id: cargo-cache
|
|
with:
|
|
path: |
|
|
~/.cargo/registry
|
|
~/.cargo/git
|
|
target
|
|
key: macos-universal-${{ hashFiles('Cargo.lock', 'Cargo.toml', 'apps/**/Cargo.toml') }}
|
|
restore-keys: macos-universal-
|
|
- name: Check and test shared libraries and native apps
|
|
run: |
|
|
cargo check --workspace --locked
|
|
cargo test --workspace --locked
|
|
- name: Build universal app without signing material
|
|
id: build
|
|
run: scripts/macos/package.sh universal-apple-darwin "$GITHUB_RUN_NUMBER" --build-only
|
|
- name: Sign and verify distributable macOS assets
|
|
if: github.event_name != 'pull_request' && github.repository == 'ZASENJC/ttree'
|
|
env:
|
|
MACOS_COMMUNITY_CERTIFICATE: ${{ secrets.MACOS_COMMUNITY_CERTIFICATE }}
|
|
MACOS_COMMUNITY_CERTIFICATE_PASSWORD: ${{ secrets.MACOS_COMMUNITY_CERTIFICATE_PASSWORD }}
|
|
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
|
|
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
|
|
RELEASE_TAG: ${{ needs.metadata.outputs.release_tag }}
|
|
APP_VERSION: ${{ needs.metadata.outputs.app_version }}
|
|
run: |
|
|
brew list minisign >/dev/null 2>&1 || brew install minisign
|
|
scripts/macos/package.sh universal-apple-darwin "$GITHUB_RUN_NUMBER" --package-only
|
|
scripts/release/generate-manifest.sh dist/macos "$RELEASE_TAG" "$GITHUB_REPOSITORY"
|
|
scripts/release/verify-macos-assets.sh dist/macos "$RELEASE_TAG" "$GITHUB_REPOSITORY" "$APP_VERSION"
|
|
python3 scripts/release/checksums.py dist/macos --write macos.sha256
|
|
- name: Upload signed macOS assets
|
|
if: github.event_name != 'pull_request' && github.repository == 'ZASENJC/ttree'
|
|
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
|
with:
|
|
name: macos-${{ github.run_id }}-${{ github.run_attempt }}
|
|
path: dist/macos/
|
|
if-no-files-found: error
|
|
retention-days: 7
|
|
compression-level: 0
|
|
|
|
- name: Preserve compiled Mac dependencies after packaging failures
|
|
if: always() && steps.build.outcome == 'success' && steps.cargo-cache.outputs.cache-hit != 'true'
|
|
uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
|
|
with:
|
|
path: |
|
|
~/.cargo/registry
|
|
~/.cargo/git
|
|
target
|
|
key: ${{ steps.cargo-cache.outputs.cache-primary-key }}
|
|
|
|
windows:
|
|
needs: metadata
|
|
runs-on: windows-2022
|
|
steps:
|
|
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
|
- uses: dtolnay/rust-toolchain@4be7066ada62dd38de10e7b70166bc74ed198c30 # stable
|
|
with:
|
|
targets: x86_64-pc-windows-msvc
|
|
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
|
|
with:
|
|
python-version: '3.12'
|
|
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
|
with:
|
|
node-version: '22'
|
|
- uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
|
|
with:
|
|
path: |
|
|
~/.cargo/registry
|
|
~/.cargo/git
|
|
target
|
|
key: windows-x64-${{ hashFiles('Cargo.lock', 'Cargo.toml', 'apps/**/Cargo.toml') }}
|
|
restore-keys: windows-x64-
|
|
- name: Check and test shared libraries and native apps
|
|
run: |
|
|
cargo check --workspace --locked
|
|
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
|
|
cargo test --workspace --locked
|
|
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
|
|
- name: Build opt-in updater verification executable without signing material
|
|
if: github.event_name != 'pull_request' && github.repository == 'ZASENJC/ttree'
|
|
run: |
|
|
cargo build --locked --release -p ttree-windows --features updater-smoke --target x86_64-pc-windows-msvc
|
|
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
|
|
New-Item -ItemType Directory -Force target/updater-probe | Out-Null
|
|
Copy-Item target/x86_64-pc-windows-msvc/release/ttree-windows.exe target/updater-probe/TTREE.exe
|
|
- name: Build and validate portable ZIP
|
|
run: ./scripts/windows/package.ps1
|
|
- name: Launch packaged Windows app
|
|
run: ./scripts/windows/smoke.ps1 -Exe target/package/windows/TTREE/TTREE.exe -Output target/windows-smoke
|
|
- name: Sign local upgrade fixture after compilation
|
|
if: github.event_name != 'pull_request' && github.repository == 'ZASENJC/ttree'
|
|
env:
|
|
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
|
|
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
|
|
run: |
|
|
bash scripts/release/validate-secrets.sh updater
|
|
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
|
|
New-Item -ItemType Directory -Force target/updater-source | Out-Null
|
|
Copy-Item dist/windows/*.zip target/updater-source/
|
|
python scripts/release/checksums.py target/updater-source --write SHA256SUMS
|
|
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
|
|
$env:TAURI_PRIVATE_KEY = $env:TAURI_SIGNING_PRIVATE_KEY
|
|
$env:TAURI_PRIVATE_KEY_PASSWORD = $env:TAURI_SIGNING_PRIVATE_KEY_PASSWORD
|
|
Copy-Item target/updater-source/SHA256SUMS target/updater-checksums.txt
|
|
npx --yes --package @tauri-apps/cli@2.8.4 tauri signer sign target/updater-checksums.txt | Out-Null
|
|
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
|
|
Copy-Item target/updater-checksums.txt.sig target/updater-source/SHA256SUMS.sig
|
|
Remove-Item target/updater-checksums.txt, target/updater-checksums.txt.sig
|
|
- name: Verify real Windows upgrade and restart
|
|
if: github.event_name != 'pull_request' && github.repository == 'ZASENJC/ttree'
|
|
run: ./scripts/windows/upgrade-smoke.ps1 -ProbeExe target/updater-probe/TTREE.exe -ReleaseDirectory target/updater-source -ExpectedExe target/package/windows/TTREE/TTREE.exe -Version '${{ needs.metadata.outputs.app_version }}' -Output target/windows-smoke
|
|
- name: Record Windows checksums
|
|
run: python scripts/release/checksums.py dist/windows --write windows.sha256
|
|
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
|
with:
|
|
name: windows-${{ github.run_id }}-${{ github.run_attempt }}
|
|
path: dist/windows/
|
|
if-no-files-found: error
|
|
retention-days: 7
|
|
compression-level: 0
|
|
- name: Upload Windows smoke evidence
|
|
if: always()
|
|
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
|
with:
|
|
name: windows-smoke-${{ github.run_id }}-${{ github.run_attempt }}
|
|
path: target/windows-smoke/
|
|
if-no-files-found: warn
|
|
retention-days: 7
|
|
|
|
publish:
|
|
needs: [metadata, macos, windows]
|
|
if: needs.metadata.outputs.publish == 'true' && github.repository == 'ZASENJC/ttree'
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
contents: write
|
|
env:
|
|
APP_VERSION: ${{ needs.metadata.outputs.app_version }}
|
|
RELEASE_TAG: ${{ needs.metadata.outputs.release_tag }}
|
|
PRERELEASE: ${{ needs.metadata.outputs.prerelease }}
|
|
GH_TOKEN: ${{ github.token }}
|
|
steps:
|
|
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
|
with:
|
|
fetch-depth: 0
|
|
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
|
|
with:
|
|
python-version: '3.12'
|
|
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
|
with:
|
|
node-version: '22'
|
|
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
|
|
with:
|
|
name: macos-${{ github.run_id }}-${{ github.run_attempt }}
|
|
path: dist/release
|
|
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
|
|
with:
|
|
name: windows-${{ github.run_id }}-${{ github.run_attempt }}
|
|
path: dist/release
|
|
- name: Verify transferred assets and updater signature
|
|
env:
|
|
VERIFY_MACOS_CONTAINERS: '0'
|
|
run: |
|
|
sudo apt-get update -qq
|
|
sudo apt-get install -y minisign
|
|
python3 scripts/release/checksums.py dist/release --check macos.sha256 --check windows.sha256
|
|
scripts/release/verify-macos-assets.sh dist/release "$RELEASE_TAG" "$GITHUB_REPOSITORY" "$APP_VERSION"
|
|
python3 scripts/release/verify-assets.py dist/release "$APP_VERSION"
|
|
rm dist/release/macos.sha256 dist/release/windows.sha256
|
|
python3 scripts/release/checksums.py dist/release --write SHA256SUMS
|
|
- name: Sign cross-platform update checksums
|
|
env:
|
|
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
|
|
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
|
|
run: scripts/release/sign-checksums.sh dist/release
|
|
- name: Generate release notes and publish verified draft
|
|
run: scripts/release/publish.sh
|