Skip to content

Release Packages

Release Packages #3

Workflow file for this run

name: Release Packages
on:
release:
# 仅在 GitHub Release 发布时触发。
types: [published]
# 允许手动触发(用于测试)。
workflow_dispatch:
permissions:
# 用于上传构建产物到 Release。
contents: write
jobs:
build:
name: Build (${{ matrix.os }})
runs-on: ${{ matrix.os }}
env:
# FFmpeg 下载源(使用仓库环境变量/密钥可覆盖)。
FFMPEG_BASE_URL: https://dl.liangbm3.site/downloads/ffmpeg
# 如果需要鉴权,请在仓库 Secrets 里配置 FFMPEG_TOKEN。
FFMPEG_TOKEN: ${{ secrets.FFMPEG_TOKEN }}
strategy:
# 允许某个平台失败时其它平台继续构建。
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
# 对齐项目的 Go 版本要求。
go-version: '1.26.x'
- name: Set up Node
uses: actions/setup-node@v4
with:
node-version: '20'
# 缓存前端依赖以加速构建。
cache: 'npm'
cache-dependency-path: frontend/package-lock.json
- name: Install Linux build deps
if: runner.os == 'Linux'
# Wails 在 Linux 上需要 GTK/WebKit 的开发依赖。
run: |
sudo apt-get update
sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.1-dev
- name: Install NSIS
if: runner.os == 'Windows'
# 生成 Windows 安装包需要 NSIS。
shell: powershell
run: |
choco install -y nsis
$nsisPath = "C:\Program Files (x86)\NSIS"
if (Test-Path $nsisPath) {
$nsisPath | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
}
- name: Install Wails and Task
shell: bash
run: |
# 安装构建与打包所需的 CLI 工具。
go install github.com/wailsapp/wails/v3/cmd/wails3@latest
go install github.com/go-task/task/v3/cmd/task@latest
echo "$(go env GOPATH)/bin" >> "$GITHUB_PATH"
- name: Build packages (no ffmpeg)
shell: bash
# 产出依赖系统 FFmpeg 的版本。
run: |
task package:no-ffmpeg
- name: Collect artifacts (no ffmpeg)
shell: bash
# 用后缀区分产物版本。
run: |
mkdir -p dist
shopt -s nullglob
suffix="no-ffmpeg"
if [ "$RUNNER_OS" = "Windows" ]; then
if [ -f "bin/AI-ViewNote.exe" ]; then
cp "bin/AI-ViewNote.exe" "dist/AI-ViewNote-$suffix.exe"
fi
for f in bin/AI-ViewNote-*-installer.exe; do
base=$(basename "$f")
cp "$f" "dist/${base%.exe}-$suffix.exe"
done
for f in bin/*.msix; do
base=$(basename "$f")
cp "$f" "dist/${base%.msix}-$suffix.msix"
done
elif [ "$RUNNER_OS" = "macOS" ]; then
if [ -d "bin/AI-ViewNote.app" ]; then
ditto -c -k --sequesterRsrc --keepParent "bin/AI-ViewNote.app" "dist/AI-ViewNote-macos-$suffix.app.zip"
fi
else
if [ -f "bin/AI-ViewNote" ]; then
cp "bin/AI-ViewNote" "dist/AI-ViewNote-$suffix"
fi
for f in bin/*.AppImage; do
base=$(basename "$f")
cp "$f" "dist/${base%.AppImage}-$suffix.AppImage"
done
for f in bin/*.deb; do
base=$(basename "$f")
cp "$f" "dist/${base%.deb}-$suffix.deb"
done
for f in bin/*.rpm; do
base=$(basename "$f")
cp "$f" "dist/${base%.rpm}-$suffix.rpm"
done
for f in bin/*.pkg.tar.zst; do
base=$(basename "$f")
cp "$f" "dist/${base%.pkg.tar.zst}-$suffix.pkg.tar.zst"
done
fi
- name: Build packages (with ffmpeg)
shell: bash
# 将 FFmpeg 打包进各平台产物。
run: |
# 先下载对应平台的 FFmpeg 到 bin 目录。
mkdir -p bin
if [ "$RUNNER_OS" = "Windows" ]; then
curl -fL -H "X-Download-Token: ${FFMPEG_TOKEN}" "${FFMPEG_BASE_URL}/ffmpeg-windows-amd64.exe" -o "bin/ffmpeg-windows-amd64.exe"
elif [ "$RUNNER_OS" = "macOS" ]; then
arch="arm64"
if [ "$(uname -m)" = "x86_64" ]; then
arch="amd64"
fi
curl -fL -H "X-Download-Token: ${FFMPEG_TOKEN}" "${FFMPEG_BASE_URL}/ffmpeg-darwin-${arch}" -o "bin/ffmpeg-darwin-${arch}"
else
arch="amd64"
if [ "$(uname -m)" = "aarch64" ]; then
arch="arm64"
fi
curl -fL -H "X-Download-Token: ${FFMPEG_TOKEN}" "${FFMPEG_BASE_URL}/ffmpeg-linux-${arch}" -o "bin/ffmpeg-linux-${arch}"
fi
task package:with-ffmpeg NFPM_CONFIG=./build/linux/nfpm/nfpm-with-ffmpeg.yaml
- name: Collect artifacts (with ffmpeg)
shell: bash
# 保持文件名唯一,避免上传冲突。
run: |
mkdir -p dist
shopt -s nullglob
suffix="ffmpeg"
if [ "$RUNNER_OS" = "Windows" ]; then
if [ -f "bin/AI-ViewNote.exe" ]; then
cp "bin/AI-ViewNote.exe" "dist/AI-ViewNote-$suffix.exe"
fi
for f in bin/AI-ViewNote-*-installer.exe; do
base=$(basename "$f")
cp "$f" "dist/${base%.exe}-$suffix.exe"
done
for f in bin/*.msix; do
base=$(basename "$f")
cp "$f" "dist/${base%.msix}-$suffix.msix"
done
elif [ "$RUNNER_OS" = "macOS" ]; then
if [ -d "bin/AI-ViewNote.app" ]; then
ditto -c -k --sequesterRsrc --keepParent "bin/AI-ViewNote.app" "dist/AI-ViewNote-macos-$suffix.app.zip"
fi
else
if [ -f "bin/AI-ViewNote" ]; then
cp "bin/AI-ViewNote" "dist/AI-ViewNote-$suffix"
fi
for f in bin/*.AppImage; do
base=$(basename "$f")
cp "$f" "dist/${base%.AppImage}-$suffix.AppImage"
done
for f in bin/*.deb; do
base=$(basename "$f")
cp "$f" "dist/${base%.deb}-$suffix.deb"
done
for f in bin/*.rpm; do
base=$(basename "$f")
cp "$f" "dist/${base%.rpm}-$suffix.rpm"
done
for f in bin/*.pkg.tar.zst; do
base=$(basename "$f")
cp "$f" "dist/${base%.pkg.tar.zst}-$suffix.pkg.tar.zst"
done
fi
- name: Upload release assets
uses: softprops/action-gh-release@v2
if: github.event_name == 'release'
with:
# 上传 dist 中的所有产物到 Release。
files: dist/**
- name: Upload artifacts (manual)
uses: actions/upload-artifact@v4
if: github.event_name == 'workflow_dispatch'
with:
# 手动触发时上传到 Actions 产物。
name: dist-${{ runner.os }}
path: dist/**