Repository navigation
Release #15
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: Release | |
| on: | |
| workflow_dispatch: | |
| concurrency: | |
| group: release | |
| jobs: | |
| gates: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| version: ${{ steps.version.outputs.version }} | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - uses: pnpm/action-setup@v6 | |
| - uses: actions/setup-node@v7 | |
| with: | |
| node-version: 24 | |
| cache: pnpm | |
| - run: pnpm install --frozen-lockfile | |
| - uses: swatinem/rust-cache@v2 | |
| with: | |
| workspaces: './src-tauri -> target' | |
| - run: pnpm licenses:check | |
| - run: pnpm attribution:check | |
| - run: pnpm coverage:check | |
| - run: pnpm lint | |
| - run: pnpm test | |
| # Regenerate before `pnpm build` so the Vite plugin ships the freshly | |
| # validated .md into dist/; the diff fails the build on any drift. | |
| - name: rust attribution freshness | |
| run: | | |
| curl -fsSL https://github.com/EmbarkStudios/cargo-about/releases/download/0.9.1/cargo-about-0.9.1-x86_64-unknown-linux-musl.tar.gz \ | |
| | tar xz --strip-components=1 -C /tmp | |
| cd src-tauri | |
| cargo fetch | |
| /tmp/cargo-about generate about.hbs -o THIRD-PARTY-LICENSES-RUST.md | |
| git diff --exit-code -- THIRD-PARTY-LICENSES-RUST.md | |
| - run: pnpm build | |
| - uses: EmbarkStudios/cargo-deny-action@v2 | |
| with: | |
| command: check licenses advisories | |
| manifest-path: ./src-tauri/Cargo.toml | |
| - id: version | |
| run: echo "version=$(node -p "require('./package.json').version")" >> "$GITHUB_OUTPUT" | |
| - name: stage web dist for the release zip | |
| run: cp .github/release/web-README.md dist/README.md | |
| - uses: actions/upload-artifact@v7 | |
| with: | |
| name: web-dist | |
| path: dist | |
| # Single creation point: tauri-action's own tag lookup races across matrix | |
| # legs and can split assets over duplicate drafts (tauri-action#914). | |
| create-release: | |
| needs: gates | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| outputs: | |
| release_id: ${{ steps.create.outputs.release_id }} | |
| steps: | |
| - id: create | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| TAG="v${{ needs.gates.outputs.version }}" | |
| # Keep head off the gh pipe: piping into head masks a failed lookup | |
| # (rate limit / 5xx) as "no draft" and would POST a duplicate. | |
| DRAFTS=$(gh api "repos/$GITHUB_REPOSITORY/releases" --paginate \ | |
| --jq ".[] | select(.tag_name==\"$TAG\" and .draft) | .id") | |
| ID=$(printf '%s\n' "$DRAFTS" | head -n1) | |
| if [ -z "$ID" ]; then | |
| # prerelease default: 0.x must not become "latest" by a publish | |
| # click alone (the updater endpoint serves releases/latest). | |
| ID=$(gh api -X POST "repos/$GITHUB_REPOSITORY/releases" \ | |
| -f tag_name="$TAG" \ | |
| -f name="ZPLab $TAG" \ | |
| -f body="See the assets to download this version and install." \ | |
| -F draft=true -F prerelease=true --jq .id) | |
| fi | |
| echo "release_id=$ID" >> "$GITHUB_OUTPUT" | |
| publish-tauri: | |
| needs: create-release | |
| permissions: | |
| contents: write | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - platform: macos-latest # Arm (M1+) | |
| args: '--target aarch64-apple-darwin' | |
| - platform: macos-latest # Intel, cross-compiled on the arm64 runner | |
| args: '--target x86_64-apple-darwin' | |
| # Oldest LTS with webkit2gtk-4.1, standard support until April 2027. glibc is forward compatible | |
| # only, so a newer runner drops Debian 12 and Ubuntu 22.04. Moving the runner is a release decision. | |
| - platform: ubuntu-22.04 | |
| args: '' | |
| - platform: windows-latest | |
| args: '' | |
| runs-on: ${{ matrix.platform }} | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - name: install dependencies (ubuntu only) | |
| if: startsWith(matrix.platform, 'ubuntu') | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf xdg-utils libcups2-dev libdbus-1-dev | |
| - uses: pnpm/action-setup@v6 | |
| - uses: actions/setup-node@v7 | |
| with: | |
| node-version: 24 | |
| cache: pnpm | |
| - uses: dtolnay/rust-toolchain@stable | |
| with: | |
| targets: ${{ matrix.platform == 'macos-latest' && 'aarch64-apple-darwin,x86_64-apple-darwin' || '' }} | |
| - uses: swatinem/rust-cache@v2 | |
| with: | |
| workspaces: './src-tauri -> target' | |
| - run: pnpm install --frozen-lockfile | |
| # The SEA sidecar clones a node binary; the arm64 runner cross-builds | |
| # x86_64, so that leg needs a target-arch node of the exact same version | |
| # (the build script rejects a skew). | |
| - name: fetch x86_64 node for the SEA sidecar | |
| if: matrix.args == '--target x86_64-apple-darwin' | |
| run: | | |
| V=$(node --version) | |
| curl -fsSL "https://nodejs.org/dist/${V}/node-${V}-darwin-x64.tar.gz" | tar xz -C "$RUNNER_TEMP" | |
| echo "ZPLAB_SEA_NODE=$RUNNER_TEMP/node-${V}-darwin-x64/bin/node" >> "$GITHUB_ENV" | |
| - uses: tauri-apps/tauri-action@v1 | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} | |
| TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }} | |
| with: | |
| releaseId: ${{ needs.create-release.outputs.release_id }} | |
| updaterJsonPreferNsis: true | |
| args: ${{ matrix.args }} | |
| - name: glibc floor | |
| if: startsWith(matrix.platform, 'ubuntu') | |
| run: | | |
| # deb and rpm link the system glibc, so the floor is what RHEL 9 ships. | |
| # The AppImage bundles the runner's libraries, so the guard does not lower its 2.35. | |
| FLOOR=GLIBC_2.34 | |
| BIN="src-tauri/target/release/$(jq -r .mainBinaryName src-tauri/tauri.conf.json)" | |
| MAX=$(objdump -T "$BIN" | grep -o 'GLIBC_[0-9.]*' | sort -Vu | tail -1) | |
| echo "$BIN requires ${MAX:?no glibc symbols found}, floor $FLOOR" | |
| [ "$(printf '%s\n%s\n' "$MAX" "$FLOOR" | sort -V | tail -1)" = "$FLOOR" ] || { echo "$MAX is newer than the floor $FLOOR"; exit 1; } | |
| msix: | |
| needs: gates | |
| uses: ./.github/workflows/msix.yml | |
| upload-web-dist: | |
| needs: [gates, create-release] | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| steps: | |
| - uses: actions/download-artifact@v8 | |
| with: | |
| name: web-dist | |
| path: dist | |
| - name: zip browser build | |
| run: | | |
| cd dist | |
| zip -r "../ZPLab_${{ needs.gates.outputs.version }}_web.zip" . | |
| - name: upload to draft release | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| GH_REPO: ${{ github.repository }} | |
| # gh resolves the tag to the draft release even though the git ref | |
| # does not exist until the release is published | |
| run: gh release upload "v${{ needs.gates.outputs.version }}" "ZPLab_${{ needs.gates.outputs.version }}_web.zip" --clobber |