Address review feedback from gemini-code-assist on docs/agents/contributing.md:11: Scope linters kept flagging valid scopes like 'agents' as unknown because the list read as exhaustive. Annotate it as examples (not exhaustive) and add 'agents' to the Other group so both humans and review bots stop tripping on scopes that are already in regular use across the repo history. Assisted-By: Claude <noreply@anthropic.com> Signed-off-by: Aleksei Sviridkin <f@lex.la>
5.2 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
- Ran
make generatein every package whosevalues.yaml,values.schema.json,Chart.yaml, orREADME.mdwas touched, and committed the regenerated files
Regenerate Artifacts Before Committing
Several files in each package are produced by make generate from values.yaml + values.schema.json and must stay in sync with the hand-edited sources:
packages/(apps|extra)/<name>/README.md— regenerated bycozyvalues-gen(parameter table, formatting).packages/(apps|extra)/<name>/values.schema.json—cozyvalues-genrewrites ordering and derived fields.packages/system/<name>-rd/cozyrds/<name>.yaml— produced byhack/update-crd.sh, whichmake generateinvokes.
Before committing edits to any of those sources, run make generate inside the package and stage the full diff:
make -C packages/<apps-or-extra>/<name> generate
git add packages/<apps-or-extra>/<name>/ packages/system/<name>-rd/
The repo's pre-commit CI job runs make generate in every package and then git diff --exit-code. Any unstaged generator output fails the job with exit code 123 and blocks the PR. Also rerun make generate after a git commit --amend if the amended change touched any of the sources above.
To locate packages a WIP branch likely needs to be regenerated:
git diff --name-only | xargs -n1 dirname | sort -u | grep ^packages/
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 (e.g., not exhaustive — use any scope that names the component you are touching):
- 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,agents,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])"'