| name | release-kaos |
| description | Execute a full KAOS release. Use this skill when asked to release a new version of KAOS. The user provides the target version (e.g., v0.5.0) in their prompt. This skill handles pre-flight checks, release creation, CI monitoring, artifact validation, smoke testing, and post-release cleanup. |
| allowed-tools | shell |
Release KAOS
Execute a full release of KAOS. The user provides the target version (e.g., v0.5.0) in their prompt.
Step 1: Extract Version
Extract the version from the user's prompt. It should match vX.Y.Z format. Store as VERSION (with v prefix) and VERSION_NUM (without prefix).
Step 2: Pre-Flight Checks
Run ALL of these checks before proceeding. Stop and report if any fail.
git checkout main && git pull
git status --porcelain
gh run list --branch main --limit 3 --json conclusion,name
git tag -l "$VERSION"
Step 3: Generate and Review Release Notes
Generate GitHub's release notes before creating the release, then review them and write a semantic overview. The final release notes must keep the generated PR changelog, but they must start with a human-readable summary of what changed and why it matters.
GENERATED_NOTES="$(mktemp)"
RELEASE_NOTES="$(mktemp)"
gh api "repos/axsaucedo/kaos/releases/generate-notes" \
-f tag_name="$VERSION" \
-f target_commitish=main \
--jq .body > "$GENERATED_NOTES"
cat "$GENERATED_NOTES"
git log --oneline "$(git describe --tags --abbrev=0 origin/main 2>/dev/null || echo HEAD~50)"..origin/main
Write a concise semantic overview in $RELEASE_NOTES:
## Overview
Summarize the release as a coherent product/update narrative, not as a PR list.
## Highlights
- Group related work by user-visible outcome or operational impact.
- Mention compatibility, migration, or validation notes when relevant.
## Generated changelog
<paste the generated notes here unchanged, except for obvious duplicate headings>
If the generated notes are sparse, use merged PR titles, commit messages, docs, and changed files to infer the overview. Do not invent claims that cannot be supported by the release contents.
Step 4: Create the Release
Create the release using the reviewed release notes:
gh release create "$VERSION" --target main --title "$VERSION" --notes-file "$RELEASE_NOTES"
This triggers .github/workflows/release.yaml which runs ~28 jobs.
Step 5: Monitor CI Pipeline
Poll the release workflow until ALL jobs complete. Do NOT stop until every job succeeds or fails.
gh run list --workflow=release.yaml --limit 3 --json databaseId,status,conclusion
gh run view <RUN_ID> --json jobs --jq '.jobs[] | "\(.name): \(.status) \(.conclusion)"'
Expected jobs: validate, tests (3 E2E shards + unit), build-images, build-helm, publish-python, publish-pydantic-ai-server, publish-docs, deploy-ui, create-release, release-standalone-repos, bump-version.
If any job fails: investigate logs with gh run view <RUN_ID> --log-failed, diagnose, fix, and re-trigger if needed.
Step 6: Validate All Artifacts
Check EVERY artifact. Report status for each.
docker pull axsauze/kaos-operator:$VERSION_NUM
docker pull axsauze/kaos-agent:$VERSION_NUM
docker pull axsauze/kaos-mcp-python-string:$VERSION_NUM
pip install kaos-cli==$VERSION_NUM
pip install pydantic-ai-server==$VERSION_NUM
curl -sI https://axsaucedo.github.io/kaos/v$VERSION_NUM/ | head -5
curl -sI https://axsaucedo.github.io/kaos/latest/ | head -5
curl -sI https://axsaucedo.github.io/kaos/dev/ | head -5
curl -sI https://axsaucedo.github.io/kaos-ui/v$VERSION_NUM/ | head -5
curl -sI https://axsaucedo.github.io/kaos-ui/latest/ | head -5
helm repo add kaos https://axsaucedo.github.io/kaos/charts/ 2>/dev/null || helm repo update kaos
helm search repo kaos/kaos-operator --versions | head -5
gh release view $VERSION --json assets,body | head -20
gh release view $VERSION --repo axsaucedo/pydantic-ai-server 2>&1 | head -5
gh release view $VERSION --repo axsaucedo/kaos-ui 2>&1 | head -5
Step 7: Docs Race Condition Check
If docs pages return 404, a race condition may have occurred between release.yaml and docs.yaml deployments:
gh workflow run rebuild-docs.yaml -f version=$VERSION_NUM
Step 8: Smoke Test on KIND Cluster (if available)
If a KIND cluster is available, upgrade and test:
helm upgrade kaos kaos/kaos-operator --version $VERSION_NUM -n kaos-system \
--set controllerManager.manager.image.tag=$VERSION_NUM \
--set defaultImages.agentRuntime=axsauze/kaos-agent:$VERSION_NUM \
--set defaultImages.mcpPythonString=axsauze/kaos-mcp-python-string:$VERSION_NUM \
--reuse-values
kubectl get deployment kaos-kaos-operator-controller-manager -n kaos-system \
-o jsonpath='{.spec.template.spec.containers[0].image}'
Step 9: Merge Version Bump PR
The release pipeline creates an automated PR to bump VERSION to the next dev version. Find and merge it:
gh pr list --search "bump" --json number,title
gh pr merge <PR_NUMBER> --merge
Step 10: Maintain Historical Release Notes
When asked to update historical release notes, apply the same format to existing releases:
- List releases in tag order with
gh release list --limit 100.
- For each release, inspect the current body with
gh release view <tag> --json body.
- Compare the tag with the previous release tag using
git log <previous>..<tag> --oneline and, where possible, merged PRs from the generated changelog.
- Edit the release body so it starts with
## Overview, has grouped semantic highlights, and preserves the original/generated PR changelog under ## Generated changelog.
- If there is not enough evidence for a meaningful summary, say so briefly in the overview instead of inventing details.
Use gh release edit <tag> --notes-file <file> for each update. Retain existing assets and release metadata.
Step 11: Final Report
Print a summary table of all artifacts and their status:
| Artifact | Status |
|---|
| Docker images (3) | ✅/❌ |
| PyPI: kaos-cli | ✅/❌ |
| PyPI: pydantic-ai-server | ✅/❌ |
| Docs: version page | ✅/❌ |
| Docs: /latest/ | ✅/❌ |
| Docs: /dev/ | ✅/❌ |
| UI: version page | ✅/❌ |
| Helm chart | ✅/❌ |
| GitHub Release | ✅/❌ |
| Standalone repos | ✅/❌ |
| Bump PR merged | ✅/❌ |
Troubleshooting Reference
- PyPI OIDC error: Verify workflow filename in PyPI trusted publisher config matches
release.yaml exactly; verify pypi environment exists
- Docker push fails: Check
DOCKERHUB_USERNAME / DOCKERHUB_TOKEN secrets
- Standalone repo fails: Check
CROSS_REPO_TOKEN has repo scope
- Helm chart missing from release:
build-helm must complete before create-release
- Helm upgrade uses old images:
defaultImages uses flat strings; --reuse-values keeps old tags — always set explicitly