Merge branch 'main' into dependabot/npm_and_yarn/webs/production-depe… #611
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Build and Release Multi-Platform | |
| on: | |
| push: | |
| tags: | |
| - 'v*' | |
| branches: | |
| - '**' | |
| paths-ignore: | |
| # 文档文件(不包括 skill-sublinkpro,它会被嵌入到二进制文件中) | |
| - '*.md' | |
| - 'docs/**' | |
| # AI 代理配置和私有文档 | |
| - '.agents/**' | |
| - '.claude/**' | |
| - '.codex/**' | |
| - 'AGENTS.md' | |
| - 'CLAUDE.md' | |
| - 'GEMINI.md' | |
| - 'CONTRIBUTING.md' | |
| # 编辑器/IDE 配置 | |
| - '.vscode/**' | |
| - '.idea/**' | |
| - '.editorconfig' | |
| # Git 配置 | |
| - '.gitignore' | |
| - '.gitattributes' | |
| # 许可证文件 | |
| - 'LICENSE' | |
| - 'COPYING' | |
| permissions: | |
| contents: write | |
| packages: write | |
| jobs: | |
| build-frontend: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v7 | |
| - name: Set up Node.js | |
| uses: actions/setup-node@v7 | |
| with: | |
| node-version: '24' | |
| # cache: 'yarn' # Disabled to prevent using system Yarn v1 which conflicts with Corepack Yarn v4 | |
| - name: Enable Corepack | |
| run: corepack enable | |
| - name: Get yarn cache directory path | |
| id: yarn-cache-dir-path | |
| run: | | |
| cd webs | |
| echo "dir=$(yarn config get cacheFolder)" >> $GITHUB_OUTPUT | |
| - name: Cache dependencies | |
| uses: actions/cache@v6 | |
| id: yarn-cache | |
| with: | |
| path: ${{ steps.yarn-cache-dir-path.outputs.dir }} | |
| key: ${{ runner.os }}-yarn-${{ hashFiles('webs/yarn.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-yarn- | |
| - name: Install frontend dependencies | |
| run: | | |
| cd webs | |
| yarn install --immutable | |
| - name: Lint frontend | |
| run: | | |
| cd webs | |
| yarn run lint | |
| - name: Build frontend | |
| run: | | |
| cd webs | |
| yarn run build | |
| - name: Upload frontend artifacts | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: frontend-dist | |
| path: webs/dist/ | |
| retention-days: 1 | |
| backend-quality: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v7 | |
| - name: Set up Go | |
| uses: actions/setup-go@v7 | |
| with: | |
| go-version: '1.26.4' | |
| cache: true | |
| cache-dependency-path: go.sum | |
| - name: Download Go modules | |
| run: go mod download | |
| - name: Run golangci-lint | |
| uses: golangci/golangci-lint-action@v9 | |
| with: | |
| version: v2.12.2 | |
| - name: Run Go tests | |
| run: go test ./... | |
| # 使用矩阵策略并发构建不同架构的二进制文件 | |
| build-go-binaries: | |
| needs: [build-frontend, backend-quality] | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false # 允许其他架构继续构建,即使某个失败 | |
| matrix: | |
| include: | |
| - goos: linux | |
| goarch: amd64 | |
| output: sublinkPro-linux-amd64 | |
| upx: true | |
| - goos: linux | |
| goarch: arm64 | |
| output: sublinkPro-linux-arm64 | |
| upx: true | |
| - goos: linux | |
| goarch: arm | |
| goarm: 7 | |
| output: sublinkPro-linux-armv7 | |
| upx: true | |
| - goos: linux | |
| goarch: 386 | |
| output: sublinkPro-linux-x86 | |
| upx: true | |
| - goos: windows | |
| goarch: amd64 | |
| output: sublinkPro-windows-amd64.exe | |
| upx: false | |
| - goos: windows | |
| goarch: 386 | |
| output: sublinkPro-windows-x86.exe | |
| upx: false | |
| - goos: darwin | |
| goarch: amd64 | |
| output: sublinkPro-darwin-amd64 | |
| upx: false | |
| - goos: darwin | |
| goarch: arm64 | |
| output: sublinkPro-darwin-arm64 | |
| upx: false | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v7 | |
| - name: Set up Go | |
| uses: actions/setup-go@v7 | |
| with: | |
| go-version: '1.26.4' | |
| cache: true | |
| cache-dependency-path: go.sum | |
| - name: Download frontend artifacts | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: frontend-dist | |
| path: static/ | |
| - name: Write version to VERSION file | |
| run: | | |
| if [[ $GITHUB_REF == refs/tags/* ]]; then | |
| TAG_NAME=${GITHUB_REF#refs/tags/} | |
| else | |
| TAG_NAME=$(git rev-parse --short HEAD) | |
| fi | |
| echo "$TAG_NAME" > VERSION | |
| echo "Written version $TAG_NAME to VERSION file" | |
| - name: Build Go binary for ${{ matrix.goos }}/${{ matrix.goarch }} | |
| run: | | |
| mkdir -p build | |
| echo "Building ${{ matrix.output }} for ${{ matrix.goos }}/${{ matrix.goarch }}..." | |
| if [ -n "${{ matrix.goarm }}" ]; then | |
| export GOARM="${{ matrix.goarm }}" | |
| echo "Using GOARM=${GOARM}" | |
| fi | |
| CGO_ENABLED=0 GOOS=${{ matrix.goos }} GOARCH=${{ matrix.goarch }} \ | |
| go build -tags=prod -ldflags="-s -w" -o build/${{ matrix.output }} . | |
| echo "Build completed. Binary size:" | |
| ls -lh build/${{ matrix.output }} | |
| - name: Compress binary with UPX | |
| if: matrix.upx | |
| run: | | |
| # 安装 UPX | |
| sudo apt-get update && sudo apt-get install -y upx | |
| echo "=== Original binary size ===" | |
| ls -lh build/${{ matrix.output }} | |
| # 使用最佳压缩率压缩 Linux 二进制文件 | |
| upx --best --lzma build/${{ matrix.output }} || true | |
| echo "=== Compressed binary size ===" | |
| ls -lh build/${{ matrix.output }} | |
| - name: Upload binary artifact | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: binary-${{ matrix.goos }}-${{ matrix.goarch }} | |
| path: build/${{ matrix.output }} | |
| retention-days: 1 | |
| # 合并所有架构的二进制文件 | |
| merge-binaries: | |
| needs: build-go-binaries | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Download all binary artifacts | |
| uses: actions/download-artifact@v8 | |
| with: | |
| pattern: binary-* | |
| path: build/ | |
| merge-multiple: true | |
| - name: Verify all binaries | |
| run: | | |
| echo "=== All binary files ===" | |
| ls -lh build/ | |
| # 验证所有必需的二进制文件都存在 | |
| REQUIRED_FILES=( | |
| "sublinkPro-linux-amd64" | |
| "sublinkPro-linux-arm64" | |
| "sublinkPro-linux-armv7" | |
| "sublinkPro-linux-x86" | |
| "sublinkPro-windows-amd64.exe" | |
| "sublinkPro-windows-x86.exe" | |
| "sublinkPro-darwin-amd64" | |
| "sublinkPro-darwin-arm64" | |
| ) | |
| MISSING=0 | |
| for file in "${REQUIRED_FILES[@]}"; do | |
| if [ ! -f "build/$file" ]; then | |
| echo "ERROR: Missing required binary: $file" | |
| MISSING=1 | |
| else | |
| echo "OK: $file exists" | |
| fi | |
| done | |
| if [ $MISSING -eq 1 ]; then | |
| echo "ERROR: Some required binaries are missing!" | |
| exit 1 | |
| fi | |
| echo "=== All binaries verified successfully ===" | |
| - name: Upload merged binaries | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: go-binaries | |
| path: build/ | |
| retention-days: 1 | |
| release: | |
| if: startsWith(github.ref, 'refs/tags/') | |
| needs: merge-binaries | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v7 | |
| with: | |
| fetch-depth: 0 | |
| - name: Download binary artifacts | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: go-binaries | |
| path: build/ | |
| - name: Generate changelog | |
| id: changelog | |
| run: | | |
| CURRENT_TAG=${GITHUB_REF#refs/tags/} | |
| PREVIOUS_TAG=$(git describe --tags --abbrev=0 HEAD~1 2>/dev/null || echo "") | |
| echo "current_tag=$CURRENT_TAG" >> $GITHUB_OUTPUT | |
| if [ -z "$PREVIOUS_TAG" ]; then | |
| echo "## 🎉 首次发布" > changelog.md | |
| echo "" >> changelog.md | |
| echo "### 📝 所有提交:" >> changelog.md | |
| git log --pretty=format:"- %s (%h)" >> changelog.md | |
| else | |
| echo "## 🚀 更新内容 ($PREVIOUS_TAG -> $CURRENT_TAG)" > changelog.md | |
| echo "" >> changelog.md | |
| echo "### 📝 提交记录:" >> changelog.md | |
| git log --pretty=format:"- %s (%h)" $PREVIOUS_TAG..$CURRENT_TAG >> changelog.md | |
| fi | |
| echo "" >> changelog.md | |
| echo "### 📦 发布文件:" >> changelog.md | |
| echo "- \`sublinkPro-linux-amd64\` - Linux x64" >> changelog.md | |
| echo "- \`sublinkPro-linux-arm64\` - Linux ARM64" >> changelog.md | |
| echo "- \`sublinkPro-linux-armv7\` - Linux ARMv7 (32-bit)" >> changelog.md | |
| echo "- \`sublinkPro-linux-x86\` - Linux x86 (32-bit)" >> changelog.md | |
| echo "- \`sublinkPro-windows-amd64.exe\` - Windows x64" >> changelog.md | |
| echo "- \`sublinkPro-windows-x86.exe\` - Windows x86 (32-bit)" >> changelog.md | |
| echo "- \`sublinkPro-darwin-amd64\` - macOS x64" >> changelog.md | |
| echo "- \`sublinkPro-darwin-arm64\` - macOS ARM64 (Apple Silicon)" >> changelog.md | |
| - name: Create Release | |
| uses: softprops/action-gh-release@v3 | |
| with: | |
| tag_name: ${{ steps.changelog.outputs.current_tag }} | |
| name: Release ${{ steps.changelog.outputs.current_tag }} | |
| body_path: changelog.md | |
| files: | | |
| build/sublinkPro-linux-amd64 | |
| build/sublinkPro-linux-arm64 | |
| build/sublinkPro-linux-armv7 | |
| build/sublinkPro-linux-x86 | |
| build/sublinkPro-windows-amd64.exe | |
| build/sublinkPro-windows-x86.exe | |
| build/sublinkPro-darwin-amd64 | |
| build/sublinkPro-darwin-arm64 | |
| draft: false | |
| prerelease: false | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| build-docker: | |
| needs: [build-frontend, merge-binaries] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v7 | |
| - name: Download frontend artifacts | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: frontend-dist | |
| path: static/ | |
| - name: Download binary artifacts | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: go-binaries | |
| path: build/ | |
| - name: Set up QEMU | |
| uses: docker/setup-qemu-action@v4 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v4 | |
| - name: Log in to Docker Hub | |
| uses: docker/login-action@v4 | |
| with: | |
| username: ${{ secrets.DOCKER_USERNAME }} | |
| password: ${{ secrets.DOCKER_PASSWORD }} | |
| - name: Build and Push Multi-Arch Docker Image | |
| run: | | |
| if [[ $GITHUB_REF == refs/tags/* ]]; then | |
| # 带 tag 的推送:使用 tag 版本号 + latest | |
| TAG=${GITHUB_REF#refs/tags/} | |
| docker buildx build --no-cache --pull --platform linux/amd64,linux/arm64,linux/arm/v7,linux/386 \ | |
| -f Dockerfile.ci \ | |
| -t zerodeng/sublink-pro:${TAG} \ | |
| -t zerodeng/sublink-pro:latest \ | |
| --push . | |
| else | |
| # 分支推送:dev 和 main 分支统一使用 dev 标签,其他分支使用分支名 | |
| BRANCH=${GITHUB_REF#refs/heads/} | |
| if [[ "$BRANCH" == "dev" || "$BRANCH" == "main" ]]; then | |
| DOCKER_TAG="dev" | |
| else | |
| # 将分支名中的 / 替换为 - 以兼容 Docker tag 格式 | |
| DOCKER_TAG=${BRANCH//\//-} | |
| fi | |
| docker buildx build --no-cache --pull --platform linux/amd64,linux/arm64,linux/arm/v7,linux/386 \ | |
| -f Dockerfile.ci \ | |
| -t zerodeng/sublink-pro:${DOCKER_TAG} \ | |
| --push . | |
| fi |