event-catalog / event-catalog/agents
Add a `catalog-path` input: the action requires eventcatalog.config.js at the catalog repo root
- Dominant language
- TypeScript
- Stars
- 40
- Forks
- 2
- PR merge metrics
- No merged PRs in 30d
Description
Thanks for shipping this — the two-phase plan/apply split is a nice design, and the
read-only planning phase made it easy to evaluate safely.
I hit a hard blocker while trialling `code-to-docs` against a catalog repository whose
`eventcatalog.config.js` does not sit at the repository root. The catalog lives in a
subdirectory (say `catalog/`), because the same repository also carries tooling and CI
config that shouldn't be inside the catalog itself. As far as I can tell from the source
there's currently no way to express that layout, and the run aborts before the agent does
any work.
## Reproduction
1. A catalog repository laid out as:
```
.
├── catalog/
│ ├── eventcatalog.config.js
│ ├── events/
│ └── services/
└── package.json
```
2. A producing repository with a workflow calling the action:
```yaml
- uses: event-catalog/agents@main
with:
agent: code-to-docs
catalog-repo: /
catalog-token: ${{ secrets.CATALOG_TOKEN }}
```
3. Open a pull request in the producing repository that changes a file the agent should
document.
**Expected:** the agent plans and applies documentation changes against the catalog root
at `catalog/`, then opens a pull request on the catalog repository.
**Actual:** the run exits immediately with
```
EventCatalog directory is missing, empty, or does not contain eventcatalog.config.js
```
and posts that as the pull-request summary. No plan, no catalog PR.
## Why
The catalog path is fixed at two points and isn't exposed as an input:
- `action.yml:52` — the catalog repo is checked out to `path: eventcatalog`.
- `action.yml:67` — `EVENTCATALOG_CATALOG_PATH: eventcatalog`, hardcoded rather than
wired to an input.
`resolveCatalogPath` (`src/utils/eventcatalog-utils.ts:39-41`) resolves that against the
workspace, and `inspectCatalogDirectory` (`:44` onwards) then requires
`eventcatalog.config.js` *directly* inside it — `ready` is
`exists && entries.length > 0 && hasConfig`, with `configPath` built as
`join(catalogPath, 'eventcatalog.config.js')`. `pr-review.ts:36-37` treats a non-`ready`
inspection as a hard stop.
Net effect: the checkout directory and the EventCatalog root are required to be the same
directory, so `eventcatalog.config.js` must be at the root of whatever repo `catalog-repo`
names. Credit where it's due — this fails fast, cheaply, and with a message that names the
missing file, which is much better than failing halfway through.
## One thing to watch if you add the input
A `catalog-path` input on its own would move the failure later rather than fix it, because
the authorization guard normalises in a different coordinate space:
- `pr-review.ts:106` collects written files via `getChangedCatalogFiles(catalogPath)` —
the **resolved** path. That runs `git status --porcelain` with `cwd` set to it
(`eventcatalog-utils.ts:115-117`), and porcelain reports paths relative to the **repo
root**, not to `cwd`. With a nested catalog root those come back as
`catalog/events/Foo/index.mdx`.
- `pr-review.ts:107` passes `config.catalogPath` — the **raw** input — into
`getUnauthorizedCatalogChanges`, and `normalizeCatalogPath`
(`src/utils/impact-plan.ts:3-16`) strips exactly one literal `${catalogRoot}/` prefix.
Plan targets are documented as relative to the EventCatalog root, so they arrive as
`events/Foo/index.mdx`.
Those two never converge for a nested root, so `isCatalogChangeAllowedByTarget` returns
false for every legitimately written file, and the run ends with *"the agent changed files
outside the approved impact plan"* — after `applyDocumentationPlan` at `:105` has already
been paid for, and with a message that reads as agent misbehaviour rather than a path
mismatch. Today this is latent: because the checkout dir and the catalog root coincide,
the prefix strip is a harmless no-op and both call sites happen to agree.
## Suggested shape
- Add a `catalog-path` input (default `.`), interpreted relative to the catalog checkout,
and pass it through to `EVENTCATALOG_CATALOG_PATH` — keeping the checkout `path` itself
stable so nothing else moves.
- Make the guard's normalisation use the same coordinate space as the git call: either
compare against the resolved catalog root, or prefix plan targets with the
catalog-relative-to-repo-root segment before comparing.
- Optionally, when the config isn't found, mention in the error that the config must be at
the configured catalog path — the current wording sent me looking for a broken checkout
rather than an unsupported layout.
Happy to test a branch against the layout above if that's useful.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start with action.yml, src/utils/eventcatalog-utils.ts, src/utils/impact-plan.ts, and pr-review.ts to trace checkout paths, catalog resolution, and authorization checks. Reproduce the nested catalog layout from the issue, then verify that the configured path reaches inspection and that changed files are compared in the same coordinate space before a catalog pull request is opened.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- github-actions, typescript
- Domain
- ci-cd, devops
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 58/100