Skip to content

fix(plugins): publish plugin bundles to R2 by default#74

Merged
yacosta738 merged 3 commits into
mainfrom
fix/plugins-r2-publish-default
Feb 24, 2026
Merged

fix(plugins): publish plugin bundles to R2 by default#74
yacosta738 merged 3 commits into
mainfrom
fix/plugins-r2-publish-default

Conversation

@yacosta738
Copy link
Copy Markdown
Contributor

@yacosta738 yacosta738 commented Feb 24, 2026

This pull request updates the plugin publishing workflow to prioritize Cloudflare R2 for artifact and metadata storage, adds integrity verification steps, and makes Cloudflare Pages deployment optional and clearly separated as a legacy feature. Documentation in both English and Spanish is revised to reflect these changes and new required variables.

Workflow and deployment changes:

  • The workflow now uploads immutable artifacts and mutable metadata to Cloudflare R2 in atomic order, verifies catalog integrity, and checks public Worker endpoints. Legacy Cloudflare Pages deployment is now optional and controlled via a flag. [1] [2] [3] [4] [5] [6]
  • New required input and repository variable for the Cloudflare R2 bucket (cloudflare_r2_bucket_name/CLOUDFLARE_R2_BUCKET_NAME) are introduced, and the Pages project variable is now optional. [1] [2] [3]

Documentation updates:

  • English and Spanish docs are updated to describe the new R2-first publishing flow, integrity checks, and clarify the optional legacy Pages deployment. [1] [2] [3] [4]
  • .github/workflows/README.md is revised to explain the new order of operations, required secrets/vars, and the distinction between R2 publishing and optional Pages deployment.

Summary by CodeRabbit

  • New Features

    • Plugin artifacts and metadata now publish primarily to Cloudflare R2 with atomic uploads, integrity verification, and optional legacy Cloudflare Pages deployment.
    • Added smoke-checks for public Worker endpoints and stricter deployment validation (R2 bucket required).
  • Documentation

    • Updated publishing guides: new R2 configuration variable, optional Pages path, and revised onboarding/plugin placement guidance.

@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented Feb 24, 2026

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
corvus-plugins-edge 4d4a314 Feb 24 2026, 11:55 AM

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Feb 24, 2026

Warning

Rate limit exceeded

@yacosta738 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 4 minutes and 36 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 67cd454 and 4d4a314.

📒 Files selected for processing (1)
  • .github/workflows/publish-plugins.yml
📝 Walkthrough

Walkthrough

The pull request changes the plugin publishing workflow to upload immutable artifacts and mutable metadata to Cloudflare R2 (primary path), adds catalog integrity verification and public Worker smoke-checks, and makes the legacy Cloudflare Pages catalog UI deployment optional; docs and workflow inputs/validation were updated accordingly.

Changes

Cohort / File(s) Summary
GitHub Actions workflow & docs
.github/workflows/README.md, .github/workflows/publish-plugins.yml
Added Cloudflare R2 bucket input/validation and environment wiring; introduced Wrangler installation and R2 upload steps for artifacts, signatures, certificates, manifest, catalog.json/revocations.json; added verification step to validate catalog entries in R2 and smoke-check public Worker endpoints; made Pages deployment conditional and default false; added error handling for missing R2/API credentials.
Documentation (EN/ES guides)
clients/web/apps/docs/src/content/docs/en/guides/plugins.md, clients/web/apps/docs/src/content/docs/es/guides/plugins.md
Rewrote publish workflow documentation to describe the R2-first publishing flow, introduced CLOUDFLARE_R2_BUCKET_NAME as primary configuration, repositioned CLOUDFLARE_PAGES_PROJECT_NAME as an optional legacy setting, and updated onboarding guidance for plugin layout and metadata.

Sequence Diagram(s)

