name: Release
on:
workflow_dispatch:
inputs:
version:
description: 'Release version (e.g., 1.2.3)'
required: true
dry-run:
description: 'Run in dry-run mode (no package publish, draft release)'
type: boolean
default: true
env:
CARGO_TERM_COLOR: always
jobs:
validate:
runs-on: ubuntu-24.04
steps:
- name: Validate inputs
run: |
if ! [[ "${{ github.event.inputs.version }}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "⚠️ Error: Version format must be x.x.x (e.g., 1.2.3)."
exit 1
fi
echo "✅ Version format is valid."
package-linux:
runs-on: ubuntu-24.04
needs: [ validate ]
steps:
- uses: actions/checkout@v4
- name: Install Rust
uses: actions-rust-lang/setup-rust-toolchain@v1
- name: Install Tools
uses: taiki-e/install-action@v2
with:
tool: cargo-auditable,cargo-audit,cargo-edit
- name: Set version
run: cargo set-version ${{ github.event.inputs.version }}
- name: Build
run: |
cargo auditable build --release
cargo auditable build --profile release-shim --bin kopi-shim
- name: Targz
run: |
mkdir -p archive/pkg
cp ./target/release/kopi target/
cp ./target/release-shim/kopi-shim target/
os_lower=$(echo "${{ runner.os }}" | tr '[:upper:]' '[:lower:]')
cd target/
tar -zcvf ../archive/pkg/kopi-${{ github.event.inputs.version }}-${os_lower}-x64.tar.gz ./kopi ./kopi-shim
- name: Upload Artifact
uses: actions/upload-artifact@v4
with:
name: package-${{ runner.os }}
path: archive/pkg
retention-days: 1
package-macos:
runs-on: macos-15-large
needs: [ validate ]
steps:
- uses: actions/checkout@v4
- name: Install Rust
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
target: aarch64-apple-darwin
- name: Install Tools
uses: taiki-e/install-action@v2
with:
tool: cargo-auditable,cargo-audit,cargo-edit
- name: Set version
run: cargo set-version ${{ github.event.inputs.version }}
- name: Build (x86_64)
run: |
cargo auditable build --release --target x86_64-apple-darwin
cargo auditable build --profile release-shim --bin kopi-shim --target x86_64-apple-darwin
- name: Targz (x86_64)
run: |
mkdir -p archive/pkg
os_lower=$(echo "${{ runner.os }}" | tr '[:upper:]' '[:lower:]')
cd target/x86_64-apple-darwin/
cp ./release/kopi .
cp ./release-shim/kopi-shim .
tar -zcvf ../../archive/pkg/kopi-${{ github.event.inputs.version }}-${os_lower}-x86_64.tar.gz ./kopi ./kopi-shim
- name: Build (aarch64)
run: |
cargo auditable build --release --target aarch64-apple-darwin
cargo auditable build --profile release-shim --bin kopi-shim --target aarch64-apple-darwin
- name: Targz (aarch64)
run: |
mkdir -p archive/pkg
os_lower=$(echo "${{ runner.os }}" | tr '[:upper:]' '[:lower:]')
cd target/aarch64-apple-darwin/
cp ./release/kopi .
cp ./release-shim/kopi-shim .
tar -zcvf ../../archive/pkg/kopi-${{ github.event.inputs.version }}-${os_lower}-aarch64.tar.gz ./kopi ./kopi-shim
- name: Upload Artifact
uses: actions/upload-artifact@v4
with:
name: package-${{ runner.os }}
path: archive/pkg
retention-days: 1
package-windows:
runs-on: windows-2025
needs: [ validate ]
steps:
- uses: actions/checkout@v4
- name: Install Rust
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
target: aarch64-pc-windows-msvc
- name: Install Tools
uses: taiki-e/install-action@v2
with:
tool: cargo-auditable,cargo-audit,cargo-edit
- name: Set version
run: cargo set-version ${{ github.event.inputs.version }}
- name: Install Wix
run: dotnet tool install --global wix
- name: Build bundle (x64)
run: |
pkg/wix/build-bundle.ps1 -Version ${{ github.event.inputs.version }} -Platform x64
New-Item -Path archive/pkg -ItemType Directory -Force
Copy-Item ./pkg/wix/output/kopi-bundle-with-vcredist-${{ github.event.inputs.version }}-windows-x64.exe ./archive/pkg/
Copy-Item ./pkg/wix/output/en-us/kopi-${{ github.event.inputs.version }}-windows-x64.msi ./archive/pkg/
- name: Zip (x64)
run: |
New-Item -Path archive/pkg -ItemType Directory -Force
Compress-Archive -Path ./target/x86_64-pc-windows-msvc/release/kopi.exe, ./target/x86_64-pc-windows-msvc/release-shim/kopi-shim.exe -DestinationPath archive/pkg/kopi-${{ github.event.inputs.version }}-windows-x64.zip
- name: Build bundle (arm64)
run: |
pkg/wix/build-bundle.ps1 -Version ${{ github.event.inputs.version }} -Platform arm64
New-Item -Path archive/pkg -ItemType Directory -Force
Copy-Item ./pkg/wix/output/kopi-bundle-with-vcredist-${{ github.event.inputs.version }}-windows-arm64.exe ./archive/pkg/
Copy-Item ./pkg/wix/output/en-us/kopi-${{ github.event.inputs.version }}-windows-arm64.msi ./archive/pkg/
- name: Zip (arm64)
run: |
New-Item -Path archive/pkg -ItemType Directory -Force
Compress-Archive -Path ./target/aarch64-pc-windows-msvc/release/kopi.exe, ./target/aarch64-pc-windows-msvc/release-shim/kopi-shim.exe -DestinationPath archive/pkg/kopi-${{ github.event.inputs.version }}-windows-arm64.zip
- name: Upload Artifact
uses: actions/upload-artifact@v4
with:
name: package-${{ runner.os }}
path: archive/pkg
retention-days: 1
release:
runs-on: ubuntu-24.04
needs:
- package-linux
- package-macos
- package-windows
permissions:
contents: write
steps:
- uses: actions/checkout@v4
- name: Install Rust
uses: actions-rust-lang/setup-rust-toolchain@v1
- name: Install Tools
uses: taiki-e/install-action@v2
with:
tool: cargo-edit
- name: Fetch Linux archive
uses: actions/download-artifact@v4
with:
name: package-Linux
path: release
- name: Fetch Mac archive
uses: actions/download-artifact@v4
with:
name: package-macOS
path: release
- name: Fetch Windows archive
uses: actions/download-artifact@v4
with:
name: package-Windows
path: release
- name: Generate SHA256 checksums
run: |
cd release
for file in *; do
if [ -f "$file" ]; then
sha256sum "$file" | cut -d' ' -f1 > "${file}.sha256"
fi
done
- name: Show release artifacts
run: ls -la release
- name: Configure Git
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
- name: Set version
run: cargo set-version ${{ github.event.inputs.version }}
- name: Commit, Tag, and Push
run: |
git add .
git commit -m "Bump v${{ github.event.inputs.version }}"
git tag v${{ github.event.inputs.version }}
git push
git push --tags
- name: Publish
if: ${{ github.event.inputs.dry-run == 'false' }}
run: cargo publish
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
- name: Publish (dry-run)
if: ${{ github.event.inputs.dry-run == 'true' }}
run: cargo publish --dry-run
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
- name: Create release
if: ${{ github.event.inputs.dry-run == 'false' }}
run: gh release create v${{ github.event.inputs.version }} --generate-notes release/*
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Create release (dry-run)
if: ${{ github.event.inputs.dry-run == 'true' }}
run: gh release create v${{ github.event.inputs.version }} --generate-notes release/* --draft
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}