Files
grm/AGENTS.md
T

5.2 KiB

AGENTS.md — Project Conventions for GRM

Build & Test Commands

make setup          # Create venv, install deps, set up hooks
make lint-all       # ruff + pyright + bandit + ansible-lint + checkmake
make pytest-cov     # Unit tests with 100% coverage enforcement
make test-unit      # Unit tests without coverage
make molecule       # All 6 scenarios on Ubuntu 22.04
make molecule-all   # All 6 scenarios on all 4 supported OSes
make test-all       # pytest-cov + molecule

Architecture

  • Python CLI (src/gitea_runner_manager/) — Click-based CLI that delegates to Ansible
  • Ansible Role (ansible/roles/gitea-runner/) — Idempotent role for rootless Docker runner setup
  • CI Scripts (scripts/) — Automation for auto-merge, post-merge, publishing, molecule distribution, PR reviews

PR Workflow (Mandatory)

Every change to master goes through this workflow. No exceptions.

1. Create Vikunja Task

Create a task in Vikunja project 6 to get a GRM-N identifier.

2. Create Branch

git checkout master && git pull
git checkout -b GRM-N-short-description

3. Implement Changes

  • Write code following conventions below
  • Write/update tests (100% coverage required)
  • Update documentation (CHANGELOG, README, AGENTS.md as needed)

4. Commit (Conventional Commits)

Branch commits use conventional commit format (no GRM-N: prefix):

feat: add new feature
fix: resolve bug
docs: update README

5. Push and Create PR

  • PR title format: GRM-N: <vikunja task title> (colon-separated)
  • PR body: summary of changes, Closes GRM-N
  • Add ready-to-merge label only after review is complete

6. Review the PR (Mandatory — Before Adding ready-to-merge Label)

Review the full diff (git diff master...HEAD) focusing on:

  • Functional completeness: Does the code do what it claims? Are all requirements met?
  • Edge cases: Are boundary conditions, empty inputs, error paths handled?
  • Technical excellence:
    • Architecture compliance and evolution
    • Single Responsibility Principle (SRP)
    • Deduplication (no copy-paste, single source of truth)
    • Code smells detection and removal
    • Best industry practices
    • Industry-grade code quality
    • Reusability
    • Clean code
    • Readability
    • Maintainability
    • Extensibility
  • Performance: No unnecessary allocations, O(n) vs O(n²), efficient data structures
  • Security: No secrets in logs/process list, input validation, no injection vectors
  • User experience: Clear error messages, intuitive CLI flags, helpful output
  • Documentation: Completeness and relevance of docs, CHANGELOG entries, AGENTS.md updates

Post review comments using scripts/review_pr.py:

REPO_TOKEN=<token> python3 scripts/review_pr.py <pr_number> <owner/repo> \
  --event REQUEST_CHANGES \
  --body "Review summary" \
  --comments-json comments.json

7. Address Review Comments

Fix each comment one by one, commit, and push. Re-review until satisfied.

8. Approve and Merge

Once all comments are addressed:

REPO_TOKEN=<token> python3 scripts/review_pr.py <pr_number> <owner/repo> \
  --event APPROVE \
  --body "All comments addressed. LGTM."

Then add the ready-to-merge label. The auto-merge workflow will:

  1. Wait for all CI checks to pass
  2. Squash-merge with title: GRM-N <conventional commit message> (space-separated)
  3. The post-merge workflow marks the Vikunja task as done

Title Format Summary

What Format Example
Branch name GRM-N-short-description GRM-33-add-pr-review-step
Branch commits <conventional commit> feat: add review script
PR title GRM-N: <vikunja task title> GRM-33: Add mandatory PR review step
Merge commit GRM-N <conventional commit> GRM-33 feat: add review script

Key Conventions

  • Python 3.12+ required (ruff/pyright target py312)
  • 100% test coverage required (--cov-fail-under=100)
  • Conventional commits on feature branches (no GRM-N: prefix)
  • Branch names must include GRM-N task ID
  • Line length: 120 chars
  • Secrets are passed via temp JSON files, never on the command line (CWE-214)
  • CI triggers only on opened and synchronize PR events (not labeled)

Ansible Role Structure

main.yml → systemd_check → user_setup → rootless_docker → install_runner → prune → integration_test
  • install_runner.yml handles: download, config, validate, register, service
  • main.yml handles: prune, integration_test (NOT install_runner — avoids duplicates)
  • systemctl --user tasks must be guarded by docker_rootless_setup
  • Template creation tasks are NOT guarded by docker_rootless_setup (they just create files)

Molecule Scenarios

6 scenarios: default, multi-instance, lifecycle, template-content, deregister, update 4 platforms: ubuntu-2204, ubuntu-2404, debian-12, archlinux Platform list is defined in scripts/distribute_molecule.py (single source of truth)

Known Issues

  • ansible-lint may warn about command-instead-of-module for systemctl --user calls — this is expected (systemd module doesn't support user services) and skipped in .ansible-lint
  • Molecule Docker driver may print "Event loop is closed" warnings on interrupt — harmless