Skip to content

feat(ci): add automated Epic documentation audit workflow#36294

Open
jdcmsd wants to merge 5 commits into
mainfrom
autodoc-action-addition
Open

feat(ci): add automated Epic documentation audit workflow#36294
jdcmsd wants to merge 5 commits into
mainfrom
autodoc-action-addition

Conversation

@jdcmsd

@jdcmsd jdcmsd commented Jun 23, 2026

Copy link
Copy Markdown
Member

This resolves #36293 by adding an automation that hopefully works. Testing on core-workflow-repo seemed entirely promising, so hopefully the change of environment won't add any complications!

All secrets (AUTODOC_*) have already been provisioned by moi.

This PR fixes: #36293

@github-actions

github-actions Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

🤖 Bedrock Review — us.deepseek.r1-v1:0

New Issues

  • 🔴 Critical: .github/workflows/issue_autodoc.yml:119 — Finalize step commits changes but never pushes them (local commit will be lost after job ends)
  • 🟠 High: .github/workflows/issue_autodoc.yml:44 — jq query fails when issue has no parent (parent is null), breaking preflight check for non-Epic issues
  • 🟠 High: .github/workflows/issue_autodoc.yml:70 — Missing contents: write permission (needed to push doc changes in finalize step)
  • 🟡 Medium: .github/workflows/issue_autodoc.yml:103 — Installs global npm package @anthropic-ai/claude-code without version pinning (security risk from untrusted package updates)

Run: #28055682450 · tokens: in: 2428 · out: 1767 · total: 4195

@claude

claude Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Claude finished @jdcmsd's task in 1m 42s —— View job


Rollback Safety Analysis

  • Gather context
  • Read rollback-unsafe categories reference
  • Get full PR diff
  • Analyze changes against unsafe categories
  • Apply appropriate label

Result: ✅ Safe To Rollback

This PR adds a single new GitHub Actions workflow file (.github/workflows/issue_autodoc.yml). It does not touch any of the rollback-unsafe categories:

Category Verdict
C-1 Structural Data Model Change ✅ No database tables or storage structures changed
C-2 Elasticsearch Mapping Change ✅ No ES mapping or indexing code
C-3 Content JSON Model Version ✅ No contentlet_as_json or model version changes
C-4 DROP TABLE / DROP COLUMN ✅ No schema drops
H-1 One-Way Data Migration ✅ No data transformations
H-2 RENAME TABLE / RENAME COLUMN ✅ No renames
H-3 PK Restructuring ✅ No primary key changes
H-4 New Field Type ✅ No new content type fields
H-5 Storage Provider Change ✅ No binary storage changes
H-6 DROP PROCEDURE / FUNCTION ✅ No stored procedure drops
H-7 NOT NULL Column Without Default ✅ No schema changes
H-8 VTL Viewtool Contract Change ✅ No viewtool changes
M-1 Column Type Change ✅ No column type changes
M-2 Push Publishing Bundle Format ✅ No bundle format changes
M-3 REST/GraphQL API Contract ✅ No API contract changes
M-4 OSGi Interface Change ✅ No OSGi changes

The change is purely additive CI/CD automation — a new workflow that runs on issue closure and calls the Claude Code CLI to generate Epic documentation. Rolling back to N-1 simply means this workflow no longer exists; no persistent data, schema, or contract is affected.

Label applied: AI: Safe To Rollback

@github-actions github-actions Bot added the Area : CI/CD PR changes GitHub Actions/workflows label Jun 23, 2026
Replace uv/Python-script-based eval and finalize steps with:
- Python3 stdlib context assembly using gh CLI and grep
- Shell finalize using gh issue comment, curl for dotCMS API,
  and git commit/push
- prompts/burlap.txt read directly via cat (no YAML parsing)
- Fix jq null parent bug in preflight guard

Eliminates dependency on dotcms-aios PR merge order.
@github-actions

github-actions Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

🤖 Bedrock Review — us.deepseek.r1-v1:0

null


Run: #28057893300 · tokens: in: 4830 · out: 2044 · total: 6874

@github-actions

github-actions Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

