e0a5f57793
Vendor the rebranded BoosAPI Desktop client (Tauri + Vue) into metapi as a monorepo subdirectory under desktop/. Source only — node_modules, dist, Cargo target and the upstream .git history are excluded. desktop/ keeps its own independent Cargo workspace (desktop/src-tauri with crates/*); it is not part of the backend boosapi crate, so a `cargo check` at the metapi root still compiles only the backend. Build the desktop app from desktop/src-tauri per desktop/README.md. Note: app icons are still placeholder assets pending the final BoosAPI logo. The updater signing keys live outside the repo and are not included.
375 lines
13 KiB
YAML
375 lines
13 KiB
YAML
name: Release
|
|
|
|
on:
|
|
push:
|
|
tags:
|
|
- 'v*.*.*'
|
|
|
|
permissions: write-all
|
|
|
|
env:
|
|
CARGO_INCREMENTAL: 0
|
|
RUST_BACKTRACE: short
|
|
|
|
concurrency:
|
|
group: '${{ github.workflow }}-${{ github.ref }}'
|
|
cancel-in-progress: true
|
|
|
|
jobs:
|
|
# ── Validate tag matches package.json version ──────────
|
|
check-version:
|
|
name: Check Version
|
|
if: ${{ !contains(github.ref_name, '-test') }}
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Validate tag vs package.json
|
|
run: |
|
|
TAG="${GITHUB_REF_NAME}"
|
|
PKG_VERSION="v$(jq -r .version package.json)"
|
|
if [[ "$TAG" != "$PKG_VERSION" ]]; then
|
|
echo "❌ Tag $TAG does not match package.json $PKG_VERSION"
|
|
exit 1
|
|
fi
|
|
echo "✅ Version $TAG is consistent"
|
|
|
|
# ── Generate release notes via git-cliff ─────────────
|
|
draft-release-notes:
|
|
name: Generate Release Notes
|
|
needs: [check-version]
|
|
if: ${{ !contains(github.ref_name, '-test') }}
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
contents: write
|
|
outputs:
|
|
body: ${{ steps.cliff.outputs.content }}
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
- name: Generate changelog
|
|
uses: orhun/git-cliff-action@v4
|
|
id: cliff
|
|
with:
|
|
config: cliff.toml
|
|
args: --latest --strip header
|
|
env:
|
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
GITHUB_REPO: ${{ github.repository }}
|
|
CLIFF_REPO: ${{ github.repository }}
|
|
|
|
- name: Create draft release
|
|
uses: softprops/action-gh-release@v2
|
|
with:
|
|
tag_name: ${{ github.ref_name }}
|
|
name: 'BoosApi ${{ github.ref_name }}'
|
|
body: ${{ steps.cliff.outputs.content }}
|
|
draft: true
|
|
prerelease: ${{ contains(github.ref_name, '-rc') }}
|
|
token: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
# ── Build for macOS / Windows / Linux x86_64 ───────────
|
|
release:
|
|
name: Build (${{ matrix.target }})
|
|
needs: [check-version, draft-release-notes]
|
|
if: ${{ !contains(github.ref_name, '-test') }}
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
# macOS
|
|
- os: macos-latest
|
|
target: aarch64-apple-darwin
|
|
- os: macos-latest
|
|
target: x86_64-apple-darwin
|
|
# Windows
|
|
- os: windows-latest
|
|
target: x86_64-pc-windows-msvc
|
|
- os: windows-latest
|
|
target: aarch64-pc-windows-msvc
|
|
# Linux x86_64
|
|
- os: ubuntu-22.04
|
|
target: x86_64-unknown-linux-gnu
|
|
|
|
runs-on: ${{ matrix.os }}
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
submodules: recursive
|
|
|
|
- name: Install Rust
|
|
uses: dtolnay/rust-toolchain@stable
|
|
with:
|
|
targets: ${{ matrix.target }}
|
|
|
|
- name: Rust cache
|
|
uses: Swatinem/rust-cache@v2
|
|
with:
|
|
prefix-key: 'v1'
|
|
key: '${{ matrix.os }}-${{ matrix.target }}'
|
|
workspaces: src-tauri -> target
|
|
|
|
- name: Install Linux dependencies
|
|
if: matrix.os == 'ubuntu-22.04'
|
|
run: |
|
|
sudo apt-get update
|
|
sudo apt-get install -y \
|
|
libwebkit2gtk-4.1-dev \
|
|
libayatana-appindicator3-dev \
|
|
librsvg2-dev \
|
|
patchelf
|
|
|
|
- name: Install x86_64 OpenSSL (macOS Intel cross-compile)
|
|
if: matrix.target == 'x86_64-apple-darwin'
|
|
run: |
|
|
arch -x86_64 brew install openssl@3
|
|
echo "OPENSSL_DIR=$(arch -x86_64 brew --prefix openssl@3)" >> $GITHUB_ENV
|
|
echo "OPENSSL_INCLUDE_DIR=$(arch -x86_64 brew --prefix openssl@3)/include" >> $GITHUB_ENV
|
|
echo "OPENSSL_LIB_DIR=$(arch -x86_64 brew --prefix openssl@3)/lib" >> $GITHUB_ENV
|
|
|
|
- name: Install Protoc
|
|
uses: arduino/setup-protoc@v3
|
|
with:
|
|
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
- uses: actions/setup-node@v4
|
|
with:
|
|
node-version: '20'
|
|
|
|
- uses: pnpm/action-setup@v4
|
|
with:
|
|
run_install: false
|
|
|
|
- name: Get linked dependency versions
|
|
id: dep-versions
|
|
shell: bash
|
|
run: |
|
|
SM_SHA=$(git -C libs/stream-monaco rev-parse HEAD)
|
|
MS_SHA=$(git -C libs/markstream-vue rev-parse HEAD)
|
|
echo "cache-key=${{ runner.os }}-${{ matrix.target }}-linked-deps-${SM_SHA:0:12}-${MS_SHA:0:12}" >> $GITHUB_OUTPUT
|
|
|
|
- name: Cache linked dependencies
|
|
id: cache-linked-deps
|
|
uses: actions/cache@v4
|
|
with:
|
|
path: |
|
|
libs/stream-monaco/node_modules
|
|
libs/stream-monaco/dist
|
|
libs/markstream-vue/node_modules
|
|
libs/markstream-vue/packages/markdown-parser/node_modules
|
|
libs/markstream-vue/packages/markdown-parser/dist
|
|
libs/markstream-vue/packages/markstream-react/node_modules
|
|
libs/markstream-vue/packages/markstream-react/dist
|
|
key: ${{ steps.dep-versions.outputs.cache-key }}
|
|
|
|
- name: Build linked dependencies
|
|
if: steps.cache-linked-deps.outputs.cache-hit != 'true'
|
|
shell: bash
|
|
run: |
|
|
pnpm --dir libs/stream-monaco install --frozen-lockfile
|
|
pnpm --dir libs/stream-monaco build
|
|
|
|
pnpm --dir libs/markstream-vue install --frozen-lockfile
|
|
pnpm --dir libs/markstream-vue run build:parser
|
|
pnpm --dir libs/markstream-vue/packages/markstream-react build
|
|
|
|
- name: Install frontend dependencies
|
|
run: pnpm install --frozen-lockfile
|
|
|
|
- name: Build with Tauri
|
|
uses: tauri-apps/tauri-action@v0
|
|
env:
|
|
NODE_OPTIONS: '--max_old_space_size=4096'
|
|
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 }}
|
|
APPLE_SIGNING_IDENTITY: ${{ matrix.os == 'macos-latest' && '-' || '' }}
|
|
with:
|
|
tagName: ${{ github.ref_name }}
|
|
releaseName: 'BoosApi ${{ github.ref_name }}'
|
|
releaseBody: ${{ needs.draft-release-notes.outputs.body }}
|
|
releaseDraft: true
|
|
prerelease: ${{ contains(github.ref_name, '-rc') }}
|
|
tauriScript: pnpm tauri
|
|
args: --target ${{ matrix.target }}
|
|
includeUpdaterJson: true
|
|
|
|
- name: Package Windows portable (zip)
|
|
if: contains(matrix.target, 'windows')
|
|
shell: pwsh
|
|
run: |
|
|
$exe = "src-tauri/target/${{ matrix.target }}/release/BoosApi.exe"
|
|
$arch = if ("${{ matrix.target }}" -match "aarch64") { "arm64" } else { "x64" }
|
|
$zipName = "BoosApi_${{ github.ref_name }}_windows-${arch}-portable.zip"
|
|
Compress-Archive -Path $exe -DestinationPath $zipName
|
|
|
|
- name: Upload Windows portable to release
|
|
if: contains(matrix.target, 'windows')
|
|
uses: softprops/action-gh-release@v2
|
|
with:
|
|
tag_name: ${{ github.ref_name }}
|
|
draft: true
|
|
token: ${{ secrets.GITHUB_TOKEN }}
|
|
files: BoosApi_${{ github.ref_name }}_windows-*-portable.zip
|
|
|
|
# ── Build for Linux ARM64 (cross-compile) ──────────────
|
|
release-linux-arm:
|
|
name: Build (aarch64-unknown-linux-gnu)
|
|
needs: [check-version, draft-release-notes]
|
|
if: ${{ !contains(github.ref_name, '-test') }}
|
|
runs-on: ubuntu-22.04
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
submodules: recursive
|
|
|
|
- name: Install Rust
|
|
uses: dtolnay/rust-toolchain@stable
|
|
with:
|
|
targets: aarch64-unknown-linux-gnu
|
|
|
|
- name: Rust cache
|
|
uses: Swatinem/rust-cache@v2
|
|
with:
|
|
prefix-key: 'v1'
|
|
key: 'ubuntu-22.04-aarch64-unknown-linux-gnu'
|
|
workspaces: src-tauri -> target
|
|
|
|
- name: Setup cross-compilation sources
|
|
run: |
|
|
cat > /tmp/sources.list << 'EOF'
|
|
deb [arch=amd64,i386] http://archive.ubuntu.com/ubuntu jammy main multiverse universe restricted
|
|
deb [arch=amd64,i386] http://archive.ubuntu.com/ubuntu jammy-security main multiverse universe restricted
|
|
deb [arch=amd64,i386] http://archive.ubuntu.com/ubuntu jammy-updates main multiverse universe restricted
|
|
deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports jammy main multiverse universe restricted
|
|
deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports jammy-security main multiverse universe restricted
|
|
deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports jammy-updates main multiverse universe restricted
|
|
EOF
|
|
sudo mv /etc/apt/sources.list /etc/apt/sources.list.bak
|
|
sudo mv /tmp/sources.list /etc/apt/sources.list
|
|
sudo dpkg --add-architecture arm64
|
|
sudo apt-get update
|
|
|
|
- name: Install ARM64 dependencies
|
|
run: |
|
|
sudo apt-get install -y \
|
|
gcc-aarch64-linux-gnu \
|
|
g++-aarch64-linux-gnu \
|
|
libwebkit2gtk-4.1-dev:arm64 \
|
|
libayatana-appindicator3-dev:arm64 \
|
|
librsvg2-dev:arm64 \
|
|
libssl-dev:arm64 \
|
|
patchelf:arm64
|
|
|
|
- name: Install Protoc
|
|
uses: arduino/setup-protoc@v3
|
|
with:
|
|
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
- uses: actions/setup-node@v4
|
|
with:
|
|
node-version: '20'
|
|
|
|
- uses: pnpm/action-setup@v4
|
|
with:
|
|
run_install: false
|
|
|
|
- name: Get linked dependency versions
|
|
id: dep-versions
|
|
run: |
|
|
SM_SHA=$(git -C libs/stream-monaco rev-parse HEAD)
|
|
MS_SHA=$(git -C libs/markstream-vue rev-parse HEAD)
|
|
echo "cache-key=${{ runner.os }}-aarch64-unknown-linux-gnu-linked-deps-${SM_SHA:0:12}-${MS_SHA:0:12}" >> $GITHUB_OUTPUT
|
|
|
|
- name: Cache linked dependencies
|
|
id: cache-linked-deps
|
|
uses: actions/cache@v4
|
|
with:
|
|
path: |
|
|
libs/stream-monaco/node_modules
|
|
libs/stream-monaco/dist
|
|
libs/markstream-vue/node_modules
|
|
libs/markstream-vue/packages/markdown-parser/node_modules
|
|
libs/markstream-vue/packages/markdown-parser/dist
|
|
libs/markstream-vue/packages/markstream-react/node_modules
|
|
libs/markstream-vue/packages/markstream-react/dist
|
|
key: ${{ steps.dep-versions.outputs.cache-key }}
|
|
|
|
- name: Build linked dependencies
|
|
if: steps.cache-linked-deps.outputs.cache-hit != 'true'
|
|
run: |
|
|
pnpm --dir libs/stream-monaco install --frozen-lockfile
|
|
pnpm --dir libs/stream-monaco build
|
|
|
|
pnpm --dir libs/markstream-vue install --frozen-lockfile
|
|
pnpm --dir libs/markstream-vue run build:parser
|
|
pnpm --dir libs/markstream-vue/packages/markstream-react build
|
|
|
|
- name: Install frontend dependencies
|
|
run: pnpm install --frozen-lockfile
|
|
|
|
- name: Build for Linux ARM64
|
|
run: |
|
|
export PKG_CONFIG_ALLOW_CROSS=1
|
|
export PKG_CONFIG_PATH=/usr/lib/aarch64-linux-gnu/pkgconfig/:$PKG_CONFIG_PATH
|
|
export PKG_CONFIG_SYSROOT_DIR=/usr/aarch64-linux-gnu/
|
|
pnpm tauri build --target aarch64-unknown-linux-gnu --bundles deb,rpm
|
|
env:
|
|
NODE_OPTIONS: '--max_old_space_size=4096'
|
|
CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc
|
|
CC_aarch64_unknown_linux_gnu: aarch64-linux-gnu-gcc
|
|
CXX_aarch64_unknown_linux_gnu: aarch64-linux-gnu-g++
|
|
AR_aarch64_unknown_linux_gnu: aarch64-linux-gnu-ar
|
|
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
|
|
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
|
|
|
|
- name: Upload Linux ARM64 artifacts
|
|
uses: softprops/action-gh-release@v2
|
|
with:
|
|
tag_name: ${{ github.ref_name }}
|
|
name: 'BoosApi ${{ github.ref_name }}'
|
|
draft: true
|
|
prerelease: ${{ contains(github.ref_name, '-rc') }}
|
|
token: ${{ secrets.GITHUB_TOKEN }}
|
|
files: |
|
|
src-tauri/target/aarch64-unknown-linux-gnu/release/bundle/deb/*.deb
|
|
src-tauri/target/aarch64-unknown-linux-gnu/release/bundle/rpm/*.rpm
|
|
|
|
# ── Publish draft release as latest ────────────────────
|
|
publish-release:
|
|
name: Publish Release
|
|
needs: [release, release-linux-arm]
|
|
if: ${{ !contains(github.ref_name, '-test') }}
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
contents: write
|
|
steps:
|
|
- name: Publish draft release
|
|
uses: softprops/action-gh-release@v2
|
|
with:
|
|
tag_name: ${{ github.ref_name }}
|
|
draft: false
|
|
prerelease: ${{ contains(github.ref_name, '-rc') }}
|
|
make_latest: true
|
|
token: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
# ── Deploy website after release ────────────────────────
|
|
deploy-website:
|
|
name: Deploy Website
|
|
needs: [publish-release]
|
|
if: ${{ !contains(github.ref_name, '-test') }}
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Trigger website deployment
|
|
uses: actions/github-script@v7
|
|
with:
|
|
script: |
|
|
await github.rest.actions.createWorkflowDispatch({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
workflow_id: 'deploy-website.yml',
|
|
ref: 'main',
|
|
});
|