Files
ecs/.github/workflows/build_binary.yaml
2025-07-17 08:56:12 +00:00

480 lines
18 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: Build and Release
on:
workflow_dispatch:
tags:
- "v*.*.*"
jobs:
build:
name: Release Check And Build
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Get latest tag
id: tag
run: |
TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.1.0")
echo "tag=$TAG" >> $GITHUB_OUTPUT
echo "version=${TAG#v}" >> $GITHUB_OUTPUT
- name: Generate changelog
id: changelog
run: |
TAG="${{ steps.tag.outputs.tag }}"
PREV_TAG=$(git describe --tags --abbrev=0 "$TAG^" 2>/dev/null || echo "")
if [ -z "$PREV_TAG" ]; then
CHANGELOG=$(git log --oneline --pretty=format:"* %H %s" "$TAG" | head -20)
else
CHANGELOG=$(git log --oneline --pretty=format:"* %H %s" "$PREV_TAG..$TAG")
fi
FULL_CHANGELOG="## Changelog"$'\n'"$CHANGELOG"
echo "$FULL_CHANGELOG" > changelog.txt
echo "changelog<<EOF" >> $GITHUB_OUTPUT
echo "$FULL_CHANGELOG" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
- name: Create release if not exists
run: |
TAG="${{ steps.tag.outputs.tag }}"
RELEASE_EXISTS=$(curl -s -H "Authorization: Bearer ${{ secrets.GHT }}" "https://api.github.com/repos/${{ github.repository }}/releases/tags/$TAG" | jq -r '.id // empty')
if [ -z "$RELEASE_EXISTS" ]; then
echo "Creating release for tag $TAG"
CHANGELOG_BODY=$(cat changelog.txt | jq -Rs .)
RELEASE_RESPONSE=$(curl -s -X POST -H "Authorization: Bearer ${{ secrets.GHT }}" \
-H "Content-Type: application/json" \
-d "{\"tag_name\":\"$TAG\",\"name\":\"$TAG\",\"body\":$CHANGELOG_BODY,\"draft\":false,\"prerelease\":false}" \
"https://api.github.com/repos/${{ github.repository }}/releases")
echo "Release created: $(echo $RELEASE_RESPONSE | jq -r '.id')"
else
echo "Release already exists for tag $TAG"
fi
- name: Delete existing release assets
run: |
TAG="${{ steps.tag.outputs.tag }}"
RELEASE_ID=$(curl -s -H "Authorization: Bearer ${{ secrets.GHT }}" "https://api.github.com/repos/${{ github.repository }}/releases/tags/$TAG" | jq -r '.id')
if [ "$RELEASE_ID" != "null" ]; then
echo "Deleting existing release assets..."
ASSETS=$(curl -s -H "Accept: application/vnd.github.v3+json" "https://api.github.com/repos/${{ github.repository }}/releases/$RELEASE_ID/assets" | jq -r '.[] | .id')
for asset in $ASSETS; do
echo "Deleting asset with ID: $asset"
curl -s -X DELETE -H "Authorization: Bearer ${{ secrets.GHT }}" "https://api.github.com/repos/${{ github.repository }}/releases/assets/$asset"
done
sleep 30
fi
release-binary:
name: Release Go Binary
needs: build
strategy:
fail-fast: false
matrix:
include:
- goos: linux
goarch: amd64
cgo_enabled: "1"
cc: x86_64-linux-gnu-gcc
cflags: "-O2 -static -fno-stack-protector"
ldflags: "-extldflags=-static -s -w"
packages: "build-essential gcc"
runner: ubuntu-latest
- goos: linux
goarch: 386
cgo_enabled: "1"
cc: x86_64-linux-gnu-gcc
cflags: "-m32 -O1 -march=i686 -mtune=generic -fno-stack-protector"
ldflags: "-extldflags=-static -s -w"
packages: "build-essential gcc-multilib"
runner: ubuntu-latest
- goos: linux
goarch: arm64
cgo_enabled: "1"
cc: aarch64-linux-gnu-gcc
cflags: "-O1 -fno-stack-protector"
ldflags: "-extldflags=-static -s -w"
packages: "build-essential gcc-aarch64-linux-gnu"
runner: ubuntu-latest
- goos: linux
goarch: riscv64
cgo_enabled: "1"
cc: riscv64-linux-gnu-gcc
cflags: "-O1 -fno-stack-protector"
ldflags: "-extldflags=-static -s -w"
packages: "build-essential gcc-riscv64-linux-gnu"
runner: ubuntu-latest
- goos: linux
goarch: mips64
cgo_enabled: "1"
cc: mips64-linux-gnuabi64-gcc
cflags: "-O1 -fno-stack-protector"
ldflags: "-extldflags=-static -s -w"
packages: "build-essential gcc-mips64-linux-gnuabi64"
runner: ubuntu-latest
- goos: linux
goarch: mips64le
cgo_enabled: "1"
cc: mips64el-linux-gnuabi64-gcc
cflags: "-O1 -fno-stack-protector"
ldflags: "-extldflags=-static -s -w"
packages: "build-essential gcc-mips64el-linux-gnuabi64"
runner: ubuntu-latest
- goos: linux
goarch: ppc64le
cgo_enabled: "1"
cc: powerpc64le-linux-gnu-gcc
cflags: "-O1 -fno-stack-protector"
ldflags: "-extldflags=-static -s -w"
packages: "build-essential gcc-powerpc64le-linux-gnu"
runner: ubuntu-latest
- goos: windows
goarch: amd64
cgo_enabled: "1"
cc: x86_64-w64-mingw32-gcc
cflags: "-O2 -static-libgcc -static-libstdc++"
ldflags: "-extldflags=-static -s -w"
packages: "build-essential gcc-mingw-w64-x86-64"
runner: ubuntu-latest
- goos: windows
goarch: 386
cgo_enabled: "1"
cc: i686-w64-mingw32-gcc
cflags: "-O2 -static-libgcc -static-libstdc++"
ldflags: "-extldflags=-static -s -w"
packages: "build-essential gcc-mingw-w64-i686"
runner: ubuntu-latest
- goos: darwin
goarch: amd64
cgo_enabled: "1"
cc: "clang --target=x86_64-apple-darwin"
cflags: "-O2 -arch x86_64 -mmacosx-version-min=10.12"
ldflags: "-s -w"
runner: ubuntu-latest
requires_osxcross: true
- goos: darwin
goarch: arm64
cgo_enabled: "1"
cc: "clang --target=aarch64-apple-darwin"
cflags: "-O2 -arch arm64 -mmacosx-version-min=11.0"
ldflags: "-s -w"
runner: ubuntu-latest
requires_osxcross: true
- goos: linux
goarch: arm
cgo_enabled: "0"
ldflags: "-s -w"
runner: ubuntu-latest
- goos: linux
goarch: s390x
cgo_enabled: "0"
ldflags: "-s -w"
runner: ubuntu-latest
- goos: linux
goarch: mips
cgo_enabled: "0"
ldflags: "-s -w"
runner: ubuntu-latest
- goos: linux
goarch: mipsle
cgo_enabled: "0"
ldflags: "-s -w"
runner: ubuntu-latest
- goos: linux
goarch: ppc64
cgo_enabled: "0"
ldflags: "-s -w"
runner: ubuntu-latest
- goos: windows
goarch: arm64
cgo_enabled: "0"
ldflags: "-s -w"
runner: ubuntu-latest
- goos: freebsd
goarch: amd64
cgo_enabled: "0"
ldflags: "-s -w"
runner: ubuntu-latest
- goos: freebsd
goarch: arm64
cgo_enabled: "0"
ldflags: "-s -w"
runner: ubuntu-latest
runs-on: ${{ matrix.runner }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: 1.23.4
- name: Configure Git for Private Modules
run: |
git config --global url."https://${{ secrets.GHT }}@github.com/".insteadOf "https://github.com/"
git config --global url."git@github.com:".insteadOf "https://github.com/"
env:
GITHUB_TOKEN: ${{ secrets.GHT }}
# 只在非macOS环境安装交叉编译工具
- name: Install cross-compilation tools
if: matrix.runner != 'macos-latest'
run: |
sudo apt-get update || true
case "${{ matrix.goos }}-${{ matrix.goarch }}" in
linux-386)
sudo apt-get install -y build-essential gcc-multilib g++-multilib ;;
linux-arm64)
sudo apt-get install -y build-essential gcc-aarch64-linux-gnu ;;
linux-riscv64)
sudo apt-get install -y build-essential gcc-riscv64-linux-gnu ;;
linux-mips64)
sudo apt-get install -y build-essential gcc-mips64-linux-gnuabi64 ;;
linux-mips64le)
sudo apt-get install -y build-essential gcc-mips64el-linux-gnuabi64 ;;
linux-ppc64le)
sudo apt-get install -y build-essential gcc-powerpc64le-linux-gnu ;;
windows-amd64|windows-386)
sudo apt-get install -y build-essential gcc-mingw-w64-x86-64 gcc-mingw-w64-i686 ;;
*)
sudo apt-get install -y build-essential || true ;;
esac
# 需要支持CGO的Darwin交叉编译需要安装osxcross
- name: Install osxcross for Darwin
if: matrix.requires_osxcross == true
run: |
git clone https://github.com/tpoechtrager/osxcross.git
cd osxcross
wget -nc https://github.com/joseluisq/macosx-sdks/releases/download/12.3/MacOSX12.3.sdk.tar.xz
mv MacOSX12.3.sdk.tar.xz tarballs/
UNATTENDED=yes OSX_VERSION_MIN=10.12 ./build.sh
echo "$PWD/target/bin" >> $GITHUB_PATH
echo "OSXCROSS_ROOT=$PWD" >> $GITHUB_ENV
- name: Get latest tag
id: tag
run: |
TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.1.0")
echo "tag=$TAG" >> $GITHUB_OUTPUT
echo "version=${TAG#v}" >> $GITHUB_OUTPUT
- name: Build Binary
run: |
go clean -modcache
export CGO_ENABLED=${{ matrix.cgo_enabled }}
export GOOS=${{ matrix.goos }}
export GOARCH=${{ matrix.goarch }}
if [[ -n "${{ matrix.goarm }}" ]]; then
export GOARM=${{ matrix.goarm }}
fi
if [[ -n "${{ matrix.gomips }}" ]]; then
export GOMIPS=${{ matrix.gomips }}
fi
if [[ "${{ matrix.cgo_enabled }}" == "1" && "${{ matrix.goos }}" == "darwin" ]]; then
if [[ "${{ matrix.goarch }}" == "amd64" ]]; then
export CC="x86_64-apple-darwin21.4-clang"
export CXX="x86_64-apple-darwin21.4-clang++"
elif [[ "${{ matrix.goarch }}" == "arm64" ]]; then
export CC="aarch64-apple-darwin21.4-clang"
export CXX="aarch64-apple-darwin21.4-clang++"
fi
export CGO_CFLAGS="${{ matrix.cflags }}"
export CGO_LDFLAGS="${{ matrix.ldflags }}"
export OSXCROSS_ROOT="${OSXCROSS_ROOT}"
elif [[ "${{ matrix.cgo_enabled }}" == "1" && "${{ matrix.runner }}" != "macos-latest" ]]; then
export CC="${{ matrix.cc }}"
export CGO_CFLAGS="${{ matrix.cflags }}"
if [[ "${{ matrix.goos }}" == "windows" ]]; then
export CGO_LDFLAGS="-static-libgcc -static-libstdc++"
fi
fi
echo "CGO Configuration:"
echo "CGO_ENABLED=$CGO_ENABLED"
echo "GOOS=$GOOS"
echo "GOARCH=$GOARCH"
echo "CC=$CC"
echo "CGO_CFLAGS=$CGO_CFLAGS"
echo "CGO_LDFLAGS=$CGO_LDFLAGS"
if [[ "${{ matrix.cgo_enabled }}" == "1" ]]; then
echo "Testing compiler..."
echo 'int main() { return 0; }' > test.c
$CC $CGO_CFLAGS test.c -o test || (echo "Compiler test failed" && exit 1)
rm -f test.c test
echo "Compiler test passed"
fi
go mod download
go mod tidy -v
mkdir -p bin
BINARY_NAME="goecs"
if [[ "${{ matrix.goos }}" == "windows" ]]; then
BINARY_NAME="${BINARY_NAME}.exe"
fi
LDFLAGS="-s -w -X main.version=${{ steps.tag.outputs.version }} -X main.arch=${{ matrix.goarch }}"
if [[ "${{ matrix.cgo_enabled }}" == "1" ]]; then
LDFLAGS="${LDFLAGS} -checklinkname=0 ${{ matrix.ldflags }}"
echo "Building $BINARY_NAME for ${{ matrix.goos }}/${{ matrix.goarch }} with CGO"
echo "Final build command: CGO_ENABLED=$CGO_ENABLED GOOS=$GOOS GOARCH=$GOARCH CC=$CC go build"
env CGO_ENABLED=$CGO_ENABLED GOOS=$GOOS GOARCH=$GOARCH CC="$CC" CGO_CFLAGS="$CGO_CFLAGS" CGO_LDFLAGS="$CGO_LDFLAGS" \
go build -o bin/$BINARY_NAME -v -ldflags="$LDFLAGS" -trimpath ./
else
LDFLAGS="${LDFLAGS} -checklinkname=0 ${{ matrix.ldflags }}"
echo "Building $BINARY_NAME for ${{ matrix.goos }}/${{ matrix.goarch }} without CGO"
env CGO_ENABLED=0 GOOS=$GOOS GOARCH=$GOARCH \
go build -o bin/$BINARY_NAME -v -ldflags="$LDFLAGS" -trimpath ./
fi
if [[ -f "bin/$BINARY_NAME" ]]; then
echo "Successfully built bin/$BINARY_NAME"
ls -la bin/$BINARY_NAME
else
echo "Build failed for ${{ matrix.goos }}/${{ matrix.goarch }}"
exit 1
fi
- name: Create ZIP archive
run: |
cd bin
BINARY_NAME="goecs"
if [[ "${{ matrix.goos }}" == "windows" ]]; then
BINARY_NAME="${BINARY_NAME}.exe"
fi
ZIP_NAME="goecs_${{ matrix.goos }}_${{ matrix.goarch }}"
if [[ -n "${{ matrix.goarm }}" ]]; then
ZIP_NAME="${ZIP_NAME}v${{ matrix.goarm }}"
fi
if [[ -n "${{ matrix.gomips }}" ]]; then
ZIP_NAME="${ZIP_NAME}_${{ matrix.gomips }}"
fi
ZIP_NAME="${ZIP_NAME}.zip"
zip "$ZIP_NAME" "$BINARY_NAME"
echo "Created $ZIP_NAME"
ls -la "$ZIP_NAME"
- name: Upload to Release
run: |
TAG="${{ steps.tag.outputs.tag }}"
RELEASE_ID=$(curl -s -H "Authorization: Bearer ${{ secrets.GHT }}" "https://api.github.com/repos/${{ github.repository }}/releases/tags/$TAG" | jq -r '.id')
cd bin
for file in *.zip; do
if [[ -f "$file" ]]; then
echo "Uploading $file to release..."
curl -s -H "Authorization: Bearer ${{ secrets.GHT }}" \
-H "Content-Type: application/zip" \
--data-binary @"$file" \
"https://uploads.github.com/repos/${{ github.repository }}/releases/$RELEASE_ID/assets?name=$file"
fi
done
checksums:
name: Generate Checksums
runs-on: ubuntu-latest
needs: release-binary
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Get latest tag
id: tag
run: |
TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.1.0")
echo "tag=$TAG" >> $GITHUB_OUTPUT
- name: Download release assets
run: |
TAG="${{ steps.tag.outputs.tag }}"
RELEASE_ID=$(curl -s -H "Authorization: Bearer ${{ secrets.GHT }}" "https://api.github.com/repos/${{ github.repository }}/releases/tags/$TAG" | jq -r '.id')
mkdir -p assets
ASSETS=$(curl -s -H "Accept: application/vnd.github.v3+json" "https://api.github.com/repos/${{ github.repository }}/releases/$RELEASE_ID/assets")
echo "$ASSETS" | jq -r '.[] | select(.name | endswith(".zip")) | .browser_download_url' | while read url; do
filename=$(basename "$url")
echo "Downloading $filename..."
curl -L -H "Authorization: Bearer ${{ secrets.GHT }}" "$url" -o "assets/$filename"
done
- name: Generate checksums
run: |
cd assets
sha256sum *.zip > checksums.txt
if [[ -f "../goecs.sh" ]]; then
sha256sum ../goecs.sh >> checksums.txt
fi
cat checksums.txt
- name: Upload checksums
run: |
TAG="${{ steps.tag.outputs.tag }}"
RELEASE_ID=$(curl -s -H "Authorization: Bearer ${{ secrets.GHT }}" "https://api.github.com/repos/${{ github.repository }}/releases/tags/$TAG" | jq -r '.id')
curl -s -H "Authorization: Bearer ${{ secrets.GHT }}" \
-H "Content-Type: text/plain" \
--data-binary @assets/checksums.txt \
"https://uploads.github.com/repos/${{ github.repository }}/releases/$RELEASE_ID/assets?name=checksums.txt"
update-script:
name: Update Script Version
runs-on: ubuntu-latest
needs: checksums
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Get latest tag
id: tag
run: |
TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.1.0")
echo "tag=$TAG" >> $GITHUB_OUTPUT
echo "version=${TAG#v}" >> $GITHUB_OUTPUT
- name: Update goecs.sh version
run: |
VERSION="${{ steps.tag.outputs.version }}"
BRANCH="master"
git config --global user.name "github-actions[bot]"
git config --global user.email "github-actions[bot]@users.noreply.github.com"
git config --global --unset url."git@github.com:".insteadOf || true
git fetch origin $BRANCH
git checkout $BRANCH
if [ -f "goecs.sh" ]; then
sed -i "s/\(_yellow \"Unable to get version info, using default version \).*\(\".*\)/\1$VERSION\2/" "goecs.sh"
sed -i "s/\(ECS_VERSION=\"\).*\(\"\)/\1$VERSION\2/" "goecs.sh"
if ! git diff --quiet "goecs.sh"; then
git add "goecs.sh"
git commit -m "chore: update ECS_VERSION to $VERSION in goecs.sh"
git push origin $BRANCH
echo "Updated goecs.sh with version $VERSION"
else
echo "No changes needed in goecs.sh"
fi
else
echo "goecs.sh not found, skipping version update"
fi
env:
GITHUB_TOKEN: ${{ secrets.GHT }}