🤖 Bedrock Review — us.deepseek.r1-v1:0

null


Run: #28058153839 · tokens: in: 4830 · out: 2048 · total: 6878

- Fix -f → -F on gh api PATCH so the file is read, not sent literally
- Prepend <!-- autodoc-report --> marker in finalize before posting so
  idempotent edit lookup works (marker was not in the report itself)
- Add --paginate to comment lookup to search beyond the first page
- Use jq first // empty instead of | head -1 to avoid SIGPIPE
- Fix urlTitle awk to use sub() consistent with title/tags/seoDescription
- Remove -k (TLS bypass); add --fail-with-body to dotCMS curl calls
- Add comment clarifying AUTODOC_DOTCMS_API_TOKEN_AISEARCH is used by
  the Claude subprocess via burlap.txt, not directly by a workflow step
@github-actions

github-actions Bot commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

🤖 Bedrock Review — qwen.qwen3-next-80b-a3b

#### New Issues
- 🔴 Critical: `.github/workflows/issue_autodoc.yml:278` — `git commit` uses `|| true` to suppress failure, but `git push` follows unconditionally — if commit fails (e.g., no changes, network, permission), push still runs and may fail or push stale state; this breaks replay safety and causes inconsistent repo state
- 🔴 Critical: `.github/workflows/issue_autodoc.yml:249` — `curl` to dotCMS API uses `$URL_TITLE` directly in JSON query string without escaping — SQL injection risk via malicious URL title (e.g., `" OR 1=1 --`) — `DotConnect.addParam()` required, not string interpolation
- 🔴 Critical: `.github/workflows/issue_autodoc.yml:266` — `curl` to dotCMS API uses `$IDENTIFIER` directly in URL path — unvalidated input in HTTP endpoint — potential path traversal or injection if identifier contains malicious characters
- 🔴 Critical: `.github/workflows/issue_autodoc.yml:278` — `git push` runs without any auth or network timeout — if network fails mid-push, workflow continues silently; no retry, no rollback, no error handling — high blast radius for repo corruption
- 🟠 High: `.github/workflows/issue_autodoc.yml:198` — `awk` extracts `urlTitle` from report without validating format or length — if malformed, dotCMS API may reject or create invalid content, but failure is silent
- 🟠 High: `.github/workflows/issue_autodoc.yml:218` — `awk` extracts `title`, `tags`, `seoDescription` without validation — empty or malformed values may cause dotCMS API to reject request, but no fallback or error logging
- 🟠 High: `.github/workflows/issue_autodoc.yml:278` — `git push` without branch specification — assumes default branch, but workflow runs on detached HEAD after checkout — may push to wrong branch or fail silently
- 🟡 Medium: `.github/workflows/issue_autodoc.yml:119` — Installs global npm package `@anthropic-ai/claude-code` without version pinning (security risk from untrusted package updates) — still present from prior finding

#### Existing
- 🟡 Medium: `.github/workflows/issue_autodoc.yml:103` — Installs global npm package @anthropic-ai/claude-code without version pinning (security risk from untrusted package updates) — still present from prior finding

#### Resolved
- ✅ `.github/workflows/issue_autodoc.yml:119` — Prior finding about missing push was addressed by adding `git push`, but introduced new critical flaws — now resolved as original issue is superseded
- ✅ `.github/workflows/issue_autodoc.yml:44` — Prior finding about `parent` being null is irrelevant — this PR introduces a new workflow, not modifying the prior one
- ✅ `.github/workflows/issue_autodoc.yml:70` — Prior finding about missing write permission is resolved — this PR correctly sets `contents: read` and `issues: write` as needed

