name: Release
on:
push:
tags:
- 'v*'
workflow_dispatch:
inputs:
release_type:
description: 'Type of release'
required: true
default: 'patch'
type: choice
options:
- patch
- minor
- major
env:
CARGO_TERM_COLOR: always
NODE_VERSION: '18'
RUST_VERSION: '1.70'
jobs:
test:
name: Test Suite
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Rust
uses: actions-rs/toolchain@v1
with:
toolchain: ${{ env.RUST_VERSION }}
components: rustfmt, clippy
override: true
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Install wasm-pack
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
- name: Install dependencies
run: npm ci
- name: Lint Rust code
run: cargo clippy --all-targets --all-features -- -D warnings
- name: Format check
run: cargo fmt --all -- --check
- name: Run Rust tests
run: cargo test --verbose
- name: Run Node.js tests
run: npm test
- name: Build project
run: npm run build
- name: Run benchmarks
run: cargo bench
build-wasm:
name: Build WebAssembly
runs-on: ubuntu-latest
needs: test
steps:
- uses: actions/checkout@v4
- name: Setup Rust
uses: actions-rs/toolchain@v1
with:
toolchain: ${{ env.RUST_VERSION }}
targets: wasm32-unknown-unknown
override: true
- name: Install wasm-pack
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
- name: Install wasm-opt
run: |
wget https://github.com/WebAssembly/binaryen/releases/download/version_116/binaryen-version_116-x86_64-linux.tar.gz
tar -xzf binaryen-version_116-x86_64-linux.tar.gz
sudo cp binaryen-version_116/bin/wasm-opt /usr/local/bin/
- name: Build WebAssembly
run: ./scripts/build-wasm.sh
- name: Upload WASM artifacts
uses: actions/upload-artifact@v3
with:
name: wasm-build
path: |
dist/
pkg/
retention-days: 1
build-native:
name: Build Native Bindings
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
runs-on: ${{ matrix.os }}
needs: test
steps:
- uses: actions/checkout@v4
- name: Setup Rust
uses: actions-rs/toolchain@v1
with:
toolchain: ${{ env.RUST_VERSION }}
override: true
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Build native bindings
run: npm run build:node
- name: Test native bindings
run: npm run test:node
- name: Upload native artifacts
uses: actions/upload-artifact@v3
with:
name: native-${{ matrix.os }}
path: build/Release/
retention-days: 1
create-release:
name: Create Release
runs-on: ubuntu-latest
needs: [test, build-wasm, build-native]
outputs:
version: ${{ steps.version.outputs.version }}
release_created: ${{ steps.release.outputs.release_created }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Determine version
id: version
run: |
if [[ $GITHUB_REF == refs/tags/* ]]; then
VERSION=${GITHUB_REF#refs/tags/v}
else
# Get current version and increment
CURRENT_VERSION=$(node -p "require('./package.json').version")
npm version ${{ github.event.inputs.release_type }} --no-git-tag-version
VERSION=$(node -p "require('./package.json').version")
# Commit version bump
git config user.name "GitHub Actions"
git config user.email "actions@github.com"
git add package.json package-lock.json
git commit -m "chore: bump version to $VERSION"
git tag "v$VERSION"
git push origin main --tags
fi
echo "version=$VERSION" >> $GITHUB_OUTPUT
- name: Download artifacts
uses: actions/download-artifact@v3
with:
path: artifacts/
- name: Prepare release assets
run: |
mkdir -p release/
# Copy WASM build
cp -r artifacts/wasm-build/* release/
# Package native bindings
for os in ubuntu-latest windows-latest macos-latest; do
if [ -d "artifacts/native-$os" ]; then
platform=$(echo $os | sed 's/-latest//')
tar -czf "release/native-bindings-$platform.tar.gz" -C "artifacts/native-$os" .
fi
done
# Create source tarball
git archive --format=tar.gz --prefix=cuda-rust-wasm-${{ steps.version.outputs.version }}/ HEAD > release/source.tar.gz
- name: Generate changelog
run: |
# Generate changelog from git commits
git log --oneline --pretty=format:"- %s" $(git describe --tags --abbrev=0 HEAD^)..HEAD > CHANGELOG.md
- name: Create GitHub Release
id: release
uses: softprops/action-gh-release@v1
with:
tag_name: v${{ steps.version.outputs.version }}
name: Release v${{ steps.version.outputs.version }}
body_path: CHANGELOG.md
draft: false
prerelease: false
files: |
release/*
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
publish-npm:
name: Publish to NPM
runs-on: ubuntu-latest
needs: create-release
if: needs.create-release.outputs.release_created == 'true'
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
registry-url: 'https://registry.npmjs.org'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Download WASM artifacts
uses: actions/download-artifact@v3
with:
name: wasm-build
path: .
- name: Publish to NPM
run: npm publish --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Update package version
run: |
npm version ${{ needs.create-release.outputs.version }} --no-git-tag-version
git config user.name "GitHub Actions"
git config user.email "actions@github.com"
git add package.json package-lock.json
git commit -m "chore: update version to ${{ needs.create-release.outputs.version }}"
git push origin main
publish-docker:
name: Publish Docker Image
runs-on: ubuntu-latest
needs: create-release
if: needs.create-release.outputs.release_created == 'true'
steps:
- uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: vibecast/cuda-rust-wasm
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
deploy-docs:
name: Deploy Documentation
runs-on: ubuntu-latest
needs: create-release
if: needs.create-release.outputs.release_created == 'true'
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Generate documentation
run: |
# Generate API docs
npm run docs
# Copy demo files
cp -r demo/ docs/demo/
# Copy examples
cp -r examples/ docs/examples/
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./docs
cname: cuda-rust-wasm.vibecast.io
notify:
name: Notify Release
runs-on: ubuntu-latest
needs: [create-release, publish-npm, publish-docker, deploy-docs]
if: always() && needs.create-release.outputs.release_created == 'true'
steps:
- name: Notify Discord
uses: Ilshidur/action-discord@master
with:
args: |
🚀 **CUDA-Rust-WASM v${{ needs.create-release.outputs.version }}** has been released!
📦 **NPM:** `npm install cuda-rust-wasm@${{ needs.create-release.outputs.version }}`
🐳 **Docker:** `docker pull vibecast/cuda-rust-wasm:${{ needs.create-release.outputs.version }}`
📚 **Docs:** https://cuda-rust-wasm.vibecast.io
🔗 **GitHub:** https://github.com/vibecast/cuda-rust-wasm/releases/tag/v${{ needs.create-release.outputs.version }}
env:
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
- name: Update package registries
run: |
echo "Release v${{ needs.create-release.outputs.version }} published successfully!"
echo "NPM: $(npm view cuda-rust-wasm@${{ needs.create-release.outputs.version }} version)"