Repository navigation
v1.3.5 #19
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: Release Build | |
| on: | |
| release: | |
| types: [published] | |
| workflow_dispatch: | |
| inputs: | |
| version: | |
| description: 'Version to build (e.g., v1.3.5)' | |
| required: true | |
| default: 'v1.3.5' | |
| 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.13' | |
| - 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 | |
| # Pushes updated manifests to your tap, bucket, winget-pkgs fork (opens PR to Microsoft), and AUR. | |
| # Each step no-ops when its secret is unset. Requires PACKAGING_GITHUB_PAT for Git-hosted targets. | |
| publish-downstream-packages: | |
| name: Publish downstream package manifests | |
| runs-on: ubuntu-latest | |
| needs: [upload-assets] | |
| if: github.event_name == 'release' | |
| permissions: | |
| contents: read | |
| steps: | |
| - name: Checkout release tag | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| ref: ${{ github.event.release.tag_name }} | |
| fetch-depth: 1 | |
| - name: Render manifests from release zips | |
| env: | |
| RELEASE_TAG: ${{ github.event.release.tag_name }} | |
| GITHUB_REPOSITORY: ${{ github.repository }} | |
| run: | | |
| set -euo pipefail | |
| if [ -n "${{ github.event.release.published_at }}" ]; then | |
| export RELEASE_DATE_UTC="$(echo '${{ github.event.release.published_at }}' | cut -dT -f1)" | |
| fi | |
| chmod +x packaging/ci/render-release-manifests.sh | |
| packaging/ci/render-release-manifests.sh | |
| - name: Push Homebrew tap | |
| env: | |
| TOKEN: ${{ secrets.PACKAGING_GITHUB_PAT }} | |
| RELEASE_TAG: ${{ github.event.release.tag_name }} | |
| OWNER: ${{ github.repository_owner }} | |
| run: | | |
| set -euo pipefail | |
| if [ -z "${TOKEN:-}" ]; then echo "Skip Homebrew: PACKAGING_GITHUB_PAT unset"; exit 0; fi | |
| VER="${RELEASE_TAG#v}" | |
| DEFAULT="$(GH_TOKEN="${TOKEN}" gh api "repos/${OWNER}/homebrew-marchat" --jq .default_branch)" | |
| git clone --depth 1 "https://x-access-token:${TOKEN}@github.com/${OWNER}/homebrew-marchat.git" /tmp/homebrew-marchat | |
| cp packaging-out/marchat.rb /tmp/homebrew-marchat/Formula/marchat.rb | |
| cd /tmp/homebrew-marchat | |
| git config user.email "41898282+github-actions[bot]@users.noreply.github.com" | |
| git config user.name "github-actions[bot]" | |
| git add Formula/marchat.rb | |
| if git diff --cached --quiet; then echo "Homebrew: no changes"; exit 0; fi | |
| git commit -m "marchat ${VER}" | |
| git push origin "HEAD:${DEFAULT}" | |
| - name: Push Scoop bucket | |
| env: | |
| TOKEN: ${{ secrets.PACKAGING_GITHUB_PAT }} | |
| RELEASE_TAG: ${{ github.event.release.tag_name }} | |
| OWNER: ${{ github.repository_owner }} | |
| run: | | |
| set -euo pipefail | |
| if [ -z "${TOKEN:-}" ]; then echo "Skip Scoop: PACKAGING_GITHUB_PAT unset"; exit 0; fi | |
| VER="${RELEASE_TAG#v}" | |
| DEFAULT="$(GH_TOKEN="${TOKEN}" gh api "repos/${OWNER}/scoop-marchat" --jq .default_branch)" | |
| git clone --depth 1 "https://x-access-token:${TOKEN}@github.com/${OWNER}/scoop-marchat.git" /tmp/scoop-marchat | |
| cp packaging-out/marchat.json /tmp/scoop-marchat/bucket/marchat.json | |
| cd /tmp/scoop-marchat | |
| git config user.email "41898282+github-actions[bot]@users.noreply.github.com" | |
| git config user.name "github-actions[bot]" | |
| git add bucket/marchat.json | |
| if git diff --cached --quiet; then echo "Scoop: no changes"; exit 0; fi | |
| git commit -m "marchat ${VER}" | |
| git push origin "HEAD:${DEFAULT}" | |
| - name: Open winget-pkgs PR | |
| env: | |
| TOKEN: ${{ secrets.PACKAGING_GITHUB_PAT }} | |
| RELEASE_TAG: ${{ github.event.release.tag_name }} | |
| OWNER: ${{ github.repository_owner }} | |
| REPO_FULL: ${{ github.repository }} | |
| run: | | |
| set -euo pipefail | |
| if [ -z "${TOKEN:-}" ]; then echo "Skip winget: PACKAGING_GITHUB_PAT unset"; exit 0; fi | |
| VER="${RELEASE_TAG#v}" | |
| BRANCH="marchat-${VER}" | |
| BASE_BRANCH="$(GH_TOKEN="${TOKEN}" gh api repos/microsoft/winget-pkgs --jq .default_branch)" | |
| git clone --depth 1 "https://x-access-token:${TOKEN}@github.com/${OWNER}/winget-pkgs.git" /tmp/winget-pkgs | |
| cd /tmp/winget-pkgs | |
| git checkout -B "${BRANCH}" | |
| DEST="manifests/c/Cod-e-Codes/Marchat/${VER}" | |
| mkdir -p "${DEST}" | |
| cp "${GITHUB_WORKSPACE}/packaging-out/winget/"*.yaml "${DEST}/" | |
| git config user.email "41898282+github-actions[bot]@users.noreply.github.com" | |
| git config user.name "github-actions[bot]" | |
| git add "${DEST}" | |
| if git diff --cached --quiet; then echo "winget: no changes"; exit 0; fi | |
| git commit -m "Marchat: ${VER}" | |
| git push -u origin "${BRANCH}" --force | |
| EXISTING="$(GH_TOKEN="${TOKEN}" gh pr list --repo microsoft/winget-pkgs --head "${OWNER}:${BRANCH}" --json number --jq 'length')" | |
| if [ "${EXISTING}" != "0" ]; then echo "winget: PR already open for ${OWNER}:${BRANCH}"; exit 0; fi | |
| BODY_FILE="$(mktemp)" | |
| { | |
| echo "Automated PR for **${REPO_FULL}** release **${RELEASE_TAG}**." | |
| echo | |
| echo "Manifests match published release zips (workflow publish-downstream-packages)." | |
| } > "${BODY_FILE}" | |
| GH_TOKEN="${TOKEN}" gh pr create \ | |
| --repo microsoft/winget-pkgs \ | |
| --head "${OWNER}:${BRANCH}" \ | |
| --base "${BASE_BRANCH}" \ | |
| --title "Marchat: version ${VER}" \ | |
| --body-file "${BODY_FILE}" | |
| - name: Push AUR package | |
| env: | |
| AUR_SSH_PRIVATE_KEY: ${{ secrets.AUR_SSH_PRIVATE_KEY }} | |
| RELEASE_TAG: ${{ github.event.release.tag_name }} | |
| run: | | |
| set -euo pipefail | |
| if [ -z "${AUR_SSH_PRIVATE_KEY:-}" ]; then echo "Skip AUR: AUR_SSH_PRIVATE_KEY unset"; exit 0; fi | |
| VER="${RELEASE_TAG#v}" | |
| mkdir -p ~/.ssh | |
| chmod 700 ~/.ssh | |
| printf '%s\n' "${AUR_SSH_PRIVATE_KEY}" > ~/.ssh/aur_marchat_ci | |
| chmod 600 ~/.ssh/aur_marchat_ci | |
| ssh-keyscan -H aur.archlinux.org >> ~/.ssh/known_hosts 2>/dev/null || true | |
| export GIT_SSH_COMMAND="ssh -i ~/.ssh/aur_marchat_ci -o IdentitiesOnly=yes -o StrictHostKeyChecking=accept-new" | |
| # Clone over HTTPS (anonymous read). SSH is only required for push and would fail clone if the key is wrong/unregistered. | |
| git clone https://aur.archlinux.org/marchat-bin.git /tmp/marchat-aur | |
| git -C /tmp/marchat-aur remote set-url origin ssh://aur@aur.archlinux.org/marchat-bin.git | |
| cp "${GITHUB_WORKSPACE}/packaging-out/aur/PKGBUILD" /tmp/marchat-aur/PKGBUILD | |
| cp "${GITHUB_WORKSPACE}/packaging-out/aur/.SRCINFO" /tmp/marchat-aur/.SRCINFO | |
| cd /tmp/marchat-aur | |
| git config user.email "41898282+github-actions[bot]@users.noreply.github.com" | |
| git config user.name "github-actions[bot]" | |
| git add PKGBUILD .SRCINFO | |
| if git diff --cached --quiet; then echo "AUR: no changes"; exit 0; fi | |
| git commit -m "release ${VER}" | |
| git push origin HEAD |