Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Working conventions for activegraph

## Commit messages — Conventional Commits (required going forward)

All new commits **and PR titles** must follow [Conventional Commits](https://www.conventionalcommits.org/):

```
type(optional-scope): short imperative subject
```
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated

PRs are **squash-merged**, so the PR title becomes the single commit on the
default branch — write the PR title as a conventional commit.

Types that appear in the generated changelog (see `cliff.toml`):

| type | Changelog section |
|--------|-------------------|
| `feat` | Added |
| `fix` | Fixed |
| `perf` | Performance |

Other valid types are fine but are **excluded** from the changelog:
`chore`, `ci`, `docs`, `refactor`, `test`, `style`, `build`, `revert`.

Examples:
- `feat(node): support composite id_property constraints`
- `fix(query): escape backticks in relationship type names`
- `perf: batch index lookups in schema inspection`
- `ci: skip the matrix on docs-only changes`

Reference a PR/issue in the subject as `(#1234)` — `cliff.toml` turns it into a link.

## CHANGELOG.md

- The `[Unreleased]` section is generated from conventional commits:
`rake changelog` (refresh) / `rake "changelog[v12.0.0.beta.8]"` (finalize a
version at release).
- The task is **non-destructive**: it only rewrites the top `[Unreleased]`/version
section and inserts it under the preamble. Everything below is **hand-written
history from before conventional commits were adopted — never regenerate or
overwrite it** (git-cliff can't reproduce those non-conventional commits).
29 changes: 20 additions & 9 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -55,19 +55,30 @@ task 'coverage' do
task.invoke
end

# Regenerate CHANGELOG.md from the commit history with git-cliff
# (https://git-cliff.org; `brew install git-cliff`). Run after merging PRs to
# refresh [Unreleased]; pass the release tag to finalize a version section:
# rake "changelog[v12.0.0.beta.7]"
desc 'Regenerate CHANGELOG.md from commits (git-cliff)'
# Refresh CHANGELOG.md's [Unreleased] section from conventional commits with
# git-cliff (https://git-cliff.org; `brew install git-cliff`). Non-destructive:
# generates only the new (unreleased) entries and inserts them under the
# preamble, leaving the hand-written history below untouched — activegraph's
# pre-conventional-commit history can't be regenerated. Pass the release tag to
# finalize the section as a version at release time:
# rake "changelog[v12.0.0.beta.8]"
desc 'Refresh CHANGELOG.md [Unreleased] from conventional commits (git-cliff)'
task :changelog, [:tag] do |_task, args|
cmd = %w[git cliff]
cmd = %w[git cliff --unreleased --strip all]
if (tag = args[:tag])
tag.match?(/\Av\d[\w.-]*\z/) or raise "Invalid tag #{tag.inspect} (expected e.g. v12.0.0.beta.7)" # rubocop:disable Style/AndOr
# array form (no shell) means the tag can't inject commands
tag.match?(/\Av\d[\w.-]*\z/) or raise "Invalid tag #{tag.inspect} (expected e.g. v12.0.0.beta.8)" # rubocop:disable Style/AndOr
cmd += ['--tag', tag]
end
# Pass args to sh as an array — no shell, so the tag can't inject commands.
sh(*cmd, '-o', 'CHANGELOG.md')
section = IO.popen(cmd, &:read).strip
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
# git-cliff still emits a bare `## [Unreleased]` heading with no entries when
# nothing matched — only touch the file when there's at least one entry.
abort 'git-cliff produced no entries (no conventional commits since the last release).' unless section.match?(/^- /)
Comment thread
klobuczek marked this conversation as resolved.
Outdated
changelog = File.read('CHANGELOG.md')
.sub(/^## \[Unreleased\].*?(?=^## \[)/m, '') # drop a stale [Unreleased] block
.sub(/^(?=## \[)/, "#{section}\n\n") # insert fresh section under the preamble
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
File.write('CHANGELOG.md', changelog)
Comment thread
klobuczek marked this conversation as resolved.
puts "Updated CHANGELOG.md:\n#{section}"
end

task default: ['spec']
Loading