Skip to content

Merge pull request #244 from OpenMined/madhava/fixes #221

Merge pull request #244 from OpenMined/madhava/fixes

Merge pull request #244 from OpenMined/madhava/fixes #221

Workflow file for this run

name: Release
on:
push:
branches:
- main
paths:
- 'cli/**.rs'
- 'cli/Cargo.toml'
- 'cli/Cargo.lock'
workflow_dispatch:
inputs:
bump_type:
description: 'Version bump type'
required: false
type: choice
default: 'none'
options:
- none
- patch
- minor
- major
force_version:
description: 'Force a specific version (e.g., 0.1.1)'
required: false
type: string
skip_tests:
description: 'Skip tests (use with caution)'
required: false
type: boolean
default: false
bump_only:
description: 'Only bump the version and skip build/release steps'
required: false
type: boolean
default: false
permissions:
contents: write
packages: write
pull-requests: write
actions: write
env:
CARGO_TERM_COLOR: always
jobs:
test:
name: Run tests
if: ${{ !inputs.skip_tests && !inputs.bump_only }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup workspace dependencies
run: |
chmod +x scripts/setup-workspace.sh
./scripts/setup-workspace.sh
- name: Install protoc
uses: arduino/setup-protoc@v2
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
- name: Install Rust
uses: dtolnay/rust-toolchain@master
with:
toolchain: 1.91.0
- name: Run tests
run: cd cli && cargo test --all-features
check-version:
name: Check if version needs bump
needs: [test]
if: ${{ always() && (needs.test.result == 'success' || needs.test.result == 'skipped') }}
runs-on: ubuntu-latest
outputs:
needs_bump: ${{ steps.check.outputs.needs_bump }}
current_version: ${{ steps.check.outputs.current_version }}
new_version: ${{ steps.check.outputs.new_version }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup workspace dependencies
run: |
chmod +x scripts/setup-workspace.sh
./scripts/setup-workspace.sh
- name: Check version
id: check
shell: bash
run: |
# Check if force_version is provided
if [[ -n "${{ github.event.inputs.force_version }}" ]]; then
CURRENT_VERSION=$(grep '^version = ' cli/Cargo.toml | head -1 | sed 's/version = "\(.*\)"/\1/')
NEW_VERSION="${{ github.event.inputs.force_version }}"
echo "current_version=$CURRENT_VERSION" >> $GITHUB_OUTPUT
echo "new_version=$NEW_VERSION" >> $GITHUB_OUTPUT
if [[ "$CURRENT_VERSION" != "$NEW_VERSION" ]]; then
echo "needs_bump=true" >> $GITHUB_OUTPUT
echo "Forcing version from $CURRENT_VERSION to $NEW_VERSION"
else
echo "needs_bump=false" >> $GITHUB_OUTPUT
echo "Version is already $NEW_VERSION"
fi
# Check if manual bump_type is provided
elif [[ "${{ github.event.inputs.bump_type }}" != "" && "${{ github.event.inputs.bump_type }}" != "none" ]]; then
CURRENT_VERSION=$(grep '^version = ' cli/Cargo.toml | head -1 | sed 's/version = "\(.*\)"/\1/')
echo "current_version=$CURRENT_VERSION" >> $GITHUB_OUTPUT
# Calculate new version based on bump type
IFS='.' read -ra VERSION_PARTS <<< "$CURRENT_VERSION"
MAJOR="${VERSION_PARTS[0]}"
MINOR="${VERSION_PARTS[1]}"
PATCH="${VERSION_PARTS[2]}"
case "${{ github.event.inputs.bump_type }}" in
major)
NEW_VERSION="$((MAJOR + 1)).0.0"
;;
minor)
NEW_VERSION="$MAJOR.$((MINOR + 1)).0"
;;
patch)
NEW_VERSION="$MAJOR.$MINOR.$((PATCH + 1))"
;;
esac
echo "new_version=$NEW_VERSION" >> $GITHUB_OUTPUT
echo "needs_bump=true" >> $GITHUB_OUTPUT
echo "Manual bump requested: ${{ github.event.inputs.bump_type }} (from $CURRENT_VERSION to $NEW_VERSION)"
else
# Get current version from Cargo.toml
CURRENT_VERSION=$(grep '^version = ' cli/Cargo.toml | head -1 | sed 's/version = "\(.*\)"/\1/')
echo "current_version=$CURRENT_VERSION" >> $GITHUB_OUTPUT
# Check if this version has been published already
if git tag | grep -q "v$CURRENT_VERSION"; then
echo "Version $CURRENT_VERSION already exists, bumping patch version"
IFS='.' read -ra VERSION_PARTS <<< "$CURRENT_VERSION"
MAJOR="${VERSION_PARTS[0]}"
MINOR="${VERSION_PARTS[1]}"
PATCH="${VERSION_PARTS[2]}"
NEW_PATCH=$((PATCH + 1))
NEW_VERSION="$MAJOR.$MINOR.$NEW_PATCH"
echo "new_version=$NEW_VERSION" >> $GITHUB_OUTPUT
echo "needs_bump=true" >> $GITHUB_OUTPUT
else
echo "Version $CURRENT_VERSION is new"
echo "new_version=$CURRENT_VERSION" >> $GITHUB_OUTPUT
echo "needs_bump=false" >> $GITHUB_OUTPUT
fi
fi
bump-version:
name: Bump version if needed
runs-on: ubuntu-latest
needs: check-version
if: needs.check-version.outputs.needs_bump == 'true'
outputs:
version: ${{ needs.check-version.outputs.new_version }}
steps:
- uses: actions/checkout@v4
with:
token: ${{ secrets.PAT_TOKEN || secrets.GITHUB_TOKEN }}
fetch-depth: 0
- name: Setup workspace dependencies
run: |
chmod +x scripts/setup-workspace.sh
./scripts/setup-workspace.sh
- name: Update version in Cargo.toml
shell: bash
run: |
# Only update the package version (line 3), not dependency versions
sed -i '3s/^version = .*/version = "${{ needs.check-version.outputs.new_version }}"/' cli/Cargo.toml
# Update Cargo.lock
cd cli && cargo update --workspace
- name: Commit version bump
shell: bash
run: |
git config user.name github-actions[bot]
git config user.email github-actions[bot]@users.noreply.github.com
git add cli/Cargo.toml cli/Cargo.lock
git commit -m "chore: bump version to ${{ needs.check-version.outputs.new_version }} [skip ci]"
git push
build:
name: Build ${{ matrix.target }}
runs-on: ${{ matrix.os }}
needs: [check-version, bump-version]
if: |
always() &&
!inputs.bump_only &&
needs.check-version.result == 'success' &&
(needs.bump-version.result == 'success' || needs.bump-version.result == 'skipped')
strategy:
matrix:
include:
# Linux
- os: ubuntu-latest
target: x86_64-unknown-linux-gnu
binary: bv
- os: ubuntu-latest
target: x86_64-unknown-linux-musl
binary: bv
- os: ubuntu-latest
target: aarch64-unknown-linux-gnu
binary: bv
# macOS
- os: macos-latest
target: x86_64-apple-darwin
binary: bv
- os: macos-latest
target: aarch64-apple-darwin
binary: bv
# Windows
- os: windows-latest
target: x86_64-pc-windows-msvc
binary: bv.exe
- os: windows-latest
target: aarch64-pc-windows-msvc
binary: bv.exe
steps:
- uses: actions/checkout@v4
with:
ref: main
- name: Setup workspace dependencies (Unix)
if: runner.os != 'Windows'
run: |
chmod +x scripts/setup-workspace.sh
./scripts/setup-workspace.sh
- name: Setup workspace dependencies (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: |
$repoRoot = (Resolve-Path ".").Path
$parentDir = Split-Path $repoRoot -Parent
git config --global url."https://github.com/".insteadOf "git@github.com:"
function Clone-IfMissing($name, $url, $branch = $null) {
$dest = Join-Path $parentDir $name
if (Test-Path $dest) {
Write-Host "$name already exists at $dest"
} else {
Write-Host "Cloning $name to $dest..."
if ($branch) {
git clone -b $branch $url $dest
} else {
git clone $url $dest
}
}
}
Clone-IfMissing "syftbox-sdk" "https://github.com/OpenMined/syftbox-sdk.git"
Clone-IfMissing "syft-crypto-core" "https://github.com/OpenMined/syft-crypto-core.git"
Clone-IfMissing "syftbox" "https://github.com/OpenMined/syftbox.git" "madhava/biovault"
Clone-IfMissing "biovault-beaver" "https://github.com/OpenMined/biovault-beaver.git"
Clone-IfMissing "sbenv" "https://github.com/OpenMined/sbenv.git"
Clone-IfMissing "bioscript" "https://github.com/OpenMined/bioscript.git"
function Create-Junction($name) {
$link = Join-Path $repoRoot $name
$target = Join-Path $parentDir $name
if (-not (Test-Path $link)) {
cmd /c mklink /J $link $target
Write-Host "Created junction: $name -> $target"
}
}
Create-Junction "syftbox-sdk"
Create-Junction "syft-crypto-core"
Create-Junction "syftbox"
Create-Junction "biovault-beaver"
Create-Junction "sbenv"
Create-Junction "bioscript"
- name: Install protoc
uses: arduino/setup-protoc@v2
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
- name: Install Rust
uses: dtolnay/rust-toolchain@master
with:
toolchain: 1.91.0
targets: ${{ matrix.target }}
- name: Ensure target installed
run: rustup target add ${{ matrix.target }}
- name: Install cross-compilation tools
if: matrix.os == 'ubuntu-latest'
run: |
if [[ "${{ matrix.target }}" == "x86_64-unknown-linux-musl" ]]; then
sudo apt-get update
sudo apt-get install -y musl-tools
elif [[ "${{ matrix.target }}" == "aarch64-unknown-linux-gnu" ]]; then
sudo apt-get update
sudo apt-get install -y gcc-aarch64-linux-gnu
fi
- name: Configure cargo target linker
if: matrix.os == 'ubuntu-latest'
shell: bash
run: |
mkdir -p ~/.cargo
cfg=~/.cargo/config.toml
if [[ "${{ matrix.target }}" == "x86_64-unknown-linux-musl" ]]; then
printf '[target.x86_64-unknown-linux-musl]\nlinker = "musl-gcc"\n' >> "$cfg"
elif [[ "${{ matrix.target }}" == "aarch64-unknown-linux-gnu" ]]; then
printf '[target.aarch64-unknown-linux-gnu]\nlinker = "aarch64-linux-gnu-gcc"\n' >> "$cfg"
fi
- name: Build
shell: bash
run: |
cd cli
cargo build --release --target ${{ matrix.target }}
- name: Package binary
shell: bash
run: |
cd cli/target/${{ matrix.target }}/release
if [[ "${{ matrix.os }}" == "windows-latest" ]]; then
7z a ../../../../bv-${{ matrix.target }}.zip ${{ matrix.binary }}
else
tar czf ../../../../bv-${{ matrix.target }}.tar.gz ${{ matrix.binary }}
fi
cd -
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: bv-${{ matrix.target }}
path: |
bv-${{ matrix.target }}.tar.gz
bv-${{ matrix.target }}.zip
publish-crate:
name: Publish to crates.io
runs-on: ubuntu-latest
needs: [build, check-version, bump-version]
if: |
always() &&
!inputs.bump_only &&
needs.build.result == 'success' &&
(needs.bump-version.result == 'success' || needs.bump-version.result == 'skipped')
steps:
- uses: actions/checkout@v4
with:
ref: main
- name: Setup workspace dependencies
run: |
chmod +x scripts/setup-workspace.sh
./scripts/setup-workspace.sh
- name: Install protoc
uses: arduino/setup-protoc@v2
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
- name: Install Rust
uses: dtolnay/rust-toolchain@master
with:
toolchain: 1.91.0
- name: Publish to crates.io
run: cd cli && cargo publish --token ${{ secrets.CARGO_REGISTRY_TOKEN }}
continue-on-error: true
create-release:
name: Create GitHub Release
runs-on: ubuntu-latest
needs: [build, check-version, bump-version, publish-crate]
if: |
always() &&
!inputs.bump_only &&
needs.build.result == 'success' &&
(needs.bump-version.result == 'success' || needs.bump-version.result == 'skipped')
steps:
- uses: actions/checkout@v4
with:
ref: main
- name: Setup workspace dependencies
run: |
chmod +x scripts/setup-workspace.sh
./scripts/setup-workspace.sh
- name: Get final version
id: version
shell: bash
run: |
VERSION=$(grep '^version = ' cli/Cargo.toml | head -1 | sed 's/version = "\(.*\)"/\1/')
echo "version=$VERSION" >> $GITHUB_OUTPUT
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
- name: Create Release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: v${{ steps.version.outputs.version }}
release_name: Release v${{ steps.version.outputs.version }}
draft: false
prerelease: false
body: |
# BioVault v${{ steps.version.outputs.version }}
## Installation
### Using curl (macOS/Linux)
```bash
curl -fsSL https://raw.githubusercontent.com/${{ github.repository }}/main/install.sh | sh
```
### Using Cargo
```bash
cargo install biovault
```
- name: Upload Release Assets
run: |
for file in artifacts/*/*.{tar.gz,zip}; do
if [ -f "$file" ]; then
asset_name=$(basename "$file")
echo "Uploading $asset_name"
gh release upload v${{ steps.version.outputs.version }} "$file" \
--repo ${{ github.repository }}
fi
done
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}