Skip to content

feat(plugins): automate plugin release publishing on Cloudflare#63

Merged
yacosta738 merged 2 commits into
mainfrom
feature/plugins
Feb 21, 2026
Merged

feat(plugins): automate plugin release publishing on Cloudflare#63
yacosta738 merged 2 commits into
mainfrom
feature/plugins

Conversation

@yacosta738
Copy link
Copy Markdown
Contributor

@yacosta738 yacosta738 commented Feb 21, 2026

Add tag-driven plugin release automation with immutable artifact paths, signing, and catalog updates so plugin releases deploy consistently without per-plugin workflow changes.

Summary by CodeRabbit

  • New Features

    • Automated plugin publish flow on release tags: builds WASM, produces immutable bundles, signs artifacts, optional OCI publish and Cloudflare Pages catalog deployment.
    • Memory.surreal.graphs plugin added to the public catalog.
  • Documentation

    • Revised plugin onboarding and publishing guide with release-driven workflow, metadata requirements, and deployment/secret guidance.
    • Updated docs site content and examples for artifact/manifest validation.
  • Infrastructure

    • Immutable artifact hosting paths with long-term caching and improved headers.

Add tag-driven plugin release automation with immutable artifact paths, signing, and catalog updates so plugin releases deploy consistently without per-plugin workflow changes.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Feb 21, 2026

No actionable comments were generated in the recent review. 🎉


📝 Walkthrough

Walkthrough

Adds an automated, tag-driven plugin publishing pipeline that resolves plugin metadata, builds WASM artifacts, signs and verifies bundles with cosign, conditionally publishes to OCI, generates a web catalog, and optionally deploys to Cloudflare Pages. Also adds plugin metadata, catalog artifacts, headers, and doc updates.

Changes

Cohort / File(s) Summary
Workflow & CI docs
.github/workflows/publish-plugins.yml, .github/workflows/README.md
New publish-plugins workflow: tag/manual triggers, plugin resolution from Cargo.toml, WASM build, bundle assembly, cosign sign/verify (keyed or keyless), optional OCI push, catalog site build, Cloudflare Pages deployment; README updated.
Static/Link config
.lycheeignore
Added ignore rule for GNU Make website.
Plugin metadata
clients/agent-runtime/plugins/memory-surreal-graphs/Cargo.toml
Adds package.metadata.corvus fields (plugin_id, publisher, runtime_api, capabilities, entrypoints, and resource limits).
Onboarding logic
clients/agent-runtime/src/onboard/wizard.rs
Enable Surreal Graphs installation flag and propagate bootstrap backend changes back into main memory config for subsequent setup checks.
Docs (EN/ES) — Guides & Frontmatter
clients/web/apps/docs/src/content/docs/.../plugins.md, .../index.mdx, .../404.mdx, .../es/.../plugins.md, .../es/.../index.mdx
Rewrote plugin publishing guide for release-driven workflow, updated onboarding and secrets requirements; refactored frontmatter to nested action lists in several MDX files.
Docs site pages
clients/web/apps/docs/src/pages/404.astro
Removed the Astro 404 page component and its locale/UI logic.
Plugin catalog site
clients/web/apps/plugins/README.md, clients/web/apps/plugins/src/pages/index.astro, clients/web/apps/plugins/public/_headers, clients/web/apps/plugins/public/artifacts/.../plugin-manifest.json, clients/web/apps/plugins/public/catalog.json
Adds immutable artifact/manifest files and populated catalog.json, sets long-term caching headers for artifacts, updates README and index page with endpoints and examples; includes signature/certificate URLs in manifests.
Hosting config
clients/web/apps/plugins/vercel.json
Removed Vercel-specific headers file (deleted).

Sequence Diagram(s)

