__lmao_amend_later__ #9
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: Release | |
| permissions: | |
| contents: read | |
| on: | |
| push: | |
| branches: | |
| - main | |
| workflow_dispatch: | |
| jobs: | |
| build: | |
| name: Build binaries | |
| runs-on: ubuntu-latest | |
| strategy: | |
| matrix: | |
| include: | |
| - goos: linux | |
| goarch: amd64 | |
| cgo: 0 | |
| - goos: linux | |
| goarch: arm64 | |
| cgo: 0 | |
| - goos: linux | |
| goarch: 386 | |
| cgo: 0 | |
| - goos: linux | |
| goarch: arm | |
| goarm: "7" | |
| cgo: 0 | |
| - goos: linux | |
| goarch: mipsle | |
| gomips: softfloat | |
| cgo: 0 | |
| - goos: linux | |
| goarch: mips | |
| gomips: softfloat | |
| cgo: 0 | |
| - goos: linux | |
| goarch: mips64le | |
| gomips: softfloat | |
| cgo: 0 | |
| - goos: linux | |
| goarch: riscv64 | |
| cgo: 0 | |
| - goos: android | |
| goarch: arm64 | |
| cgo: 1 | |
| api: 21 | |
| - goos: android | |
| goarch: arm | |
| cgo: 1 | |
| api: 21 | |
| steps: | |
| - name: Check out code | |
| uses: actions/checkout@v6 | |
| - name: Set up Go | |
| uses: actions/setup-go@v6 | |
| with: | |
| go-version: "1.25.5" | |
| # Install Android NDK only for android rows | |
| - 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: Build | |
| env: | |
| GOOS: ${{ matrix.goos }} | |
| GOARCH: ${{ matrix.goarch }} | |
| GOMIPS: ${{ matrix.gomips }} | |
| GOARM: ${{ matrix.goarm }} | |
| CGO_ENABLED: ${{ matrix.cgo }} | |
| ANDROID_API: ${{ matrix.api }} | |
| ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }} | |
| VERSION: ${{ github.ref_name }} | |
| run: | | |
| echo "Building for $GOOS/$GOARCH${GOARM:+/arm$GOARM} (CGO_ENABLED=$CGO_ENABLED)" | |
| if [ "$GOOS" = "android" ]; then | |
| if [ -z "$ANDROID_NDK_HOME" ]; then | |
| echo "ANDROID_NDK_HOME is not set – did setup-ndk run?" | |
| exit 1 | |
| fi | |
| TOOLCHAIN_BIN="$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin" | |
| if [ "$GOARCH" = "arm64" ]; then | |
| export CC="$TOOLCHAIN_BIN/aarch64-linux-android${ANDROID_API}-clang" | |
| elif [ "$GOARCH" = "arm" ]; then | |
| export CC="$TOOLCHAIN_BIN/armv7a-linux-androideabi${ANDROID_API}-clang" | |
| else | |
| echo "Unsupported ANDROID GOARCH=$GOARCH" | |
| exit 1 | |
| fi | |
| echo "Using Android NDK CC=$CC" | |
| fi | |
| mkdir -p dist | |
| # Set extension for windows | |
| if [ "${GOOS}" = "windows" ]; then | |
| EXT=.exe | |
| else | |
| EXT= | |
| fi | |
| GOOS=$GOOS GOARCH=$GOARCH GOARM=$GOARM GOMIPS=$GOMIPS \ | |
| go build -ldflags "-s -w -checklinkname=0" -trimpath \ | |
| -o "dist/client-${GOOS}-${GOARCH}${EXT}" \ | |
| ./client | |
| GOOS=$GOOS GOARCH=$GOARCH GOARM=$GOARM GOMIPS=$GOMIPS \ | |
| go build -ldflags "-s -w -checklinkname=0" -trimpath \ | |
| -o "dist/server-${GOOS}-${GOARCH}${EXT}" \ | |
| ./server | |
| - name: Upload artifact | |
| uses: actions/upload-artifact@v6 | |
| with: | |
| name: good-turn-${{ matrix.goos }}-${{ matrix.goarch }} | |
| path: dist/** | |
| release: | |
| name: Create GitHub Release | |
| needs: build | |
| runs-on: ubuntu-latest | |
| outputs: | |
| should_release: ${{ steps.meta.outputs.should_release }} | |
| tag_name: ${{ steps.meta.outputs.tag_name }} | |
| permissions: | |
| contents: write | |
| steps: | |
| - name: Check out code | |
| uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| fetch-tags: true | |
| - name: Download build artifacts | |
| uses: actions/download-artifact@v7 | |
| with: | |
| path: dist | |
| - name: Prepare release metadata | |
| id: meta | |
| run: | | |
| LATEST_TAG="$(git tag -l | grep -E '^(v)?[0-9]+\.[0-9]+\.[0-9]+$' | sort -V | tail -n 1 || true)" | |
| PREFIX="" | |
| BASE_VERSION="$LATEST_TAG" | |
| if [ -z "$LATEST_TAG" ]; then | |
| BASE_VERSION="0.0.0" | |
| elif [ "${LATEST_TAG#v}" != "$LATEST_TAG" ]; then | |
| PREFIX="v" | |
| BASE_VERSION="${LATEST_TAG#v}" | |
| fi | |
| IFS=. read -r MAJOR MINOR PATCH <<< "$BASE_VERSION" | |
| if [ -n "$LATEST_TAG" ]; then | |
| RANGE="$LATEST_TAG..HEAD" | |
| else | |
| RANGE="HEAD" | |
| fi | |
| COMMITS="$(git log --no-merges --format='%s' "$RANGE")" | |
| BUMP="" | |
| if printf '%s\n' "$COMMITS" | grep -Eiq '^break([(:! ]|$)'; then | |
| BUMP="major" | |
| MAJOR=$((MAJOR + 1)) | |
| MINOR=0 | |
| PATCH=0 | |
| elif printf '%s\n' "$COMMITS" | grep -Eiq '^feat([(:! ]|$)'; then | |
| BUMP="minor" | |
| MINOR=$((MINOR + 1)) | |
| PATCH=0 | |
| elif printf '%s\n' "$COMMITS" | grep -Eiq '^fix([(:! ]|$)'; then | |
| BUMP="patch" | |
| PATCH=$((PATCH + 1)) | |
| fi | |
| NEXT_VERSION="${MAJOR}.${MINOR}.${PATCH}" | |
| NEXT_TAG="${PREFIX}${NEXT_VERSION}" | |
| { | |
| echo "previous_tag=$LATEST_TAG" | |
| echo "range=$RANGE" | |
| echo "bump=$BUMP" | |
| echo "should_release=$([ -n "$BUMP" ] && echo true || echo false)" | |
| echo "tag_name=$NEXT_TAG" | |
| echo "release_name=$NEXT_TAG" | |
| echo "body_path=release-notes.md" | |
| } >> "$GITHUB_OUTPUT" | |
| - name: Generate release notes from commit messages | |
| id: notes | |
| if: steps.meta.outputs.should_release == 'true' | |
| env: | |
| PREVIOUS_TAG: ${{ steps.meta.outputs.previous_tag }} | |
| NEXT_TAG: ${{ steps.meta.outputs.tag_name }} | |
| BUMP: ${{ steps.meta.outputs.bump }} | |
| RANGE: ${{ steps.meta.outputs.range }} | |
| run: | | |
| strip_prefix() { | |
| sed -E 's/^(feat|fix|break)([(!:]|[[:space:]])+[[:space:]]*//I' | |
| } | |
| FEATURES="$(git log --no-merges --format='%s (%h)' "$RANGE" | grep -Ei '^feat([(:! ]|$)' | strip_prefix | LC_ALL=C sort -f || true)" | |
| FIXES="$(git log --no-merges --format='%s (%h)' "$RANGE" | grep -Ei '^fix([(:! ]|$)' | strip_prefix | LC_ALL=C sort -f || true)" | |
| BREAKING="$(git log --no-merges --format='%s (%h)' "$RANGE" | grep -Ei '^break([(:! ]|$)' | strip_prefix | LC_ALL=C sort -f || true)" | |
| { | |
| echo "body_path=release-notes.md" | |
| } >> "$GITHUB_OUTPUT" | |
| { | |
| if [ -n "$BREAKING" ]; then | |
| echo "### Breaking Changes" | |
| echo | |
| printf '%s\n' "$BREAKING" | sed 's/^/- /' | |
| echo | |
| fi | |
| if [ -n "$FEATURES" ]; then | |
| echo "### Features" | |
| echo | |
| printf '%s\n' "$FEATURES" | sed 's/^/- /' | |
| echo | |
| fi | |
| if [ -n "$FIXES" ]; then | |
| echo "### Bug Fixes" | |
| echo | |
| printf '%s\n' "$FIXES" | sed 's/^/- /' | |
| echo | |
| fi | |
| } > release-notes.md | |
| - name: Create Release | |
| if: steps.meta.outputs.should_release == 'true' | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| # upload every file in dist/ including nested files | |
| files: | | |
| dist/** | |
| tag_name: ${{ steps.meta.outputs.tag_name }} | |
| target_commitish: ${{ github.sha }} | |
| name: ${{ steps.meta.outputs.release_name }} | |
| body_path: ${{ steps.meta.outputs.body_path }} | |
| overwrite_files: true | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Skip release when no semantic commit is found | |
| if: steps.meta.outputs.should_release != 'true' | |
| run: | | |
| echo "No new semantic release created." | |
| echo "Add a commit starting with break, feat, or fix after the latest tag." | |
| docker: | |
| name: Publish Docker image | |
| needs: release | |
| if: needs.release.outputs.should_release == 'true' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| packages: write | |
| steps: | |
| - name: Check out code | |
| uses: actions/checkout@v6 | |
| - name: Set up QEMU | |
| uses: docker/setup-qemu-action@v4 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v4 | |
| - name: Prepare image name | |
| id: image | |
| env: | |
| REPOSITORY: ${{ github.repository }} | |
| run: | | |
| echo "name=ghcr.io/$(echo "$REPOSITORY" | tr '[:upper:]' '[:lower:]')" >> "$GITHUB_OUTPUT" | |
| - name: Log in to GitHub Container Registry | |
| uses: docker/login-action@v4 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Extract Docker metadata | |
| id: meta | |
| uses: docker/metadata-action@v6 | |
| with: | |
| images: ${{ steps.image.outputs.name }} | |
| tags: | | |
| type=raw,value=latest | |
| type=raw,value=${{ needs.release.outputs.tag_name }} | |
| - name: Build and push Docker image | |
| uses: docker/build-push-action@v7 | |
| with: | |
| context: . | |
| file: ./Dockerfile | |
| platforms: linux/amd64,linux/arm64 | |
| push: true | |
| tags: ${{ steps.meta.outputs.tags }} | |
| labels: ${{ steps.meta.outputs.labels }} |