Skip to content

feat(release): add an experimental flag to Create Tag - #646

Merged
guibeira merged 1 commit into
mainfrom
feat/create-tag-experimental
Jul 30, 2026
Merged

guibeira merged 1 commit into
mainfrom
feat/create-tag-experimental

Conversation

@guibeira

@guibeira guibeira commented Jul 30, 2026 •

Copy link
Copy Markdown
Collaborator

Adds an Experimental checkbox to Create Tag. Ticking it marks the worker
experimental in the registry — a badge, nothing more: the version publishes
to the channel you picked, installs normally, and resolves normally.

This is the replacement for the experimental channel reverted in #643. That
one needed resolver support the registry never had, and isolating a release
from latest is not what "this is unstable" should mean.

Depends on iii-hq/registry#81 (the column + the badge). Merging this
first would 422 every publish: the registry's publish payload is a strict
object, so it rejects the unknown field.

The path the flag takes

Create Tag input  →  annotated tag message (`experimental: true`)
                  →  parse_release_tag.py  (output `experimental`)
                  →  release.yml  (setup job output)
                  →  _publish-registry.yml
                  →  build_publish_payload.py  →  POST /publish

It rides the tag annotation next to registry-tag: because the tag is all
the Release workflow receives — anything the publish needs has to be written
there.

Two rules worth knowing

Anything but the literal true is false. A lightweight tag, a missing
line, a typo (experimental: yes) — all publish as stable. Marking a worker
experimental is the deliberate choice, so it takes the exact word.

Leaving the box unticked is the promotion. The registry treats a release
without the flag as the signal that the worker stabilised and drops the
badge, so there is no separate promote step. Re-releasing while still
experimental keeps the original mark.

The payload always carries the key, always as a real boolean — the registry
422s a stringly-typed value, and a workflow input is a string.

