-
Notifications
You must be signed in to change notification settings - Fork 2
Add TinyBus module integration and release binaries #2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
73bbfdc
697210e
6be3ade
bf7b69d
0cc9720
665ad2f
682d01d
ade3153
d27f28e
9056853
547baea
9302965
6fd5f55
64e8b9c
873d193
9e438d7
81b208e
6607b10
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,73 @@ | ||
| #!/usr/bin/env bash | ||
| set -euo pipefail | ||
|
|
||
| minimum="${1:-90}" | ||
| report="${2:-coverage.json}" | ||
| workspace_root="$(pwd -P)/" | ||
| source_root="${workspace_root}src/" | ||
|
|
||
| cargo llvm-cov \ | ||
| --locked \ | ||
| --all-targets \ | ||
| --all-features \ | ||
| --json \ | ||
| --output-path "$report" | ||
|
|
||
| covered_files="$(jq --arg source_root "$source_root" ' | ||
| [ | ||
| .data[].files[] | ||
| | select(.filename | startswith($source_root)) | ||
| | select(.summary.lines.count > 0) | ||
| ] | ||
| | length | ||
| ' "$report")" | ||
|
|
||
| if [[ "$covered_files" -eq 0 ]]; then | ||
| echo "coverage report contains no files with executable lines under src/" >&2 | ||
| exit 1 | ||
| fi | ||
|
|
||
| summary="$(jq -r --arg workspace_root "$workspace_root" --arg source_root "$source_root" ' | ||
| .data[].files[] | ||
| | select(.filename | startswith($source_root)) | ||
| | select(.summary.lines.count > 0) | ||
| | [ | ||
| (.filename | ltrimstr($workspace_root)), | ||
| (.summary.lines.percent | tostring), | ||
| (.summary.lines.covered | tostring), | ||
| (.summary.lines.count | tostring) | ||
| ] | ||
| | @tsv | ||
| ' "$report")" | ||
|
|
||
| printf 'File\tLine coverage\tCovered lines\tCoverable lines\n' | ||
| while IFS=$'\t' read -r file percent covered count; do | ||
| printf '%s\t%.2f%%\t%s\t%s\n' "$file" "$percent" "$covered" "$count" | ||
| done <<< "$summary" | ||
|
|
||
| if [[ -n "${GITHUB_STEP_SUMMARY:-}" ]]; then | ||
| { | ||
| printf '### Per-file line coverage\n\n' | ||
| printf '| File | Coverage | Lines |\n' | ||
| printf '| --- | ---: | ---: |\n' | ||
| while IFS=$'\t' read -r file percent covered count; do | ||
| printf '| %s | %.2f%% | %s/%s |\n' "$file" "$percent" "$covered" "$count" | ||
| done <<< "$summary" | ||
| } >> "$GITHUB_STEP_SUMMARY" | ||
| fi | ||
|
|
||
| failures="$(jq -r \ | ||
| --arg workspace_root "$workspace_root" \ | ||
| --arg source_root "$source_root" \ | ||
| --argjson minimum "$minimum" ' | ||
| .data[].files[] | ||
| | select(.filename | startswith($source_root)) | ||
| | select(.summary.lines.count > 0) | ||
| | select(.summary.lines.percent < $minimum) | ||
| | "\(.filename | ltrimstr($workspace_root)): \(.summary.lines.percent)%" | ||
| ' "$report")" | ||
|
|
||
| if [[ -n "$failures" ]]; then | ||
| printf '\nFiles below %s%% line coverage:\n%s\n' "$minimum" "$failures" >&2 | ||
| exit 1 | ||
| fi |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -25,6 +25,11 @@ jobs: | |
| if: ${{ github.ref == 'refs/heads/main' }} | ||
| runs-on: ubuntu-latest | ||
| environment: Production | ||
| outputs: | ||
| crate_name: ${{ steps.version.outputs.crate_name }} | ||
| next_version: ${{ steps.version.outputs.next_version }} | ||
| tag: ${{ steps.version.outputs.tag }} | ||
| tinybus_version: ${{ steps.version.outputs.tinybus_version }} | ||
| steps: | ||
| - uses: actions/checkout@v7 | ||
| with: | ||
|
|
@@ -35,6 +40,8 @@ jobs: | |
| with: | ||
| components: rustfmt, clippy | ||
|
|
||
| - uses: taiki-e/install-action@cargo-llvm-cov | ||
|
|
||
| - uses: Swatinem/rust-cache@v2 | ||
|
|
||
| - name: Check formatting | ||
|
|
@@ -46,6 +53,9 @@ jobs: | |
| - name: Test | ||
| run: cargo test --all-features | ||
|
|
||
| - name: Require 90% line coverage in every source file | ||
| run: .github/scripts/check-file-coverage.sh 90 coverage.json | ||
|
|
||
| - name: Build documentation | ||
| env: | ||
| RUSTDOCFLAGS: -D warnings | ||
|
|
@@ -58,12 +68,23 @@ jobs: | |
| set -euo pipefail | ||
|
|
||
| metadata="$(cargo metadata --format-version 1 --no-deps)" | ||
| crate_name="$(jq -r '.packages[0].name' <<< "$metadata")" | ||
| current_version="$(jq -r '.packages[0].version' <<< "$metadata")" | ||
| crate_name="tinydocs" | ||
| current_version="$(jq -r '.packages[] | select(.name == "tinydocs") | .version' <<< "$metadata")" | ||
| tinybus_version="$( | ||
| cargo metadata \ | ||
| --manifest-path vendor/tinybus/Cargo.toml \ | ||
| --format-version 1 \ | ||
| --no-deps \ | ||
| | jq -r '.packages[] | select(.name == "tinybus") | .version' | ||
| )" | ||
| if [[ -z "$current_version" || "$current_version" == "null" ]]; then | ||
| echo "Could not resolve the current crate version" >&2 | ||
| exit 1 | ||
| fi | ||
| if [[ -z "$tinybus_version" || "$tinybus_version" == "null" ]]; then | ||
| echo "Could not resolve the TinyBus version" >&2 | ||
| exit 1 | ||
| fi | ||
|
|
||
| IFS=. read -r major minor patch <<< "$current_version" | ||
| case "${{ inputs.bump }}" in | ||
|
|
@@ -99,6 +120,7 @@ jobs: | |
| echo "current_version=${current_version}" | ||
| echo "next_version=${next_version}" | ||
| echo "tag=${tag}" | ||
| echo "tinybus_version=${tinybus_version}" | ||
| } >> "$GITHUB_OUTPUT" | ||
|
|
||
| - name: Update crate version | ||
|
|
@@ -108,6 +130,7 @@ jobs: | |
| run: | | ||
| set -euo pipefail | ||
| perl -0pi -e 's/(\[package\][\s\S]*?\nversion = ")[^"]+(")/$1$ENV{NEXT_VERSION}$2/' Cargo.toml | ||
| perl -0pi -e 's/(\[package\][\s\S]*?\nversion = ")[^"]+(")/$1$ENV{NEXT_VERSION}$2/' crates/tinydocs-module/Cargo.toml | ||
| cargo update -p "$CRATE_NAME" --precise "$NEXT_VERSION" | ||
|
|
||
| - name: Commit version bump and tag | ||
|
|
@@ -117,12 +140,31 @@ jobs: | |
| set -euo pipefail | ||
| git config user.name "github-actions[bot]" | ||
| git config user.email "41898282+github-actions[bot]@users.noreply.github.com" | ||
| git add Cargo.toml Cargo.lock | ||
| git add Cargo.toml Cargo.lock crates/tinydocs-module/Cargo.toml | ||
| git commit -m "Release ${RELEASE_TAG}" | ||
| git tag -a "${RELEASE_TAG}" -m "Release ${RELEASE_TAG}" | ||
|
|
||
| - name: Package crate | ||
| run: cargo package --locked | ||
| run: cargo package --locked --package tinydocs | ||
|
|
||
| - name: Package TinyBus source and module SDK | ||
| run: | | ||
| set -euo pipefail | ||
| tinybus_revision="$(git -C vendor/tinybus rev-parse --short=12 HEAD)" | ||
| git -C vendor/tinybus archive \ | ||
| --format=tar.gz \ | ||
| --prefix="tinybus-${tinybus_revision}/" \ | ||
| --output="$PWD/target/package/tinybus-source-${tinybus_revision}.tar.gz" \ | ||
| HEAD | ||
|
|
||
| - name: Upload source packages | ||
| uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: source-packages | ||
| path: | | ||
| target/package/${{ steps.version.outputs.crate_name }}-${{ steps.version.outputs.next_version }}.crate | ||
| target/package/tinybus-source-*.tar.gz | ||
| if-no-files-found: error | ||
|
|
||
| - name: Push release commit and tag | ||
| env: | ||
|
|
@@ -133,6 +175,107 @@ jobs: | |
| git push origin "${RELEASE_TAG}" | ||
|
|
||
| - name: Publish to crates.io | ||
| run: cargo publish --locked | ||
| run: cargo publish --locked --package tinydocs | ||
| env: | ||
| CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} | ||
|
|
||
| native-bundles: | ||
| name: Native bundle (${{ matrix.os }}) | ||
| needs: publish | ||
| strategy: | ||
| fail-fast: false | ||
| matrix: | ||
| os: | ||
| - ubuntu-latest | ||
| - macos-latest | ||
| runs-on: ${{ matrix.os }} | ||
| steps: | ||
| - uses: actions/checkout@v7 | ||
| with: | ||
| ref: ${{ needs.publish.outputs.tag }} | ||
| persist-credentials: false | ||
| submodules: true | ||
|
|
||
| - uses: dtolnay/rust-toolchain@stable | ||
|
|
||
| - uses: Swatinem/rust-cache@v2 | ||
|
Comment on lines
+158
to
+166
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/usr/bin/env bash
set -euo pipefail
echo "== workflow outline =="
wc -l .github/workflows/release.yml
sed -n '1,230p' .github/workflows/release.yml
echo
echo "== uses lines =="
rg -n '^\s+-\s+uses:\s+|uses:\s+' .github/workflows/release.ymlRepository: tinyhumansai/tinydocs Length of output: 6765 Security Misconfiguration (CWE-829): Inclusion of Functionality from Untrusted Control Sphere Reachability: Internal Pin release-workflow actions to full commit SHAs. The release workflow runs actions while resolving the release commit, building the module, and uploading assets that 🤖 Prompt for AI Agents |
||
| 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: Build TinyDocs module | ||
| run: cargo build --locked --release --package tinydocs-module | ||
|
|
||
| - name: Assemble native bundle | ||
| id: bundle | ||
| shell: bash | ||
| env: | ||
| TINYBUS_VERSION: ${{ needs.publish.outputs.tinybus_version }} | ||
| TINYDOCS_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" | ||
|
|
||
| - name: Upload native bundle | ||
| uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: tinydocs-${{ runner.os }} | ||
| path: ${{ steps.bundle.outputs.archive }} | ||
| if-no-files-found: error | ||
|
|
||
| github-release: | ||
| name: Create GitHub release | ||
| needs: | ||
| - publish | ||
| - native-bundles | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/download-artifact@v4 | ||
| with: | ||
| pattern: '*' | ||
| path: release-assets | ||
| merge-multiple: true | ||
|
|
||
| - 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 | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
Repository: tinyhumansai/tinydocs
Length of output: 159
🏁 Script executed:
Repository: tinyhumansai/tinydocs
Length of output: 273
🏁 Script executed:
Repository: tinyhumansai/tinydocs
Length of output: 544
🏁 Script executed:
Repository: tinyhumansai/tinydocs
Length of output: 11173
🌐 Web query:
Cargo cargo update --workspace after manifest version changes documentation💡 Result:
The cargo update --workspace command is designed to update dependencies as recorded in the Cargo.lock file, specifically targeting packages defined within your workspace [1][2]. According to the official Cargo documentation, the --workspace (or -w) flag is primarily useful for updating Cargo.lock after you have manually changed version numbers in your Cargo.toml files [1][2]. When you use this flag, Cargo attempts to update only the packages defined in the workspace, while other packages are updated only if they do not already exist in the lockfile [1][3]. It is important to note that the cargo update command does not automatically modify or write to your Cargo.toml files to reflect new version requirements [4]. The command updates the dependency versions pinned in the Cargo.lock file based on the constraints already present in your manifest [2][5]. If you are looking to automatically update the version requirements inside your Cargo.toml files (e.g., upgrading a dependency to the latest version), you would typically use external tools like cargo-edit (specifically the cargo upgrade command) rather than cargo update [4][6]. In summary: - cargo update --workspace: Updates Cargo.lock to match changes you have already made in Cargo.toml [1][2]. - Cargo.toml changes: You must manually edit these or use other tools; cargo update will not update them for you [4].
Citations:
cargo-upgrade) rust-lang/cargo#10498Update the whole workspace lock after the version edits.
The release workflow edits both
Cargo.tomlandcrates/tinydocs-module/Cargo.toml, then recordsCargo.lockand later uses--lockedbuilds.cargo update -p "$CRATE_NAME" --precise "$NEXT_VERSION"only refreshestinydocs; runcargo update --workspaceinstead so both workspace package entries in the lockfile stay aligned.🤖 Prompt for AI Agents