Files
Fig-TreeWalker/.gitea/workflows/build.yml
2026-01-19 17:26:46 +08:00

407 lines
16 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.

name: Release Build
on:
push:
tags: ["*"]
workflow_dispatch:
inputs:
version:
description: "版本号 (例如: v1.0.0, v1.1.0-alpha)"
required: true
default: "dev-build"
jobs:
build-linux-x64:
runs-on: ubuntu
container:
image: git.fig-lang.cn/puqiar/fig-ci:base-latest
options: --network=host
steps:
- name: 验证构建环境
run: |
echo "=== 环境验证开始 ==="
xmake --version
clang++ --version | head -1
echo "=== 环境验证通过 ==="
- name: 检出代码
run: |
git clone https://git.fig-lang.cn/${{ github.repository }} .
git checkout ${{ github.ref }}
- name: 设置版本
run: |
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
VERSION="${{ inputs.version }}"
else
VERSION="${GITHUB_REF#refs/tags/}"
fi
echo "构建版本: $VERSION"
echo "VERSION=$VERSION" >> $GITHUB_ENV
- name: 获取提交信息
run: |
# 获取最新提交信息,如果是标签则获取标签指向的提交
if git describe --tags --exact-match >/dev/null 2>&1; then
# 标签发布:获取标签关联的提交信息
COMMIT_HASH=$(git rev-list -n 1 $VERSION)
COMMIT_MSG=$(git log -1 --pretty=format:"%s" $COMMIT_HASH)
COMMIT_BODY=$(git log -1 --pretty=format:"%b" $COMMIT_HASH)
else
# 手动触发或非标签提交:获取最新提交信息
COMMIT_MSG=$(git log -1 --pretty=format:"%s")
COMMIT_BODY=$(git log -1 --pretty=format:"%b")
fi
# 组合完整的提交信息
if [ -n "$COMMIT_BODY" ]; then
RELEASE_BODY="${COMMIT_MSG}%0A%0A${COMMIT_BODY}"
else
RELEASE_BODY="${COMMIT_MSG}"
fi
# 保存到环境变量
echo "RELEASE_BODY=${RELEASE_BODY}" >> $GITHUB_ENV
echo "提交信息已保存"
- name: 构建项目 (Linux)
run: |
echo "开始构建Linux版本..."
xmake f -p linux -a x86_64 -m release -y
xmake build -j$(nproc)
echo "Linux构建成功。"
- name: 构建Linux安装器
run: |
echo "开始构建Linux安装器..."
cd Installer/ConsoleInstaller
python3 -m venv venv
. venv/bin/activate
pip config set global.index-url https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple
pip install --upgrade pip
pip install -r requirements.txt
python3 -m PyInstaller -F -n FigSetup-Linux --distpath ./dist/linux main.py
echo "Linux安装器构建完成"
- name: 打包Linux发布文件
run: |
VERSION="${{ env.VERSION }}"
PACKAGE_NAME="Fig-${VERSION}-linux-x86_64"
mkdir -p "${PACKAGE_NAME}"
cp build/linux/x86_64/release/Fig "${PACKAGE_NAME}/"
if [ -d "src/Module/Library" ]; then
cp -r src/Module/Library "${PACKAGE_NAME}/"
echo "已包含Library目录。"
fi
tar -czf "${PACKAGE_NAME}.tar.gz" "${PACKAGE_NAME}"
sha256sum "${PACKAGE_NAME}.tar.gz" > "${PACKAGE_NAME}.sha256"
echo "Linux打包完成: ${PACKAGE_NAME}.tar.gz"
- name: 发布Linux版本到Gitea
env:
GITEA_TOKEN: ${{ secrets.CI_TOKEN }}
run: |
VERSION="${{ env.VERSION }}"
RELEASE_BODY="${{ env.RELEASE_BODY }}"
API="https://git.fig-lang.cn/api/v1/repos/${{ github.repository }}"
# 修复使用兼容性最好的case语句判断预发布版本
case "$VERSION" in
*-alpha* | *-beta* | *-dev* | *-rc* | dev-build)
PRERELEASE=true
echo "检测到预发布版本: $VERSION"
;;
*)
PRERELEASE=false
echo "检测到稳定版本: $VERSION"
;;
esac
echo "正在为Linux版本创建/更新发布 $VERSION ..."
RESPONSE=$(curl -sS -X POST -H "Authorization: token $GITEA_TOKEN" \
-H "Content-Type: application/json" \
-d "{\"tag_name\":\"$VERSION\",\"name\":\"Fig $VERSION\",\"body\":\"$RELEASE_BODY\",\"draft\":false,\"prerelease\":$PRERELEASE}" \
"$API/releases" 2>/dev/null || echo '{"id":0}')
RELEASE_ID=$(echo "$RESPONSE" | grep -o '"id":[0-9]*' | head -1 | cut -d':' -f2)
if [ -z "$RELEASE_ID" ] || [ "$RELEASE_ID" = "0" ]; then
echo "尝试通过标签获取已有发布的ID..."
RELEASE_ID=$(curl -sS -H "Authorization: token $GITEA_TOKEN" \
"$API/releases/tags/$VERSION" | grep -o '"id":[0-9]*' | head -1 | cut -d':' -f2)
fi
if [ -z "$RELEASE_ID" ]; then
echo "错误:无法获取或创建发布 ID"
exit 1
fi
echo "使用发布 ID: $RELEASE_ID 进行上传"
# 上传语言包
curl -sS -X POST -H "Authorization: token $GITEA_TOKEN" \
-H "Content-Type: application/octet-stream" \
--data-binary @Fig-$VERSION-linux-x86_64.tar.gz \
"$API/releases/$RELEASE_ID/assets?name=Fig-$VERSION-linux-x86_64.tar.gz"
curl -sS -X POST -H "Authorization: token $GITEA_TOKEN" \
-H "Content-Type: text/plain" \
--data-binary @Fig-$VERSION-linux-x86_64.sha256 \
"$API/releases/$RELEASE_ID/assets?name=Fig-$VERSION-linux-x86_64.sha256"
# 上传Linux安装器
if [ -f "Installer/ConsoleInstaller/dist/linux/FigSetup-Linux" ]; then
echo "正在上传Linux安装器..."
curl -sS -X POST -H "Authorization: token $GITEA_TOKEN" \
-H "Content-Type: application/octet-stream" \
--data-binary @Installer/ConsoleInstaller/dist/linux/FigSetup-Linux \
"$API/releases/$RELEASE_ID/assets?name=FigSetup-Linux"
fi
echo "✅ Linux版本发布完成"
build-windows-x64:
runs-on: windows
steps:
- name: 验证Windows工具链
run: |
Set-ExecutionPolicy Bypass -Scope Process -Force
if (Get-Command xmake -ErrorAction SilentlyContinue) {
Write-Host '✅ xmake 已安装'
xmake --version
} else { Write-Host '警告: xmake 未找到' }
if (Get-Command clang++ -ErrorAction SilentlyContinue) {
Write-Host '✅ clang++ 已安装'
clang++ --version
} else { Write-Host '警告: clang++ 未找到' }
- name: 检出代码
run: |
$env:Path = "C:\Program Files\Git\cmd;$env:Path"
git clone https://git.fig-lang.cn/$env:GITHUB_REPOSITORY .
git checkout $env:GITHUB_REF
- name: 设置版本和提交信息 (Windows)
run: |
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
# 最简版本逻辑
# 手动触发 -> 使用输入框的文本默认是dev-build
# 标签推送 -> 使用标签名
if ($env:GITHUB_EVENT_NAME -eq 'workflow_dispatch') {
# 手动触发:使用输入框的值
$VERSION = '${{ inputs.version }}'
} else {
# 标签推送:使用标签名
$VERSION = '${{ github.ref_name }}'
}
Write-Host "构建版本: $VERSION"
# 获取提交信息
$COMMIT_MSG = git log -1 --pretty=format:"%s" 2>$null
$COMMIT_BODY = git log -1 --pretty=format:"%b" 2>$null
$RELEASE_BODY = $COMMIT_MSG
if (-not [string]::IsNullOrWhiteSpace($COMMIT_BODY)) {
$RELEASE_BODY = "${COMMIT_MSG}`n`n${COMMIT_BODY}"
}
# 设置环境变量
$RELEASE_BODY_JSON = $RELEASE_BODY -replace "`r`n", "\n" -replace "`n", "\n"
"VERSION=$VERSION" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8
"RELEASE_BODY=$RELEASE_BODY_JSON" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8
Write-Host "版本和提交信息已设置"
- name: 构建项目 (Windows Native)
run: |
xmake f -p windows -a x86_64 -m release -y
xmake build -j $env:NUMBER_OF_PROCESSORS
Write-Host 'Windows构建成功。'
- name: 构建Windows安装器
run: |
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
Write-Host "开始构建Windows安装器..."
cd Installer\ConsoleInstaller
pip install -r requirements.txt
pyinstaller -F -i logo.ico -n FigSetup --distpath .\dist\windows main.py
Write-Host "Windows安装器构建完成"
- name: 打包Windows发布文件
run: |
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
$VERSION = $env:VERSION
Write-Host "打包版本: $VERSION"
$PACKAGE_NAME = "Fig-${VERSION}-windows-x86_64"
Write-Host "打包名称: $PACKAGE_NAME"
New-Item -ItemType Directory -Force -Path $PACKAGE_NAME
if (Test-Path 'build\windows\x86_64\release\Fig.exe') {
Copy-Item 'build\windows\x86_64\release\Fig.exe' $PACKAGE_NAME\
} elseif (Test-Path 'build\windows\x86_64\release\Fig') {
Copy-Item 'build\windows\x86_64\release\Fig' $PACKAGE_NAME\Fig.exe
} else {
Write-Host '错误:未找到构建输出文件'
exit 1
}
if (Test-Path 'src\Module\Library') {
Copy-Item -Recurse 'src\Module\Library' $PACKAGE_NAME\
}
$ZIP_NAME = "$PACKAGE_NAME.zip"
Compress-Archive -Path $PACKAGE_NAME -DestinationPath $ZIP_NAME
$Hash = Get-FileHash $ZIP_NAME -Algorithm SHA256
"$($Hash.Hash) $ZIP_NAME" | Out-File "$PACKAGE_NAME.sha256" -Encoding UTF8
Write-Host "Windows打包完成: $ZIP_NAME"
- name: 发布Windows版本到Gitea
env:
GITEA_TOKEN: ${{ secrets.CI_TOKEN }}
run: |
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
Write-Host "=== 开始发布流程 ==="
# 1. 确定版本号
$VERSION = $null
# 首先尝试获取当前HEAD指向的精确标签
$exactTag = git describe --tags --exact-match 2>$null
if ($exactTag) {
$VERSION = $exactTag.Trim()
Write-Host "方式一:通过精确标签获取版本: $VERSION"
}
# 如果失败尝试获取指向当前HEAD的所有标签
if (-not $VERSION) {
$tagsAtHead = git tag --points-at HEAD 2>$null
if ($tagsAtHead) {
$VERSION = ($tagsAtHead -split "`n")[0].Trim()
Write-Host "方式二通过HEAD关联标签获取版本: $VERSION"
}
}
# 如果仍然失败,说明是手动触发或无标签推送,使用 dev-build
if (-not $VERSION) {
$VERSION = "dev-build"
Write-Host "方式三:无标签,使用默认版本: $VERSION"
}
Write-Host "最终发布版本: $VERSION"
# 2. 根据版本后缀判断是否为预发布
if ($VERSION -match '-(alpha|beta|dev|rc)') {
$PRERELEASE = $true
Write-Host "版本类型:预发布版本"
} elseif ($VERSION -eq 'dev-build') {
$PRERELEASE = $true
Write-Host "版本类型:开发构建"
} else {
$PRERELEASE = $false
Write-Host "版本类型:稳定版本"
}
# 3. 获取本次提交信息作为发布描述
$COMMIT_MSG = git log -1 --pretty=format:"%s" 2>$null
$COMMIT_BODY = git log -1 --pretty=format:"%b" 2>$null
$RELEASE_BODY = $COMMIT_MSG
if (-not [string]::IsNullOrWhiteSpace($COMMIT_BODY)) {
$RELEASE_BODY = "${COMMIT_MSG}`n`n${COMMIT_BODY}"
}
# 将正文中的换行符转换为JSON可识别的\n
$RELEASE_BODY_JSON = $RELEASE_BODY -replace "`r`n", "\n" -replace "`n", "\n"
Write-Host "发布描述: $RELEASE_BODY"
# 4. 设置API相关变量
$REPO = $env:GITHUB_REPOSITORY
$API = "https://git.fig-lang.cn/api/v1/repos/$REPO"
$TOKEN = $env:GITEA_TOKEN
# 5. 检查必需的文件
$ZIP_FILE = "Fig-$VERSION-windows-x86_64.zip"
$HASH_FILE = "Fig-$VERSION-windows-x86_64.sha256"
$INSTALLER_PATH = "Installer\ConsoleInstaller\dist\windows\FigSetup.exe"
if (-not (Test-Path $ZIP_FILE)) {
Write-Host "❌ 致命错误:找不到构建产物 $ZIP_FILE"
Write-Host "当前目录文件列表:"
Get-ChildItem *.zip
exit 1
}
Write-Host "正在为版本 [$VERSION] 创建/更新发布..."
# 6. 创建发布请求体
$CREATE_BODY = @{
tag_name = $VERSION
name = "Fig $VERSION"
body = $RELEASE_BODY_JSON
draft = $false
prerelease = $PRERELEASE
} | ConvertTo-Json
Write-Host "发布请求体: $CREATE_BODY"
# 7. 创建或获取已有的发布
$RESPONSE = Invoke-RestMethod -Method Post -Uri "$API/releases" `
-Headers @{
Authorization = "token $TOKEN"
'Content-Type' = 'application/json'
} -Body $CREATE_BODY -ErrorAction SilentlyContinue
if (-not $RESPONSE -or -not $RESPONSE.id) {
Write-Host "创建新发布失败,尝试获取已有发布..."
$RESPONSE = Invoke-RestMethod -Uri "$API/releases/tags/$VERSION" `
-Headers @{Authorization = "token $TOKEN" } `
-ErrorAction SilentlyContinue
}
if ($RESPONSE -and $RESPONSE.id) {
$RELEASE_ID = $RESPONSE.id
Write-Host "✅ 成功获取发布 ID: $RELEASE_ID"
} else {
Write-Host "❌ 致命错误:无法创建或获取发布"
exit 1
}
# 8. 上传所有资产
Write-Host "正在上传ZIP文件 [$ZIP_FILE]..."
$uploadResult1 = Invoke-RestMethod -Method Post -Uri "$API/releases/$RELEASE_ID/assets?name=$ZIP_FILE" `
-Headers @{
Authorization = "token $TOKEN"
'Content-Type' = 'application/octet-stream'
} -InFile $ZIP_FILE -ErrorAction SilentlyContinue
Write-Host "正在上传校验文件 [$HASH_FILE]..."
$uploadResult2 = Invoke-RestMethod -Method Post -Uri "$API/releases/$RELEASE_ID/assets?name=$HASH_FILE" `
-Headers @{
Authorization = "token $TOKEN"
'Content-Type' = 'text/plain'
} -InFile $HASH_FILE -ErrorAction SilentlyContinue
if (Test-Path $INSTALLER_PATH) {
Write-Host "正在上传Windows安装器 [FigSetup.exe]..."
$uploadResult3 = Invoke-RestMethod -Method Post -Uri "$API/releases/$RELEASE_ID/assets?name=FigSetup.exe" `
-Headers @{
Authorization = "token $TOKEN"
'Content-Type' = 'application/octet-stream'
} -InFile $INSTALLER_PATH -ErrorAction SilentlyContinue
} else {
Write-Host "⚠️ 警告:未找到安装器文件,跳过上传"
}
Write-Host "✅ Windows版本 [$VERSION] 发布完成!"