Merge pull request #361 from nxtrace/main #713
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 & Release | |
| permissions: | |
| contents: read | |
| defaults: | |
| run: | |
| shell: bash | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} | |
| cancel-in-progress: true | |
| on: | |
| workflow_dispatch: | |
| push: | |
| branches: [ main ] | |
| tags: [ "v*" ] | |
| paths: | |
| - "**/*.go" | |
| - "go.mod" | |
| - "go.sum" | |
| - ".github/workflows/*.yml" | |
| pull_request: | |
| types: [opened, synchronize, reopened] | |
| paths: | |
| - "**/*.go" | |
| - "go.mod" | |
| - "go.sum" | |
| - ".github/workflows/*.yml" | |
| jobs: | |
| build: | |
| runs-on: ubuntu-latest | |
| continue-on-error: ${{ matrix.allow_fail || false }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| goos: [windows, freebsd, openbsd, linux, dragonfly] | |
| goarch: [amd64, 386] | |
| exclude: | |
| - goarch: 386 | |
| goos: dragonfly | |
| include: | |
| - { goos: linux, goarch: arm, goarm: 7 } | |
| - { goos: linux, goarch: arm, goarm: 6 } | |
| - { goos: linux, goarch: arm, goarm: 5 } | |
| - { goos: android, goarch: arm64 } | |
| - { goos: windows, goarch: arm64 } | |
| # windows/arm 已于 Go 1.26 移除 | |
| - { goos: linux, goarch: arm64 } | |
| - { goos: linux, goarch: riscv64 } | |
| - { goos: linux, goarch: loong64 } | |
| - { goos: linux, goarch: mips64 } | |
| - { goos: linux, goarch: mips64le } | |
| - { goos: linux, goarch: mipsle } | |
| - { goos: linux, goarch: mips } | |
| - { goos: linux, goarch: mipsle, gomips: softfloat } | |
| - { goos: linux, goarch: mips, gomips: softfloat } | |
| - { goos: linux, goarch: ppc64 } | |
| - { goos: linux, goarch: ppc64le } | |
| - { goos: freebsd, goarch: arm64 } | |
| - { goos: freebsd, goarch: arm, goarm: 7 } | |
| - { goos: linux, goarch: s390x } | |
| - { goos: openbsd, goarch: arm64 } | |
| - { goos: openbsd, goarch: arm, goarm: 7 } | |
| env: | |
| CGO_ENABLED: ${{ matrix.goos == 'android' && 1 || 0 }} | |
| GOOS: ${{ matrix.goos }} | |
| GOARCH: ${{ matrix.goarch }} | |
| GOARM: ${{ matrix.goarm }} | |
| GOMIPS: ${{ matrix.gomips }} | |
| steps: | |
| - name: Checkout codebase | |
| uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| fetch-tags: true | |
| - name: Set up Go (built-in cache) | |
| uses: actions/setup-go@v6 | |
| with: | |
| go-version: '1.26.x' | |
| check-latest: true | |
| cache: true | |
| - name: Show Go toolchain info | |
| run: | | |
| set -Eeuo pipefail | |
| go version && go env && echo "Supported targets (dist list):" && go tool dist list | sort -u | |
| - name: Setup Android NDK | |
| if: matrix.goos == 'android' | |
| id: setup-ndk | |
| uses: nttld/setup-ndk@v1 | |
| with: | |
| ndk-version: r26d | |
| add-to-path: false | |
| - name: Resolve build metadata | |
| run: | | |
| set -Eeuo pipefail | |
| BUILD_VERSION="$(git describe --tags --always 2>/dev/null || echo dev)" | |
| BUILD_DATE="$(date -u +'%Y-%m-%dT%H:%M:%SZ')" | |
| COMMIT_SHA1="$(git rev-parse --short HEAD 2>/dev/null || echo unknown)" | |
| ARM_SUFFIX="" | |
| if [ -n "${GOARM:-}" ]; then ARM_SUFFIX="v${GOARM}"; fi | |
| PLATFORM="${GOOS}_${GOARCH}${ARM_SUFFIX}" | |
| EXT="" | |
| if [ "${GOOS}" = "windows" ]; then EXT=".exe"; fi | |
| SOFT="" | |
| if [ "${GOMIPS:-}" = "softfloat" ]; then SOFT="_softfloat"; fi | |
| if [ "$GOOS" = "android" ]; then | |
| ANDROID_API=21 | |
| TOOLCHAIN_BIN="${{ steps.setup-ndk.outputs.ndk-path }}/toolchains/llvm/prebuilt/linux-x86_64/bin" | |
| export CC="$TOOLCHAIN_BIN/aarch64-linux-android${ANDROID_API}-clang" | |
| echo "CC=${CC}" >> "$GITHUB_ENV" | |
| fi | |
| echo "BUILD_VERSION=${BUILD_VERSION}" >> "$GITHUB_ENV" | |
| echo "BUILD_DATE=${BUILD_DATE}" >> "$GITHUB_ENV" | |
| echo "COMMIT_SHA1=${COMMIT_SHA1}" >> "$GITHUB_ENV" | |
| echo "ARM_SUFFIX=${ARM_SUFFIX}" >> "$GITHUB_ENV" | |
| echo "PLATFORM=${PLATFORM}" >> "$GITHUB_ENV" | |
| echo "EXT=${EXT}" >> "$GITHUB_ENV" | |
| echo "SOFT=${SOFT}" >> "$GITHUB_ENV" | |
| - name: Get project dependencies | |
| run: go mod download | |
| - name: Install UPX (selected Linux targets) | |
| if: > | |
| matrix.goos == 'linux' && ( | |
| matrix.goarch == 'amd64' || | |
| matrix.goarch == '386' || | |
| matrix.goarch == 'arm64' || | |
| (matrix.goarch == 'arm' && matrix.goarm == '7') | |
| ) | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y upx | |
| - name: Build all flavors | |
| run: | | |
| mkdir -p dist | |
| LD_BASE="-X github.com/nxtrace/NTrace-core/config.Version=${BUILD_VERSION} \ | |
| -X github.com/nxtrace/NTrace-core/config.BuildDate=${BUILD_DATE} \ | |
| -X github.com/nxtrace/NTrace-core/config.CommitID=${COMMIT_SHA1} \ | |
| -w -s" | |
| for SPEC in "nexttrace:" "nexttrace-tiny:flavor_tiny" "ntr:flavor_ntr"; do | |
| BIN="${SPEC%%:*}" | |
| TAGS="${SPEC#*:}" | |
| NAME="${BIN}_${PLATFORM}${EXT}${SOFT}" | |
| BUILD_ARGS=(-trimpath) | |
| if [ -n "$TAGS" ]; then BUILD_ARGS+=( -tags "$TAGS" ); fi | |
| BUILD_ARGS+=( -o "dist/${NAME}" -ldflags "$LD_BASE" ) | |
| echo "build => dist/${NAME} (tags: ${TAGS:-none})" | |
| go build "${BUILD_ARGS[@]}" | |
| if command -v upx >/dev/null 2>&1; then | |
| case "${GOOS}-${GOARCH}-${GOARM:-}" in | |
| linux-amd64-*|linux-386-*|linux-arm64-*|linux-arm-7) upx -9 "dist/${NAME}" ;; | |
| *) ;; | |
| esac | |
| fi | |
| done | |
| - name: Verify tiny/ntr decoupling | |
| run: | | |
| set -Eeuo pipefail | |
| for BIN in "nexttrace-tiny" "ntr"; do | |
| FNAME="${BIN}_${PLATFORM}${EXT}${SOFT}" | |
| if go version -m "dist/${FNAME}" 2>/dev/null | grep -qE 'github\.com/gin-gonic/gin|github\.com/jsdelivr/globalping-cli'; then | |
| echo "FAIL: ${FNAME} contains gin or globalping-cli dependency" | |
| exit 1 | |
| fi | |
| done | |
| echo "Decoupling check passed" | |
| - name: Upload artifacts | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: build-${{ matrix.goos }}-${{ matrix.goarch }}${{ matrix.goarm && format('-v{0}', matrix.goarm) || '' }}${{ matrix.gomips && format('-{0}', matrix.gomips) || '' }} | |
| path: dist/ | |
| if-no-files-found: error | |
| build-darwin: | |
| runs-on: macos-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: { goarch: [ amd64, arm64 ] } | |
| env: | |
| CGO_ENABLED: 1 | |
| GOOS: darwin | |
| GOARCH: ${{ matrix.goarch }} | |
| steps: | |
| - name: Checkout codebase | |
| uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| fetch-tags: true | |
| - name: Set up Go (built-in cache) | |
| uses: actions/setup-go@v6 | |
| with: | |
| go-version: '1.26.x' | |
| check-latest: true | |
| cache: true | |
| - name: Show Go toolchain info | |
| run: | | |
| set -Eeuo pipefail | |
| go version && go env && echo "Supported targets (dist list):" && go tool dist list | sort -u | |
| - name: Sanity check (Xcode/SDK/lipo/pcap) | |
| run: | | |
| set -Eeuo pipefail | |
| xcode-select -p | |
| SDKROOT="$(xcrun --sdk macosx --show-sdk-path)" | |
| echo "$SDKROOT" | |
| clang --version || true | |
| xcrun -f lipo | |
| command -v lipo >/dev/null || (echo "lipo not found"; exit 1) | |
| test -f "$SDKROOT/usr/include/pcap/pcap.h" || (echo "pcap headers not found in SDK"; exit 1) | |
| - name: Resolve build metadata + Darwin CGO flags | |
| run: | | |
| set -Eeuo pipefail | |
| SDKROOT="$(xcrun --sdk macosx --show-sdk-path)" | |
| if [ "${GOARCH}" = "amd64" ]; then ARCH_FLAG="-arch x86_64"; else ARCH_FLAG="-arch arm64"; fi | |
| CC="$(xcrun -f clang)"; CXX="$(xcrun -f clang++)" | |
| echo "CC=${CC}" >> "$GITHUB_ENV" | |
| echo "CXX=${CXX}" >> "$GITHUB_ENV" | |
| echo "CGO_CFLAGS=-isysroot ${SDKROOT} ${ARCH_FLAG} -mmacosx-version-min=11.0" >> "$GITHUB_ENV" | |
| echo "CGO_LDFLAGS=-isysroot ${SDKROOT} ${ARCH_FLAG} -mmacosx-version-min=11.0" >> "$GITHUB_ENV" | |
| BUILD_VERSION="$(git describe --tags --always 2>/dev/null || echo dev)" | |
| BUILD_DATE="$(date -u +'%Y-%m-%dT%H:%M:%SZ')" | |
| COMMIT_SHA1="$(git rev-parse --short HEAD 2>/dev/null || echo unknown)" | |
| echo "BUILD_VERSION=${BUILD_VERSION}" >> "$GITHUB_ENV" | |
| echo "BUILD_DATE=${BUILD_DATE}" >> "$GITHUB_ENV" | |
| echo "COMMIT_SHA1=${COMMIT_SHA1}" >> "$GITHUB_ENV" | |
| - name: Get project dependencies | |
| run: go mod download | |
| - name: Build all flavors (Darwin, CGO+libpcap via SDK) | |
| run: | | |
| mkdir -p dist | |
| LD_BASE="-X github.com/nxtrace/NTrace-core/config.Version=${BUILD_VERSION} \ | |
| -X github.com/nxtrace/NTrace-core/config.BuildDate=${BUILD_DATE} \ | |
| -X github.com/nxtrace/NTrace-core/config.CommitID=${COMMIT_SHA1} \ | |
| -w -s" | |
| for SPEC in "nexttrace:" "nexttrace-tiny:flavor_tiny" "ntr:flavor_ntr"; do | |
| BIN="${SPEC%%:*}" | |
| TAGS="${SPEC#*:}" | |
| NAME="${BIN}_${GOOS}_${GOARCH}" | |
| BUILD_ARGS=(-trimpath) | |
| if [ -n "$TAGS" ]; then BUILD_ARGS+=( -tags "$TAGS" ); fi | |
| BUILD_ARGS+=( -o "dist/${NAME}" -ldflags "$LD_BASE" ) | |
| echo "build => dist/${NAME} (tags: ${TAGS:-none})" | |
| go build "${BUILD_ARGS[@]}" | |
| done | |
| - name: Verify tiny/ntr decoupling | |
| run: | | |
| set -Eeuo pipefail | |
| for BIN in "nexttrace-tiny" "ntr"; do | |
| FNAME="${BIN}_${GOOS}_${GOARCH}" | |
| if go version -m "dist/${FNAME}" 2>/dev/null | grep -qE 'github\.com/gin-gonic/gin|github\.com/jsdelivr/globalping-cli'; then | |
| echo "FAIL: ${FNAME} contains gin or globalping-cli dependency" | |
| exit 1 | |
| fi | |
| done | |
| echo "Decoupling check passed" | |
| - name: Upload artifacts | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: build-darwin-${{ matrix.goarch }} | |
| path: dist/ | |
| if-no-files-found: error | |
| # Build Universal binaries for all flavors | |
| darwin-universal: | |
| runs-on: macos-latest | |
| needs: [ build-darwin ] | |
| steps: | |
| - name: Download darwin slices (flatten) | |
| uses: actions/download-artifact@v8 | |
| with: | |
| pattern: build-darwin-* | |
| merge-multiple: true | |
| path: dist | |
| - name: Make macOS Universal (amd64+arm64) for all flavors | |
| run: | | |
| set -Eeuo pipefail | |
| for BIN in nexttrace nexttrace-tiny ntr; do | |
| AMD64="dist/${BIN}_darwin_amd64" | |
| ARM64="dist/${BIN}_darwin_arm64" | |
| if [ -f "$AMD64" ] && [ -f "$ARM64" ]; then | |
| lipo -create -output "dist/${BIN}_darwin_universal" "$AMD64" "$ARM64" | |
| file "dist/${BIN}_darwin_universal" || true | |
| echo "Built: dist/${BIN}_darwin_universal" | |
| else | |
| echo "Missing darwin slices for ${BIN}; cannot build universal." >&2 | |
| exit 1 | |
| fi | |
| done | |
| ls -l dist | |
| - name: Upload universal artifacts | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: build-darwin-universal | |
| path: | | |
| dist/nexttrace_darwin_universal | |
| dist/nexttrace-tiny_darwin_universal | |
| dist/ntr_darwin_universal | |
| if-no-files-found: error | |
| # Download all build artifacts and publish to a single release | |
| release: | |
| runs-on: ubuntu-latest | |
| needs: [ build, build-darwin, darwin-universal ] | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| steps: | |
| - name: Download all artifacts (flatten) | |
| uses: actions/download-artifact@v8 | |
| with: | |
| pattern: build-* | |
| merge-multiple: true | |
| path: dist_release | |
| - name: Show downloaded files | |
| run: | | |
| set -Eeuo pipefail | |
| ls -lah dist_release | |
| test -n "$(find dist_release -type f -print -quit)" || { echo "No artifacts found in dist_release"; exit 1; } | |
| - name: Create GitHub Release (draft) | |
| uses: softprops/action-gh-release@v3 | |
| with: | |
| draft: true | |
| name: ${{ github.ref_name }} | |
| tag_name: ${{ github.ref_name }} | |
| files: dist_release/* | |
| token: ${{ secrets.GT_TOKEN }} | |
| fail_on_unmatched_files: true | |
| publish-new-formula: | |
| runs-on: ubuntu-latest | |
| needs: [ release ] | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| steps: | |
| - name: config git | |
| run: | | |
| git config --global user.email "${{ secrets.GIT_MAIL }}" | |
| git config --global user.name "${{ secrets.GIT_NAME }}" | |
| - name: Clone repo | |
| run: git clone https://github.com/nxtrace/homebrew-nexttrace.git | |
| - name: Exec script | |
| run: | | |
| set -Eeuo pipefail | |
| cd homebrew-nexttrace | |
| bash genFormula.sh | |
| - name: Git Push | |
| run: | | |
| set -Eeuo pipefail | |
| cd homebrew-nexttrace | |
| git add -A | |
| git commit -m 'Publish a new version with Formula' || true | |
| git remote set-url origin https://${{ secrets.GT_TOKEN }}@github.com/nxtrace/homebrew-nexttrace.git | |
| git push | |
| - run: echo "🍏 This job's status is ${{ job.status }}." |