--- name: release description: Automates the full release process — analyzes changes, suggests version, updates CHANGELOG and pubspec.yaml, commits, tags, and pushes. --- # Release Process Automates everything from changelog update to git tag push. **Prerequisites:** - Working tree must be clean (`git status` shows no changes) - You should be on the branch you want to release from (usually `main`) - All changes should already be pushed and CI should be green --- ## Step 1: Preflight Checks Verify the working tree is clean and we're on the right branch: ```bash git status --porcelain git branch --show-current ``` If working tree is not clean, **STOP** and tell the user to commit or stash changes first. --- ## Step 2: Analyze Changes Since Last Release Find the last release tag and show what changed: ```bash # Last release tag (empty if first release) LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "") if [ -n "$LAST_TAG" ]; then echo "Last release: $LAST_TAG" echo "" echo "=== Commits since $LAST_TAG ===" git log "${LAST_TAG}..HEAD" --oneline echo "" echo "=== Stats ===" git diff --stat "${LAST_TAG}..HEAD" else echo "No previous releases found. This will be the first release." echo "" echo "=== All commits ===" git log --oneline -20 fi ``` --- ## Step 3: Read CHANGELOG [Unreleased] Read `CHANGELOG.md` and extract the `[Unreleased]` section to understand what's being released. Show the content to the user as a summary of what will be in the release notes. If the `[Unreleased]` section is empty, **STOP** and tell the user there's nothing to release — they should update the CHANGELOG first (use `/changelog-docs` skill). --- ## Step 4: Determine Version Read current version from `pubspec.yaml`: ```bash grep '^version:' pubspec.yaml ``` Calculate next build number: ```bash TAG_COUNT=$(git tag --list 'v*' | wc -l) NEXT_BUILD=$((TAG_COUNT + 1)) echo "Next build number: +${NEXT_BUILD}" ``` **SemVer rules (pre-1.0):** - `patch` (0.9.0 → 0.9.1): bug fixes, small improvements, minor tweaks - `minor` (0.9.0 → 0.10.0): new features, significant additions - `major` (0.9.0 → 1.0.0): stable release, breaking public API changes Analyze the [Unreleased] content and suggest a version bump type with reasoning. **Ask the user** using AskUserQuestion with options: - Option 1: Suggested version (with reasoning) - Option 2: Alternative version - Option 3: Other (user types custom version) Wait for user confirmation before proceeding. --- ## Step 5: Update CHANGELOG.md After user confirms version `X.Y.Z`: 1. Get today's date (format: YYYY-MM-DD) 2. In `CHANGELOG.md`, find the line `## [Unreleased]` 3. Insert a blank line after it, then add `## [X.Y.Z] - YYYY-MM-DD` 4. All existing content between `## [Unreleased]` and the new version header stays under the version header 5. The `## [Unreleased]` section should be left empty (no subsection headers) Result should look like: ```markdown ## [Unreleased] ## [0.9.0] - 2026-02-19 ### Added - ... ### Changed - ... ``` Use the Edit tool to make the changes precisely. --- ## Step 6: Bump Version in pubspec.yaml Update the `version:` line in `pubspec.yaml`: ``` version: X.Y.Z+N ``` Where `N` is the build number calculated in Step 4. Use the Edit tool to make the change. --- ## Step 6.5: Update Version on Landing Page Update the version in `docs/index.html` in two places: 1. **Hero badge** — find `vOLD` and replace with `vX.Y.Z` 2. **JSON-LD structured data** — find `"softwareVersion": "OLD"` and replace with `"softwareVersion": "X.Y.Z"` Use the Edit tool to make both changes. --- ## Step 7: Generate Release Notes Create **user-facing release notes** in English from the CHANGELOG `[X.Y.Z]` section. These notes will be used as the annotated tag message and will appear on the GitHub Release page. **Rules:** - **Bilingual:** First the full English section, then a horizontal rule `---`, then the full Russian section (NOT inline per-line translation) - Strip all file names, class names, and technical details (no `steam_import_service.dart`, no `collectionStatsProvider`) - Rewrite each entry as a short, clear sentence a user would understand - Group into: `## What's New`, `## Improvements`, `## Bug Fixes` (skip empty groups) - Russian section uses: `## Что нового`, `## Улучшения`, `## Исправления` - Use bullet points, no bold prefixes - Keep it concise: 1 line per feature, max 2 sentences for complex features - Add a footer: `**Full Changelog**: https://github.com/hacan359/tonkatsu_box/compare/vPREV...vX.Y.Z` **Example transformation:** CHANGELOG (technical): ``` ### Added - **Steam Library import** — new `SteamApi` client (`steam_api.dart`) fetches user's owned games... ``` Release notes (user-facing): ``` ## What's New - Import your Steam game library — games are automatically matched to IGDB with playtime tracking. --- ## Что нового - Импорт библиотеки Steam — игры автоматически привязываются к IGDB с отслеживанием времени. ``` **Show the generated release notes to the user** and ask for confirmation before proceeding. Save the release notes text for use in Step 8. --- ## Step 7.5: Create F-Droid / IzzyOnDroid Changelog IzzyOnDroid (and F-Droid) show a per-version "What's New" read from a plain-text file named after the **versionCode** — the build number `N` from Step 4, i.e. the same `N` as `pubspec.yaml` `X.Y.Z+N`. Create `fastlane/metadata/android/en-US/changelogs/N.txt`: - Plain text, **max 500 characters** (hard limit — Izzy skips longer files). - English only (this is the `en-US` locale file). - Condense the English user-facing notes from Step 7: a `vX.Y.Z` header line, then 2-5 bullets of the most important changes. - No markdown headers, no file/class names, no Russian. - **Do NOT** touch or rename older `changelogs/*.txt` — one file per release, they are immutable history. Example (`changelogs/35.txt`): ``` v0.39.0 * Import your Steam library with automatic IGDB matching. * New mood-grid export with custom captions. * Fixed crash when opening an empty collection. ``` Use the Write tool, then verify the byte count is under 500: ```bash wc -m < fastlane/metadata/android/en-US/changelogs/N.txt ``` --- ## Step 7.6: Overwrite assets/whats_new.md (in-app "What's new" dialog) The app shows `assets/whats_new.md` in a dialog on the first launch after an update (`lib/core/services/whats_new_service.dart`). The file always holds ONLY the current release's notes — **overwrite it completely** with the Write tool (not Edit): - First line: `# X.Y.Z` — must match the pubspec version **exactly**; the app only shows the section whose heading equals its own version. - Then the condensed English user-facing notes from Step 7: optionally a short `**bold**`-led intro paragraph for the headline feature, followed by `- ` bullets. - Mini-markdown only (`**bold**`, `*italic*`, `- ` bullets). No `##` headers, no file/class names, no links, no Russian. - Keep it one dialog tall: an intro + ~5-10 bullets max. --- ## Step 8: Commit, Tag, Push ```bash # Stage the changed files (N = build number from Step 4) git add pubspec.yaml CHANGELOG.md docs/index.html assets/whats_new.md \ "fastlane/metadata/android/en-US/changelogs/${N}.txt" # Create commit git commit -m "release: vX.Y.Z" # Create annotated tag with release notes (use HEREDOC for multiline) git tag -a "vX.Y.Z" -m "$(cat <<'EOF' Release vX.Y.Z EOF )" # Push commit and tag git push origin HEAD git push origin "vX.Y.Z" ``` --- ## Step 9: Report Tell the user: - Commit created with hash - Tag `vX.Y.Z` pushed - GitHub Actions release workflow is now running - It will: run quality gate → build Windows + Android → create GitHub Release with artifacts - They can monitor progress at the repository's Actions tab --- ## Important Notes - **Never skip** the user confirmation step (Step 4) - **Never run** this skill if the working tree is dirty - If the quality-gate fails in CI after push, the release artifacts won't be built — the user should fix issues and create a new patch release - The skill does NOT run `flutter analyze` or `flutter test` locally — CI handles that - Build number is sequential: count of existing `v*` tags + 1 - **Every release must add** `fastlane/metadata/android/en-US/changelogs/N.txt` (Step 7.5) — IzzyOnDroid reads it as the version's "What's New"; a missing file means no changelog shown for that build - **Every release must overwrite** `assets/whats_new.md` (Step 7.6) — the in-app "What's new" dialog shows it after the update; a stale version heading means the dialog silently never appears for the new version