mirror of
https://github.com/qingjian-team/qingjian.git
synced 2026-11-06 08:13:51 +00:00
Bumps [Swatinem/rust-cache](https://github.com/swatinem/rust-cache) from 2.9.2 to 2.9.3. - [Release notes](https://github.com/swatinem/rust-cache/releases) - [Changelog](https://github.com/Swatinem/rust-cache/blob/master/CHANGELOG.md) - [Commits](https://github.com/swatinem/rust-cache/compare/6323deb102c322ba6fcbdcafc7e3dddab59af2b6...d1527c8f67ef9af357290475d4af4b0fab8f12e0) --- updated-dependencies: - dependency-name: Swatinem/rust-cache dependency-version: 2.9.3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
471 lines
22 KiB
YAML
471 lines
22 KiB
YAML
# 推 v<版本> 标签发四个平台(共用一个 GitHub Release);单平台补丁推 macos-v / windows-v / linux-v / android-v<版本>,只打那一个平台。
|
||
# 版本号读各平台壳:macOS apps/macos/Cargo.toml、Windows apps/windows/server/Cargo.toml、Linux apps/linux/server/Cargo.toml、Android apps/android/core/Cargo.toml,要打的平台都得与标签一致。
|
||
# 流程:prepare 核对版本、建草稿 Release → 各平台 job 并行打包,把安装包与摘要 / 构建信息片段传到草稿上
|
||
# → publish 合并片段、转正、生成并签名 releases.json、触发官网构建。任何平台失败都停在草稿,不会发出缺平台的版本。
|
||
# 流程见 docs/notes/release.md。macOS 的签名与公证可选,下面的 Secrets 配齐才签,否则出 ad-hoc 包;
|
||
# Windows 现在没有代码签名(QINGJIAN_UIACCESS=0 关掉 uiAccess,否则没签名的 Server 起不来),证书办下来再加 signtool。
|
||
# QINGJIAN_CERT_P12 Developer ID Application + Installer 两张证书(含私钥)导出的 .p12,base64
|
||
# QINGJIAN_CERT_PASSWORD .p12 的密码
|
||
# QINGJIAN_SIGN_IDENTITY "Developer ID Application: 名字 (TEAMID)"
|
||
# QINGJIAN_INSTALLER_IDENTITY "Developer ID Installer: 名字 (TEAMID)"
|
||
# QINGJIAN_NOTARY_KEY App Store Connect API 密钥 .p8,base64
|
||
# QINGJIAN_NOTARY_KEY_ID 密钥的 Key ID
|
||
# QINGJIAN_NOTARY_ISSUER 密钥的 Issuer ID
|
||
# Android 的 APK 签名(打 Android 时必须,没配这个 job 直接失败):
|
||
# QINGJIAN_ANDROID_KEYSTORE 密钥库 .jks,base64;换了已装的用户就不能覆盖升级
|
||
# QINGJIAN_ANDROID_KEYSTORE_PASSWORD 密钥库密码
|
||
# QINGJIAN_ANDROID_KEY_ALIAS 密钥别名
|
||
# QINGJIAN_ANDROID_KEY_PASSWORD 密钥密码
|
||
# 版本索引的签名(必须,没配门禁直接失败):
|
||
# QINGJIAN_INDEX_SIGNING_KEY releases.json 的 ed25519 私钥(base64 的 32 字节,tools/release-sign keygen 生成),
|
||
# 公钥在 crates/qingjian-update/src/index/signature.rs;软件内检查更新只认签过名的索引
|
||
# 发版后让官网重新构建(也可选):
|
||
# QINGJIAN_WEB_TOKEN fine-grained PAT,对 qingjian-team/qingjian-web 有 Contents: read and write
|
||
# (官网由 Cloudflare 按仓库提交自动构建,tools/release/bump-website.sh 往那边推一个小提交)
|
||
#
|
||
# 门禁:版本号与标签一致且不带 -dev;标签指向的提交必须在 main 上(防止从没合并的分支或手滑的本地提交发版)。
|
||
# Secrets 不放 workflow 顶层 env,只注入真正用它的那一步;有没有配由第一步算成输出(secrets 不能直接写在 if 里)。
|
||
# actions 钉到 commit(注释是对应标签),Dependabot 每周更新;产品数据与本地整句模型按 tools/release/data.lock 钉住的 data-vN Release 下载、按锁文件里的哈希校验,标签与哈希记进 build-info.json。
|
||
name: release
|
||
|
||
on:
|
||
push:
|
||
tags: ['v*', 'macos-v*', 'windows-v*', 'linux-v*', 'android-v*']
|
||
|
||
env:
|
||
CARGO_TERM_COLOR: always
|
||
|
||
jobs:
|
||
prepare:
|
||
runs-on: ubuntu-26.04
|
||
permissions:
|
||
contents: write
|
||
outputs:
|
||
version: ${{ steps.gate.outputs.version }}
|
||
macos: ${{ steps.gate.outputs.macos }}
|
||
windows: ${{ steps.gate.outputs.windows }}
|
||
linux: ${{ steps.gate.outputs.linux }}
|
||
android: ${{ steps.gate.outputs.android }}
|
||
steps:
|
||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||
with:
|
||
fetch-depth: 0
|
||
persist-credentials: false
|
||
|
||
- name: Check versions match tag and tag is on main
|
||
id: gate
|
||
env:
|
||
INDEX_KEY_SET: ${{ secrets.QINGJIAN_INDEX_SIGNING_KEY != '' }}
|
||
run: |
|
||
if [[ "$INDEX_KEY_SET" != "true" ]]; then
|
||
echo "没配 QINGJIAN_INDEX_SIGNING_KEY:releases.json 签不了名,已装的青简都不认这份索引、收不到更新提示(docs/notes/release.md)" >&2
|
||
exit 1
|
||
fi
|
||
case "$GITHUB_REF_NAME" in
|
||
v*) PLATFORMS="macos windows linux android"; VERSION="${GITHUB_REF_NAME#v}" ;;
|
||
*-v*) PLATFORMS="${GITHUB_REF_NAME%%-v*}"; VERSION="${GITHUB_REF_NAME#*-v}" ;;
|
||
esac
|
||
declare -A MANIFEST=([macos]=apps/macos/Cargo.toml [windows]=apps/windows/server/Cargo.toml [linux]=apps/linux/server/Cargo.toml [android]=apps/android/core/Cargo.toml)
|
||
for platform in $PLATFORMS; do
|
||
found="$(sed -n 's/^version = "\(.*\)"/\1/p' "${MANIFEST[$platform]}" | head -1)"
|
||
if [[ "$found" != "$VERSION" ]]; then
|
||
echo "${MANIFEST[$platform]} 是 $found,标签是 $GITHUB_REF_NAME,先改版本号再打标签" >&2
|
||
exit 1
|
||
fi
|
||
done
|
||
if [[ "$VERSION" == *-dev ]]; then
|
||
echo "$VERSION 还是开发版号,发版提交要先去掉 -dev(docs/notes/release.md)" >&2
|
||
exit 1
|
||
fi
|
||
git fetch --no-tags origin main
|
||
if ! git merge-base --is-ancestor "$GITHUB_SHA" origin/main; then
|
||
echo "标签 $GITHUB_REF_NAME 指向的提交 $GITHUB_SHA 不在 main 上,先合并再发" >&2
|
||
exit 1
|
||
fi
|
||
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
|
||
for platform in macos windows linux android; do
|
||
[[ " $PLATFORMS " == *" $platform "* ]] && on=true || on=false
|
||
echo "$platform=$on" >> "$GITHUB_OUTPUT"
|
||
done
|
||
|
||
- name: Create draft release
|
||
env:
|
||
GH_TOKEN: ${{ github.token }}
|
||
VERSION: ${{ steps.gate.outputs.version }}
|
||
MACOS: ${{ steps.gate.outputs.macos }}
|
||
WINDOWS: ${{ steps.gate.outputs.windows }}
|
||
LINUX: ${{ steps.gate.outputs.linux }}
|
||
ANDROID: ${{ steps.gate.outputs.android }}
|
||
MAC_SIGNED: ${{ secrets.QINGJIAN_CERT_P12 != '' }}
|
||
run: |
|
||
NOTES="$RUNNER_TEMP/notes.md"
|
||
python3 tools/release/releases_json.py --notes-for "$VERSION" > "$NOTES"
|
||
if [[ "$MACOS" == "true" && "$MAC_SIGNED" != "true" ]]; then
|
||
printf '\n> macOS:这一版没有 Apple 开发者签名,首次打开系统会拦一下:到「系统设置 → 隐私与安全性」底部点「仍要打开」再装一次。\n' >> "$NOTES"
|
||
fi
|
||
if [[ "$WINDOWS" == "true" ]]; then
|
||
printf '\n> Windows:这一版没有代码签名:安装时 SmartScreen 拦截请点「更多信息 → 仍要运行」;任务栏搜索、「设置」等系统应用里候选窗口可能被遮挡。\n' >> "$NOTES"
|
||
fi
|
||
if [[ "$LINUX" == "true" ]]; then
|
||
printf '\n> Linux:预编译包在 Ubuntu 26.04 上构建,其他发行版请用源码安装;解开后运行 install.sh,说明见官网文档「Linux」。\n' >> "$NOTES"
|
||
fi
|
||
if [[ "$ANDROID" == "true" ]]; then
|
||
printf '\n> Android:预览版,功能比桌面版少;APK 只支持 arm64、Android 8.0 及以上,下载后在手机上安装,系统可能要你允许「安装未知应用」。\n' >> "$NOTES"
|
||
fi
|
||
case "$GITHUB_REF_NAME" in
|
||
macos-v*) TITLE="青简 macOS $VERSION" ;;
|
||
windows-v*) TITLE="青简 Windows $VERSION" ;;
|
||
linux-v*) TITLE="青简 Linux $VERSION" ;;
|
||
android-v*) TITLE="青简 Android $VERSION" ;;
|
||
*) TITLE="青简 $VERSION" ;;
|
||
esac
|
||
# 带预发布后缀的版本(0.1.4-beta.1)是测试渠道的:标成预发布,不抢 GitHub 的 latest
|
||
PRERELEASE=(); [[ "$VERSION" == *-* ]] && PRERELEASE=(--prerelease --latest=false)
|
||
gh release create "$GITHUB_REF_NAME" --draft --verify-tag --title "$TITLE" --notes-file "$NOTES" ${PRERELEASE[@]+"${PRERELEASE[@]}"}
|
||
|
||
macos:
|
||
needs: prepare
|
||
if: needs.prepare.outputs.macos == 'true'
|
||
runs-on: macos-26
|
||
permissions:
|
||
contents: write
|
||
env:
|
||
VERSION: ${{ needs.prepare.outputs.version }}
|
||
steps:
|
||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||
with:
|
||
# bundle.sh 用提交数当构建号
|
||
fetch-depth: 0
|
||
persist-credentials: false
|
||
|
||
- uses: dtolnay/rust-toolchain@683b588c487a69d01f6c6ddf40f036ff682cc2c8 # v1
|
||
with:
|
||
toolchain: 1.96.0
|
||
targets: aarch64-apple-darwin, x86_64-apple-darwin
|
||
|
||
- uses: Swatinem/rust-cache@d1527c8f67ef9af357290475d4af4b0fab8f12e0 # v2.9.3
|
||
|
||
- name: Detect optional secrets
|
||
id: secrets
|
||
run: |
|
||
echo "sign=${{ secrets.QINGJIAN_CERT_P12 != '' }}" >> "$GITHUB_OUTPUT"
|
||
echo "notarize=${{ secrets.QINGJIAN_NOTARY_KEY != '' }}" >> "$GITHUB_OUTPUT"
|
||
|
||
- name: Fetch product data
|
||
env:
|
||
GH_TOKEN: ${{ github.token }}
|
||
run: |
|
||
tools/release/data-fetch.sh
|
||
ls -la data/generated data/generated/dicts data/models/hanzhang-tongbian
|
||
|
||
- name: Import signing certificates
|
||
if: steps.secrets.outputs.sign == 'true'
|
||
env:
|
||
CERT_P12: ${{ secrets.QINGJIAN_CERT_P12 }}
|
||
CERT_PASSWORD: ${{ secrets.QINGJIAN_CERT_PASSWORD }}
|
||
SIGN_IDENTITY: ${{ secrets.QINGJIAN_SIGN_IDENTITY }}
|
||
INSTALLER_IDENTITY: ${{ secrets.QINGJIAN_INSTALLER_IDENTITY }}
|
||
run: |
|
||
KEYCHAIN="$RUNNER_TEMP/signing.keychain-db"
|
||
security create-keychain -p "" "$KEYCHAIN"
|
||
security set-keychain-settings -lut 21600 "$KEYCHAIN"
|
||
security unlock-keychain -p "" "$KEYCHAIN"
|
||
echo "$CERT_P12" | base64 --decode > "$RUNNER_TEMP/cert.p12"
|
||
security import "$RUNNER_TEMP/cert.p12" -P "$CERT_PASSWORD" -A -t cert -f pkcs12 -k "$KEYCHAIN"
|
||
rm -f "$RUNNER_TEMP/cert.p12"
|
||
security set-key-partition-list -S apple-tool:,apple:,codesign:,productbuild: -s -k "" "$KEYCHAIN" >/dev/null
|
||
security list-keychains -d user -s "$KEYCHAIN" $(security list-keychains -d user | tr -d '"')
|
||
{
|
||
echo "QINGJIAN_SIGN_IDENTITY=$SIGN_IDENTITY"
|
||
echo "QINGJIAN_INSTALLER_IDENTITY=$INSTALLER_IDENTITY"
|
||
} >> "$GITHUB_ENV"
|
||
|
||
- name: Store notarization credentials
|
||
if: steps.secrets.outputs.notarize == 'true'
|
||
env:
|
||
NOTARY_KEY: ${{ secrets.QINGJIAN_NOTARY_KEY }}
|
||
NOTARY_KEY_ID: ${{ secrets.QINGJIAN_NOTARY_KEY_ID }}
|
||
NOTARY_ISSUER: ${{ secrets.QINGJIAN_NOTARY_ISSUER }}
|
||
run: |
|
||
echo "$NOTARY_KEY" | base64 --decode > "$RUNNER_TEMP/AuthKey.p8"
|
||
xcrun notarytool store-credentials qingjian --key "$RUNNER_TEMP/AuthKey.p8" \
|
||
--key-id "$NOTARY_KEY_ID" --issuer "$NOTARY_ISSUER"
|
||
rm -f "$RUNNER_TEMP/AuthKey.p8"
|
||
echo "QINGJIAN_NOTARY_PROFILE=qingjian" >> "$GITHUB_ENV"
|
||
|
||
- name: Build pkg (arm64)
|
||
run: QINGJIAN_TARGET=aarch64-apple-darwin apps/macos/scripts/bundle.sh --pkg
|
||
|
||
- name: Build pkg (x86_64)
|
||
run: QINGJIAN_TARGET=x86_64-apple-darwin apps/macos/scripts/bundle.sh --pkg
|
||
|
||
- name: Upload to draft release
|
||
env:
|
||
GH_TOKEN: ${{ github.token }}
|
||
run: tools/release/upload-build.sh macos "macOS $(sw_vers -productVersion)" target/pkg/*.pkg
|
||
|
||
windows:
|
||
needs: prepare
|
||
if: needs.prepare.outputs.windows == 'true'
|
||
runs-on: windows-latest
|
||
permissions:
|
||
contents: write
|
||
defaults:
|
||
run:
|
||
shell: bash
|
||
env:
|
||
VERSION: ${{ needs.prepare.outputs.version }}
|
||
# 没有代码签名证书:Server 不带 uiAccess(没签名的 exe 带 uiAccess=true 起不来;build.rs 缺省也不带,build.ps1 还会按 -Sign 重设)。证书办下来后在 build.ps1 加 signtool、走 -Sign。
|
||
QINGJIAN_UIACCESS: '0'
|
||
PYTHON: python
|
||
# Windows 上 Python 的标准输出缺省 cp1252,中文更新日志会编码失败。
|
||
PYTHONUTF8: '1'
|
||
steps:
|
||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||
with:
|
||
fetch-depth: 0
|
||
persist-credentials: false
|
||
|
||
- uses: dtolnay/rust-toolchain@683b588c487a69d01f6c6ddf40f036ff682cc2c8 # v1
|
||
with:
|
||
toolchain: 1.96.0
|
||
# 安装包另带一份 32 位 TSF DLL(build.ps1 编)
|
||
targets: i686-pc-windows-msvc
|
||
|
||
- uses: Swatinem/rust-cache@d1527c8f67ef9af357290475d4af4b0fab8f12e0 # v2.9.3
|
||
|
||
- name: Fetch product data
|
||
env:
|
||
GH_TOKEN: ${{ github.token }}
|
||
run: |
|
||
tools/release/data-fetch.sh
|
||
ls -la data/generated data/generated/dicts data/models/hanzhang-tongbian
|
||
|
||
# 与开发机同版本(7.1.0,自带简体中文翻译;Chocolatey 只有 6.x,6 的安装包不带简中)。钉死 GitHub Release 上的文件。
|
||
- name: Install Inno Setup 7.1.0
|
||
shell: pwsh
|
||
run: |
|
||
$url = 'https://github.com/jrsoftware/issrc/releases/download/is-7_1_0/innosetup-7.1.0-x64.exe'
|
||
# 下载来的安装程序要以管理员身份执行,先核对 SHA-256(2026-09-11 从上面地址下载后算出),对不上就不装。
|
||
$expected = '0362a383ed217d4c4239b5933866dd96d3eb2102737da92f80f6057a4b40df2f'
|
||
$exe = Join-Path $env:RUNNER_TEMP 'innosetup.exe'
|
||
Invoke-WebRequest -Uri $url -OutFile $exe
|
||
$actual = (Get-FileHash -Path $exe -Algorithm SHA256).Hash.ToLowerInvariant()
|
||
if ($actual -ne $expected) { throw "Inno Setup 安装程序 SHA-256 不符:$actual" }
|
||
Start-Process -FilePath $exe -ArgumentList '/VERYSILENT', '/SUPPRESSMSGBOXES', '/NORESTART', '/SP-' -Wait
|
||
& "${env:ProgramFiles}\Inno Setup 7\ISCC.exe" --version
|
||
|
||
- name: Build installer
|
||
shell: pwsh
|
||
run: powershell -NoProfile -ExecutionPolicy Bypass -File apps\windows\installer\build.ps1
|
||
|
||
- name: Upload to draft release
|
||
env:
|
||
GH_TOKEN: ${{ github.token }}
|
||
run: tools/release/upload-build.sh windows "$(powershell -NoProfile -Command '(Get-CimInstance Win32_OperatingSystem).Caption' | tr -d '\r')" target/installer/*.exe
|
||
|
||
linux:
|
||
needs: prepare
|
||
if: needs.prepare.outputs.linux == 'true'
|
||
# Fcitx5 插件链接的是构建机上的 Fcitx5,与已验证的 Ubuntu 26.04 一致
|
||
runs-on: ubuntu-26.04
|
||
permissions:
|
||
contents: write
|
||
env:
|
||
VERSION: ${{ needs.prepare.outputs.version }}
|
||
steps:
|
||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||
with:
|
||
persist-credentials: false
|
||
|
||
- uses: dtolnay/rust-toolchain@683b588c487a69d01f6c6ddf40f036ff682cc2c8 # v1
|
||
with:
|
||
toolchain: 1.96.0
|
||
|
||
- uses: Swatinem/rust-cache@d1527c8f67ef9af357290475d4af4b0fab8f12e0 # v2.9.3
|
||
|
||
- name: Install Fcitx5 build dependencies
|
||
run: |
|
||
sudo apt-get update
|
||
sudo apt-get install -y cmake g++ pkg-config libssl-dev libfcitx5core-dev libfcitx5config-dev libfcitx5utils-dev nlohmann-json3-dev fcitx5
|
||
|
||
- name: Fetch product data
|
||
env:
|
||
GH_TOKEN: ${{ github.token }}
|
||
run: |
|
||
tools/release/data-fetch.sh
|
||
ls -la data/generated data/generated/dicts data/models/hanzhang-tongbian
|
||
|
||
- name: Build package
|
||
run: apps/linux/scripts/package.sh
|
||
|
||
# 装进临时目录再卸载:包里文件齐、校验过得去、两个二进制在这台机器上找得到全部动态库
|
||
- name: Smoke-test package
|
||
run: |
|
||
work="$RUNNER_TEMP/package-test"
|
||
mkdir -p "$work"
|
||
tar -xzf target/linux-package/*.tar.gz -C "$work"
|
||
cd "$work"/qingjian-*/
|
||
export XDG_DATA_HOME="$work/data"
|
||
./install.sh --prefix "$work/prefix"
|
||
for binary in "$work/prefix/bin/qingjian-linux-server" "$work/prefix/lib/fcitx5/qingjian.so"; do
|
||
if ldd "$binary" | grep 'not found'; then exit 1; fi
|
||
done
|
||
./uninstall.sh --prefix "$work/prefix"
|
||
test ! -e "$work/prefix/bin/qingjian-linux-server"
|
||
|
||
- name: Upload to draft release
|
||
env:
|
||
GH_TOKEN: ${{ github.token }}
|
||
run: tools/release/upload-build.sh linux "$(. /etc/os-release && echo "$PRETTY_NAME"), Fcitx5 $(pkg-config --modversion Fcitx5Core)" target/linux-package/*.tar.gz
|
||
|
||
# deb / rpm:全在容器里编(Rust 部分 Ubuntu 22.04,fcitx5 插件对着 Debian 13 / Fedora 42 各编一份),见 docs/notes/linux-packaging.md。
|
||
# 只挂在 Release 上、不进 releases.json:每种格式两个包(qingjian 与 qingjian-fcitx5),检查更新与官网下载页仍按 tar.gz 认 Linux。
|
||
linux-packages:
|
||
needs: prepare
|
||
if: needs.prepare.outputs.linux == 'true'
|
||
runs-on: ubuntu-26.04
|
||
permissions:
|
||
contents: write
|
||
env:
|
||
VERSION: ${{ needs.prepare.outputs.version }}
|
||
steps:
|
||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||
with:
|
||
persist-credentials: false
|
||
|
||
# build.sh 把本机的 ~/.cargo 与 ~/.rustup 挂进 Ubuntu 22.04 容器编 Rust 部分
|
||
- uses: dtolnay/rust-toolchain@683b588c487a69d01f6c6ddf40f036ff682cc2c8 # v1
|
||
with:
|
||
toolchain: 1.96.0
|
||
|
||
- name: Fetch product data
|
||
env:
|
||
GH_TOKEN: ${{ github.token }}
|
||
run: tools/release/data-fetch.sh
|
||
|
||
- name: Build deb and rpm
|
||
run: apps/linux/packaging/build.sh deb rpm
|
||
|
||
# 在干净容器里装、自检(插件缺不缺库、打 nihao 出候选、卸载清干净);图形会话里打字仍要真机试
|
||
- name: Smoke-test packages
|
||
run: apps/linux/packaging/smoke/run.sh debian:trixie ubuntu:26.04 fedora:42
|
||
|
||
- name: Upload to draft release
|
||
env:
|
||
GH_TOKEN: ${{ github.token }}
|
||
run: tools/release/upload-build.sh linux-packages "deb:Debian 13 容器;rpm:Fedora 42 容器;Rust 部分:Ubuntu 22.04 容器" target/linux-pkg/out/*.deb target/linux-pkg/out/*.rpm
|
||
|
||
android:
|
||
needs: prepare
|
||
if: needs.prepare.outputs.android == 'true'
|
||
runs-on: ubuntu-26.04
|
||
permissions:
|
||
contents: write
|
||
env:
|
||
VERSION: ${{ needs.prepare.outputs.version }}
|
||
NDK_VERSION: 29.0.13599879
|
||
steps:
|
||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||
with:
|
||
persist-credentials: false
|
||
|
||
- uses: dtolnay/rust-toolchain@683b588c487a69d01f6c6ddf40f036ff682cc2c8 # v1
|
||
with:
|
||
toolchain: 1.96.0
|
||
targets: aarch64-linux-android
|
||
|
||
- uses: Swatinem/rust-cache@d1527c8f67ef9af357290475d4af4b0fab8f12e0 # v2.9.3
|
||
|
||
# Gradle 8.14 只认到 JDK 24,runner 缺省的是 25
|
||
- name: Use JDK 21
|
||
run: |
|
||
if [[ ! -d "${JAVA_HOME_21_X64:-}" ]]; then
|
||
echo "runner 上没有 JDK 21(JAVA_HOME_21_X64):" >&2
|
||
ls /usr/lib/jvm >&2
|
||
exit 1
|
||
fi
|
||
echo "JAVA_HOME=$JAVA_HOME_21_X64" >> "$GITHUB_ENV"
|
||
|
||
# NDK 版本要与 app/build.gradle.kts 的 ndkVersion 一致
|
||
- name: Install NDK and cargo-ndk
|
||
run: |
|
||
yes | "$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager" --install "ndk;$NDK_VERSION" "platforms;android-36" > /dev/null
|
||
cargo install cargo-ndk --version 4.1.2 --locked
|
||
echo "sdk.dir=$ANDROID_HOME" > apps/android/local.properties
|
||
|
||
- name: Fetch product data
|
||
env:
|
||
GH_TOKEN: ${{ github.token }}
|
||
run: |
|
||
tools/release/data-fetch.sh
|
||
ls -la data/generated data/generated/dicts
|
||
|
||
- name: Build signed APK
|
||
env:
|
||
KEYSTORE_BASE64: ${{ secrets.QINGJIAN_ANDROID_KEYSTORE }}
|
||
QINGJIAN_ANDROID_KEYSTORE_PASSWORD: ${{ secrets.QINGJIAN_ANDROID_KEYSTORE_PASSWORD }}
|
||
QINGJIAN_ANDROID_KEY_ALIAS: ${{ secrets.QINGJIAN_ANDROID_KEY_ALIAS }}
|
||
QINGJIAN_ANDROID_KEY_PASSWORD: ${{ secrets.QINGJIAN_ANDROID_KEY_PASSWORD }}
|
||
run: |
|
||
if [[ -z "$KEYSTORE_BASE64" ]]; then
|
||
echo "没配 QINGJIAN_ANDROID_KEYSTORE:APK 签不了名,装不上(docs/notes/release.md)" >&2
|
||
exit 1
|
||
fi
|
||
export QINGJIAN_ANDROID_KEYSTORE="$RUNNER_TEMP/release.jks"
|
||
echo "$KEYSTORE_BASE64" | base64 -d > "$QINGJIAN_ANDROID_KEYSTORE"
|
||
(cd apps/android && ./gradlew assembleRelease --no-daemon --console=plain)
|
||
rm -f "$QINGJIAN_ANDROID_KEYSTORE"
|
||
mkdir -p target/android-package
|
||
cp apps/android/app/build/outputs/apk/release/app-release.apk "target/android-package/qingjian-$VERSION-android-arm64.apk"
|
||
|
||
- name: Verify APK signature
|
||
run: |
|
||
apksigner="$(ls -d "$ANDROID_HOME"/build-tools/* | sort -V | tail -1)/apksigner"
|
||
"$apksigner" verify --print-certs target/android-package/*.apk
|
||
|
||
- name: Upload to draft release
|
||
env:
|
||
GH_TOKEN: ${{ github.token }}
|
||
run: tools/release/upload-build.sh android "$(. /etc/os-release && echo "$PRETTY_NAME"), NDK $NDK_VERSION" target/android-package/*.apk
|
||
|
||
publish:
|
||
needs: [prepare, macos, windows, linux, linux-packages, android]
|
||
# 没选中的平台是 skipped,照样发;有平台失败就停在草稿
|
||
if: ${{ !cancelled() && needs.prepare.result == 'success' && !contains(needs.*.result, 'failure') }}
|
||
runs-on: ubuntu-26.04
|
||
permissions:
|
||
contents: write
|
||
steps:
|
||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||
with:
|
||
persist-credentials: false
|
||
|
||
- uses: dtolnay/rust-toolchain@683b588c487a69d01f6c6ddf40f036ff682cc2c8 # v1
|
||
with:
|
||
toolchain: 1.96.0
|
||
|
||
- uses: Swatinem/rust-cache@d1527c8f67ef9af357290475d4af4b0fab8f12e0 # v2.9.3
|
||
|
||
- name: Detect optional secrets
|
||
id: secrets
|
||
run: echo "website=${{ secrets.QINGJIAN_WEB_TOKEN != '' }}" >> "$GITHUB_OUTPUT"
|
||
|
||
- name: Merge checksums and build info, publish
|
||
env:
|
||
GH_TOKEN: ${{ github.token }}
|
||
VERSION: ${{ needs.prepare.outputs.version }}
|
||
run: tools/release/finish-release.sh "$GITHUB_REF_NAME" "$VERSION" "$RUNNER_TEMP/release"
|
||
|
||
- name: Generate releases.json
|
||
env:
|
||
GH_TOKEN: ${{ github.token }}
|
||
QINGJIAN_INDEX_SIGNING_KEY: ${{ secrets.QINGJIAN_INDEX_SIGNING_KEY }}
|
||
run: tools/release/publish-releases-json.sh "$GITHUB_REF_NAME" "$RUNNER_TEMP/release"
|
||
|
||
- name: Trigger website build
|
||
if: steps.secrets.outputs.website == 'true'
|
||
env:
|
||
QINGJIAN_WEB_TOKEN: ${{ secrets.QINGJIAN_WEB_TOKEN }}
|
||
run: tools/release/bump-website.sh
|