chore: bump version to 0.3.70 #1272
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: Build and Release | |
| on: | |
| push: | |
| # Branches trigger builds only (no release) | |
| # - main: production builds | |
| # - beta: beta channel builds | |
| branches: [main, beta] | |
| # Tags trigger full release workflow | |
| # - v1.2.3: stable release | |
| # - v1.2.3-beta.1: beta/prerelease | |
| tags: ["v*"] | |
| # pull_request: | |
| # branches: [main, beta] | |
| permissions: | |
| contents: write | |
| discussions: write | |
| pull-requests: read | |
| packages: write | |
| env: | |
| CARGO_TERM_COLOR: always | |
| BINARY_NAME: stakpak | |
| jobs: | |
| # Determine release type once, other jobs reference this | |
| setup: | |
| runs-on: ubuntu-22.04 | |
| outputs: | |
| is_beta: ${{ steps.check.outputs.is_beta }} | |
| version: ${{ steps.check.outputs.version }} | |
| steps: | |
| - name: Check release type | |
| id: check | |
| run: | | |
| TAG=${GITHUB_REF#refs/tags/} | |
| # Remove 'v' prefix if present | |
| VERSION=${TAG#v} | |
| echo "version=$VERSION" >> $GITHUB_OUTPUT | |
| if [[ "$TAG" == *"-beta"* ]]; then | |
| echo "is_beta=true" >> $GITHUB_OUTPUT | |
| else | |
| echo "is_beta=false" >> $GITHUB_OUTPUT | |
| fi | |
| build: | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - os: ubuntu-22.04 | |
| target: x86_64-unknown-linux-musl | |
| artifact_name: stakpak-linux-x86_64 | |
| features: --features jemalloc | |
| - os: ubuntu-22.04-arm | |
| target: aarch64-unknown-linux-musl | |
| artifact_name: stakpak-linux-aarch64 | |
| features: --features jemalloc | |
| docker: rust:1.91-alpine3.21 | |
| - os: macos-15 | |
| target: x86_64-apple-darwin | |
| artifact_name: stakpak-darwin-x86_64 | |
| - os: macos-15 | |
| target: aarch64-apple-darwin | |
| artifact_name: stakpak-darwin-aarch64 | |
| - os: windows-2022 | |
| target: x86_64-pc-windows-msvc | |
| artifact_name: stakpak-windows-x86_64 | |
| runs-on: ${{ matrix.os }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install Rust | |
| if: ${{ !matrix.docker }} | |
| uses: dtolnay/rust-toolchain@1.91.0 | |
| with: | |
| targets: ${{ matrix.target }} | |
| - name: Rust Cache | |
| if: ${{ !matrix.docker }} | |
| uses: Swatinem/rust-cache@v2 | |
| with: | |
| shared-key: ${{ matrix.target }} | |
| - name: Install MUSL tools | |
| if: endsWith(matrix.target, 'linux-musl') && !matrix.docker | |
| run: sudo apt-get update && sudo apt-get install -y musl-tools | |
| - name: Docker cargo cache | |
| if: matrix.docker | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cargo-docker/registry | |
| ~/.cargo-docker/git | |
| key: docker-cargo-${{ matrix.target }}-${{ hashFiles('**/Cargo.lock') }} | |
| restore-keys: docker-cargo-${{ matrix.target }}- | |
| - name: Docker build cache (target dir) | |
| if: matrix.docker | |
| uses: actions/cache@v4 | |
| with: | |
| path: target/ | |
| key: docker-target-${{ matrix.target }}-${{ hashFiles('**/Cargo.lock') }} | |
| restore-keys: docker-target-${{ matrix.target }}- | |
| # Alpine is required for aarch64-musl: Ubuntu's musl-gcc wrapper lacks | |
| # C11 atomics support needed by jemalloc and libsql-ffi on ARM. | |
| - name: Build and test in Alpine container | |
| if: matrix.docker | |
| run: | | |
| mkdir -p ~/.cargo-docker/registry ~/.cargo-docker/git | |
| docker run --rm \ | |
| --user 0:0 \ | |
| -v "${{ github.workspace }}:/build" \ | |
| -w /build \ | |
| -v "$HOME/.cargo-docker/registry:/usr/local/cargo/registry" \ | |
| -v "$HOME/.cargo-docker/git:/usr/local/cargo/git" \ | |
| -e SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt \ | |
| ${{ matrix.docker }} sh -c ' | |
| set -euo pipefail | |
| apk add --no-cache gcc musl-dev make binutils pkgconfig openssl-dev openssl-libs-static ca-certificates vim | |
| cargo build --release --target ${{ matrix.target }} ${{ matrix.features }} | |
| cargo test --target ${{ matrix.target }} ${{ matrix.features }} | |
| # Verify jemalloc overrides musl malloc | |
| BINARY="target/${{ matrix.target }}/release/stakpak" | |
| if nm "$BINARY" 2>/dev/null | grep -q " W malloc$"; then | |
| echo "FAIL: jemalloc not overriding musl malloc — SQLite will SIGSEGV" | |
| exit 1 | |
| fi | |
| echo "OK: jemalloc override verified" | |
| ' | |
| - name: Fix Docker cache permissions | |
| if: matrix.docker | |
| run: sudo chown -R $(id -u):$(id -g) ~/.cargo-docker | |
| - name: Build | |
| if: ${{ !matrix.docker }} | |
| run: cargo build --release --target ${{ matrix.target }} ${{ matrix.features }} | |
| - name: Run tests | |
| if: ${{ !matrix.docker }} | |
| run: cargo test --target ${{ matrix.target }} ${{ matrix.features }} | |
| - name: Verify jemalloc overrides musl malloc | |
| if: endsWith(matrix.target, 'linux-musl') && !matrix.docker | |
| run: | | |
| BINARY="target/${{ matrix.target }}/release/stakpak" | |
| if nm "$BINARY" 2>/dev/null | grep -q " W malloc$"; then | |
| echo "FAIL: jemalloc not overriding musl malloc — SQLite will SIGSEGV" | |
| exit 1 | |
| fi | |
| echo "OK: jemalloc override verified" | |
| - name: Prepare binary | |
| if: startsWith(github.ref, 'refs/tags/') | |
| shell: bash | |
| run: | | |
| cd target/${{ matrix.target }}/release | |
| if [ "$RUNNER_OS" == "Windows" ]; then | |
| 7z a ../../../${{ matrix.artifact_name }}.zip ${{ env.BINARY_NAME }}.exe | |
| else | |
| tar czf ../../../${{ matrix.artifact_name }}.tar.gz ${{ env.BINARY_NAME }} | |
| fi | |
| - name: Upload artifact | |
| if: startsWith(github.ref, 'refs/tags/') | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ${{ matrix.artifact_name }} | |
| path: ${{ matrix.artifact_name }}.* | |
| retention-days: 1 | |
| release: | |
| needs: [setup, build] | |
| if: startsWith(github.ref, 'refs/tags/') | |
| runs-on: ubuntu-22.04 | |
| steps: | |
| - name: Download artifacts | |
| uses: actions/download-artifact@v4 | |
| - name: Create Release | |
| uses: softprops/action-gh-release@v1 | |
| with: | |
| files: | | |
| stakpak-linux-x86_64/stakpak-linux-x86_64.tar.gz | |
| stakpak-linux-aarch64/stakpak-linux-aarch64.tar.gz | |
| stakpak-darwin-x86_64/stakpak-darwin-x86_64.tar.gz | |
| stakpak-darwin-aarch64/stakpak-darwin-aarch64.tar.gz | |
| stakpak-windows-x86_64/stakpak-windows-x86_64.zip | |
| draft: false | |
| prerelease: ${{ needs.setup.outputs.is_beta == 'true' }} | |
| generate_release_notes: true | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| publish_crates_io: | |
| needs: build | |
| if: startsWith(github.ref, 'refs/tags/') | |
| runs-on: ubuntu-22.04 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install Rust | |
| uses: dtolnay/rust-toolchain@1.91.0 | |
| - name: Extract version from tag | |
| id: get_version | |
| run: | | |
| VERSION=${GITHUB_REF#refs/tags/} | |
| # Remove 'v' prefix if present | |
| VERSION=${VERSION#v} | |
| echo "VERSION=$VERSION" >> $GITHUB_OUTPUT | |
| echo "Tag version: $VERSION" | |
| # Verify version matches Cargo.toml | |
| CARGO_VERSION=$(grep -m1 '^version = ' Cargo.toml | sed 's/version = "\(.*\)"/\1/') | |
| echo "Cargo.toml version: $CARGO_VERSION" | |
| if [ "$VERSION" != "$CARGO_VERSION" ]; then | |
| echo "Warning: Tag version ($VERSION) does not match Cargo.toml version ($CARGO_VERSION)" | |
| echo "Updating Cargo.toml to match tag version" | |
| sed -i "s/^version = \".*\"/version = \"$VERSION\"/" Cargo.toml | |
| fi | |
| - name: Login to crates.io | |
| run: echo "$CRATES_IO_TOKEN" | cargo login | |
| env: | |
| CRATES_IO_TOKEN: ${{ secrets.CRATES_IO_TOKEN }} | |
| - name: Publish workspace members to crates.io | |
| run: | | |
| set -e | |
| VERSION=${{ steps.get_version.outputs.VERSION }} | |
| echo "Publishing workspace members to crates.io version $VERSION" | |
| # Function to publish a package, skip if already published | |
| publish_package() { | |
| local pkg=$1 | |
| echo "Publishing $pkg..." | |
| # Capture output and exit code | |
| set +e | |
| OUTPUT=$(cargo publish -p "$pkg" --no-verify 2>&1) | |
| EXIT_CODE=$? | |
| set -e | |
| if [ $EXIT_CODE -eq 0 ]; then | |
| echo "$pkg published successfully" | |
| echo "Waiting 15s for index propagation..." | |
| sleep 15 | |
| elif echo "$OUTPUT" | grep -q "already uploaded"; then | |
| echo "$pkg version $VERSION already published, skipping" | |
| else | |
| echo "Error publishing $pkg:" | |
| echo "$OUTPUT" | |
| exit 1 | |
| fi | |
| } | |
| # Publish dependencies first, then the main crate | |
| # Order matters: publish dependencies before dependents | |
| publish_package stakai | |
| publish_package stakpak-shared | |
| publish_package stakpak-api | |
| publish_package stakpak-mcp-client | |
| publish_package stakpak-mcp-server | |
| publish_package stakpak-mcp-proxy | |
| publish_package stakpak-agent-core | |
| publish_package stakpak-gateway | |
| publish_package stakpak-server | |
| publish_package stakpak-tui | |
| # Finally publish the main CLI crate | |
| publish_package stakpak | |
| echo "All packages published successfully!" | |
| env: | |
| CARGO_REGISTRY_TOKEN: ${{ secrets.CRATES_IO_TOKEN }} | |
| docker: | |
| needs: [setup, build] | |
| if: startsWith(github.ref, 'refs/tags/') | |
| runs-on: ubuntu-22.04 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Login to GitHub Container Registry | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Build and push Docker image | |
| uses: docker/build-push-action@v5 | |
| with: | |
| context: . | |
| platforms: linux/amd64 | |
| push: true | |
| tags: | | |
| ghcr.io/${{ github.repository }}:v${{ needs.setup.outputs.version }} | |
| ${{ needs.setup.outputs.is_beta != 'true' && format('ghcr.io/{0}:latest', github.repository) || '' }} | |
| update-release-notes: | |
| needs: release | |
| if: startsWith(github.ref, 'refs/tags/') | |
| runs-on: ubuntu-22.04 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 # Need full history for git-cliff | |
| - name: Install git-cliff | |
| run: cargo install git-cliff | |
| - name: Generate release notes with git-cliff | |
| run: | | |
| VERSION=${GITHUB_REF#refs/tags/} | |
| # Get the previous tag to generate notes between tags | |
| PREV_TAG=$(git describe --tags --abbrev=0 "$VERSION^" 2>/dev/null || echo "") | |
| if [ -z "$PREV_TAG" ]; then | |
| echo "No previous tag found, skipping release notes generation" | |
| exit 0 | |
| fi | |
| # Generate notes between previous and current tag | |
| git-cliff "$PREV_TAG..$VERSION" --strip all > release_notes.md | |
| # Check if release notes are empty | |
| if [ ! -s release_notes.md ]; then | |
| echo "No commits found between $PREV_TAG and $VERSION" | |
| exit 0 | |
| fi | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Update GitHub Release | |
| run: | | |
| VERSION=${GITHUB_REF#refs/tags/} | |
| # Check if release notes file exists and has content | |
| if [ ! -f release_notes.md ]; then | |
| echo "Release notes file not found, skipping update" | |
| exit 0 | |
| fi | |
| # Check if file is empty or only contains whitespace | |
| if [ ! -s release_notes.md ] || ! grep -q '[^[:space:]]' release_notes.md; then | |
| echo "Release notes file is empty, skipping update" | |
| exit 0 | |
| fi | |
| echo "Updating release notes for $VERSION" | |
| gh release edit "$VERSION" --notes-file release_notes.md || echo "Failed to update release notes, continuing anyway" | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| homebrew: | |
| needs: [setup, release] | |
| # Only update homebrew for stable releases (not beta) | |
| if: startsWith(github.ref, 'refs/tags/') && needs.setup.outputs.is_beta == 'false' | |
| runs-on: ubuntu-22.04 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| repository: stakpak/homebrew-stakpak | |
| token: ${{ secrets.HOMEBREW_TAP_GITHUB_TOKEN }} | |
| - name: Update Homebrew formula | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.HOMEBREW_TAP_GITHUB_TOKEN }} | |
| VERSION: ${{ needs.setup.outputs.version }} | |
| run: | | |
| curl -L "https://github.com/${{ github.repository }}/releases/download/v${VERSION}/stakpak-darwin-x86_64.tar.gz" -o stakpak-darwin-x86_64.tar.gz | |
| curl -L "https://github.com/${{ github.repository }}/releases/download/v${VERSION}/stakpak-darwin-aarch64.tar.gz" -o stakpak-darwin-aarch64.tar.gz | |
| curl -L "https://github.com/${{ github.repository }}/releases/download/v${VERSION}/stakpak-linux-x86_64.tar.gz" -o stakpak-linux-x86_64.tar.gz | |
| curl -L "https://github.com/${{ github.repository }}/releases/download/v${VERSION}/stakpak-linux-aarch64.tar.gz" -o stakpak-linux-aarch64.tar.gz | |
| SHA256_DARWIN_X64=$(sha256sum stakpak-darwin-x86_64.tar.gz | cut -d ' ' -f 1) | |
| SHA256_DARWIN_ARM=$(sha256sum stakpak-darwin-aarch64.tar.gz | cut -d ' ' -f 1) | |
| SHA256_LINUX_X64=$(sha256sum stakpak-linux-x86_64.tar.gz | cut -d ' ' -f 1) | |
| SHA256_LINUX_ARM=$(sha256sum stakpak-linux-aarch64.tar.gz | cut -d ' ' -f 1) | |
| cat > stakpak.rb << EOF | |
| class Stakpak < Formula | |
| desc "Stakpak CLI tool" | |
| homepage "https://github.com/stakpak/stakpak" | |
| version "${VERSION}" | |
| on_macos do | |
| if Hardware::CPU.arm? | |
| url "https://github.com/${{ github.repository }}/releases/download/v${VERSION}/stakpak-darwin-aarch64.tar.gz" | |
| sha256 "${SHA256_DARWIN_ARM}" | |
| else | |
| url "https://github.com/${{ github.repository }}/releases/download/v${VERSION}/stakpak-darwin-x86_64.tar.gz" | |
| sha256 "${SHA256_DARWIN_X64}" | |
| end | |
| end | |
| on_linux do | |
| if Hardware::CPU.arm? | |
| url "https://github.com/${{ github.repository }}/releases/download/v${VERSION}/stakpak-linux-aarch64.tar.gz" | |
| sha256 "${SHA256_LINUX_ARM}" | |
| else | |
| url "https://github.com/${{ github.repository }}/releases/download/v${VERSION}/stakpak-linux-x86_64.tar.gz" | |
| sha256 "${SHA256_LINUX_X64}" | |
| end | |
| end | |
| def install | |
| bin.install "stakpak" | |
| end | |
| end | |
| EOF | |
| git config user.name "GitHub Actions" | |
| git config user.email "actions@github.com" | |
| git add stakpak.rb | |
| git commit -m "Update stakpak to v${VERSION}" | |
| git push |