diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d9efe52..bbee280 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -180,14 +180,45 @@ jobs: CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} native-bundles: - name: Native bundle (${{ matrix.os }}) + name: Module bundle (${{ matrix.id }}) needs: publish strategy: fail-fast: false matrix: - os: - - ubuntu-latest - - macos-latest + include: + - id: ubuntu-22.04-x86_64 + os: ubuntu-22.04 + target: x86_64-unknown-linux-gnu + - id: ubuntu-22.04-arm64 + os: ubuntu-22.04-arm + target: aarch64-unknown-linux-gnu + - id: ubuntu-24.04-x86_64 + os: ubuntu-24.04 + target: x86_64-unknown-linux-gnu + - id: ubuntu-24.04-arm64 + os: ubuntu-24.04-arm + target: aarch64-unknown-linux-gnu + - id: macos-15-x86_64 + os: macos-15-intel + target: x86_64-apple-darwin + - id: macos-15-arm64 + os: macos-15 + target: aarch64-apple-darwin + - id: macos-26-x86_64 + os: macos-26-intel + target: x86_64-apple-darwin + - id: macos-26-arm64 + os: macos-26 + target: aarch64-apple-darwin + - id: windows-2022-x86_64 + os: windows-2022 + target: x86_64-pc-windows-msvc + - id: windows-2025-x86_64 + os: windows-2025 + target: x86_64-pc-windows-msvc + - id: windows-11-arm64 + os: windows-11-arm + target: aarch64-pc-windows-msvc runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v7 @@ -199,60 +230,83 @@ jobs: - uses: dtolnay/rust-toolchain@stable - uses: Swatinem/rust-cache@v2 - with: - workspaces: | - . -> target - vendor/tinybus -> target - - name: Build TinyBus host - working-directory: vendor/tinybus - run: cargo build --locked --release --package tinybus --all-features --bin tinybus + - name: Verify native Rust target + shell: bash + env: + EXPECTED_TARGET: ${{ matrix.target }} + run: | + set -euo pipefail + actual_target="$(rustc -vV | sed -n 's/^host: //p')" + [[ "$actual_target" == "$EXPECTED_TARGET" ]] - - name: Build TinyDocs module + - name: Build installable module run: cargo build --locked --release --package tinydocs-module - - name: Assemble native bundle - id: bundle + - name: Assemble Unix module package + if: ${{ runner.os != 'Windows' }} + id: unix_package shell: bash env: - TINYBUS_VERSION: ${{ needs.publish.outputs.tinybus_version }} - TINYDOCS_VERSION: ${{ needs.publish.outputs.next_version }} + BUNDLE_ID: ${{ matrix.id }} + VERSION: ${{ needs.publish.outputs.next_version }} run: | set -euo pipefail - target_triple="$(rustc -vV | sed -n 's/^host: //p')" - bundle_name="tinydocs-${TINYDOCS_VERSION}-tinybus-${TINYBUS_VERSION}-${target_triple}" - bundle_root="dist/${bundle_name}" - module_root="${bundle_root}/modules" - mkdir -p "${bundle_root}/bin" "$module_root" "${bundle_root}/docs" - - install -m 755 vendor/tinybus/target/release/tinybus "${bundle_root}/bin/tinybus" - - module_artifact="$(find target/release -maxdepth 1 -type f \( -name 'libtinydocs_module.so' -o -name 'libtinydocs_module.dylib' \) -print -quit)" - if [[ -z "$module_artifact" || ! -f "$module_artifact" ]]; then - echo "the TinyDocs module artifact is missing" >&2 - exit 1 - fi - install -m 644 "$module_artifact" "$module_root/" - - module_name="$(basename "$module_artifact")" - module_hash="$(shasum -a 256 "${module_root}/${module_name}" | awk '{print $1}')" - printf '"%s" = "%s"\n' "$module_name" "$module_hash" > "${module_root}/modules.toml" - - install -m 644 LICENSE "${bundle_root}/LICENSE" - install -m 644 README.md "${bundle_root}/README.md" - install -m 644 docs/specs/tinybus-module.md "${bundle_root}/docs/tinydocs-module.md" - install -m 644 vendor/tinybus/docs/protocol.md "${bundle_root}/docs/tinybus-protocol.md" - cp -R vendor/tinybus/docs/modules "${bundle_root}/docs/tinybus-modules" - - tar -C dist -czf "dist/${bundle_name}.tar.gz" "$bundle_name" - echo "archive=dist/${bundle_name}.tar.gz" >> "$GITHUB_OUTPUT" + library_name="tinydocs_module" + case "$RUNNER_OS" in + Linux) module="target/release/lib${library_name}.so" ;; + macOS) module="target/release/lib${library_name}.dylib" ;; + *) echo "unsupported Unix runner: ${RUNNER_OS}" >&2; exit 1 ;; + esac + package_name="tinydocs-module-${VERSION}-${BUNDLE_ID}" + package_root="dist/${package_name}" + mkdir -p "$package_root" + install -m 755 "$module" "$package_root/" + install -m 644 LICENSE README.md docs/specs/tinybus-module.md "$package_root/" + module_name="$(basename "$module")" + module_hash="$(sha256sum "$package_root/$module_name" | awk '{print $1}')" + printf '"%s" = "%s"\n' "$module_name" "$module_hash" \ + > "$package_root/modules.toml" + tar -C "$package_root" -czf "dist/${package_name}.tar.gz" . + echo "archive=dist/${package_name}.tar.gz" >> "$GITHUB_OUTPUT" + + - name: Assemble Windows module package + if: ${{ runner.os == 'Windows' }} + id: windows_package + shell: pwsh + env: + BUNDLE_ID: ${{ matrix.id }} + VERSION: ${{ needs.publish.outputs.next_version }} + run: | + $ErrorActionPreference = 'Stop' + $libraryName = 'tinydocs_module' + $module = "target/release/$libraryName.dll" + $packageName = "tinydocs-module-$env:VERSION-$env:BUNDLE_ID" + $packageRoot = "dist/$packageName" + New-Item -ItemType Directory -Force $packageRoot | Out-Null + Copy-Item -LiteralPath $module, 'LICENSE', 'README.md' -Destination $packageRoot + $hash = (Get-FileHash -LiteralPath $module -Algorithm SHA256).Hash.ToLowerInvariant() + $moduleName = Split-Path -Leaf $module + "`"$moduleName`" = `"$hash`"`n" | + Set-Content -Path "$packageRoot/modules.toml" -Encoding utf8NoBOM + Compress-Archive -Path "$packageRoot/*" -DestinationPath "dist/$packageName.zip" + "archive=dist/$packageName.zip" >> $env:GITHUB_OUTPUT + + - name: Upload Unix module package + if: ${{ runner.os != 'Windows' }} + uses: actions/upload-artifact@v4 + with: + name: tinydocs-module-${{ matrix.id }} + path: ${{ steps.unix_package.outputs.archive }} + if-no-files-found: error - - name: Upload native bundle + - name: Upload Windows module package + if: ${{ runner.os == 'Windows' }} uses: actions/upload-artifact@v4 with: - name: tinydocs-${{ runner.os }} - path: ${{ steps.bundle.outputs.archive }} + name: tinydocs-module-${{ matrix.id }} + path: ${{ steps.windows_package.outputs.archive }} if-no-files-found: error github-release: @@ -268,14 +322,55 @@ jobs: path: release-assets merge-multiple: true + - uses: actions/checkout@v7 + with: + ref: ${{ needs.publish.outputs.tag }} + persist-credentials: false + submodules: true + + - uses: dtolnay/rust-toolchain@stable + + - name: Create release checksum manifest with TinyBus + shell: bash + run: | + set -euo pipefail + shopt -s nullglob + assets=(release-assets/tinydocs-module-*.tar.gz release-assets/tinydocs-module-*.zip) + if [[ ${#assets[@]} -ne 11 ]]; then + echo "expected 11 module archives, found ${#assets[@]}" >&2 + exit 1 + fi + checksum_args=() + for asset in "${assets[@]}"; do checksum_args+=(--path "$asset"); done + cargo run --manifest-path vendor/tinybus/Cargo.toml --locked \ + --package tinybus --all-features --bin tinybus -- \ + modules checksum "${checksum_args[@]}" --output release-assets/checksum.toml + - name: Create release and upload assets env: GH_TOKEN: ${{ github.token }} RELEASE_TAG: ${{ needs.publish.outputs.tag }} REPOSITORY: ${{ github.repository }} - run: >- - gh release create "$RELEASE_TAG" release-assets/* - --repo "$REPOSITORY" - --verify-tag - --title "$RELEASE_TAG" - --generate-notes + run: | + set -euo pipefail + gh release create "$RELEASE_TAG" release-assets/* \ + --repo "$REPOSITORY" \ + --verify-tag \ + --title "$RELEASE_TAG" \ + --generate-notes + + - name: Verify the published module through TinyBus + shell: bash + env: + RELEASE_TAG: ${{ needs.publish.outputs.tag }} + REPOSITORY: ${{ github.repository }} + VERSION: ${{ needs.publish.outputs.next_version }} + run: | + set -euo pipefail + archive="tinydocs-module-${VERSION}-ubuntu-24.04-x86_64.tar.gz" + release_url="https://github.com/${REPOSITORY}/releases/tag/${RELEASE_TAG}" + sha256="$(sed -n "s/^\"${archive}\" = \"\([0-9a-f]\{64\}\)\"$/\1/p" release-assets/checksum.toml)" + test -n "$sha256" + cargo run --manifest-path vendor/tinybus/Cargo.toml --locked \ + --package tinybus --all-features --example github_module_host -- \ + "$release_url" "$archive" "$sha256" diff --git a/Cargo.lock b/Cargo.lock index 5783deb..db2c31f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -40,6 +40,12 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "base64" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac07cdecf99051d9a5238b80f35af32cdeba5b336e55d957b318b50137e18da5" + [[package]] name = "bitflags" version = "2.13.1" @@ -70,6 +76,16 @@ version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04" +[[package]] +name = "cc" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d262e149917187838d5b42777c8253bcb64500067342904e7d429499a6f277e" +dependencies = [ + "find-msvc-tools", + "shlex", +] + [[package]] name = "cfg-if" version = "1.0.4" @@ -131,7 +147,7 @@ version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fdf00e8af6d0b3e92d4bbf9b76f773d8b84ea80f310324ad16cbdc2e653e02c" dependencies = [ - "base64", + "base64 0.22.1", "crc32fast", "image", "quick-xml", @@ -157,6 +173,22 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + +[[package]] +name = "fastrand" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da7c62ceae207dd37ea5b845da6a0696c799f85e97da1ab5b7910be3c1c80223" + [[package]] name = "fax" version = "0.2.7" @@ -172,6 +204,22 @@ dependencies = [ "simd-adler32", ] +[[package]] +name = "filetime" +version = "0.2.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c287a33c7f0a620c38e641e7f60827713987b3c0f26e8ddc9462cc69cf75759" +dependencies = [ + "cfg-if", + "libc", +] + +[[package]] +name = "find-msvc-tools" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b73573e6edcd2af0cdf47bd6cb58f0b3839491263c314eaad1ccf24430e1de" + [[package]] name = "flate2" version = "1.1.9" @@ -183,6 +231,28 @@ dependencies = [ "zlib-rs", ] +[[package]] +name = "getrandom" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "getrandom" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" +dependencies = [ + "cfg-if", + "libc", + "r-efi", +] + [[package]] name = "gif" version = "0.14.2" @@ -210,6 +280,22 @@ version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" +[[package]] +name = "http" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "918d3568bebf352712bc2ef3d46a8bcf1a75b373be6539de198e9105cbbf9ce0" +dependencies = [ + "bytes", + "itoa", +] + +[[package]] +name = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + [[package]] name = "image" version = "0.25.9" @@ -244,6 +330,18 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" +[[package]] +name = "libc" +version = "0.2.189" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" + +[[package]] +name = "linux-raw-sys" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" + [[package]] name = "log" version = "0.4.33" @@ -291,6 +389,12 @@ version = "1.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" +[[package]] +name = "percent-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + [[package]] name = "pin-project-lite" version = "0.2.17" @@ -350,6 +454,74 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + +[[package]] +name = "ring" +version = "0.17.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.17", + "libc", + "untrusted", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustix" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.61.2", +] + +[[package]] +name = "rustls" +version = "0.23.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0283386ce02abc0151e1761d08802dfe86c173b0b494af5cbc086574e453da06" +dependencies = [ + "log", + "once_cell", + "ring", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-pki-types" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f4925028c7eb5d1fcdaf196971378ed9d2c1c4efc7dc5d011256f76c99c0a96" +dependencies = [ + "zeroize", +] + +[[package]] +name = "rustls-webpki" +version = "0.103.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + [[package]] name = "serde" version = "1.0.229" @@ -393,6 +565,21 @@ dependencies = [ "zmij", ] +[[package]] +name = "serde_spanned" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" +dependencies = [ + "serde", +] + +[[package]] +name = "shlex" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" + [[package]] name = "simd-adler32" version = "0.3.10" @@ -405,6 +592,12 @@ version = "1.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + [[package]] name = "syn" version = "2.0.119" @@ -427,6 +620,30 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "tar" +version = "0.4.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f6221d9a6003c78398e3b239969f352578258df48c8eb051caadae0015bc840" +dependencies = [ + "filetime", + "libc", + "xattr", +] + +[[package]] +name = "tempfile" +version = "3.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" +dependencies = [ + "fastrand", + "getrandom 0.4.3", + "once_cell", + "rustix", + "windows-sys 0.61.2", +] + [[package]] name = "thiserror" version = "2.0.20" @@ -466,12 +683,18 @@ name = "tinybus" version = "0.1.0" dependencies = [ "async-trait", + "flate2", "serde", "serde_json", + "tar", + "tempfile", "thiserror", "tinybus-macros", "tokio", + "toml", "tracing", + "ureq", + "zip 2.4.2", ] [[package]] @@ -538,6 +761,47 @@ dependencies = [ "syn 3.0.3", ] +[[package]] +name = "toml" +version = "0.8.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.22.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "toml_write", + "winnow", +] + +[[package]] +name = "toml_write" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" + [[package]] name = "tracing" version = "0.1.44" @@ -581,12 +845,175 @@ version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "ureq" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "972d7902c8735f2695410b8aed7df6ed12a47394aa1c8d7af49f0497b731a94d" +dependencies = [ + "base64 0.23.1", + "flate2", + "log", + "percent-encoding", + "rustls", + "rustls-pki-types", + "ureq-proto", + "utf8-zero", + "webpki-roots", +] + +[[package]] +name = "ureq-proto" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da5f78b09e6941e1a0f2e30e695e4b120377b54d5e0aec11b594bb57b3971613" +dependencies = [ + "base64 0.23.1", + "http", + "httparse", + "log", +] + +[[package]] +name = "utf8-zero" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8c0a043c9540bae7c578c88f91dda8bd82e59ae27c21baca69c8b191aaf5a6e" + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "webpki-roots" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dcd9d09a39985f5344844e66b0c530a33843579125f23e21e9f0f220850f22a" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "weezl" version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a28ac98ddc8b9274cb41bb4d9d4d5c425b6020c50c46f25559911905610b4a88" +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winnow" +version = "0.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" +dependencies = [ + "memchr", +] + +[[package]] +name = "xattr" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32e45ad4206f6d2479085147f02bc2ef834ac85886624a23575ae137c8aa8156" +dependencies = [ + "libc", + "rustix", +] + [[package]] name = "zerocopy" version = "0.8.56" @@ -607,6 +1034,12 @@ dependencies = [ "syn 2.0.119", ] +[[package]] +name = "zeroize" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e" + [[package]] name = "zip" version = "2.4.2" diff --git a/README.md b/README.md index f8bca37..13dcf54 100644 --- a/README.md +++ b/README.md @@ -88,10 +88,16 @@ GenerateDocx(DocumentSpec) -> Vec The release workflow attaches installable Linux and macOS bundles containing the matching TinyBus host, the TinyDocs module, a SHA-256 `modules.toml` -allowlist, and protocol/module documentation. It also attaches the published -crate and pinned TinyBus source. TinyBus modules are target-specific and -trusted: download the bundle matching the host, and install it only from a -trusted release. +allowlist, and protocol/module documentation. It also publishes +`checksum.toml`, which TinyBus uses to verify a downloaded precompiled module +archive, plus the crates.io package and pinned TinyBus source. TinyBus modules +are target-specific and trusted: download the bundle matching the host, and +install it only from a trusted release. + +A TinyBus host can download and verify the matching archive directly from a +tagged GitHub release with `ModuleHost::load_github_release`; the archive must +be selected by its exact target-specific asset name and the release URL must +point to the tag, not a moving branch. Run the real loader test locally after building the release artifact: diff --git a/crates/tinydocs-module/tests/module_e2e.rs b/crates/tinydocs-module/tests/module_e2e.rs index f346bc9..c52e85e 100644 --- a/crates/tinydocs-module/tests/module_e2e.rs +++ b/crates/tinydocs-module/tests/module_e2e.rs @@ -22,6 +22,16 @@ async fn built_cdylib_loads_and_generates_a_docx_over_the_bus() { let modules = ModuleHost::new(broker); let loaded = modules.load_file(artifact).expect("module should load"); assert_eq!(loaded.name, "tinydocs-module"); + assert_eq!(loaded.manifest.bus_name.as_str(), BUS_NAME); + assert_eq!(loaded.manifest.object_path.as_str(), OBJECT_PATH); + assert!( + loaded + .manifest + .provides + .iter() + .flat_map(|interface| interface.methods.iter()) + .any(|method| method.as_str() == "GenerateDocx") + ); let client = Connection::connect(bus.connect().await.unwrap()) .await diff --git a/docs/plans/tinybus-module.md b/docs/plans/tinybus-module.md index b37b3c9..6df8344 100644 --- a/docs/plans/tinybus-module.md +++ b/docs/plans/tinybus-module.md @@ -18,6 +18,8 @@ default library dependency graph. - [x] Run that real-loader test in CI. - [x] Build and upload installable Linux and macOS TinyBus bundles, source packages, module allowlists, and documentation during release. +- [x] Publish a release-level `checksum.toml` so TinyBus can verify each + precompiled module archive before extraction. - [x] Document build, loading, trust, and payload constraints. ## Verification diff --git a/docs/specs/tinybus-module.md b/docs/specs/tinybus-module.md index 4df3908..a3ed6f0 100644 --- a/docs/specs/tinybus-module.md +++ b/docs/specs/tinybus-module.md @@ -68,6 +68,8 @@ module itself retains no document state between calls. - CI executes that loader test on Linux. - A release uploads Linux and macOS bundles containing the matching TinyBus host, TinyDocs module, SHA-256 allowlist, and operational documentation. +- A release uploads `checksum.toml` with the SHA-256 digest of every archive so + TinyBus can verify a precompiled module before extracting or loading it. - The release also uploads the crates.io package and pinned TinyBus source. ## Open questions diff --git a/vendor/tinybus b/vendor/tinybus index dd6063a..0b161d2 160000 --- a/vendor/tinybus +++ b/vendor/tinybus @@ -1 +1 @@ -Subproject commit dd6063afc71ed82d2c9609f83fdbab758b96c2ed +Subproject commit 0b161d201f4517116d3df2f33662eec2538724dc