Verification

  • .github/scripts/tests/: 157 passed (7 new — 5 on the annotation
    parsing incl. typo/casing/absent, 2 on the payload's boolean)
  • End-to-end dry run on a scratch repo, both directions: an annotated tag
    carrying experimental: true produced "experimental": true (JSON bool)
    in the payload; the same tag without the line produced false
  • All three edited workflows parse as YAML

Summary by CodeRabbit

  • New Features

    • Added support for marking releases as experimental during tag creation and registry publishing.
    • Experimental status is propagated through release workflows and included in registry metadata.
    • Added documentation describing experimental releases and promotion to stable status.
  • Bug Fixes

    • Ensured the experimental registry field is always recorded as a boolean, defaulting to false.
    • Invalid or missing experimental tag values now safely fall back to false.
  • Tests

    • Added coverage for experimental release parsing and payload generation.

Create Tag gains an `experimental` checkbox that marks the worker
experimental in the registry. It is a badge, not a channel: the version
publishes to the channel the operator picked, installs normally, and
resolves normally. This is what replaces the reverted `experimental`
channel — that one needed resolver support the registry never had, and
isolating a release from `latest` is not what "this is unstable" should
mean.

The flag rides the annotated tag message next to `registry-tag:`, since the
tag is all the Release workflow receives, and travels from there through
`parse_release_tag.py` to the publish payload. Anything but the literal
`true` publishes as stable, so a lightweight tag, a missing line, or a typo
can never mark a stable worker by accident.

The payload always carries the key as a real boolean. The registry reads a
missing flag as the promotion signal and clears the badge, and rejects a
stringly-typed value with 422 — a CI value that lost its type should fail
loudly rather than silently promote a worker.

Requires iii-hq/registry#81, which adds the column and the badge.
@guibeira guibeira added the no-ticket PR deliberately has no Linear ticket (bump/typo/CI-only) label Jul 30, 2026
@vercel

vercel Bot commented Jul 30, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
workers Ready Ready Preview Jul 30, 2026 6:49pm
workers-tech-spec Ready Ready Preview Jul 30, 2026 6:49pm

Request Review

@github-actions

Copy link
Copy Markdown
Contributor

skill-check — worker

0 verified, 50 skipped (no docs/).

Layer Result
structure ✓
vale ✓
ai ✓
render ✓

Four for four. Nicely done.

@coderabbitai

coderabbitai Bot commented Jul 30, 2026 •

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The release flow now records experimental status in tags, parses and forwards it through GitHub Actions, and always includes it as a boolean in registry publish payloads. Tests and release documentation cover default, valid, normalized, and invalid annotation values.

Changes

Experimental release metadata

Layer / File(s) Summary
Tag input and annotation contract
.github/workflows/create-tag.yml, docs/sops/release.md
Tag creation accepts an experimental checkbox, writes experimental: true/false into annotated tags, and documents the resulting behavior.
Release annotation parsing and wiring
.github/scripts/parse_release_tag.py, .github/workflows/release.yml, .github/scripts/tests/test_parse_release_tag.py
Tag annotations produce a normalized experimental output, which is forwarded from the setup job into the publish workflow and covered by parsing tests.
Registry payload generation
.github/scripts/build_publish_payload.py, .github/workflows/_publish-registry.yml, .github/scripts/tests/test_build_publish_payload.py
The publish workflow passes experimental input to the payload builder, which always emits a boolean experimental field with default and explicit-value tests.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

  • iii-hq/workers#631: Adjacent changes to experimental routing in tag and publish workflows.
  • iii-hq/workers#643: Related changes to experimental registry-channel support in release parsing and versioning.

Suggested labels: no-ticket

Suggested reviewers: ytallo, rohitg00

Sequence Diagram(s)

sequenceDiagram
  participant Operator as Release Operator
  participant CreateTag as create-tag.yml
  participant ParseTag as parse_release_tag.py
  participant Release as release.yml
  participant Publish as _publish-registry.yml
  participant Payload as build_publish_payload.py
  Operator->>CreateTag: Select experimental option
  CreateTag->>ParseTag: Create annotated tag with experimental field
  ParseTag->>Release: Emit normalized experimental output
  Release->>Publish: Pass experimental workflow input
  Publish->>Payload: Pass experimental value
  Payload-->>Publish: Generate payload with boolean experimental field
Loading

Poem

I’m a bunny with a tag in tow,
Marking which releases wear a glow.
Through scripts and workflows, flags hop bright,
Into payloads, true or false and right.
Stable carrots wait when badges go.

🚥 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 is concise and accurately describes the main change: adding an experimental flag to the Create Tag release flow.
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.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/create-tag-experimental

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.

@guibeira
guibeira marked this pull request as ready for review July 30, 2026 19:58

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
.github/scripts/build_publish_payload.py (1)

332-332: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Avoid truthiness coercion for experimental.

bool("false") is True. The CLI currently normalizes its string before calling build_payload, but a direct caller passing a string could accidentally publish a stable worker as experimental. Validate that this parameter is a real boolean, then emit it directly.

Proposed fix
 def build_payload(
     *,
@@
     bundle: dict[str, Any] | None = None,
     experimental: bool = False,
 ) -> dict[str, Any]:
+    if not isinstance(experimental, bool):
+        raise TypeError("experimental must be a bool")
+
     root = repo_root / worker
@@
-        "experimental": bool(experimental),
+        "experimental": experimental,

Also applies to: 368-372

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/scripts/build_publish_payload.py at line 332, Update build_payload’s
experimental parameter handling to require an actual boolean rather than
coercing arbitrary values with bool(). Validate and reject string or other
non-boolean inputs, then emit the validated experimental value directly in the
payload while preserving the default False behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/sops/release.md`:
- Around line 113-116: Update the experimental release documentation near the
parse_release_tag.py flow to state that the value is trimmed and compared
case-insensitively, so variants such as “TRUE” and “ true ” are accepted while
missing or other values publish as stable.

---

Nitpick comments:
In @.github/scripts/build_publish_payload.py:
- Line 332: Update build_payload’s experimental parameter handling to require an
actual boolean rather than coercing arbitrary values with bool(). Validate and
reject string or other non-boolean inputs, then emit the validated experimental
value directly in the payload while preserving the default False behavior.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 3fa88d93-6344-457b-bf83-b6f5a7c46251

📥 Commits

Reviewing files that changed from the base of the PR and between ebebcee and aa03a62.

📒 Files selected for processing (8)
  • .github/scripts/build_publish_payload.py
  • .github/scripts/parse_release_tag.py
  • .github/scripts/tests/test_build_publish_payload.py
  • .github/scripts/tests/test_parse_release_tag.py
  • .github/workflows/_publish-registry.yml
  • .github/workflows/create-tag.yml
  • .github/workflows/release.yml
  • docs/sops/release.md

Comment thread docs/sops/release.md
Comment on lines +113 to +116
It travels the same way the channel does: `experimental: true` in the
annotated tag message, read by `parse_release_tag.py`, forwarded through
`release.yml` to the publish payload. Anything but the literal `true` — a
missing line, a lightweight tag, a typo — publishes as stable.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Document the normalization rule for experimental.

parse_release_tag.py accepts case-insensitive values and surrounding whitespace (TRUE, true), but this says only the literal true is accepted. State the trim-and-lowercase behavior explicitly so the documentation matches the parser and tests.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/sops/release.md` around lines 113 - 116, Update the experimental release
documentation near the parse_release_tag.py flow to state that the value is
trimmed and compared case-insensitively, so variants such as “TRUE” and “ true ”
are accepted while missing or other values publish as stable.

@guibeira
guibeira merged commit a7bffe2 into main Jul 30, 2026
18 checks passed

This branch was successfully deployed

2 active deployments
Preview – workers-tech-spec — aa03a62e Deployed Jul 30, 2026 by vercel[bot]
Preview – workers — aa03a62e Deployed Jul 30, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

no-ticket PR deliberately has no Linear ticket (bump/typo/CI-only)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant