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<> $GITHUB_OUTPUT echo "$FULL_CHANGELOG" >> $GITHUB_OUTPUT echo "EOF" >> $GITHUB_OUTPUT - name: Create or update release run: | TAG="${{ steps.tag.outputs.tag }}" CHANGELOG_BODY=$(cat changelog.txt | jq -Rs .) 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 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" else curl -s -X PATCH -H "Authorization: Bearer ${{ secrets.GHT }}" \ -H "Content-Type: application/json" \ -d "{\"body\":$CHANGELOG_BODY}" \ "https://api.github.com/repos/${{ github.repository }}/releases/$RELEASE_EXISTS" 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 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 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: windows goarch: arm64 cgo_enabled: "0" ldflags: "-extldflags=-static -s -w" packages: "build-essential" runner: ubuntu-latest - goos: darwin goarch: amd64 cgo_enabled: "0" ldflags: "-s -w" runner: macos-latest - goos: darwin goarch: arm64 cgo_enabled: "0" ldflags: "-s -w" runner: macos-latest - 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.24.5 - 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 }} - name: Install cross-compilation tools if: matrix.runner != 'macos-latest' run: | sudo apt-get update -qq 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 ;; esac - 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 -cache -modcache -testcache 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 if [[ "${{ matrix.cgo_enabled }}" == "1" ]]; then echo 'int main() { return 0; }' > test.c $CC $CGO_CFLAGS test.c -o test || exit 1 rm -f test.c test fi rm -rf vendor/ go mod download go mod tidy 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 }}" env CGO_ENABLED=1 GOOS=$GOOS GOARCH=$GOARCH CC="$CC" CGO_CFLAGS="$CGO_CFLAGS" CGO_LDFLAGS="$CGO_LDFLAGS" \ go build -a -o bin/$BINARY_NAME -ldflags="$LDFLAGS" -trimpath ./ else LDFLAGS="${LDFLAGS} -checklinkname=0 ${{ matrix.ldflags }}" env CGO_ENABLED=0 GOOS=$GOOS GOARCH=$GOARCH \ go build -o bin/$BINARY_NAME -ldflags="$LDFLAGS" -trimpath ./ fi [[ -f "bin/$BINARY_NAME" ]] || exit 1 - 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" - 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 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") 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 - 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 fi fi env: GITHUB_TOKEN: ${{ secrets.GHT }}