Skip to content

v0.11.0-beta.4

v0.11.0-beta.4 #9

Workflow file for this run

name: Release Build
on:
release:
types: [published]
workflow_dispatch:
inputs:
version:
description: 'Version to build (e.g., v0.11.0-beta.4)'
required: true
default: 'v0.11.0-beta.4'
permissions:
contents: read
jobs:
# Matrix jobs cannot expose job outputs; docker/release text need a stable VERSION from one job.
resolve-version:
name: Resolve version
runs-on: ubuntu-latest
outputs:
version: ${{ steps.version.outputs.VERSION }}
steps:
- name: Set version from release or workflow input
id: version
run: |
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
echo "VERSION=${{ github.event.inputs.version }}" >> $GITHUB_OUTPUT
else
echo "VERSION=${{ github.event.release.tag_name }}" >> $GITHUB_OUTPUT
fi
build:
name: Build Release Binaries
needs: [resolve-version]
runs-on: ubuntu-latest
env:
# Static cross-compiled binaries (pure Go SQLite driver); matches Dockerfile and local release scripts.
CGO_ENABLED: "0"
strategy:
matrix:
include:
# Linux
- goos: linux
goarch: amd64
platform: linux-amd64
# linux/arm64: also use on Termux (Android). GOOS=linux + CGO_ENABLED=0 static ELF is the usual
# portable choice; GOOS=android cross-builds often require CGO/NDK and are a poor fit for CI.
- goos: linux
goarch: arm64
platform: linux-arm64
# Windows
- goos: windows
goarch: amd64
platform: windows-amd64
ext: .exe
# macOS
- goos: darwin
goarch: amd64
platform: darwin-amd64
- goos: darwin
goarch: arm64
platform: darwin-arm64
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
- name: Set up Go
uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
with:
go-version: '1.25.9'
- name: Get build metadata
id: metadata
run: |
echo "BUILD_TIME=$(date -u +"%Y-%m-%dT%H:%M:%SZ")" >> $GITHUB_OUTPUT
echo "GIT_COMMIT=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
- name: Build client
env:
GOOS: ${{ matrix.goos }}
GOARCH: ${{ matrix.goarch }}
run: |
go build \
-ldflags "-X github.com/Cod-e-Codes/marchat/shared.ClientVersion=${{ needs.resolve-version.outputs.version }} \
-X github.com/Cod-e-Codes/marchat/shared.ServerVersion=${{ needs.resolve-version.outputs.version }} \
-X github.com/Cod-e-Codes/marchat/shared.BuildTime=${{ steps.metadata.outputs.BUILD_TIME }} \
-X github.com/Cod-e-Codes/marchat/shared.GitCommit=${{ steps.metadata.outputs.GIT_COMMIT }}" \
-o "build/marchat-client-${{ matrix.platform }}${{ matrix.ext }}" \
./client
- name: Build server
env:
GOOS: ${{ matrix.goos }}
GOARCH: ${{ matrix.goarch }}
run: |
go build \
-ldflags "-X github.com/Cod-e-Codes/marchat/shared.ClientVersion=${{ needs.resolve-version.outputs.version }} \
-X github.com/Cod-e-Codes/marchat/shared.ServerVersion=${{ needs.resolve-version.outputs.version }} \
-X github.com/Cod-e-Codes/marchat/shared.BuildTime=${{ steps.metadata.outputs.BUILD_TIME }} \
-X github.com/Cod-e-Codes/marchat/shared.GitCommit=${{ steps.metadata.outputs.GIT_COMMIT }}" \
-o "build/marchat-server-${{ matrix.platform }}${{ matrix.ext }}" \
./cmd/server
- name: Create release archive
run: |
cd build
zip "../marchat-${{ needs.resolve-version.outputs.version }}-${{ matrix.platform }}.zip" \
"marchat-client-${{ matrix.platform }}${{ matrix.ext }}" \
"marchat-server-${{ matrix.platform }}${{ matrix.ext }}"
- name: Upload release artifact
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: marchat-${{ matrix.platform }}
path: |
marchat-${{ needs.resolve-version.outputs.version }}-${{ matrix.platform }}.zip
upload-assets:
name: Upload GitHub Release Assets
runs-on: ubuntu-latest
if: ${{ github.event_name != 'workflow_dispatch' }}
needs: [build]
permissions:
contents: write
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Download all artifacts
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
path: release-artifacts
# softprops/action-gh-release is still node20 in action.yml; gh CLI avoids the forced-node24 annotation.
- name: Upload zips to GitHub Release
if: ${{ github.event_name != 'workflow_dispatch' }}
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -euo pipefail
TAG="${{ github.event.release.tag_name }}"
REPO="${{ github.repository }}"
mapfile -t zips < <(find release-artifacts -type f -name '*.zip' | sort)
if [ "${#zips[@]}" -eq 0 ]; then
echo "No .zip files under release-artifacts"
exit 1
fi
gh release upload "$TAG" "${zips[@]}" --clobber --repo "$REPO"
- name: Delete Uploaded Artifacts
if: ${{ github.event_name != 'workflow_dispatch' }}
uses: geekyeggo/delete-artifact@176a747ab7e287e3ff4787bf8a148716375ca118 # v6.0.0
with:
name: |
marchat-linux-amd64
marchat-linux-arm64
marchat-windows-amd64
marchat-darwin-amd64
marchat-darwin-arm64
docker:
name: Build and Push Docker Image
runs-on: ubuntu-latest
needs: [build, resolve-version]
permissions:
contents: write
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0
- name: Log in to Docker Hub
uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # v4.0.0
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PAT }}
- name: Get metadata
id: meta
run: |
echo "BUILD_TIME=$(date -u +"%Y-%m-%dT%H:%M:%SZ")" >> $GITHUB_OUTPUT
echo "GIT_COMMIT=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
- name: Build and push Docker image
uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294 # v7.0.0
with:
provenance: false
context: .
platforms: linux/amd64,linux/arm64
push: true
build-args: |
VERSION=${{ needs.resolve-version.outputs.version }}
BUILD_TIME=${{ steps.meta.outputs.BUILD_TIME }}
GIT_COMMIT=${{ steps.meta.outputs.GIT_COMMIT }}
tags: |
codecodesxyz/marchat:${{ needs.resolve-version.outputs.version }}
codecodesxyz/marchat:latest
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Append Docker image info to GitHub Release
if: ${{ github.event_name != 'workflow_dispatch' }}
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
VERSION: ${{ needs.resolve-version.outputs.version }}
run: |
set -euo pipefail
TAG="${{ github.event.release.tag_name }}"
REPO="${{ github.repository }}"
EXISTING="$(gh release view "$TAG" --repo "$REPO" --json body -q '(.body // "")')"
{
printf '%s\n\n' "$EXISTING"
printf '%s\n\n' '## Docker Image'
printf '%s\n\n' 'A multi-architecture Docker image (linux/amd64, linux/arm64) is available on Docker Hub:'
printf '%s\n' '```bash'
printf 'docker pull codecodesxyz/marchat:%s\n' "$VERSION"
printf '%s\n' '# or use latest tag'
printf '%s\n' 'docker pull codecodesxyz/marchat:latest'
printf '%s\n' '```'
} > /tmp/marchat-release-body.md
gh release edit "$TAG" --repo "$REPO" --notes-file /tmp/marchat-release-body.md