sequenceDiagram
    participant GH as GitHub Actions
    participant Resolver as Resolver (Python step)
    participant Cargo as Cargo/WASM Build
    participant Catalog as Catalog Generator
    participant Cosign as Cosign
    participant OCI as OCI Registry
    participant Pages as Cloudflare Pages

    GH->>Resolver: Trigger (tag or manual) -> resolve plugin_id, path, version
    Resolver->>GH: emit meta outputs (paths, urls, flags)
    GH->>Cargo: build wasm (wasm32-wasip1) using meta outputs
    Cargo->>GH: produce wasm artifact
    GH->>Catalog: assemble bundle, compute sha256, write plugin-manifest.json & catalog.json
    GH->>Cosign: sign artifact (keyed or keyless)
    Cosign->>GH: return signature (+certificate if keyless)
    GH->>Cosign: verify signature in CI
    GH->>OCI: optional push bundle to OCI (if configured)
    GH->>Pages: build catalog site and deploy to Cloudflare Pages (optional)
    GH->>GH: upload artifacts and post step summary (URLs, digests)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested labels

codex

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description is brief but does not follow the provided template structure with required sections like Related Issues, Tested Information, and Checklist. Fill in the template sections including Related Issues, Tested Information, Breaking Changes (if any), and complete the Checklist to provide complete context for reviewers.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main feature: automating plugin release publishing on Cloudflare with tag-driven workflows.

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

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/plugins

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 21, 2026

✅ Contributor Report

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

Metric Description Value Threshold Status
PR Merge Rate PRs merged vs closed 89% >= 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 3039 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 363 >= 0
Merger Diversity Unique maintainers who merged PRs 3 >= 0
Repo History Merge Rate Merge rate in this repo 88% >= 0%
Repo History Min PRs Previous PRs in this repo 43 >= 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-21 to 2026-02-21

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: 8

🧹 Nitpick comments (2)
clients/web/apps/plugins/src/pages/index.astro (1)

27-34: Hardcoded version 0.1.0 will drift as the plugin evolves.

These endpoint entries and curl examples hard-code memory.surreal.graphs/0.1.0. Since the catalog at /catalog.json is the canonical runtime source for the latest version, consider either:

  • Noting in the UI that these are versioned (immutable) examples and directing users to /catalog.json for the current version, or
  • Adding a brief comment in source indicating this section needs updating when a new version is tagged.

Also applies to: 47-52

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

In `@clients/web/apps/plugins/src/pages/index.astro` around lines 27 - 34, Replace
the hardcoded version string "memory.surreal.graphs/0.1.0" used inside the <p
class="endpoint"> code elements and any other occurrences (e.g., the second
occurrence at lines ~47-52) by either 1) adding a visible note in the UI near
those <p class="endpoint"> elements that these are immutable, versioned examples
and directing users to the canonical runtime catalog at "/catalog.json" for the
latest version, or 2) adding a short inline source comment next to the code
strings (the literal "memory.surreal.graphs/0.1.0") reminding maintainers to
update these entries when a new plugin tag is published; ensure you update both
occurrences shown and keep the displayed example path unchanged if you choose
the UI note option.
.github/workflows/publish-plugins.yml (1)

347-364: Concurrent publishes of different plugins can clobber each other's catalog entries.

The catalog upsert reads its base from the repo checkout (clients/web/apps/plugins/public/catalog.json). Since the concurrency group is per-ref (plugins-publish-${{ github.ref }}), two different plugin tags can run simultaneously. Both start from the same base catalog, each adds only its own plugin, and whichever Cloudflare deploy finishes last overwrites the other's entry.

This is acceptable for a single-plugin setup today but will cause data loss when multiple plugins are published in close succession. Consider serializing all plugin publishes under a single concurrency group, or fetching the live catalog from Cloudflare before upserting.

