name: Release
on:
push:
tags:
- "v*"
permissions:
contents: write
jobs:
verify:
name: verify
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Cache Rust build
uses: Swatinem/rust-cache@v2
- name: Run tests
run: cargo test --locked
- name: Check formatting
run: cargo fmt -- --check
- name: Run clippy
run: cargo clippy --all-targets --all-features -- -D warnings
build-release:
name: build-release
needs: verify
runs-on: ${{ matrix.os }}
strategy:
matrix:
include:
- os: ubuntu-latest
target: x86_64-unknown-linux-gnu
artifact_name: tli
asset_name: tli-linux-x64.zip
- os: macos-latest
target: aarch64-apple-darwin
artifact_name: tli
asset_name: tli-macos-arm64.zip
- os: windows-latest
target: x86_64-pc-windows-msvc
artifact_name: tli.exe
asset_name: tli-windows-x64.zip
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
- name: Cache Rust build
uses: Swatinem/rust-cache@v2
- name: Set version from tag
env:
VERSION: ${{ github.ref_name }}
shell: pwsh
run: |
$version = $env:VERSION -replace '^v', ''
$cargoToml = 'Cargo.toml'
$content = Get-Content $cargoToml -Raw
$updated = [regex]::Replace($content, '(?m)^version = "[^"]+"', "version = `"$version`"", 1)
if ($updated -eq $content) {
throw "Failed to update Cargo.toml version from tag $version"
}
Set-Content $cargoToml $updated -NoNewline
- name: Build release binary
run: cargo build --release --target ${{ matrix.target }}
- name: Package binary
shell: pwsh
run: |
Compress-Archive -Path "target/${{ matrix.target }}/release/${{ matrix.artifact_name }}" -DestinationPath "target/${{ matrix.target }}/release/${{ matrix.asset_name }}" -Force
- name: Upload workflow artifact
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.asset_name }}
path: target/${{ matrix.target }}/release/${{ matrix.asset_name }}
- name: Upload binary to GitHub Release
uses: softprops/action-gh-release@v2
with:
files: target/${{ matrix.target }}/release/${{ matrix.asset_name }}
generate_release_notes: true
publish-crates:
name: publish-crates
needs: build-release
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Cache Rust build
uses: Swatinem/rust-cache@v2
- name: Set version from tag
env:
VERSION: ${{ github.ref_name }}
run: |
VERSION="${VERSION#v}"
sed -i -E "0,/^version = \"[^\"]+\"/s//version = \"$VERSION\"/" Cargo.toml
- name: Publish to crates.io
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
run: cargo publish --allow-dirty
publish-npm:
name: publish-npm
needs: build-release
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version: 22
registry-url: "https://registry.npmjs.org"
- name: Set version from tag
run: |
VERSION="${GITHUB_REF_NAME#v}"
npm version "$VERSION" --no-git-tag-version
working-directory: npm
- name: Download release artifacts
uses: actions/download-artifact@v4
with:
path: dist
- name: Bundle release binaries into npm package
run: |
TMP_DIR="$(mktemp -d)"
trap 'rm -rf "$TMP_DIR"' EXIT
LINUX_ZIP="$(find dist -type f -name 'tli-linux-x64.zip' -print -quit)"
MACOS_ZIP="$(find dist -type f -name 'tli-macos-arm64.zip' -print -quit)"
WINDOWS_ZIP="$(find dist -type f -name 'tli-windows-x64.zip' -print -quit)"
test -n "$LINUX_ZIP"
test -n "$MACOS_ZIP"
test -n "$WINDOWS_ZIP"
unzip -j "$LINUX_ZIP" tli -d "$TMP_DIR"
mv "$TMP_DIR/tli" npm/bin/tli-linux-x64
unzip -j "$MACOS_ZIP" tli -d "$TMP_DIR"
mv "$TMP_DIR/tli" npm/bin/tli-darwin-arm64
unzip -j "$WINDOWS_ZIP" tli.exe -d "$TMP_DIR"
mv "$TMP_DIR/tli.exe" npm/bin/tli-win32-x64.exe
chmod +x npm/bin/tli-linux-x64 npm/bin/tli-darwin-arm64
test -f npm/bin/tli.js
test -f npm/bin/tli-linux-x64
test -f npm/bin/tli-darwin-arm64
test -f npm/bin/tli-win32-x64.exe
- name: Copy README and LICENSE to npm package
run: |
cp README.md npm/README.md
cp LICENSE npm/LICENSE
- name: Publish to npm
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
run: npm publish --access public
working-directory: npm