From 5b8373d1e14d1a701bfd07fbcb278d74fb9617ed Mon Sep 17 00:00:00 2001 From: auricom <27022259+auricom@users.noreply.github.com> Date: Mon, 19 Jan 2026 15:48:59 +0100 Subject: [PATCH 1/6] ci: release process with changelog --- .github/workflows/release.yml | 121 +++++++++++ RELEASE.md | 388 +++++++++++++++++++++++++++++++--- 2 files changed, 477 insertions(+), 32 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ed45e0600b..b924ed251a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -5,7 +5,80 @@ on: - '**/v*.*.*' # Matches tags like evm/single/v0.2.0, testapp/v0.4.0, etc. permissions: {} + jobs: + generate-changelog: + name: Generate Changelog and Create Release Branch + runs-on: ubuntu-latest + permissions: + contents: write + outputs: + changelog: ${{ steps.cliff.outputs.content }} + release-branch: ${{ steps.create-branch.outputs.branch-name }} + steps: + - name: Checkout code + uses: actions/checkout@v6 + with: + fetch-depth: 0 # Full history needed for changelog generation + + - name: Install git-cliff + uses: taiki-e/install-action@v2 + with: + tool: git-cliff + + - name: Generate changelog + id: cliff + run: | + # Generate changelog from CHANGELOG.md for this release + CHANGELOG_CONTENT=$(git cliff --unreleased --strip all) + + # Save to file and output + echo "$CHANGELOG_CONTENT" > RELEASE_CHANGELOG.md + echo "Generated changelog:" + cat RELEASE_CHANGELOG.md + + # Export for GitHub Release (escape for multiline output) + { + echo 'content<> $GITHUB_OUTPUT + + - name: Create release branch + id: create-branch + run: | + TAG="${{ github.ref_name }}" + BRANCH_NAME="release/$TAG" + + echo "Creating release branch: $BRANCH_NAME" + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + + git checkout -b "$BRANCH_NAME" + + # Update CHANGELOG.md with the generated content + if [ -f "CHANGELOG.md" ]; then + # Add generated changelog to CHANGELOG.md + cat RELEASE_CHANGELOG.md >> CHANGELOG_RELEASE_NOTES.md + echo "Changelog prepared for release: $TAG" >> CHANGELOG_RELEASE_NOTES.md + fi + + # Commit the changelog + git add -A + if git diff --staged --quiet; then + echo "No changes to commit" + else + git commit -m "chore: prepare release $TAG" \ + -m "Generated changelog for $TAG release." \ + -m "This is an automated commit created by the release workflow." + fi + + # Push the branch + git push origin "$BRANCH_NAME" + + echo "branch-name=$BRANCH_NAME" >> $GITHUB_OUTPUT + echo "::notice::Created release branch: $BRANCH_NAME" + parse-tag: name: Parse Release Tag runs-on: ubuntu-latest @@ -85,3 +158,51 @@ jobs: tags: | ghcr.io/${{ github.repository_owner }}/${{ needs.parse-tag.outputs.image-name }}:${{ needs.parse-tag.outputs.version }} ghcr.io/${{ github.repository_owner }}/${{ needs.parse-tag.outputs.image-name }}:latest + + create-github-release: + name: Create GitHub Release + needs: [generate-changelog, parse-tag, build-and-push] + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - name: Create GitHub Release + uses: softprops/action-gh-release@v2 + with: + draft: true + name: ${{ github.ref_name }} + tag_name: ${{ github.ref_name }} + body: | + ## ${{ needs.parse-tag.outputs.image-name }} ${{ needs.parse-tag.outputs.version }} + + **⚠️ This is a draft release. Please update the following before publishing:** + + - [ ] Add **Upgrade Priority** (Critical/High/Medium/Low) + - [ ] Add **General Description** of the release + - [ ] Review and refine the **Changelog** below + - [ ] Document **Tested Upgrade Paths** (which versions were tested in E2E) + - [ ] Verify Docker images are available + - [ ] Publish announcements in Slack and Telegram after publishing + + --- + + ### Changelog + + ${{ needs.generate-changelog.outputs.changelog }} + + --- + + ### Docker Images + + ```bash + docker pull ghcr.io/${{ github.repository_owner }}/${{ needs.parse-tag.outputs.image-name }}:${{ needs.parse-tag.outputs.version }} + docker pull ghcr.io/${{ github.repository_owner }}/${{ needs.parse-tag.outputs.image-name }}:latest + ``` + + ### Release Branch + + A release branch has been created for your review: `${{ needs.generate-changelog.outputs.release-branch }}` + + You can checkout this branch to make edits to the changelog before merging. + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/RELEASE.md b/RELEASE.md index fd11b700ca..94f8814a3e 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -7,6 +7,232 @@ This document covers the release process for ev-node components: --- +## Support Policy + +**Version Support:** +- We provide support for **two major versions** (current and previous) +- Supported versions receive: + - Security fixes + - Critical bug fixes +- Older versions are considered end-of-life and will not receive updates + +**Example:** +- If current version is v2.x.x, we support v2.x.x and v1.x.x +- When v3.0.0 is released, v1.x.x reaches end-of-life + +--- + +## Release Workflow Overview + +### Automated Steps + +When a SemVer-compliant tag is pushed (matching pattern `**/v*.*.*`), the GitHub workflow automatically: + +1. ✅ Creates a new branch `release/` from the tagged commit +2. ✅ Generates changelog from `./CHANGELOG.md` using [git-cliff](https://github.com/orhun/git-cliff) +3. ✅ Commits the generated changelog to the release branch +4. ✅ Builds multi-platform Docker images (amd64, arm64) +5. ✅ Publishes images to GitHub Container Registry (GHCR) +6. ✅ Creates a draft GitHub Release with the generated changelog + +### Manual Steps + +After the automated workflow completes: + +1. 📝 Review the release branch `release/` +2. 📝 Edit and refine the generated changelog if needed +3. 📝 Add **recommended upgrade priority** (Critical/High/Medium/Low) +4. 📝 Add **general description** of the release +5. 📝 Ensure **tested upgrade paths** are documented (1-2 lines in changelog) +6. ✅ Merge the release branch or update the GitHub Release directly +7. ✅ Publish the GitHub Release (change from draft to published) +8. 📢 Publish announcement message in **public Slack channel** +9. 📢 Publish announcement message in **public Telegram channel** + +### Release Priority Guidelines + +When adding upgrade priority to releases, use these guidelines: + +- **Critical**: Security vulnerabilities, data loss bugs, or breaking issues requiring immediate upgrade +- **High**: Important bug fixes, significant performance improvements, or recommended features +- **Medium**: Regular feature releases, minor bug fixes, general improvements +- **Low**: Optional features, documentation updates, or non-critical enhancements + +--- + +## Changelog Management + +### Overview + +- **Source of Truth**: GitHub Releases (manually curated) +- **Base Document**: `./CHANGELOG.md` (maintained in repository) +- **Generation Tool**: [git-cliff](https://github.com/orhun/git-cliff) + +### Changelog Workflow + +The release workflow automatically generates changelogs from `./CHANGELOG.md`: + +1. When you push a tag, the workflow reads `./CHANGELOG.md` +2. Generates formatted release notes using git-cliff +3. Creates a new branch `release/` +4. Commits the generated changelog to this branch +5. Creates a draft GitHub Release with the changelog + +**You can then:** +- Review the release branch and edit the changelog +- Refine the generated content +- Add additional context, upgrade instructions, or breaking changes +- Merge the branch or update GitHub Release directly + +### Maintaining CHANGELOG.md + +Follow these best practices for maintaining `./CHANGELOG.md`: + +**Format:** + +```markdown +# Changelog + +All notable changes to this project will be documented in this file. + +## [Unreleased] + +### Added +- New feature X +- New feature Y + +### Changed +- Modified behavior of Z + +### Fixed +- Bug fix for issue #123 + +### Security +- Security patch for vulnerability ABC + +### Tested Upgrades +- Tested: v0.2.x → v0.3.0 +- Tested: v0.1.5 → v0.3.0 (multi-version jump) + +## [0.3.0] - 2026-01-15 + +### Added +- Feature A +- Feature B + +### Fixed +- Critical bug C + +### Tested Upgrades +- Tested: v0.2.3 → v0.3.0 +``` + +**Categories:** +- **Added**: New features +- **Changed**: Changes to existing functionality +- **Deprecated**: Features marked for removal +- **Removed**: Removed features +- **Fixed**: Bug fixes +- **Security**: Security-related changes +- **Tested Upgrades**: 1-2 lines documenting which upgrade paths were tested in E2E tests + +**Important:** Always include **Tested Upgrades** section in the changelog for each release, documenting which version upgrade paths were validated through E2E testing. + +### Commit Message Best Practices + +While the changelog is based on `./CHANGELOG.md`, following conventional commit messages helps with project organization: + +**Examples:** + +```bash +feat(evm): add support for blob transactions +fix(da): resolve namespace collision in batch submission +docs: update installation guide +perf(block): optimize block validation pipeline +``` + +**Breaking Changes:** + +Mark breaking changes prominently in CHANGELOG.md: + +```markdown +### Changed +- **BREAKING**: Sequencer interface now requires context parameter +``` + +--- + +## Communication and Announcements + +### GitHub Releases + +**GitHub Releases** are the official source of truth for all releases. + +Each release should include: +- Version number and tag +- **Upgrade Priority**: Critical/High/Medium/Low +- **General Description**: Overview of the release +- **Changelog**: Generated and curated list of changes +- **Tested Upgrade Paths**: 1-2 lines from CHANGELOG.md +- **Breaking Changes**: Highlighted prominently (if any) +- **Installation Instructions**: Links to documentation +- **Known Issues**: Any outstanding issues (if applicable) + +### Slack Announcements + +After publishing a GitHub Release, post an announcement to the **public Slack channel**: + +**Template:** + +``` +🚀 **ev-node v0.3.0 Released** + +Upgrade Priority: [Medium] + +This release includes [brief description]. + +Key highlights: +• Feature X +• Bug fix Y +• Performance improvement Z + +Tested upgrade paths: v0.2.x → v0.3.0 + +📦 Release notes: https://github.com/evstack/ev-node/releases/tag/v0.3.0 +📚 Documentation: https://docs.evstack.io + +Docker images: +• ghcr.io/evstack/ev-node-evm:v0.3.0 +``` + +### Telegram Announcements + +Post the same announcement to the **public Telegram channel**: + +**Template:** + +``` +🚀 ev-node v0.3.0 Released + +⚡ Upgrade Priority: Medium + +This release includes [brief description]. + +Key highlights: +✅ Feature X +✅ Bug fix Y +✅ Performance improvement Z + +Tested upgrade paths: v0.2.x → v0.3.0 + +Release notes: https://github.com/evstack/ev-node/releases/tag/v0.3.0 +Documentation: https://docs.evstack.io + +Docker: ghcr.io/evstack/ev-node-evm:v0.3.0 +``` + +--- + ## Docker Image Releases (Automated) ### When to Use @@ -17,43 +243,58 @@ Release deployable applications (EVM nodes, test apps, etc.) as Docker images. ```bash # 1. Ensure CI passes on main -# 2. Create and push tag -git tag evm/single/v0.2.0 -git push origin evm/single/v0.2.0 +# 2. Update CHANGELOG.md with release notes (including tested upgrade paths) +# 3. Create and push tag +git tag evm/v0.2.0 +git push origin evm/v0.2.0 -# 3. Monitor workflow +# 4. Monitor workflow # GitHub → Actions → Release workflow -# 4. Verify release -docker pull ghcr.io/evstack/ev-node-evm:v0.2.0 +# 5. Review release branch (release/evm/v0.2.0) +git checkout release/evm/v0.2.0 +# Edit generated changelog if needed +git commit -am "Refine release notes" +git push + +# 6. Complete GitHub Release (add priority, description) +# 7. Publish the release +# 8. Announce in Slack and Telegram ``` ### Tag Format -Use the hierarchical tag format: `{app-path}/v{major}.{minor}.{patch}` +Use the tag format: `{app-name}/v{major}.{minor}.{patch}` + +The tag name corresponds to the app directory at `./apps/{app-name}/` **Examples:** -- `apps/evm/v0.2.0` → Releases `apps/evm/` -- `apps/testapp/v1.0.0` → Releases `apps/testapp/` -- `apps/grpc/v2.1.3` → Releases `apps/grpc/` +- `evm/v0.2.0` → Releases `./apps/evm/` +- `testapp/v1.0.0` → Releases `./apps/testapp/` +- `grpc/v2.1.3` → Releases `./apps/grpc/` + +**Note:** Tags do NOT include the "apps/" prefix, even though app directories are located at `./apps//` ### Automated Process When you push a tag, the release workflow automatically: 1. ✅ Validates tag format and app directory structure -2. ✅ Builds multi-platform Docker image (amd64, arm64) -3. ✅ Publishes to GitHub Container Registry (GHCR): +2. ✅ Creates release branch with generated changelog +3. ✅ Builds multi-platform Docker image (amd64, arm64) +4. ✅ Publishes to GitHub Container Registry (GHCR): - Version tag: `ghcr.io/evstack/ev-node-{app}:v0.2.0` - Latest tag: `ghcr.io/evstack/ev-node-{app}:latest` +5. ✅ Creates draft GitHub Release ### Requirements -- App directory must exist at `./apps/{app-path}/` -- Dockerfile must exist at `./apps/{app-path}/Dockerfile` +- App directory must exist at `./apps/{app-name}/` +- Dockerfile must exist at `./apps/{app-name}/Dockerfile` - Tag must match pattern `**/v*.*.*` - CI must pass on main branch +- `CHANGELOG.md` must be up-to-date --- @@ -97,6 +338,7 @@ Packages must be released in the following order: These packages only depend on `core` and can be released in parallel after `core`: +1. **github.com/evstack/ev-node/da** - Path: `./da` 2. **github.com/evstack/ev-node** - Path: `./` (root) 3. **github.com/evstack/ev-node/execution/evm** - Path: `./execution/evm` @@ -113,8 +355,9 @@ These packages have the most dependencies and should be released last: **Before Starting:** - Create a protected version branch (e.g., `v0` for major versions, `v0.3` for minor breaking changes) -- Ensure CHANGELOG.md is up to date with all changes properly categorized +- Ensure `CHANGELOG.md` is up to date with all changes properly categorized - Remove all `replace` directives from go.mod files +- Run E2E tests and document tested upgrade paths in CHANGELOG.md #### Phase 1: Release Core @@ -156,6 +399,7 @@ git tag execution/evm/v0.3.0 git push origin execution/evm/v0.3.0 # Verify all are available +go list -m github.com/evstack/ev-node/da@v0.3.0 go list -m github.com/evstack/ev-node@v0.3.0 go list -m github.com/evstack/ev-node/execution/evm@v0.3.0 ``` @@ -165,9 +409,10 @@ go list -m github.com/evstack/ev-node/execution/evm@v0.3.0 After all dependencies are available: ```bash - # Update and release apps/evm +cd apps/evm go get github.com/evstack/ev-node/core@v0.3.0 +go get github.com/evstack/ev-node/da@v0.3.0 go get github.com/evstack/ev-node/execution/evm@v0.3.0 go get github.com/evstack/ev-node@v0.3.0 go mod tidy @@ -178,6 +423,8 @@ git push origin apps/evm/v0.3.0 go list -m github.com/evstack/ev-node/apps/evm@v0.3.0 ``` +**Note:** For Go modules, the `apps/evm` tag IS used because it's a Go module path. The restriction on not using "apps/" prefix applies only to Docker image release tags. + --- ## Common Release Scenarios @@ -185,47 +432,56 @@ go list -m github.com/evstack/ev-node/apps/evm@v0.3.0 ### Scenario 1: Release Single App (Docker Only) ```bash +# Update CHANGELOG.md with release notes # Tag and push - automation handles the rest git tag evm/v0.2.0 git push origin evm/v0.2.0 + +# Review release branch, edit if needed +# Complete GitHub Release with priority and description +# Publish and announce in Slack and Telegram ``` ### Scenario 2: Release Multiple Apps ```bash # Release apps independently -git tag evm/single/v0.2.0 +git tag evm/v0.2.0 git tag testapp/v1.0.0 -git push origin evm/single/v0.2.0 testapp/v1.0.0 +git push origin evm/v0.2.0 testapp/v1.0.0 -# Each triggers its own workflow +# Each triggers its own workflow and creates separate release branches ``` ### Scenario 3: Full Go Module Release ```bash -# 1. Core +# 1. Update CHANGELOG.md with all changes +# 2. Release core git tag core/v0.3.0 && git push origin core/v0.3.0 -# 2. Wait 5-10 min, update deps, then release first-level +# 3. Wait 5-10 min, update deps, then release first-level git tag da/v0.3.0 && git push origin da/v0.3.0 git tag v0.3.0 && git push origin v0.3.0 git tag execution/evm/v0.3.0 && git push origin execution/evm/v0.3.0 -# 3. Wait, update deps, then release apps +# 4. Wait, update deps, then release apps git tag apps/evm/v0.3.0 && git push origin apps/evm/v0.3.0 + +# 5. Review release branches and complete GitHub Releases +# 6. Announce in Slack and Telegram ``` ### Scenario 4: Hotfix/Patch Release ```bash # For Docker images - delete and recreate -git tag -d evm/single/v0.2.0 -git push origin :refs/tags/evm/single/v0.2.0 +git tag -d evm/v0.2.0 +git push origin :refs/tags/evm/v0.2.0 -# Fix code, create new tag -git tag evm/single/v0.2.1 -git push origin evm/single/v0.2.1 +# Fix code, update CHANGELOG.md, create new tag +git tag evm/v0.2.1 +git push origin evm/v0.2.1 # For Go modules - create new patch version # Do NOT delete Go module tags - create v0.3.1 instead @@ -241,12 +497,19 @@ git push origin evm/single/v0.2.1 # Check workflow status # GitHub → Actions → Release +# Check release branch exists +git fetch origin +git checkout release/evm/v0.2.0 + # Pull and test image docker pull ghcr.io/evstack/ev-node-evm:v0.2.0 docker run ghcr.io/evstack/ev-node-evm:v0.2.0 --version # Check GHCR # GitHub → Packages → ev-node-evm + +# Verify GitHub Release exists (draft initially) +# GitHub → Releases ``` ### Go Module Release @@ -267,12 +530,13 @@ go get github.com/evstack/ev-node/core@v0.3.0 **"App directory does not exist"** -- Ensure tag matches app path: `apps/evm/` → `apps/evm/v0.2.0` +- Ensure tag name corresponds to app directory: `evm/v0.2.0` → `./apps/evm/` - Check spelling and case sensitivity +- Remember: tags do NOT include "apps/" prefix **"Dockerfile not found"** -- Verify Dockerfile exists at `apps/{app-path}/Dockerfile` +- Verify Dockerfile exists at `./apps/{app-name}/Dockerfile` - Check filename is exactly `Dockerfile` **"Image not found" in tests** @@ -280,6 +544,18 @@ go get github.com/evstack/ev-node/core@v0.3.0 - Wait for Docker build workflow to complete - Check workflow dependencies in Actions tab +**"Release branch not created"** + +- Check workflow logs for errors +- Verify git-cliff configuration +- Ensure CHANGELOG.md exists and is properly formatted + +**"Changelog generation failed"** + +- Verify `./CHANGELOG.md` exists in repository root +- Check git-cliff configuration file +- Review workflow logs for specific errors + ### Go Module Releases **Go proxy delay** @@ -302,8 +578,10 @@ go get github.com/evstack/ev-node/core@v0.3.0 - ✅ All changes merged to `main` - ✅ CI workflow passes -- ✅ CHANGELOG.md updated +- ✅ `CHANGELOG.md` updated with all changes +- ✅ Tested upgrade paths documented in CHANGELOG.md (1-2 lines) - ✅ Documentation updated +- ✅ E2E tests completed successfully - ✅ Local testing complete - ✅ Remove `replace` directives from go.mod files @@ -321,7 +599,7 @@ While modules can have independent versions, keep major versions synchronized ac ```bash # Good: Annotated tag with description -git tag -a evm/single/v0.2.0 -m "Release EVM single v0.2.0 +git tag -a evm/v0.2.0 -m "Release EVM v0.2.0 Features: - Added feature X @@ -332,7 +610,41 @@ Bug fixes: " # Avoid: Lightweight tag without description -git tag evm/single/v0.2.0 # Less informative +git tag evm/v0.2.0 # Less informative +``` + +### Release Checklist Template + +Use this checklist for each release: + +```markdown +## Release v0.3.0 Checklist + +### Pre-Release +- [ ] All PRs merged to main +- [ ] CI passing on main +- [ ] CHANGELOG.md updated with tested upgrade paths +- [ ] E2E tests passed +- [ ] Documentation updated +- [ ] Replace directives removed + +### Release +- [ ] Tag created and pushed +- [ ] Workflow completed successfully +- [ ] Release branch reviewed +- [ ] Changelog refined (if needed) +- [ ] Docker images verified +- [ ] Go modules verified (if applicable) + +### Post-Release +- [ ] GitHub Release published with: + - [ ] Upgrade priority + - [ ] General description + - [ ] Tested upgrade paths + - [ ] Breaking changes (if any) +- [ ] Slack announcement posted +- [ ] Telegram announcement posted +- [ ] Documentation site updated ``` --- @@ -350,3 +662,15 @@ git tag evm/single/v0.2.0 # Less informative - **Go modules**: NEVER delete tags. Create a new patch version instead (e.g., v0.3.1) to avoid Go proxy issues. 5. **Protected Branches**: Create version branches (e.g., `v0`, `v0.3`) for maintaining release history and backporting fixes. + +6. **Release Branches**: The workflow automatically creates `release/` branches. These can be reviewed, edited, and merged or discarded after the release is published. + +7. **Changelog as Source**: The `./CHANGELOG.md` file in the repository is the base for all generated release notes. Keep it well-maintained and up-to-date. + +8. **Communication is Key**: Always announce releases in both Slack and Telegram channels to keep the community informed. + +9. **Tested Upgrade Paths**: Always document which upgrade paths were tested in E2E tests in the CHANGELOG.md (1-2 lines per release). This helps users understand which upgrade scenarios have been validated. + +10. **Tag Format Distinction**: + - **Docker releases**: Use tags WITHOUT "apps/" prefix (e.g., `evm/v0.2.0`) + - **Go module releases**: Use full module path in tags (e.g., `apps/evm/v0.3.0`) From 0ed697096f5ebd4458ef90d0dd827279772a3a7f Mon Sep 17 00:00:00 2001 From: auricom <27022259+auricom@users.noreply.github.com> Date: Thu, 22 Jan 2026 10:36:39 +0100 Subject: [PATCH 2/6] claude code --- .github/workflows/release.yml | 102 ++++++++++++++++++++++++++++++---- 1 file changed, 90 insertions(+), 12 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b924ed251a..5aef81294d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -21,26 +21,104 @@ jobs: with: fetch-depth: 0 # Full history needed for changelog generation - - name: Install git-cliff - uses: taiki-e/install-action@v2 - with: - tool: git-cliff + - name: Get previous tag + id: get-prev-tag + run: | + # Get the previous tag + CURRENT_TAG="${{ github.ref_name }}" + PREV_TAG=$(git tag --sort=-version:refname | grep -A1 "^${CURRENT_TAG}$" | tail -1) + + if [ -z "$PREV_TAG" ] || [ "$PREV_TAG" = "$CURRENT_TAG" ]; then + echo "No previous tag found, using initial commit" + PREV_TAG=$(git rev-list --max-parents=0 HEAD) + fi - - name: Generate changelog - id: cliff + echo "prev-tag=$PREV_TAG" >> $GITHUB_OUTPUT + echo "::notice::Comparing $PREV_TAG to $CURRENT_TAG" + + - name: Generate git diff + id: git-diff run: | - # Generate changelog from CHANGELOG.md for this release - CHANGELOG_CONTENT=$(git cliff --unreleased --strip all) + PREV_TAG="${{ steps.get-prev-tag.outputs.prev-tag }}" + CURRENT_TAG="${{ github.ref_name }}" + + # Generate detailed diff with file statistics + git diff --stat "$PREV_TAG"..HEAD > git-diff-stats.txt + git log --oneline "$PREV_TAG"..HEAD > git-commits.txt + git diff "$PREV_TAG"..HEAD > git-full-diff.txt + + echo "Generated git diff from $PREV_TAG to HEAD" + echo "Commit summary:" + cat git-commits.txt + + # Capture outputs for next step (truncate diff to fit GitHub limits) + { + echo 'commits<> $GITHUB_OUTPUT + + { + echo 'stats<> $GITHUB_OUTPUT + + { + echo 'diff<> $GITHUB_OUTPUT - # Save to file and output - echo "$CHANGELOG_CONTENT" > RELEASE_CHANGELOG.md - echo "Generated changelog:" + - name: Generate changelog with Claude + id: claude + uses: anthropics/claude-code-action@v1 + with: + claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} + prompt: | + You are a technical writer creating release notes for a blockchain node software project called ev-node. + Analyze the provided git changes and generate a clear, comprehensive changelog in markdown format. + + Follow these guidelines: + - Start with a brief summary of the release + - Group changes by category: Features, Bug Fixes, Performance, Documentation, etc. + - Use clear, concise bullet points + - Highlight breaking changes prominently if any + - Include technical details that would help developers understand the changes + - Format as clean markdown suitable for a GitHub release + + + Generate a changelog for this release based on the following git changes: + + ## Commits: + ``` + ${{ steps.git-diff.outputs.commits }} + ``` + + ## File Statistics: + ``` + ${{ steps.git-diff.outputs.stats }} + ``` + + ## Full Diff (first 50000 chars): + ```diff + ${{ steps.git-diff.outputs.diff }} + ``` + + Please generate a well-formatted changelog in markdown that summarizes these changes for users and developers. + + - name: Save changelog output + id: changelog-output + run: | + # Save Claude's response to file + echo "${{ steps.claude.outputs.content }}" > RELEASE_CHANGELOG.md + echo "Generated changelog with Claude AI:" cat RELEASE_CHANGELOG.md # Export for GitHub Release (escape for multiline output) { echo 'content<> $GITHUB_OUTPUT From 7d1edd9961b8117e86999daf9e7128bc089b1cb0 Mon Sep 17 00:00:00 2001 From: auricom <27022259+auricom@users.noreply.github.com> Date: Thu, 22 Jan 2026 11:05:20 +0100 Subject: [PATCH 3/6] ai suggestions --- .github/workflows/README.md | 282 ++++++++++++++++++++++++++++++++++ .github/workflows/release.yml | 4 + 2 files changed, 286 insertions(+) create mode 100644 .github/workflows/README.md diff --git a/.github/workflows/README.md b/.github/workflows/README.md new file mode 100644 index 0000000000..cf4e37c740 --- /dev/null +++ b/.github/workflows/README.md @@ -0,0 +1,282 @@ +# GitHub Workflows Documentation + +Comprehensive guide to ev-node CI/CD workflows, orchestration, and tag-based release process. + +## Table of Contents + +- [Workflow Architecture](#workflow-architecture) +- [CI Workflow](#ci-workflow) +- [Release Workflow](#release-workflow) +- [Tag-Based Release Process](#tag-based-release-process) +- [Troubleshooting](#troubleshooting) + +## Workflow Architecture + +``` +┌──────────────────────────────────────────────────────────────┐ +│ Trigger Events │ +│ • push to main • pull_request • merge_group • tags │ +└───────────────────────────┬──────────────────────────────────┘ + │ + ┌───────────────────┴────────────────────┐ + │ │ + v v +┌───────────────────┐ ┌────────────────────┐ +│ CI Workflow │ │ Release Workflow │ +│ (ci.yml) │ │ (release.yml) │ +│ │ │ │ +│ 1. Image Tag │ │ Trigger: Tag │ +│ Generation │ │ **/v*.*.* │ +│ • PR: pr-# │ │ │ +│ • Branch: ref │ │ 1. Parse Tag │ +│ │ │ • Validate │ +│ 2. Parallel: │ │ • Extract │ +│ • Lint │ │ │ +│ • Docker │ │ 2. Build & Push │ +│ • Tests │ │ • Multi-arch │ +│ • Proto │ │ • Version tag │ +│ │ │ • Latest tag │ +│ 3. Sequential: │ │ │ +│ • Docker E2E │ │ │ +└───────────────────┘ └────────────────────┘ +``` + +## CI Workflow + +**Entry Point:** `ci.yml` - Orchestrates all CI processes + +**Triggers:** `push` to main | `pull_request` | `merge_group` + +### Image Tag Generation + +First job generates consistent Docker tags for all downstream jobs: +- **PRs:** `pr-{number}` (e.g., `pr-123`) +- **Branches:** Sanitized ref name (e.g., `main`) + +### Parallel Jobs + +**Lint** (`lint.yml`) - Code quality checks: +- golangci-lint, hadolint, yamllint, markdown-lint, goreleaser-check + +**Docker** (`docker.yml`) - Image builds: +- Multi-platform (linux/amd64, linux/arm64) +- Pushes to GHCR with generated tag +- Skips for merge groups (uses PR cache) + +**Tests** (`test.yml`) - Comprehensive testing: +- Build all binaries, Go mod tidy check +- Unit tests, Integration tests, E2E tests, EVM tests +- Combined coverage upload to Codecov + +**Proto** (`proto.yml`) - Protobuf validation using Buf + +### Sequential Jobs + +**Docker E2E Tests** (`docker-tests.yml`): +- Waits for Docker build completion +- Runs E2E and upgrade tests using built images +- Can be manually triggered via `workflow_dispatch` + +### Dependencies + +``` +determine-image-tag + ├─→ lint + ├─→ docker ──→ docker-tests + ├─→ test + └─→ proto +``` + +## Release Workflow + +**Entry Point:** `release.yml` - Automated Docker image releases + +**Triggers:** Tag push matching `**/v*.*.*` (e.g., `evm/single/v0.2.0`) + +### Parse Release Tag + +Extracts and validates: +```yaml +Input: evm/single/v0.2.0 +Output: + app-path: evm/single + version: v0.2.0 + image-name: ev-node-evm-single + dockerfile: apps/evm/single/Dockerfile +``` + +**Validation:** +- ✅ App directory exists: `./apps/{app-path}` +- ✅ Dockerfile exists: `apps/{app-path}/Dockerfile` +- ✅ Tag matches: `**/v*.*.*` +- ✅ Semantic versioning format + +### Build and Push + +- Multi-platform build (amd64, arm64) +- Publishes to GHCR: + - `ghcr.io/{owner}/ev-node-{app}:v0.2.0` (version tag) + - `ghcr.io/{owner}/ev-node-{app}:latest` (latest tag) + +## Tag-Based Release Process + +### Tag Format + +**Pattern:** `{app-path}/v{major}.{minor}.{patch}` + +Maps directly to `./apps/` directory structure: + +| Tag | App Path | Version | Image Name | +|-----|----------|---------|------------| +| `evm/single/v0.2.0` | `evm/single` | `v0.2.0` | `ev-node-evm-single` | +| `testapp/v1.0.0` | `testapp` | `v1.0.0` | `ev-node-testapp` | +| `grpc/single/v2.1.3` | `grpc/single` | `v2.1.3` | `ev-node-grpc-single` | + +### Release Steps + +#### 1. Pre-Release Checklist +- [ ] Changes committed and pushed to `main` +- [ ] CI passes +- [ ] CHANGELOG.md updated +- [ ] Dockerfile exists in app directory + +#### 2. Create Tag + +```bash +# Annotated tag with release notes +git tag -a evm/single/v0.2.0 -m "Release EVM single v0.2.0 + +Features: +- Added feature X +- Improved performance Y + +Bug fixes: +- Fixed issue Z +" + +git push origin evm/single/v0.2.0 +``` + +#### 3. Automated Process + +Workflow automatically: +1. Validates tag and app structure +2. Builds multi-platform images +3. Publishes to GHCR with version + latest tags + +#### 4. Verify + +```bash +docker pull ghcr.io/evstack/ev-node-evm-single:v0.2.0 +docker run ghcr.io/evstack/ev-node-evm-single:v0.2.0 --version +``` + +### Multiple Releases + +```bash +# Individual tags +git tag evm/single/v0.2.0 && git push origin evm/single/v0.2.0 +git tag testapp/v1.0.0 && git push origin testapp/v1.0.0 + +# Multiple at once +git push origin evm/single/v0.2.0 testapp/v1.0.0 +``` + +### Semantic Versioning + +- **MAJOR (v2.0.0):** Breaking changes +- **MINOR (v1.1.0):** New features, backward compatible +- **PATCH (v1.0.1):** Bug fixes, backward compatible + +### Rollback + +```bash +# Delete tag +git tag -d evm/single/v0.2.0 +git push origin :refs/tags/evm/single/v0.2.0 + +# Fix and recreate +git tag -a evm/single/v0.2.0 -m "Release message" +git push origin evm/single/v0.2.0 +``` + +### Best Practices + +1. Use annotated tags with descriptive messages +2. Update CHANGELOG.md before tagging +3. Ensure CI passes on main +4. Test locally before release +5. Document breaking changes +6. Version tags are immutable references +7. Latest tag points to most recent release + +### Adding New Apps + +1. Create directory: `apps/new-app/Dockerfile` +2. Add to CI yaml (if needed): + ```yaml + apps: [{"name": "ev-node-new-app", "dockerfile": "apps/new-app/Dockerfile"}] + ``` +3. Create tag: `git tag new-app/v1.0.0 && git push origin new-app/v1.0.0` + +## Environment & Secrets + +### Variables + +| Variable | Description | Example | +|----------|-------------|---------| +| `EV_NODE_IMAGE_REPO` | GHCR repository | `ghcr.io/evstack` | +| `EV_NODE_IMAGE_TAG` | Image tag | `pr-123`, `main` | + +### Secrets + +| Secret | Description | Used By | +|--------|-------------|---------| +| `GITHUB_TOKEN` | GHCR authentication | Docker workflows | +| `CODECOV_TOKEN` | Coverage upload | Test workflow | + +## Troubleshooting + +### Release Errors + +**"App directory does not exist"** +- Tag must match app path: `apps/evm/single/` → `evm/single/v0.2.0` + +**"Dockerfile not found"** +- Verify `apps/{app-path}/Dockerfile` exists + +**"Invalid tag format"** +- Use `evm/single/v0.2.0` not `evm/single/0.2.0` + +### CI Errors + +**Docker E2E "image not found"** +- Wait for Docker build job completion + +**Coverage upload fails** +- Verify `CODECOV_TOKEN` in repository settings + +**Lint failures** +- Run locally: `make lint` + +### Manual Triggers + +**Docker E2E tests:** +``` +GitHub → Actions → "Docker Tests" → Run workflow +Enter tag: pr-123, main, v0.2.0 +``` + +**Check images:** +```bash +gh api /orgs/evstack/packages/container/ev-node-evm-single/versions +docker pull ghcr.io/evstack/ev-node-evm-single:v0.2.0 +``` + +## Additional Resources + +- **Complete Release Guide:** [RELEASE.md](../RELEASE.md) +- **Quick Start:** [RELEASE_QUICK_START.md](../RELEASE_QUICK_START.md) +- **GitHub Actions:** https://docs.github.com/en/actions +- **Semantic Versioning:** https://semver.org/ +- **GHCR Docs:** https://docs.github.com/en/packages diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5aef81294d..18dabec74c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -26,6 +26,10 @@ jobs: run: | # Get the previous tag CURRENT_TAG="${{ github.ref_name }}" + if [[ ! "$CURRENT_TAG" =~ ^[a-zA-Z0-9/_.-]+$ ]]; then + echo "::error::Invalid tag format: $CURRENT_TAG" + exit 1 + fi PREV_TAG=$(git tag --sort=-version:refname | grep -A1 "^${CURRENT_TAG}$" | tail -1) if [ -z "$PREV_TAG" ] || [ "$PREV_TAG" = "$CURRENT_TAG" ]; then From 0c09500f768b0c463d9d7a31117c6fddeb5789ed Mon Sep 17 00:00:00 2001 From: auricom <27022259+auricom@users.noreply.github.com> Date: Thu, 22 Jan 2026 11:12:22 +0100 Subject: [PATCH 4/6] remove readme --- .github/workflows/README.md | 282 ---------------------------------- .github/workflows/release.yml | 4 +- 2 files changed, 2 insertions(+), 284 deletions(-) delete mode 100644 .github/workflows/README.md diff --git a/.github/workflows/README.md b/.github/workflows/README.md deleted file mode 100644 index cf4e37c740..0000000000 --- a/.github/workflows/README.md +++ /dev/null @@ -1,282 +0,0 @@ -# GitHub Workflows Documentation - -Comprehensive guide to ev-node CI/CD workflows, orchestration, and tag-based release process. - -## Table of Contents - -- [Workflow Architecture](#workflow-architecture) -- [CI Workflow](#ci-workflow) -- [Release Workflow](#release-workflow) -- [Tag-Based Release Process](#tag-based-release-process) -- [Troubleshooting](#troubleshooting) - -## Workflow Architecture - -``` -┌──────────────────────────────────────────────────────────────┐ -│ Trigger Events │ -│ • push to main • pull_request • merge_group • tags │ -└───────────────────────────┬──────────────────────────────────┘ - │ - ┌───────────────────┴────────────────────┐ - │ │ - v v -┌───────────────────┐ ┌────────────────────┐ -│ CI Workflow │ │ Release Workflow │ -│ (ci.yml) │ │ (release.yml) │ -│ │ │ │ -│ 1. Image Tag │ │ Trigger: Tag │ -│ Generation │ │ **/v*.*.* │ -│ • PR: pr-# │ │ │ -│ • Branch: ref │ │ 1. Parse Tag │ -│ │ │ • Validate │ -│ 2. Parallel: │ │ • Extract │ -│ • Lint │ │ │ -│ • Docker │ │ 2. Build & Push │ -│ • Tests │ │ • Multi-arch │ -│ • Proto │ │ • Version tag │ -│ │ │ • Latest tag │ -│ 3. Sequential: │ │ │ -│ • Docker E2E │ │ │ -└───────────────────┘ └────────────────────┘ -``` - -## CI Workflow - -**Entry Point:** `ci.yml` - Orchestrates all CI processes - -**Triggers:** `push` to main | `pull_request` | `merge_group` - -### Image Tag Generation - -First job generates consistent Docker tags for all downstream jobs: -- **PRs:** `pr-{number}` (e.g., `pr-123`) -- **Branches:** Sanitized ref name (e.g., `main`) - -### Parallel Jobs - -**Lint** (`lint.yml`) - Code quality checks: -- golangci-lint, hadolint, yamllint, markdown-lint, goreleaser-check - -**Docker** (`docker.yml`) - Image builds: -- Multi-platform (linux/amd64, linux/arm64) -- Pushes to GHCR with generated tag -- Skips for merge groups (uses PR cache) - -**Tests** (`test.yml`) - Comprehensive testing: -- Build all binaries, Go mod tidy check -- Unit tests, Integration tests, E2E tests, EVM tests -- Combined coverage upload to Codecov - -**Proto** (`proto.yml`) - Protobuf validation using Buf - -### Sequential Jobs - -**Docker E2E Tests** (`docker-tests.yml`): -- Waits for Docker build completion -- Runs E2E and upgrade tests using built images -- Can be manually triggered via `workflow_dispatch` - -### Dependencies - -``` -determine-image-tag - ├─→ lint - ├─→ docker ──→ docker-tests - ├─→ test - └─→ proto -``` - -## Release Workflow - -**Entry Point:** `release.yml` - Automated Docker image releases - -**Triggers:** Tag push matching `**/v*.*.*` (e.g., `evm/single/v0.2.0`) - -### Parse Release Tag - -Extracts and validates: -```yaml -Input: evm/single/v0.2.0 -Output: - app-path: evm/single - version: v0.2.0 - image-name: ev-node-evm-single - dockerfile: apps/evm/single/Dockerfile -``` - -**Validation:** -- ✅ App directory exists: `./apps/{app-path}` -- ✅ Dockerfile exists: `apps/{app-path}/Dockerfile` -- ✅ Tag matches: `**/v*.*.*` -- ✅ Semantic versioning format - -### Build and Push - -- Multi-platform build (amd64, arm64) -- Publishes to GHCR: - - `ghcr.io/{owner}/ev-node-{app}:v0.2.0` (version tag) - - `ghcr.io/{owner}/ev-node-{app}:latest` (latest tag) - -## Tag-Based Release Process - -### Tag Format - -**Pattern:** `{app-path}/v{major}.{minor}.{patch}` - -Maps directly to `./apps/` directory structure: - -| Tag | App Path | Version | Image Name | -|-----|----------|---------|------------| -| `evm/single/v0.2.0` | `evm/single` | `v0.2.0` | `ev-node-evm-single` | -| `testapp/v1.0.0` | `testapp` | `v1.0.0` | `ev-node-testapp` | -| `grpc/single/v2.1.3` | `grpc/single` | `v2.1.3` | `ev-node-grpc-single` | - -### Release Steps - -#### 1. Pre-Release Checklist -- [ ] Changes committed and pushed to `main` -- [ ] CI passes -- [ ] CHANGELOG.md updated -- [ ] Dockerfile exists in app directory - -#### 2. Create Tag - -```bash -# Annotated tag with release notes -git tag -a evm/single/v0.2.0 -m "Release EVM single v0.2.0 - -Features: -- Added feature X -- Improved performance Y - -Bug fixes: -- Fixed issue Z -" - -git push origin evm/single/v0.2.0 -``` - -#### 3. Automated Process - -Workflow automatically: -1. Validates tag and app structure -2. Builds multi-platform images -3. Publishes to GHCR with version + latest tags - -#### 4. Verify - -```bash -docker pull ghcr.io/evstack/ev-node-evm-single:v0.2.0 -docker run ghcr.io/evstack/ev-node-evm-single:v0.2.0 --version -``` - -### Multiple Releases - -```bash -# Individual tags -git tag evm/single/v0.2.0 && git push origin evm/single/v0.2.0 -git tag testapp/v1.0.0 && git push origin testapp/v1.0.0 - -# Multiple at once -git push origin evm/single/v0.2.0 testapp/v1.0.0 -``` - -### Semantic Versioning - -- **MAJOR (v2.0.0):** Breaking changes -- **MINOR (v1.1.0):** New features, backward compatible -- **PATCH (v1.0.1):** Bug fixes, backward compatible - -### Rollback - -```bash -# Delete tag -git tag -d evm/single/v0.2.0 -git push origin :refs/tags/evm/single/v0.2.0 - -# Fix and recreate -git tag -a evm/single/v0.2.0 -m "Release message" -git push origin evm/single/v0.2.0 -``` - -### Best Practices - -1. Use annotated tags with descriptive messages -2. Update CHANGELOG.md before tagging -3. Ensure CI passes on main -4. Test locally before release -5. Document breaking changes -6. Version tags are immutable references -7. Latest tag points to most recent release - -### Adding New Apps - -1. Create directory: `apps/new-app/Dockerfile` -2. Add to CI yaml (if needed): - ```yaml - apps: [{"name": "ev-node-new-app", "dockerfile": "apps/new-app/Dockerfile"}] - ``` -3. Create tag: `git tag new-app/v1.0.0 && git push origin new-app/v1.0.0` - -## Environment & Secrets - -### Variables - -| Variable | Description | Example | -|----------|-------------|---------| -| `EV_NODE_IMAGE_REPO` | GHCR repository | `ghcr.io/evstack` | -| `EV_NODE_IMAGE_TAG` | Image tag | `pr-123`, `main` | - -### Secrets - -| Secret | Description | Used By | -|--------|-------------|---------| -| `GITHUB_TOKEN` | GHCR authentication | Docker workflows | -| `CODECOV_TOKEN` | Coverage upload | Test workflow | - -## Troubleshooting - -### Release Errors - -**"App directory does not exist"** -- Tag must match app path: `apps/evm/single/` → `evm/single/v0.2.0` - -**"Dockerfile not found"** -- Verify `apps/{app-path}/Dockerfile` exists - -**"Invalid tag format"** -- Use `evm/single/v0.2.0` not `evm/single/0.2.0` - -### CI Errors - -**Docker E2E "image not found"** -- Wait for Docker build job completion - -**Coverage upload fails** -- Verify `CODECOV_TOKEN` in repository settings - -**Lint failures** -- Run locally: `make lint` - -### Manual Triggers - -**Docker E2E tests:** -``` -GitHub → Actions → "Docker Tests" → Run workflow -Enter tag: pr-123, main, v0.2.0 -``` - -**Check images:** -```bash -gh api /orgs/evstack/packages/container/ev-node-evm-single/versions -docker pull ghcr.io/evstack/ev-node-evm-single:v0.2.0 -``` - -## Additional Resources - -- **Complete Release Guide:** [RELEASE.md](../RELEASE.md) -- **Quick Start:** [RELEASE_QUICK_START.md](../RELEASE_QUICK_START.md) -- **GitHub Actions:** https://docs.github.com/en/actions -- **Semantic Versioning:** https://semver.org/ -- **GHCR Docs:** https://docs.github.com/en/packages diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 18dabec74c..50f9a01f53 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -2,7 +2,7 @@ name: Release on: push: tags: - - '**/v*.*.*' # Matches tags like evm/single/v0.2.0, testapp/v0.4.0, etc. + - "**/v*.*.*" # Matches tags like evm/single/v0.2.0, testapp/v0.4.0, etc. permissions: {} @@ -19,7 +19,7 @@ jobs: - name: Checkout code uses: actions/checkout@v6 with: - fetch-depth: 0 # Full history needed for changelog generation + fetch-depth: 0 # Full history needed for changelog generation - name: Get previous tag id: get-prev-tag From 09be625b1526756f5d92ce92a1a5dd9035777e09 Mon Sep 17 00:00:00 2001 From: auricom <27022259+auricom@users.noreply.github.com> Date: Thu, 22 Jan 2026 18:25:21 +0100 Subject: [PATCH 5/6] updates --- .github/workflows/release.yml | 328 +++++++++++++++++++++++----------- RELEASE.md | 229 ++++++++++++++++++------ 2 files changed, 402 insertions(+), 155 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 50f9a01f53..c828c636ce 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -7,159 +7,207 @@ on: permissions: {} jobs: - generate-changelog: - name: Generate Changelog and Create Release Branch + create-release-branch: + name: Create Release Branch runs-on: ubuntu-latest permissions: contents: write + pull-requests: write outputs: - changelog: ${{ steps.cliff.outputs.content }} release-branch: ${{ steps.create-branch.outputs.branch-name }} + app-path: ${{ steps.parse-tag.outputs.app-path }} + prev-tag: ${{ steps.get-prev-tag.outputs.prev-tag }} steps: - name: Checkout code uses: actions/checkout@v6 with: fetch-depth: 0 # Full history needed for changelog generation + - name: Parse tag + id: parse-tag + run: | + TAG="${{ github.ref_name }}" + # Extract app path from tag (e.g., test-evm from test-evm/v0.2.0) + APP_PATH="${TAG%/v*}" + echo "app-path=$APP_PATH" >> $GITHUB_OUTPUT + echo "::notice::Application: $APP_PATH" + - name: Get previous tag id: get-prev-tag run: | - # Get the previous tag + # Get the previous tag from the same application CURRENT_TAG="${{ github.ref_name }}" if [[ ! "$CURRENT_TAG" =~ ^[a-zA-Z0-9/_.-]+$ ]]; then echo "::error::Invalid tag format: $CURRENT_TAG" exit 1 fi - PREV_TAG=$(git tag --sort=-version:refname | grep -A1 "^${CURRENT_TAG}$" | tail -1) + + # Extract application prefix (everything before the version) + # e.g., test-evm/v0.2.0 -> test-evm + APP_PREFIX="${CURRENT_TAG%/v*}" + echo "::notice::Application prefix: $APP_PREFIX" + + # Filter by app prefix and sort by version + MATCHING_TAGS=$(git tag --sort=-version:refname | grep "^${APP_PREFIX}/v") + + echo "::notice::Found tags for $APP_PREFIX:" + echo "$MATCHING_TAGS" | head -4 + + # Get the previous tag (the one right after the current tag in the sorted list) + PREV_TAG=$(echo "$MATCHING_TAGS" | grep -A1 "^${CURRENT_TAG}$" | tail -1) if [ -z "$PREV_TAG" ] || [ "$PREV_TAG" = "$CURRENT_TAG" ]; then - echo "No previous tag found, using initial commit" + echo "::notice::No previous tag found for $APP_PREFIX, using initial commit" PREV_TAG=$(git rev-list --max-parents=0 HEAD) fi echo "prev-tag=$PREV_TAG" >> $GITHUB_OUTPUT echo "::notice::Comparing $PREV_TAG to $CURRENT_TAG" - - name: Generate git diff - id: git-diff + - name: Create release branch + id: create-branch run: | + TAG="${{ github.ref_name }}" + BRANCH_NAME="release/$TAG" + APP_PATH="${{ steps.parse-tag.outputs.app-path }}" PREV_TAG="${{ steps.get-prev-tag.outputs.prev-tag }}" - CURRENT_TAG="${{ github.ref_name }}" - # Generate detailed diff with file statistics - git diff --stat "$PREV_TAG"..HEAD > git-diff-stats.txt - git log --oneline "$PREV_TAG"..HEAD > git-commits.txt - git diff "$PREV_TAG"..HEAD > git-full-diff.txt + echo "Creating release branch: $BRANCH_NAME" - echo "Generated git diff from $PREV_TAG to HEAD" - echo "Commit summary:" - cat git-commits.txt + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" - # Capture outputs for next step (truncate diff to fit GitHub limits) - { - echo 'commits<> $GITHUB_OUTPUT + git checkout -b "$BRANCH_NAME" - { - echo 'stats<> $GITHUB_OUTPUT + # Generate a structured changelog + APP_DIR="apps/$APP_PATH" + CHANGELOG_FILE="$APP_DIR/CHANGELOG.md" - { - echo 'diff<> $GITHUB_OUTPUT + mkdir -p "$APP_DIR" - - name: Generate changelog with Claude - id: claude - uses: anthropics/claude-code-action@v1 - with: - claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} - prompt: | - You are a technical writer creating release notes for a blockchain node software project called ev-node. - Analyze the provided git changes and generate a clear, comprehensive changelog in markdown format. + # Start the changelog + echo "# Release $TAG" > "$CHANGELOG_FILE" + echo "" >> "$CHANGELOG_FILE" + echo "Released on $(date +%Y-%m-%d)" >> "$CHANGELOG_FILE" + echo "" >> "$CHANGELOG_FILE" - Follow these guidelines: - - Start with a brief summary of the release - - Group changes by category: Features, Bug Fixes, Performance, Documentation, etc. - - Use clear, concise bullet points - - Highlight breaking changes prominently if any - - Include technical details that would help developers understand the changes - - Format as clean markdown suitable for a GitHub release + # Get commit statistics + COMMIT_COUNT=$(git rev-list --count "$PREV_TAG"..HEAD) + FILES_CHANGED=$(git diff --shortstat "$PREV_TAG"..HEAD | sed 's/^[[:space:]]*//') + echo "## Summary" >> "$CHANGELOG_FILE" + echo "" >> "$CHANGELOG_FILE" + echo "- **$COMMIT_COUNT commits** since $PREV_TAG" >> "$CHANGELOG_FILE" + if [ -n "$FILES_CHANGED" ]; then + echo "- $FILES_CHANGED" >> "$CHANGELOG_FILE" + fi + echo "" >> "$CHANGELOG_FILE" + + # Group commits by conventional commit type + echo "## Changes" >> "$CHANGELOG_FILE" + echo "" >> "$CHANGELOG_FILE" + + # Features + FEATURES=$(git log --oneline "$PREV_TAG"..HEAD | grep -i "^[a-f0-9]* feat" || true) + if [ -n "$FEATURES" ]; then + echo "### ✨ Features" >> "$CHANGELOG_FILE" + echo "" >> "$CHANGELOG_FILE" + echo "$FEATURES" | sed 's/^[a-f0-9]* feat[:(]*[^)]*[)]* /- /' >> "$CHANGELOG_FILE" + echo "" >> "$CHANGELOG_FILE" + fi - Generate a changelog for this release based on the following git changes: + # Fixes + FIXES=$(git log --oneline "$PREV_TAG"..HEAD | grep -i "^[a-f0-9]* fix" || true) + if [ -n "$FIXES" ]; then + echo "### 🐛 Bug Fixes" >> "$CHANGELOG_FILE" + echo "" >> "$CHANGELOG_FILE" + echo "$FIXES" | sed 's/^[a-f0-9]* fix[:(]*[^)]*[)]* /- /' >> "$CHANGELOG_FILE" + echo "" >> "$CHANGELOG_FILE" + fi - ## Commits: - ``` - ${{ steps.git-diff.outputs.commits }} - ``` + # Chores + CHORES=$(git log --oneline "$PREV_TAG"..HEAD | grep -i "^[a-f0-9]* chore" || true) + if [ -n "$CHORES" ]; then + echo "### 🔧 Chores" >> "$CHANGELOG_FILE" + echo "" >> "$CHANGELOG_FILE" + echo "$CHORES" | sed 's/^[a-f0-9]* chore[:(]*[^)]*[)]* /- /' >> "$CHANGELOG_FILE" + echo "" >> "$CHANGELOG_FILE" + fi - ## File Statistics: - ``` - ${{ steps.git-diff.outputs.stats }} - ``` + # Other commits + OTHER=$(git log --oneline "$PREV_TAG"..HEAD | grep -iv "^[a-f0-9]* \(feat\|fix\|chore\)" || true) + if [ -n "$OTHER" ]; then + echo "### 📝 Other Changes" >> "$CHANGELOG_FILE" + echo "" >> "$CHANGELOG_FILE" + echo "$OTHER" | sed 's/^[a-f0-9]* /- /' >> "$CHANGELOG_FILE" + echo "" >> "$CHANGELOG_FILE" + fi - ## Full Diff (first 50000 chars): - ```diff - ${{ steps.git-diff.outputs.diff }} - ``` + # Full commit list + echo "---" >> "$CHANGELOG_FILE" + echo "" >> "$CHANGELOG_FILE" + echo "### All Commits" >> "$CHANGELOG_FILE" + echo "" >> "$CHANGELOG_FILE" + git log --oneline "$PREV_TAG"..HEAD | sed 's/^/- /' >> "$CHANGELOG_FILE" + echo "" >> "$CHANGELOG_FILE" + + # Prepend to existing changelog if it exists + if [ -f "$CHANGELOG_FILE.old" ]; then + cat "$CHANGELOG_FILE.old" >> "$CHANGELOG_FILE" + rm "$CHANGELOG_FILE.old" + fi - Please generate a well-formatted changelog in markdown that summarizes these changes for users and developers. + echo "Generated changelog:" + cat "$CHANGELOG_FILE" - - name: Save changelog output - id: changelog-output - run: | - # Save Claude's response to file - echo "${{ steps.claude.outputs.content }}" > RELEASE_CHANGELOG.md - echo "Generated changelog with Claude AI:" - cat RELEASE_CHANGELOG.md + # Commit the changelog + git add "$CHANGELOG_FILE" + git commit -m "chore: add changelog for $TAG" \ + -m "Generated structured changelog for $TAG release." - # Export for GitHub Release (escape for multiline output) - { - echo 'content<> $GITHUB_OUTPUT + # Push the branch + git push origin "$BRANCH_NAME" - - name: Create release branch - id: create-branch + echo "branch-name=$BRANCH_NAME" >> $GITHUB_OUTPUT + echo "::notice::Created release branch: $BRANCH_NAME with changelog" + + - name: Create Pull Request + id: create-pr + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | TAG="${{ github.ref_name }}" - BRANCH_NAME="release/$TAG" + BRANCH_NAME="${{ steps.create-branch.outputs.branch-name }}" + PREV_TAG="${{ steps.get-prev-tag.outputs.prev-tag }}" + APP_PATH="${{ steps.parse-tag.outputs.app-path }}" - echo "Creating release branch: $BRANCH_NAME" - git config user.name "github-actions[bot]" - git config user.email "github-actions[bot]@users.noreply.github.com" + # Create the PR using GitHub CLI + PR_URL=$(gh pr create \ + --base main \ + --head "$BRANCH_NAME" \ + --title "Release: $TAG" \ + --body "## Release $TAG - git checkout -b "$BRANCH_NAME" + This PR was automatically created for the release of \`$TAG\`. - # Update CHANGELOG.md with the generated content - if [ -f "CHANGELOG.md" ]; then - # Add generated changelog to CHANGELOG.md - cat RELEASE_CHANGELOG.md >> CHANGELOG_RELEASE_NOTES.md - echo "Changelog prepared for release: $TAG" >> CHANGELOG_RELEASE_NOTES.md - fi + **Previous tag:** \`$PREV_TAG\` - # Commit the changelog - git add -A - if git diff --staged --quiet; then - echo "No changes to commit" - else - git commit -m "chore: prepare release $TAG" \ - -m "Generated changelog for $TAG release." \ - -m "This is an automated commit created by the release workflow." - fi + ### Changelog - # Push the branch - git push origin "$BRANCH_NAME" + A structured changelog has been automatically generated and committed to \`apps/$APP_PATH/CHANGELOG.md\`. - echo "branch-name=$BRANCH_NAME" >> $GITHUB_OUTPUT - echo "::notice::Created release branch: $BRANCH_NAME" + The changelog includes: + - Summary of commits and file changes + - Changes grouped by type (Features, Bug Fixes, Chores, etc.) + - Full commit list + + **To enhance the changelog with Claude AI:** + Check the draft release for a ready-to-use Claude prompt that you can copy and use in your IDE. + + Please review the changes and changelog before merging.") + + echo "pr-url=$PR_URL" >> $GITHUB_OUTPUT + echo "::notice::Created pull request: $PR_URL" parse-tag: name: Parse Release Tag @@ -243,11 +291,66 @@ jobs: create-github-release: name: Create GitHub Release - needs: [generate-changelog, parse-tag, build-and-push] + needs: [create-release-branch, parse-tag, build-and-push] runs-on: ubuntu-latest permissions: contents: write steps: + - name: Checkout code + uses: actions/checkout@v6 + with: + ref: ${{ needs.create-release-branch.outputs.release-branch }} + fetch-depth: 0 + + - name: Generate changelog prompt + id: changelog-prompt + run: | + PREV_TAG="${{ needs.create-release-branch.outputs.prev-tag }}" + TAG="${{ github.ref_name }}" + + # Generate git diff data + git diff --stat "$PREV_TAG"..HEAD > git-diff-stats.txt + git log --oneline "$PREV_TAG"..HEAD > git-commits.txt + + # Create prompt file (plain text, no markdown code blocks) + cat > claude-prompt.txt << 'EOF_PROMPT' + You are a technical writer creating release notes for a blockchain node software project called ev-node. + Analyze the provided git changes and generate a clear, comprehensive changelog in markdown format. + + Follow these guidelines: + - Start with a brief summary of the release + - Group changes by category: Features, Bug Fixes, Performance, Documentation, etc. + - Use clear, concise bullet points + - Highlight breaking changes prominently if any + - Include technical details that would help developers understand the changes + - Format as clean markdown suitable for a GitHub release + + Generate a changelog for this release based on the following git changes: + + Commits: + EOF_PROMPT + + cat git-commits.txt >> claude-prompt.txt + + cat >> claude-prompt.txt << 'EOF_PROMPT' + + File Statistics: + EOF_PROMPT + + cat git-diff-stats.txt >> claude-prompt.txt + + cat >> claude-prompt.txt << 'EOF_PROMPT' + + Please generate a well-formatted changelog in markdown that summarizes these changes for users and developers. + EOF_PROMPT + + # Encode for GitHub (escape special characters) + { + echo 'prompt<> $GITHUB_OUTPUT + - name: Create GitHub Release uses: softprops/action-gh-release@v2 with: @@ -261,7 +364,7 @@ jobs: - [ ] Add **Upgrade Priority** (Critical/High/Medium/Low) - [ ] Add **General Description** of the release - - [ ] Review and refine the **Changelog** below + - [ ] Enhance the **Changelog** using Claude (see prompt below) - [ ] Document **Tested Upgrade Paths** (which versions were tested in E2E) - [ ] Verify Docker images are available - [ ] Publish announcements in Slack and Telegram after publishing @@ -270,7 +373,22 @@ jobs: ### Changelog - ${{ needs.generate-changelog.outputs.changelog }} + A basic changelog is available in: `apps/${{ needs.create-release-branch.outputs.app-path }}/CHANGELOG.md` + + **To enhance the changelog with Claude AI:** + 1. Open your IDE with Claude integration + 2. Copy the prompt below and send it to Claude + 3. Replace the changelog in `apps/${{ needs.create-release-branch.outputs.app-path }}/CHANGELOG.md` with Claude's output + 4. Commit and push the changes to the release branch: `${{ needs.create-release-branch.outputs.release-branch }}` + +
+ 📋 Click to expand Claude Prompt + + ``` + ${{ steps.changelog-prompt.outputs.prompt }} + ``` + +
--- @@ -283,8 +401,8 @@ jobs: ### Release Branch - A release branch has been created for your review: `${{ needs.generate-changelog.outputs.release-branch }}` + A release branch has been created for your review: `${{ needs.create-release-branch.outputs.release-branch }}` - You can checkout this branch to make edits to the changelog before merging. + You can checkout this branch to review and enhance the changelog before merging. env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/RELEASE.md b/RELEASE.md index 94f8814a3e..28adc98cdb 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -10,6 +10,7 @@ This document covers the release process for ev-node components: ## Support Policy **Version Support:** + - We provide support for **two major versions** (current and previous) - Supported versions receive: - Security fixes @@ -17,6 +18,7 @@ This document covers the release process for ev-node components: - Older versions are considered end-of-life and will not receive updates **Example:** + - If current version is v2.x.x, we support v2.x.x and v1.x.x - When v3.0.0 is released, v1.x.x reaches end-of-life @@ -29,25 +31,79 @@ This document covers the release process for ev-node components: When a SemVer-compliant tag is pushed (matching pattern `**/v*.*.*`), the GitHub workflow automatically: 1. ✅ Creates a new branch `release/` from the tagged commit -2. ✅ Generates changelog from `./CHANGELOG.md` using [git-cliff](https://github.com/orhun/git-cliff) -3. ✅ Commits the generated changelog to the release branch -4. ✅ Builds multi-platform Docker images (amd64, arm64) -5. ✅ Publishes images to GitHub Container Registry (GHCR) -6. ✅ Creates a draft GitHub Release with the generated changelog +2. ✅ Analyzes git changes since the last tag (commits, diffs, file statistics) +3. ✅ Generates a basic structured changelog (grouped by conventional commit types) +4. ✅ Commits the generated changelog to the release branch +5. ✅ Creates a Pull Request for the release branch +6. ✅ Builds multi-platform Docker images (amd64, arm64) +7. ✅ Publishes images to GitHub Container Registry (GHCR) +8. ✅ Creates a draft GitHub Release with a Claude AI prompt for manual enhancement ### Manual Steps After the automated workflow completes: -1. 📝 Review the release branch `release/` -2. 📝 Edit and refine the generated changelog if needed -3. 📝 Add **recommended upgrade priority** (Critical/High/Medium/Low) -4. 📝 Add **general description** of the release -5. 📝 Ensure **tested upgrade paths** are documented (1-2 lines in changelog) -6. ✅ Merge the release branch or update the GitHub Release directly -7. ✅ Publish the GitHub Release (change from draft to published) -8. 📢 Publish announcement message in **public Slack channel** -9. 📢 Publish announcement message in **public Telegram channel** +1. 📝 Review the Pull Request for `release/` +2. 📝 (Optional) Enhance the changelog using Claude AI: + - Copy the Claude prompt from the draft GitHub Release + - Use it in your IDE with Claude integration + - Update the changelog file with the enhanced output + - Commit and push changes to the release branch +3. 📝 Edit and refine the generated changelog as needed +4. 📝 Add **recommended upgrade priority** (Critical/High/Medium/Low) to the GitHub Release +5. 📝 Add **general description** of the release to the GitHub Release +6. 📝 Ensure **tested upgrade paths** are documented (1-2 lines in changelog) +7. ✅ Merge the Pull Request to bring changelog into `main` +8. ✅ Update the draft GitHub Release with your refined changelog (if enhanced) +9. ✅ Publish the GitHub Release (change from draft to published) +10. 📢 Publish announcement message in **public Slack channel** +11. 📢 Publish announcement message in **public Telegram channel** + +### Release Branch Lifecycle + +The `release/` branch is automatically created and should follow this lifecycle: + +**1. Review and Refine (Before Publishing)** + +- Review the auto-generated changelog in the release branch +- Make any necessary edits to improve clarity +- Add upgrade priority, general description, and tested upgrade paths + +**2. Update GitHub Release** + +- Copy the refined changelog to the draft GitHub Release +- Verify all information is accurate + +**3. Publish Release** + +- Publish the GitHub Release (change from draft) + +**4. Merge Pull Request to Main** + +- **Always merge the Pull Request to bring the changelog into `main`** +- This keeps the repository's changelog files in sync +- Ensures the release notes are preserved in the repository +- The workflow creates a PR automatically for easy review and merge + +```bash +# Option 1: Merge via GitHub UI (recommended) +# Review the PR and click "Merge Pull Request" + +# Option 2: Merge via command line +git checkout main +git pull origin main +git merge release/evm/v0.2.0 +git push origin main + +# The release branch can be deleted after merging (GitHub will prompt you) +``` + +**Why merge back?** + +- Keeps CHANGELOG files updated in the repository +- Provides a git history of all releases +- Ensures the next release can build upon previous changelogs +- Makes changelog available for the next release ### Release Priority Guidelines @@ -65,24 +121,35 @@ When adding upgrade priority to releases, use these guidelines: ### Overview - **Source of Truth**: GitHub Releases (manually curated) -- **Base Document**: `./CHANGELOG.md` (maintained in repository) -- **Generation Tool**: [git-cliff](https://github.com/orhun/git-cliff) +- **Basic Generation**: Automated bash script (conventional commit grouping) +- **Enhancement Tool**: Claude AI (manual, via provided prompt) +- **Analysis Method**: Git commits, diffs, and file statistics since last tag ### Changelog Workflow -The release workflow automatically generates changelogs from `./CHANGELOG.md`: +The release workflow automatically generates a basic structured changelog: -1. When you push a tag, the workflow reads `./CHANGELOG.md` -2. Generates formatted release notes using git-cliff -3. Creates a new branch `release/` -4. Commits the generated changelog to this branch -5. Creates a draft GitHub Release with the changelog +1. When you push a tag, the workflow identifies the previous tag +2. Collects git commits, file statistics, and code diffs since the previous tag +3. Generates a structured changelog grouped by conventional commit types (feat, fix, chore, other) +4. Creates a new branch `release/` +5. Commits the basic changelog to this branch +6. Creates a Pull Request for review +7. Creates a draft GitHub Release with a Claude AI prompt for manual enhancement + +**The draft release includes:** + +- Basic changelog from the release branch +- A ready-to-use Claude prompt in a collapsible section +- Instructions for enhancing the changelog using Claude in your IDE **You can then:** -- Review the release branch and edit the changelog -- Refine the generated content -- Add additional context, upgrade instructions, or breaking changes -- Merge the branch or update GitHub Release directly + +- (Optional) Copy the Claude prompt and use it in your IDE to generate an enhanced changelog +- Update the changelog file in the release branch with Claude's output +- Review and edit the changelog as needed +- Merge the Pull Request to bring changes into `main` +- Update the GitHub Release with your final changelog ### Maintaining CHANGELOG.md @@ -98,36 +165,45 @@ All notable changes to this project will be documented in this file. ## [Unreleased] ### Added + - New feature X - New feature Y ### Changed + - Modified behavior of Z ### Fixed + - Bug fix for issue #123 ### Security + - Security patch for vulnerability ABC ### Tested Upgrades + - Tested: v0.2.x → v0.3.0 - Tested: v0.1.5 → v0.3.0 (multi-version jump) ## [0.3.0] - 2026-01-15 ### Added + - Feature A - Feature B ### Fixed + - Critical bug C ### Tested Upgrades + - Tested: v0.2.3 → v0.3.0 ``` **Categories:** + - **Added**: New features - **Changed**: Changes to existing functionality - **Deprecated**: Features marked for removal @@ -138,6 +214,36 @@ All notable changes to this project will be documented in this file. **Important:** Always include **Tested Upgrades** section in the changelog for each release, documenting which version upgrade paths were validated through E2E testing. +### Example: Documenting Tested Upgrades + +After running E2E upgrade tests, document the results in your changelog. This helps users understand which upgrade scenarios have been validated: + +**Good Examples:** + +```markdown +### Tested Upgrades + +- ✅ v1.0.0-beta.10 → v1.0.0-beta.11 (single version) +- ✅ v1.0.0-beta.9 → v1.0.0-beta.11 (skip version) +- ⚠️ v1.0.0-beta.8 → v1.0.0-beta.11 (requires manual data migration - see upgrade guide) +``` + +```markdown +### Tested Upgrades + +- ✅ v0.2.3 → v0.3.0 (standard upgrade) +- ✅ v0.2.0 → v0.3.0 (multi-version jump) +- ❌ v0.1.x → v0.3.0 (not supported - upgrade to v0.2.x first) +``` + +**What to include:** + +- Use ✅ for successful/recommended upgrades +- Use ⚠️ for upgrades that work but require special steps +- Use ❌ for unsupported/untested upgrade paths +- Note if manual intervention is required +- Link to upgrade guides for complex migrations + ### Commit Message Best Practices While the changelog is based on `./CHANGELOG.md`, following conventional commit messages helps with project organization: @@ -157,6 +263,7 @@ Mark breaking changes prominently in CHANGELOG.md: ```markdown ### Changed + - **BREAKING**: Sequencer interface now requires context parameter ``` @@ -169,6 +276,7 @@ Mark breaking changes prominently in CHANGELOG.md: **GitHub Releases** are the official source of truth for all releases. Each release should include: + - Version number and tag - **Upgrade Priority**: Critical/High/Medium/Low - **General Description**: Overview of the release @@ -243,25 +351,31 @@ Release deployable applications (EVM nodes, test apps, etc.) as Docker images. ```bash # 1. Ensure CI passes on main -# 2. Update CHANGELOG.md with release notes (including tested upgrade paths) -# 3. Create and push tag +# 2. Run E2E upgrade tests and document results +# 3. Create and push tag (workflow will generate changelog from git history) git tag evm/v0.2.0 git push origin evm/v0.2.0 # 4. Monitor workflow # GitHub → Actions → Release workflow -# 5. Review release branch (release/evm/v0.2.0) -git checkout release/evm/v0.2.0 -# Edit generated changelog if needed -git commit -am "Refine release notes" -git push +# 5. Review Pull Request (release/evm/v0.2.0) +# GitHub → Pull Requests → Review the automated PR -# 6. Complete GitHub Release (add priority, description) -# 7. Publish the release -# 8. Announce in Slack and Telegram +# 6. (Optional) Enhance changelog with Claude AI +# Copy prompt from draft GitHub Release +# Use in IDE with Claude, then update changelog file + +# 7. Merge Pull Request +# GitHub → Pull Requests → Merge PR (or use git commands) + +# 8. Complete GitHub Release (add priority, description, tested upgrade paths) +# 9. Publish the release +# 10. Announce in Slack and Telegram ``` +**Note:** The workflow generates a basic structured changelog automatically by grouping conventional commits. You can optionally enhance it using Claude AI via the provided prompt in the draft GitHub Release. Just ensure your commit messages are clear and descriptive. + ### Tag Format Use the tag format: `{app-name}/v{major}.{minor}.{patch}` @@ -294,7 +408,6 @@ When you push a tag, the release workflow automatically: - Dockerfile must exist at `./apps/{app-name}/Dockerfile` - Tag must match pattern `**/v*.*.*` - CI must pass on main branch -- `CHANGELOG.md` must be up-to-date --- @@ -437,7 +550,9 @@ go list -m github.com/evstack/ev-node/apps/evm@v0.3.0 git tag evm/v0.2.0 git push origin evm/v0.2.0 -# Review release branch, edit if needed +# Review Pull Request +# Optionally enhance with Claude AI (prompt in draft release) +# Merge PR # Complete GitHub Release with priority and description # Publish and announce in Slack and Telegram ``` @@ -450,7 +565,7 @@ git tag evm/v0.2.0 git tag testapp/v1.0.0 git push origin evm/v0.2.0 testapp/v1.0.0 -# Each triggers its own workflow and creates separate release branches +# Each triggers its own workflow, creates separate release branches and PRs ``` ### Scenario 3: Full Go Module Release @@ -468,7 +583,7 @@ git tag execution/evm/v0.3.0 && git push origin execution/evm/v0.3.0 # 4. Wait, update deps, then release apps git tag apps/evm/v0.3.0 && git push origin apps/evm/v0.3.0 -# 5. Review release branches and complete GitHub Releases +# 5. Review and merge Pull Requests, complete GitHub Releases # 6. Announce in Slack and Telegram ``` @@ -497,7 +612,10 @@ git push origin evm/v0.2.1 # Check workflow status # GitHub → Actions → Release -# Check release branch exists +# Check Pull Request exists +# GitHub → Pull Requests → release/evm/v0.2.0 + +# Or check release branch git fetch origin git checkout release/evm/v0.2.0 @@ -547,14 +665,20 @@ go get github.com/evstack/ev-node/core@v0.3.0 **"Release branch not created"** - Check workflow logs for errors -- Verify git-cliff configuration -- Ensure CHANGELOG.md exists and is properly formatted +- Verify previous tag detection is working correctly +- Ensure git history is accessible with full depth + +**"Pull Request creation failed"** + +- Check workflow logs for errors +- Verify repository permissions for github-actions bot +- Ensure the release branch was created successfully -**"Changelog generation failed"** +**"Claude prompt not showing in release"** -- Verify `./CHANGELOG.md` exists in repository root -- Check git-cliff configuration file -- Review workflow logs for specific errors +- Check the draft GitHub Release body +- Look for the collapsible "Click to expand Claude Prompt" section +- Verify git diff data was captured properly in the workflow ### Go Module Releases @@ -621,6 +745,7 @@ Use this checklist for each release: ## Release v0.3.0 Checklist ### Pre-Release + - [ ] All PRs merged to main - [ ] CI passing on main - [ ] CHANGELOG.md updated with tested upgrade paths @@ -629,14 +754,18 @@ Use this checklist for each release: - [ ] Replace directives removed ### Release + - [ ] Tag created and pushed - [ ] Workflow completed successfully -- [ ] Release branch reviewed -- [ ] Changelog refined (if needed) +- [ ] Pull Request created and reviewed +- [ ] Changelog enhanced with Claude (if desired) +- [ ] Changelog refined as needed +- [ ] Pull Request merged - [ ] Docker images verified - [ ] Go modules verified (if applicable) ### Post-Release + - [ ] GitHub Release published with: - [ ] Upgrade priority - [ ] General description @@ -663,7 +792,7 @@ Use this checklist for each release: 5. **Protected Branches**: Create version branches (e.g., `v0`, `v0.3`) for maintaining release history and backporting fixes. -6. **Release Branches**: The workflow automatically creates `release/` branches. These can be reviewed, edited, and merged or discarded after the release is published. +6. **Release Branches and Pull Requests**: The workflow automatically creates `release/` branches and corresponding Pull Requests. Review the PR, optionally enhance the changelog with Claude AI using the provided prompt, then merge the PR to bring changes into `main`. 7. **Changelog as Source**: The `./CHANGELOG.md` file in the repository is the base for all generated release notes. Keep it well-maintained and up-to-date. From f91abaa4ac69d397b2c242a04535defd5698c1e9 Mon Sep 17 00:00:00 2001 From: auricom <27022259+auricom@users.noreply.github.com> Date: Thu, 22 Jan 2026 18:48:11 +0100 Subject: [PATCH 6/6] recs --- RELEASE.md | 58 ++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 43 insertions(+), 15 deletions(-) diff --git a/RELEASE.md b/RELEASE.md index 28adc98cdb..817b1ddba0 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -46,16 +46,19 @@ After the automated workflow completes: 1. 📝 Review the Pull Request for `release/` 2. 📝 (Optional) Enhance the changelog using Claude AI: - Copy the Claude prompt from the draft GitHub Release - - Use it in your IDE with Claude integration - - Update the changelog file with the enhanced output + - Use one of these methods: + - **IDE:** Claude extension in VSCode, or Cursor/Zed with built-in support + - **CLI:** Use `claude-code` command (requires installation) + - **Web:** Paste prompt at [claude.ai](https://claude.ai) + - Update the changelog file with Claude's enhanced output - Commit and push changes to the release branch 3. 📝 Edit and refine the generated changelog as needed 4. 📝 Add **recommended upgrade priority** (Critical/High/Medium/Low) to the GitHub Release 5. 📝 Add **general description** of the release to the GitHub Release 6. 📝 Ensure **tested upgrade paths** are documented (1-2 lines in changelog) -7. ✅ Merge the Pull Request to bring changelog into `main` -8. ✅ Update the draft GitHub Release with your refined changelog (if enhanced) -9. ✅ Publish the GitHub Release (change from draft to published) +7. ✅ Update the draft GitHub Release with your refined changelog (if enhanced) +8. ✅ Publish the GitHub Release (change from draft to published) +9. ✅ Merge the Pull Request to bring changelog into `main` (before or after publishing - see below) 10. 📢 Publish announcement message in **public Slack channel** 11. 📢 Publish announcement message in **public Telegram channel** @@ -69,21 +72,33 @@ The `release/` branch is automatically created and should follow this - Make any necessary edits to improve clarity - Add upgrade priority, general description, and tested upgrade paths -**2. Update GitHub Release** +**2. Update and Publish GitHub Release** - Copy the refined changelog to the draft GitHub Release +- Add upgrade priority, general description, and tested upgrade paths - Verify all information is accurate +- Publish the GitHub Release (change from draft to published) -**3. Publish Release** +**3. Choose When to Merge** -- Publish the GitHub Release (change from draft) +- Decide whether to merge the PR before or after publishing (see option 4 below) +- Most teams prefer merging **after** publishing to ensure release notes are finalized **4. Merge Pull Request to Main** -- **Always merge the Pull Request to bring the changelog into `main`** -- This keeps the repository's changelog files in sync -- Ensures the release notes are preserved in the repository -- The workflow creates a PR automatically for easy review and merge +⏰ **Timing:** You can merge the PR either before or after publishing the GitHub Release: + +- **Option A (Recommended):** Merge **after** publishing the release + - Ensures the release notes are finalized before committing to main + - Release branch serves as a staging area for refinement + - Prevents premature changelog in repository + +- **Option B:** Merge **before** publishing the release + - Changelog is immediately available in main + - Useful if you want the changelog visible before the release is public + - Allows for faster iteration + +The key is to **always merge eventually** to keep changelogs in sync with repository history. ```bash # Option 1: Merge via GitHub UI (recommended) @@ -145,12 +160,23 @@ The release workflow automatically generates a basic structured changelog: **You can then:** -- (Optional) Copy the Claude prompt and use it in your IDE to generate an enhanced changelog +- (Optional) Enhance the changelog using Claude AI using one of these methods: + - **Option 1:** Use Claude in your IDE (VSCode with Claude extension, Cursor, Zed, or compatible IDE) + - **Option 2:** Use Claude Code CLI (`claude-code` command - requires installation) + - **Option 3:** Copy the prompt to [claude.ai](https://claude.ai) and paste results manually +- Copy the prompt from the collapsible section in the draft release +- Generate an enhanced changelog with Claude - Update the changelog file in the release branch with Claude's output - Review and edit the changelog as needed - Merge the Pull Request to bring changes into `main` - Update the GitHub Release with your final changelog +**Claude AI Setup:** +- **For IDE integration:** Install Claude extension for VSCode, or use Cursor/Zed which have built-in Claude support +- **For CLI usage:** Install Claude Code from [Anthropic's CLI tools](https://docs.anthropic.com/claude/docs/cli) +- **For web usage:** Simply visit [claude.ai](https://claude.ai) (requires Anthropic account) +- Note: API keys or subscriptions may be required depending on your usage method + ### Maintaining CHANGELOG.md Follow these best practices for maintaining `./CHANGELOG.md`: @@ -364,7 +390,8 @@ git push origin evm/v0.2.0 # 6. (Optional) Enhance changelog with Claude AI # Copy prompt from draft GitHub Release -# Use in IDE with Claude, then update changelog file +# Options: Use Claude in IDE (VSCode/Cursor/Zed), CLI (claude-code), or web (claude.ai) +# Update changelog file with enhanced output, commit and push # 7. Merge Pull Request # GitHub → Pull Requests → Merge PR (or use git commands) @@ -552,7 +579,8 @@ git push origin evm/v0.2.0 # Review Pull Request # Optionally enhance with Claude AI (prompt in draft release) -# Merge PR +# Options: IDE extension, CLI, or claude.ai +# Merge PR (before or after publishing - see workflow overview) # Complete GitHub Release with priority and description # Publish and announce in Slack and Telegram ```