ci: enhance GitHub Actions workflow with multi-platform release builds #22
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
| # GitHub Actions Workflow for oho CLI | |
| # Supports: Auto build/test, Release on tag, Multi-platform, Multi-arch | |
| name: Go CI/CD | |
| on: | |
| push: | |
| branches: [master] | |
| tags: | |
| - 'v*' | |
| pull_request: | |
| branches: [master] | |
| workflow_dispatch: | |
| env: | |
| GO_VERSION: '1.21' | |
| APP_NAME: oho | |
| jobs: | |
| # =========================================== | |
| # Job 1: 代码质量检查 | |
| # =========================================== | |
| lint: | |
| name: Lint | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Go | |
| uses: actions/setup-go@v5 | |
| with: | |
| go-version: ${{ env.GO_VERSION }} | |
| - name: Download dependencies | |
| working-directory: oho | |
| run: go mod download | |
| - name: Run golangci-lint | |
| uses: golangci/golangci-lint-action@v6 | |
| with: | |
| version: latest | |
| args: --timeout=5m | |
| working-directory: oho | |
| # =========================================== | |
| # Job 2: 测试 | |
| # =========================================== | |
| test: | |
| name: Test | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Go | |
| uses: actions/setup-go@v5 | |
| with: | |
| go-version: ${{ env.GO_VERSION }} | |
| - name: Download dependencies | |
| working-directory: oho | |
| run: go mod download | |
| - name: Run tests | |
| working-directory: oho | |
| run: | | |
| go test -v -race -coverprofile=coverage.out ./... | |
| - name: Upload coverage to Codecov | |
| if: github.event_name == 'pull_request' | |
| uses: codecov/codecov-action@v4 | |
| with: | |
| files: ./coverage.out | |
| flags: unittests | |
| name: codecov-umbrella | |
| # =========================================== | |
| # Job 3: 构建 (PR 和 master 推送时) | |
| # =========================================== | |
| build: | |
| name: Build | |
| runs-on: ubuntu-latest | |
| needs: [lint, test] | |
| strategy: | |
| matrix: | |
| goos: [linux, windows, darwin] | |
| goarch: [amd64, arm64] | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Go | |
| uses: actions/setup-go@v5 | |
| with: | |
| go-version: ${{ env.GO_VERSION }} | |
| - name: Download dependencies | |
| working-directory: oho | |
| run: go mod download | |
| - name: Build | |
| working-directory: oho | |
| env: | |
| GOOS: ${{ matrix.goos }} | |
| GOARCH: ${{ matrix.goarch }} | |
| run: | | |
| go build -ldflags="-s -w" -o bin/${APP_NAME}-${GOOS}-${GOARCH}${{ matrix.goos == 'windows' && '.exe' || '' }} ./cmd | |
| - name: Upload artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ${{ env.APP_NAME }}-${{ matrix.goos }}-${{ matrix.goarch }} | |
| path: oho/bin/${{ env.APP_NAME }}-${{ matrix.goos }}-${{ matrix.goarch }}${{ matrix.goos == 'windows' && '.exe' || '' }} | |
| retention-days: 7 | |
| # =========================================== | |
| # Job 4: Release 发布 (仅在 tag 推送时) | |
| # =========================================== | |
| release: | |
| name: Release | |
| runs-on: ubuntu-latest | |
| needs: [lint, test] | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| permissions: | |
| contents: write | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| # Linux | |
| - os: ubuntu-latest | |
| goos: linux | |
| goarch: amd64 | |
| ext: '' | |
| - os: ubuntu-latest | |
| goos: linux | |
| goarch: arm64 | |
| ext: '' | |
| # Windows | |
| - os: windows-latest | |
| goos: windows | |
| goarch: amd64 | |
| ext: .exe | |
| # macOS | |
| - os: macos-latest | |
| goos: darwin | |
| goarch: amd64 | |
| ext: '' | |
| - os: macos-latest | |
| goos: darwin | |
| goarch: arm64 | |
| ext: '' | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Go | |
| uses: actions/setup-go@v5 | |
| with: | |
| go-version: ${{ env.GO_VERSION }} | |
| - name: Download dependencies | |
| working-directory: oho | |
| run: go mod download | |
| - name: Build Release | |
| working-directory: oho | |
| env: | |
| GOOS: ${{ matrix.goos }} | |
| GOARCH: ${{ matrix.goarch }} | |
| run: | | |
| mkdir -p dist | |
| OUTPUT_NAME="${{ env.APP_NAME }}-${{ matrix.goos }}-${{ matrix.goarch }}${{ matrix.ext }}" | |
| go build -ldflags="-s -w -X main.Version=${GITHUB_REF#refs/tags/}" -o "dist/${OUTPUT_NAME}" ./cmd | |
| - name: Create checksums | |
| working-directory: oho/dist | |
| run: | | |
| ${{ matrix.goos == 'windows' && 'certutil -hashfile' || 'sha256sum' }} ${{ env.APP_NAME }}-${{ matrix.goos }}-${{ matrix.goarch }}${{ matrix.ext }} > ${{ env.APP_NAME }}-${{ matrix.goos }}-${{ matrix.goarch }}${{ matrix.ext }}.sha256 | |
| - name: Upload Release Asset | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| tag_name: ${{ github.ref_name }} | |
| files: | | |
| oho/dist/${{ env.APP_NAME }}-${{ matrix.goos }}-${{ matrix.goarch }}${{ matrix.ext }} | |
| oho/dist/${{ env.APP_NAME }}-${{ matrix.goos }}-${{ matrix.goarch }}${{ matrix.ext }}.sha256 | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| # =========================================== | |
| # Job 5: 通知 (发布成功后) | |
| # =========================================== | |
| notify: | |
| name: Notify | |
| runs-on: ubuntu-latest | |
| needs: [release] | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| steps: | |
| - name: Create GitHub Release summary | |
| run: | | |
| echo "## 🎉 Release Published" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "**Version:** ${{ github.ref_name }}" >> $GITHUB_STEP_SUMMARY | |
| echo "**Commit:** ${{ github.sha }}" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "### Downloads" >> $GITHUB_STEP_SUMMARY | |
| echo "- [Release Page](${{ github.server_url }}/${{ github.repository }}/releases/tag/${{ github.ref_name }})" >> $GITHUB_STEP_SUMMARY |