Skip to main content

automated-release-run

Use this skill whenever the user asks to "release <repo>", "run the release for <repo>", "trigger the automated release for <repo>", or any variation of triggering and monitoring the automated-release.yml workflow for a SonarSource analyzer project to completion. Unlike automated-release-setup (which wires the workflow into a repo once), this skill runs an actual release: it interviews the user for the workflow_dispatch inputs, checks releasability, triggers the workflow, then polls and merges the resulting pull requests so nobody has to remember to come back later.

소스 정보

저장소
SonarSource/release-github-actions
최근 소스 활동
2026년 8월 31일 12:50
감지된 SKILL.md 언어
영어
스타
7
포크
1

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
name
automated-release-run
description
Use this skill whenever the user asks to "release <repo>", "run the release for <repo>", "trigger the automated release for <repo>", or any variation of triggering and monitoring the automated-release.yml workflow for a SonarSource analyzer project to completion. Unlike automated-release-setup (which wires the workflow into a repo once), this skill runs an actual release: it interviews the user for the workflow_dispatch inputs, checks releasability, triggers the workflow, then polls and merges the resulting pull requests so nobody has to remember to come back later.
# Run an Automated Release Trigger the repo's automated-release wrapper workflow (the hand-authored `.github/workflows/*.yml` file that forwards to `SonarSource/release-github-actions/.github/workflows/automated-release.yml@v1` — its filename varies per repo, see Step 1) for an analyzer repo and stay with it until every pull request it opens (version bump, SQS, SQC, SQAA) is reviewed, green, and merged, and the SONAR integration ticket's fixVersion is set — so the user can ask once and walk away instead of babysitting PRs across multiple repos and a Jira ticket. This skill assumes the target repo already has that wrapper workflow set up (see the `automated-release-setup` skill if it doesn't). **Always link, don't just name.** Whenever you mention a Jira ticket, a GitHub workflow run, or a pull request anywhere in this skill's output, include its actual URL (`https://sonarsource.atlassian.net/browse/<KEY>` for Jira, or whatever `gh`/the Atlassian MCP returns) — not just the key/number. The user should be able to click straight through without having to construct the link themselves. **Heads up on permission prompts.** This skill runs a number of read-only shell commands (`gh`, `git`, `date`, `mktemp`) to inspect repo/release state and poll status as it goes. If you'd rather not approve each one individually, pre-approve these command prefixes for the session (or project-locally in `.claude/settings.local.json`) before starting — the skill itself has no way to do this for you. ## Step 1 — Identify the repo and read its release config 1. **Check the current directory first.** If it's already a git checkout of a repo under the `SonarSource` org (`git remote get-url origin`) with a `.github/workflows/*.yml` file that forwards to `release-github-actions/.github/workflows/automated-release.yml@v1` (grep as in step 4 below — don't assume the filename), ask the user via `AskUserQuestion`: "Release `<repo>` (the one you're in)?" with that as the first/default option and "No, a different repo" as the other. Only fall through to step 2 below if the user picks the latter, or if the current directory isn't a recognizable checkout at all. 2. Otherwise, parse the repo name from the request, e.g. "Release sonar-pli" or "Release SonarSource/sonar-pli". A bare name (`sonar-pli`) is assumed to be under the `SonarSource` GitHub org; accept a full `org/repo` too. 3. Find a local checkout to read the wrapper workflow file from: - If the current directory is already a checkout of that repo (`git remote get-url origin` matches), use it directly. - Otherwise, ask the user (via `AskUserQuestion`) where it's already cloned — offer a free-text path option and a "not cloned yet" option. Don't assume any particular directory layout (e.g. `~/Projects`) — that's a personal convention, not a portable default. - If not cloned, ask where to clone it, defaulting to a fresh temp directory (`mktemp -d`) so it's disposable. A shallow `git clone` is enough — this only needs to read one YAML file, not build or test anything. 4. Read the repo's wrapper workflow file. **Don't assume it's named `automated-release.yml`** — it's hand-authored per repo (by the `automated-release-setup` skill or manually) and the filename varies (e.g. sonar-php uses `AutomateRelease.yml`). Find it by content, not name: ```bash grep -rl "release-github-actions/.github/workflows/automated-release.yml@v1" .github/workflows/ ``` Use whatever path that returns for every later step in this skill (reading inputs here, and the `gh workflow run <filename>` call in Step 5 — that command also takes the actual filename, not a hardcoded `automated-release.yml`). This file declares `workflow_dispatch` inputs and forwards them to `SonarSource/release-github-actions/.github/workflows/automated-release.yml@v1`. **Parse the actual file — don't assume a fixed input list.** Every repo customizes it (e.g. some add `ide-integration`, `dry-run`, `bump-version`; others don't). 5. From that same file, note the hardcoded `with:` values for `project-name`, `plugin-name`, `jira-project-key` — these are fixed per repo, don't ask the user for them. ## Step 2 — Releasability pre-flight Before interviewing the user, verify the target branch (default `master`, or whatever the user names in Step 3) is actually releasable. This is a fast fail before spending any time on the interview or a full workflow run. ```bash gh api "/repos/<owner>/<repo>/commits/<branch>/status" \ --jq '.statuses[] | select(.context=="Releasability")' ``` - Fail with the description shown if `.state != "success"`, or if the description contains "failed optional checks" (mirrors `check-releasability-status/action.yml`'s logic). - Also check for any other failing required checks on the branch: ```bash gh api "/repos/<owner>/<repo>/commits/<branch>/check-runs" \ --jq '.check_runs[] | select(.conclusion != "success" and .conclusion != "skipped" and .conclusion != "neutral")' ``` - If either check fails, stop — but don't just report the failure and give up. Diagnose it and help the user fix it (see "Diagnosing and fixing releasability problems" below). Do not proceed to Step 3 until releasability passes. - Tell the user this is a **pre-flight convenience check**, not the authoritative one — the workflow's own `check-releasability` job re-checks the exact commit SHA via `SonarSource/gh-action_releasability@v3` when it actually runs, so this step is about failing fast and cheaply, not replacing that gate. ### Diagnosing and fixing releasability problems Don't stop at "releasability failed" — read the `description` field closely, since it usually names the specific sub-check that failed (e.g. `"failed optional checks -> Jira"`, `"failed optional checks -> Peachee Languages Statistics"`) and diagnose each failure to a concrete, actionable cause before presenting it to the user: - **`-> Jira`**: the releasability check requires no unresolved tickets against the project's unreleased Jira version. Query for the blockers directly instead of asking the user to go look. Resolve the Jira `cloudId` (site host, e.g. `sonarsource.atlassian.net`) via `mcp__atlassian__getAccessibleAtlassianResources` if not already known, then use the Atlassian MCP (`mcp__atlassian__searchJiraIssuesUsingJql`) with something like: `project = <JIRA_PROJECT_KEY> AND fixVersion in unreleasedVersions() AND status not in (Done, Closed, Resolved, Canceled)` — adjust the "done-like" status list per project if that query returns nothing, since workflow status names vary per project. List every matching ticket with its **clickable Jira link** (`https://<site>/browse/<KEY>`), summary, status, and assignee so the user can see exactly what's outstanding without having to go look it up themselves, and check `mcp__atlassian__getTransitionsForJiraIssue` for each to see whether a direct "Close as Done" / "Cancel Issue" / similar terminal transition exists. - **`-> Quality Gate`**: a SonarQube quality gate is failing on the release branch — link the user directly to the project's SonarQube quality gate page rather than guessing at a fix; this isn't something to auto-resolve. - **`-> Dependencies` / `-> Licenses` / `-> Manifest Values` / `-> Parent POM` / `-> GitHub`**: these indicate a code/config problem (outdated parent POM, license mismatch, manifest metadata) that needs a real code change — report which one failed, with a link to the releasability check run (`target_url` on the status) so the user can see the detail, and stop; don't attempt an automated fix for these. - **Other failing check-runs** (from the check-runs API call above, not the Releasability status itself): report the check name with a link to its GitHub Actions run/job (`.html_url` on the check-run) so the user can look at the logs directly; these are usually CI/build failures needing a real fix, not a quick toggle. For each fixable issue (mainly the Jira case), **suggest the concrete fix, with a link to the ticket, and ask for confirmation before acting** — e.g. "[SONARPLI-390](<jira-link>) is 'In Validation' and blocking release; transition it to Done?" — since transitioning a ticket or touching shared state is visible to others and should not happen silently. Use `mcp__atlassian__transitionJiraIssue` once confirmed, and share the ticket's link again in the confirmation of what was done. **After every fix is applied, don't assume it's reflected immediately** — the `Releasability` commit status is stale until it's recomputed. Find the job that posted it and re-run just that job, then re-poll the status before declaring victory: ```bash # The status's target_url points at the workflow run that posted it. Find the specific # job named "Releasability Check" (or similar) inside that run: gh run view <run-id-from-target_url> --repo <owner>/<repo> --json jobs \ --jq '.jobs[] | select(.name | test("Releasability"; "i"))' # Re-run just that job (not the whole pipeline): gh run rerun <run-id> --repo <owner>/<repo> --job <job-id> # Poll until it completes, then re-fetch the Releasability status (same command as above) # and confirm the description no longer mentions the fixed issue. ``` Repeat the diagnose → fix → confirm → re-run → re-check loop until releasability actually passes (description like `"passed releasability checks"`, not just `state == "success"` with a lingering "failed optional checks" description). Only then proceed to Step 3. ## Step 3 — Interview Using `AskUserQuestion`, ask for each `workflow_dispatch` input found in Step 1, in the order they appear in the YAML: - **`AskUserQuestion` requires ≥2 options per question — it errors out otherwise.** A required free-text input with no meaningful default (e.g. `short-description` on a repo where it has no YAML default) is not a valid multi-choice question. For these, either (a) skip `AskUserQuestion` entirely and just ask in plain text, or (b) derive a concrete draft value first — e.g. from the unreleased Jira ticket(s) for this project (see the derivation pattern used for `short-description` below) — and offer that draft as one option against a "type my own" option as the second. Don't send a single-option question; it fails validation and wastes a round trip. Batch the remaining genuinely-multi-choice inputs (booleans, branch, version) into one `AskUserQuestion` call rather than a call-per-input. - If a required free-text field like `short-description` has no natural default, consider proactively querying the project's unreleased Jira backlog (`project = <jira-project-key> AND fixVersion in unreleasedVersions() ORDER BY issuetype ASC, key ASC` via `mcp__atlassian__searchJiraIssuesUsingJql`) and drafting a summary from the ticket(s) found, rather than asking the user to write one from scratch or falling back to a generic placeholder — this is the same backlog Step 3's release-notes drafting already reads, so it's not extra API surface. - Show each input's description and default value so the user can accept a default with one click instead of retyping it. - Present boolean inputs as Yes/No with the YAML default pre-selected. - For `new-version` (or equivalent): explain it is the *next* Jira version to create after this release, **not** the version being released, and that leaving it blank lets the workflow increment the last component of the current Jira version (`2.1` → `2.2`). Passing the version being released is a trap: it normalizes to the version that was just released, so `create-jira-version` finds it already exists, skips creation, and returns the just-released version as the "next" one — which the bump-version job would then write back to the branch. Wrapper repos often still describe this input as "new version to release"; ignore that wording. - If the user sets `dry-run` (or `use-jira-sandbox`/`is-draft-release`) to `false`... actually, the important warning is the opposite: **if `dry-run` is left `true` or explicitly requested**, tell the user plainly that this is not a true no-op. It only affects the Jira sandbox and whether the GitHub release is a draft — the SQS/SQC/SQAA/bump-version pull requests are still created for real either way. Don't let "dry-run" imply nothing will happen outside GitHub. - If `sqs-integration` is enabled (default `true`), also ask which SQS release this analyzer version will ship with — this sets the `fixVersion` on the SONAR/SQS integration ticket that the workflow creates later (see Step 9). Ask this now, up front, rather than after the SQS PR merges — the skill's whole point is one confirmation before triggering, then walking away; asking mid-flight would reintroduce the exact interruption it's meant to avoid. Compute a default before asking, don't ask blind: query the Jira **SONAR** project's versions (`jira_client.project_versions()` — same pattern as `get-jira-release-notes/get_jira_release_notes.py`), filter to `released == false`, sort by `releaseDate` ascending, and take the first as "next SQS release" (names follow the `sqs-YYYY.N` convention, e.g. `sqs-2026.5`). Ask via `AskUserQuestion` with that default as the first option (labelled with its name and release date, e.g. "sqs-2026.5 (2026-09-21, next release) — default") and a free-text option to name a different version — "next" is a reasonable guess but not a guarantee, a change can miss a train and ship in a later one. Store the chosen version name; nothing is written to Jira yet — see Step 9. - For `release-notes`: if the user leaves it blank (accepting auto-generation by `get-jira-release-notes`), ask via `AskUserQuestion` (Yes/No) whether they'd like a short intro paragraph drafted ahead of the auto-generated issue list. The `release-notes` input is all-or-nothing — a non-blank value fully replaces auto-generation — so this only works by building the whole value here, not by asking the workflow to prepend anything: 1. If yes, fetch the same issues `get-jira-release-notes` would (`project = <jira-project-key> AND fixVersion = "<new-version>" ORDER BY issuetype ASC, key ASC` via `mcp__atlassian__searchJiraIssuesUsingJql`), using the `issue-categories` order from that repo's `automated-release.yml` `with:` block if it overrides the default (`Feature,False Positive,False Negative,Bug,Security,Maintenance`). 2. Draft a 1-2 sentence paragraph summarizing the release's theme from those issue summaries and the `short-description` already given, and show it to the user for approval/edit — one round of confirmation, same as everywhere else in this step. 3. Reproduce `get_jira_release_notes.py`'s `format_notes_as_markdown` structure exactly (`# Release notes - {project name} - {version}` header, then `### {category}` sections in order, each issue as `[KEY](jira-url/browse/KEY) summary`), inserting the approved paragraph directly under the header line. Use this full string as the `release-notes` value passed in Step 5. 4. If the user declines, leave `release-notes` blank — unchanged, auto-generated behavior. ## Step 4 — Summary and confirmation Show a concrete table of input → value (including defaults accepted silently) and the exact `gh workflow run` command that will be executed. If `sqs-integration` is enabled, include the SQS fixVersion chosen in Step 3 as its own row (e.g. `| SQS fixVersion (SONAR ticket) | sqs-2026.5 |`), and note that it will be applied automatically to the SONAR integration ticket once that ticket exists later in the run (Step 9) — with no further prompt for it. Also state plainly what happens *after* triggering: this skill will monitor the workflow to completion, then automatically approve and merge all resulting pull requests (bump-version, SQS, SQC, SQAA) as soon as each is green — with no further prompts in between, unless something fails or needs a judgment call (see Step 8's failure handling). Ask the user to confirm this whole flow once, up front, in plain language — triggering a release is a cross-repo, hard-to-reverse action, and the point of this skill is that one confirmation here is the only interaction needed; don't ask again before merging each PR later, or before setting the fixVersion in Step 9. ## Step 5 — Trigger Use the actual filename discovered in Step 1 (e.g. `AutomateRelease.yml`), not a hardcoded `automated-release.yml` — `gh workflow run` and `gh run list --workflow` both need the real filename or they'll silently match nothing / the wrong workflow. ```bash gh workflow run <actual-filename> --repo <owner>/<repo> --ref <branch> \ -f "<input>=<value>" ... ``` Conveniently, `gh workflow run` actually does print the run URL directly to stdout on recent `gh` versions — capture and share that; don't assume you need to construct one, but do construct `https://github.com/<owner>/<repo>/actions/workflows/<actual-filename>` as a fallback if the output is empty. Then resolve the run ID the same way `publish-github-release/action.yml` does: ```bash sleep 30 RUN_ID=$(gh run list --repo <owner>/<repo> --workflow <actual-filename> --limit 1 \ --created ">=$SINCE" --json databaseId --jq '.[0].databaseId') ``` Compute `SINCE` as "5 minutes ago" in UTC ISO-8601. `date` flags differ between macOS (`date -u -v-5M`) and GNU/Linux (`date -u -d '5 minutes ago'`) — detect which is available (`date -v-5M +%s >/dev/null 2>&1` succeeds on BSD/macOS date) and use the matching form, since this skill runs on a user's local machine, not just CI. If `RUN_ID` comes back empty, wait a bit longer and retry — don't fail immediately. ## Step 6 — Monitor the workflow run Poll every ~15 seconds. **Avoid the bash variable name `status`** in polling scripts — it's a read-only/special variable in some shells and assigning to it crashes the script with `read-only variable: status`; use `run_status`/`run_conclusion` instead. ```bash gh run view "$RUN_ID" --repo <owner>/<repo> --json status,conclusion ``` until `status == "completed"`. If `conclusion != "success"` (or `status` is `cancelled` or `failure`), don't stop immediately — first check whether the failure is a **real** problem or a **transient infra blip**, since the two need very different responses: 1. Run `gh run view "$RUN_ID" --repo <owner>/<repo> --log-failed` and read the actual error. 2. **Transient/infra signatures** — retry automatically without asking, since these are noise, not signal: - The `Check Releasability` job re-checking the exact commit SHA (this happens even though Step 2 already passed the pre-flight check — the workflow's own check is authoritative and re-runs independently, per Step 2's caveat) fails one specific sub-check with a network-level error rather than a real business-rule violation, e.g. `java.lang.IllegalStateException: java.io.IOException: Connection reset` on the `Jira` sub-check while every other sub-check (`QA`, `GitHub`, `ParentPOM`, `CheckDependencies`, `QualityGate`, etc.) passed. This is a dropped connection to the lambda backing that one check, not an actual unresolved-ticket problem — Step 2 already ruled that out. - Any other single-job failure whose log shows a connection/timeout/network error unrelated to the actual release logic. - In these cases: tell the user plainly what failed and why it looks transient (name the
GitHub에서 보기
이 SKILL.md는 매우 커서 SkillsMP가 여기에는 첫 섹션만 미리 보여줍니다. GitHub에서 보기