Skip to content

Add R2 release publishing for stable downloads#127

Merged
F16shen merged 1 commit into
AI-Shell-Team:mainfrom
F16shen:release/r2-cdn-sync
Apr 22, 2026
Merged

Add R2 release publishing for stable downloads#127
F16shen merged 1 commit into
AI-Shell-Team:mainfrom
F16shen:release/r2-cdn-sync

Conversation

@F16shen
Copy link
Copy Markdown
Collaborator

@F16shen F16shen commented Apr 22, 2026

Summary

This PR keeps GitHub Release assets as part of the release flow while also publishing stable release bundles to the R2-backed download bucket.

It moves stable self-update downloads to versioned release paths, adds a dedicated publish step that refreshes download/latest, and updates public install documentation so stable installs are described in generic product terms while manual bundle downloads point to GitHub Releases.

What Changed

  • Updated .github/workflows/release.yml to:
    • keep uploading built bundles to GitHub Release
    • upload release artifacts for cross-job reuse
    • add a publish-release-bundles job gated by the release environment
    • publish versioned artifacts to the release bucket and refresh download/latest
    • include the bucket publish result in the release summary
  • Added packaging/scripts/publish_release.sh to:
    • discover built release artifacts
    • upload bundles and .sha256 files to download/releases/<version>/
    • write the stable version to download/latest
    • validate the published CDN URLs after upload
  • Updated src/aish/cli/update_manager.py so stable downloads resolve through download/releases/<version>/... instead of the old flat path
  • Updated tests/test_update_manager.py to cover the versioned stable download URLs and the download-base override behavior
  • Updated README*.md and QUICKSTART.md copy in this repo so:
    • stable install text no longer exposes CDN implementation details
    • manual bundle download guidance points readers to GitHub Release assets

Why

The stable install and self-update flows now depend on a download/latest metadata file plus versioned release artifact directories. The release pipeline has to publish those objects automatically, otherwise stable installs and updates would keep depending on the old flat release layout.

Validation

  • /home/lixin/workspace/aishell/aish/.venv/bin/python -m pytest tests/test_update_manager.py -k download_release -q
  • bash -n /home/lixin/workspace/aishell/aish/packaging/scripts/publish_release.sh

Notes

  • GitHub Release assets remain part of the release process; this change adds synchronized bucket publishing rather than replacing Release assets.
  • The PR only contains changes from the aish repository itself.

Summary by CodeRabbit

Release Notes

  • Documentation

    • Updated installation guides across all languages to reflect downloads from GitHub Releases instead of legacy distribution sources.
  • New Features

    • Introduced CDN-based release distribution system for faster and more reliable downloads.
    • Updated version resolution to explicitly target the latest stable release.

Update the release workflow to keep GitHub Release assets while also publishing versioned bundles to the release bucket and refreshing download/latest. Switch stable self-update downloads to versioned release paths, add targeted test coverage for the new URLs, and align public documentation so stable installs are described in generic terms while manual bundle downloads point to GitHub Releases.
@github-actions
Copy link
Copy Markdown
Contributor

Thanks for the pull request. A maintainer will review it when available.

Please keep the PR focused, explain the why in the description, and make sure local checks pass before requesting review.

Contribution guide: https://github.com/AI-Shell-Team/aish/blob/main/CONTRIBUTING.md

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 22, 2026

📝 Walkthrough

Walkthrough

The PR establishes a release distribution system: GitHub Actions workflow now uploads built bundles as per-architecture artifacts and publishes them to an R2/CDN bucket via a new publish_release.sh script. The UpdateManager class is updated to construct CDN URLs using a versioned path structure. Documentation is updated to reflect the new stable version resolution method.

Changes

Cohort / File(s) Summary
CI Release Workflow
.github/workflows/release.yml
Added per-architecture artifact uploads via actions/upload-artifact@v6 with error on missing files. New publish-release-bundles job downloads artifacts and runs publish_release.sh. Updated release-summary job dependencies to include the new publishing step.
Release Publishing Script
packaging/scripts/publish_release.sh
New Bash script that publishes release bundles to R2-compatible storage. Enforces environment variables, discovers tarballs and checksums, uploads with immutable caching, validates via CDN URLs, and reports results to GitHub step summary.
Application Update Logic
src/aish/cli/update_manager.py
Added get_release_download_url() method to construct CDN URLs with versioned path structure (/releases/{version}/). Updated download_release() to use the new method instead of direct URL formatting.
Tests & Documentation
tests/test_update_manager.py, QUICKSTART.md, README.md, README_*.md
Updated download URL assertions to match new CDN path structure (releases/0.3.0/). Updated installation documentation across 8 language variants to reflect resolution of "latest stable version" instead of "latest release directory."