🤖 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 347 - 364, The current
upsert reads from the repo file (source_catalog / catalog_payload /
existing_plugins) which allows concurrent jobs to clobber each other; modify the
workflow to fetch the live published catalog from Cloudflare (or the deployment
origin) before merging: retrieve the remote catalog JSON, fall back to
{"plugins": []} if missing, validate it's a list, then perform the merge by
filtering out existing plugin.id and appending plugin_entry (use the same
filtered variable logic), sort by id and write the updated catalog to
dist_dir/"catalog.json"; alternatively, change the GitHub Actions concurrency
key to a single global group name so publishes are serialized (i.e., update the
concurrency group instead of reading the repo file) — implement one of these two
fixes and keep validation/error handling for malformed catalogs.
🤖 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 412-438: The workflow unconditionally passes --output-certificate
to cosign even when COSIGN_PRIVATE_KEY is set, but key-based signing (seen in
the sign-blob branch that checks COSIGN_PRIVATE_KEY) does not produce a Fulcio
identity certificate, so certificate_path will be meaningless and downstream
steps (the oras push that tries to include the .pem and the cp that stages it)
will fail under set -euo pipefail; fix by changing the sign step to only include
--output-certificate "$certificate_path" when COSIGN_PRIVATE_KEY is empty (i.e.,
in keyless mode), or alternately add file-existence guards before the downstream
oras push / cp steps to skip including/copying certificate_path when the .pem
does not exist, ensuring variables signature_path, certificate_path and
artifact_path remain consistent.

In `@clients/agent-runtime/src/onboard/wizard.rs`:
- Around line 2772-2775: The assignment config = bootstrap.memory overwrites the
user's explicit auto_save choice when install_and_handle_surreal_graphs falls
back to markdown; change the merge to preserve the user's auto_save (and any
other user-provided flags) by merging rather than blindly replacing: after
calling install_and_handle_surreal_graphs(&mut bootstrap, true) check if
bootstrap.memory.backend != backend and then set config = bootstrap.memory but
copy config.auto_save = previous_config.auto_save (or copy any non-default
user-driven fields from the original config into bootstrap.memory) so that the
user's auto_save preference survives the fallback; use the existing names
config, bootstrap.memory, install_and_handle_surreal_graphs, and
memory_config_defaults_for_backend("markdown") to locate and update the logic.

