Skip to content

docs(release): add bilingual v1.7.0 release note template #17

docs(release): add bilingual v1.7.0 release note template

docs(release): add bilingual v1.7.0 release note template #17

name: Release Desktop Multi-OS
on:
push:
tags:
- "v*"
workflow_dispatch:
inputs:
tag:
description: "Tag to build and upload (for example: v1.6.1)"
required: true
type: string
source_ref:
description: "Optional build source ref (branch/commit/tag). Defaults to the release tag when omitted."
required: false
type: string
permissions:
contents: write
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true"
jobs:
ensure-release:
name: Ensure GitHub Release Exists
runs-on: ubuntu-latest
outputs:
tag_name: ${{ steps.tag.outputs.tag_name }}
steps:
- name: Checkout repository
uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Resolve tag name
id: tag
shell: bash
run: |
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
TAG_NAME="${{ github.event.inputs.tag }}"
else
TAG_NAME="${GITHUB_REF#refs/tags/}"
fi
if [ -z "$TAG_NAME" ]; then
echo "::error::Unable to resolve release tag."
exit 1
fi
echo "tag_name=$TAG_NAME" >> "$GITHUB_OUTPUT"
echo "Resolved tag: $TAG_NAME"
- name: Ensure release record exists
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
shell: bash
run: |
TAG_NAME="${{ steps.tag.outputs.tag_name }}"
if gh release view "$TAG_NAME" >/dev/null 2>&1; then
echo "Release already exists for $TAG_NAME."
else
gh release create "$TAG_NAME" --title "$TAG_NAME" --notes "Automated desktop multi-OS release assets."
fi
build-and-upload:
name: Build and Upload (${{ matrix.platform_label }})
needs: ensure-release
runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false
matrix:
include:
- runner: windows-latest
platform_label: windows
files: |
src-tauri/target/release/bundle/**/*.exe
src-tauri/target/release/bundle/**/*.msi
- runner: ubuntu-latest
platform_label: linux
files: |
src-tauri/target/release/bundle/**/*.AppImage
src-tauri/target/release/bundle/**/*.deb
- runner: macos-latest
platform_label: macos
files: |
src-tauri/target/release/bundle/**/*.dmg
steps:
- name: Checkout repository
uses: actions/checkout@v5
with:
ref: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.source_ref != '' && github.event.inputs.source_ref || github.event_name == 'workflow_dispatch' && github.event.inputs.tag || github.ref }}
fetch-depth: 0
lfs: false
- name: Setup Node.js
uses: actions/setup-node@v5
with:
node-version: "20"
cache: "npm"
- name: Setup Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Install Linux native dependencies
if: runner.os == 'Linux'
shell: bash
run: |
set -euo pipefail
sudo apt-get update
if apt-cache show libwebkit2gtk-4.1-dev >/dev/null 2>&1; then
WEBKIT_PKG="libwebkit2gtk-4.1-dev"
else
WEBKIT_PKG="libwebkit2gtk-4.0-dev"
fi
if apt-cache show libayatana-appindicator3-dev >/dev/null 2>&1; then
APPINDICATOR_PKG="libayatana-appindicator3-dev"
else
APPINDICATOR_PKG="libappindicator3-dev"
fi
sudo apt-get install -y \
"${WEBKIT_PKG}" \
libgtk-3-dev \
librsvg2-dev \
patchelf \
"${APPINDICATOR_PKG}"
echo "Installed Linux native dependencies with ${WEBKIT_PKG} and ${APPINDICATOR_PKG}."
- name: Install dependencies
run: npm ci
- name: Prepare Godot sidecar binary (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: |
$ErrorActionPreference = "Stop"
New-Item -ItemType Directory -Path "build\godot" -Force | Out-Null
$archive = "build\godot\godot-win64.zip"
Invoke-WebRequest -Uri "https://github.com/godotengine/godot/releases/download/4.3-stable/Godot_v4.3-stable_win64.exe.zip" -OutFile $archive
Expand-Archive -Path $archive -DestinationPath "build\godot\extract" -Force
$godotExe = Get-ChildItem -Path "build\godot\extract" -Filter "Godot_v4.3-stable_win64.exe" -Recurse | Select-Object -First 1
if (-not $godotExe) {
$godotExe = Get-ChildItem -Path "build\godot\extract" -Filter "*.exe" -Recurse | Where-Object { $_.Name -notmatch "_console\.exe$" } | Sort-Object Length -Descending | Select-Object -First 1
}
if (-not $godotExe) {
throw "Failed to locate extracted Godot Windows executable."
}
if ($godotExe.Length -lt 1048576) {
throw "Resolved Godot executable is too small ($($godotExe.Length) bytes): $($godotExe.FullName)"
}
Copy-Item -Path $godotExe.FullName -Destination "src-tauri\bin\godot-x86_64-pc-windows-msvc.exe" -Force
- name: Prepare Godot sidecar binary (Linux)
if: runner.os == 'Linux'
shell: bash
run: |
set -euo pipefail
mkdir -p build/godot
curl -fsSL "https://github.com/godotengine/godot/releases/download/4.3-stable/Godot_v4.3-stable_linux.x86_64.zip" -o build/godot/godot-linux.zip
unzip -q -o build/godot/godot-linux.zip -d build/godot/extract
GODOT_BIN="$(find build/godot/extract -maxdepth 2 -type f -name 'Godot_v4.3-stable_linux.x86_64' | head -n 1)"
if [ -z "${GODOT_BIN}" ]; then
echo "Failed to locate extracted Godot Linux executable."
exit 1
fi
cp "${GODOT_BIN}" src-tauri/bin/godot-x86_64-unknown-linux-gnu
chmod +x src-tauri/bin/godot-x86_64-unknown-linux-gnu
- name: Prepare Godot sidecar binary (macOS)
if: runner.os == 'macOS'
shell: bash
run: |
set -euo pipefail
mkdir -p build/godot
curl -fsSL "https://github.com/godotengine/godot/releases/download/4.3-stable/Godot_v4.3-stable_macos.universal.zip" -o build/godot/godot-macos.zip
unzip -q -o build/godot/godot-macos.zip -d build/godot/extract
GODOT_BIN="$(find build/godot/extract -type f -path '*Godot.app/Contents/MacOS/Godot' | head -n 1)"
if [ -z "${GODOT_BIN}" ]; then
echo "Failed to locate extracted Godot macOS executable."
exit 1
fi
ARCH="$(uname -m)"
if [ "${ARCH}" = "arm64" ] || [ "${ARCH}" = "aarch64" ]; then
TARGET_BIN="src-tauri/bin/godot-aarch64-apple-darwin"
else
TARGET_BIN="src-tauri/bin/godot-x86_64-apple-darwin"
fi
cp "${GODOT_BIN}" "${TARGET_BIN}"
chmod +x "${TARGET_BIN}"
- name: Build desktop bundle
run: npm run tauri:build:mini
- name: Upload workflow artifacts
uses: actions/upload-artifact@v4
with:
name: release-${{ needs.ensure-release.outputs.tag_name }}-${{ matrix.platform_label }}
if-no-files-found: error
path: ${{ matrix.files }}
- name: Upload assets to GitHub release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ needs.ensure-release.outputs.tag_name }}
files: ${{ matrix.files }}
fail_on_unmatched_files: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
build-and-upload-android:
name: Build and Upload (android-apk)
needs: ensure-release
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v5
with:
ref: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.source_ref != '' && github.event.inputs.source_ref || github.event_name == 'workflow_dispatch' && github.event.inputs.tag || github.ref }}
fetch-depth: 0
lfs: false
- name: Setup Node.js
uses: actions/setup-node@v5
with:
node-version: "20"
cache: "npm"
- name: Setup Java 23.0.1
uses: actions/setup-java@v5
with:
distribution: temurin
java-version: "23.0.1"
- name: Setup Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Setup Android SDK
uses: android-actions/setup-android@v3
- name: Install Android SDK dependencies
shell: bash
run: |
set -euo pipefail
yes | sdkmanager --licenses >/dev/null 2>&1 || true
sdkmanager \
"platform-tools" \
"platforms;android-36" \
"ndk;27.2.12479018"
- name: Install dependencies
run: npm ci
- name: Build Android universal APK
shell: bash
run: |
set -euo pipefail
NOTE_CONNECTION_TAURI_ANDROID_TARGET=universal npm run tauri:android:build
- name: Upload workflow artifacts
uses: actions/upload-artifact@v4
with:
name: release-${{ needs.ensure-release.outputs.tag_name }}-android-apk
if-no-files-found: error
path: |
src-tauri/gen/android/app/build/outputs/apk/**/*.apk
- name: Upload APK assets to GitHub release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ needs.ensure-release.outputs.tag_name }}
files: |
src-tauri/gen/android/app/build/outputs/apk/**/*.apk
fail_on_unmatched_files: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}