Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
5 changes: 3 additions & 2 deletions .agents/skills/ui-expose-attribute/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,9 @@ new page or section instead of a field: references/new-page.md.
do not run the bundler — report the UI build as unverified (CI builds it on
every PR).** The check the skill must run: `npm ci && npm run build` from
`src/cockpit/389-console`. The production bundle is built on every PR (inside
the RPM tarball step), so a broken import fails all CI even though CI runs no
JS lint or test. `npm run eslint` is advisory. **Never run `npm run prettier:fix`** — there is no prettier config, so
the RPM tarball step), so a broken import fails the Build job of both pytest
workflows even though CI runs no JS lint or test; a UI-only PR then runs just
the `webui` suite. `npm run eslint` is advisory. **Never run `npm run prettier:fix`** — there is no prettier config, so
it mass-reformats with defaults that fight eslint. **Never edit `cockpit_dist/`** —
it is a generated copy of `dist/`.

Expand Down
5 changes: 3 additions & 2 deletions .agents/skills/verify-changes/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,13 @@ Verify: every gate exits 0 — check with `echo $?` after each.
| Rust crates (src/, src/plugins/) | cargo tests + the affected pytest suite |
| lib389 or dsconf/dsctl/dsidm/dscreate | static gates + the clu suite |
| dirsrvtests | static gates + the suite you touched |
| Cockpit UI (src/cockpit/389-console/) | npm build (+ audit) |
| Cockpit UI (src/cockpit/389-console/) | npm build (+ audit) + the webui suite on both backends; a UI-only PR runs no other suite |

## Reference: the CI commands, check by check

Everything below is taken from the CI workflow files (pytest.yml, lmdbpytest.yml,
compile.yml, cargotest.yml, validate.yml, npm.yml) and rpm.mk — passing them means
compile.yml, cargotest.yml, validate.yml, npm.yml, codeql.yml; nightly-dispatch.yml
only re-runs the pytest pair on release branches) and rpm.mk — passing them means
passing in CI. **This is documentation of what the build/test skill must achieve,
not commands to run directly on an unprepared host** (step 1). Background:
docs/agents/building.md and docs/agents/testing.md.
Expand Down
9 changes: 6 additions & 3 deletions .agents/skills/verify-changes/references/container-recipe.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,20 @@ Every command in a code block is copied character-exact from .github/workflows/p
(differences in lmdbpytest.yml are noted). CI splits this into two jobs: "Build" runs
*inside* the quay.io/389ds/ci-images:test image as a GitHub Actions container job;
"BDB Test" drives docker from the runner. Locally one systemd container serves both
stages; `podman` accepts the same flags wherever `sudo docker` appears.
stages; `podman` accepts the same flags wherever `sudo docker` appears. CI pulls the
image first in a five-attempt backoff loop because quay.io pulls time out transiently
(issue 7528); locally a plain pull is fine.

## Stage 1 — start the systemd test container (run from the repo root)

CID=$(sudo docker run -d -h server.example.com --ulimit core=-1 --cap-add=SYS_PTRACE --privileged --rm --shm-size=4gb -v ${PWD}:/workspace quay.io/389ds/ci-images:test)
CID=$(sudo docker run -d -h server.example.com --ulimit core=-1 --cap-add=SYS_PTRACE --privileged --rm --shm-size=4gb --sysctl net.ipv4.ip_local_reserved_ports=38900-39399 -v ${PWD}:/workspace quay.io/389ds/ci-images:test)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick: The recipe claims to document the CI container flow and describes the five-attempt pull backoff, but its executable recipe contains no docker pull retry loop; following the recipe still relies on an implicit pull from docker run, which fails immediately on a transient quay.io timeout instead of retrying.

Triggers: When a developer follows the container recipe during a transient quay.io image-pull timeout.

Suggested fix: Add the workflow's character-exact five-attempt docker pull loop before the docker run command, or clearly state that the loop is intentionally omitted from the local recipe.

Suggested change
CID=$(sudo docker run -d -h server.example.com --ulimit core=-1 --cap-add=SYS_PTRACE --privileged --rm --shm-size=4gb --sysctl net.ipv4.ip_local_reserved_ports=38900-39399 -v ${PWD}:/workspace quay.io/389ds/ci-images:test)
for i in 1 2 3 4 5; do
sudo docker pull quay.io/389ds/ci-images:test && break
if [ "$i" -eq 5 ]; then
echo "Image pull failed after $i attempts"
exit 1
fi
echo "Pull failed, retrying in $((i * 15))s..."
sleep $((i * 15))
done
CID=$(sudo docker run -d -h server.example.com --ulimit core=-1 --cap-add=SYS_PTRACE --privileged --rm --shm-size=4gb --sysctl net.ipv4.ip_local_reserved_ports=38900-39399 -v ${PWD}:/workspace quay.io/389ds/ci-images:test)


Flag by flag: `-d` detached; `-h server.example.com` the hostname tests expect;
`--ulimit core=-1` unlimited core dumps; `--cap-add=SYS_PTRACE` lets debuggers and
sanitizers attach; `--privileged` needed for systemd and instance management; `--rm`
autodelete on stop; `--shm-size=4gb` large /dev/shm for the databases;
`-v ${PWD}:/workspace` mounts the checkout. The image boots systemd — wait for it
`--sysctl net.ipv4.ip_local_reserved_ports=38900-39399` keeps the test instances' ports out
of the kernel's ephemeral range; `-v ${PWD}:/workspace` mounts the checkout. The image boots systemd — wait for it
(verbatim loop; it prints failures until ready):

until sudo docker exec $CID sh -c "systemctl is-system-running"
Expand Down
8 changes: 6 additions & 2 deletions docs/agents/building.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,22 @@ The build jobs run in a prebuilt `quay.io/389ds/ci-images` container (`:test` or

| Workflow | Trigger | Key command |
|---|---|---|
| `pytest.yml` | push (`main`, `389-ds-base-*`), PR, nightly, manual | `SKIP_AUDIT_CI=1 make -f rpm.mk dist-bz2 rpms` in the `:test` image, then one `py.test` job per suite on the BDB backend |
| `pytest.yml` | PR, nightly on `main`, manual | `SKIP_AUDIT_CI=1 make -f rpm.mk dist-bz2 rpms` in the `:test` image, then one `py.test` job per suite on the BDB backend |
| `lmdbpytest.yml` | same | identical build; its test job exports `NSSLAPD_DB_LIB=mdb` to switch the backend and drops the read-only-BDB guard |
| `nightly-dispatch.yml` | nightly on `main` (00:30 UTC), manual | `gh workflow run` of `pytest.yml` and `lmdbpytest.yml` on each `389-ds-base-X.Y[.Z]` branch with a commit in the last 30 days, once per head whatever the result; release branches have no push or schedule trigger of their own |
| `compile.yml` | push, PR, manual | `autoreconf -fvi && ./configure` (no flags), `make V=0`, across a compiler/flag matrix: GCC, GCC Strict, GCC Static Analyzer (`-fanalyzer`), Clang, Clang `-Weverything` |
| `cargotest.yml` | push, PR, nightly, manual | `./configure --enable-debug`, `make V=0`, then `make check-local` |
| `npm.yml` | push, PR, nightly, manual | `npx --yes audit-ci --config audit-ci.json` in `src/cockpit/389-console` |
| `codeql.yml` | PR, push (`main`), weekly, manual | bare `./configure` + `make`; analyses C/C++ and Python only, with `+security-extended` queries |
| `validate.yml` | push, PR, manual | `testimony validate` over `dirsrvtests/tests/suites`, the duplicate-`:id:` check, and `vermin --target=3.8` over both `src/lib389` and `dirsrvtests` |
| `coverity.yml` | weekly cron only | bare `./configure`; the Coverity scan action drives `make` |
| `release.yml` | tag push `389-ds-base-*`, manual | `TAG=<tag> make -f rpm.mk dist-bz2`, then a GitHub release upload |
| `backport.yml` | merged PR carrying a `backport/X.Y` label | cherry-picks the squash commit onto `389-ds-base-X.Y` and opens the backport PR; a conflicting cherry-pick arrives as a draft PR with the markers committed |

Facts that change how you use these:

- A doc-only change runs no GitHub Actions workflow: every push- or PR-triggered workflow above ignores `**.md`, `docs/agents/**`, `docs/design/**`, `LICENSE*`, `.packit.yaml` and `.github/renovate.json`, while `docs/slapi.doxy.in` and the doxygen assets stay CI-visible because `make all` consumes them. Packit's COPR builds, the `rpm-build:*` checks, still run on such a PR because `.packit.yaml` has no path filter (`.github/workflows/pytest.yml` (`paths-ignore`); `.packit.yaml` (`copr_build`)).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick: The statement that a doc-only change runs no GitHub Actions workflow is false for a merged doc-only PR carrying a backport/X.Y label: backport.yml is triggered by pull_request_target on closed and processes that label regardless of changed paths.

Triggers: When a documentation-only PR is merged with a backport/X.Y label.

Suggested fix: Limit the statement to the build/test workflows, or explicitly mention the conditional backport workflow exception.

Suggested change
- A doc-only change runs no GitHub Actions workflow: every push- or PR-triggered workflow above ignores `**.md`, `docs/agents/**`, `docs/design/**`, `LICENSE*`, `.packit.yaml` and `.github/renovate.json`, while `docs/slapi.doxy.in` and the doxygen assets stay CI-visible because `make all` consumes them. Packit's COPR builds, the `rpm-build:*` checks, still run on such a PR because `.packit.yaml` has no path filter (`.github/workflows/pytest.yml` (`paths-ignore`); `.packit.yaml` (`copr_build`)).
- A doc-only change runs no build or test GitHub Actions workflow: every push- or PR-triggered build/test workflow above ignores `**.md`, `docs/agents/**`, `docs/design/**`, `LICENSE*`, `.packit.yaml` and `.github/renovate.json`, while `docs/slapi.doxy.in` and the doxygen assets stay CI-visible because `make all` consumes them. A merged doc-only PR carrying a `backport/X.Y` label is still processed by `backport.yml`, which runs on `pull_request_target` `closed`. Packit's COPR builds, the `rpm-build:*` checks, still run on such a PR because `.packit.yaml` has no path filter (`.github/workflows/pytest.yml` (`paths-ignore`); `.packit.yaml` (`copr_build`)).

- A PR that touches nothing outside `src/cockpit/389-console/` builds the RPMs and then runs only the `webui` suite, on both backends; a renamed file counts under both its paths, and any API failure falls back to the full matrix (`.github/scripts/pr_scope.py`; `.github/workflows/pytest.yml` (Check if the diff is limited to the Web UI step)).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue: The documentation says every UI-only PR runs the webui suite, but a UI-only PR whose only changed file is a Markdown file is filtered out by the workflows' **.md paths-ignore rule and runs no pytest workflow at all.

Triggers: When a UI-only PR changes only one or more *.md files under src/cockpit/389-console/.

Suggested fix: Qualify the statement to apply only when the PR contains at least one non-ignored UI file, or document the Markdown path-ignore exception.

Suggested change
- A PR that touches nothing outside `src/cockpit/389-console/` builds the RPMs and then runs only the `webui` suite, on both backends; a renamed file counts under both its paths, and any API failure falls back to the full matrix (`.github/scripts/pr_scope.py`; `.github/workflows/pytest.yml` (Check if the diff is limited to the Web UI step)).
- A PR that touches nothing outside `src/cockpit/389-console/` and includes at least one non-ignored UI file builds the RPMs and then runs only the `webui` suite, on both backends; a renamed file counts under both its paths, and any API failure falls back to the full matrix (`.github/scripts/pr_scope.py`; `.github/workflows/pytest.yml` (Check if the diff is limited to the Web UI step)).

- In a container, run `git config --global --add safe.directory "$PWD"` before any `rpm.mk` target — `dist-bz2` shells out to `git ls-files`, and without the safe-directory entry the tarball is silently empty (`.github/workflows/pytest.yml` (Add GITHUB_WORKSPACE as a safe directory step); `rpm.mk` (`dist-bz2`)).
- `dist-bz2` tars `git ls-files` output, so uncommitted changes are **excluded**; `rpms` rsyncs the working tree, so uncommitted changes are **included**. Testing an uncommitted patch requires the `rpms` path (`rpm.mk` (`dist-bz2`, `local-archive`)).
- Keep `dist-bz2` in the RPM command: `rpms` does not depend on `download-cargo-dependencies` (`dist-bz2` and `srpms` do), so `make -f rpm.mk rpms` alone can fail on a clean tree (`rpm.mk` (`rpms`)).
Expand Down Expand Up @@ -61,7 +65,7 @@ The shipping configuration is the RPM spec's `%configure`: `--enable-cmocka`, `-

## The pytest matrix

- Every directory under `dirsrvtests/tests/suites/` becomes one CI job; `replication` is split into one job per `*_test.py` file (`.github/scripts/generate_matrix.py`).
- Every directory under `dirsrvtests/tests/suites/` becomes one CI job; `replication` is split into one job per `*_test.py` file (`.github/scripts/generate_matrix.py`). That is the full run; a web-UI-only PR narrows it to `webui` and a manual dispatch to its `pytest_tests` value (see the trigger facts above).
- `dirsrvtests/tests/stress/`, `perf/` and `tickets/` are run by no workflow — the generator walks only `suites/`.
- The per-suite invocation, inside a privileged `:test` container with the freshly built RPMs installed:

Expand Down
4 changes: 3 additions & 1 deletion docs/agents/ui.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,9 @@ Run from `src/cockpit/389-console/` unless noted:
- There are no JS unit tests and no lint gate in CI, but the production build
runs on every PR inside the RPM build — a broken import fails it. The only
other JS gate is the dependency audit `npx audit-ci`
(`.github/workflows/npm.yml`). Playwright webui tests live under
(`.github/workflows/npm.yml`). A PR that touches nothing outside
`src/cockpit/389-console/` then runs only the `webui` pytest suite, on both
backends (`.github/scripts/pr_scope.py`). Playwright webui tests live under
`dirsrvtests/tests/suites/webui/` ([testing.md](testing.md)).
- esbuild writes `dist/`; packaging consumes `cockpit_dist/`, a generated
copy of it — never edit `cockpit_dist/` (generated-files table:
Expand Down