Skip to content

(MOT-4299) feat(release): resolve promotion candidates from next by default - #714

Open
ytallo wants to merge 2 commits into
mainfrom
chore/promote-from-next
Open

(MOT-4299) feat(release): resolve promotion candidates from next by default#714
ytallo wants to merge 2 commits into
mainfrom
chore/promote-from-next

Conversation

@ytallo

@ytallo ytallo commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Summary

Two staged-release pipeline follow-ups to MOT-4299:

  • Promote Worker now only requires the worker input. A promotion always ships the candidate behind next, so version is resolved from the Registry (resolve_version() from registry_release.py, stable-semver enforced) and release_run_id is located by querying Release runs for head_branch=<worker>/vX.Y.Z (tag-push runs carry the tag there). Both inputs remain as optional overrides for the repair paths: retrying an interrupted promotion after next moved on, and dispatched Release re-runs whose head_branch is main. All downstream gates are untouched — evidence identity, tag_sha match, and the registry precondition that next still points at the resolved version.
  • Drop dead harness_smoke detection from release.yml. The setup output has had no consumer since 7f57418 gated candidates on the smoke only.

The release SOP's "Promote to latest" section is updated to match.

Verification

  • yaml.safe_load on both workflows; bash -n on the new resolve step; heredoc Python compiles.
  • Derivations checked against production (read-only): harness@next resolves to 1.7.3, and the run lookup for harness/v1.7.3 returns Release run 30997666861 (event push, success) — matching what would have been typed manually.
  • grep confirms no remaining harness_smoke references in .github/ or docs/.

Summary by CodeRabbit

  • New Features

    • Worker promotions can now automatically resolve the candidate version and matching Release run.
    • Manual version and Release run inputs remain available for retries and recovery scenarios.
    • Promotion validation now reports missing or invalid candidates clearly.
  • Bug Fixes

    • Removed outdated Harness smoke-target detection from the release workflow.
  • Documentation

    • Updated release procedures to describe automatic candidate and Release run resolution.

ytallo added 2 commits August 5, 2026 10:21
The harness_smoke setup output has had no consumer since 7f57418 gated
candidates on the smoke only; candidate-ready hardcodes the harness gate
as skipped.
A promotion always ships the candidate behind next, so Promote Worker now
only requires the worker: the version is resolved from the Registry and
the Release run is located from the resulting tag. Both inputs remain as
overrides for the repair paths (retrying after next moved on, dispatched
Release re-runs).
@vercel

vercel Bot commented Aug 5, 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 Aug 5, 2026 2:47pm
workers-tech-spec Ready Ready Preview Aug 5, 2026 2:47pm

Request Review

@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

skill-check — worker

0 verified, 54 skipped (no docs/).

Layer Result
structure
vale
ai
render

Four for four. Nicely done.

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The promotion workflow now resolves omitted version and Release run inputs automatically. It validates resolved values and uses them throughout promotion. The release workflow no longer detects or exposes Harness smoke targets. The release SOP documents the new defaults.

Changes

Worker promotion resolution

Layer / File(s) Summary
Resolve promotion inputs
.github/workflows/promote-worker.yml, docs/sops/release.md
The workflow accepts optional inputs, resolves missing values from the Registry next channel and Release tag, validates them, exports them, and names evidence artifacts with the resolved version. The SOP documents this flow.

Harness smoke detection removal

Layer / File(s) Summary
Remove Harness smoke detection
.github/workflows/release.yml
The release setup no longer inspects Harness dependencies or exposes the harness_smoke output.

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

Sequence Diagram(s)

sequenceDiagram
  participant Operator
  participant PromoteWorker
  participant Registry
  participant ReleaseWorkflow
  Operator->>PromoteWorker: Dispatch with optional version and release_run_id
  PromoteWorker->>Registry: Read next channel when version is omitted
  Registry-->>PromoteWorker: Return candidate version
  PromoteWorker->>ReleaseWorkflow: Find run by worker version tag
  ReleaseWorkflow-->>PromoteWorker: Return release run ID
  PromoteWorker->>PromoteWorker: Validate and export resolved values
Loading

Possibly related PRs

  • iii-hq/workers#667: Modifies the Release workflow and tag-based promotion flow.
  • iii-hq/workers#692: Extends the promotion workflow, release workflow, and release SOP.
  • iii-hq/workers#694: Modifies the release/promotion workflow and SOP around the Registry next channel.

Poem

A rabbit found next beneath the moon,
And matched the Release run soon.
The worker hopped with values clear,
While Harness smoke logs disappeared.
Promotion tracks now guide the way.

🚥 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 clearly and concisely describes the main change: resolving promotion candidates from the Registry's next channel by default.
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 unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/promote-from-next

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.

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

🤖 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 @.github/workflows/promote-worker.yml:
- Around line 91-94: Update the stable-version validation regex in the
workflow’s version-check block to require each MAJOR, MINOR, and PATCH component
to be either 0 or a nonzero digit followed by digits, rejecting values such as
01.2.3 while preserving acceptance of valid stable MAJOR.MINOR.PATCH versions.
- Around line 96-105: Update the Release workflow lookup in the run_id
resolution block to pass the tag through the documented branch filter instead of
head_branch. Keep the existing tag construction, run selection, and missing-run
handling unchanged, using branch="${WORKER}/v${version}" in the gh api request.
🪄 Autofix

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: 2cdabf97-7b79-4d16-9f06-4081979120aa