sequenceDiagram
    actor GH as GitHub Actions
    participant R2 as Cloudflare R2
    participant Verify as Verification Job
    participant Worker as Public Worker
    participant Pages as Cloudflare Pages

    GH->>R2: Upload artifact, signature, certificate, manifest
    GH->>R2: Upload catalog.json & revocations.json (atomic)
    GH->>Verify: Request catalog integrity check
    Verify->>R2: Fetch catalog.json & revocations.json
    R2-->>Verify: Return assets
    Verify-->>GH: Validation result
    GH->>Worker: Smoke-check public Worker endpoints (R2-backed URLs)
    Worker-->>GH: Accessibility result
    alt deploy_cloudflare_pages == true
        GH->>Pages: Build & deploy legacy UI
        Pages-->>GH: Deployment result
    end
    GH->>GH: Upload build artifacts for traceability
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: shifting plugin bundle publishing to R2 as the default approach, which aligns with the substantial workflow refactoring across multiple files.
Description check ✅ Passed The description comprehensively covers the key changes: R2 publishing with integrity checks, optional Cloudflare Pages deployment, new required variables, and documentation updates in both languages. It includes references to specific changes and follows the template structure with Summary and related context.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/plugins-r2-publish-default

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Feb 24, 2026

✅ Contributor Report

User: @yacosta738
Status: Passed (12/13 metrics passed)

Metric Description Value Threshold Status
PR Merge Rate PRs merged vs closed 88% >= 30%
Repo Quality Repos with ≥100 stars 0 >= 0
Positive Reactions Positive reactions received 9 >= 1
Negative Reactions Negative reactions received 0 <= 5
Account Age GitHub account age 3041 days >= 30 days
Activity Consistency Regular activity over time 108% >= 0%
Issue Engagement Issues with community engagement 0 >= 0
Code Reviews Code reviews given to others 366 >= 0
Merger Diversity Unique maintainers who merged PRs 3 >= 0
Repo History Merge Rate Merge rate in this repo 89% >= 0%
Repo History Min PRs Previous PRs in this repo 54 >= 0
Profile Completeness Profile richness (bio, followers) 90 >= 0
Suspicious Patterns Spam-like activity detection 1 N/A

Contributor Report evaluates based on public GitHub activity. Analysis period: 2025-02-24 to 2026-02-24

Copy link
Copy Markdown
Contributor

@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: 3

🧹 Nitpick comments (2)
.github/workflows/publish-plugins.yml (2)

368-385: Catalog assembled from local git checkout, not from R2 — sequential plugin publishes can lose entries

The bundle step reads clients/web/apps/plugins/public/catalog.json from the checked-out repo. With R2 now the source of truth, any plugin published after the last repo-side commit will not be included in this base, and its entry will be silently dropped when the next plugin is published.

concurrency: cancel-in-progress: true prevents overlapping runs but not back-to-back runs from different commits (or the same commit for multiple plugin tags).

The fix is to download the current catalog/catalog.json from R2 as the base before merging in the new entry. Pnpm/Node isn't available yet at this step, but the Cloudflare REST API can be hit directly with curl to read the object, or pnpm/Node setup could be moved earlier in the job.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/publish-plugins.yml around lines 368 - 385, The current
logic uses the repo's clients/web/apps/plugins/public/catalog.json
(source_catalog) as the base which can miss entries already published to R2;
change the base-loading code to first attempt fetching the canonical catalog
from R2 (e.g., curl the Cloudflare R2 REST URL for catalog/catalog.json) and
parse that JSON into catalog_payload; if the R2 fetch fails or returns non-JSON
fall back to reading source_catalog or to {"plugins": []}; then continue using
existing_plugins, filtered, and catalog_out as before to merge the new
plugin_entry and write dist_dir / "catalog.json". Ensure the R2 fetch is done
before building filtered so sequential publishes use R2 as the source of truth.

554-572: Install wrangler once instead of spawning it 6 times in the upload step

The wrangler_put() function is called 6 times (lines 565–572), and with 2 more r2 object get calls in the verify step plus 1 pages deploy call, that's 9 pnpm dlx invocations. Each one bootstraps a new Node.js process and re-validates the package cache. Installing wrangler once and reusing the binary is significantly faster.

♻️ Suggested approach

Add a dedicated install step right after the Node.js setup step, then replace all pnpm dlx wrangler@4.44.0 calls with just wrangler:

+     - name: 📦 Install wrangler
+       run: pnpm add -g wrangler@4.44.0

Then in the upload step's wrangler_put helper:

-           pnpm dlx wrangler@4.44.0 r2 object put "${CLOUDFLARE_R2_BUCKET}/${key}" \
+           wrangler r2 object put "${CLOUDFLARE_R2_BUCKET}/${key}" \
              --file "$file" \
              --content-type "$content_type"

