258 lines
7.8 KiB
YAML
258 lines
7.8 KiB
YAML
# ============================================================================
|
||
# Incudal 预构建产物包发布工作流
|
||
# 在推送版本 tag (v*) 或手动触发时,自动构建前后端并打包为 .tar.gz 发行包
|
||
# 支持 amd64 和 arm64 双架构
|
||
# ============================================================================
|
||
|
||
name: Build & Release
|
||
|
||
on:
|
||
push:
|
||
tags:
|
||
- 'v*'
|
||
workflow_dispatch:
|
||
inputs:
|
||
tag:
|
||
description: '发行版本号(例如 v1.0.0),留空则使用 git SHA 作为预览版'
|
||
required: false
|
||
default: ''
|
||
|
||
env:
|
||
NODE_VERSION: '22'
|
||
|
||
jobs:
|
||
# ===== 构建发行包(多架构矩阵) =====
|
||
build:
|
||
name: 构建 (${{ matrix.arch }})
|
||
runs-on: ${{ matrix.runner }}
|
||
strategy:
|
||
matrix:
|
||
include:
|
||
- arch: amd64
|
||
runner: ubuntu-latest
|
||
- arch: arm64
|
||
runner: ubuntu-24.04-arm
|
||
permissions:
|
||
contents: write
|
||
|
||
steps:
|
||
- name: 检出代码
|
||
uses: actions/checkout@v4
|
||
|
||
- name: 安装 pnpm
|
||
uses: pnpm/action-setup@v4
|
||
|
||
- name: 安装 Node.js
|
||
uses: actions/setup-node@v4
|
||
with:
|
||
node-version: ${{ env.NODE_VERSION }}
|
||
cache: 'pnpm'
|
||
|
||
# ===== 安装依赖 =====
|
||
- name: 安装全部依赖
|
||
run: pnpm install --frozen-lockfile --ignore-scripts
|
||
|
||
- name: 重新构建 esbuild(Vite 构建需要)
|
||
run: pnpm rebuild esbuild
|
||
|
||
# ===== 生成 Prisma Client =====
|
||
- name: 生成 Prisma Client
|
||
run: pnpm --filter server exec prisma generate
|
||
env:
|
||
DATABASE_URL: postgresql://user:pass@localhost:5432/db
|
||
|
||
# ===== 构建前端 =====
|
||
- name: 构建前端 (Vite)
|
||
run: pnpm --filter client build
|
||
|
||
# ===== 构建后端 =====
|
||
- name: 编译后端 (TypeScript)
|
||
run: pnpm --filter server build
|
||
|
||
# ===== 准备发行目录 =====
|
||
- name: 准备发行目录结构
|
||
run: |
|
||
mkdir -p release/client/dist
|
||
mkdir -p release/server
|
||
|
||
# 复制前端构建产物
|
||
cp -r client/dist/* release/client/dist/
|
||
|
||
# 复制后端构建产物
|
||
cp -r server/dist release/server/
|
||
cp -r server/prisma release/server/
|
||
cp server/prisma.config.ts release/server/
|
||
cp server/package.json release/server/
|
||
cp -r server/templates release/server/
|
||
|
||
# 复制根配置文件
|
||
cp package.json release/
|
||
cp pnpm-workspace.yaml release/
|
||
|
||
# ===== 安装生产依赖 =====
|
||
- name: 安装后端生产依赖
|
||
working-directory: release/server
|
||
run: |
|
||
# 在发行目录中只安装生产依赖
|
||
npm install --omit=dev --ignore-scripts
|
||
|
||
# 在当前架构的 runner 上原生生成 Prisma Client
|
||
DATABASE_URL="postgresql://user:pass@localhost:5432/db" npx prisma generate
|
||
|
||
# ===== 创建启动辅助脚本 =====
|
||
- name: 创建管理脚本
|
||
run: |
|
||
cat > release/incudal.sh << 'SCRIPT'
|
||
#!/bin/bash
|
||
# Incudal 快捷管理脚本
|
||
set -e
|
||
APP_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||
|
||
case "${1:-}" in
|
||
start)
|
||
echo "🚀 启动 Incudal..."
|
||
cd "$APP_DIR/server"
|
||
npx prisma migrate deploy
|
||
cd "$APP_DIR"
|
||
exec node server/dist/app.js
|
||
;;
|
||
migrate)
|
||
echo "🔄 执行数据库迁移..."
|
||
cd "$APP_DIR/server"
|
||
npx prisma migrate deploy
|
||
echo "✅ 迁移完成"
|
||
;;
|
||
version)
|
||
echo "Incudal $(node -e "console.log(require('./package.json').version)")"
|
||
;;
|
||
*)
|
||
echo "用法: $0 {start|migrate|version}"
|
||
exit 1
|
||
;;
|
||
esac
|
||
SCRIPT
|
||
chmod +x release/incudal.sh
|
||
|
||
# ===== 确定版本号 =====
|
||
- name: 确定版本号
|
||
id: version
|
||
run: |
|
||
if [[ "${{ github.event_name }}" == "push" && "${{ github.ref_type }}" == "tag" ]]; then
|
||
VERSION="${{ github.ref_name }}"
|
||
elif [[ -n "${{ github.event.inputs.tag }}" ]]; then
|
||
VERSION="${{ github.event.inputs.tag }}"
|
||
else
|
||
VERSION="preview-$(echo ${{ github.sha }} | head -c 7)"
|
||
fi
|
||
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
||
echo "📦 版本号: $VERSION"
|
||
|
||
# ===== 打包 =====
|
||
- name: 打包为 tar.gz
|
||
run: |
|
||
VERSION="${{ steps.version.outputs.version }}"
|
||
cd release
|
||
tar -czf "../incudal-${VERSION}-linux-${{ matrix.arch }}.tar.gz" .
|
||
cd ..
|
||
ls -lh "incudal-${VERSION}-linux-${{ matrix.arch }}.tar.gz"
|
||
echo "📦 发行包大小: $(du -h "incudal-${VERSION}-linux-${{ matrix.arch }}.tar.gz" | cut -f1)"
|
||
|
||
# ===== 上传构建产物 =====
|
||
- name: 上传构建产物
|
||
uses: actions/upload-artifact@v4
|
||
with:
|
||
name: incudal-${{ steps.version.outputs.version }}-linux-${{ matrix.arch }}
|
||
path: incudal-${{ steps.version.outputs.version }}-linux-${{ matrix.arch }}.tar.gz
|
||
retention-days: 30
|
||
|
||
# ===== 发布 Release(等待所有架构构建完成) =====
|
||
release:
|
||
name: 发布 Release
|
||
needs:
|
||
- build
|
||
if: startsWith(github.ref, 'refs/tags/v')
|
||
runs-on: ubuntu-latest
|
||
permissions:
|
||
contents: write
|
||
|
||
steps:
|
||
- name: 确定版本号
|
||
id: version
|
||
run: echo "version=${{ github.ref_name }}" >> $GITHUB_OUTPUT
|
||
|
||
# 下载所有架构的构建产物
|
||
- name: 下载 amd64 产物
|
||
uses: actions/download-artifact@v4
|
||
with:
|
||
name: incudal-${{ steps.version.outputs.version }}-linux-amd64
|
||
|
||
- name: 下载 arm64 产物
|
||
uses: actions/download-artifact@v4
|
||
with:
|
||
name: incudal-${{ steps.version.outputs.version }}-linux-arm64
|
||
|
||
- name: 列出发行文件
|
||
run: ls -lh incudal-*.tar.gz
|
||
|
||
# 创建 Release 并上传所有架构的产物
|
||
- name: 创建 GitHub Release
|
||
uses: softprops/action-gh-release@v2
|
||
with:
|
||
files: |
|
||
incudal-*.tar.gz
|
||
generate_release_notes: true
|
||
draft: false
|
||
prerelease: ${{ contains(github.ref_name, 'alpha') || contains(github.ref_name, 'beta') || contains(github.ref_name, 'rc') }}
|
||
|
||
# ===== 构建并推送 Docker 镜像(多架构) =====
|
||
docker:
|
||
name: 构建 Docker 镜像
|
||
if: startsWith(github.ref, 'refs/tags/v')
|
||
runs-on: ubuntu-latest
|
||
permissions:
|
||
contents: read
|
||
packages: write
|
||
|
||
steps:
|
||
- name: 检出代码
|
||
uses: actions/checkout@v4
|
||
|
||
# 设置 QEMU(用于跨架构构建 arm64)
|
||
- name: 设置 QEMU
|
||
uses: docker/setup-qemu-action@v3
|
||
|
||
# 设置 Docker Buildx(多架构构建引擎)
|
||
- name: 设置 Docker Buildx
|
||
uses: docker/setup-buildx-action@v3
|
||
|
||
# 登录 GitHub Container Registry
|
||
- name: 登录 GHCR
|
||
uses: docker/login-action@v3
|
||
with:
|
||
registry: ghcr.io
|
||
username: ${{ github.actor }}
|
||
password: ${{ secrets.GITHUB_TOKEN }}
|
||
|
||
# 提取版本号和元数据
|
||
- name: 提取 Docker 元数据
|
||
id: meta
|
||
uses: docker/metadata-action@v5
|
||
with:
|
||
images: ghcr.io/${{ github.repository }}
|
||
tags: |
|
||
type=semver,pattern={{version}}
|
||
type=semver,pattern={{major}}.{{minor}}
|
||
type=raw,value=latest
|
||
|
||
# 构建并推送多架构镜像
|
||
- name: 构建并推送 Docker 镜像
|
||
uses: docker/build-push-action@v6
|
||
with:
|
||
context: .
|
||
platforms: linux/amd64,linux/arm64
|
||
push: true
|
||
tags: ${{ steps.meta.outputs.tags }}
|
||
labels: ${{ steps.meta.outputs.labels }}
|
||
cache-from: type=gha
|
||
cache-to: type=gha,mode=max
|