$npx -y skills add opendatahub-io/ai-helpers --skill odh-llm-d-releaseOrchestrate the opendatahub-io release for all llm-d components in one cycle. Collects upstream(llm-d) versions, auto-discovers the release tracker issue, then spawns parallel sub-agents — one per component (release branch, Konflux onboarder workflow, PR validation, approve+merge
| 1 | # ODH llm-d Release Orchestrator |
| 2 | |
| 3 | Runs once per ODH release cycle by the release manager. Drives release |
| 4 | branch creation, the Konflux onboarder workflow, onboarder-PR validation |
| 5 | and merge, Quay image verification, KServe metadata PR, and the tracker |
| 6 | comment — for every llm-d component in one shot. |
| 7 | |
| 8 | **Single input:** `--version v3.5-ea2`. Three values derive from it: |
| 9 | |
| 10 | | Use | Value | |
| 11 | |---|---| |
| 12 | | ODH release branch on each component repo | `release-v3.5-ea2` | |
| 13 | | Konflux onboarder `version` input + Quay image tag | `v3.5-ea2` | |
| 14 | | GitHub release tag on each component repo | `odh-v3.5-ea2` | |
| 15 | |
| 16 | ## Value flow (for `--version v3.5-ea2`) |
| 17 | |
| 18 | This diagram shows where the version goes, what name it takes at each stop, |
| 19 | and which script flag receives it. Three derived values are colored below: |
| 20 | `B` = release branch, `T` = image tag (unchanged from `VERSION`), |
| 21 | `R` = GitHub release tag. |
| 22 | |
| 23 | ```text |
| 24 | release manager |
| 25 | └─ /odh-llm-d-release --version v3.5-ea2 |
| 26 | |
| 27 | orchestrator (SKILL.md) |
| 28 | VERSION = v3.5-ea2 |
| 29 | RELEASE_BRANCH= release-v3.5-ea2 (B = release_branch_prefix + VERSION) |
| 30 | IMAGE_TAG = v3.5-ea2 (T = VERSION, unchanged) |
| 31 | RELEASE_TAG = odh-v3.5-ea2 (R = github_release_tag_prefix + VERSION) |
| 32 | │ |
| 33 | ├── per-component sub-agent (one per component, in parallel) |
| 34 | │ step 1 create-release-branch.sh --branch B → branch release-v3.5-ea2 |
| 35 | │ step 2 onboarder-trigger-gha.sh --version T → Konflux builds quay.io/.../<image>:v3.5-ea2 |
| 36 | │ step 6 release-image-checker.sh --tag T → verifies quay.io/.../<image>:v3.5-ea2 |
| 37 | │ step 7 create-github-release.sh --tag R → draft GH release tagged odh-v3.5-ea2 |
| 38 | │ |
| 39 | └── KServe metadata sub-agent |
| 40 | open-kserve-metadata-pr.sh --version VERSION → PR title/branch use v3.5-ea2 |
| 41 | (the upstream component versions in --updates |
| 42 | are SEPARATE — collected from the release |
| 43 | manager via AskUserQuestion in step 1) |
| 44 | ``` |
| 45 | |
| 46 | ## Step 0 — Parse arguments and load config |
| 47 | |
| 48 | Parse `$ARGUMENTS`: |
| 49 | |
| 50 | - `--version <ver>` (required) — the ODH release version. Accepted forms: |
| 51 | - **GA**: `v3.5`, `v3.5.0` |
| 52 | - **Early Access**: `v3.5-ea1`, `v3.5-ea.1`, `v3.5.0-ea.1` (also `v3.5.0-ea1`) |
| 53 | |
| 54 | Validate that `--version` matches `^v[0-9]+\.[0-9]+(\.[0-9]+)?(-[A-Za-z0-9.]+)?$`. |
| 55 | If missing or malformed, prompt the user via `AskUserQuestion` and stop on cancel. |
| 56 | |
| 57 | Load the registry: |
| 58 | |
| 59 | ```bash |
| 60 | SKILL_DIR="${CLAUDE_SKILL_DIR:-$(cd "$(dirname "$0")" && pwd)}" |
| 61 | CONFIG="${SKILL_DIR}/references/components.yaml" |
| 62 | |
| 63 | VERSION="<parsed>" |
| 64 | RELEASE_BRANCH="$(yq -r '.release.release_branch_prefix' "${CONFIG}")${VERSION}" |
| 65 | IMAGE_TAG="${VERSION}" |
| 66 | RELEASE_TAG="$(yq -r '.release.github_release_tag_prefix' "${CONFIG}")${VERSION}" |
| 67 | ``` |
| 68 | |
| 69 | Run the tools check: |
| 70 | |
| 71 | ```bash |
| 72 | bash "${SKILL_DIR}/scripts/tools-checker.sh" |
| 73 | ``` |
| 74 | |
| 75 | If it fails, stop and surface what's missing. |
| 76 | |
| 77 | ## Step 1 — Collect upstream versions |
| 78 | |
| 79 | For the KServe metadata PR, gather the upstream version for every component |
| 80 | and every entry in `kserve_extra_entries` (vLLM today). Use a **single** |
| 81 | `AskUserQuestion` call so the release manager fills them all in at once |
| 82 | rather than answering one prompt at a time. |
| 83 | |
| 84 | Build the list of names to ask about: |
| 85 | |
| 86 | ```bash |
| 87 | # Per-component entries (kserve_entry_name) + extras (e.g. vLLM) |
| 88 | yq -r '.components | to_entries[] | .value.kserve_entry_name' "${CONFIG}" |
| 89 | yq -r '.release.kserve_extra_entries[]' "${CONFIG}" |
| 90 | ``` |
| 91 | |
| 92 | Issue one `AskUserQuestion` with one question per name, prompting "Upstream |
| 93 | version for `<name>` (e.g. v0.7.1):". Cancel ⇒ stop. |
| 94 | |
| 95 | Build `UPDATES` for the KServe sub-agent from the collected answers: |
| 96 | |
| 97 | ```json |
| 98 | [{"name": "llm-d-router", "version": "v0.7.1"}, ...] |
| 99 | ``` |
| 100 | |
| 101 | ## Step 2 — Auto-discover the tracker issue |
| 102 | |
| 103 | ```bash |
| 104 | bash "${SKILL_DIR}/scripts/tracker-issue-finder.sh" \ |
| 105 | --version "${VERSION}" |
| 106 | ``` |
| 107 | |
| 108 | Parse the output. Behavior: |
| 109 | |
| 110 | - **`tracker-issue-finder.sh` exited non-zero** (GitHub API/search failure): |
| 111 | tell the user the search failed (show stderr), and ask whether to retry, |
| 112 | to provide an issue number directly, or to skip the final c |