Apply the same substitution to the r2 object get calls in the verify step and the pages deploy call in the Pages deployment step.

Additionally, wrangler@4.44.0 is pinned but the current latest release is 4.65.0. The intervening releases (4.45.0, 4.56.0, 4.57.0) include R2 binding provisioning features and snapshot-expiration API improvements. Upgrading would bring incremental improvements, though the core r2 object put/get commands remain compatible.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/publish-plugins.yml around lines 554 - 572, Replace
repeated 'pnpm dlx wrangler@4.44.0' invocations by installing wrangler once and
reusing the binary: add an install step after Node setup that runs 'pnpm dlx -y
wrangler@4.65.0 --no-install' or the equivalent to place a persistent 'wrangler'
binary on PATH, then update the wrangler_put() helper and all other call sites
(the 'wrangler_put' function body, all calls to wrangler_put, the 'r2 object
get' verify calls, and the 'pages deploy' call) to invoke 'wrangler' directly
instead of 'pnpm dlx wrangler@4.44.0'; also bump the pinned version to 4.65.0 to
pick up recent R2 improvements.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/publish-plugins.yml:
- Around line 592-637: The inline Python verification reads TMP_CATALOG_PATH and
validates catalog.json but never validates the downloaded revocations.json;
extend the same Python block to load and parse the revocations file
(tmp_dir/revocations.json or a new env var like TMP_REVOCATIONS_PATH), ensure it
is valid JSON and has the expected top-level structure (e.g., a "revocations"
key that is a list or the schema your pipeline expects), and call SystemExit
with a descriptive error if the file is malformed or missing required fields;
update the inline script variables and validation logic near the existing
catalog checks (look for the python block and uses of TMP_CATALOG_PATH, tmp_dir,
and "revocations.json").

In `@clients/web/apps/docs/src/content/docs/es/guides/plugins.md`:
- Around line 159-161: Fix inconsistent spacing around the label/code span in
the repository variable bullet list by ensuring each item uses the same pattern
"Label: `CODE`" with a single space after the colon; update the items that
mention CLOUDFLARE_R2_BUCKET_NAME and CLOUDFLARE_PAGES_PROJECT_NAME so both have
exactly one space after the colon before the backtick-wrapped variable name to
match the other list entries.
- Around line 130-134: Fix the minor Markdown formatting: remove the extra
leading whitespace before the parenthetical continuation in the "8. Sube
artefactos..." list item so the continuation aligns with the item text, ensure
there is a blank line (or proper newline) separating "9. Verifica integridad del
catálogo..." and "10. Opcionalmente..." so the numbered items render separately,
and delete the stray space immediately before the backtick in the "(
`deploy_cloudflare_pages=true` )" phrase so the code span is contiguous.

---

Nitpick comments:
In @.github/workflows/publish-plugins.yml:
- Around line 368-385: The current logic uses the repo's
clients/web/apps/plugins/public/catalog.json (source_catalog) as the base which
can miss entries already published to R2; change the base-loading code to first
attempt fetching the canonical catalog from R2 (e.g., curl the Cloudflare R2
REST URL for catalog/catalog.json) and parse that JSON into catalog_payload; if
the R2 fetch fails or returns non-JSON fall back to reading source_catalog or to
{"plugins": []}; then continue using existing_plugins, filtered, and catalog_out
as before to merge the new plugin_entry and write dist_dir / "catalog.json".
Ensure the R2 fetch is done before building filtered so sequential publishes use
R2 as the source of truth.
- Around line 554-572: Replace repeated 'pnpm dlx wrangler@4.44.0' invocations
by installing wrangler once and reusing the binary: add an install step after
Node setup that runs 'pnpm dlx -y wrangler@4.65.0 --no-install' or the
equivalent to place a persistent 'wrangler' binary on PATH, then update the
wrangler_put() helper and all other call sites (the 'wrangler_put' function
body, all calls to wrangler_put, the 'r2 object get' verify calls, and the
'pages deploy' call) to invoke 'wrangler' directly instead of 'pnpm dlx
wrangler@4.44.0'; also bump the pinned version to 4.65.0 to pick up recent R2
improvements.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between f94d21e and 476b78f.

📒 Files selected for processing (4)
  • .github/workflows/README.md
  • .github/workflows/publish-plugins.yml
  • clients/web/apps/docs/src/content/docs/en/guides/plugins.md
  • clients/web/apps/docs/src/content/docs/es/guides/plugins.md

