From 79147bc594300cd5c9c48b1549ab12ac5b878ce4 Mon Sep 17 00:00:00 2001 From: Aaron Schlesinger <70865+arschles@users.noreply.github.com> Date: Sat, 11 Jul 2026 11:26:47 -0700 Subject: [PATCH] progress --- .github/workflows/cli-release.yml | 92 +++++++++++++++++++++++++ cli/mise.toml | 6 +- cli/scripts/publish-cli-r2.sh | 73 -------------------- cli/scripts/upload-install-script-r2.sh | 0 4 files changed, 95 insertions(+), 76 deletions(-) create mode 100644 .github/workflows/cli-release.yml delete mode 100755 cli/scripts/publish-cli-r2.sh mode change 100755 => 100644 cli/scripts/upload-install-script-r2.sh diff --git a/.github/workflows/cli-release.yml b/.github/workflows/cli-release.yml new file mode 100644 index 0000000..5ee6af7 --- /dev/null +++ b/.github/workflows/cli-release.yml @@ -0,0 +1,92 @@ +name: cli-release + +on: + push: + tags: ["v*"] + workflow_dispatch: + +permissions: + contents: read + +env: + QT_R2_BUCKET: ${{ vars.QT_R2_BUCKET || 'quantiles-cli' }} + +jobs: + build: + name: ${{ matrix.target }} + strategy: + fail-fast: false + matrix: + include: + - runner: macos-13 + target: x86_64-apple-darwin + - runner: macos-14 + target: aarch64-apple-darwin + - runner: ubuntu-24.04 + target: x86_64-unknown-linux-gnu + - runner: ubuntu-24.04-arm + target: aarch64-unknown-linux-gnu + runs-on: ${{ matrix.runner }} + defaults: + run: + working-directory: cli + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + with: + targets: ${{ matrix.target }} + - uses: Swatinem/rust-cache@v2 + with: + workspaces: cli + - name: Build release binary + run: cargo build --locked --release --target ${{ matrix.target }} + - name: Package release artifact + env: + TARGET: ${{ matrix.target }} + run: | + version="$(cargo metadata --locked --no-deps --format-version 1 | jq -r '.packages[0].version')" + archive="qt-${version}-${TARGET}.tar.gz" + mkdir -p dist/package + cp "target/${TARGET}/release/qt" dist/package/qt + COPYFILE_DISABLE=1 tar -czf "dist/${archive}" -C dist/package qt + shasum -a 256 "dist/${archive}" > "dist/${archive}.sha256" + - uses: actions/upload-artifact@v4 + with: + name: cli-${{ matrix.target }} + path: cli/dist/qt-*.tar.gz* + if-no-files-found: error + + publish: + name: publish to R2 + needs: build + runs-on: ubuntu-24.04 + environment: release + env: + CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} + steps: + - uses: actions/checkout@v4 + - uses: actions/download-artifact@v4 + with: + pattern: cli-* + path: dist + merge-multiple: true + - uses: dtolnay/rust-toolchain@stable + - name: Install Wrangler + run: npm install --global wrangler@4 + - name: Publish release artifacts and installer + working-directory: cli + run: | + version="$(cargo metadata --locked --no-deps --format-version 1 | jq -r '.packages[0].version')" + if [[ "$GITHUB_REF_TYPE" == "tag" && "$GITHUB_REF_NAME" != "v${version}" ]]; then + echo "tag $GITHUB_REF_NAME does not match CLI version v${version}" >&2 + exit 1 + fi + object_prefix="releases/v${version}" + + for file in ../dist/qt-*.tar.gz ../dist/qt-*.tar.gz.sha256; do + wrangler r2 object put "${QT_R2_BUCKET}/${object_prefix}/$(basename "$file")" --file "$file" --remote --cache-control "no-store" + done + + wrangler r2 object put "${QT_R2_BUCKET}/install.sh" --file scripts/install.sh --remote --cache-control "no-store" + wrangler r2 object put "${QT_R2_BUCKET}/${object_prefix}/install.sh" --file scripts/install.sh --remote --cache-control "no-store" diff --git a/cli/mise.toml b/cli/mise.toml index 5b9cdca..80a1f28 100644 --- a/cli/mise.toml +++ b/cli/mise.toml @@ -40,10 +40,10 @@ run = [ [tasks.run-http-client-example] run="cargo run --example http_client" -# build the CLI for ARM Mac, package the binaries, and publish the archives, -# checksums, and install script to the quantiles-cli R2 bucket +# dispatch the GitHub Actions release workflow, which builds the CLI for all +# supported macOS and Linux targets and publishes the release artifacts to R2 [tasks.publish-cli-r2] -run="bash scripts/publish-cli-r2.sh" +run="gh workflow run cli-release.yml" # upload only the install script to R2; use this when installer logic changes # but the already-published CLI release artifact does not need to be rebuilt diff --git a/cli/scripts/publish-cli-r2.sh b/cli/scripts/publish-cli-r2.sh deleted file mode 100755 index 72e2c80..0000000 --- a/cli/scripts/publish-cli-r2.sh +++ /dev/null @@ -1,73 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -# macOS defaults to 256 open files, which is too low for linking large Rust binaries. -ulimit -n 65536 2>/dev/null || true - -bucket="${QT_R2_BUCKET:-quantiles-cli}" -dist_dir="${QT_DIST_DIR:-dist}" - -if ! command -v wrangler >/dev/null 2>&1; then - echo "wrangler is required to publish to Cloudflare R2" >&2 - exit 1 -fi - -if ! command -v jq >/dev/null 2>&1; then - echo "jq is required to parse cargo metadata" >&2 - exit 1 -fi - -version="$(cargo metadata --no-deps --format-version 1 | jq -r '.packages[0].version')" - -if [[ -z "$version" || "$version" == "null" ]]; then - echo "failed to read crate version from cargo metadata" >&2 - exit 1 -fi - -mkdir -p "$dist_dir" - -object_prefix="releases/v${version}" - -echo "Building target: aarch64-apple-darwin" - -cargo build --target aarch64-apple-darwin - -mac_binary_path="target/aarch64-apple-darwin/debug/qt" -linux_binary_path="./qt-linux" - -if [[ ! -x "$mac_binary_path" ]]; then - echo "built binary not found at ${mac_binary_path}" >&2 - exit 1 -fi - -if [[ ! -x "$linux_binary_path" ]]; then - echo "linux binary not found at ${linux_binary_path}. please build it and place it there first." >&2 - exit 1 -fi - -for target in "aarch64-apple-darwin" "x86_64-unknown-linux-gnu"; do - if [[ "$target" == "aarch64-apple-darwin" ]]; then - binary_path="$mac_binary_path" - else - binary_path="$linux_binary_path" - fi - - archive="${dist_dir}/qt-${version}-${target}.tar.gz" - checksum="${archive}.sha256" - - tmpdir="$(mktemp -d)" - cp "$binary_path" "$tmpdir/qt" - COPYFILE_DISABLE=1 tar -czf "$archive" -C "$tmpdir" "qt" - rm -rf "$tmpdir" - ( - cd "$dist_dir" - shasum -a 256 "$(basename "$archive")" > "$(basename "$checksum")" - ) - - wrangler r2 object put "${bucket}/${object_prefix}/$(basename "$archive")" --file "$archive" --remote --cache-control "no-store" - wrangler r2 object put "${bucket}/${object_prefix}/$(basename "$checksum")" --file "$checksum" --remote --cache-control "no-store" - - echo "published ${archive} to r2://${bucket}/${object_prefix}/$(basename "$archive")" -done - -echo "All targets published successfully." diff --git a/cli/scripts/upload-install-script-r2.sh b/cli/scripts/upload-install-script-r2.sh old mode 100755 new mode 100644