Address review feedback: - Sync scope lists between PR template and contributing guide - Add 'maintenance' to Other scopes in contributing guide - Add scope to the docs example for format consistency - Simplify rebase push example to drop unnecessary refspec mapping - Add 'text' language tag to trailer code fence (MD040) Assisted-By: Claude <noreply@anthropic.com> Signed-off-by: Aleksei Sviridkin <f@lex.la>
3.8 KiB
Contributing Conventions for AI Agents
Project-side conventions for commits, branches, and pull requests in Cozystack.
Checklist for Creating a Pull Request
- Commit message follows Conventional Commits format
- Commit is signed off with
--signoff - Branch is rebased on
upstream/main(no extra commits) - PR body includes description and release note
Commit Format
Follow Conventional Commits with --signoff:
git commit --signoff -m "type(scope): brief description"
Types: feat, fix, docs, style, refactor, perf, test, build, ci, chore
Scopes:
- System:
dashboard,platform,cilium,kube-ovn,linstor,fluxcd,cluster-api - Apps:
postgres,mariadb,redis,kafka,clickhouse,virtual-machine,kubernetes - Other:
api,hack,tests,ci,docs,maintenance
Breaking changes: append ! after type/scope (feat(api)!: ...) or add a BREAKING CHANGE: footer.
Examples:
git commit --signoff -m "feat(dashboard): add config hash annotations to restart pods on config changes"
git commit --signoff -m "fix(postgres): update operator to version 1.2.3"
git commit --signoff -m "docs(contributing): add installation guide"
AI Agent Attribution
When an AI agent authors or materially assists with a commit, add an Assisted-By: trailer naming the model:
Assisted-By: Claude <noreply@anthropic.com>
Assisted-By: GPT-5 <noreply@openai.com>
Assisted-By: Gemini <noreply@google.com>
This sits alongside the Signed-off-by: trailer produced by --signoff. Use one trailer per model if multiple contributed.
Rebasing on upstream/main
If the branch has extra commits, clean it up:
git fetch upstream
git checkout -b my-feature upstream/main
git cherry-pick <your-commit-hash>
git push -f origin my-feature
Pull Request Body
Fill in the template at .github/PULL_REQUEST_TEMPLATE.md. It includes the required release-note block.
Create the PR with gh pr create --title "type(scope): brief description" --body-file <file>.
Fetching Unresolved Review Comments
Cozystack uses GitHub review threads with resolution status. Only unresolved threads are actionable — resolved threads are already handled.
The REST endpoint /pulls/{pr}/reviews returns review summaries, not individual review comments. Use the GraphQL API to access reviewThreads with isResolved status:
gh api graphql -F owner=cozystack -F repo=cozystack -F pr=<PR_NUMBER> -f query='
query($owner: String!, $repo: String!, $pr: Int!) {
repository(owner: $owner, name: $repo) {
pullRequest(number: $pr) {
reviewThreads(first: 100) {
nodes {
isResolved
comments(first: 100) {
nodes {
id
path
line
author { login }
bodyText
url
createdAt
}
}
}
}
}
}
}' --jq '.data.repository.pullRequest.reviewThreads.nodes[] | select(.isResolved == false) | .comments.nodes[]'
Compact one-line variant:
gh api graphql -F owner=cozystack -F repo=cozystack -F pr=<PR_NUMBER> -f query='
query($owner: String!, $repo: String!, $pr: Int!) {
repository(owner: $owner, name: $repo) {
pullRequest(number: $pr) {
reviewThreads(first: 100) {
nodes {
isResolved
comments(first: 100) {
nodes {
path
line
author { login }
bodyText
}
}
}
}
}
}
}' --jq '.data.repository.pullRequest.reviewThreads.nodes[] | select(.isResolved == false) | .comments.nodes[] | "\(.path):\(.line // "N/A") - \(.author.login): \(.bodyText[:150])"'