<!-- dotcms-review-findings:[{"sev":"🔴 Critical","loc":".github/workflows/issue_autodoc.yml:278","desc":"git commit uses || true and git push runs unconditionally — breaks replay safety and may push stale or corrupted state"},{"sev":"🔴 Critical","loc":".github/workflows/issue_autodoc.yml:249","desc":"Unescaped $URL_TITLE used in curl JSON query — SQL injection risk via malicious title"},{"sev":"🔴 Critical","loc":".github/workflows/issue_autodoc.yml:266","desc":"Unvalidated $IDENTIFIER used in dotCMS API URL — potential injection or path traversal"},{"sev":"🔴 Critical","loc":".github/workflows/issue_autodoc.yml:278","desc":"git push runs without timeout, retry, or error handling — high blast radius for repo corruption"},{"sev":"🟠 High","loc":".github/workflows/issue_autodoc.yml:198","desc":"urlTitle extracted via awk without validation — silent failure on malformed input"},{"sev":"🟠 High","loc":".github/workflows/issue_autodoc.yml:218","desc":"title, tags, seoDescription extracted via awk without validation — silent API rejection risk"},{"sev":"🟠 High","loc":".github/workflows/issue_autodoc.yml:278","desc":"git push runs without branch specification — may push to wrong branch on detached HEAD"},{"sev":"🟡 Medium","loc":".github/workflows/issue_autodoc.yml:119","desc":"Installs global npm package @anthropic-ai/claude-code without version pinning (security risk from untrusted package updates)"}] -->

Run: #28098358004 · tokens: in: 4664 · out: 1063 · total: 5727

- Make git push conditional on commit succeeding (|| true was causing
  unconditional push even when there was nothing new to commit)
- Add git push origin HEAD for explicit branch targeting
- Validate urlTitle is a URL slug before interpolating into JSON query
  (non-slug chars would break the shell-built -d payload)
- Validate IDENTIFIER matches UUID format before placing in URL
- Add comment on unpinned npm install explaining the tradeoff
@github-actions

github-actions Bot commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

🤖 Bedrock Review — qwen.qwen3-next-80b-a3b

#### New Issues
- 🔴 Critical: `.github/workflows/issue_autodoc.yml:218` — Unescaped `$URL_TITLE` used in curl JSON query — SQL injection risk via malicious title
- 🔴 Critical: `.github/workflows/issue_autodoc.yml:225` — Unvalidated `$IDENTIFIER` used in dotCMS API URL — potential injection or path traversal
- 🔴 Critical: `.github/workflows/issue_autodoc.yml:278` — git push runs without timeout, retry, or error handling — high blast radius for repo corruption
- 🔴 Critical: `.github/workflows/issue_autodoc.yml:278` — git push runs without branch specification — may push to wrong branch on detached HEAD
- 🟠 High: `.github/workflows/issue_autodoc.yml:198` — urlTitle extracted via awk without validation — silent failure on malformed input
- 🟠 High: `.github/workflows/issue_autodoc.yml:218` — title, tags, seoDescription extracted via awk without validation — silent API rejection risk
- 🟡 Medium: `.github/workflows/issue_autodoc.yml:119` — Installs global npm package @anthropic-ai/claude-code without version pinning (security risk from untrusted package updates)

#### Existing
- 🔴 Critical: `.github/workflows/issue_autodoc.yml:278` — git commit uses || true and git push runs unconditionally — breaks replay safety and may push stale or corrupted state
- 🔴 Critical: `.github/workflows/issue_autodoc.yml:249` — Unescaped $URL_TITLE used in curl JSON query — SQL injection risk via malicious title
- 🔴 Critical: `.github/workflows/issue_autodoc.yml:266` — Unvalidated $IDENTIFIER used in dotCMS API URL — potential injection or path traversal
- 🔴 Critical: `.github/workflows/issue_autodoc.yml:278` — git push runs without timeout, retry, or error handling — high blast radius for repo corruption
- 🟠 High: `.github/workflows/issue_autodoc.yml:198` — urlTitle extracted via awk without validation — silent failure on malformed input
- 🟠 High: `.github/workflows/issue_autodoc.yml:218` — title, tags, seoDescription extracted via awk without validation — silent API rejection risk
- 🟠 High: `.github/workflows/issue_autodoc.yml:278` — git push runs without branch specification — may push to wrong branch on detached HEAD
- 🟡 Medium: `.github/workflows/issue_autodoc.yml:119` — Installs global npm package @anthropic-ai/claude-code without version pinning (security risk from untrusted package updates)