Sequence Diagram(s)

sequenceDiagram
    participant Build as Build System
    participant GHA as GitHub Actions
    participant Artifact as Artifact Storage
    participant R2 as R2/CDN
    participant Client as UpdateManager
    participant CDN as CDN Endpoint

    Build->>GHA: Build release bundles per architecture
    GHA->>Artifact: Upload artifacts (release-bundle-linux-*)
    GHA->>R2: Run publish_release.sh
    
    R2->>R2: Discover tarballs & checksums
    R2->>R2: Upload to bucket with versioning
    R2->>R2: Create 'latest' version pointer
    
    R2->>CDN: HTTP validation checks
    CDN-->>R2: Confirm all URLs accessible
    
    R2->>GHA: Report to step summary
    
    Client->>Client: Call get_release_download_url()
    Client->>CDN: Construct versioned URL<br/>(releases/0.3.0/)
    CDN-->>Client: Serve release bundle
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

size: S, tests, docs, core

Poem

🐰 A bundle takes flight on the CDN wind,
Versioned releases with checksums pinned,
R2 buckets hold treasures so fair,
While UpdateManager fetches from air—
Latest stable, forever in sync! ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding R2 release publishing infrastructure for distributing stable downloads via versioned CDN paths.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown
Contributor

This pull request description looks incomplete. Please update the missing sections below before review.

Missing items:

  • User-visible Changes
  • Compatibility
  • Testing
  • Change Type
  • Scope

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

🧹 Nitpick comments (1)
src/aish/cli/update_manager.py (1)

85-89: Harden tag handling in URL builder with existing normalizer.

Line 87 strips a leading v but doesn’t validate input shape. Reusing normalize_tag() here keeps tag parsing consistent for all callers and avoids malformed release paths.

Suggested patch
 def get_release_download_url(self, tag_name: str, filename: str) -> str:
     """Resolve the CDN URL for a versioned release artifact."""
-    version_str = tag_name.lstrip("v")
+    normalized_tag = self.normalize_tag(tag_name)
+    version_str = normalized_tag.lstrip("v")
     return f"{self.get_download_base_url()}/releases/{version_str}/{filename}"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/aish/cli/update_manager.py` around lines 85 - 89, The URL builder
get_release_download_url currently only strips a leading "v" from tag_name which
can produce inconsistent or malformed paths; update get_release_download_url to
call the existing normalize_tag(tag_name) to obtain a validated, normalized
version string before building the path, then use that normalized value in the
f"{self.get_download_base_url()}/releases/{version}/{filename}" construction;
reference normalize_tag and get_release_download_url so reviewers can find and
verify the fix.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packaging/scripts/publish_release.sh`:
- Around line 69-81: The current validation loop only checks HTTP status; update
the validation to specially verify the "latest" entry in validated_urls returns
the expected VERSION and retry a few times if it doesn't. Modify the logic
around validated_urls/for url in "${validated_urls[@]}" to detect when url ends
with "/latest" (or compare against
"${CDN_BASE_URL%/}/${DOWNLOAD_PREFIX}/latest"), perform a body fetch (curl -fsS
with timeouts) and assert the response contains the ${VERSION} string (with a
small retry loop, e.g., 3 attempts and short sleep between attempts) before
treating it as valid; keep the existing status-only check for artifact release
URLs. Ensure failures still cause a non-zero exit.

In `@README_CN.md`:
- Line 124: The README_CN has inconsistent wording about download source: the
sentence in the "快速开始方式二" section still refers to “官方发布目录” while Line 124
describes parsing the “最新稳定版本” and downloading matching bundle from GitHub
Releases; update the "快速开始方式二" text to match the new approach by replacing
“官方发布目录” (or any equivalent phrasing) with a clear reference to downloading the
matching bundle from the GitHub Releases assets (e.g. “从对应版本的 GitHub Releases
资产下载最新稳定版本的 bundle”), and ensure the brief installer description and the
quick-start step use the same phrasing.

In `@README_DE.md`:
- Line 129: Die Schnellstart-Sektion verwendet noch die Formulierung
"offiziellen Release-Verzeichnis" und muss mit der aktualisierten
Line-129-Formulierung über GitHub-Release-Assets pro Version abgeglichen werden;
ersetze in der Schnellstart-Paragraph (Schnellstart, bisherige Formulierung
"offiziellen Release-Verzeichnis") den Text so dass er dieselbe Aussage wie die
Line-129-Satzstruktur verwendet (z. B. "GitHub‑Release‑Assets pro Version") und
prüfe auf konsistente Begriffe für Installer, Bundle und die Zielpfade
(`/usr/local/bin`, `aish`, `aish-sandbox`, `aish-uninstall`) im gesamten
README_DE.md.

