From 01d23f5f4346fb75ef29dda4c6466f5d599f4e3e Mon Sep 17 00:00:00 2001 From: Ovi Trif Date: Sun, 29 Mar 2026 17:13:33 +0200 Subject: [PATCH 1/5] chore: add changelog for release notes Co-Authored-By: Claude Opus 4.6 (1M context) --- .claude/commands/pr.md | 7 +++++++ .claude/commands/release.md | 19 ++++++++++++++++--- .cursor/rules/rules.main.mdc | 10 ++++++++++ .github/pull_request_template.md | 1 + AGENTS.md | 9 +++++++++ CHANGELOG.md | 10 ++++++++++ 6 files changed, 53 insertions(+), 3 deletions(-) create mode 100644 CHANGELOG.md diff --git a/.claude/commands/pr.md b/.claude/commands/pr.md index 8bc662c94..781daf940 100644 --- a/.claude/commands/pr.md +++ b/.claude/commands/pr.md @@ -186,6 +186,13 @@ gh pr create --base $base --title "..." --body "..." [--draft] - Instruct the user to drag-and-drop each media file into the Preview section via the GitHub web UI - Note: GitHub does not support programmatic media upload to PR bodies +### 8b. Backfill Changelog PR Number + +If the PR was created (not dry run) and `CHANGELOG.md` was modified in the branch (`git diff $base...HEAD --name-only | grep CHANGELOG.md`): +- Read `CHANGELOG.md` and scan `## [Unreleased]` entries for lines missing a `(#NUMBER)` suffix +- Append the actual PR number to those entries, e.g. `- Add foo` becomes `- Add foo (#123)` +- If any entries were updated, amend the last commit and force-push + ### 9. Output Summary **If PR created:** diff --git a/.claude/commands/release.md b/.claude/commands/release.md index e8e9b641d..861f75c1c 100644 --- a/.claude/commands/release.md +++ b/.claude/commands/release.md @@ -53,6 +53,19 @@ If "Previous tag": ask `"Which tag?"` with a text input (default: `v{oldVersionN If "master" or if the release is minor/major: `{baseRef} = master`. +### 2c. Finalize Changelog + +Read `CHANGELOG.md` and check whether `## [Unreleased]` has any entries beneath it. + +**If entries exist:** +1. Replace `## [Unreleased]` with `## [{newVersionName}] - {YYYY-MM-DD}` (today's date) +2. Insert a fresh empty `## [Unreleased]` section above the new version heading +3. Update the compare link references at the bottom of the file: + - Change `[Unreleased]` link to compare from `v{newVersionName}...HEAD` + - Add a new `[{newVersionName}]` link comparing `v{oldVersionName}...v{newVersionName}` + +**If no entries:** Print `⚠ CHANGELOG.md has no unreleased entries — continuing without changelog update.` and proceed. + ### 3. Create Release Branch & Bump Version ```bash @@ -78,7 +91,7 @@ Edit `app/build.gradle.kts`: - Change `versionName = "{old}"` to `versionName = "{newVersionName}"` ```bash -git add app/build.gradle.kts +git add app/build.gradle.kts CHANGELOG.md git commit -m "chore: version {newVersionName}" git push -u origin release-{newVersionName} ``` @@ -131,13 +144,13 @@ gh release create v{newVersionName} \ ### 6. Generate Store Release Notes -Fetch the auto-generated release notes from the draft release: +Read the `## [{newVersionName}]` section from `CHANGELOG.md` as the primary source for release content. If that section is empty or was not created in Step 2c, fall back to fetching auto-generated release notes: ```bash gh release view v{newVersionName} --json body --jq .body ``` -Using those notes as context, write a concise user-facing summary of the release (2-3 sentences max, no commit hashes or PR numbers, written for end users not developers). Focus on new features and important bug fixes. Omit chores, maintenance, refactoring, CI changes, and test coverage improvements — these are not relevant to Play Store users. Translate the summary into 5 languages. +Using the changelog entries (or auto-generated notes as fallback) as context, write a concise user-facing summary of the release (2-3 sentences max, no commit hashes or PR numbers, written for end users not developers). Focus on new features and important bug fixes. Omit chores, maintenance, refactoring, CI changes, and test coverage improvements — these are not relevant to Play Store users. Translate the summary into 5 languages. Create `.ai/` directory if it doesn't exist. Save to `.ai/release-notes-{newVersionName}.md`: diff --git a/.cursor/rules/rules.main.mdc b/.cursor/rules/rules.main.mdc index fe903e7c2..a2292eb71 100644 --- a/.cursor/rules/rules.main.mdc +++ b/.cursor/rules/rules.main.mdc @@ -62,6 +62,16 @@ alwaysApply: true --- +## Changelog rules: +- add an entry under `## [Unreleased]` in `CHANGELOG.md` for `feat:` and `fix:` PRs; skip for `chore:`, `ci:`, `refactor:`, `test:`, `docs:` unless the change is user-facing +- use standard Keep a Changelog categories: `### Added`, `### Changed`, `### Deprecated`, `### Removed`, `### Fixed`, `### Security` +- append `(#PR_NUMBER)` at the end of each changelog entry when the PR number is known +- place new entries at the bottom of their category section +- never modify released version sections — only edit `## [Unreleased]` +- create category headings on demand (don't add empty stubs) + +--- + ## Rules for Android Unit tests and Instrumentation tests: - run unit tests for specific files like this: `./gradlew :app:testDevDebugUnitTest --tests "to.bitkit.repositories.LightningRepoTest"` - write unit tests in the same style and using same libraries as: `CurrencyRepoTest`, `LightningRepoTest`, `WalletRepoTest` diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 79350fd1d..cfd4a327f 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,4 +1,5 @@ + ### Description diff --git a/AGENTS.md b/AGENTS.md index 46af00cd0..cb514cc1f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -237,6 +237,15 @@ suspend fun getData(): Result = withContext(Dispatchers.IO) { - ALWAYS use `.toImmutableList()`, `.toImmutableMap()`, `.toImmutableSet()` when producing collections for UI state - ALWAYS use `persistentListOf()`, `persistentMapOf()`, `persistentSetOf()` for default values in UiState fields +### Changelog + +- ALWAYS add an entry under `## [Unreleased]` in `CHANGELOG.md` for `feat:` and `fix:` PRs; skip for `chore:`, `ci:`, `refactor:`, `test:`, `docs:` unless the change is user-facing +- USE standard Keep a Changelog categories: `### Added`, `### Changed`, `### Deprecated`, `### Removed`, `### Fixed`, `### Security` +- ALWAYS append `(#PR_NUMBER)` at the end of each changelog entry when the PR number is known +- ALWAYS place new entries at the bottom of their category section +- NEVER modify released version sections — only edit `## [Unreleased]` +- ALWAYS create category headings on demand (don't add empty stubs) + ### Device Debugging (adb) - App IDs per flavor: `to.bitkit.dev` (dev/regtest), `to.bitkit.tnet` (testnet), `to.bitkit` (mainnet) diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 000000000..358ebc984 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,10 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +[Unreleased]: https://github.com/synonymdev/bitkit-android/compare/v2.1.2...HEAD From 6245c4d9ff9324f995c9918f4db1fcf5b38489d5 Mon Sep 17 00:00:00 2001 From: Ovi Trif Date: Mon, 30 Mar 2026 14:13:57 +0200 Subject: [PATCH 2/5] chore: review Co-Authored-By: Claude Opus 4.6 (1M context) --- .claude/commands/pr.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.claude/commands/pr.md b/.claude/commands/pr.md index 781daf940..1c22bbdf7 100644 --- a/.claude/commands/pr.md +++ b/.claude/commands/pr.md @@ -191,7 +191,7 @@ gh pr create --base $base --title "..." --body "..." [--draft] If the PR was created (not dry run) and `CHANGELOG.md` was modified in the branch (`git diff $base...HEAD --name-only | grep CHANGELOG.md`): - Read `CHANGELOG.md` and scan `## [Unreleased]` entries for lines missing a `(#NUMBER)` suffix - Append the actual PR number to those entries, e.g. `- Add foo` becomes `- Add foo (#123)` -- If any entries were updated, amend the last commit and force-push +- If any entries were updated, create a new commit with message `chore: backfill changelog pr number` and push ### 9. Output Summary From 72ce8cc351dee7ebdf5b7b614efea2010cf3eeba Mon Sep 17 00:00:00 2001 From: Ovi Trif Date: Mon, 30 Mar 2026 14:28:11 +0200 Subject: [PATCH 3/5] chore: review 2 Co-Authored-By: Claude Opus 4.6 (1M context) --- .claude/commands/release.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.claude/commands/release.md b/.claude/commands/release.md index 861f75c1c..6cd2cdf63 100644 --- a/.claude/commands/release.md +++ b/.claude/commands/release.md @@ -91,11 +91,14 @@ Edit `app/build.gradle.kts`: - Change `versionName = "{old}"` to `versionName = "{newVersionName}"` ```bash -git add app/build.gradle.kts CHANGELOG.md +git add app/build.gradle.kts +# Only stage CHANGELOG.md if step 2c modified it (i.e. unreleased entries were found) git commit -m "chore: version {newVersionName}" git push -u origin release-{newVersionName} ``` +If step 2c updated `CHANGELOG.md`, also `git add CHANGELOG.md` before the commit. + ### 4. Create Version Bump PR Read `.github/pull_request_template.md` for structure. Create PR: From 1c1989e2a9ff8ef7de43dcdd40e39b9e714c6bca Mon Sep 17 00:00:00 2001 From: Ovi Trif Date: Mon, 30 Mar 2026 14:32:35 +0200 Subject: [PATCH 4/5] chore: review 3 Co-Authored-By: Claude Opus 4.6 (1M context) --- .claude/commands/pr.md | 4 ++-- .cursor/rules/rules.main.mdc | 2 +- AGENTS.md | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.claude/commands/pr.md b/.claude/commands/pr.md index 1c22bbdf7..d99c0eed9 100644 --- a/.claude/commands/pr.md +++ b/.claude/commands/pr.md @@ -189,8 +189,8 @@ gh pr create --base $base --title "..." --body "..." [--draft] ### 8b. Backfill Changelog PR Number If the PR was created (not dry run) and `CHANGELOG.md` was modified in the branch (`git diff $base...HEAD --name-only | grep CHANGELOG.md`): -- Read `CHANGELOG.md` and scan `## [Unreleased]` entries for lines missing a `(#NUMBER)` suffix -- Append the actual PR number to those entries, e.g. `- Add foo` becomes `- Add foo (#123)` +- Read `CHANGELOG.md` and scan `## [Unreleased]` entries for lines missing a `#NUMBER` suffix +- Append the actual PR number to those entries, e.g. `- Add foo` becomes `- Add foo #123` - If any entries were updated, create a new commit with message `chore: backfill changelog pr number` and push ### 9. Output Summary diff --git a/.cursor/rules/rules.main.mdc b/.cursor/rules/rules.main.mdc index a2292eb71..fb3f06686 100644 --- a/.cursor/rules/rules.main.mdc +++ b/.cursor/rules/rules.main.mdc @@ -65,7 +65,7 @@ alwaysApply: true ## Changelog rules: - add an entry under `## [Unreleased]` in `CHANGELOG.md` for `feat:` and `fix:` PRs; skip for `chore:`, `ci:`, `refactor:`, `test:`, `docs:` unless the change is user-facing - use standard Keep a Changelog categories: `### Added`, `### Changed`, `### Deprecated`, `### Removed`, `### Fixed`, `### Security` -- append `(#PR_NUMBER)` at the end of each changelog entry when the PR number is known +- append `#PR_NUMBER` at the end of each changelog entry when the PR number is known - place new entries at the bottom of their category section - never modify released version sections — only edit `## [Unreleased]` - create category headings on demand (don't add empty stubs) diff --git a/AGENTS.md b/AGENTS.md index cb514cc1f..998a7ab03 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -241,7 +241,7 @@ suspend fun getData(): Result = withContext(Dispatchers.IO) { - ALWAYS add an entry under `## [Unreleased]` in `CHANGELOG.md` for `feat:` and `fix:` PRs; skip for `chore:`, `ci:`, `refactor:`, `test:`, `docs:` unless the change is user-facing - USE standard Keep a Changelog categories: `### Added`, `### Changed`, `### Deprecated`, `### Removed`, `### Fixed`, `### Security` -- ALWAYS append `(#PR_NUMBER)` at the end of each changelog entry when the PR number is known +- ALWAYS append `#PR_NUMBER` at the end of each changelog entry when the PR number is known - ALWAYS place new entries at the bottom of their category section - NEVER modify released version sections — only edit `## [Unreleased]` - ALWAYS create category headings on demand (don't add empty stubs) From 4da4bd854dd3cef5d9e7ef944eff12ee044b28f1 Mon Sep 17 00:00:00 2001 From: Ovi Trif Date: Mon, 30 Mar 2026 14:36:13 +0200 Subject: [PATCH 5/5] chore: review 4 Co-Authored-By: Claude Opus 4.6 (1M context) --- .cursor/rules/rules.main.mdc | 2 +- AGENTS.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.cursor/rules/rules.main.mdc b/.cursor/rules/rules.main.mdc index fb3f06686..b09f345ff 100644 --- a/.cursor/rules/rules.main.mdc +++ b/.cursor/rules/rules.main.mdc @@ -66,7 +66,7 @@ alwaysApply: true - add an entry under `## [Unreleased]` in `CHANGELOG.md` for `feat:` and `fix:` PRs; skip for `chore:`, `ci:`, `refactor:`, `test:`, `docs:` unless the change is user-facing - use standard Keep a Changelog categories: `### Added`, `### Changed`, `### Deprecated`, `### Removed`, `### Fixed`, `### Security` - append `#PR_NUMBER` at the end of each changelog entry when the PR number is known -- place new entries at the bottom of their category section +- place new entries at the top of their category section (newest first) - never modify released version sections — only edit `## [Unreleased]` - create category headings on demand (don't add empty stubs) diff --git a/AGENTS.md b/AGENTS.md index 998a7ab03..7813c3116 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -242,7 +242,7 @@ suspend fun getData(): Result = withContext(Dispatchers.IO) { - ALWAYS add an entry under `## [Unreleased]` in `CHANGELOG.md` for `feat:` and `fix:` PRs; skip for `chore:`, `ci:`, `refactor:`, `test:`, `docs:` unless the change is user-facing - USE standard Keep a Changelog categories: `### Added`, `### Changed`, `### Deprecated`, `### Removed`, `### Fixed`, `### Security` - ALWAYS append `#PR_NUMBER` at the end of each changelog entry when the PR number is known -- ALWAYS place new entries at the bottom of their category section +- ALWAYS place new entries at the top of their category section (newest first) - NEVER modify released version sections — only edit `## [Unreleased]` - ALWAYS create category headings on demand (don't add empty stubs)