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

feat(release): add an experimental flag to Create Tag#646
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
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