In `@clients/web/apps/docs/src/content/docs/es/guides/plugins.md`:
- Around line 118-158: In the workflow description fix three Spanish/i18n
issues: in the signature step text "si no keyless" (item starting with "Firma el
artefacto con cosign") add the missing comma or rephrase to "si no, keyless" or
"o bien keyless OIDC si no existe"; change "del app" to "de la app" in the
Cloudflare deploy line that currently reads "Hace build del app de catálogo y
deploy a Cloudflare Pages"; and replace "límites/capabilities" with
"límites/capacidades" in the important integration instructions (the line that
lists "Define límites/capabilities en `package.metadata.corvus`").

In `@clients/web/apps/plugins/public/_headers`:
- Around line 11-33: Add the missing CORS header to each artifact rule in the
_headers file so cross-origin fetches and WebAssembly.instantiateStreaming calls
succeed; for every block that starts with paths like "/artifacts/*/*/*.wasm",
"/artifacts/*/*/*.json", "/artifacts/*/*/*.sig", "/artifacts/*/*/*.pem", and the
catch-all "/artifacts/*/*/*", add the header "Access-Control-Allow-Origin: *"
alongside the existing Cache-Control and X-Content-Type-Options entries.
- Around line 11-33: Add CORS headers to the artifact routes so cross-origin
WASM/JSON fetches succeed: update each header block for the patterns
"/artifacts/*/*/*.wasm", "/artifacts/*/*/*.json", "/artifacts/*/*/*.sig",
"/artifacts/*/*/*.pem", and the catch-all "/artifacts/*/*/*" to include
"Access-Control-Allow-Origin: *" (or a scoped origin) and optionally
"Access-Control-Allow-Methods: GET, OPTIONS" and "Access-Control-Allow-Headers:
Content-Type" to cover browser preflight requests.
- Around line 11-33: The new `_headers` rules use multiple splats (e.g.
/artifacts/*/*/*.wasm, /artifacts/*/*/*.json, /artifacts/*/*/*.sig,
/artifacts/*/*/*.pem, /artifacts/*/*/*) which Cloudflare Pages rejects because
it allows only one splat; replace these with single-splat or placeholder-style
patterns such as /artifacts/:seg1/:seg2/:seg3 (or a single splat
/artifacts/:path* for a catch-all) and move shared Cache-Control and
X-Content-Type-Options entries under that single pattern; if you need
per-extension Content-Type overrides (since you referenced
.wasm/.json/.sig/.pem), implement a Pages Function (e.g.
functions/artifacts/[[path]].ts) to detect the file extension and set
Content-Type accordingly while leaving cache and security headers in the
`_headers` single-pattern rule.
- Around line 31-33: Keep the existing specific patterns for .wasm, .json, .sig,
and .pem (they correctly precede the catch-all under Netlify's "first match
wins") and do not change those; update the catch-all rule for /artifacts/*/*/*
to include a default Content-Type (for example, add "Content-Type:
application/octet-stream") so unknown/new artifact extensions still get a safe
type hint while retaining the long cache header "Cache-Control: public,
max-age=31536000, immutable".

In `@clients/web/apps/plugins/public/catalog.json`:
- Around line 2-27: The catalog entry for plugin id "memory.surreal.graphs" is
missing the required "signature" block (same omission as in the plugin
manifest); update the catalog JSON entry to include a "signature" object that
matches the schema your publish workflow and runtime expect (e.g., the same
signature fields used in the plugin-manifest.json such as signature value, key
id/type or algorithm and any timestamp/metadata), ensuring the "artifact.digest"
and "signature" correspond to the signed artifact so the catalog upsert and
runtime validation succeed.

---

Nitpick comments:
In @.github/workflows/publish-plugins.yml:
- Around line 347-364: The current upsert reads from the repo file
(source_catalog / catalog_payload / existing_plugins) which allows concurrent
jobs to clobber each other; modify the workflow to fetch the live published
catalog from Cloudflare (or the deployment origin) before merging: retrieve the
remote catalog JSON, fall back to {"plugins": []} if missing, validate it's a
list, then perform the merge by filtering out existing plugin.id and appending
plugin_entry (use the same filtered variable logic), sort by id and write the
updated catalog to dist_dir/"catalog.json"; alternatively, change the GitHub
Actions concurrency key to a single global group name so publishes are
serialized (i.e., update the concurrency group instead of reading the repo file)
— implement one of these two fixes and keep validation/error handling for
malformed catalogs.

In `@clients/web/apps/plugins/src/pages/index.astro`:
- Around line 27-34: Replace the hardcoded version string
"memory.surreal.graphs/0.1.0" used inside the <p class="endpoint"> code elements
and any other occurrences (e.g., the second occurrence at lines ~47-52) by
either 1) adding a visible note in the UI near those <p class="endpoint">
elements that these are immutable, versioned examples and directing users to the
canonical runtime catalog at "/catalog.json" for the latest version, or 2)
adding a short inline source comment next to the code strings (the literal
"memory.surreal.graphs/0.1.0") reminding maintainers to update these entries
when a new plugin tag is published; ensure you update both occurrences shown and
keep the displayed example path unchanged if you choose the UI note option.

Comment thread .github/workflows/publish-plugins.yml
Comment thread clients/agent-runtime/src/onboard/wizard.rs
Comment thread clients/web/apps/docs/src/content/docs/es/guides/plugins.md
Comment thread clients/web/apps/plugins/public/_headers Outdated
Comment thread clients/web/apps/plugins/public/_headers Outdated
Comment thread clients/web/apps/plugins/public/catalog.json
@cloudflare-workers-and-pages
Copy link
Copy Markdown

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

Deploying corvus-plugins with  Cloudflare Pages  Cloudflare Pages

Latest commit: 0d526c3
Status: ✅  Deploy successful!
Preview URL: https://041d8db0.corvus-plugins.pages.dev
Branch Preview URL: https://feature-plugins.corvus-plugins.pages.dev

View logs

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

Deploying corvus with  Cloudflare Pages  Cloudflare Pages

Latest commit: 0d526c3
Status: ✅  Deploy successful!
Preview URL: https://431f37ac.corvus-42x.pages.dev
Branch Preview URL: https://feature-plugins.corvus-42x.pages.dev

View logs

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