#### Resolved
- ✅ `.github/workflows/issue_autodoc.yml:249` — URL_TITLE now validated with grep regex before use
- ✅ `.github/workflows/issue_autodoc.yml:266` — IDENTIFIER now validated with UUID regex before use

<!-- dotcms-review-findings:[{"sev":"🔴 Critical","loc":".github/workflows/issue_autodoc.yml:218","desc":"Unescaped $URL_TITLE used in curl JSON query — SQL injection risk via malicious title"},{"sev":"🔴 Critical","loc":".github/workflows/issue_autodoc.yml:225","desc":"Unvalidated $IDENTIFIER used in dotCMS API URL — potential injection or path traversal"},{"sev":"🔴 Critical","loc":".github/workflows/issue_autodoc.yml:278","desc":"git push runs without timeout, retry, or error handling — high blast radius for repo corruption"},{"sev":"🔴 Critical","loc":".github/workflows/issue_autodoc.yml:278","desc":"git push runs without branch specification — may push to wrong branch on detached HEAD"},{"sev":"🟠 High","loc":".github/workflows/issue_autodoc.yml:198","desc":"urlTitle extracted via awk without validation — silent failure on malformed input"},{"sev":"🟠 High","loc":".github/workflows/issue_autodoc.yml:218","desc":"title, tags, seoDescription extracted via awk without validation — silent API rejection risk"},{"sev":"🟡 Medium","loc":".github/workflows/issue_autodoc.yml:119","desc":"Installs global npm package @anthropic-ai/claude-code without version pinning (security risk from untrusted package updates)"}] -->

Run: #28098738596 · tokens: in: 5077 · out: 995 · total: 6072

@jdcmsd

jdcmsd commented Jun 24, 2026

Copy link
Copy Markdown
Member Author

Claude's roasting this bedrock review:

This one is the reviewer losing track of its own state, not new problems.

Look at the "Resolved" section — it correctly acknowledges that URL_TITLE and IDENTIFIER validation were fixed. Then in "New Issues" it flags the exact same concerns at lines 218 and 225, which are just the shifted line numbers of the same curl command and the same UUID check — both of which now sit after the validation guards we added. The reviewer saw the guards fix the old line numbers (249/266 → resolved) but then re-flagged the code they guard as if it were fresh unprotected code.

Same story for git push: we changed || true + unconditional push to a conditional if git commit; then git push origin HEAD; fi. The reviewer marks both the || true and the branch-spec concerns as "existing" — i.e. it doesn't recognize the fix — while simultaneously flagging them as new. It's reading the file inconsistently across the two passes.

The "git push without timeout/retry → repo corruption" finding has always been noise. A failed git push fails the step. Nothing corrupts.

Nothing in this report requires a code change. The only open item across all the reviews is npm version pinning, which we consciously chose to address with a comment rather than pinning to a stale version. If the team has a formal policy requiring pinned versions in workflow files, that's the one thing worth revisiting — but it's a policy call, not a bug.

jdcmsd added a commit to dotCMS/core-workflow-test that referenced this pull request Jun 24, 2026
Rewrites the `issue_autodoc.yml` workflow to eliminate the `uv` /
Python-script dependency, making it self-contained.

**What changed:**
- Removed: `Set up uv`, `Install autodoc dependencies`, `uv run python
finalize.py` steps
- Build eval context: Python3 stdlib + `gh` CLI in a heredoc (no pip, no
venv)
- Run Claude: unchanged — `claude --print --allowedTools Bash,Write <
/tmp/eval_context.md`
- Finalize: pure shell + inline Python3 heredocs for JSON payloads; `gh
issue comment` for posting; `curl` for dotCMS EDIT/NEW; `git push` for
committing
- Fixed jq null-parent bug in preflight guard
- Reads `prompts/burlap.txt` directly (no YAML parsing)

This mirrors the change in `dotCMS/core` PR dotCMS#36294 and resolves the
ordering dependency on the dotcms-aios PR.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AI: Safe To Rollback Area : CI/CD PR changes GitHub Actions/workflows

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

Add autodoc CI automation

2 participants