Comment thread .github/workflows/publish-plugins.yml Outdated
Comment thread clients/web/apps/docs/src/content/docs/es/guides/plugins.md Outdated
Comment thread clients/web/apps/docs/src/content/docs/es/guides/plugins.md Outdated
@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented Feb 24, 2026

Deploying corvus-plugins with  Cloudflare Pages  Cloudflare Pages

Latest commit: 4d4a314
Status: ✅  Deploy successful!
Preview URL: https://f7988219.corvus-plugins.pages.dev
Branch Preview URL: https://fix-plugins-r2-publish-defau.corvus-plugins.pages.dev

View logs

@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented Feb 24, 2026

Deploying corvus with  Cloudflare Pages  Cloudflare Pages

Latest commit: 4d4a314
Status: ✅  Deploy successful!
Preview URL: https://10c21f74.corvus-42x.pages.dev
Branch Preview URL: https://fix-plugins-r2-publish-defau.corvus-42x.pages.dev

View logs

Copy link
Copy Markdown
Contributor

@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: 1

♻️ Duplicate comments (1)
.github/workflows/publish-plugins.yml (1)

633-669: ⚠️ Potential issue | 🟡 Minor

Also validate revocations.updated_at.

You parse revocations.json, but updated_at is never validated. A malformed file could pass the check while still missing required metadata.

✅ Proposed addition
          if "revoked" not in revocations:
              raise SystemExit("revocations payload missing required key: revoked")
          if not isinstance(revocations.get("revoked"), list):
              raise SystemExit("revocations/revoked must be a list")
+         if not revocations.get("updated_at"):
+             raise SystemExit("revocations payload missing required key: updated_at")
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/publish-plugins.yml around lines 633 - 669, The
revocations JSON currently isn't validating the updated_at field; after checking
revocations is a dict and validating "revoked" is a list, add a check that
revocations contains the "updated_at" key and that its value is a valid
timestamp (e.g., non-empty string or integer) — use
revocations.get("updated_at") to fetch it and raise SystemExit with a clear
message like "revocations payload missing required key: updated_at" or
"revocations/updated_at must be a valid timestamp" if the validation fails.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/publish-plugins.yml:
- Around line 371-390: The remote catalog fetch currently falls back silently to
the local repo copy on any error; change the logic around
catalog_base_url/remote_catalog_url/catalog_payload so that if
urllib.request.urlopen raises urllib.error.HTTPError you only accept the local
fallback when the HTTP status is 404 (resource genuinely missing) or when an
explicit env var like ALLOW_LOCAL_CATALOG_FALLBACK is set; for all other errors
(URLError, JSONDecodeError when decoding the remote payload, or non-404
HTTPError) exit/raise a non-zero failure so the workflow fails fast and does not
overwrite R2 with stale source_catalog; keep the existing local-source parsing
(source_catalog.read_text and json.loads) only for the allowed 404 or
explicit-fallback cases.

---

Duplicate comments:
In @.github/workflows/publish-plugins.yml:
- Around line 633-669: The revocations JSON currently isn't validating the
updated_at field; after checking revocations is a dict and validating "revoked"
is a list, add a check that revocations contains the "updated_at" key and that
its value is a valid timestamp (e.g., non-empty string or integer) — use
revocations.get("updated_at") to fetch it and raise SystemExit with a clear
message like "revocations payload missing required key: updated_at" or
"revocations/updated_at must be a valid timestamp" if the validation fails.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 476b78f and 67cd454.

📒 Files selected for processing (2)
  • .github/workflows/publish-plugins.yml
  • clients/web/apps/docs/src/content/docs/es/guides/plugins.md

Comment thread .github/workflows/publish-plugins.yml Outdated
@yacosta738 yacosta738 merged commit c8d964c into main Feb 24, 2026
15 checks passed
@yacosta738 yacosta738 deleted the fix/plugins-r2-publish-default branch February 24, 2026 12:28
@yacosta738 yacosta738 mentioned this pull request Mar 16, 2026
This was referenced Apr 19, 2026
This was referenced Apr 29, 2026
@dallay-bot dallay-bot Bot mentioned this pull request May 3, 2026
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.

1 participant