v0.3.39 — analytics panel, migrate CLI, RTK auto-download, hot-reload… #237
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Release | |
| on: | |
| push: | |
| tags: | |
| - 'v*' | |
| permissions: | |
| contents: read | |
| env: | |
| CARGO_TERM_COLOR: always | |
| FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true | |
| jobs: | |
| # CI only runs on PRs (not pushes to main). For release tags, we verify | |
| # the commit is on main and skip CI polling entirely. PRs are where CI | |
| # gates happen; main is protected by branch protection requiring PR merge. | |
| wait-for-ci: | |
| name: Verify main branch | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Confirm commit is on main | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| SHA="${{ github.sha }}" | |
| REPO="${{ github.repository }}" | |
| # Verify the tag points to a commit on main | |
| MAIN_SHA=$(gh api "repos/$REPO/branches/main" --jq '.commit.sha' 2>/dev/null || echo "") | |
| if [ -z "$MAIN_SHA" ]; then | |
| echo "ERROR: Could not fetch main branch HEAD" | |
| exit 1 | |
| fi | |
| # Check if our SHA is reachable from main (may not be HEAD if tag is on older commit) | |
| MERGE_BASE=$(gh api "repos/$REPO/compare/${MAIN_SHA}...${SHA}" --jq '.status' 2>/dev/null || echo "error") | |
| case "$MERGE_BASE" in | |
| "identical"|"behind") | |
| echo "Commit $SHA is on main (main is at $MAIN_SHA)" | |
| ;; | |
| *) | |
| # Also accept if SHA IS main HEAD | |
| if [ "$SHA" = "$MAIN_SHA" ]; then | |
| echo "Commit $SHA is main HEAD" | |
| else | |
| echo "WARNING: Commit $SHA may not be on main (status: $MERGE_BASE). Proceeding anyway." | |
| fi | |
| ;; | |
| esac | |
| echo "Ready to release." | |
| publish-crate: | |
| name: Publish to crates.io | |
| needs: [wait-for-ci, build-release] | |
| runs-on: ubuntu-latest | |
| outputs: | |
| version: ${{ steps.check.outputs.version }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Check if already published | |
| id: check | |
| run: | | |
| VERSION=$(grep '^version' Cargo.toml | head -1 | sed 's/.*"\(.*\)"/\1/') | |
| echo "version=$VERSION" >> "$GITHUB_OUTPUT" | |
| if curl -sf "https://crates.io/api/v1/crates/opencrabs/$VERSION" > /dev/null 2>&1; then | |
| echo "published=true" >> "$GITHUB_OUTPUT" | |
| echo "v$VERSION already on crates.io — skipping build" | |
| else | |
| echo "published=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Install Rust | |
| if: steps.check.outputs.published == 'false' | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Install ALSA dev | |
| if: steps.check.outputs.published == 'false' | |
| run: sudo apt-get update && sudo apt-get install -y libasound2-dev | |
| - name: Publish | |
| if: steps.check.outputs.published == 'false' | |
| continue-on-error: true | |
| env: | |
| CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} | |
| run: cargo publish --allow-dirty | |
| build-release: | |
| name: Build Release | |
| needs: wait-for-ci | |
| runs-on: ${{ matrix.os }} | |
| permissions: | |
| contents: write | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - os: ubuntu-latest | |
| target: x86_64-unknown-linux-gnu | |
| artifact_name: opencrabs | |
| asset_suffix: linux-amd64 | |
| - os: ubuntu-24.04-arm | |
| target: aarch64-unknown-linux-gnu | |
| artifact_name: opencrabs | |
| asset_suffix: linux-arm64 | |
| - os: windows-latest | |
| target: x86_64-pc-windows-msvc | |
| artifact_name: opencrabs.exe | |
| asset_suffix: windows-amd64 | |
| - os: macos-latest | |
| target: x86_64-apple-darwin | |
| artifact_name: opencrabs | |
| asset_suffix: macos-amd64 | |
| - os: macos-latest | |
| target: aarch64-apple-darwin | |
| artifact_name: opencrabs | |
| asset_suffix: macos-arm64 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set version | |
| id: version | |
| shell: bash | |
| run: echo "version=${GITHUB_REF#refs/tags/v}" >> "$GITHUB_OUTPUT" | |
| - name: Install Rust | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| targets: ${{ matrix.target }} | |
| - name: Install Linux dependencies | |
| if: contains(matrix.os, 'ubuntu') | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y libasound2-dev | |
| - name: Install CMake (Windows) | |
| if: matrix.os == 'windows-latest' | |
| uses: lukka/get-cmake@latest | |
| - name: Install NASM (Windows) | |
| if: matrix.os == 'windows-latest' | |
| uses: ilammy/setup-nasm@v1 | |
| - name: Build | |
| shell: bash | |
| env: | |
| CFLAGS: ${{ matrix.target == 'aarch64-apple-darwin' && '-march=armv8-a+crypto' || '' }} | |
| CXXFLAGS: ${{ matrix.target == 'aarch64-apple-darwin' && '-march=armv8-a+crypto' || '' }} | |
| AWS_LC_SYS_CMAKE_BUILDER: ${{ matrix.os == 'windows-latest' && '1' || '' }} | |
| run: cargo build --locked --release --target ${{ matrix.target }} --all-features | |
| - name: Download and bundle RTK 0.40.0 | |
| shell: bash | |
| run: | | |
| RTK_VERSION="0.40.0" | |
| RTK_TARGET="${{ matrix.target }}" | |
| # Map Rust targets to RTK release asset names (v0.40.0 actual names) | |
| case "$RTK_TARGET" in | |
| x86_64-unknown-linux-gnu) | |
| RTK_ASSET="rtk-x86_64-unknown-linux-musl.tar.gz" | |
| ;; | |
| aarch64-unknown-linux-gnu) | |
| RTK_ASSET="rtk-aarch64-unknown-linux-gnu.tar.gz" | |
| ;; | |
| x86_64-apple-darwin) | |
| RTK_ASSET="rtk-x86_64-apple-darwin.tar.gz" | |
| ;; | |
| aarch64-apple-darwin) | |
| RTK_ASSET="rtk-aarch64-apple-darwin.tar.gz" | |
| ;; | |
| x86_64-pc-windows-msvc) | |
| RTK_ASSET="rtk-x86_64-pc-windows-msvc.zip" | |
| ;; | |
| *) | |
| echo "Unknown target: $RTK_TARGET" | |
| exit 1 | |
| ;; | |
| esac | |
| RTK_URL="https://github.com/rtk-ai/rtk/releases/download/v${RTK_VERSION}/${RTK_ASSET}" | |
| echo "Downloading RTK from: $RTK_URL" | |
| curl -L -o "/tmp/$RTK_ASSET" "$RTK_URL" | |
| # Extract RTK binary | |
| mkdir -p /tmp/rtk-extract | |
| if [[ "$RTK_ASSET" == *.zip ]]; then | |
| unzip -q "/tmp/$RTK_ASSET" -d /tmp/rtk-extract | |
| else | |
| tar xzf "/tmp/$RTK_ASSET" -C /tmp/rtk-extract | |
| fi | |
| # Find the rtk binary in the extracted archive | |
| RTK_BINARY=$(find /tmp/rtk-extract -name "rtk" -o -name "rtk.exe" | head -1) | |
| if [ -z "$RTK_BINARY" ]; then | |
| echo "RTK binary not found in archive" | |
| ls -laR /tmp/rtk-extract | |
| exit 1 | |
| fi | |
| # Copy to the release directory alongside opencrabs | |
| RELEASE_DIR="target/${{ matrix.target }}/release" | |
| cp "$RTK_BINARY" "$RELEASE_DIR/" | |
| if [[ "${{ matrix.os }}" != "windows-latest" ]]; then | |
| chmod +x "$RELEASE_DIR/rtk" | |
| fi | |
| echo "RTK binary bundled at: $RELEASE_DIR/$(basename $RTK_BINARY)" | |
| ls -lh "$RELEASE_DIR/$(basename $RTK_BINARY)" | |
| - name: Strip binary (Unix) | |
| if: matrix.os != 'windows-latest' | |
| run: strip target/${{ matrix.target }}/release/${{ matrix.artifact_name }} | |
| - name: Create archive | |
| shell: bash | |
| run: | | |
| ASSET_NAME="opencrabs-v${{ steps.version.outputs.version }}-${{ matrix.asset_suffix }}" | |
| cd target/${{ matrix.target }}/release | |
| if [ "${{ matrix.os }}" = "windows-latest" ]; then | |
| 7z a ../../../${ASSET_NAME}.zip ${{ matrix.artifact_name }} rtk.exe | |
| else | |
| tar czf ../../../${ASSET_NAME}.tar.gz ${{ matrix.artifact_name }} rtk | |
| fi | |
| - name: Upload artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: opencrabs-v${{ steps.version.outputs.version }}-${{ matrix.asset_suffix }} | |
| path: | | |
| opencrabs-v${{ steps.version.outputs.version }}-${{ matrix.asset_suffix }}.tar.gz | |
| opencrabs-v${{ steps.version.outputs.version }}-${{ matrix.asset_suffix }}.zip | |
| create-release: | |
| name: Create Release | |
| needs: [publish-crate, build-release] | |
| if: always() && needs.publish-crate.result != 'cancelled' && needs.build-release.result != 'cancelled' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Extract version from tag | |
| id: version | |
| run: echo "version=${GITHUB_REF#refs/tags/v}" >> "$GITHUB_OUTPUT" | |
| - name: Extract changelog for this version | |
| id: changelog | |
| run: | | |
| # Extract the section for this version from CHANGELOG.md | |
| version="${{ steps.version.outputs.version }}" | |
| body=$(awk "/^## \\[${version}\\]/{found=1; next} /^## \\[/{if(found) exit} found{print}" CHANGELOG.md) | |
| # Write to file to preserve newlines | |
| echo "$body" > /tmp/release_notes.md | |
| # Add full changelog link (extract previous version from CHANGELOG.md) | |
| echo "" >> /tmp/release_notes.md | |
| prev_version=$(awk "/^## \\[${version}\\]/{found=1; next} found && /^## \\[/{match(\$0, /\\[([^]]+)\\]/, m); print m[1]; exit}" CHANGELOG.md) | |
| if [ -n "$prev_version" ]; then | |
| echo "**Full Changelog:** https://github.com/${{ github.repository }}/compare/v${prev_version}...v${version}" >> /tmp/release_notes.md | |
| fi | |
| - name: Download all artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| path: artifacts | |
| - name: Collect release assets | |
| run: | | |
| mkdir -p release-assets | |
| find artifacts -type f \( -name '*.tar.gz' -o -name '*.zip' \) -exec cp {} release-assets/ \; | |
| ls -la release-assets/ | |
| - name: Create GitHub Release | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| # Use --clobber so the workflow can attach binaries to a release | |
| # that was already created manually (e.g. via `gh release create`) | |
| if gh release view "v${{ steps.version.outputs.version }}" &>/dev/null; then | |
| # Release exists -- upload assets and ensure it's not a draft | |
| gh release upload "v${{ steps.version.outputs.version }}" \ | |
| release-assets/* --clobber | |
| gh release edit "v${{ steps.version.outputs.version }}" --draft=false | |
| else | |
| gh release create "v${{ steps.version.outputs.version }}" \ | |
| --title "v${{ steps.version.outputs.version }}" \ | |
| --notes-file /tmp/release_notes.md \ | |
| --latest \ | |
| release-assets/* | |
| fi |