Files
incudal/.github/workflows/release.yml
T
2026-06-20 14:26:29 +08:00

258 lines
7.8 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ============================================================================
# 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: 重新构建 esbuildVite 构建需要)
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