2346 lines
87 KiB
YAML
2346 lines
87 KiB
YAML
name: Publish Release
|
|
|
|
# Action-first kreuzberg release pipeline.
|
|
#
|
|
# Orchestrates 16 alef language targets:
|
|
# crates · python · node · wasm · ruby · php · cli · homebrew · go · c-ffi
|
|
# java · csharp · elixir · dart · swift · zig · kotlin
|
|
# (R is excluded — distributed automatically by R-Universe from this repo's HEAD.)
|
|
#
|
|
# Mirrors html-to-markdown's publish.yaml composition: every registry
|
|
# interaction, every multi-platform build, and every release-asset upload
|
|
# routes through a shared kreuzberg-dev/actions composite. Repo-quirky inline
|
|
# bash is reserved for matrix expansion / artifact path stitching only.
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
inputs:
|
|
tag:
|
|
description: "Release tag to build (e.g., v5.0.0-rc.1)"
|
|
required: false
|
|
type: string
|
|
ref:
|
|
description: "Git ref (branch, tag, or commit) to build; defaults to the tag"
|
|
required: false
|
|
type: string
|
|
targets:
|
|
description: "Comma-separated list of release targets, or 'all'"
|
|
required: false
|
|
type: string
|
|
default: "all"
|
|
dry_run:
|
|
description: "Prepare artifacts without publishing"
|
|
required: false
|
|
type: boolean
|
|
default: false
|
|
republish:
|
|
description: "Delete and re-create the tag on current HEAD before publishing"
|
|
required: false
|
|
type: boolean
|
|
default: false
|
|
force_republish:
|
|
description: "Force republish targets whose registry version already exists"
|
|
required: false
|
|
type: boolean
|
|
default: false
|
|
release:
|
|
types: [published]
|
|
repository_dispatch:
|
|
types: [publish-release]
|
|
|
|
permissions:
|
|
contents: write
|
|
id-token: write
|
|
|
|
concurrency:
|
|
group: ${{ github.workflow }}-${{ (github.event_name == 'workflow_dispatch' && (github.event.inputs.ref || github.event.inputs.tag)) || github.ref || github.run_id }}
|
|
cancel-in-progress: false
|
|
|
|
jobs:
|
|
prepare:
|
|
name: Prepare metadata
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
tag: ${{ steps.meta.outputs.tag }}
|
|
version: ${{ steps.meta.outputs.version }}
|
|
ref: ${{ steps.meta.outputs.ref }}
|
|
checkout_ref: ${{ steps.meta.outputs.checkout_ref }}
|
|
target_sha: ${{ steps.meta.outputs.target_sha }}
|
|
matrix_ref: ${{ steps.meta.outputs.matrix_ref }}
|
|
is_tag: ${{ steps.meta.outputs.is_tag }}
|
|
is_prerelease: ${{ steps.meta.outputs.is_prerelease }}
|
|
npm_tag: ${{ steps.meta.outputs.npm_tag }}
|
|
dry_run: ${{ steps.meta.outputs.dry_run }}
|
|
force_republish: ${{ steps.meta.outputs.force_republish }}
|
|
release_targets: ${{ steps.meta.outputs.release_targets }}
|
|
release_any: ${{ steps.meta.outputs.release_any }}
|
|
release_python: ${{ steps.meta.outputs.release_python }}
|
|
release_node: ${{ steps.meta.outputs.release_node }}
|
|
release_ruby: ${{ steps.meta.outputs.release_ruby }}
|
|
release_cli: ${{ steps.meta.outputs.release_cli }}
|
|
release_crates: ${{ steps.meta.outputs.release_crates }}
|
|
release_homebrew: ${{ steps.meta.outputs.release_homebrew }}
|
|
release_java: ${{ steps.meta.outputs.release_java }}
|
|
release_csharp: ${{ steps.meta.outputs.release_csharp }}
|
|
release_go: ${{ steps.meta.outputs.release_go }}
|
|
release_wasm: ${{ steps.meta.outputs.release_wasm }}
|
|
release_php: ${{ steps.meta.outputs.release_php }}
|
|
release_elixir: ${{ steps.meta.outputs.release_elixir }}
|
|
release_c_ffi: ${{ steps.meta.outputs.release_c_ffi }}
|
|
release_dart: ${{ steps.meta.outputs.release_dart }}
|
|
release_swift: ${{ steps.meta.outputs.release_swift }}
|
|
release_zig: ${{ steps.meta.outputs.release_zig }}
|
|
release_kotlin: ${{ steps.meta.outputs.release_kotlin }}
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v6.0.2
|
|
with:
|
|
ref: ${{ (inputs.republish == true && (inputs.ref || github.event.repository.default_branch)) || inputs.ref || inputs.tag || github.ref }}
|
|
fetch-depth: 0
|
|
|
|
- name: Retag for republish
|
|
if: ${{ inputs.republish == true || github.event.client_payload.republish == true }}
|
|
uses: kreuzberg-dev/actions/retag-for-republish@v1
|
|
with:
|
|
tag: ${{ inputs.tag || github.event.client_payload.tag }}
|
|
token: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
- name: Resolve release metadata
|
|
id: meta
|
|
uses: kreuzberg-dev/actions/prepare-release-metadata@v1
|
|
|
|
- name: Ensure GitHub Release exists for tag
|
|
if: ${{ steps.meta.outputs.is_tag == 'true' && steps.meta.outputs.dry_run != 'true' }}
|
|
uses: kreuzberg-dev/actions/publish-github-release@v1
|
|
with:
|
|
tag: ${{ steps.meta.outputs.tag }}
|
|
target: ${{ steps.meta.outputs.target_sha }}
|
|
notes: "Release ${{ steps.meta.outputs.tag }}"
|
|
draft: "true"
|
|
prerelease: ${{ steps.meta.outputs.is_prerelease }}
|
|
|
|
validate-versions:
|
|
name: Validate language manifest versions
|
|
needs: prepare
|
|
if: ${{ needs.prepare.outputs.is_tag == 'true' }}
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v6.0.2
|
|
with:
|
|
ref: ${{ needs.prepare.outputs.checkout_ref }}
|
|
fetch-depth: 0
|
|
|
|
- name: Validate versions
|
|
uses: kreuzberg-dev/actions/validate-versions@v1
|
|
with:
|
|
version: ${{ needs.prepare.outputs.version }}
|
|
|
|
# ─── Registry existence checks ────────────────────────────────────────
|
|
|
|
check-pypi:
|
|
name: Check PyPI for existing version
|
|
needs: prepare
|
|
if: ${{ needs.prepare.outputs.is_tag == 'true' && needs.prepare.outputs.release_python == 'true' }}
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
exists: ${{ steps.check.outputs.exists }}
|
|
steps:
|
|
- id: check
|
|
uses: kreuzberg-dev/actions/check-registry@v1
|
|
with:
|
|
registry: pypi
|
|
package: kreuzberg
|
|
version: ${{ needs.prepare.outputs.version }}
|
|
|
|
check-npm:
|
|
name: Check npm for existing versions
|
|
needs: prepare
|
|
if: ${{ needs.prepare.outputs.is_tag == 'true' && (needs.prepare.outputs.release_node == 'true' || needs.prepare.outputs.release_wasm == 'true') }}
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
node_exists: ${{ steps.check.outputs.exists }}
|
|
wasm_exists: ${{ steps.check.outputs.wasm_exists }}
|
|
steps:
|
|
- id: check
|
|
uses: kreuzberg-dev/actions/check-registry@v1
|
|
with:
|
|
registry: npm
|
|
package: "@kreuzberg/node"
|
|
version: ${{ needs.prepare.outputs.version }}
|
|
extra-packages: |
|
|
wasm_exists=@kreuzberg/wasm
|
|
|
|
check-rubygems:
|
|
name: Check RubyGems for existing version
|
|
needs: prepare
|
|
if: ${{ needs.prepare.outputs.is_tag == 'true' && needs.prepare.outputs.release_ruby == 'true' }}
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
exists: ${{ steps.check.outputs.exists }}
|
|
steps:
|
|
- id: check
|
|
uses: kreuzberg-dev/actions/check-registry@v1
|
|
with:
|
|
registry: rubygems
|
|
package: kreuzberg
|
|
version: ${{ needs.prepare.outputs.version }}
|
|
|
|
check-maven:
|
|
name: Check Maven Central for existing version
|
|
needs: prepare
|
|
if: ${{ needs.prepare.outputs.is_tag == 'true' && (needs.prepare.outputs.release_java == 'true' || needs.prepare.outputs.release_kotlin == 'true') }}
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
java_exists: ${{ steps.check.outputs.exists }}
|
|
kotlin_exists: ${{ steps.check.outputs.kotlin_exists }}
|
|
steps:
|
|
- id: check
|
|
uses: kreuzberg-dev/actions/check-registry@v1
|
|
with:
|
|
registry: maven
|
|
package: "dev.kreuzberg:kreuzberg"
|
|
version: ${{ needs.prepare.outputs.version }}
|
|
extra-packages: |
|
|
kotlin_exists=dev.kreuzberg:kreuzberg-android
|
|
|
|
check-nuget:
|
|
name: Check NuGet for existing version
|
|
needs: prepare
|
|
if: ${{ needs.prepare.outputs.is_tag == 'true' && needs.prepare.outputs.release_csharp == 'true' }}
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
exists: ${{ steps.check.outputs.exists }}
|
|
steps:
|
|
- id: check
|
|
uses: kreuzberg-dev/actions/check-registry@v1
|
|
with:
|
|
registry: nuget
|
|
package: Kreuzberg
|
|
version: ${{ needs.prepare.outputs.version }}
|
|
|
|
check-packagist:
|
|
name: Check Packagist for existing version
|
|
needs: prepare
|
|
if: ${{ needs.prepare.outputs.is_tag == 'true' && needs.prepare.outputs.release_php == 'true' }}
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
exists: ${{ steps.check.outputs.exists }}
|
|
steps:
|
|
- id: check
|
|
uses: kreuzberg-dev/actions/check-registry@v1
|
|
with:
|
|
registry: packagist
|
|
package: kreuzberg/kreuzberg
|
|
version: ${{ needs.prepare.outputs.version }}
|
|
|
|
check-cratesio:
|
|
name: Check crates.io for existing versions
|
|
needs: prepare
|
|
if: ${{ needs.prepare.outputs.is_tag == 'true' && needs.prepare.outputs.release_crates == 'true' }}
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
kreuzberg_exists: ${{ steps.check.outputs.exists }}
|
|
tesseract_exists: ${{ steps.check.outputs.tesseract_exists }}
|
|
paddle_exists: ${{ steps.check.outputs.paddle_exists }}
|
|
cli_exists: ${{ steps.check.outputs.cli_exists }}
|
|
all_exist: ${{ steps.derive.outputs.all_exist }}
|
|
steps:
|
|
- id: check
|
|
uses: kreuzberg-dev/actions/check-registry@v1
|
|
with:
|
|
registry: cratesio
|
|
package: kreuzberg
|
|
version: ${{ needs.prepare.outputs.version }}
|
|
extra-packages: |
|
|
tesseract_exists=kreuzberg-tesseract
|
|
paddle_exists=kreuzberg-paddle-ocr
|
|
cli_exists=kreuzberg-cli
|
|
|
|
- id: derive
|
|
# Inline: aggregate four check-registry outputs into a single boolean
|
|
# the publish-crates job can guard on. No shared action equivalent.
|
|
run: |
|
|
if [[ "${{ steps.check.outputs.exists }}" == "true" \
|
|
&& "${{ steps.check.outputs.tesseract_exists }}" == "true" \
|
|
&& "${{ steps.check.outputs.paddle_exists }}" == "true" \
|
|
&& "${{ steps.check.outputs.cli_exists }}" == "true" ]]; then
|
|
echo "all_exist=true" >> "$GITHUB_OUTPUT"
|
|
else
|
|
echo "all_exist=false" >> "$GITHUB_OUTPUT"
|
|
fi
|
|
|
|
check-hex:
|
|
name: Check Hex.pm for existing versions
|
|
needs: prepare
|
|
if: ${{ needs.prepare.outputs.is_tag == 'true' && needs.prepare.outputs.release_elixir == 'true' }}
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
elixir_exists: ${{ steps.check.outputs.exists }}
|
|
steps:
|
|
- id: check
|
|
uses: kreuzberg-dev/actions/check-registry@v1
|
|
with:
|
|
registry: hex
|
|
package: kreuzberg
|
|
version: ${{ needs.prepare.outputs.version }}
|
|
|
|
check-pub:
|
|
name: Check pub.dev for existing version
|
|
needs: prepare
|
|
if: ${{ needs.prepare.outputs.is_tag == 'true' && needs.prepare.outputs.release_dart == 'true' }}
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
exists: ${{ steps.check.outputs.exists }}
|
|
steps:
|
|
- id: check
|
|
uses: kreuzberg-dev/actions/check-registry@v1
|
|
with:
|
|
registry: pub
|
|
package: kreuzberg
|
|
version: ${{ needs.prepare.outputs.version }}
|
|
|
|
check-zig:
|
|
name: Check Zig package presence
|
|
needs: prepare
|
|
if: ${{ (needs.prepare.outputs.is_tag == 'true' || needs.prepare.outputs.dry_run == 'true') && needs.prepare.outputs.release_zig == 'true' }}
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
exists: ${{ steps.check.outputs.exists }}
|
|
steps:
|
|
- id: check
|
|
# `registry: github-release` (not `registry: zig`) — alef check-registry's
|
|
# zig path only verifies the release tag exists. On a real release that's
|
|
# always true, so it short-circuits `publish-zig` to skipped (regression:
|
|
# v4.x shipped without the zig tarball asset because of this). Verify
|
|
# the actual asset is present instead.
|
|
uses: kreuzberg-dev/actions/check-registry@v1
|
|
with:
|
|
registry: github-release
|
|
package: kreuzberg-zig-v${{ needs.prepare.outputs.version }}.tar.gz
|
|
version: ${{ needs.prepare.outputs.version }}
|
|
repo: ${{ github.repository }}
|
|
assets: kreuzberg-zig-v${{ needs.prepare.outputs.version }}.tar.gz
|
|
|
|
check-homebrew:
|
|
name: Check Homebrew tap for formula
|
|
needs: prepare
|
|
if: ${{ needs.prepare.outputs.is_tag == 'true' && needs.prepare.outputs.release_homebrew == 'true' }}
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
exists: ${{ steps.check.outputs.exists }}
|
|
steps:
|
|
- id: check
|
|
uses: kreuzberg-dev/actions/check-registry@v1
|
|
with:
|
|
registry: homebrew
|
|
package: kreuzberg
|
|
version: ${{ needs.prepare.outputs.version }}
|
|
tap-repo: kreuzberg-dev/homebrew-tap
|
|
|
|
check-cli:
|
|
name: Check GitHub Release for CLI assets
|
|
needs: prepare
|
|
if: ${{ needs.prepare.outputs.is_tag == 'true' && needs.prepare.outputs.release_cli == 'true' }}
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
exists: ${{ steps.check.outputs.exists }}
|
|
steps:
|
|
- id: check
|
|
uses: kreuzberg-dev/actions/check-registry@v1
|
|
with:
|
|
registry: github-release
|
|
package: kreuzberg
|
|
version: ${{ needs.prepare.outputs.version }}
|
|
repo: kreuzberg-dev/kreuzberg
|
|
tag: ${{ needs.prepare.outputs.tag }}
|
|
asset-prefix: kreuzberg-cli-
|
|
assets: |
|
|
kreuzberg-cli-aarch64-apple-darwin.tar.gz,kreuzberg-cli-aarch64-unknown-linux-gnu.tar.gz,kreuzberg-cli-aarch64-unknown-linux-musl.tar.gz,kreuzberg-cli-x86_64-unknown-linux-gnu.tar.gz,kreuzberg-cli-x86_64-unknown-linux-musl.tar.gz,kreuzberg-cli-x86_64-pc-windows-msvc.zip
|
|
|
|
check-go:
|
|
name: Check GitHub Release for Go FFI assets
|
|
needs: prepare
|
|
if: ${{ needs.prepare.outputs.is_tag == 'true' && needs.prepare.outputs.release_go == 'true' }}
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
exists: ${{ steps.check.outputs.exists }}
|
|
steps:
|
|
- id: check
|
|
uses: kreuzberg-dev/actions/check-registry@v1
|
|
with:
|
|
registry: github-release
|
|
package: kreuzberg
|
|
version: ${{ needs.prepare.outputs.version }}
|
|
repo: kreuzberg-dev/kreuzberg
|
|
tag: ${{ needs.prepare.outputs.tag }}
|
|
asset-prefix: kreuzberg-go-
|
|
|
|
check-c-ffi:
|
|
name: Check GitHub Release for C FFI assets
|
|
needs: prepare
|
|
if: ${{ needs.prepare.outputs.is_tag == 'true' && needs.prepare.outputs.release_c_ffi == 'true' }}
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
exists: ${{ steps.check.outputs.exists }}
|
|
steps:
|
|
- id: check
|
|
uses: kreuzberg-dev/actions/check-registry@v1
|
|
with:
|
|
registry: github-release
|
|
package: kreuzberg
|
|
version: ${{ needs.prepare.outputs.version }}
|
|
repo: kreuzberg-dev/kreuzberg
|
|
tag: ${{ needs.prepare.outputs.tag }}
|
|
asset-prefix: kreuzberg-ffi-
|
|
|
|
check-elixir-release:
|
|
name: Check GitHub Release for Elixir NIF assets
|
|
needs: prepare
|
|
if: ${{ needs.prepare.outputs.is_tag == 'true' && needs.prepare.outputs.release_elixir == 'true' }}
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
exists: ${{ steps.check.outputs.exists }}
|
|
steps:
|
|
- id: check
|
|
uses: kreuzberg-dev/actions/check-registry@v1
|
|
with:
|
|
registry: github-release
|
|
package: kreuzberg
|
|
version: ${{ needs.prepare.outputs.version }}
|
|
repo: kreuzberg-dev/kreuzberg
|
|
tag: ${{ needs.prepare.outputs.tag }}
|
|
asset-prefix: libkreuzberg_nif-
|
|
|
|
# ─── Build matrix jobs ────────────────────────────────────────────────
|
|
|
|
python-wheels:
|
|
name: Build Python wheels (${{ matrix.os }})
|
|
needs: [prepare, check-pypi]
|
|
if: ${{ needs.prepare.outputs.release_python == 'true' && (needs.check-pypi.outputs.exists != 'true' || needs.prepare.outputs.force_republish == 'true') }}
|
|
runs-on: ${{ matrix.os }}
|
|
env:
|
|
MACOSX_DEPLOYMENT_TARGET: "10.12"
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
os: [ubuntu-latest, ubuntu-24.04-arm, windows-latest, macos-latest]
|
|
steps:
|
|
- uses: actions/checkout@v6.0.2
|
|
with:
|
|
ref: ${{ needs.prepare.outputs.checkout_ref }}
|
|
fetch-depth: 0
|
|
|
|
submodules: recursive
|
|
- name: Build wheels
|
|
uses: kreuzberg-dev/actions/build-python-wheels@v1
|
|
with:
|
|
python-version: "3.13"
|
|
package-dir: packages/python
|
|
# PyO3 abi3-py310 → one wheel per platform covers Python 3.10+.
|
|
cibw-build: "cp310-*"
|
|
upload-artifact: "false"
|
|
# AlmaLinux 8 base ships OpenSSL 1.1.1 (CentOS 7 base of manylinux2014
|
|
# ships 1.0.2k which openssl-sys 0.9.115+ rejects).
|
|
manylinux-x86_64-image: "manylinux_2_28"
|
|
manylinux-aarch64-image: "manylinux_2_28"
|
|
# manylinux_2_28 (AlmaLinux 8) ships OpenSSL 1.1.1 — manylinux2014 ships 1.0.2k
|
|
# which openssl-sys 0.9.115+ rejects. CARGO_TARGET_*_LINKER points cargo at the
|
|
# in-image gcc instead of looking for triple-prefixed binaries that aren't there.
|
|
cibw-before-build-linux: "dnf install -y openssl-devel pkgconfig && pip install maturin uv && source ~/.cargo/env"
|
|
cibw-environment: 'MATURIN_BUILD_ARGS="--compatibility manylinux_2_28" CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER=gcc CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=gcc CC_x86_64_unknown_linux_gnu=gcc CC_aarch64_unknown_linux_gnu=gcc CXX_x86_64_unknown_linux_gnu=g++ CXX_aarch64_unknown_linux_gnu=g++'
|
|
# cibw's bundled rustup-init on Windows defaults host triple to gnu, and
|
|
# rust-toolchain.toml channel="1.95" resolves against that gnu host. Install
|
|
# 1.95-x86_64-pc-windows-msvc explicitly AND set RUSTUP_TOOLCHAIN env var so
|
|
# cargo bypasses the toolchain.toml override (env var > toml in rustup precedence).
|
|
cibw-before-build-windows: "rustup install 1.95-x86_64-pc-windows-msvc --profile minimal --component rust-src --component rustfmt --component clippy && rustup target add x86_64-pc-windows-msvc --toolchain 1.95-x86_64-pc-windows-msvc && pip install maturin uv && set PATH=%USERPROFILE%\\.cargo\\bin;%PATH%"
|
|
cibw-environment-windows: 'MATURIN_BUILD_ARGS="--target x86_64-pc-windows-msvc" RUSTUP_TOOLCHAIN="1.95-x86_64-pc-windows-msvc"'
|
|
|
|
- name: Upload wheels
|
|
uses: actions/upload-artifact@v7.0.1
|
|
with:
|
|
name: python-wheels-${{ matrix.os }}
|
|
path: wheelhouse/*.whl
|
|
retention-days: 14
|
|
|
|
python-sdist:
|
|
name: Build Python sdist
|
|
# The sdist compiles on the consumer's machine, so its Cargo.toml must carry
|
|
# registry version-deps, not workspace paths. build-python-sdist@v1 rewrites
|
|
# them (--require-registry) then runs maturin sdist, so the core crates must be
|
|
# on crates.io first. The status guard lets it run when publish-crates is
|
|
# skipped, blocking only on its actual failure.
|
|
needs: [prepare, check-pypi, publish-crates]
|
|
if: ${{ !cancelled() && needs.publish-crates.result != 'failure' && needs.prepare.outputs.release_python == 'true' && (needs.check-pypi.outputs.exists != 'true' || needs.prepare.outputs.force_republish == 'true') }}
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v6.0.2
|
|
with:
|
|
ref: ${{ needs.prepare.outputs.checkout_ref }}
|
|
fetch-depth: 0
|
|
|
|
submodules: recursive
|
|
- uses: kreuzberg-dev/actions/setup-rust@v1
|
|
- uses: actions/setup-python@v6.2.0
|
|
with:
|
|
python-version: "3.13"
|
|
|
|
- uses: kreuzberg-dev/actions/build-python-sdist@v1
|
|
with:
|
|
manifest-path: crates/kreuzberg-py/Cargo.toml
|
|
output-dir: dist
|
|
|
|
- uses: actions/upload-artifact@v7.0.1
|
|
with:
|
|
name: python-sdist
|
|
path: dist/*.tar.gz
|
|
retention-days: 14
|
|
|
|
node-bindings:
|
|
name: Build Node bindings (${{ matrix.target }})
|
|
needs: [prepare, check-npm]
|
|
if: ${{ needs.prepare.outputs.release_node == 'true' && (needs.check-npm.outputs.node_exists != 'true' || needs.prepare.outputs.force_republish == 'true') }}
|
|
runs-on: ${{ matrix.os }}
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- { os: ubuntu-latest, target: x86_64-unknown-linux-gnu }
|
|
- { os: ubuntu-24.04-arm, target: aarch64-unknown-linux-gnu }
|
|
- { os: macos-latest, target: aarch64-apple-darwin }
|
|
- { os: windows-latest, target: x86_64-pc-windows-msvc }
|
|
steps:
|
|
- uses: actions/checkout@v6.0.2
|
|
with:
|
|
ref: ${{ needs.prepare.outputs.checkout_ref }}
|
|
fetch-depth: 0
|
|
|
|
submodules: recursive
|
|
- uses: kreuzberg-dev/actions/setup-rust@v1
|
|
with:
|
|
target: ${{ matrix.target }}
|
|
|
|
- uses: kreuzberg-dev/actions/setup-node-workspace@v1
|
|
with:
|
|
node-version: "24"
|
|
|
|
- name: Build NAPI binding
|
|
uses: kreuzberg-dev/actions/build-node-napi@v1
|
|
with:
|
|
crate-dir: crates/kreuzberg-node
|
|
build-command: pnpm exec napi build --release --target ${{ matrix.target }} --platform
|
|
|
|
- uses: actions/upload-artifact@v7.0.1
|
|
with:
|
|
name: node-bindings-${{ matrix.target }}
|
|
path: crates/kreuzberg-node/*.node
|
|
retention-days: 14
|
|
|
|
wasm-bindings:
|
|
name: Build WASM package
|
|
needs: [prepare, check-npm]
|
|
if: ${{ needs.prepare.outputs.release_wasm == 'true' && (needs.check-npm.outputs.wasm_exists != 'true' || needs.prepare.outputs.force_republish == 'true') }}
|
|
runs-on: ubuntu-latest
|
|
# WASM cold-build of kreuzberg-wasm (no-ORT feature set) runs ~12-15 min.
|
|
# GHA cancelled this job at the ~12-min mark with "runner shutdown signal"
|
|
# in three consecutive runs (preemption, not timeout). Explicit timeout
|
|
# bounds the budget; a dedicated cache-key-prefix keeps the WASM target
|
|
# cache warm across runs and brings rebuilds under 5 min.
|
|
timeout-minutes: 90
|
|
steps:
|
|
- uses: actions/checkout@v6.0.2
|
|
with:
|
|
ref: ${{ needs.prepare.outputs.checkout_ref }}
|
|
fetch-depth: 0
|
|
|
|
submodules: recursive
|
|
- uses: kreuzberg-dev/actions/setup-rust@v1
|
|
with:
|
|
target: wasm32-unknown-unknown
|
|
cache-key-prefix: wasm-bindings
|
|
|
|
- uses: kreuzberg-dev/actions/install-wasi-sdk@v1
|
|
|
|
- uses: kreuzberg-dev/actions/setup-node-workspace@v1
|
|
with:
|
|
node-version: "24"
|
|
|
|
- uses: kreuzberg-dev/actions/build-wasm-package@v1
|
|
with:
|
|
crate-dir: crates/kreuzberg-wasm
|
|
pack-tarball: "true"
|
|
|
|
- uses: actions/upload-artifact@v7.0.1
|
|
with:
|
|
name: wasm-bundle
|
|
path: |
|
|
crates/kreuzberg-wasm/dist/**
|
|
crates/kreuzberg-wasm/dist-node/**
|
|
crates/kreuzberg-wasm/dist-web/**
|
|
retention-days: 14
|
|
|
|
ruby-gem:
|
|
name: Build Ruby gem (${{ matrix.label }})
|
|
# build-ruby-gem@v1 rewrites workspace path-deps to registry version-deps
|
|
# (--require-registry) before compiling, so the core crates must be on
|
|
# crates.io first: order after publish-crates. The status guard lets the build
|
|
# still run when publish-crates is skipped (crates already published), blocking
|
|
# only on its actual failure.
|
|
needs: [prepare, check-rubygems, publish-crates]
|
|
if: ${{ !cancelled() && needs.publish-crates.result != 'failure' && needs.prepare.outputs.release_ruby == 'true' && (needs.check-rubygems.outputs.exists != 'true' || needs.prepare.outputs.force_republish == 'true') }}
|
|
runs-on: ${{ matrix.os }}
|
|
env:
|
|
RB_SYS_CARGO_PROFILE: release
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- { os: ubuntu-latest, label: linux-x86_64 }
|
|
- { os: ubuntu-24.04-arm, label: linux-aarch64 }
|
|
- { os: macos-latest, label: macos-arm64 }
|
|
# Ruby on Windows is MinGW (rb-sys → x86_64-pc-windows-gnu) but ort-sys
|
|
# only ships msvc prebuilts; the ABIs are incompatible. Skip until ORT
|
|
# publishes mingw binaries or kreuzberg moves to ort-tract on Ruby/Win.
|
|
steps:
|
|
- uses: actions/checkout@v6.0.2
|
|
with:
|
|
ref: ${{ needs.prepare.outputs.checkout_ref }}
|
|
fetch-depth: 0
|
|
|
|
submodules: recursive
|
|
- uses: kreuzberg-dev/actions/setup-rust@v1
|
|
|
|
- uses: ruby/setup-ruby@v1.309.0
|
|
with:
|
|
ruby-version: "3.3"
|
|
bundler-cache: false
|
|
|
|
- uses: kreuzberg-dev/actions/build-ruby-gem@v1
|
|
with:
|
|
package-dir: packages/ruby
|
|
|
|
- name: Package gem
|
|
# Inline: rake build emits the .gem under pkg/; no shared action wraps it.
|
|
working-directory: packages/ruby
|
|
run: bundle exec rake build
|
|
shell: bash
|
|
|
|
- uses: actions/upload-artifact@v7.0.1
|
|
with:
|
|
name: rubygems-${{ matrix.label }}
|
|
path: packages/ruby/pkg/*.gem
|
|
retention-days: 14
|
|
|
|
php-extension:
|
|
name: Build PHP extension (php${{ matrix.php }} ${{ matrix.platform.label }})
|
|
# build-php-extension@v1 rewrites path-deps to registry versions before
|
|
# building; the core crates must be published first. The status guard lets the
|
|
# build run when publish-crates is skipped, blocking only on its actual failure.
|
|
needs: [prepare, check-packagist, publish-crates]
|
|
if: ${{ !cancelled() && needs.publish-crates.result != 'failure' && needs.prepare.outputs.release_php == 'true' && (needs.check-packagist.outputs.exists != 'true' || needs.prepare.outputs.force_republish == 'true') }}
|
|
runs-on: ${{ matrix.platform.os }}
|
|
timeout-minutes: 60
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
php: ["8.2", "8.3", "8.4"]
|
|
platform:
|
|
- { os: ubuntu-latest, label: linux-x86_64, target: x86_64-unknown-linux-gnu }
|
|
- { os: ubuntu-24.04-arm, label: linux-arm64, target: aarch64-unknown-linux-gnu }
|
|
- { os: macos-latest, label: macos-arm64, target: aarch64-apple-darwin }
|
|
- { os: windows-latest, label: windows-x86_64, target: x86_64-pc-windows-msvc }
|
|
steps:
|
|
- uses: actions/checkout@v6.0.2
|
|
with:
|
|
ref: ${{ needs.prepare.outputs.checkout_ref }}
|
|
fetch-depth: 0
|
|
|
|
submodules: recursive
|
|
- uses: kreuzberg-dev/actions/setup-php@v1
|
|
with:
|
|
php-version: ${{ matrix.php }}
|
|
|
|
- uses: kreuzberg-dev/actions/setup-rust@v1
|
|
with:
|
|
target: ${{ matrix.platform.target }}
|
|
|
|
- uses: kreuzberg-dev/actions/build-php-extension@v1
|
|
with:
|
|
crate-name: kreuzberg-php
|
|
lib-name: kreuzberg_php
|
|
php-version: ${{ matrix.php }}
|
|
php-ts: nts
|
|
|
|
- uses: kreuzberg-dev/actions/install-alef@v1
|
|
|
|
- uses: kreuzberg-dev/actions/package-php-pie@v1
|
|
with:
|
|
php-version: ${{ matrix.php }}
|
|
php-ts: nts
|
|
target: ${{ matrix.platform.target }}
|
|
windows-compiler: ${{ contains(matrix.platform.target, 'windows') && 'vs17' || '' }}
|
|
version: ${{ needs.prepare.outputs.version }}
|
|
output-dir: dist/php-package
|
|
|
|
- uses: actions/upload-artifact@v7.0.1
|
|
with:
|
|
name: php-package-${{ matrix.platform.label }}-php${{ matrix.php }}
|
|
path: |
|
|
dist/php-package/php_*.tgz
|
|
dist/php-package/php_*.tgz.sha256
|
|
dist/php-package/php_*.zip
|
|
dist/php-package/php_*.zip.sha256
|
|
retention-days: 14
|
|
|
|
cli-binaries:
|
|
name: Build CLI binary (${{ matrix.target }})
|
|
needs: [prepare, check-cli]
|
|
if: ${{ needs.prepare.outputs.release_cli == 'true' && (needs.check-cli.outputs.exists != 'true' || needs.prepare.outputs.force_republish == 'true') }}
|
|
runs-on: ${{ matrix.os }}
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- { os: ubuntu-latest, target: x86_64-unknown-linux-gnu }
|
|
- { os: ubuntu-24.04-arm, target: aarch64-unknown-linux-gnu }
|
|
- { os: macos-latest, target: aarch64-apple-darwin }
|
|
- { os: windows-latest, target: x86_64-pc-windows-msvc }
|
|
steps:
|
|
- uses: actions/checkout@v6.0.2
|
|
with:
|
|
ref: ${{ needs.prepare.outputs.checkout_ref }}
|
|
fetch-depth: 0
|
|
|
|
submodules: recursive
|
|
- uses: kreuzberg-dev/actions/setup-rust@v1
|
|
with:
|
|
target: ${{ matrix.target }}
|
|
|
|
- uses: kreuzberg-dev/actions/build-rust-cli@v1
|
|
id: build
|
|
with:
|
|
package-name: kreuzberg-cli
|
|
binary-name: kreuzberg
|
|
target: ${{ matrix.target }}
|
|
|
|
- name: Package CLI artifact
|
|
# Inline: archive layout (.tar.gz on Unix, .zip on Windows) varies per
|
|
# OS in a way no shared action covers; tiny and self-contained.
|
|
env:
|
|
BINARY_PATH: ${{ steps.build.outputs.binary-path }}
|
|
TARGET: ${{ matrix.target }}
|
|
shell: bash
|
|
run: |
|
|
STAGE="kreuzberg-cli-${TARGET}"
|
|
mkdir -p "$STAGE"
|
|
if [[ "$RUNNER_OS" == "Windows" ]]; then
|
|
cp "$BINARY_PATH" "$STAGE/kreuzberg.exe"
|
|
7z a "${STAGE}.zip" "$STAGE" >/dev/null
|
|
else
|
|
cp "$BINARY_PATH" "$STAGE/kreuzberg"
|
|
tar -czf "${STAGE}.tar.gz" "$STAGE"
|
|
fi
|
|
|
|
- uses: actions/upload-artifact@v7.0.1
|
|
with:
|
|
name: cli-${{ matrix.target }}
|
|
path: |
|
|
kreuzberg-cli-${{ matrix.target }}.tar.gz
|
|
kreuzberg-cli-${{ matrix.target }}.zip
|
|
if-no-files-found: ignore
|
|
retention-days: 14
|
|
|
|
cli-binaries-musl:
|
|
# Alpine container build: ort-sys ships no musl prebuilts, so we use Alpine's
|
|
# system onnxruntime-dev (apk) plus -C target-feature=-crt-static for cdylib.
|
|
# Each Dockerfile is single-arch (FROM alpine:3.21); arch-matched runners
|
|
# produce arch-matched binaries without qemu emulation.
|
|
name: Build CLI binary (${{ matrix.target }})
|
|
needs: [prepare, check-cli]
|
|
if: ${{ needs.prepare.outputs.release_cli == 'true' && (needs.check-cli.outputs.exists != 'true' || needs.prepare.outputs.force_republish == 'true') }}
|
|
runs-on: ${{ matrix.os }}
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- { os: ubuntu-latest, target: x86_64-unknown-linux-musl }
|
|
- { os: ubuntu-24.04-arm, target: aarch64-unknown-linux-musl }
|
|
steps:
|
|
- uses: actions/checkout@v6.0.2
|
|
with:
|
|
ref: ${{ needs.prepare.outputs.checkout_ref }}
|
|
fetch-depth: 0
|
|
|
|
submodules: recursive
|
|
- name: Build CLI via Alpine Docker
|
|
run: |
|
|
docker build -f docker/Dockerfile.musl-build \
|
|
--output type=local,dest=./build-output .
|
|
|
|
- name: Package CLI artifact (with bundled lib/)
|
|
env:
|
|
TARGET: ${{ matrix.target }}
|
|
shell: bash
|
|
run: |
|
|
STAGE="kreuzberg-cli-${TARGET}"
|
|
mkdir -p "$STAGE/lib"
|
|
cp build-output/kreuzberg "$STAGE/kreuzberg"
|
|
cp build-output/kreuzberg.bin "$STAGE/kreuzberg.bin"
|
|
cp -a build-output/lib/. "$STAGE/lib/"
|
|
chmod +x "$STAGE/kreuzberg"
|
|
tar -czf "${STAGE}.tar.gz" "$STAGE"
|
|
|
|
- uses: actions/upload-artifact@v7.0.1
|
|
with:
|
|
name: cli-${{ matrix.target }}
|
|
path: kreuzberg-cli-${{ matrix.target }}.tar.gz
|
|
if-no-files-found: error
|
|
retention-days: 14
|
|
|
|
go-ffi-libraries:
|
|
name: Build Go FFI library (${{ matrix.platform }})
|
|
needs: [prepare, check-go]
|
|
if: ${{ needs.prepare.outputs.release_go == 'true' && (needs.check-go.outputs.exists != 'true' || needs.prepare.outputs.force_republish == 'true') }}
|
|
runs-on: ${{ matrix.os }}
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- { os: ubuntu-latest, platform: linux-x86_64, target: x86_64-unknown-linux-gnu }
|
|
- { os: ubuntu-24.04-arm, platform: linux-aarch64, target: aarch64-unknown-linux-gnu }
|
|
- { os: macos-latest, platform: macos-arm64, target: aarch64-apple-darwin }
|
|
- { os: windows-latest, platform: windows-x86_64, target: x86_64-pc-windows-msvc }
|
|
steps:
|
|
- uses: actions/checkout@v6.0.2
|
|
with:
|
|
ref: ${{ needs.prepare.outputs.checkout_ref }}
|
|
fetch-depth: 0
|
|
|
|
submodules: recursive
|
|
- uses: kreuzberg-dev/actions/setup-rust@v1
|
|
with:
|
|
target: ${{ matrix.target }}
|
|
|
|
- uses: kreuzberg-dev/actions/build-go-ffi@v1
|
|
with:
|
|
target: ${{ matrix.target }}
|
|
crate-name: kreuzberg-ffi
|
|
lib-name: kreuzberg_ffi
|
|
header-path: crates/kreuzberg-ffi/include/kreuzberg.h
|
|
archive-name: kreuzberg-go-${{ matrix.platform }}.tar.gz
|
|
output-dir: dist/go-ffi
|
|
|
|
- uses: actions/upload-artifact@v7.0.1
|
|
with:
|
|
name: go-ffi-${{ matrix.platform }}
|
|
path: dist/go-ffi/*.tar.gz
|
|
if-no-files-found: error
|
|
retention-days: 14
|
|
|
|
c-ffi-libraries:
|
|
name: Build C FFI distribution (${{ matrix.platform }})
|
|
needs: [prepare, check-c-ffi]
|
|
if: ${{ needs.prepare.outputs.release_c_ffi == 'true' && (needs.check-c-ffi.outputs.exists != 'true' || needs.prepare.outputs.force_republish == 'true') }}
|
|
runs-on: ${{ matrix.os }}
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- { os: ubuntu-latest, platform: linux-x86_64, target: x86_64-unknown-linux-gnu }
|
|
- { os: ubuntu-24.04-arm, platform: linux-aarch64, target: aarch64-unknown-linux-gnu }
|
|
- { os: macos-latest, platform: macos-arm64, target: aarch64-apple-darwin }
|
|
- { os: windows-latest, platform: windows-x86_64, target: x86_64-pc-windows-msvc }
|
|
steps:
|
|
- uses: actions/checkout@v6.0.2
|
|
with:
|
|
ref: ${{ needs.prepare.outputs.checkout_ref }}
|
|
fetch-depth: 0
|
|
|
|
submodules: recursive
|
|
- uses: kreuzberg-dev/actions/setup-rust@v1
|
|
with:
|
|
target: ${{ matrix.target }}
|
|
|
|
- uses: kreuzberg-dev/actions/build-rust-ffi@v1
|
|
with:
|
|
crate-name: kreuzberg-ffi
|
|
target: ${{ matrix.target }}
|
|
|
|
- name: Stage C FFI distribution
|
|
# Inline: bundle library + header + LICENSE into a single tarball
|
|
# named to match upload-c-ffi-release's expected asset prefix.
|
|
env:
|
|
TARGET: ${{ matrix.target }}
|
|
PLATFORM: ${{ matrix.platform }}
|
|
shell: bash
|
|
run: |
|
|
STAGE="kreuzberg-ffi-${PLATFORM}"
|
|
mkdir -p "$STAGE/lib" "$STAGE/include"
|
|
find "target/${TARGET}/release" -maxdepth 1 -type f \
|
|
\( -name 'libkreuzberg_ffi.*' -o -name 'kreuzberg_ffi.dll' \) \
|
|
-exec cp {} "$STAGE/lib/" \;
|
|
cp crates/kreuzberg-ffi/include/kreuzberg.h "$STAGE/include/"
|
|
cp LICENSE "$STAGE/" 2>/dev/null || true
|
|
mkdir -p dist/c-ffi
|
|
tar -czf "dist/c-ffi/${STAGE}.tar.gz" "$STAGE"
|
|
|
|
- uses: actions/upload-artifact@v7.0.1
|
|
with:
|
|
name: c-ffi-${{ matrix.platform }}
|
|
path: dist/c-ffi/*.tar.gz
|
|
if-no-files-found: error
|
|
retention-days: 14
|
|
|
|
java-natives:
|
|
name: Build Java natives (${{ matrix.classifier }})
|
|
needs: [prepare, check-maven]
|
|
if: ${{ needs.prepare.outputs.release_java == 'true' && (needs.check-maven.outputs.java_exists != 'true' || needs.prepare.outputs.force_republish == 'true') }}
|
|
runs-on: ${{ matrix.os }}
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- { os: ubuntu-latest, classifier: linux-x86_64, target: x86_64-unknown-linux-gnu }
|
|
- { os: ubuntu-24.04-arm, classifier: linux-aarch64, target: aarch64-unknown-linux-gnu }
|
|
- { os: macos-latest, classifier: macos-arm64, target: aarch64-apple-darwin }
|
|
- { os: windows-latest, classifier: windows-x86_64, target: x86_64-pc-windows-msvc }
|
|
steps:
|
|
- uses: actions/checkout@v6.0.2
|
|
with:
|
|
ref: ${{ needs.prepare.outputs.checkout_ref }}
|
|
fetch-depth: 0
|
|
|
|
submodules: recursive
|
|
- uses: kreuzberg-dev/actions/setup-rust@v1
|
|
with:
|
|
target: ${{ matrix.target }}
|
|
|
|
- uses: kreuzberg-dev/actions/build-java-natives@v1
|
|
with:
|
|
target: ${{ matrix.target }}
|
|
crate-name: kreuzberg-ffi
|
|
lib-name: kreuzberg_ffi
|
|
classifier: ${{ matrix.classifier }}
|
|
|
|
- uses: actions/upload-artifact@v7.0.1
|
|
with:
|
|
name: java-natives-${{ matrix.classifier }}
|
|
path: dist/java-natives
|
|
if-no-files-found: error
|
|
retention-days: 14
|
|
|
|
java-natives-musl:
|
|
# Alpine container build via Dockerfile.musl-ffi (system onnxruntime-dev).
|
|
name: Build Java natives (linux-musl-${{ matrix.arch }})
|
|
needs: [prepare, check-maven]
|
|
if: ${{ needs.prepare.outputs.release_java == 'true' && (needs.check-maven.outputs.java_exists != 'true' || needs.prepare.outputs.force_republish == 'true') }}
|
|
runs-on: ${{ matrix.os }}
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- { os: ubuntu-latest, arch: x86_64, classifier: linux-musl-x86_64 }
|
|
- { os: ubuntu-24.04-arm, arch: aarch64, classifier: linux-musl-aarch64 }
|
|
steps:
|
|
- uses: actions/checkout@v6.0.2
|
|
with:
|
|
ref: ${{ needs.prepare.outputs.checkout_ref }}
|
|
fetch-depth: 0
|
|
|
|
submodules: recursive
|
|
- name: Build kreuzberg-ffi via Alpine Docker
|
|
run: |
|
|
docker build -f docker/Dockerfile.musl-ffi \
|
|
--output type=local,dest=./build-output .
|
|
|
|
- name: Stage native lib for Java classifier layout
|
|
env:
|
|
CLASSIFIER: ${{ matrix.classifier }}
|
|
run: |
|
|
mkdir -p "dist/java-natives/${CLASSIFIER}"
|
|
cp build-output/libkreuzberg_ffi.so "dist/java-natives/${CLASSIFIER}/libkreuzberg_ffi.so"
|
|
|
|
- uses: actions/upload-artifact@v7.0.1
|
|
with:
|
|
name: java-natives-${{ matrix.classifier }}
|
|
path: dist/java-natives
|
|
if-no-files-found: error
|
|
retention-days: 14
|
|
|
|
kotlin-android-natives:
|
|
name: Build Kotlin Android natives (${{ matrix.abi }})
|
|
needs: [prepare, check-maven]
|
|
if: ${{ needs.prepare.outputs.release_kotlin == 'true' && (needs.check-maven.outputs.kotlin_exists != 'true' || needs.prepare.outputs.force_republish == 'true') }}
|
|
runs-on: ubuntu-latest
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- { abi: arm64-v8a }
|
|
- { abi: x86_64 }
|
|
steps:
|
|
- uses: actions/checkout@v6.0.2
|
|
with:
|
|
ref: ${{ needs.prepare.outputs.checkout_ref }}
|
|
fetch-depth: 0
|
|
submodules: recursive
|
|
- uses: kreuzberg-dev/actions/setup-rust@v1
|
|
- uses: kreuzberg-dev/actions/build-android-natives@v1
|
|
with:
|
|
crate-name: kreuzberg-ffi
|
|
abis: ${{ matrix.abi }}
|
|
- uses: actions/upload-artifact@v7.0.1
|
|
with:
|
|
name: kotlin-android-${{ matrix.abi }}
|
|
path: dist/android-natives
|
|
if-no-files-found: error
|
|
retention-days: 14
|
|
|
|
csharp-natives:
|
|
name: Build C# natives (${{ matrix.rid }})
|
|
needs: [prepare, check-nuget]
|
|
if: ${{ needs.prepare.outputs.release_csharp == 'true' && (needs.check-nuget.outputs.exists != 'true' || needs.prepare.outputs.force_republish == 'true') }}
|
|
runs-on: ${{ matrix.os }}
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- { os: ubuntu-latest, rid: linux-x64, target: x86_64-unknown-linux-gnu }
|
|
- { os: ubuntu-24.04-arm, rid: linux-arm64, target: aarch64-unknown-linux-gnu }
|
|
- { os: macos-latest, rid: osx-arm64, target: aarch64-apple-darwin }
|
|
- { os: windows-latest, rid: win-x64, target: x86_64-pc-windows-msvc }
|
|
steps:
|
|
- uses: actions/checkout@v6.0.2
|
|
with:
|
|
ref: ${{ needs.prepare.outputs.checkout_ref }}
|
|
fetch-depth: 0
|
|
|
|
submodules: recursive
|
|
- uses: kreuzberg-dev/actions/setup-rust@v1
|
|
with:
|
|
target: ${{ matrix.target }}
|
|
|
|
- uses: kreuzberg-dev/actions/build-csharp-natives@v1
|
|
with:
|
|
target: ${{ matrix.target }}
|
|
crate-name: kreuzberg-ffi
|
|
lib-name: kreuzberg_ffi
|
|
rid: ${{ matrix.rid }}
|
|
|
|
- uses: actions/upload-artifact@v7.0.1
|
|
with:
|
|
name: csharp-natives-${{ matrix.rid }}
|
|
path: dist/csharp-natives
|
|
if-no-files-found: error
|
|
retention-days: 14
|
|
|
|
csharp-natives-musl:
|
|
# Alpine container build via Dockerfile.musl-ffi (system onnxruntime-dev).
|
|
name: Build C# natives (linux-musl-${{ matrix.arch }})
|
|
needs: [prepare, check-nuget]
|
|
if: ${{ needs.prepare.outputs.release_csharp == 'true' && (needs.check-nuget.outputs.exists != 'true' || needs.prepare.outputs.force_republish == 'true') }}
|
|
runs-on: ${{ matrix.os }}
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- { os: ubuntu-latest, arch: x64, rid: linux-musl-x64 }
|
|
- { os: ubuntu-24.04-arm, arch: arm64, rid: linux-musl-arm64 }
|
|
steps:
|
|
- uses: actions/checkout@v6.0.2
|
|
with:
|
|
ref: ${{ needs.prepare.outputs.checkout_ref }}
|
|
fetch-depth: 0
|
|
|
|
submodules: recursive
|
|
- name: Build kreuzberg-ffi via Alpine Docker
|
|
run: |
|
|
docker build -f docker/Dockerfile.musl-ffi \
|
|
--output type=local,dest=./build-output .
|
|
|
|
- name: Stage native lib for NuGet RID layout
|
|
env:
|
|
RID: ${{ matrix.rid }}
|
|
run: |
|
|
mkdir -p "dist/csharp-natives/runtimes/${RID}/native"
|
|
cp build-output/libkreuzberg_ffi.so "dist/csharp-natives/runtimes/${RID}/native/libkreuzberg_ffi.so"
|
|
|
|
- uses: actions/upload-artifact@v7.0.1
|
|
with:
|
|
name: csharp-natives-${{ matrix.rid }}
|
|
path: dist/csharp-natives
|
|
if-no-files-found: error
|
|
retention-days: 14
|
|
|
|
elixir-natives:
|
|
name: Build Elixir NIF (${{ matrix.label }})
|
|
# build-elixir-natives@v1 rewrites path-deps to registry versions before
|
|
# building (so the hex source fallback resolves); needs published crates. The
|
|
# status guard lets the build run when publish-crates is skipped, blocking only
|
|
# on its actual failure.
|
|
needs: [prepare, check-elixir-release, publish-crates]
|
|
if: ${{ !cancelled() && needs.publish-crates.result != 'failure' && needs.prepare.outputs.release_elixir == 'true' && (needs.check-elixir-release.outputs.exists != 'true' || needs.prepare.outputs.force_republish == 'true') }}
|
|
runs-on: ${{ matrix.os }}
|
|
timeout-minutes: 90
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
os: [ubuntu-latest, ubuntu-24.04-arm, macos-latest, windows-latest]
|
|
nif: ["2.16", "2.17"]
|
|
include:
|
|
- os: ubuntu-latest
|
|
label: linux-x86_64
|
|
target: x86_64-unknown-linux-gnu
|
|
- os: ubuntu-24.04-arm
|
|
label: linux-aarch64
|
|
target: aarch64-unknown-linux-gnu
|
|
- os: macos-latest
|
|
label: macos-arm64
|
|
target: aarch64-apple-darwin
|
|
- os: windows-latest
|
|
label: windows-x86_64
|
|
target: x86_64-pc-windows-msvc
|
|
steps:
|
|
- uses: actions/checkout@v6.0.2
|
|
with:
|
|
ref: ${{ needs.prepare.outputs.checkout_ref }}
|
|
fetch-depth: 0
|
|
|
|
submodules: recursive
|
|
- uses: erlef/setup-beam@v1.24.0
|
|
with:
|
|
elixir-version: "1.17"
|
|
otp-version: "27"
|
|
|
|
- uses: kreuzberg-dev/actions/setup-rust@v1
|
|
with:
|
|
target: ${{ matrix.target }}
|
|
|
|
- uses: kreuzberg-dev/actions/build-elixir-natives@v1
|
|
with:
|
|
target: ${{ matrix.target }}
|
|
nif-crate-name: kreuzberg_nif
|
|
nif-crate-path: packages/elixir/native/kreuzberg_nif
|
|
package-dir: packages/elixir
|
|
nif-version: ${{ needs.prepare.outputs.version }}
|
|
nif-api-version: ${{ matrix.nif }}
|
|
|
|
- uses: actions/upload-artifact@v7.0.1
|
|
with:
|
|
name: elixir-${{ matrix.label }}-nif-${{ matrix.nif }}
|
|
path: dist/elixir-natives/*.tar.gz
|
|
if-no-files-found: error
|
|
retention-days: 14
|
|
|
|
elixir-natives-musl:
|
|
# Alpine container build via Dockerfile.musl-rustler (system onnxruntime-dev).
|
|
# Replicates RustlerPrecompiled tarball naming the build-elixir-natives action
|
|
# uses for non-musl variants: lib{nif}-v{ver}-nif-{api}-{target}.so.tar.gz + sha256.
|
|
# Like elixir-natives, needs published crates for the hex source fallback.
|
|
name: Build Elixir NIF (linux-musl-${{ matrix.arch }} nif-${{ matrix.nif }})
|
|
needs: [prepare, check-elixir-release, publish-crates]
|
|
if: ${{ !cancelled() && needs.publish-crates.result != 'failure' && needs.prepare.outputs.release_elixir == 'true' && (needs.check-elixir-release.outputs.exists != 'true' || needs.prepare.outputs.force_republish == 'true') }}
|
|
runs-on: ${{ matrix.os }}
|
|
timeout-minutes: 90
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
os: [ubuntu-latest, ubuntu-24.04-arm]
|
|
nif: ["2.16", "2.17"]
|
|
include:
|
|
- os: ubuntu-latest
|
|
arch: x86_64
|
|
target: x86_64-unknown-linux-musl
|
|
- os: ubuntu-24.04-arm
|
|
arch: aarch64
|
|
target: aarch64-unknown-linux-musl
|
|
steps:
|
|
- uses: actions/checkout@v6.0.2
|
|
with:
|
|
ref: ${{ needs.prepare.outputs.checkout_ref }}
|
|
fetch-depth: 0
|
|
|
|
submodules: recursive
|
|
- name: Build kreuzberg_nif via Alpine Docker
|
|
run: |
|
|
docker build -f docker/Dockerfile.musl-rustler \
|
|
--output type=local,dest=./build-output .
|
|
|
|
- name: Package NIF as RustlerPrecompiled tarball
|
|
env:
|
|
TARGET: ${{ matrix.target }}
|
|
NIF_API: ${{ matrix.nif }}
|
|
NIF_VERSION: ${{ needs.prepare.outputs.version }}
|
|
shell: bash
|
|
run: |
|
|
set -euo pipefail
|
|
mkdir -p dist/elixir-natives staging
|
|
cp build-output/libkreuzberg_nif.so staging/libkreuzberg_nif.so
|
|
TARBALL="libkreuzberg_nif-v${NIF_VERSION}-nif-${NIF_API}-${TARGET}.so.tar.gz"
|
|
tar -czf "dist/elixir-natives/${TARBALL}" -C staging libkreuzberg_nif.so
|
|
( cd dist/elixir-natives && sha256sum "${TARBALL}" >"${TARBALL}.sha256" )
|
|
|
|
- uses: actions/upload-artifact@v7.0.1
|
|
with:
|
|
name: elixir-musl-${{ matrix.arch }}-nif-${{ matrix.nif }}
|
|
path: dist/elixir-natives/*.tar.gz
|
|
if-no-files-found: error
|
|
retention-days: 14
|
|
|
|
dart-android-natives:
|
|
name: Build Dart Android natives (${{ matrix.abi }})
|
|
needs: [prepare, check-pub]
|
|
if: ${{ needs.prepare.outputs.release_dart == 'true' && (needs.check-pub.outputs.exists != 'true' || needs.prepare.outputs.force_republish == 'true') }}
|
|
runs-on: ubuntu-latest
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- { abi: arm64-v8a }
|
|
- { abi: x86_64 }
|
|
steps:
|
|
- uses: actions/checkout@v6.0.2
|
|
with:
|
|
ref: ${{ needs.prepare.outputs.checkout_ref }}
|
|
fetch-depth: 0
|
|
submodules: recursive
|
|
- uses: kreuzberg-dev/actions/setup-rust@v1
|
|
- uses: kreuzberg-dev/actions/build-android-natives@v1
|
|
with:
|
|
crate-name: kreuzberg-dart
|
|
abis: ${{ matrix.abi }}
|
|
- uses: actions/upload-artifact@v7.0.1
|
|
with:
|
|
name: dart-android-${{ matrix.abi }}
|
|
path: dist/android-natives
|
|
if-no-files-found: error
|
|
retention-days: 14
|
|
|
|
dart-ios-xcframework:
|
|
name: Build Dart iOS XCFramework
|
|
needs: [prepare, check-pub]
|
|
if: ${{ needs.prepare.outputs.release_dart == 'true' && (needs.check-pub.outputs.exists != 'true' || needs.prepare.outputs.force_republish == 'true') }}
|
|
runs-on: macos-latest
|
|
steps:
|
|
- uses: actions/checkout@v6.0.2
|
|
with:
|
|
ref: ${{ needs.prepare.outputs.checkout_ref }}
|
|
fetch-depth: 0
|
|
submodules: recursive
|
|
- uses: kreuzberg-dev/actions/setup-rust@v1
|
|
- uses: kreuzberg-dev/actions/build-ios-xcframework@v1
|
|
with:
|
|
crate-name: kreuzberg-dart
|
|
- uses: actions/upload-artifact@v7.0.1
|
|
with:
|
|
name: dart-ios-xcframework
|
|
path: dist/ios-xcframework
|
|
if-no-files-found: error
|
|
retention-days: 14
|
|
|
|
dart-server-natives:
|
|
name: Build Dart server native (${{ matrix.blob }})
|
|
needs: [prepare, check-pub]
|
|
if: ${{ needs.prepare.outputs.release_dart == 'true' && (needs.check-pub.outputs.exists != 'true' || needs.prepare.outputs.force_republish == 'true') }}
|
|
runs-on: ${{ matrix.os }}
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- {
|
|
os: ubuntu-latest,
|
|
target: x86_64-unknown-linux-gnu,
|
|
blob: linux-x86_64,
|
|
lib: libkreuzberg_dart.so,
|
|
}
|
|
- {
|
|
os: ubuntu-24.04-arm,
|
|
target: aarch64-unknown-linux-gnu,
|
|
blob: linux-aarch64,
|
|
lib: libkreuzberg_dart.so,
|
|
}
|
|
- {
|
|
os: macos-latest,
|
|
target: aarch64-apple-darwin,
|
|
blob: macos-arm64,
|
|
lib: libkreuzberg_dart.dylib,
|
|
}
|
|
- {
|
|
os: windows-latest,
|
|
target: x86_64-pc-windows-msvc,
|
|
blob: windows-x86_64,
|
|
lib: kreuzberg_dart.dll,
|
|
}
|
|
steps:
|
|
- uses: actions/checkout@v6.0.2
|
|
with:
|
|
ref: ${{ needs.prepare.outputs.checkout_ref }}
|
|
fetch-depth: 0
|
|
submodules: recursive
|
|
- uses: kreuzberg-dev/actions/setup-rust@v1
|
|
with:
|
|
target: ${{ matrix.target }}
|
|
- name: Build Dart server native
|
|
run: cargo build -p kreuzberg-dart --release --target ${{ matrix.target }}
|
|
shell: bash
|
|
- name: Stage native library
|
|
shell: bash
|
|
env:
|
|
TARGET: ${{ matrix.target }}
|
|
LIB: ${{ matrix.lib }}
|
|
run: |
|
|
mkdir -p dist/server-natives
|
|
cp "target/${TARGET}/release/${LIB}" "dist/server-natives/${LIB}"
|
|
- uses: actions/upload-artifact@v7.0.1
|
|
with:
|
|
name: dart-server-${{ matrix.blob }}
|
|
path: dist/server-natives
|
|
if-no-files-found: error
|
|
retention-days: 14
|
|
|
|
dart-package:
|
|
name: Build Dart package
|
|
needs: [prepare, check-pub]
|
|
if: ${{ needs.prepare.outputs.release_dart == 'true' && needs.check-pub.outputs.exists != 'true' }}
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v6.0.2
|
|
with:
|
|
ref: ${{ needs.prepare.outputs.checkout_ref }}
|
|
fetch-depth: 0
|
|
|
|
submodules: recursive
|
|
- uses: kreuzberg-dev/actions/setup-rust@v1
|
|
|
|
- uses: kreuzberg-dev/actions/build-dart-package@v1
|
|
with:
|
|
# flutter_rust_bridge.yaml lives in packages/dart/rust/, where rust_root: .
|
|
package-dir: packages/dart/rust
|
|
crate-name: kreuzberg-dart
|
|
|
|
- uses: actions/upload-artifact@v7.0.1
|
|
with:
|
|
name: dart-package
|
|
path: packages/dart
|
|
retention-days: 14
|
|
|
|
swift-artifactbundle:
|
|
name: Build Swift artifact bundle
|
|
needs: prepare
|
|
if: ${{ needs.prepare.outputs.release_swift == 'true' }}
|
|
runs-on: macos-latest
|
|
steps:
|
|
- uses: actions/checkout@v6.0.2
|
|
with:
|
|
ref: ${{ needs.prepare.outputs.checkout_ref }}
|
|
fetch-depth: 0
|
|
submodules: recursive
|
|
- uses: kreuzberg-dev/actions/setup-rust@v1
|
|
- uses: kreuzberg-dev/actions/build-swift-artifactbundle@v1
|
|
id: bundle
|
|
with:
|
|
crate-name: kreuzberg-swift
|
|
artifact-name: KreuzbergSwift
|
|
include-macos-x86_64: "false"
|
|
include-ios-x86_64: "false"
|
|
- uses: actions/upload-artifact@v7.0.1
|
|
with:
|
|
name: swift-artifactbundle
|
|
path: ${{ steps.bundle.outputs.bundle-zip }}
|
|
if-no-files-found: error
|
|
retention-days: 14
|
|
|
|
swift-package:
|
|
name: Build Swift package
|
|
needs: prepare
|
|
if: ${{ needs.prepare.outputs.release_swift == 'true' }}
|
|
runs-on: macos-latest
|
|
steps:
|
|
- uses: actions/checkout@v6.0.2
|
|
with:
|
|
ref: ${{ needs.prepare.outputs.checkout_ref }}
|
|
fetch-depth: 0
|
|
|
|
submodules: recursive
|
|
- uses: kreuzberg-dev/actions/setup-rust@v1
|
|
|
|
- uses: kreuzberg-dev/actions/build-swift-package@v1
|
|
with:
|
|
package-dir: packages/swift
|
|
crate-name: kreuzberg-swift
|
|
|
|
- uses: actions/upload-artifact@v7.0.1
|
|
with:
|
|
name: swift-package
|
|
path: packages/swift
|
|
retention-days: 14
|
|
|
|
zig-package:
|
|
name: Build Zig package (smoke check)
|
|
needs: prepare
|
|
if: ${{ needs.prepare.outputs.release_zig == 'true' }}
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v6.0.2
|
|
with:
|
|
ref: ${{ needs.prepare.outputs.checkout_ref }}
|
|
fetch-depth: 0
|
|
|
|
submodules: recursive
|
|
- uses: kreuzberg-dev/actions/setup-rust@v1
|
|
|
|
- uses: kreuzberg-dev/actions/build-zig-package@v1
|
|
with:
|
|
ffi-crate: kreuzberg-ffi
|
|
package-dir: packages/zig
|
|
|
|
# ─── GitHub Release asset uploads ─────────────────────────────────────
|
|
|
|
upload-cli-release:
|
|
name: Upload CLI binaries to GitHub Release
|
|
needs: [prepare, cli-binaries]
|
|
if: ${{ needs.prepare.outputs.is_tag == 'true' && needs.cli-binaries.result == 'success' }}
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/download-artifact@v8.0.1
|
|
with:
|
|
pattern: cli-*
|
|
path: dist/cli
|
|
merge-multiple: true
|
|
|
|
- uses: kreuzberg-dev/actions/upload-release-assets@v1
|
|
with:
|
|
tag: ${{ needs.prepare.outputs.tag }}
|
|
working-directory: dist/cli
|
|
dry-run: ${{ needs.prepare.outputs.dry_run }}
|
|
assets: |
|
|
kreuzberg-cli-*.tar.gz
|
|
kreuzberg-cli-*.zip
|
|
|
|
upload-go-release:
|
|
name: Upload Go FFI archives to GitHub Release
|
|
needs: [prepare, go-ffi-libraries]
|
|
if: ${{ needs.prepare.outputs.is_tag == 'true' && needs.go-ffi-libraries.result == 'success' }}
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/download-artifact@v8.0.1
|
|
with:
|
|
pattern: go-ffi-*
|
|
path: dist/go-ffi
|
|
merge-multiple: true
|
|
|
|
- uses: kreuzberg-dev/actions/upload-release-assets@v1
|
|
with:
|
|
tag: ${{ needs.prepare.outputs.tag }}
|
|
working-directory: dist/go-ffi
|
|
dry-run: ${{ needs.prepare.outputs.dry_run }}
|
|
assets: kreuzberg-go-*.tar.gz
|
|
|
|
upload-c-ffi-release:
|
|
name: Upload C FFI archives to GitHub Release
|
|
needs: [prepare, c-ffi-libraries]
|
|
if: ${{ needs.prepare.outputs.is_tag == 'true' && needs.c-ffi-libraries.result == 'success' }}
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/download-artifact@v8.0.1
|
|
with:
|
|
pattern: c-ffi-*
|
|
path: dist/c-ffi
|
|
merge-multiple: true
|
|
|
|
- uses: kreuzberg-dev/actions/upload-release-assets@v1
|
|
with:
|
|
tag: ${{ needs.prepare.outputs.tag }}
|
|
working-directory: dist/c-ffi
|
|
dry-run: ${{ needs.prepare.outputs.dry_run }}
|
|
assets: kreuzberg-ffi-*.tar.gz
|
|
|
|
upload-elixir-release:
|
|
name: Upload Elixir NIF archives to GitHub Release
|
|
needs: [prepare, elixir-natives, elixir-natives-musl]
|
|
if: ${{ needs.prepare.outputs.is_tag == 'true' && (needs.elixir-natives.result == 'success' || needs.elixir-natives-musl.result == 'success') }}
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/download-artifact@v8.0.1
|
|
with:
|
|
pattern: elixir-*
|
|
path: dist/elixir
|
|
merge-multiple: true
|
|
|
|
- uses: kreuzberg-dev/actions/upload-release-assets@v1
|
|
with:
|
|
tag: ${{ needs.prepare.outputs.tag }}
|
|
working-directory: dist/elixir
|
|
dry-run: ${{ needs.prepare.outputs.dry_run }}
|
|
assets: libkreuzberg_nif-*.tar.gz
|
|
|
|
upload-php-pie-release:
|
|
name: Upload PHP PIE archives to GitHub Release
|
|
needs: [prepare, php-extension]
|
|
if: ${{ needs.prepare.outputs.is_tag == 'true' && needs.php-extension.result == 'success' }}
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/download-artifact@v8.0.1
|
|
with:
|
|
pattern: php-package-*
|
|
path: dist/php-package
|
|
merge-multiple: true
|
|
|
|
- uses: kreuzberg-dev/actions/upload-release-assets@v1
|
|
with:
|
|
tag: ${{ needs.prepare.outputs.tag }}
|
|
working-directory: dist/php-package
|
|
dry-run: ${{ needs.prepare.outputs.dry_run }}
|
|
assets: |
|
|
php_*.tgz
|
|
php_*.tgz.sha256
|
|
php_*.zip
|
|
php_*.zip.sha256
|
|
|
|
upload-swift-bundle:
|
|
name: Upload Swift artifact bundle to GitHub Release
|
|
needs: [prepare, swift-artifactbundle]
|
|
if: ${{ needs.prepare.outputs.is_tag == 'true' && needs.swift-artifactbundle.result == 'success' }}
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/download-artifact@v8.0.1
|
|
with:
|
|
name: swift-artifactbundle
|
|
path: dist/swift-bundle
|
|
|
|
- uses: kreuzberg-dev/actions/upload-release-assets@v1
|
|
with:
|
|
tag: ${{ needs.prepare.outputs.tag }}
|
|
working-directory: dist/swift-bundle
|
|
dry-run: ${{ needs.prepare.outputs.dry_run }}
|
|
assets: "*.zip"
|
|
|
|
# Verifies every expected release asset is present on the GitHub release
|
|
# before the publish-* fan-out depends on those URLs.
|
|
verify-assets:
|
|
name: Verify release assets
|
|
needs:
|
|
- prepare
|
|
- upload-cli-release
|
|
- upload-go-release
|
|
- upload-c-ffi-release
|
|
- upload-elixir-release
|
|
- upload-php-pie-release
|
|
if: ${{ always() && needs.prepare.outputs.is_tag == 'true' && needs.prepare.outputs.dry_run != 'true' && !contains(needs.*.result, 'failure') }}
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: kreuzberg-dev/actions/verify-release-assets@v1
|
|
with:
|
|
tag: ${{ needs.prepare.outputs.tag }}
|
|
expected-assets: |
|
|
# CLI
|
|
kreuzberg-cli-*.tar.gz
|
|
kreuzberg-cli-*.zip
|
|
# Go FFI
|
|
kreuzberg-go-*.tar.gz
|
|
# C FFI
|
|
kreuzberg-ffi-*.tar.gz
|
|
# Elixir NIF
|
|
libkreuzberg_nif-*.tar.gz
|
|
|
|
# ─── Publish jobs ─────────────────────────────────────────────────────
|
|
|
|
publish-crates:
|
|
name: Publish crates.io packages
|
|
needs: [prepare, validate-versions, check-cratesio]
|
|
if: ${{ needs.prepare.outputs.release_crates == 'true' && needs.prepare.outputs.is_tag == 'true' && (needs.check-cratesio.outputs.all_exist != 'true' || needs.prepare.outputs.force_republish == 'true') }}
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
contents: read
|
|
id-token: write
|
|
steps:
|
|
- uses: actions/checkout@v6.0.2
|
|
with:
|
|
ref: ${{ needs.prepare.outputs.ref }}
|
|
|
|
submodules: recursive
|
|
- uses: kreuzberg-dev/actions/setup-rust@v1
|
|
|
|
- uses: kreuzberg-dev/actions/publish-crates@v1
|
|
with:
|
|
crates: kreuzberg-tesseract kreuzberg-paddle-ocr kreuzberg kreuzberg-cli
|
|
version: ${{ needs.prepare.outputs.version }}
|
|
dry-run: ${{ needs.prepare.outputs.dry_run }}
|
|
|
|
publish-pypi:
|
|
name: Publish to PyPI
|
|
needs: [prepare, python-wheels, python-sdist, check-pypi]
|
|
if: ${{ needs.prepare.outputs.release_python == 'true' && needs.prepare.outputs.is_tag == 'true' && (needs.check-pypi.outputs.exists != 'true' || needs.prepare.outputs.force_republish == 'true') }}
|
|
runs-on: ubuntu-latest
|
|
environment: pypi
|
|
permissions:
|
|
contents: read
|
|
id-token: write
|
|
steps:
|
|
- uses: actions/download-artifact@v8.0.1
|
|
with:
|
|
pattern: python-wheels-*
|
|
path: dist
|
|
merge-multiple: true
|
|
- uses: actions/download-artifact@v8.0.1
|
|
with:
|
|
name: python-sdist
|
|
path: dist
|
|
|
|
- name: Verify Python wheel package contents
|
|
uses: kreuzberg-dev/actions/verify-package-contents@v1
|
|
with:
|
|
language: python
|
|
artifact-path: dist
|
|
package-name: kreuzberg
|
|
# Per-archive patterns don't apply uniformly: wheels carry the
|
|
# native .so/.dylib/.dll but sdist doesn't; sdist carries the
|
|
# source tree the wheels strip. The basic `python` allowlist also
|
|
# only matches wheels. strict=false reports diffs without blocking.
|
|
strict: "false"
|
|
|
|
- uses: kreuzberg-dev/actions/publish-pypi@v1
|
|
with:
|
|
packages-dir: dist
|
|
dry-run: ${{ needs.prepare.outputs.dry_run }}
|
|
|
|
publish-rubygems:
|
|
name: Publish Ruby gems
|
|
needs: [prepare, ruby-gem, check-rubygems]
|
|
if: ${{ needs.prepare.outputs.release_ruby == 'true' && needs.prepare.outputs.is_tag == 'true' && (needs.check-rubygems.outputs.exists != 'true' || needs.prepare.outputs.force_republish == 'true') }}
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
contents: read
|
|
id-token: write
|
|
steps:
|
|
- uses: actions/download-artifact@v8.0.1
|
|
with:
|
|
pattern: rubygems-*
|
|
path: dist
|
|
merge-multiple: true
|
|
|
|
- uses: ruby/setup-ruby@v1.309.0
|
|
with:
|
|
ruby-version: "3.3"
|
|
bundler-cache: false
|
|
|
|
- uses: rubygems/configure-rubygems-credentials@v2.0.0
|
|
|
|
- name: Verify Ruby gem package contents
|
|
uses: kreuzberg-dev/actions/verify-package-contents@v1
|
|
with:
|
|
language: ruby
|
|
artifact-path: dist
|
|
package-name: kreuzberg
|
|
|
|
- uses: kreuzberg-dev/actions/publish-rubygems@v1
|
|
with:
|
|
gems-dir: dist
|
|
dry-run: ${{ needs.prepare.outputs.dry_run }}
|
|
|
|
publish-node:
|
|
name: Publish Node packages
|
|
needs: [prepare, node-bindings, check-npm]
|
|
if: ${{ needs.prepare.outputs.release_node == 'true' && needs.prepare.outputs.is_tag == 'true' && (needs.check-npm.outputs.node_exists != 'true' || needs.prepare.outputs.force_republish == 'true') }}
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
contents: read
|
|
id-token: write
|
|
steps:
|
|
- uses: actions/checkout@v6.0.2
|
|
with:
|
|
ref: ${{ needs.prepare.outputs.ref }}
|
|
|
|
submodules: recursive
|
|
- uses: actions/download-artifact@v8.0.1
|
|
with:
|
|
pattern: node-bindings-*
|
|
path: crates/kreuzberg-node/artifacts
|
|
merge-multiple: true
|
|
|
|
- uses: kreuzberg-dev/actions/setup-node-workspace@v1
|
|
with:
|
|
node-version: "24"
|
|
registry-url: "https://registry.npmjs.org/"
|
|
|
|
- name: Stage platform packages with napi
|
|
# Inline: napi artifacts → per-platform npm/ subpackages. Equivalent
|
|
# of `napi create-npm-dirs && napi artifacts`; trivially small.
|
|
working-directory: crates/kreuzberg-node
|
|
run: |
|
|
pnpm exec napi create-npm-dirs
|
|
pnpm exec napi artifacts --output-dir artifacts --npm-dir npm
|
|
shell: bash
|
|
|
|
- name: Pack platform sub-packages
|
|
# `publish-npm packages-dir` mode expects *.tgz inputs; napi only
|
|
# stages the per-platform directories. Run `npm pack` in each so
|
|
# the publish action has tarballs to upload (or dry-run).
|
|
working-directory: crates/kreuzberg-node
|
|
shell: bash
|
|
run: |
|
|
for d in npm/*/; do
|
|
[ -d "$d" ] || continue
|
|
(cd "$d" && npm pack)
|
|
done
|
|
|
|
- name: Verify Node platform sub-package contents
|
|
uses: kreuzberg-dev/actions/verify-package-contents@v1
|
|
with:
|
|
language: node-platform
|
|
artifact-path: crates/kreuzberg-node/npm
|
|
package-name: "@kreuzberg/node"
|
|
# NAPI scaffolds stub package.json dirs for every platform in
|
|
# crates/kreuzberg-node/package.json's `napi.triples.additional`,
|
|
# not just the targets we build (e.g. darwin-x64, win32-arm64-msvc
|
|
# are listed but not built — their npm/*.tgz contains no .node).
|
|
# Use strict=false so verify reports stubs without failing the job.
|
|
strict: "false"
|
|
|
|
- name: Publish platform sub-packages
|
|
uses: kreuzberg-dev/actions/publish-npm@v1
|
|
with:
|
|
packages-dir: crates/kreuzberg-node/npm
|
|
npm-tag: ${{ needs.prepare.outputs.npm_tag }}
|
|
dry-run: ${{ needs.prepare.outputs.dry_run }}
|
|
env:
|
|
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
|
|
- name: Publish main @kreuzberg/node package
|
|
uses: kreuzberg-dev/actions/publish-npm@v1
|
|
with:
|
|
package-dir: crates/kreuzberg-node
|
|
npm-tag: ${{ needs.prepare.outputs.npm_tag }}
|
|
dry-run: ${{ needs.prepare.outputs.dry_run }}
|
|
env:
|
|
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
|
|
publish-wasm:
|
|
name: Publish WASM package
|
|
needs: [prepare, wasm-bindings, check-npm]
|
|
if: ${{ needs.prepare.outputs.release_wasm == 'true' && needs.prepare.outputs.is_tag == 'true' && (needs.check-npm.outputs.wasm_exists != 'true' || needs.prepare.outputs.force_republish == 'true') }}
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
contents: read
|
|
id-token: write
|
|
steps:
|
|
- uses: actions/checkout@v6.0.2
|
|
with:
|
|
ref: ${{ needs.prepare.outputs.ref }}
|
|
|
|
submodules: recursive
|
|
- uses: actions/download-artifact@v8.0.1
|
|
with:
|
|
name: wasm-bundle
|
|
path: crates/kreuzberg-wasm
|
|
|
|
- uses: kreuzberg-dev/actions/setup-node-workspace@v1
|
|
with:
|
|
node-version: "24"
|
|
registry-url: "https://registry.npmjs.org/"
|
|
|
|
- uses: kreuzberg-dev/actions/publish-npm@v1
|
|
with:
|
|
package-dir: crates/kreuzberg-wasm
|
|
npm-tag: ${{ needs.prepare.outputs.npm_tag }}
|
|
dry-run: ${{ needs.prepare.outputs.dry_run }}
|
|
env:
|
|
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
|
|
publish-packagist:
|
|
name: Trigger Packagist update
|
|
needs: [prepare, upload-php-pie-release, check-packagist]
|
|
if: ${{ needs.prepare.outputs.release_php == 'true' && needs.prepare.outputs.is_tag == 'true' && (needs.check-packagist.outputs.exists != 'true' || needs.prepare.outputs.force_republish == 'true') }}
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: kreuzberg-dev/actions/publish-packagist@v1
|
|
with:
|
|
packagist-username: kreuzberg-dev
|
|
package-name: kreuzberg/kreuzberg
|
|
version: ${{ needs.prepare.outputs.version }}
|
|
repository-url: https://github.com/kreuzberg-dev/kreuzberg
|
|
dry-run: ${{ needs.prepare.outputs.dry_run }}
|
|
env:
|
|
PACKAGIST_API_TOKEN: ${{ secrets.PACKAGIST_API_TOKEN }}
|
|
|
|
publish-maven:
|
|
name: Publish Maven (Java) package
|
|
needs: [prepare, java-natives, java-natives-musl, check-maven]
|
|
if: ${{ needs.prepare.outputs.release_java == 'true' && needs.prepare.outputs.is_tag == 'true' && (needs.check-maven.outputs.java_exists != 'true' || needs.prepare.outputs.force_republish == 'true') }}
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v6.0.2
|
|
with:
|
|
ref: ${{ needs.prepare.outputs.ref }}
|
|
|
|
submodules: recursive
|
|
- uses: actions/download-artifact@v8.0.1
|
|
with:
|
|
pattern: java-natives-*
|
|
path: artifacts/java-natives
|
|
merge-multiple: true
|
|
|
|
- uses: kreuzberg-dev/actions/stage-java-natives@v1
|
|
with:
|
|
resources-dir: packages/java/src/main/resources/natives
|
|
required-classifiers: >-
|
|
linux-x86_64 linux-aarch64 macos-arm64 windows-x86_64
|
|
linux-musl-x86_64 linux-musl-aarch64
|
|
lib-name: kreuzberg_ffi
|
|
|
|
- uses: actions/setup-java@v5.2.0
|
|
with:
|
|
distribution: temurin
|
|
java-version: "21"
|
|
cache: maven
|
|
server-id: central
|
|
server-username: MAVEN_USERNAME
|
|
server-password: MAVEN_PASSWORD
|
|
gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }}
|
|
gpg-passphrase: MAVEN_GPG_PASSPHRASE
|
|
|
|
- uses: kreuzberg-dev/actions/setup-maven@v1
|
|
|
|
- uses: kreuzberg-dev/actions/publish-maven@v1
|
|
with:
|
|
pom-file: packages/java/pom.xml
|
|
maven-profile: publish
|
|
extra-args: -DskipTests
|
|
dry-run: ${{ needs.prepare.outputs.dry_run }}
|
|
env:
|
|
MAVEN_USERNAME: ${{ secrets.CENTRAL_USERNAME }}
|
|
MAVEN_PASSWORD: ${{ secrets.CENTRAL_PASSWORD }}
|
|
MAVEN_GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
|
|
|
|
publish-kotlin-android:
|
|
name: Publish Kotlin Android (Maven Central via Gradle)
|
|
needs: [prepare, kotlin-android-natives, check-maven]
|
|
if: ${{ needs.prepare.outputs.release_kotlin == 'true' && needs.prepare.outputs.is_tag == 'true' && (needs.check-maven.outputs.kotlin_exists != 'true' || needs.prepare.outputs.force_republish == 'true') }}
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v6.0.2
|
|
with:
|
|
ref: ${{ needs.prepare.outputs.ref }}
|
|
|
|
submodules: recursive
|
|
- uses: actions/download-artifact@v8.0.1
|
|
with:
|
|
pattern: kotlin-android-*
|
|
path: kotlin-android-artifacts
|
|
merge-multiple: true
|
|
|
|
- name: Stage Android natives into Kotlin Android module
|
|
shell: bash
|
|
run: |
|
|
for abi in arm64-v8a x86_64; do
|
|
dest="packages/kotlin-android/src/main/jniLibs/${abi}"
|
|
mkdir -p "$dest"
|
|
src="kotlin-android-artifacts/${abi}/libkreuzberg_ffi.so"
|
|
if [[ -f "$src" ]]; then
|
|
cp -v "$src" "$dest/"
|
|
fi
|
|
done
|
|
|
|
- uses: android-actions/setup-android@v4.0.1
|
|
with:
|
|
packages: "platforms;android-36 build-tools;36.0.0"
|
|
|
|
- uses: kreuzberg-dev/actions/publish-maven-gradle@v1
|
|
with:
|
|
working-directory: packages/kotlin-android
|
|
gradle-task: publishAndReleaseToMavenCentral
|
|
dry-run: ${{ needs.prepare.outputs.dry_run }}
|
|
env:
|
|
MAVEN_USERNAME: ${{ secrets.CENTRAL_USERNAME }}
|
|
MAVEN_PASSWORD: ${{ secrets.CENTRAL_PASSWORD }}
|
|
MAVEN_GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }}
|
|
MAVEN_GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
|
|
|
|
publish-nuget:
|
|
name: Publish NuGet package
|
|
needs: [prepare, csharp-natives, csharp-natives-musl, check-nuget]
|
|
if: ${{ needs.prepare.outputs.release_csharp == 'true' && needs.prepare.outputs.is_tag == 'true' && (needs.check-nuget.outputs.exists != 'true' || needs.prepare.outputs.force_republish == 'true') }}
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
contents: read
|
|
id-token: write
|
|
steps:
|
|
- uses: actions/checkout@v6.0.2
|
|
with:
|
|
ref: ${{ needs.prepare.outputs.ref }}
|
|
|
|
submodules: recursive
|
|
- uses: actions/download-artifact@v8.0.1
|
|
with:
|
|
pattern: csharp-natives-*
|
|
path: csharp-natives
|
|
merge-multiple: true
|
|
|
|
- name: Stage runtimes/<rid>/native into NuGet project
|
|
# Inline: NuGet expects native libs in runtimes/<rid>/native/ adjacent
|
|
# to the .csproj. Copy from artifact tree into project.
|
|
run: |
|
|
mkdir -p packages/csharp/Kreuzberg/runtimes
|
|
for dir in csharp-natives/runtimes/*/; do
|
|
rid="$(basename "$dir")"
|
|
mkdir -p "packages/csharp/Kreuzberg/runtimes/${rid}/native"
|
|
cp -v "${dir}native/"* "packages/csharp/Kreuzberg/runtimes/${rid}/native/"
|
|
done
|
|
shell: bash
|
|
|
|
- uses: actions/setup-dotnet@v5.2.0
|
|
with:
|
|
dotnet-version: "8.0.x"
|
|
|
|
- name: Pack NuGet package
|
|
# Inline: dotnet pack with the version override; one-liner.
|
|
run: |
|
|
dotnet pack packages/csharp/Kreuzberg/Kreuzberg.csproj \
|
|
-c Release \
|
|
-p:Version=${{ needs.prepare.outputs.version }} \
|
|
-o dist/nuget
|
|
shell: bash
|
|
|
|
- uses: kreuzberg-dev/actions/publish-nuget@v1
|
|
with:
|
|
packages-dir: dist/nuget
|
|
dry-run: ${{ needs.prepare.outputs.dry_run }}
|
|
env:
|
|
NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }}
|
|
|
|
finalize-github-release-after-uploads:
|
|
name: Finalize GitHub Release (after uploads)
|
|
needs:
|
|
- prepare
|
|
- verify-assets
|
|
- upload-cli-release
|
|
- upload-go-release
|
|
- upload-c-ffi-release
|
|
- upload-elixir-release
|
|
- upload-php-pie-release
|
|
- upload-swift-bundle
|
|
if: ${{ needs.prepare.outputs.is_tag == 'true' && needs.prepare.outputs.dry_run != 'true' }}
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
contents: write
|
|
steps:
|
|
- uses: kreuzberg-dev/actions/finalize-release@v1
|
|
with:
|
|
tag: ${{ needs.prepare.outputs.tag }}
|
|
is-prerelease: ${{ needs.prepare.outputs.is_prerelease }}
|
|
|
|
publish-hex:
|
|
name: Publish Elixir Hex package
|
|
needs: [prepare, finalize-github-release-after-uploads, check-hex]
|
|
if: ${{ needs.prepare.outputs.release_elixir == 'true' && needs.prepare.outputs.is_tag == 'true' && (needs.check-hex.outputs.elixir_exists != 'true' || needs.prepare.outputs.force_republish == 'true') }}
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v6.0.2
|
|
with:
|
|
ref: ${{ needs.prepare.outputs.ref }}
|
|
|
|
submodules: recursive
|
|
- uses: kreuzberg-dev/actions/setup-rust@v1
|
|
- uses: erlef/setup-beam@v1.24.0
|
|
with:
|
|
elixir-version: "1.17"
|
|
otp-version: "27"
|
|
|
|
- name: Generate NIF checksum file
|
|
uses: kreuzberg-dev/actions/generate-elixir-checksums@v1
|
|
with:
|
|
github-repo: kreuzberg-dev/kreuzberg
|
|
tag: ${{ needs.prepare.outputs.tag }}
|
|
version: ${{ needs.prepare.outputs.version }}
|
|
lib-name: kreuzberg_nif
|
|
targets: x86_64-unknown-linux-gnu,aarch64-unknown-linux-gnu,x86_64-unknown-linux-musl,aarch64-unknown-linux-musl,aarch64-apple-darwin,x86_64-pc-windows-msvc
|
|
output-path: packages/elixir/checksum-Elixir.Kreuzberg.Native.exs
|
|
|
|
- name: Build Elixir Hex tarball with dependency rewrite
|
|
id: build-hex
|
|
uses: kreuzberg-dev/actions/build-elixir-hex@v1
|
|
with:
|
|
package-dir: packages/elixir
|
|
nif-crate-path: packages/elixir/native/kreuzberg_nif
|
|
rewrite-native-deps: "true"
|
|
dry-run: ${{ needs.prepare.outputs.dry_run }}
|
|
|
|
- uses: kreuzberg-dev/actions/publish-hex@v1
|
|
with:
|
|
package-dir: packages/elixir
|
|
tarball-path: ${{ steps.build-hex.outputs.archive-path }}
|
|
dry-run: ${{ needs.prepare.outputs.dry_run }}
|
|
env:
|
|
HEX_API_KEY: ${{ secrets.HEX_API_KEY }}
|
|
|
|
assemble-dart-bundle:
|
|
name: Assemble Dart package with native artifacts
|
|
needs:
|
|
[
|
|
prepare,
|
|
dart-package,
|
|
dart-android-natives,
|
|
dart-ios-xcframework,
|
|
dart-server-natives,
|
|
check-pub,
|
|
]
|
|
if: ${{ needs.prepare.outputs.release_dart == 'true' && needs.prepare.outputs.is_tag == 'true' && needs.check-pub.outputs.exists != 'true' }}
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/download-artifact@v8.0.1
|
|
with:
|
|
name: dart-package
|
|
path: packages/dart
|
|
|
|
- name: Download Android natives
|
|
uses: actions/download-artifact@v8.0.1
|
|
with:
|
|
pattern: dart-android-*
|
|
path: dart-android-artifacts
|
|
merge-multiple: true
|
|
|
|
- name: Download iOS XCFramework
|
|
uses: actions/download-artifact@v8.0.1
|
|
with:
|
|
name: dart-ios-xcframework
|
|
path: dart-ios-xcframework
|
|
|
|
- name: Download server natives (linux-x86_64)
|
|
uses: actions/download-artifact@v8.0.1
|
|
with:
|
|
name: dart-server-linux-x86_64
|
|
path: dart-server-artifacts/linux-x86_64
|
|
|
|
- name: Download server natives (linux-aarch64)
|
|
uses: actions/download-artifact@v8.0.1
|
|
with:
|
|
name: dart-server-linux-aarch64
|
|
path: dart-server-artifacts/linux-aarch64
|
|
|
|
- name: Download server natives (macos-arm64)
|
|
uses: actions/download-artifact@v8.0.1
|
|
with:
|
|
name: dart-server-macos-arm64
|
|
path: dart-server-artifacts/macos-arm64
|
|
|
|
- name: Download server natives (windows-x86_64)
|
|
uses: actions/download-artifact@v8.0.1
|
|
with:
|
|
name: dart-server-windows-x86_64
|
|
path: dart-server-artifacts/windows-x86_64
|
|
|
|
- name: Stage native libraries into Dart package
|
|
shell: bash
|
|
run: |
|
|
set -euo pipefail
|
|
# Android JNI libs
|
|
for abi in arm64-v8a x86_64; do
|
|
dest="packages/dart/android/src/main/jniLibs/${abi}"
|
|
mkdir -p "$dest"
|
|
src="dart-android-artifacts/${abi}/libkreuzberg_dart.so"
|
|
[[ -f "$src" ]] && cp -v "$src" "$dest/"
|
|
done
|
|
# iOS XCFramework
|
|
mkdir -p packages/dart/ios/Frameworks
|
|
for xcf in dart-ios-xcframework/*.xcframework; do
|
|
[[ -d "$xcf" ]] && cp -r "$xcf" packages/dart/ios/Frameworks/
|
|
done
|
|
# Server blobs
|
|
for entry in "linux-x86_64:libkreuzberg_dart.so" "linux-aarch64:libkreuzberg_dart.so" "macos-arm64:libkreuzberg_dart.dylib" "windows-x86_64:kreuzberg_dart.dll"; do
|
|
blob="${entry%%:*}"
|
|
lib="${entry##*:}"
|
|
dest="packages/dart/blobs/${blob}"
|
|
mkdir -p "$dest"
|
|
src="dart-server-artifacts/${blob}/${lib}"
|
|
[[ -f "$src" ]] && cp -v "$src" "$dest/"
|
|
done
|
|
|
|
- uses: actions/upload-artifact@v7.0.1
|
|
with:
|
|
name: dart-package-assembled
|
|
path: packages/dart
|
|
retention-days: 7
|
|
|
|
trigger-pubdev:
|
|
name: Trigger pub.dev publish workflow
|
|
needs: [prepare, check-pub, assemble-dart-bundle]
|
|
# pub.dev OIDC rejects tokens from `release` events. We dispatch a separate
|
|
# workflow whose `workflow_dispatch` event produces an accepted token, then
|
|
# have it download the assembled Dart package artifact from this run.
|
|
if: ${{ needs.prepare.outputs.release_dart == 'true' && needs.prepare.outputs.is_tag == 'true' && needs.prepare.outputs.dry_run != 'true' && (needs.check-pub.outputs.exists != 'true' || needs.prepare.outputs.force_republish == 'true') }}
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
actions: write
|
|
steps:
|
|
- name: Dispatch publish-pubdev workflow
|
|
env:
|
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
GH_REPO: ${{ github.repository }}
|
|
run: |
|
|
gh workflow run publish-pubdev.yaml \
|
|
--ref ${{ github.ref_name }} \
|
|
-f run_id=${{ github.run_id }}
|
|
|
|
publish-zig:
|
|
name: Publish Zig package metadata
|
|
needs: [prepare, finalize-github-release-after-uploads, check-zig]
|
|
if: ${{ needs.prepare.outputs.release_zig == 'true' && needs.prepare.outputs.is_tag == 'true' && (needs.check-zig.outputs.exists != 'true' || needs.prepare.outputs.force_republish == 'true') }}
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v6
|
|
with:
|
|
ref: ${{ needs.prepare.outputs.ref }}
|
|
submodules: recursive
|
|
|
|
- uses: kreuzberg-dev/actions/publish-zig@v1
|
|
with:
|
|
working-directory: packages/zig
|
|
tag: ${{ needs.prepare.outputs.tag }}
|
|
# Override the auto-detected package-name (`.kreuzberg` from
|
|
# build.zig.zon) to match the alef-emitted test_app URL pattern
|
|
# `{crate-name}-zig-v{version}.tar.gz`. Without this, the asset
|
|
# uploads as `kreuzberg-v{version}.tar.gz` while test_apps/zig
|
|
# fetches `kreuzberg-zig-v{version}.tar.gz` → 404 + consumer
|
|
# build.zig.zon TODO hash.
|
|
package-name: kreuzberg-zig
|
|
update-release-notes: "true"
|
|
dry-run: ${{ needs.prepare.outputs.dry_run }}
|
|
env:
|
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
# ─── Homebrew (formula update + bottles) ──────────────────────────────
|
|
#
|
|
# Topology mirrors html-to-markdown:
|
|
# 1. publish-homebrew-formula — update formula source URL/sha (no bottles)
|
|
# 2. homebrew-bottles — build bottle tarballs + JSON manifests
|
|
# 3. publish-homebrew-bottles — merge bottle DSL into formula and push
|
|
|
|
publish-homebrew-formula:
|
|
name: Update Homebrew formula
|
|
needs: [prepare, upload-cli-release, check-homebrew]
|
|
if: ${{ needs.prepare.outputs.release_homebrew == 'true' && needs.prepare.outputs.is_tag == 'true' && needs.check-homebrew.outputs.exists != 'true' }}
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
contents: write
|
|
steps:
|
|
- name: Checkout source repo
|
|
uses: actions/checkout@v6.0.2
|
|
with:
|
|
ref: ${{ needs.prepare.outputs.checkout_ref }}
|
|
|
|
- name: Checkout homebrew-tap
|
|
uses: actions/checkout@v6.0.2
|
|
with:
|
|
repository: kreuzberg-dev/homebrew-tap
|
|
token: ${{ secrets.HOMEBREW_TOKEN }}
|
|
path: homebrew-tap
|
|
|
|
- name: Update formula files
|
|
# Inline: bumps url/sha256/version in Formula/kreuzberg.rb. Equivalent
|
|
# of html-to-markdown's scripts/publish/update-homebrew-formula.sh.
|
|
env:
|
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
TAG: ${{ needs.prepare.outputs.tag }}
|
|
VERSION: ${{ needs.prepare.outputs.version }}
|
|
TAP_DIR: ${{ github.workspace }}/homebrew-tap
|
|
DRY_RUN: ${{ needs.prepare.outputs.dry_run }}
|
|
run: scripts/publish/update-homebrew-formula.sh
|
|
shell: bash
|
|
|
|
- name: Commit and push to tap
|
|
if: ${{ needs.prepare.outputs.dry_run != 'true' }}
|
|
working-directory: homebrew-tap
|
|
env:
|
|
GH_TOKEN: ${{ secrets.HOMEBREW_TOKEN }}
|
|
run: |
|
|
git config user.name "kreuzberg-bot"
|
|
git config user.email "bot@kreuzberg.dev"
|
|
if git diff --quiet Formula/; then
|
|
echo "No formula changes; skipping commit."
|
|
exit 0
|
|
fi
|
|
git add Formula/kreuzberg.rb
|
|
git commit -m "kreuzberg ${{ needs.prepare.outputs.version }}"
|
|
git push origin HEAD
|
|
shell: bash
|
|
|
|
homebrew-bottles:
|
|
name: Build Homebrew bottle (${{ matrix.bottle_tag }})
|
|
needs: [prepare, publish-homebrew-formula]
|
|
if: ${{ needs.prepare.outputs.release_homebrew == 'true' && needs.prepare.outputs.is_tag == 'true' }}
|
|
runs-on: ${{ matrix.os }}
|
|
permissions:
|
|
contents: write
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- { os: macos-latest, bottle_tag: arm64_sonoma, install_brew: false }
|
|
# Intel macOS (sequoia, macos-15-intel) bottle dropped: ort-sys 2.0.0-rc.12 has no
|
|
# prebuilt for x86_64-apple-darwin. Re-add once upstream ships it or we switch to
|
|
# a no-ort feature set for Intel Macs.
|
|
- { os: ubuntu-latest, bottle_tag: x86_64_linux, install_brew: true }
|
|
- { os: ubuntu-24.04-arm, bottle_tag: arm64_linux, install_brew: true }
|
|
steps:
|
|
- uses: actions/checkout@v5
|
|
with:
|
|
ref: ${{ needs.prepare.outputs.checkout_ref }}
|
|
|
|
submodules: recursive
|
|
- name: Install Homebrew (Linux)
|
|
if: ${{ matrix.install_brew }}
|
|
uses: kreuzberg-dev/actions/install-homebrew-linux@v1
|
|
|
|
- name: Build bottles
|
|
uses: kreuzberg-dev/actions/homebrew-build-bottles@v1
|
|
with:
|
|
tag: ${{ needs.prepare.outputs.tag }}
|
|
version: ${{ needs.prepare.outputs.version }}
|
|
tap: kreuzberg-dev/homebrew-tap
|
|
formulas: |
|
|
kreuzberg
|
|
out-dir: ${{ github.workspace }}/bottle-json
|
|
github-repo: kreuzberg-dev/kreuzberg
|
|
token: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
- uses: actions/upload-artifact@v7.0.1
|
|
with:
|
|
name: homebrew-bottle-json-${{ matrix.bottle_tag }}
|
|
path: ${{ github.workspace }}/bottle-json/*.json
|
|
if-no-files-found: error
|
|
retention-days: 14
|
|
|
|
publish-homebrew-bottles:
|
|
name: Merge Homebrew bottle DSL
|
|
needs: [prepare, publish-homebrew-formula, homebrew-bottles]
|
|
if: ${{ needs.prepare.outputs.release_homebrew == 'true' && needs.prepare.outputs.is_tag == 'true' }}
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
contents: write
|
|
steps:
|
|
- uses: actions/checkout@v6.0.2
|
|
with:
|
|
ref: ${{ needs.prepare.outputs.checkout_ref }}
|
|
|
|
submodules: recursive
|
|
- name: Checkout homebrew-tap
|
|
uses: actions/checkout@v6.0.2
|
|
with:
|
|
repository: kreuzberg-dev/homebrew-tap
|
|
token: ${{ secrets.HOMEBREW_TOKEN }}
|
|
path: homebrew-tap
|
|
|
|
- uses: actions/download-artifact@v8.0.1
|
|
with:
|
|
path: ${{ github.workspace }}/bottle-json
|
|
pattern: homebrew-bottle-json-*
|
|
merge-multiple: true
|
|
|
|
- uses: kreuzberg-dev/actions/homebrew-merge-bottles@v1
|
|
with:
|
|
tag: ${{ needs.prepare.outputs.tag }}
|
|
version: ${{ needs.prepare.outputs.version }}
|
|
tap-dir: ${{ github.workspace }}/homebrew-tap
|
|
json-dir: ${{ github.workspace }}/bottle-json
|
|
formulas: |
|
|
kreuzberg
|
|
github-repo: kreuzberg-dev/kreuzberg
|
|
|
|
- name: Commit and push bottle DSL
|
|
if: ${{ needs.prepare.outputs.dry_run != 'true' }}
|
|
# Inline: tap-side commit/push of the regenerated formula. No shared
|
|
# action covers tap commits — each repo's bot identity is unique.
|
|
working-directory: homebrew-tap
|
|
env:
|
|
GH_TOKEN: ${{ secrets.HOMEBREW_TOKEN }}
|
|
run: |
|
|
git config user.name "kreuzberg-bot"
|
|
git config user.email "bot@kreuzberg.dev"
|
|
if git diff --quiet Formula/; then
|
|
echo "No bottle DSL changes; skipping commit."
|
|
exit 0
|
|
fi
|
|
git add Formula/kreuzberg.rb
|
|
git commit -m "kreuzberg ${{ needs.prepare.outputs.version }}: add bottle DSL"
|
|
git push origin HEAD
|
|
shell: bash
|
|
|
|
# ─── Finalization ─────────────────────────────────────────────────────
|
|
|
|
release-finalize:
|
|
name: Finalize GitHub Release (post-publish validation)
|
|
needs:
|
|
- prepare
|
|
- finalize-github-release-after-uploads
|
|
- publish-crates
|
|
- publish-pypi
|
|
- publish-rubygems
|
|
- publish-node
|
|
- publish-wasm
|
|
- publish-packagist
|
|
- publish-maven
|
|
- publish-kotlin-android
|
|
- publish-nuget
|
|
- publish-hex
|
|
- trigger-pubdev
|
|
- publish-zig
|
|
- publish-homebrew-formula
|
|
- publish-homebrew-bottles
|
|
if: |
|
|
always() &&
|
|
!cancelled() &&
|
|
needs.prepare.outputs.is_tag == 'true' &&
|
|
needs.prepare.outputs.dry_run != 'true' &&
|
|
!contains(needs.*.result, 'failure')
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
contents: write
|
|
steps:
|
|
- uses: kreuzberg-dev/actions/finalize-release@v1
|
|
with:
|
|
tag: ${{ needs.prepare.outputs.tag }}
|
|
is-prerelease: ${{ needs.prepare.outputs.is_prerelease == 'true' && 'true' || 'false' }}
|
|
go-module-path: packages/go/v5
|
|
|
|
announce-discord:
|
|
name: Announce release on Discord
|
|
needs:
|
|
- prepare
|
|
- publish-crates
|
|
- publish-pypi
|
|
- publish-rubygems
|
|
- publish-node
|
|
- publish-wasm
|
|
- publish-packagist
|
|
- publish-maven
|
|
- publish-kotlin-android
|
|
- publish-nuget
|
|
- publish-hex
|
|
- trigger-pubdev
|
|
- publish-zig
|
|
- publish-homebrew-formula
|
|
- publish-homebrew-bottles
|
|
- upload-cli-release
|
|
- upload-go-release
|
|
- upload-c-ffi-release
|
|
- upload-elixir-release
|
|
- upload-php-pie-release
|
|
- upload-swift-bundle
|
|
- release-finalize
|
|
if: |
|
|
always() &&
|
|
!cancelled() &&
|
|
needs.prepare.outputs.is_tag == 'true' &&
|
|
needs.prepare.outputs.dry_run != 'true' &&
|
|
needs.prepare.outputs.is_prerelease != 'true' &&
|
|
!contains(needs.*.result, 'failure')
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
contents: write
|
|
steps:
|
|
- uses: kreuzberg-dev/actions/announce-release-discord@v1
|
|
with:
|
|
tag: ${{ needs.prepare.outputs.tag }}
|
|
webhook-url: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
|
project-name: kreuzberg
|