📥 Commits

Reviewing files that changed from the base of the PR and between c3dafba and 52c4060.

📒 Files selected for processing (3)
  • .github/workflows/promote-worker.yml
  • .github/workflows/release.yml
  • docs/sops/release.md
💤 Files with no reviewable changes (1)
  • .github/workflows/release.yml

Comment on lines +91 to 94
[[ "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] || {
echo "::error::candidate must be stable semver MAJOR.MINOR.PATCH (got ${version}); prereleases are not promotable"
exit 2
}

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

Reject numeric identifiers with leading zeroes.

The expression accepts values such as 01.2.3. Those values are not valid SemVer. This permits an invalid override to pass validation and fail later when the workflow uses the mismatched tag.

Proposed fix
-          [[ "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] || {
+          [[ "$version" =~ ^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)$ ]] || {

Semantic Versioning forbids leading zeroes in normal version identifiers. (semver.org)

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
[[ "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] || {
echo "::error::candidate must be stable semver MAJOR.MINOR.PATCH (got ${version}); prereleases are not promotable"
exit 2
}
[[ "$version" =~ ^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)$ ]] || {
echo "::error::candidate must be stable semver MAJOR.MINOR.PATCH (got ${version}); prereleases are not promotable"
exit 2
}
🤖 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/workflows/promote-worker.yml around lines 91 - 94, Update the
stable-version validation regex in the workflow’s version-check block to require
each MAJOR, MINOR, and PATCH component to be either 0 or a nonzero digit
followed by digits, rejecting values such as 01.2.3 while preserving acceptance
of valid stable MAJOR.MINOR.PATCH versions.

Comment on lines +96 to +105
run_id="$RUN_ID_INPUT"
if [[ -z "$run_id" ]]; then
tag="${WORKER}/v${version}"
run_id=$(gh api -X GET "repos/${GITHUB_REPOSITORY}/actions/workflows/release.yml/runs" \
-f head_branch="$tag" --jq '.workflow_runs[0].id // empty')
[[ -n "$run_id" ]] || {
echo "::error::No Release run found for tag ${tag}; pass release_run_id explicitly"
exit 2
}
echo "::notice::candidate evidence expected in Release run ${run_id}"

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 | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

workflow=.github/workflows/promote-worker.yml
sed -n '96,105p' "$workflow"

# Expected: the workflow-run API query uses `branch="$tag"`.
rg -n -C 2 'actions/workflows/release\.yml/runs|head_branch|branch=' "$workflow"

Repository: iii-hq/workers

Length of output: 1561


🌐 Web query:

GitHub REST API list workflow runs query parameter branch workflow_runs documentation

💡 Result:

In the GitHub REST API, the branch parameter is used to filter workflow runs by a specific branch name [1][2]. This parameter is available for the following endpoints used to list workflow runs: 1. List workflow runs for a repository: GET /repos/{owner}/{repo}/actions/runs [1][2] 2. List workflow runs for a workflow: GET /repos/{owner}/{repo}/actions/workflows/{workflow_id}/runs [1][2] When using the branch parameter, you must provide the name of the branch associated with the push event [1][2]. It is a query parameter used to narrow the results of the request [1][2].

Citations:


Query the Release workflow runs by branch, not head_branch.

head_branch is a response field from workflow runs, while the documented query filter is branch. Use branch="${WORKER}/v${version}" so the lookup can only return runs pushed on that tag.

Proposed fix
             tag="${WORKER}/v${version}"
             run_id=$(gh api -X GET "repos/${GITHUB_REPOSITORY}/actions/workflows/release.yml/runs" \
-              -f head_branch="$tag" --jq '.workflow_runs[0].id // empty')
+              -f branch="$tag" --jq '.workflow_runs[0].id // empty')
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
run_id="$RUN_ID_INPUT"
if [[ -z "$run_id" ]]; then
tag="${WORKER}/v${version}"
run_id=$(gh api -X GET "repos/${GITHUB_REPOSITORY}/actions/workflows/release.yml/runs" \
-f head_branch="$tag" --jq '.workflow_runs[0].id // empty')
[[ -n "$run_id" ]] || {
echo "::error::No Release run found for tag ${tag}; pass release_run_id explicitly"
exit 2
}
echo "::notice::candidate evidence expected in Release run ${run_id}"
run_id="$RUN_ID_INPUT"
if [[ -z "$run_id" ]]; then
tag="${WORKER}/v${version}"
run_id=$(gh api -X GET "repos/${GITHUB_REPOSITORY}/actions/workflows/release.yml/runs" \
-f branch="$tag" --jq '.workflow_runs[0].id // empty')
[[ -n "$run_id" ]] || {
echo "::error::No Release run found for tag ${tag}; pass release_run_id explicitly"
exit 2
}
echo "::notice::candidate evidence expected in Release run ${run_id}"
🤖 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/workflows/promote-worker.yml around lines 96 - 105, Update the
Release workflow lookup in the run_id resolution block to pass the tag through
the documented branch filter instead of head_branch. Keep the existing tag
construction, run selection, and missing-run handling unchanged, using
branch="${WORKER}/v${version}" in the gh api request.

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