name: Release & Publish
on:
push:
branches:
- main
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: write
pull-requests: write
id-token: write
attestations: write
packages: write
jobs:
generate-credits:
name: Generate Licenses (CREDITS)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Install cargo-binstall
uses: cargo-bins/cargo-binstall@main
- name: Install cargo-about
run: cargo binstall cargo-about -y
- name: Generate CREDITS.html
run: cargo about generate about.hbs > CREDITS.html
- name: Upload CREDITS
uses: actions/upload-artifact@v7
with:
name: credits-html
path: CREDITS.html
retention-days: 1
validate:
name: Tests, Formatting & Security
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt
- name: Setup Rust cache
uses: Swatinem/rust-cache@v2
- name: Check formatting
run: cargo fmt --all -- --check
- name: Run tests
run: |
cargo test --all-targets
cargo test --all-targets --features serde
cargo test --all-targets --features aot
- name: Security audit (cargo-deny)
uses: EmbarkStudios/cargo-deny-action@v2
with:
command: check bans licenses
validate-go:
name: Go Bindings — Build & Test
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Setup Rust cache
uses: Swatinem/rust-cache@v2
- name: Build Rust library with FFI
run: cargo build --release --features ffi
- name: Set up Go
uses: actions/setup-go@v6
with:
go-version: "stable"
cache-dependency-path: go/go.sum
- name: Test Go bindings
working-directory: ./go
run: go test -v ./...
env:
LD_LIBRARY_PATH: ${{ github.workspace }}/target/release
validate-js:
name: Node.js Bindings — Build & Test
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Setup Rust cache
uses: Swatinem/rust-cache@v2
- name: Set up Node.js
uses: actions/setup-node@v6
with:
node-version: 22
- name: Install Node.js dependencies
working-directory: ./js
run: npm install
- name: Build Node.js bindings
working-directory: ./js
run: npm run build
- name: Run Node.js tests
working-directory: ./js
run: npm test
validate-csharp:
name: C# Bindings — Build & Test
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Setup Rust cache
uses: Swatinem/rust-cache@v2
- name: Build Rust library with FFI
run: cargo build --release --features ffi,csharp
- name: Setup .NET
uses: actions/setup-dotnet@v5
with:
dotnet-version: "10.0.x"
- name: Restore C# dependencies
working-directory: ./csharp
run: dotnet restore AamCsharp.sln
- name: Build C# project
working-directory: ./csharp
run: dotnet build AamCsharp.sln --configuration Release --no-restore
- name: Run C# tests
working-directory: ./csharp/
run: dotnet test AamCsharp.sln --configuration Release --no-build -v normal
env:
LD_LIBRARY_PATH: ${{ github.workspace }}/target/release
validate-wasm:
name: WASM Bindings - Build & Test
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
targets: wasm32-unknown-unknown
- name: Install wasm-pack
run: cargo install wasm-pack --locked
- name: Build WASM package
working-directory: ./wasm
run: wasm-pack build --release --target nodejs --out-dir pkg
- name: Run WASM tests
working-directory: ./wasm
run: |
cargo test
wasm-pack test --node
validate-ruby:
name: Ruby Bindings - Build & Test
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: "3.3"
- name: Build Ruby extension
run: cargo build --manifest-path ruby/ext/aam_rs/Cargo.toml --release
env:
CARGO_NET_GIT_FETCH_WITH_CLI: "true"
- name: Run Rust tests for Ruby extension
run: cargo test --manifest-path ruby/ext/aam_rs/Cargo.toml
- name: Fix Ruby Extension Naming (Patching)
run: |
# Убираем системный префикс lib, чтобы Ruby нашел точку входа Init_aam_ruby
mv ruby/ext/aam_rs/target/release/libaam_ruby.so ruby/ext/aam_rs/target/release/aam_ruby.so 2>/dev/null || true
mv ruby/ext/aam_rs/target/release/libaam_rs_ruby.so ruby/ext/aam_rs/target/release/aam_rs_ruby.so 2>/dev/null || true
# Патчим импорт в рубишном файле на лету
sed -i 's/libaam_ruby/aam_ruby/g' ruby/lib/aam_rb.rb 2>/dev/null || true
sed -i 's/libaam_rs_ruby/aam_rs_ruby/g' ruby/lib/aam_rb.rb 2>/dev/null || true
- name: Run Ruby smoke test
run: ruby ruby/tests/test_aam_rs.rb
validate-php:
name: PHP Bindings - Build & Test
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: "8.3"
coverage: none
ini-values: ffi.enable=1
- name: Build Rust library with FFI
run: cargo build --release --features ffi
- name: Run PHP smoke test
env:
AAM_RS_LIB: ${{ github.workspace }}/target/release/libaam_rs.so
run: php php/tests/smoke.php
release-please:
needs:
[
validate,
validate-go,
validate-js,
validate-csharp,
validate-wasm,
validate-ruby,
validate-php,
]
runs-on: ubuntu-latest
outputs:
release_created: ${{ steps.release.outputs.release_created }}
tag_name: ${{ steps.release.outputs.tag_name }}
steps:
- name: Run Release Please
id: release
uses: googleapis/release-please-action@v4
with:
config-file: release-please-config.json
manifest-file: release-please-manifest.json
publish-cargo:
needs: release-please
if: ${{ needs.release-please.outputs.release_created == 'true' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@stable
- run: cargo publish --token ${{ secrets.CRATES_TOKEN }} --no-verify
build-node-bindings:
name: Build Node.js Native Addons
needs: [ release-please, generate-credits ]
if: ${{ needs.release-please.outputs.release_created == 'true' }}
strategy:
matrix:
include:
- os: ubuntu-latest
artifact: node-binding-linux-x64-gnu
binary: aam_rs_node.linux-x64-gnu.node
- os: macos-15-intel
artifact: node-binding-darwin-x64
binary: aam_rs_node.darwin-x64.node
- os: macos-latest
artifact: node-binding-darwin-arm64
binary: aam_rs_node.darwin-arm64.node
- os: windows-latest
artifact: node-binding-win32-x64-msvc
binary: aam_rs_node.win32-x64-msvc.node
runs-on: ${{ matrix.os }}
defaults:
run:
shell: bash
steps:
- uses: actions/checkout@v6
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Setup Rust cache
uses: Swatinem/rust-cache@v2
- name: Set up Node.js
uses: actions/setup-node@v6
with:
node-version: 24
- name: Install Node.js dependencies
working-directory: ./js
run: npm install
- name: Download CREDITS.html
uses: actions/download-artifact@v4
with:
name: credits-html
path: ./
- name: Copy licenses
run: cp LICENSE-MIT LICENSE-APACHE CREDITS.html js/
- name: Build release addon
working-directory: ./js
run: npm run build
- name: Upload addon artifact
uses: actions/upload-artifact@v7
with:
name: ${{ matrix.artifact }}
path: js/${{ matrix.binary }}
retention-days: 1
upload-node-to-release:
name: Upload Node.js Addons to Release
needs: [ release-please, build-node-bindings ]
if: ${{ needs.release-please.outputs.release_created == 'true' }}
runs-on: ubuntu-latest
steps:
- name: Download Node.js addon artifacts
uses: actions/download-artifact@v8
with:
pattern: node-binding-*
merge-multiple: true
path: node-artifacts
- name: Upload Node.js addons to Release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ needs.release-please.outputs.tag_name }}
files: node-artifacts/*.node
build-wasm-bindings:
name: Build & Test WASM Bindings
needs: [ release-please, generate-credits ]
if: ${{ needs.release-please.outputs.release_created == 'true' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
targets: wasm32-unknown-unknown
- name: Install wasm-pack
run: cargo install wasm-pack --locked
- name: Build WASM package
working-directory: ./wasm
run: wasm-pack build --release --target nodejs --out-dir pkg
- name: Run WASM tests
working-directory: ./wasm
run: |
cargo test
wasm-pack test --node
- name: Download CREDITS.html
uses: actions/download-artifact@v4
with:
name: credits-html
path: ./
- name: Copy licenses
run: cp LICENSE-MIT LICENSE-APACHE CREDITS.html wasm/pkg/
- name: Upload WASM artifact
uses: actions/upload-artifact@v7
with:
name: wasm-pkg
path: wasm/pkg
retention-days: 1
upload-wasm-to-release:
name: Upload WASM Package to Release
needs: [ release-please, build-wasm-bindings ]
if: ${{ needs.release-please.outputs.release_created == 'true' }}
runs-on: ubuntu-latest
steps:
- name: Download WASM package
uses: actions/download-artifact@v8
with:
name: wasm-pkg
path: wasm-pkg
- name: Zip WASM package
run: |
cd wasm-pkg
zip -r ../aam-wasm-package.zip ./*
- name: Upload WASM package to Release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ needs.release-please.outputs.tag_name }}
files: aam-wasm-package.zip
build-ruby-bindings:
name: Build & Test Ruby Bindings
needs: [ release-please, generate-credits ]
if: ${{ needs.release-please.outputs.release_created == 'true' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: "3.3"
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Build Ruby extension
run: cargo build --manifest-path ruby/ext/aam_rs/Cargo.toml --release
- name: Download CREDITS.html
uses: actions/download-artifact@v4
with:
name: credits-html
path: ./
- name: Copy licenses
run: cp LICENSE-MIT LICENSE-APACHE CREDITS.html ruby/
- name: Fix Ruby Naming and Prepare Payload
run: |
# Фикс имени для сборки гема + патч файла
cp ruby/ext/aam_rs/target/release/libaam_ruby.so ruby/lib/aam_ruby.so 2>/dev/null || true
cp ruby/ext/aam_rs/target/release/libaam_rs_ruby.so ruby/lib/aam_rs_ruby.so 2>/dev/null || true
sed -i 's/libaam_ruby/aam_ruby/g' ruby/lib/aam_rb.rb 2>/dev/null || true
sed -i 's/libaam_rs_ruby/aam_rs_ruby/g' ruby/lib/aam_rb.rb 2>/dev/null || true
cd ruby
gem build aam-ruby.gemspec --output ../aam-ruby.gem
- name: Upload Ruby artifact
uses: actions/upload-artifact@v7
with:
name: ruby-gem
path: aam-ruby.gem
retention-days: 1
upload-ruby-to-release:
name: Upload Ruby Gem to Release
needs: [ release-please, build-ruby-bindings ]
if: ${{ needs.release-please.outputs.release_created == 'true' }}
runs-on: ubuntu-latest
steps:
- name: Download Ruby artifact
uses: actions/download-artifact@v8
with:
name: ruby-gem
path: ruby-artifacts
- name: Upload Ruby package to Release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ needs.release-please.outputs.tag_name }}
files: ruby-artifacts/aam-ruby.gem
publish-ruby:
name: Publish Ruby Gem (RubyGems + GitHub Packages)
needs: [ release-please, build-ruby-bindings ]
if: ${{ needs.release-please.outputs.release_created == 'true' }}
runs-on: ubuntu-latest
steps:
- name: Download Ruby artifact
uses: actions/download-artifact@v8
with:
name: ruby-gem
path: ruby-artifacts
- name: Publish to RubyGems
env:
GEM_HOST_API_KEY: ${{ secrets.RUBY_GEMS_TOKEN }}
run: gem push ruby-artifacts/aam-ruby.gem
- name: Publish to GitHub Packages (RubyGems)
env:
GEM_HOST_API_KEY: ${{ secrets.GITHUB_TOKEN }}
run: |
OWNER=$(echo "${{ github.repository_owner }}" | tr '[:upper:]' '[:lower:]')
gem push --host "https://rubygems.pkg.github.com/$OWNER" ruby-artifacts/aam-ruby.gem
build-php-bindings:
name: Build & Test PHP Bindings
needs: [ release-please, generate-credits ]
if: ${{ needs.release-please.outputs.release_created == 'true' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: "8.3"
coverage: none
ini-values: ffi.enable=1
- name: Build native library for PHP FFI
run: cargo build --release --features ffi
- name: Download CREDITS.html
uses: actions/download-artifact@v4
with:
name: credits-html
path: ./
- name: Copy licenses
run: |
mkdir -p php-pkg
cp LICENSE-MIT LICENSE-APACHE CREDITS.html php-pkg/
- name: Package PHP artifacts
run: |
mkdir -p php-pkg/src php-pkg/tests php-pkg/native
cp php/src/AamPhp.php php-pkg/src/
cp php/tests/smoke.php php-pkg/tests/
cp php/README.md php-pkg/ 2>/dev/null || true
cp php/composer.json php-pkg/ 2>/dev/null || true
cp target/release/libaam_rs.so php-pkg/native/
cd php-pkg
zip -r ../aam-php-package.zip ./*
- name: Upload PHP artifact
uses: actions/upload-artifact@v7
with:
name: php-package
path: aam-php-package.zip
retention-days: 1
upload-php-to-release:
name: Upload PHP Package to Release
needs: [ release-please, build-php-bindings ]
if: ${{ needs.release-please.outputs.release_created == 'true' }}
runs-on: ubuntu-latest
steps:
- name: Download PHP package
uses: actions/download-artifact@v8
with:
name: php-package
path: .
- name: Upload PHP package to Release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ needs.release-please.outputs.tag_name }}
files: aam-php-package.zip
publish-php-mirror:
name: Publish PHP Package to Mirror Repo (Packagist)
needs: [ release-please, build-php-bindings ]
if: ${{ needs.release-please.outputs.release_created == 'true' }}
runs-on: ubuntu-latest
steps:
- name: Download PHP package artifact
uses: actions/download-artifact@v8
with:
name: php-package
path: php-artifact
- name: Push to PHP Mirror Repository
env:
TAG_NAME: ${{ needs.release-please.outputs.tag_name }}
TARGET_REPO: "ininids/aam-php"
MIRROR_TOKEN: ${{ secrets.PHP_MIRROR_TOKEN }}
run: |
mkdir php-repo
cd php-repo
unzip ../php-artifact/aam-php-package.zip
git init
git branch -M main
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add .
git commit -m "Release $TAG_NAME"
git tag "$TAG_NAME"
git remote add origin "https://x-access-token:${MIRROR_TOKEN}@github.com/${TARGET_REPO}.git"
git push origin main --force
git push origin "$TAG_NAME" --force
publish-npm:
name: Publish to npm
needs: [ release-please, build-node-bindings, generate-credits ]
if: ${{ needs.release-please.outputs.release_created == 'true' }}
runs-on: ubuntu-latest
defaults:
run:
shell: bash
steps:
- uses: actions/checkout@v6
- name: Set up Node.js
uses: actions/setup-node@v6
with:
node-version: 24
registry-url: https://registry.npmjs.org
- name: Download Node.js addon artifacts
uses: actions/download-artifact@v8
with:
pattern: node-binding-*
merge-multiple: true
path: node-artifacts
- name: Install Node.js dependencies
working-directory: ./js
run: npm install
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Download CREDITS.html
uses: actions/download-artifact@v4
with:
name: credits-html
path: ./
- name: Copy licenses
run: cp LICENSE-MIT LICENSE-APACHE CREDITS.html js/
- name: Populate platform packages
run: |
cp node-artifacts/aam_rs_node.linux-x64-gnu.node js/npm/linux-x64-gnu/
cp node-artifacts/aam_rs_node.darwin-x64.node js/npm/darwin-x64/
cp node-artifacts/aam_rs_node.darwin-arm64.node js/npm/darwin-arm64/
cp node-artifacts/aam_rs_node.win32-x64-msvc.node js/npm/win32-x64-msvc/
- name: Publish platform packages
working-directory: ./js
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN || secrets.NPM_TOKEN }}
run: |
npm publish ./npm/linux-x64-gnu --access public --provenance
npm publish ./npm/darwin-x64 --access public --provenance
npm publish ./npm/darwin-arm64 --access public --provenance
npm publish ./npm/win32-x64-msvc --access public --provenance
- name: Publish main package
working-directory: ./js
run: npm publish --access public --provenance
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN || secrets.NPM_TOKEN }}
publish-npm-github:
name: Publish Node package to GitHub Packages
needs: [ release-please, build-node-bindings, generate-credits ]
if: ${{ needs.release-please.outputs.release_created == 'true' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Set up Node.js for GitHub Packages
uses: actions/setup-node@v6
with:
node-version: 24
registry-url: https://npm.pkg.github.com
- name: Install Node.js dependencies
working-directory: ./js
run: npm install
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Download CREDITS.html
uses: actions/download-artifact@v4
with:
name: credits-html
path: ./
- name: Copy licenses
run: cp LICENSE-MIT LICENSE-APACHE CREDITS.html js/
- name: Publish scoped package to GitHub Packages
working-directory: ./js
env:
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
OWNER=$(echo "${{ github.repository_owner }}" | tr '[:upper:]' '[:lower:]')
npm pkg set name="@${OWNER}/aam-nodejs"
npm publish
publish-wasm-npm:
name: Publish WASM package to npm
needs: [ release-please, build-wasm-bindings ]
if: ${{ needs.release-please.outputs.release_created == 'true' }}
runs-on: ubuntu-latest
steps:
- name: Download WASM package artifact
uses: actions/download-artifact@v8
with:
name: wasm-pkg
path: wasm-pkg
- name: Set up Node.js
uses: actions/setup-node@v6
with:
node-version: 24
registry-url: https://registry.npmjs.org
- name: Publish WASM package to npm
working-directory: ./wasm-pkg
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN || secrets.NPM_TOKEN }}
run: npm publish --access public --provenance
build-c-libs:
needs: [ release-please, generate-credits ]
if: ${{ needs.release-please.outputs.release_created == 'true' }}
strategy:
matrix:
include:
- os: ubuntu-latest
artifact_name: aam-c-linux-x86_64
lib_name: aam-c.so
- os: macos-latest
artifact_name: aam-c-macos-x86_64
lib_name: aam-c.dylib
- os: windows-latest
artifact_name: aam-c-windows-x86_64
lib_name: aam-c.dll
runs-on: ${{ matrix.os }}
defaults:
run:
shell: bash
steps:
- uses: actions/checkout@v6
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Install cargo-binstall
uses: cargo-bins/cargo-binstall@main
- name: Install cbindgen
run: cargo binstall cbindgen -y
- name: Build release library
run: cargo build --release
- name: Prepare C/C++ Package Structure
run: |
mkdir -p package/include package/lib/cmake/aam-c package/bin package/examples
cbindgen --config cbindgen.toml --output package/include/aam-c.h
cp LICENSE package/ 2>/dev/null || true
cp examples/c/*.c package/examples/ 2>/dev/null || true
cp examples/c/*.aam package/examples/ 2>/dev/null || true
cp examples/c/Makefile package/examples/ 2>/dev/null || true
cp examples/c/CMakeLists.txt package/examples/ 2>/dev/null || true
cp aam-cConfig.cmake package/lib/cmake/aam-c/ 2>/dev/null || true
if [ "${{ runner.os }}" == "Windows" ]; then
cp target/release/aam_rs.dll package/bin/aam-c.dll
cp target/release/aam_rs.dll.lib package/lib/aam-c.lib
elif [ "${{ runner.os }}" == "macOS" ]; then
cp target/release/libaam_rs.dylib package/lib/libaam-c.dylib
else
cp target/release/libaam_rs.so package/lib/libaam-c.so
fi
- name: Download CREDITS.html
uses: actions/download-artifact@v4
with:
name: credits-html
path: ./
- name: Copy licenses
run: cp LICENSE-MIT LICENSE-APACHE CREDITS.html package/
- name: Zip Package
if: runner.os != 'Windows'
run: |
cd package
zip -r ../${{ matrix.artifact_name }}.zip ./*
- name: Zip Package (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: |
Compress-Archive -Path package\* -DestinationPath "${{ matrix.artifact_name }}.zip" -Force
- name: Upload Release Artifact
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ needs.release-please.outputs.tag_name }}
files: ${{ matrix.artifact_name }}.zip
build-csharp-libs:
name: Build C# Native Libraries
needs: release-please
if: ${{ needs.release-please.outputs.release_created == 'true' }}
strategy:
matrix:
include:
- os: ubuntu-latest
target: x86_64-unknown-linux-gnu
artifact: csharp-linux-x64
file: libaam_rs.so
- os: macos-15-intel
target: x86_64-apple-darwin
artifact: csharp-osx-x64
file: libaam_rs.dylib
- os: macos-latest
target: aarch64-apple-darwin
artifact: csharp-osx-arm64
file: libaam_rs.dylib
- os: windows-latest
target: x86_64-pc-windows-msvc
artifact: csharp-win-x64
file: aam_rs.dll
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v6
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
- name: Setup Rust cache
uses: Swatinem/rust-cache@v2
- name: Build release library for FFI
run: cargo build --release --features ffi --target ${{ matrix.target }}
- name: Upload C# native artifact
uses: actions/upload-artifact@v7
with:
name: ${{ matrix.artifact }}
path: target/${{ matrix.target }}/release/${{ matrix.file }}
retention-days: 1
linux:
needs: [ release-please, generate-credits ]
if: ${{ needs.release-please.outputs.release_created == 'true' }}
runs-on: ${{ matrix.platform.runner }}
strategy:
matrix:
platform:
- runner: ubuntu-22.04
target: x86_64
- runner: ubuntu-22.04
target: x86
- runner: ubuntu-22.04
target: aarch64
- runner: ubuntu-22.04
target: armv7
- runner: ubuntu-22.04
target: s390x
- runner: ubuntu-22.04
target: ppc64le
steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: 3.x
- name: Download CREDITS.html
uses: actions/download-artifact@v4
with:
name: credits-html
path: ./
- name: Build wheels
uses: PyO3/maturin-action@v1
with:
target: ${{ matrix.platform.target }}
args: --release --out dist
sccache: false
manylinux: auto
- name: Build free-threaded wheels
uses: PyO3/maturin-action@v1
with:
target: ${{ matrix.platform.target }}
args: --release --out dist -i python3.14t
sccache: false
manylinux: auto
- name: Upload wheels
uses: actions/upload-artifact@v7
with:
name: wheels-linux-${{ matrix.platform.target }}
path: dist
musllinux:
needs: [ release-please, generate-credits ]
if: ${{ needs.release-please.outputs.release_created == 'true' }}
runs-on: ${{ matrix.platform.runner }}
strategy:
matrix:
platform:
- runner: ubuntu-22.04
target: x86_64
- runner: ubuntu-22.04
target: x86
- runner: ubuntu-22.04
target: aarch64
- runner: ubuntu-22.04
target: armv7
steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: 3.x
- name: Download CREDITS.html
uses: actions/download-artifact@v4
with:
name: credits-html
path: ./
- name: Build wheels
uses: PyO3/maturin-action@v1
with:
target: ${{ matrix.platform.target }}
args: --release --out dist
sccache: false
manylinux: musllinux_1_2
- name: Build free-threaded wheels
uses: PyO3/maturin-action@v1
with:
target: ${{ matrix.platform.target }}
args: --release --out dist -i python3.14t
sccache: false
manylinux: musllinux_1_2
- name: Upload wheels
uses: actions/upload-artifact@v7
with:
name: wheels-musllinux-${{ matrix.platform.target }}
path: dist
windows:
needs: [ release-please, generate-credits ]
if: ${{ needs.release-please.outputs.release_created == 'true' }}
runs-on: ${{ matrix.platform.runner }}
strategy:
matrix:
platform:
- runner: windows-latest
target: x64
python_arch: x64
- runner: windows-latest
target: x86
python_arch: x86
- runner: windows-11-arm
target: aarch64
python_arch: arm64
steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: 3.13
architecture: ${{ matrix.platform.python_arch }}
- name: Download CREDITS.html
uses: actions/download-artifact@v4
with:
name: credits-html
path: ./
- name: Build wheels
uses: PyO3/maturin-action@v1
with:
target: ${{ matrix.platform.target }}
args: --release --out dist
sccache: false
- uses: actions/setup-python@v6
with:
python-version: 3.14t
architecture: ${{ matrix.platform.python_arch }}
- name: Build free-threaded wheels
uses: PyO3/maturin-action@v1
with:
target: ${{ matrix.platform.target }}
args: --release --out dist -i python3.14t
sccache: false
- name: Upload wheels
uses: actions/upload-artifact@v7
with:
name: wheels-windows-${{ matrix.platform.target }}
path: dist
macos:
needs: [ release-please, generate-credits ]
if: ${{ needs.release-please.outputs.release_created == 'true' }}
runs-on: ${{ matrix.platform.runner }}
strategy:
matrix:
platform:
- runner: macos-15-intel
target: x86_64
- runner: macos-latest
target: aarch64
steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: 3.x
- name: Download CREDITS.html
uses: actions/download-artifact@v4
with:
name: credits-html
path: ./
- name: Build wheels
uses: PyO3/maturin-action@v1
with:
target: ${{ matrix.platform.target }}
args: --release --out dist
sccache: false
- name: Build free-threaded wheels
uses: PyO3/maturin-action@v1
with:
target: ${{ matrix.platform.target }}
args: --release --out dist -i python3.14t
sccache: false
- name: Upload wheels
uses: actions/upload-artifact@v7
with:
name: wheels-macos-${{ matrix.platform.target }}
path: dist
sdist:
needs: [ release-please, generate-credits ]
if: ${{ needs.release-please.outputs.release_created == 'true' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Download CREDITS.html
uses: actions/download-artifact@v4
with:
name: credits-html
path: ./
- name: Build sdist
uses: PyO3/maturin-action@v1
with:
command: sdist
args: --out dist
- name: Upload sdist
uses: actions/upload-artifact@v7
with:
name: wheels-sdist
path: dist
upload-wheels-to-release:
name: Upload Python Wheels to Release
needs: [ release-please, linux, musllinux, windows, macos, sdist ]
if: ${{ needs.release-please.outputs.release_created == 'true' }}
runs-on: ubuntu-latest
steps:
- name: Download all wheels
uses: actions/download-artifact@v8
with:
pattern: wheels-*
merge-multiple: true
path: dist
- name: Upload Wheels and sdist to Release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ needs.release-please.outputs.tag_name }}
files: dist/*
publish-pypi:
name: Publish to PyPI
needs: [ release-please, linux, musllinux, windows, macos, sdist ]
if: ${{ needs.release-please.outputs.release_created == 'true' }}
runs-on: ubuntu-latest
steps:
- uses: actions/download-artifact@v8
with:
pattern: wheels-*
merge-multiple: true
path: dist
- name: Generate artifact attestation
uses: actions/attest-build-provenance@v3
with:
subject-path: "dist/*"
- name: Install uv
uses: astral-sh/setup-uv@v7
- name: Publish to PyPI
run: uv publish dist/*
env:
UV_PUBLISH_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
build-jni-libs:
name: Build JNI Native Libraries
needs: release-please
if: ${{ needs.release-please.outputs.release_created == 'true' }}
strategy:
matrix:
include:
- os: ubuntu-latest
target: x86_64-unknown-linux-gnu
artifact: jni-linux-x86_64
file: libaam_rs.so
- os: macos-15-intel
target: x86_64-apple-darwin
artifact: jni-macos-x86_64
file: libaam_rs.dylib
- os: macos-latest
target: aarch64-apple-darwin
artifact: jni-macos-aarch64
file: libaam_rs.dylib
- os: windows-latest
target: x86_64-pc-windows-msvc
artifact: jni-windows-x86_64
file: aam_rs.dll
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v6
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
- name: Build JNI release library
run: cargo build --release --target ${{ matrix.target }}
- name: Upload JNI artifact
uses: actions/upload-artifact@v7
with:
name: ${{ matrix.artifact }}
path: target/${{ matrix.target }}/release/${{ matrix.file }}
retention-days: 1
upload-jni-to-release:
name: Upload JNI to GitHub Release
needs: [ release-please, build-jni-libs ]
if: ${{ needs.release-please.outputs.release_created == 'true' }}
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Download all JNI artifacts
uses: actions/download-artifact@v8
with:
pattern: jni-*
path: jni-artifacts
merge-multiple: true
- name: Upload to GitHub Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAG_NAME: ${{ needs.release-please.outputs.tag_name }}
run: |
gh release upload "$TAG_NAME" jni-artifacts/*
build-go-libs:
name: Build Go Native Libs
needs: [ release-please, generate-credits ]
if: ${{ needs.release-please.outputs.release_created == 'true' }}
strategy:
matrix:
include:
- os: ubuntu-latest
target: x86_64-unknown-linux-gnu
artifact: aam-go-linux-x86_64
- os: macos-15-intel
target: x86_64-apple-darwin
artifact: aam-go-macos-x86_64
- os: macos-latest
target: aarch64-apple-darwin
artifact: aam-go-macos-aarch64
- os: windows-latest
target: x86_64-pc-windows-msvc
artifact: aam-go-windows-x86_64
runs-on: ${{ matrix.os }}
defaults:
run:
shell: bash
steps:
- uses: actions/checkout@v6
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
- name: Build Rust library with FFI (static + dynamic)
run: cargo build --release --features ffi --target ${{ matrix.target }}
- name: Download CREDITS.html
uses: actions/download-artifact@v4
with:
name: credits-html
path: ./
- name: Copy licenses
run: |
mkdir -p go-pkg
cp LICENSE-MIT LICENSE-APACHE CREDITS.html go-pkg/
- name: Package Go bindings
if: runner.os != 'Windows'
run: |
mkdir -p go-pkg/lib go-pkg/include go-pkg/src
cp include/aam.h go-pkg/include/
cp -r go/ go-pkg/src/
if [ "${{ runner.os }}" == "Windows" ]; then
cp target/${{ matrix.target }}/release/aam_rs.dll go-pkg/lib/ 2>/dev/null || true
cp target/${{ matrix.target }}/release/aam_rs.dll.lib go-pkg/lib/aam_rs.lib 2>/dev/null || true
elif [ "${{ runner.os }}" == "macOS" ]; then
cp target/${{ matrix.target }}/release/libaam_rs.a go-pkg/lib/ 2>/dev/null || true
cp target/${{ matrix.target }}/release/libaam_rs.dylib go-pkg/lib/ 2>/dev/null || true
else
cp target/${{ matrix.target }}/release/libaam_rs.a go-pkg/lib/ 2>/dev/null || true
cp target/${{ matrix.target }}/release/libaam_rs.so go-pkg/lib/ 2>/dev/null || true
fi
cd go-pkg && zip -r ../${{ matrix.artifact }}.zip ./*
- name: Package Go bindings (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: |
New-Item -ItemType Directory -Path go-pkg/lib,go-pkg/include,go-pkg/src -Force | Out-Null
Copy-Item include/aam.h go-pkg/include/
Copy-Item go go-pkg/src -Recurse
Copy-Item "target/${{ matrix.target }}/release/aam_rs.dll" go-pkg/lib/ -ErrorAction SilentlyContinue
Copy-Item "target/${{ matrix.target }}/release/aam_rs.dll.lib" go-pkg/lib/aam_rs.lib -ErrorAction SilentlyContinue
Compress-Archive -Path go-pkg\* -DestinationPath "${{ matrix.artifact }}.zip" -Force
- name: Upload Go package to Release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ needs.release-please.outputs.tag_name }}
files: ${{ matrix.artifact }}.zip
publish-java:
name: Publish Fat JAR & Upload to Release
needs: [ release-please, build-jni-libs, generate-credits ]
if: ${{ needs.release-please.outputs.release_created == 'true' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Set up JDK 17
uses: actions/setup-java@v5
with:
distribution: "temurin"
java-version: "17"
cache: "gradle"
- uses: actions/download-artifact@v8
with:
name: jni-linux-x86_64
path: java/src/main/resources/natives/linux-x86_64
- uses: actions/download-artifact@v8
with:
name: jni-macos-x86_64
path: java/src/main/resources/natives/macos-x86_64
- uses: actions/download-artifact@v8
with:
name: jni-macos-aarch64
path: java/src/main/resources/natives/macos-aarch64
- uses: actions/download-artifact@v8
with:
name: jni-windows-x86_64
path: java/src/main/resources/natives/windows-x86_64
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Download CREDITS.html
uses: actions/download-artifact@v4
with:
name: credits-html
path: ./
- name: Copy licenses
run: |
mkdir -p java/src/main/resources/META-INF
cp LICENSE-MIT LICENSE-APACHE CREDITS.html java/src/main/resources/META-INF/
- name: Build and Publish locally
working-directory: ./java
run: ./gradlew build publish
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.GPG_PRIVATE_KEY }}
ORG_GRADLE_PROJECT_signingInMemoryKeyPassword: ${{ secrets.GPG_PASSPHRASE }}
- name: Create Zip Bundle for Central Portal
working-directory: ./java
run: |
cd build/staging-repo
zip -r ../bundle.zip .
- name: Upload Bundle to Maven Central
working-directory: ./java
env:
CENTRAL_USERNAME: ${{ secrets.MAVEN_USERNAME }}
CENTRAL_PASSWORD: ${{ secrets.MAVEN_PASSWORD }}
run: |
echo "Uploading bundle to Maven Central Portal..."
curl --request POST \
--url 'https://central.sonatype.com/api/v1/publisher/upload?publishingType=AUTOMATIC' \
-u "$CENTRAL_USERNAME:$CENTRAL_PASSWORD" \
--header 'Accept: application/json' \
--form bundle=@build/bundle.zip \
--fail
- name: Upload JAR to Release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ needs.release-please.outputs.tag_name }}
files: java/build/libs/*.jar
publish-csharp:
name: Publish C# Package to NuGet
needs: [ release-please, build-csharp-libs, generate-credits ]
if: ${{ needs.release-please.outputs.release_created == 'true' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Setup .NET
uses: actions/setup-dotnet@v5
with:
dotnet-version: "10.0.x"
- uses: actions/download-artifact@v8
with:
name: csharp-linux-x64
path: csharp/runtimes/linux-x64/native
- uses: actions/download-artifact@v8
with:
name: csharp-osx-x64
path: csharp/runtimes/osx-x64/native
- uses: actions/download-artifact@v8
with:
name: csharp-osx-arm64
path: csharp/runtimes/osx-arm64/native
- uses: actions/download-artifact@v8
with:
name: csharp-win-x64
path: csharp/runtimes/win-x64/native
- name: Resolve package version
id: csharp_version
shell: bash
run: |
TAG="${{ needs.release-please.outputs.tag_name }}"
VERSION="${TAG##*-v}"
if [[ ! "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+([.-][0-9A-Za-z.-]+)?$ ]]; then
echo "Could not parse semantic version from tag: $TAG"
exit 1
fi
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Download CREDITS.html
uses: actions/download-artifact@v4
with:
name: credits-html
path: ./
- name: Copy licenses
run: cp LICENSE-MIT LICENSE-APACHE CREDITS.html csharp/
- name: Pack NuGet package
working-directory: ./csharp
run: dotnet pack AamCsharp.sln -c Release -p:Version=${{ steps.csharp_version.outputs.version }} -o artifacts
- name: Publish NuGet package
working-directory: ./csharp
run: dotnet nuget push "artifacts/*.nupkg" --source "https://api.nuget.org/v3/index.json" --api-key "${{ secrets.NUGET_API_KEY }}" --skip-duplicate
- name: Publish NuGet package to GitHub Packages
working-directory: ./csharp
run: |
dotnet nuget add source "https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json" \
--name github \
--username "${{ github.repository_owner }}" \
--password "${{ secrets.GITHUB_TOKEN }}" \
--store-password-in-clear-text
dotnet nuget push "artifacts/*.nupkg" --source github --api-key "${{ secrets.GITHUB_TOKEN }}" --skip-duplicate
- name: Upload NuGet package to Release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ needs.release-please.outputs.tag_name }}
files: csharp/artifacts/*.nupkg