-
Notifications
You must be signed in to change notification settings - Fork 152
[ci] Add AGENTS.md and CLAUDE.md for AI agent guidance #3846
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
rebtoor
wants to merge
1
commit into
openstack-k8s-operators:main
Choose a base branch
from
rebtoor:agents
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+300
−0
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,297 @@ | ||
| # AGENTS.md | ||
|
|
||
| ## What is this repository | ||
|
|
||
| CI-Framework is an Ansible collection (`cifmw.general`) that bootstraps | ||
| development and CI environments for RHOSO (Red Hat OpenStack Services on | ||
| OpenShift). It is **not** intended for production or long-lived deployments. | ||
|
|
||
| The upstream repository lives at | ||
| `https://github.com/openstack-k8s-operators/ci-framework`. | ||
|
|
||
| ## Tech stack | ||
|
|
||
| - **Ansible** collection (requires `ansible-core >= 2.15`). | ||
| - **Python 3** modules and plugins under `plugins/`. | ||
| - **Molecule** + Podman for per-role testing. | ||
| - **ansible-test** for unit, sanity, and integration tests on plugins. | ||
| - **Sphinx** for documentation (hosted on ReadTheDocs). | ||
| - **Zuul**, **GitHub Actions**, and **Prow** for CI. | ||
|
|
||
| ## Repository layout | ||
|
|
||
| | Path | Description | | ||
| |---|---| | ||
| | `roles/` | Ansible roles. Each has `defaults/`, `tasks/`, `molecule/`, `README.md`. | | ||
| | `playbooks/` | Domain-specific playbooks in subdirectories (`adoption/`, `ceph/`, `bgp/`, etc.). Legacy numbered-stage playbooks are deprecated -- orchestration is handled by the `cifmw_setup` role. | | ||
| | `plugins/` | Collection plugins: `action/`, `filter/`, `modules/`, `module_utils/`. Test with `ansible-test`, not Molecule. | | ||
| | `tests/` | `ansible-test` suites: `unit/` (pytest), `integration/targets/`, `sanity/ignore.txt`. | | ||
| | `ci/` | CI-only playbooks: content provider, EDPM, kuttl, architecture validation, doc build, log collection. | | ||
| | `scenarios/` | Scenario-oriented variable packs used by framework flows. | | ||
| | `scripts/` | Environment setup, Molecule runner, ansible-test runner, Zuul/Molecule generation, snippet checks. | | ||
| | `docs/` | Sphinx sources under `docs/source/`. | | ||
| | `hooks/` | Hook playbooks consumed by the framework. Some hooks have their own `roles/` subdirectory. | | ||
| | `custom/` | Local overrides (gitignored except `README.md`). Safe for local dev experiments, never committed. | | ||
| | `containerfiles/` | Podman images for CI (`Containerfile.ci`, `Containerfile.tests`). | | ||
| | `group_vars/` | Shared group variables (e.g., `all.yml`). Changes here affect every playbook run. | | ||
| | `zuul.d/` | Zuul job and project definitions. **Some files are generated -- see below.** | | ||
| | `_skeleton_role_/` | Template used by `ansible-galaxy role init` when creating new roles. | | ||
|
|
||
| ## Critical rules | ||
|
|
||
| ### Variable naming | ||
|
|
||
| All Ansible role variables **must** match the pattern `^cifmw_[a-z_][a-z0-9_]*$` | ||
| where after the `cifmw_` prefix comes the role name, then the variable name | ||
| (e.g., `cifmw_my_role_some_setting`). | ||
| This is enforced by `ansible-lint` with `strict: true` and `profile: production`. | ||
|
|
||
| ### FQCN required | ||
|
|
||
| All module calls must use fully-qualified collection names. | ||
| The following FQCN rules are enabled in `.ansible-lint`: | ||
| `fqcn-builtins`, `fqcn[action]`, `fqcn[action-core]`, `fqcn[canonical]`, `fqcn[deep]`. | ||
|
|
||
| ### Generated files -- do not hand-edit | ||
|
|
||
| The following files are **generated** by `scripts/create_role_molecule.py`: | ||
|
|
||
| - `zuul.d/molecule.yaml` | ||
| - `zuul.d/projects.yaml` (molecule section) | ||
|
|
||
| To regenerate: `make role_molecule`. To verify consistency: `make check_zuul_files`. | ||
| If you hand-edit these files, CI will reject the change. | ||
|
|
||
| ### Read-only / generated paths | ||
|
|
||
| Do **not** modify these paths directly: | ||
|
|
||
| | Path | Reason | | ||
| |---|---| | ||
| | `zuul.d/molecule.yaml` | Generated by `scripts/create_role_molecule.py`. | | ||
| | `zuul.d/projects.yaml` | Generated (molecule section). | | ||
| | `custom/` | Gitignored. Local-only overrides, never committed. | | ||
| | `hooks/playbooks/roles/` | Excluded from ansible-lint. Owned by hook authors. | | ||
|
|
||
| All other paths (`roles/`, `playbooks/`, `plugins/`, `group_vars/`, `scenarios/`, | ||
| `hooks/playbooks/`, `ci/`, `scripts/`, `docs/`) are safe to edit following the | ||
| conventions in this file. | ||
|
|
||
| ### Debugging patterns | ||
|
|
||
| Use `block`/`rescue`/`always` for complex task sequences. Dump relevant | ||
| variables in the `rescue` block, then `ansible.builtin.fail` to stop | ||
| execution. This makes CI failures much easier to diagnose. | ||
|
|
||
| ### Do not be too verbose | ||
|
|
||
| There is no need to provide explanation for each variable in each task file. | ||
| It is enough when the variable description is available in the role README | ||
| file. Add comments only to complex code. | ||
|
|
||
| ### Do not create too many variables | ||
|
|
||
| Balance the amount of variables: there is no need to create additional | ||
| variables especially for static values that are only used once by another | ||
| module or role. In that case, fewer variables means more clarity. | ||
|
|
||
| ### Make tasks easier to debug | ||
|
|
||
| Tasks should not do too many things in a single step -- on failure that | ||
| becomes difficult to debug. In some cases, adding more small, fast tasks | ||
| is better than one large task. Add debug messages only in very complex | ||
| places, not everywhere. | ||
|
|
||
| ## Playbooks | ||
|
|
||
| Do not rely on the `playbooks/` directory as the primary orchestration layer. | ||
| The numbered-stage playbooks (`01-bootstrap.yml`, `02-infra.yml`, etc.) are | ||
| **deprecated** -- orchestration is now handled by the `cifmw_setup` role. | ||
|
|
||
| The `playbooks/` directory still contains: | ||
| - **Subdirectories** (`adoption/`, `ceph/`, `bgp/`, `dcn/`, `multi-namespace/`) | ||
| with domain-specific flows. | ||
| - **Standalone playbooks** (`hooks.yml`, `update.yml`, `dcn.yml`, `nfs.yml`, | ||
| `switches_config.yml`, etc.) for specific operations. | ||
|
|
||
| ## Creating a new role | ||
|
|
||
| Always use the Makefile: | ||
|
|
||
| ``` | ||
| make new_role ROLE_NAME=my_role | ||
| ``` | ||
|
|
||
| This generates the skeleton, Molecule config, and updates Zuul jobs. | ||
| Every new role must have: | ||
|
|
||
| 1. A `README.md` documenting its parameters. | ||
| 2. Molecule test scenarios. | ||
| 3. Documentation that builds cleanly (checked in CI). | ||
|
|
||
| If the role cannot be tested via Molecule, remove the `molecule/` directory | ||
| and run `make role_molecule` to regenerate Zuul jobs. Add a note in the | ||
| role's `README.md` explaining why. | ||
|
|
||
| ## Testing | ||
|
|
||
| ### Commands | ||
|
|
||
| | Command | What it does | | ||
| |---|---| | ||
| | `make pre_commit` | Runs pre-commit hooks (shellcheck, black, ansible-lint) with dependency install. | | ||
| | `make molecule` | Runs Molecule tests for all roles with dependency install. | | ||
| | `make ansible_test` | Runs ansible-test (units + sanity + integration) with dependency install. | | ||
| | `make tests` | Runs pre-commit + Molecule. | | ||
| | `make check_zuul_files` | Regenerates Zuul YAML and fails if it differs from committed files. | | ||
| | `make docs` | Builds Sphinx documentation under `docs/_build/html/`. | | ||
| | `make spelling` | Runs `pyspelling` on docs. | | ||
| | `make plugin-development-enable` | Rewrites import paths and sets `PYTHONPATH` for local plugin dev. | | ||
| | `make plugin-development-disable` | Reverts the changes made by `plugin-development-enable`. | | ||
|
|
||
| ### Container-based testing (requires Podman) | ||
|
|
||
| | Command | What it does | | ||
| |---|---| | ||
| | `make run_ctx_pre_commit` | Pre-commit in a container. | | ||
| | `make run_ctx_molecule` | Molecule in a container. | | ||
| | `make run_ctx_ansible_test` | ansible-test in a container. | | ||
| | `make run_ctx_all_tests` | All of the above. | | ||
|
|
||
| ### Molecule specifics | ||
|
|
||
| - Config: `.config/molecule/config_podman.yml` (host) or `config_local.yml` (container). | ||
| - Test a single role: `TEST_SINGLE_ROLE=my_role make molecule` or `make run_ctx_molecule`. | ||
| - Molecule scenarios live under `roles/<name>/molecule/`. | ||
|
|
||
| ### Validation priority | ||
|
|
||
| When verifying a change, run checks in this order: | ||
|
|
||
| 1. `pre-commit run --all-files` — fast lint pass (ansible-lint, black, shellcheck). | ||
| 2. `TEST_SINGLE_ROLE=<role> make molecule` — targeted Molecule test. | ||
| 3. `make ansible_test` — plugin unit/sanity/integration tests (only if plugins changed). | ||
| 4. `make docs` — only if documentation was modified. | ||
|
|
||
| ### macOS limitations | ||
|
|
||
| The Makefile test targets (`make tests`, `make molecule`, `make ansible_test`, | ||
| `make setup_tests`, `make setup_molecule`, and their `_nodeps` variants) **do not | ||
| work on macOS**. The underlying scripts use `readlink -f`, which is not available | ||
| on macOS. These targets are designed for Linux CI environments only. | ||
|
|
||
| ## Linting and code style | ||
|
|
||
| - **ansible-lint**: `production` profile, `strict: true`. Config in `.ansible-lint`. | ||
| - **Python**: Formatted with `black`. | ||
| - **Shell**: Checked with `shellcheck` (severity=error, excludes SC2071). | ||
| - **Pre-commit**: Config in `.pre-commit-config.yaml`. Run with `make pre_commit` or `make run_ctx_pre_commit`. | ||
| - **Spelling**: `pyspelling` on docs. Run with `make spelling`. | ||
|
|
||
| ### Excluded from linting | ||
|
|
||
| ansible-lint skips: `.github/`, `scripts/`, `docs/`, `containerfiles/`, `ci/`, | ||
| and the generated Zuul files (`zuul.d/projects.yaml`, `zuul.d/molecule.yaml`). | ||
|
|
||
| ## Commit conventions | ||
|
|
||
| - **Title**: Must begin with the role name in brackets or parentheses: | ||
| `[my_role] Add feature X` or `(my_role) Fix bug Y`. | ||
| If changes span multiple roles, use `[multiple]` or `(multiple)`. | ||
| For cross-cutting changes use a category: `[ci]`, `[docs]`, `[Feature]`. | ||
|
danpawlik marked this conversation as resolved.
|
||
| - **Body**: Must be longer than 10 characters and describe **why** the change | ||
| was made. | ||
| - **Sign-off**: Required (`git commit --signoff`). The sign-off certifies a | ||
| [DCO](https://developercertificate.org/). AI agents cannot sign off on behalf | ||
| of a human -- the committer must add it themselves or amend the commit. | ||
| - **AI attribution**: Use `Co-Authored-By:` for substantial AI-generated code, | ||
| `Assisted-By:` for minor AI help. Disclose the scope in the PR description. | ||
| - **Ticket references**: Link Jira cards in the commit message body: | ||
| `Closes: ANVIL-123` (resolves the ticket) or | ||
| `Related-Issue: #OSPRH-12345` (related but does not close). | ||
| - **Cross-repo dependencies**: When a change depends on an unmerged PR/MR in | ||
| another repository, add `Depends-On: <PR-or-MR-URL>` in the PR/MR | ||
| description. Zuul uses this to test the changes together. | ||
|
|
||
| ### Commit strategy | ||
|
|
||
| To keep a clean git history, prefer a single commit per feature or fix: | ||
|
|
||
| 1. Create the initial commit normally. | ||
| 2. For subsequent changes on the same branch, amend the existing commit | ||
| (`git commit --amend`) instead of creating new ones. | ||
| 3. After amending, use `git push --force` to update the remote branch. | ||
|
|
||
| Never push directly to `main` — it is a protected branch. Always work on | ||
| a feature branch. Force pushing is only appropriate for **solo feature | ||
| branches**, never for `main` or shared branches. | ||
|
danpawlik marked this conversation as resolved.
|
||
|
|
||
| If a change is not directly related to the main goal of the pull request | ||
| but is required for it to work, add it as a **separate commit**. When | ||
| amending, be careful to edit only the commits that belong to the same | ||
| pull request. | ||
|
|
||
| ## Branch workflow | ||
|
|
||
| - The default branch is `main`. | ||
| - Feature work happens on topic branches. | ||
| - PRs target `main` unless otherwise specified. | ||
| - Branch names should be descriptive (e.g., `fix-reproducer-pull-secret`, | ||
| `feature/OSPRH-12345-new-role`). | ||
|
|
||
| ## PR process | ||
|
|
||
| - PRs are auto-set to draft on open. To undraft, push a non-`nit:` change. | ||
| - Minimum **2 approvals** required (excluding the author). | ||
| - Security-sensitive code requires additional maintainer review. | ||
| - Ownership is defined in `OWNERS` and `OWNERS_ALIASES`. | ||
|
|
||
| ## Relationship to ci-framework-jobs | ||
|
|
||
| The `ci-framework-jobs` repository holds downstream Zuul job definitions that | ||
| consume this repository. Jobs in that repo declare | ||
| `required-projects: openstack-k8s-operators/ci-framework` and | ||
| `roles: zuul: openstack-k8s-operators/ci-framework` so Zuul checks out this | ||
| repo and exposes its roles during job execution. Uni jobs orchestrate this | ||
| repo's `reproducer.yml` playbook as their main entry point. | ||
|
|
||
| When making changes here that affect CI behavior, coordinate with the | ||
| corresponding job definitions in `ci-framework-jobs`. | ||
|
|
||
| ## Plugin development | ||
|
|
||
| To develop collection plugins locally without installing the collection: | ||
|
|
||
| ``` | ||
| make plugin-development-enable | ||
| ``` | ||
|
|
||
| This rewrites import paths and sets `PYTHONPATH`. Revert with: | ||
|
|
||
| ``` | ||
| make plugin-development-disable | ||
| ``` | ||
|
|
||
| Plugins are tested with `ansible-test`, not Molecule. | ||
|
|
||
| ## Documentation first | ||
|
|
||
| Before searching the web or relying on general knowledge, check local | ||
| documentation: | ||
| - `docs/source/` — Sphinx sources for the ci-framework collection. | ||
| - Role-level `README.md` files under `roles/<name>/`. | ||
| - The downstream CI docs repository at | ||
| `https://gitlab.cee.redhat.com/ci-framework/docs` covers job types, | ||
| pipelines, troubleshooting, and glossary. | ||
|
|
||
| ## Confirm before acting | ||
|
|
||
| Before performing expensive or broad-impact operations, confirm with the | ||
| user first: | ||
|
|
||
| - Running full test suites (`make tests`, `make molecule`) — ask whether a | ||
| targeted run (`TEST_SINGLE_ROLE=<role>`) is sufficient. | ||
| - Modifying `group_vars/all.yml` — changes here affect every playbook run. | ||
| - Editing roles used by multiple playbooks — flag the blast radius. | ||
| - Cross-repo changes that require coordinated updates in `ci-framework-jobs` | ||
| or `architecture`. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| # CLAUDE.md | ||
|
|
||
| @AGENTS.md |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.