Skip to content

Build & Publish Binary Release (Auto-versioned) #2

Build & Publish Binary Release (Auto-versioned)

Build & Publish Binary Release (Auto-versioned) #2

Workflow file for this run

name: "Build & Publish Server Release (Auto-versioned)"
on:
push:
tags:
- "v*"
workflow_dispatch:
inputs:
tag:
description: "Release Tag (e.g., v2.0.1)"
required: true
type: string
permissions:
contents: write
jobs:
prepare-release:
runs-on: ubuntu-latest
outputs:
version: ${{ steps.meta.outputs.version }}
tag: ${{ steps.meta.outputs.tag }}
ref: ${{ steps.meta.outputs.ref }}
notes: ${{ steps.changelog.outputs.notes }}
steps:
- name: Resolve release metadata
id: meta
shell: bash
run: |
set -euo pipefail
if [[ "${{ github.event_name }}" == "push" ]]; then
TAG_NAME="${GITHUB_REF_NAME}"
else
TAG_NAME="${{ github.event.inputs.tag }}"
fi
if [[ -z "$TAG_NAME" ]]; then
echo "::error::Release tag is required."
exit 1
fi
VERSION="${TAG_NAME#v}"
echo "tag=$TAG_NAME" >> "$GITHUB_OUTPUT"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
echo "ref=$TAG_NAME" >> "$GITHUB_OUTPUT"
- uses: actions/checkout@v4
with:
ref: ${{ steps.meta.outputs.ref }}
fetch-depth: 0
- name: Extract release notes
id: changelog
shell: bash
run: |
set -euo pipefail
VERSION="${{ steps.meta.outputs.version }}"
NOTES="$(awk '/^## \['"${VERSION}"'\]/{flag=1; next} /^## \[/{flag=0} flag' CHANGELOG.md)"
if [[ -z "$NOTES" ]]; then
echo "::error::No changelog entry found for version ${VERSION}."
exit 1
fi
{
echo "notes<<EOF"
printf '%s\n' "$NOTES"
echo "EOF"
} >> "$GITHUB_OUTPUT"
build-server:
needs: prepare-release
strategy:
fail-fast: false
matrix:
include:
- platform: macos-latest
target: aarch64-apple-darwin
artifact_suffix: ""
- platform: macos-latest
target: x86_64-apple-darwin
artifact_suffix: ""
- platform: ubuntu-22.04
target: x86_64-unknown-linux-gnu
artifact_suffix: ""
- platform: windows-latest
target: x86_64-pc-windows-msvc
artifact_suffix: ".exe"
runs-on: ${{ matrix.platform }}
defaults:
run:
shell: bash
working-directory: server
steps:
- uses: actions/checkout@v4
with:
ref: ${{ needs.prepare-release.outputs.ref }}
fetch-depth: 0
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
toolchain: 1.88.0
targets: ${{ matrix.target }}
- name: Cache Rust build
uses: swatinem/rust-cache@v2
with:
workspaces: "./server -> target"
- name: Build release binary
run: cargo build --locked --release --target "${{ matrix.target }}"
- name: Stage release artifact
run: |
set -euo pipefail
VERSION="${{ needs.prepare-release.outputs.version }}"
TARGET="${{ matrix.target }}"
EXTENSION="${{ matrix.artifact_suffix }}"
OUTPUT_DIR="../release-artifacts/${TARGET}"
mkdir -p "$OUTPUT_DIR"
cp "target/${TARGET}/release/ai-codelint${EXTENSION}" "$OUTPUT_DIR/ai-codelint-${VERSION}-${TARGET}${EXTENSION}"
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: ai-codelint-${{ matrix.target }}
path: release-artifacts/${{ matrix.target }}/ai-codelint-${{ needs.prepare-release.outputs.version }}-${{ matrix.target }}${{ matrix.artifact_suffix }}
if-no-files-found: error
publish-release:
needs:
- prepare-release
- build-server
runs-on: ubuntu-latest
steps:
- name: Download release artifacts
uses: actions/download-artifact@v4
with:
path: release-artifacts
merge-multiple: true
- name: Write release notes
shell: bash
run: |
set -euo pipefail
printf '%s\n' "${{ needs.prepare-release.outputs.notes }}" > release-body.md
- name: Publish GitHub release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ needs.prepare-release.outputs.tag }}
name: AI CodeLint ${{ needs.prepare-release.outputs.version }}
body_path: release-body.md
prerelease: true
draft: true
files: release-artifacts/*
fail_on_unmatched_files: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}