From 8e0272105fdc32e922d3bd9d4844a6f415c5f078 Mon Sep 17 00:00:00 2001 From: Moudy Date: Tue, 5 May 2026 16:52:32 +0200 Subject: [PATCH] chore(ci): adopt conventional commits and auto-generated changelog --- .github/workflows/pr-title.yml | 26 ++++++++++++++++++ .github/workflows/release.yml | 49 ++++++++++++++++++++++++++++++++++ CONTRIBUTING.md | 15 +++++++++++ cliff.toml | 43 +++++++++++++++++++++++++++++ 4 files changed, 133 insertions(+) create mode 100644 .github/workflows/pr-title.yml create mode 100644 .github/workflows/release.yml create mode 100644 CONTRIBUTING.md create mode 100644 cliff.toml diff --git a/.github/workflows/pr-title.yml b/.github/workflows/pr-title.yml new file mode 100644 index 00000000..060c7cc1 --- /dev/null +++ b/.github/workflows/pr-title.yml @@ -0,0 +1,26 @@ +name: PR Title + +on: + pull_request: + types: [opened, edited, synchronize, reopened] + +jobs: + validate: + runs-on: ubuntu-latest + steps: + - uses: amannn/action-semantic-pull-request@v5 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + types: | + feat + fix + chore + docs + test + refactor + perf + build + ci + revert + requireScope: false diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..e967eed9 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,49 @@ +name: Release + +on: + push: + tags: ['v*'] + +permissions: + contents: write + +jobs: + release: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Generate this-release section + uses: orhun/git-cliff-action@v3 + id: cliff_latest + with: + config: cliff.toml + args: --latest --strip header + + - name: Generate full CHANGELOG.md + uses: orhun/git-cliff-action@v3 + with: + config: cliff.toml + args: --output CHANGELOG.md + + - name: Commit CHANGELOG.md to main + run: | + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + git fetch origin main + git checkout main + git add CHANGELOG.md + if git diff --cached --quiet; then + echo "No changelog changes" + else + git commit -m "chore: update CHANGELOG.md for ${{ github.ref_name }}" + git push origin main + fi + + - name: Create GitHub Release + uses: softprops/action-gh-release@v2 + with: + body: ${{ steps.cliff_latest.outputs.content }} + token: ${{ secrets.GITHUB_TOKEN }} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..18cbbb29 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,15 @@ +# Contributing + +## Commit message format + +This repo uses [Conventional Commits](https://www.conventionalcommits.org/). Pull request titles must match `type(scope): description`, or `type(scope)!: description` for breaking changes. Allowed types: `feat`, `fix`, `chore`, `docs`, `test`, `refactor`, `perf`, `build`, `ci`, `revert`. + +PR titles are checked by `.github/workflows/pr-title.yml` and used as the squash-merge commit subject, so the `main` branch log stays conventional by construction. + +Breaking changes are flagged with `!` after the type/scope, optionally with a `BREAKING CHANGE:` footer in the PR body describing the migration. `CHANGELOG.md` is auto-generated from these markers on every `v*` tag via `git-cliff`, and a GitHub Release is created with the same content. + +Examples: + +- `feat(nssa): add private PDA support` +- `fix(wallet): correct fee calculation` +- `feat(nssa)!: rename AccountId::from((prog, seed)) to AccountId::for_public_pda` diff --git a/cliff.toml b/cliff.toml new file mode 100644 index 00000000..6615a63c --- /dev/null +++ b/cliff.toml @@ -0,0 +1,43 @@ +[changelog] +header = """ +# 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). +""" +body = """ +{% if version %}\ +## [{{ version | trim_start_matches(pat="v") }}] - {{ timestamp | date(format="%Y-%m-%d") }} +{% else %}\ +## [Unreleased] +{% endif %}\ +{% for group, commits in commits | group_by(attribute="group") %} +### {{ group | upper_first }} +{% for commit in commits %}\ +- {% if commit.breaking %}**[BREAKING]** {% endif %}{{ commit.message | upper_first }}\ +{% if commit.breaking and commit.breaking_description %} ({{ commit.breaking_description }}){% endif %} +{% endfor %}\ +{% endfor %} +""" +trim = true + +[git] +conventional_commits = true +filter_unconventional = true +commit_parsers = [ + { message = "^feat", group = "Features" }, + { message = "^fix", group = "Bug Fixes" }, + { message = "^perf", group = "Performance" }, + { message = "^refactor", group = "Refactor" }, + { message = "^docs", group = "Documentation" }, + { message = "^test", group = "Testing" }, + { message = "^build", group = "Build" }, + { message = "^ci", group = "CI" }, + { message = "^chore", skip = true }, + { message = "^revert", group = "Revert" }, +] +filter_commits = false +tag_pattern = "v[0-9]*" +sort_commits = "newest"