In `@README_ES.md`:
- Line 129: Unificar la redacción sobre la fuente del bundle en README_ES.md:
reemplaza la mención "directorio oficial de releases" en la sección "Inicio
rápido" (encuentra el encabezado Inicio rápido) por "assets de GitHub Releases
por versión" para que coincida con la frase ya actualizada en la línea que
describe el instalador (la oración que dice que el instalador descarga el bundle
correspondiente para tu arquitectura e instala `aish`, `aish-sandbox` y
`aish-uninstall`), asegurándote de usar la misma terminología exacta en ambos
lugares para evitar ambigüedades.

In `@README_FR.md`:
- Line 129: Mettre à jour le texte de l’Option 2 dans README_FR.md (la section
"Option 2" du démarrage rapide) pour remplacer la mention "répertoire officiel
des releases" par une référence cohérente aux assets GitHub Releases par
version, en reprenant la même formulation utilisée à la ligne décrivant
l’installeur (qui mentionne le téléchargement des assets par architecture) afin
d’harmoniser les instructions de téléchargement manuel.

In `@README_JA.md`:
- Line 129: Update the Quick Start Option 2 text in README_JA.md to match the
new manual-install guidance: replace the phrase referencing the “official
release directory” and any instructions that point users to that location with
instructions to download the appropriate bundle from the GitHub Release assets
for the desired version (same approach used in the updated line that references
installing `aish`, `aish-sandbox`, and `aish-uninstall` into `/usr/local/bin`).
Ensure the wording explicitly instructs selecting the correct
architecture-specific asset for the chosen version and mirrors the
language/format used in the already-updated sentence about resolving the latest
stable release and installing the binaries.

In `@README.md`:
- Line 129: Update the README so both the installer description and Quick Start
Option 2 consistently point to GitHub Release assets rather than the “official
release directory”: change the text in the installer sentence that mentions
resolving the latest stable version and the Quick Start Option 2 instructions
that reference the “official release directory” to instead reference downloading
the matching bundle from the GitHub Releases assets (and ensure any curl/wget
examples, download URLs, and wording around “stable-version” reflect the GitHub
Releases approach). Use the exact section header "Quick Start Option 2" and the
installer sentence mentioning `aish`, `aish-sandbox`, and `aish-uninstall` to
locate and update the two places.

In `@tests/test_update_manager.py`:
- Around line 154-157: The test asserts a malformed duplicated
"/releases/releases/" path in stream_url; fix the URL-construction to normalize
AISH_DOWNLOAD_BASE_URL before joining so duplicate "/releases" or trailing
slashes are removed (trim any trailing "/releases" or "/" from the base) in the
function that builds stream_url (e.g., the UpdateManager method that constructs
the download URL or helper that returns stream_url), then update the test
assertion to expect a single "/releases/<version>/..." segment (use the
stream_url variable assertion).

---

Nitpick comments:
In `@src/aish/cli/update_manager.py`:
- Around line 85-89: The URL builder get_release_download_url currently only
strips a leading "v" from tag_name which can produce inconsistent or malformed
paths; update get_release_download_url to call the existing
normalize_tag(tag_name) to obtain a validated, normalized version string before
building the path, then use that normalized value in the
f"{self.get_download_base_url()}/releases/{version}/{filename}" construction;
reference normalize_tag and get_release_download_url so reviewers can find and
verify the fix.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 10f1e5ab-f68d-4b9d-adc9-94712eca7287

📥 Commits

Reviewing files that changed from the base of the PR and between 67be3c2 and 42e97ba.

📒 Files selected for processing (11)
  • .github/workflows/release.yml
  • QUICKSTART.md
  • README.md
  • README_CN.md
  • README_DE.md
  • README_ES.md
  • README_FR.md
  • README_JA.md
  • packaging/scripts/publish_release.sh
  • src/aish/cli/update_manager.py
  • tests/test_update_manager.py

Comment thread packaging/scripts/publish_release.sh
Comment thread README_CN.md
Comment thread README_DE.md
Comment thread README_ES.md
Comment thread README_FR.md
Comment thread README_JA.md
Comment thread README.md
Comment thread tests/test_update_manager.py
@F16shen F16shen merged commit f37dde0 into AI-Shell-Team:main Apr 22, 2026
13 checks passed
@F16shen F16shen deleted the release/r2-cdn-sync branch April 23, 2026 06:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant