Skip to content

Fix Chinese annotation #49

Fix Chinese annotation

Fix Chinese annotation #49

Workflow file for this run

################################################################################
# 工作流名称:自动构建与发布流程
# 文件路径:.github/workflows/build.yml
#
# 功能说明:
# 1. push 或 pull_request 到 main 分支:
# - 只执行代码质量检查(lint)和多平台构建(build)任务
# - 不推送 Docker 镜像、不创建标签、不创建 Release
#
# 2. 手动触发 (workflow_dispatch):
# - 可以通过选择 release_type 参数(Beta 或 Releases)
# * release_type=Beta:预发布;Docker 镜像推送至 beta 标签
# * release_type=Releases:正式发布;Docker 镜像推送至 latest 标签
# - 自动根据最新的 Git Tag 版本号 +1,创建并推送新标签
# - 根据选择创建对应的 GitHub Release(预发布或正式发布)
# - 推送 Docker 多架构镜像至 Docker Hub
#
# 3. Go 项目 & Docker 约束:
# - main.go 作为入口文件,且在 main 包中定义 Version 变量
# - Dockerfile 必须支持多平台构建(使用 buildx + QEMU)
# - 如需优化镜像大小,可使用多阶段构建
#
# 4. 可能出现的问题:
# - 若没有 go.mod 文件,将自动执行 go mod init;可能需要根据实际项目包名进行微调
# - freebsd 在 arm64 下有可能构建失败(需视实际情况排除该组合)
# - Windows 平台的可执行文件需添加 .exe 后缀
#
# 5. 提高可读性与用户体验:
# - 使用了部分 emoji 图标,让输出和步骤名称更加直观
# - 对关键步骤进行了中文注释说明,方便维护
################################################################################
name: 自动构建与发布流程
################################################################################
# 触发条件配置
################################################################################
on:
# 当 push 到 main 分支时:执行 lint + build,仅做测试和检查
push:
branches: [ main ]
# 当有 PR (pull_request) 合并到 main 时:执行 lint + build,仅做测试和检查
pull_request:
branches: [ main ]
# 手动触发 (workflow_dispatch)
workflow_dispatch:
inputs:
release_type:
description: '选择发布类型 (Beta=预发布, Releases=正式发布)'
required: true
default: 'Beta'
type: choice
options:
- Beta
- Releases
################################################################################
# 权限配置:允许创建标签、发布和推送到 Packages
################################################################################
permissions:
contents: write
packages: write
################################################################################
# 全局环境变量
# - 可在不同 Job 中重复使用
# - Docker 多平台构建需要在 docker/build-push-action 中引用
################################################################################
env:
GO_VERSION: "1.22.0" # Go 版本
BINARY_NAME: "HubP" # 二进制文件名
DOCKER_IMAGE: "hubp" # Docker 镜像名
PLATFORMS: "linux/amd64,linux/arm64" # Docker 多平台构建目标
################################################################################
# Job 1: 版本处理 —— 根据是否手动触发决定版本号与标签创建
################################################################################
jobs:
version:
name: 版本处理 🏷️
runs-on: ubuntu-latest
outputs:
final_version: ${{ steps.version_step.outputs.final_version }} # 下游需要的版本号
# 是否手动触发(workflow_dispatch)
is_manual: ${{ github.event_name == 'workflow_dispatch' }}
# 是否正式发布(仅当手动触发 && release_type=Releases 才为 true)
is_release: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.release_type == 'Releases' }}
steps:
- name: 检出代码 📥
uses: actions/checkout@v4
with:
fetch-depth: 0 # 获取完整提交历史,以便获取最新标签
- name: 设置版本号
id: version_step
shell: bash
run: |
############################################################################
# 如果不是手动触发 (push / pull_request),则直接使用临时版本号,不创建真实标签
############################################################################
if [ "${{ github.event_name }}" != "workflow_dispatch" ]; then
echo "当前为 push 或 PR 触发,仅使用临时版本号 v0.0.0-snapshot"
echo "final_version=v0.0.0-snapshot" >> $GITHUB_OUTPUT
exit 0
fi
############################################################################
# 如果是手动触发,则需要:
# 1. 获取最新标签
# 2. 将补丁号 +1
# 3. 生成新的版本号并输出
############################################################################
latest_tag=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0")
echo "获取到的最新标签: $latest_tag"
version_no_v="${latest_tag#v}" # 去掉前缀 v
major=$(echo "$version_no_v" | cut -d. -f1)
minor=$(echo "$version_no_v" | cut -d. -f2)
patch=$(echo "$version_no_v" | cut -d. -f3)
patch=$((patch + 1))
new_version="v${major}.${minor}.${patch}"
echo "生成新版本号: $new_version"
echo "final_version=$new_version" >> $GITHUB_OUTPUT
- name: 创建并推送新标签
if: ${{ github.event_name == 'workflow_dispatch' }}
run: |
# 仅在手动触发时才执行此步骤
version="${{ steps.version_step.outputs.final_version }}"
echo "即将创建并推送标签: ${version}"
git config --global user.name "github-actions[bot]"
git config --global user.email "github-actions[bot]@users.noreply.github.com"
git tag -a "${version}" -m "Release ${version}"
git push origin "${version}"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
################################################################################
# Job 2: 代码质量检查 (lint)
################################################################################
lint:
name: 代码质量检查 🔍
runs-on: ubuntu-latest
steps:
- name: 检出代码 📥
uses: actions/checkout@v4
- name: 设置 Go 环境 🔧
uses: actions/setup-go@v5
with:
go-version: ${{ env.GO_VERSION }}
# 不使用缓存
cache: false
- name: 执行代码格式化 & 静态检查
run: |
# 检查 go.mod
if [ ! -f go.mod ]; then
echo "错误:项目根目录下未找到 go.mod 文件,无法进行依赖管理。"
exit 1
fi
# go fmt
echo "🔹 开始执行 go fmt..."
go fmt ./...
echo "✅ go fmt 完成。"
# go vet
echo "🔹 开始执行 go vet..."
go vet ./...
echo "✅ go vet 完成。"
# 核验 main.go
if [ ! -f "main.go" ]; then
echo "错误:未找到 main.go 入口文件!"
exit 1
fi
# 核验 Dockerfile
if [ ! -f "Dockerfile" ]; then
echo "错误:未找到 Dockerfile 文件!"
exit 1
fi
################################################################################
# Job 3: 多平台构建 (build)
# - 仅进行编译与产物打包,用于测试各平台能否成功构建
# - push 或 PR 时:会触发这一过程,但不推送 Docker
################################################################################
build:
name: 多平台构建 🏗️
needs: [version, lint] # 必须先完成版本处理和代码质量检查
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
os: [ linux, darwin, windows, freebsd ]
arch: [ amd64, arm64 ]
# 如需排除某些不兼容组合,可在此添加 exclude
# exclude:
# - os: freebsd
# arch: arm64
steps:
- name: 检出代码 📥
uses: actions/checkout@v4
- name: 设置 Go 环境 🛠
uses: actions/setup-go@v5
with:
go-version: ${{ env.GO_VERSION }}
# 不使用缓存
cache: false
- name: 准备 Go 模块依赖
run: |
if [ ! -f go.mod ]; then
go mod init ${{ env.BINARY_NAME }}
fi
if [ ! -f go.sum ]; then
touch go.sum
fi
echo "正在下载依赖..."
go mod tidy
go mod download
- name: 构建与打包 📦
run: |
# 取得版本号(push 或 PR 时为 v0.0.0-snapshot;手动触发则为实际版本)
VERSION=${{ needs.version.outputs.final_version }}
echo "当前使用版本号:$VERSION"
mkdir -p release
# 构建输出目录名称
temp_dir="release/${{ env.BINARY_NAME }}-${VERSION}-${{ matrix.os }}-${{ matrix.arch }}"
mkdir -p "${temp_dir}"
# 根据系统类型决定文件名后缀(Windows 需 .exe)
binary_name="${{ env.BINARY_NAME }}"
if [ "${{ matrix.os }}" = "windows" ]; then
binary_name="${binary_name}.exe"
fi
echo "开始编译 -> OS: ${{ matrix.os }} / ARCH: ${{ matrix.arch }}"
GOOS=${{ matrix.os }} GOARCH=${{ matrix.arch }} \
go build \
-trimpath \
-ldflags="-s -w -X main.Version=${VERSION}" \
-o "${temp_dir}/${binary_name}" \
.
echo "编译完成,开始打包压缩..."
cd release
zip_file="${{ env.BINARY_NAME }}-${VERSION}-${{ matrix.os }}-${{ matrix.arch }}.zip"
# 使用 -j 参数去除路径信息,确保解压后直接是二进制文件
zip -9 "${zip_file}" -j "$(basename ${temp_dir})/${binary_name}"
echo "生成校验和..."
sha256sum "${zip_file}" | tee -a "checksums-${{ matrix.os }}-${{ matrix.arch }}.txt"
- name: 上传构建产物 📤
uses: actions/upload-artifact@v4
with:
name: build-${{ matrix.os }}-${{ matrix.arch }}
path: release
retention-days: 1
################################################################################
# Job 4: Docker 构建与推送(🐳)
# - 仅在手动触发 (workflow_dispatch) 时进行
# - 根据 release_type=Beta 或 release_type=Releases 推送对应 Docker 标签(beta/latest)
################################################################################
docker:
name: Docker 构建与推送 🐳
needs: [version, lint]
if: ${{ github.event_name == 'workflow_dispatch' }} # 仅手动触发时才执行
runs-on: ubuntu-latest
steps:
- name: 检出代码 📥
uses: actions/checkout@v4
- name: 设置 QEMU (多架构支持)
uses: docker/setup-qemu-action@v3
- name: 设置 Buildx
uses: docker/setup-buildx-action@v3
- name: 登录 Docker Hub 🔑
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: 构建并推送镜像 (预发布 / Beta)
if: ${{ needs.version.outputs.is_release != 'true' }}
uses: docker/build-push-action@v5
with:
context: .
platforms: ${{ env.PLATFORMS }}
push: true
# 不使用构建缓存
tags: |
${{ secrets.DOCKER_USERNAME }}/${{ env.DOCKER_IMAGE }}:${{ needs.version.outputs.final_version }}
${{ secrets.DOCKER_USERNAME }}/${{ env.DOCKER_IMAGE }}:beta
build-args: |
VERSION=${{ needs.version.outputs.final_version }}
GO_VERSION=${{ env.GO_VERSION }}
- name: 构建并推送镜像 (正式发布 / Releases)
if: ${{ needs.version.outputs.is_release == 'true' }}
uses: docker/build-push-action@v5
with:
context: .
platforms: ${{ env.PLATFORMS }}
push: true
# 不使用构建缓存
tags: |
${{ secrets.DOCKER_USERNAME }}/${{ env.DOCKER_IMAGE }}:${{ needs.version.outputs.final_version }}
${{ secrets.DOCKER_USERNAME }}/${{ env.DOCKER_IMAGE }}:latest
build-args: |
VERSION=${{ needs.version.outputs.final_version }}
GO_VERSION=${{ env.GO_VERSION }}
################################################################################
# Job 5: 创建 GitHub Release
# - 仅在手动触发时执行
# - 自动收集并上传多平台构建产物
# - 根据 release_type=Beta/Releases 来决定发布类型(预发布或正式发布)
################################################################################
release:
name: 创建发布 📢
needs: [version, build, docker]
if: ${{ github.event_name == 'workflow_dispatch' }}
runs-on: ubuntu-latest
steps:
- name: 下载构建产物 📥
uses: actions/download-artifact@v4
with:
path: release
pattern: build-*
merge-multiple: true
- name: 整理发布文件 🗂
run: |
mkdir -p final_release
# 收集所有 ZIP 包
find release -name "*.zip" -exec cp {} final_release/ \;
# 收集并合并校验和
find release -name "checksums-*.txt" -exec cat {} >> final_release/checksums.txt \;
############################################################################
# 生成发布说明
############################################################################
{
# 判断是正式发布(Releases)还是预发布(Beta)
if [ "${{ needs.version.outputs.is_release }}" = "true" ]; then
echo "# 🚀 正式发布 ${{ needs.version.outputs.final_version }}"
else
echo "# 🚧 预发布 ${{ needs.version.outputs.final_version }}"
fi
echo ""
echo "## 📦 支持的平台"
echo "- Linux (AMD64, ARM64)"
echo "- macOS (AMD64, ARM64)"
echo "- Windows (AMD64, ARM64)"
echo "- FreeBSD (AMD64, ARM64)"
echo ""
echo "## 🐳 Docker 镜像"
echo "支持多架构:AMD64, ARM64"
echo ""
if [ "${{ needs.version.outputs.is_release }}" = "true" ]; then
echo "### 如何拉取最新稳定版?"
echo "\`\`\`bash"
echo "docker pull ${{ secrets.DOCKER_USERNAME }}/${{ env.DOCKER_IMAGE }}:latest"
echo "docker pull ${{ secrets.DOCKER_USERNAME }}/${{ env.DOCKER_IMAGE }}:${{ needs.version.outputs.final_version }}"
echo "\`\`\`"
else
echo "### 如何拉取测试版?"
echo "\`\`\`bash"
echo "docker pull ${{ secrets.DOCKER_USERNAME }}/${{ env.DOCKER_IMAGE }}:beta"
echo "docker pull ${{ secrets.DOCKER_USERNAME }}/${{ env.DOCKER_IMAGE }}:${{ needs.version.outputs.final_version }}"
echo "\`\`\`"
fi
echo ""
echo "## 🔑 SHA256 校验和"
cat final_release/checksums.txt
} > final_release/release_notes.md
- name: 创建 GitHub Release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ needs.version.outputs.final_version }}
files: |
final_release/*.zip
final_release/checksums.txt
body_path: final_release/release_notes.md
draft: false
# 若是预发布 (Beta) 则设置为 true,若是正式发布 (Releases) 则为 false
prerelease: ${{ needs.version.outputs.is_release != 'true' }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}