Skip to content

Auto-publish CLI builds to Cloudflare R2 - #5

Open
echobt wants to merge 1 commit into
mainfrom
cursor/auto-publish-cli-r2-3be4
Open

Auto-publish CLI builds to Cloudflare R2#5
echobt wants to merge 1 commit into
mainfrom
cursor/auto-publish-cli-r2-3be4

Conversation

@echobt

@echobt echobt commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Summary

After a successful GitHub Release, Cortex CLI binaries are automatically published to software.cortex.foundation (Cloudflare R2 bucket cortex-software). cortex upgrade and the documented curl | sh / irm | iex installers consume that same layout and verify SHA-256.

This is not an AWS/OIDC path. No github-production-deploy role, no AWS keys, no new GitHub Actions variables.

Rebased onto current main (includes #4 mascot / welcome card and docs/media/intro.gif). Install notes live in docs/guides/getting-started.md — the old docs/user-guide.md was already removed on main.

What fires on tag

  1. Merge to main.github/workflows/version-bump.yml patch-bumps and pushes vX.Y.Z.
  2. Tag v* / cli-v* (or workflow_dispatch on Release) → .github/workflows/release.yml builds platform archives and creates a GitHub Release.
  3. The new publish job always workflow_calls .github/workflows/publish-r2.yml after release succeeds. Artifacts are pulled from the caller run via release_run_id.
  4. Prerelease versions (semver containing -) go to the beta channel; otherwise stable.

Manual republish: workflow_dispatch on publish-r2.yml with version + the release workflow’s release_run_id.

Secrets to set (no vars)

On CortexLM/cli (see docs/CI_SECRETS.md):

Secret Used for
R2_ACCESS_KEY_ID R2 access key for bucket cortex-software
R2_SECRET_ACCESS_KEY R2 secret
CLOUDFLARE_ACCOUNT_ID Endpoint https://$CLOUDFLARE_ACCOUNT_ID.r2.cloudflarestorage.com

Do not add AWS keys, PRODUCTION_DEPLOY_ENABLED, or PRODUCTION_SOFTWARE_BUCKET. If these R2 secrets are missing, the GitHub Release still exists and the publish job fails with a clear error.

URL map

Bucket root = host root.

Object Public URL
Unix installer https://software.cortex.foundation/install.sh
Windows installer https://software.cortex.foundation/install.ps1
Channel manifest https://software.cortex.foundation/releases/manifest.json
Per-version JSON https://software.cortex.foundation/releases/<version>.json
Linux/macOS archive https://software.cortex.foundation/v1/assets/<platform>/<version>/cortex.tar.gz
Windows archive https://software.cortex.foundation/v1/assets/windows-x86_64/<version>/cortex.zip
Checksums same asset path + .sha256

Aliases for cortex upgrade: /v1/releases/manifest.json, /v1/releases/<version>.json, /v1/releases/latest.json.

Platform keys: linux-x86_64, linux-aarch64, darwin-x86_64, darwin-aarch64, windows-x86_64.

Installers detect arch, download the matching asset, require SHA-256 verification, and install to ~/.local/bin or %LOCALAPPDATA%\Cortex\bin. cortex upgrade uses the same ReleaseInfo JSON (fixture-tested against a sample manifest.json).

Test plan

  • cargo fmt --all -- --check
  • ./scripts/clippy.sh (workspace clippy completed with -D warnings)
  • cargo test -p cortex-update (includes fixture manifest + wiremock fallback)
  • cargo test -p cortex-engine --lib github::workflow
  • cargo test -p cortex-cli --lib upgrade_cmd
  • cargo test --workspace (full suite; CI on this PR)
  • TUI / snapshot tests — no TUI surfaces changed in this PR; mascot/welcome card from Put the TUI mascot back on the welcome card and in the docs GIF. #4 kept from main
  • cargo audit (CI)

Attestation (required)

I attest that:

  • Security reviewed — R2 tokens stay in GitHub secrets (never in git). Installers and cortex upgrade refuse to install without a SHA-256 match. HTTPS required except localhost. No AWS keys. rclone config is written from secrets at job runtime.
  • Product-facing errors — update/install failures talk about the update server / software.cortex.foundation, not providers or SDKs.
  • TUI verified — no TUI surface was changed in this PR. The mascot welcome card and docs GIF from Put the TUI mascot back on the welcome card and in the docs GIF. #4 remain.
  • Tests addedReleaseManifest fixture parse, wiremock get_latest fallback to /v1/releases/manifest.json, get_release version JSON, find_binary for Cortex, install-script checksum assertion. No mock-success.
  • No secrets — no API keys, WorkOS secrets, R2/AWS credentials, or .env files are included.

Risk

Release pipeline: a missing R2 secret fails the publish job (GitHub Release already created). JSON layout matches existing cortex-update types; aliases keep /v1/releases/... working on static object storage. First production publish needs DNS for software.cortex.foundation pointed at the R2 bucket (out of this PR).

Open in Web Open in Cursor 

@echobt
echobt marked this pull request as ready for review August 30, 2026 09:32
Wire release.yml to call publish-r2.yml after a successful tag or
dispatch release. Upload archives, checksums, release JSON, and
checksum-verifying installers to software.cortex.foundation. Teach
cortex upgrade to parse the static R2 manifest layout.

Co-authored-by: Mathis <echobt@users.noreply.github.com>
@cursor
cursor Bot force-pushed the cursor/auto-publish-cli-r2-3be4 branch from 31d4c02 to af91a15 Compare August 30, 2026 09:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants