Files
claude-code-usage-bubble/.github/workflows/release-legacy.yml
T
tiennm99 1afb0f6981 ci: keep checkout tokens off disk in release builds and patch the legacy lockfile instead of re-resolving it
The release build jobs run npm install scripts, so their checkouts no longer persist the token in .git/config. The legacy rollback sets the new version on the package's own Cargo.lock entry instead of running cargo update, so the --locked build resolves nothing and fails if the lockfile differs in anything else.
2026-10-21 19:02:49 +07:00

172 lines
5.9 KiB
YAML

name: Release legacy
# Rollback for a broken Tauri release: rebuild the Win32 sources at `ref`
# under a higher version and publish them as a Windows-only release. Legacy
# clients take the exe through the GitHub API, Tauri Windows clients through
# the signed `latest.json`, and Tauri Linux clients find no entry for their
# platform, which they report as up to date. The Win32 app accepts the
# `--wait-pid <pid> --updated-to X` relaunch the Tauri updater uses.
#
# The build job holds a read-only token that is never written to disk, and
# only the steps that check or use the updater signing key see it. The write
# token lives in the publish job, which builds nothing.
on:
workflow_dispatch:
inputs:
ref:
description: 'Git ref holding the Win32 sources (e.g. v0.5.0)'
required: true
version:
description: 'Version to publish as X.Y.Z, higher than every release in the field'
required: true
tag:
description: 'Release tag, v<version>'
required: true
draft:
description: 'Publish as a draft'
type: boolean
default: true
permissions:
contents: read
jobs:
win-x64:
name: Windows x64 (legacy)
runs-on: windows-latest
outputs:
sha: ${{ steps.sha.outputs.sha }}
env:
VERSION: ${{ inputs.version }}
TAG: ${{ inputs.tag }}
defaults:
run:
shell: bash
steps:
- name: Check the inputs and the signing key
env:
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
run: |
if ! [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "::error::version '$VERSION' is not X.Y.Z."
exit 1
fi
if [ "$TAG" != "v$VERSION" ]; then
echo "::error::tag '$TAG' must be v$VERSION."
exit 1
fi
if [ -z "${TAURI_SIGNING_PRIVATE_KEY//[[:space:]]/}" ]; then
echo "::error::The TAURI_SIGNING_PRIVATE_KEY secret is empty; an unsigned build cannot be released."
exit 1
fi
- uses: actions/checkout@v7
with:
ref: ${{ inputs.ref }}
persist-credentials: false
# The legacy ref predates package.json and the release script, so take
# both from the default branch.
- uses: actions/checkout@v7
with:
ref: ${{ github.event.repository.default_branch }}
path: current
persist-credentials: false
- name: Record the commit the release points at
id: sha
run: echo "sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT"
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- uses: actions/setup-node@v7
with:
node-version: lts/*
cache: npm
cache-dependency-path: current/package-lock.json
# The Tauri CLI that signs the exe comes from the reviewed lockfile,
# not from a version resolved at run time.
- run: npm ci --prefix current
# Only the package's own version changes, in Cargo.toml and its
# Cargo.lock entry, so the `--locked` build below resolves nothing and
# fails if the lockfile differs in anything else.
- name: Set the Cargo.toml and Cargo.lock version
run: |
sed -i -E '0,/^version[[:space:]]*=/s/^version[[:space:]]*=[[:space:]]*"[^"]*"/version = "'"$VERSION"'"/' Cargo.toml
actual=$(sed -nE 's/^version[[:space:]]*=[[:space:]]*"([^"]+)".*/\1/p' Cargo.toml | head -n 1)
if [ "$actual" != "$VERSION" ]; then
echo "::error::Cargo.toml version is '$actual' after patching, expected '$VERSION'."
exit 1
fi
sed -i -E '/^name = "claude-code-usage-bubble"$/{n;s/^version = "[^"]*"$/version = "'"$VERSION"'"/}' Cargo.lock
if ! grep -A1 -x 'name = "claude-code-usage-bubble"' Cargo.lock | grep -qx "version = \"$VERSION\""; then
echo "::error::Cargo.lock has no claude-code-usage-bubble entry at version '$VERSION' after patching."
exit 1
fi
- run: cargo build --release --locked
# `--no` refuses to download a CLI that the lockfile did not install.
- name: Sign the exe
env:
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
run: |
exe=target/release/claude-code-usage-bubble.exe
npm exec --prefix current --no -- tauri signer sign --app-version "$VERSION" "$exe"
test -s "$exe.sig"
- uses: actions/upload-artifact@v7
with:
name: release-legacy-win-x64
path: |
target/release/claude-code-usage-bubble.exe
target/release/claude-code-usage-bubble.exe.sig
retention-days: 7
if-no-files-found: error
publish:
name: Publish
needs: win-x64
runs-on: ubuntu-latest
permissions:
contents: write
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAG: ${{ inputs.tag }}
TARGET: ${{ needs.win-x64.outputs.sha }}
steps:
- uses: actions/checkout@v7
with:
ref: ${{ github.event.repository.default_branch }}
persist-credentials: false
- uses: actions/setup-node@v7
with:
node-version: lts/*
- uses: actions/download-artifact@v8
with:
name: release-legacy-win-x64
path: dist
- name: Write the Windows-only latest.json and check the asset set
run: node scripts/make-latest-json.js --windows-only "$TAG" dist
- name: Create the release
env:
DRAFT: ${{ inputs.draft }}
run: |
if [ "$DRAFT" = true ]; then
mode=(--draft)
else
mode=(--latest)
fi
gh release create "$TAG" dist/* --repo "$GITHUB_REPOSITORY" --target "$TARGET" \
--title "$TAG" --generate-notes "${mode[@]}"