Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
177 changes: 177 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
name: Release

on:
push:
tags:
- 'v*'

permissions:
contents: write

env:
CARGO_TERM_COLOR: always
LLVM_SYS_140_PREFIX: /usr/lib/llvm-14

jobs:
build-linux-x86_64:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y libz3-dev llvm-14-dev libllvm14 libclang-14-dev libpolly-14-dev

- name: Setup Rust
uses: dtolnay/rust-toolchain@stable

- name: Cache cargo
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
flux-ftl/target
key: ${{ runner.os }}-cargo-release-${{ hashFiles('flux-ftl/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-release-

- name: Build release binaries
working-directory: flux-ftl
run: cargo build --release --verbose

- name: Extract version
id: version
run: echo "version=${GITHUB_REF_NAME#v}" >> "$GITHUB_OUTPUT"

- name: Package flux-ftl
run: |
mkdir -p dist
cp flux-ftl/target/release/flux-ftl dist/
cd dist
tar czf "flux-ftl-${{ steps.version.outputs.version }}-linux-x86_64.tar.gz" flux-ftl
sha256sum "flux-ftl-${{ steps.version.outputs.version }}-linux-x86_64.tar.gz" > "flux-ftl-${{ steps.version.outputs.version }}-linux-x86_64.tar.gz.sha256"
rm flux-ftl

- name: Package flux-mcp
run: |
cp flux-ftl/target/release/flux-mcp dist/
cd dist
tar czf "flux-mcp-${{ steps.version.outputs.version }}-linux-x86_64.tar.gz" flux-mcp
sha256sum "flux-mcp-${{ steps.version.outputs.version }}-linux-x86_64.tar.gz" > "flux-mcp-${{ steps.version.outputs.version }}-linux-x86_64.tar.gz.sha256"
rm flux-mcp

- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: linux-x86_64
path: dist/*
retention-days: 1

# TODO: aarch64 cross-compilation disabled — LLVM-14 + libz3 native deps
# make cross-compilation non-trivial. Revisit when GitHub provides
# native ARM64 runners with ubuntu-latest or when a suitable
# cross-compilation toolchain for these deps is established.
#
# build-linux-aarch64:
# runs-on: ubuntu-latest
# steps:
# - uses: actions/checkout@v4
#
# - name: Install system dependencies and cross tools
# run: |
# sudo apt-get update
# sudo dpkg --add-architecture arm64
# sudo apt-get install -y gcc-aarch64-linux-gnu
# # Cross-compiled LLVM-14 and z3 libs would be needed here
#
# - name: Setup Rust
# uses: dtolnay/rust-toolchain@stable
# with:
# targets: aarch64-unknown-linux-gnu
#
# - name: Build release binaries (aarch64)
# working-directory: flux-ftl
# env:
# CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc
# run: cargo build --release --target aarch64-unknown-linux-gnu
#
# - name: Extract version
# id: version
# run: echo "version=${GITHUB_REF_NAME#v}" >> "$GITHUB_OUTPUT"
#
# - name: Package binaries
# run: |
# mkdir -p dist
# cp flux-ftl/target/aarch64-unknown-linux-gnu/release/flux-ftl dist/
# cd dist && tar czf "flux-ftl-${version}-linux-aarch64.tar.gz" flux-ftl
# sha256sum *.tar.gz > checksums-aarch64.txt
#
# - name: Upload artifacts
# uses: actions/upload-artifact@v4
# with:
# name: linux-aarch64
# path: dist/*
# retention-days: 1

release:
needs: [build-linux-x86_64]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Download x86_64 artifacts
uses: actions/download-artifact@v4
with:
name: linux-x86_64
path: artifacts/

- name: Extract version
id: version
run: echo "version=${GITHUB_REF_NAME#v}" >> "$GITHUB_OUTPUT"

- name: Generate release body
id: body
run: |
FTL_SHA=$(cat artifacts/flux-ftl-${{ steps.version.outputs.version }}-linux-x86_64.tar.gz.sha256 | awk '{print $1}')
MCP_SHA=$(cat artifacts/flux-mcp-${{ steps.version.outputs.version }}-linux-x86_64.tar.gz.sha256 | awk '{print $1}')
cat > release-body.json <<ENDJSON
{
"version": "${{ steps.version.outputs.version }}",
"tag": "${GITHUB_REF_NAME}",
"binaries": [
{
"name": "flux-ftl-${{ steps.version.outputs.version }}-linux-x86_64.tar.gz",
"arch": "x86_64",
"os": "linux",
"sha256": "${FTL_SHA}"
},
{
"name": "flux-mcp-${{ steps.version.outputs.version }}-linux-x86_64.tar.gz",
"arch": "x86_64",
"os": "linux",
"sha256": "${MCP_SHA}"
}
]
}
ENDJSON
# Trim leading whitespace from heredoc indentation
sed -i 's/^ //' release-body.json
echo "json<<EOF" >> "$GITHUB_OUTPUT"
cat release-body.json >> "$GITHUB_OUTPUT"
echo "EOF" >> "$GITHUB_OUTPUT"

- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
name: "FLUX FTL ${{ github.ref_name }}"
body: |
```json
${{ steps.body.outputs.json }}
```
files: |
artifacts/flux-ftl-${{ steps.version.outputs.version }}-linux-x86_64.tar.gz
artifacts/flux-ftl-${{ steps.version.outputs.version }}-linux-x86_64.tar.gz.sha256
artifacts/flux-mcp-${{ steps.version.outputs.version }}-linux-x86_64.tar.gz
artifacts/flux-mcp-${{ steps.version.outputs.version }}-linux-x86_64.tar.gz.sha256
38 changes: 38 additions & 0 deletions scripts/release.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#!/usr/bin/env bash
set -euo pipefail

# Usage: ./scripts/release.sh <version>
# Example: ./scripts/release.sh 1.0.0
# Creates and pushes a git tag v<version>, triggering the release workflow.

VERSION="${1:-}"

if [ -z "$VERSION" ]; then
echo "Usage: $0 <version>"
echo "Example: $0 1.0.0"
exit 1
fi
Comment on lines +10 to +14

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

To prevent accidental malformed release tags, it's a good practice to validate the version string provided by the user. The script currently accepts any input. I suggest adding a check to ensure the version string conforms to a semantic versioning format like 1.2.3 or 1.2.3-beta.1.

Suggested change
if [ -z "$VERSION" ]; then
echo "Usage: $0 <version>"
echo "Example: $0 1.0.0"
exit 1
fi
if [ -z "$VERSION" ]; then
echo "Usage: $0 <version>"
echo "Example: $0 1.0.0"
exit 1
fi
if ! [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.-]+)?$ ]]; then
echo "Error: Invalid version format. Expected format like 1.0.0 or 1.0.0-beta.1"
exit 1
fi


TAG="v${VERSION}"

if git rev-parse "$TAG" >/dev/null 2>&1; then
echo "Error: Tag $TAG already exists"
exit 1
fi

# Ensure we're on main and up to date
BRANCH=$(git rev-parse --abbrev-ref HEAD)
if [ "$BRANCH" != "main" ]; then
echo "Warning: Not on main branch (currently on $BRANCH)"
read -rp "Continue anyway? [y/N] " confirm
[ "$confirm" = "y" ] || exit 1
fi
Comment on lines +23 to +29

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The script should ensure the repository is in a clean state before creating a release tag. Currently, it doesn't check for uncommitted changes or if the local branch is synchronized with the remote. Tagging from a dirty or outdated state can lead to incorrect releases. I suggest adding checks for a clean working directory and ensuring the main branch is up-to-date with origin/main. The suggested change also improves the confirmation prompt to accept both 'y' and 'Y'.

Suggested change
# Ensure we're on main and up to date
BRANCH=$(git rev-parse --abbrev-ref HEAD)
if [ "$BRANCH" != "main" ]; then
echo "Warning: Not on main branch (currently on $BRANCH)"
read -rp "Continue anyway? [y/N] " confirm
[ "$confirm" = "y" ] || exit 1
fi
# Ensure we're on main, up to date, and the working directory is clean
if ! git diff-index --quiet HEAD --; then
echo "Error: You have uncommitted changes."
exit 1
fi
BRANCH=$(git rev-parse --abbrev-ref HEAD)
if [ "$BRANCH" = "main" ]; then
echo "Fetching latest changes from origin..."
git fetch origin main
if [ "$(git rev-parse HEAD)" != "$(git rev-parse origin/main)" ]; then
echo "Error: Your local main branch is not up to date with origin/main."
exit 1
fi
else
echo "Warning: Not on main branch (currently on $BRANCH)."
read -rp "Continue anyway? [y/N] " confirm
[[ "$confirm" =~ ^[Yy]$ ]] || exit 1
fi


echo "Creating tag $TAG..."
git tag -a "$TAG" -m "Release $TAG"

echo "Pushing tag $TAG..."
git push origin "$TAG"

echo "Done. Release workflow will run at:"
echo " https://github.com/$(git remote get-url origin | sed 's|.*github.com[:/]||;s|\.git$||')/actions"
Loading