name: Release
on:
push:
tags:
- 'v*'
permissions:
contents: write id-token: write
jobs:
create-release:
name: Create Release
runs-on: ubuntu-latest
outputs:
upload_url: ${{ steps.create_release.outputs.upload_url }}
version: ${{ steps.get_version.outputs.version }}
steps:
- uses: actions/checkout@v4
- name: Get version from tag
id: get_version
run: echo "version=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT
- name: Create Release with GitHub CLI
id: create_release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
# Generate release notes
RELEASE_NOTES=$(gh api \
-X POST \
/repos/${{ github.repository }}/releases/generate-notes \
-f tag_name='${{ github.ref_name }}' \
-f target_commitish='${{ github.sha }}' \
--jq .body)
# Create release
gh release create '${{ github.ref_name }}' \
--title "Twin ${{ steps.get_version.outputs.version }}" \
--notes "## Installation
### Cargo
\`\`\`bash
cargo install twin-cli
\`\`\`
### Manual Installation
Download the appropriate binary for your platform and add it to your PATH.
## What's Changed
$RELEASE_NOTES" \
--draft=false \
--prerelease=false
# Get the upload URL for assets
echo "upload_url=$(gh release view '${{ github.ref_name }}' --json uploadUrl --jq .uploadUrl | sed 's/{?name,label}//')" >> $GITHUB_OUTPUT
build-release:
name: Build for ${{ matrix.os }}
needs: create-release
runs-on: ${{ matrix.os }}
strategy:
matrix:
include:
- os: ubuntu-latest
target: x86_64-unknown-linux-gnu
artifact_name: twin
asset_name: twin-linux-x64.tar.gz
asset_content_type: application/gzip
- os: windows-latest
target: x86_64-pc-windows-msvc
artifact_name: twin.exe
asset_name: twin-windows-x64.zip
asset_content_type: application/zip
- os: macos-latest
target: x86_64-apple-darwin
artifact_name: twin
asset_name: twin-macos-x64.tar.gz
asset_content_type: application/gzip
- os: macos-latest
target: aarch64-apple-darwin
artifact_name: twin
asset_name: twin-macos-arm64.tar.gz
asset_content_type: application/gzip
steps:
- uses: actions/checkout@v4
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
target: ${{ matrix.target }}
- name: Build Release Binary
run: cargo build --release --target ${{ matrix.target }}
- name: Package (Windows)
if: matrix.os == 'windows-latest'
shell: powershell
run: |
$version = "${{ needs.create-release.outputs.version }}"
$dist = "twin-$version-${{ matrix.target }}"
New-Item -ItemType Directory -Force -Path $dist
Copy-Item "target/${{ matrix.target }}/release/${{ matrix.artifact_name }}" -Destination "$dist/"
Copy-Item "README.md" -Destination "$dist/"
Copy-Item "LICENSE" -Destination "$dist/" -ErrorAction SilentlyContinue
Compress-Archive -Path $dist -DestinationPath "${{ matrix.asset_name }}"
- name: Package (Unix)
if: matrix.os != 'windows-latest'
run: |
version="${{ needs.create-release.outputs.version }}"
dist="twin-$version-${{ matrix.target }}"
mkdir -p "$dist"
cp "target/${{ matrix.target }}/release/${{ matrix.artifact_name }}" "$dist/"
cp README.md "$dist/"
[ -f LICENSE ] && cp LICENSE "$dist/"
tar czf "${{ matrix.asset_name }}" "$dist"
- name: Upload Release Asset
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh release upload 'v${{ needs.create-release.outputs.version }}' \
'./${{ matrix.asset_name }}' \
--clobber
publish-crates:
name: Publish to crates.io
needs: create-release
runs-on: ubuntu-latest
if: ${{ !startsWith(github.ref, 'refs/tags/v0.1.') }}
steps:
- uses: actions/checkout@v4
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
- name: Verify package
run: |
cargo package --no-verify
cargo package --list
- name: Publish to crates.io
run: |
cargo publish --no-verify