name: Release
on:
push:
tags:
- "v*"
env:
PYTHON_VERSION: "3.12"
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- name: Check formatting
run: cargo fmt --check
- name: Clippy
run: cargo clippy --features proxy -- -D warnings
- name: Unit tests
run: cargo test --features proxy --tests
crates-io:
needs: test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- name: Publish to crates.io
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
run: cargo publish --allow-dirty
github-release:
needs: test
runs-on: macos-14
permissions:
contents: write
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
targets: aarch64-apple-darwin,x86_64-apple-darwin
- name: Build arm64
run: cargo build --release --features proxy --target aarch64-apple-darwin
- name: Build x86_64
run: cargo build --release --features proxy --target x86_64-apple-darwin
- name: Package tarballs
run: |
for target in aarch64-apple-darwin x86_64-apple-darwin; do
mkdir -p staging
cp target/$target/release/llmshim staging/
tar -czf llmshim-${target}.tar.gz -C staging llmshim
rm -rf staging
done
- name: Create GitHub release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh release create ${{ github.ref_name }} \
--title "${{ github.ref_name }}" \
--generate-notes \
llmshim-aarch64-apple-darwin.tar.gz \
llmshim-x86_64-apple-darwin.tar.gz
homebrew:
needs: github-release
runs-on: macos-14
steps:
- name: Update Homebrew formula
env:
GH_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }}
run: |
VERSION=${GITHUB_REF_NAME#v}
BASE_URL="https://github.com/sanjay920/llmshim/releases/download/${GITHUB_REF_NAME}"
# Download tarballs to compute sha256
curl -sL "${BASE_URL}/llmshim-aarch64-apple-darwin.tar.gz" -o /tmp/arm64.tar.gz
curl -sL "${BASE_URL}/llmshim-x86_64-apple-darwin.tar.gz" -o /tmp/x86.tar.gz
SHA_ARM=$(shasum -a 256 /tmp/arm64.tar.gz | cut -d' ' -f1)
SHA_X86=$(shasum -a 256 /tmp/x86.tar.gz | cut -d' ' -f1)
# Generate formula
cat > /tmp/llmshim.rb << 'ENDOFTEMPLATE'
class Llmshim < Formula
desc "Blazing fast LLM API translation layer — one interface, every provider"
homepage "https://github.com/sanjay920/llmshim"
license "MIT"
version "VERSION_PLACEHOLDER"
on_macos do
if Hardware::CPU.arm?
url "URL_ARM_PLACEHOLDER"
sha256 "SHA_ARM_PLACEHOLDER"
else
url "URL_X86_PLACEHOLDER"
sha256 "SHA_X86_PLACEHOLDER"
end
end
def install
bin.install "llmshim"
end
test do
assert_predicate bin/"llmshim", :executable?
end
end
ENDOFTEMPLATE
# Replace placeholders
sed -i '' "s|VERSION_PLACEHOLDER|${VERSION}|g" /tmp/llmshim.rb
sed -i '' "s|URL_ARM_PLACEHOLDER|${BASE_URL}/llmshim-aarch64-apple-darwin.tar.gz|g" /tmp/llmshim.rb
sed -i '' "s|URL_X86_PLACEHOLDER|${BASE_URL}/llmshim-x86_64-apple-darwin.tar.gz|g" /tmp/llmshim.rb
sed -i '' "s|SHA_ARM_PLACEHOLDER|${SHA_ARM}|g" /tmp/llmshim.rb
sed -i '' "s|SHA_X86_PLACEHOLDER|${SHA_X86}|g" /tmp/llmshim.rb
# Remove leading whitespace from heredoc
sed -i '' 's/^ //' /tmp/llmshim.rb
# Get existing file SHA (if updating)
EXISTING_SHA=$(gh api repos/sanjay920/homebrew-tap/contents/Formula/llmshim.rb --jq .sha 2>/dev/null || echo "")
# Push to homebrew-tap repo
if [ -n "$EXISTING_SHA" ]; then
gh api repos/sanjay920/homebrew-tap/contents/Formula/llmshim.rb \
--method PUT \
--field message="Update llmshim to ${VERSION}" \
--field content="$(base64 -i /tmp/llmshim.rb)" \
--field sha="${EXISTING_SHA}"
else
gh api repos/sanjay920/homebrew-tap/contents/Formula/llmshim.rb \
--method PUT \
--field message="Add llmshim ${VERSION}" \
--field content="$(base64 -i /tmp/llmshim.rb)"
fi
sdist:
needs: test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: Build sdist
uses: PyO3/maturin-action@v1
with:
command: sdist
args: --out dist
working-directory: clients/python
- uses: actions/upload-artifact@v4
with:
name: wheels-sdist
path: clients/python/dist
macos:
needs: test
runs-on: macos-14
strategy:
matrix:
target: [aarch64-apple-darwin, x86_64-apple-darwin]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: Build wheel
uses: PyO3/maturin-action@v1
with:
target: ${{ matrix.target }}
args: --release --out dist
working-directory: clients/python
- uses: actions/upload-artifact@v4
with:
name: wheels-macos-${{ matrix.target }}
path: clients/python/dist
linux-x86:
needs: test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: Build wheel
uses: PyO3/maturin-action@v1
with:
target: x86_64-unknown-linux-gnu
manylinux: "2_17"
args: --release --out dist
working-directory: clients/python
- uses: actions/upload-artifact@v4
with:
name: wheels-linux-x86_64
path: clients/python/dist
linux-arm:
needs: test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: Build wheel
uses: PyO3/maturin-action@v1
with:
target: aarch64-unknown-linux-gnu
manylinux: "2_17"
args: --release --out dist --zig
working-directory: clients/python
- uses: actions/upload-artifact@v4
with:
name: wheels-linux-aarch64
path: clients/python/dist
windows:
needs: test
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: Build wheel
uses: PyO3/maturin-action@v1
with:
target: x86_64-pc-windows-msvc
args: --release --out dist
working-directory: clients/python
- uses: actions/upload-artifact@v4
with:
name: wheels-windows-x86_64
path: clients/python/dist
pypi:
needs: [sdist, macos, linux-x86, linux-arm, windows]
runs-on: ubuntu-latest
environment: release
permissions:
id-token: write
steps:
- uses: actions/download-artifact@v4
with:
pattern: wheels-*
path: dist
merge-multiple: true
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
packages-dir: dist/