ci(autodoc): route Claude execution through ai-workflows to fix Bedrock OIDC - #36842
ci(autodoc): route Claude execution through ai-workflows to fix Bedrock OIDC#36842jdcmsd wants to merge 18 commits into
Conversation
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.
- 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
- 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
Report lives as an issue comment — the repo copy is redundant. Removing the push also drops the write-scope requirement on AUTODOC_AIOS_CI.
Embed burlap.txt content directly in the workflow as a heredoc step. Update report path to /tmp — report is ephemeral, lives as issue comment. dotcms-aios checkout now solely serves vault epic context lookup.
- Add conservatism clause to prompt: if Epic lacks technical detail, set action none rather than hallucinating a draft - Restore <details> wrapping of doc draft in issue comment (was lost when post_report.py was replaced with inline shell)
- Replace label check for Epic with issue type check (github.event.issue.type.name)
- Update GraphQL parent lookup to use issueType { name } instead of labels
- Add id-token: write permission for Bedrock OIDC
- Replace npm install + claude --print with anthropics/claude-code-action@v1;
model and Bedrock role sourced from vars.BEDROCK_MODEL_ID / vars.BEDROCK_ROLE_ARN
- Split finalize into three discrete steps for easier auditing:
Post report comment / Apply doc update to dotCMS / Apply doc create to dotCMS
…log; not worth its own PR.
…tcms-aios checkout Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ck OIDC Restructures the autodoc job into prep → claude → finalize so that the Claude/Bedrock step runs inside dotCMS/ai-workflows/autodoc-executor.yml. This sets job_workflow_ref to the ai-workflows ref, satisfying the trust condition on GitHubActions-BedrockCodeReview that was blocking OIDC assumption. The claude job references autodoc-executor.yml@v3.5.0 — pending the next ai-workflows release after dotCMS/ai-workflows#<PR> merges. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
sfreudenthaler
left a comment
There was a problem hiding this comment.
These look good overall — nice work routing through ai-workflows to fix the OIDC trust issue, and the finalize step follows the same draft-then-apply pattern we landed for the changelog site publisher. Two things before this is ready to merge:
-
No human-edit guardrail on the update path (see inline comment below). My changelog publisher checks
modUseron the existing content and skips (with a visible skip marker) if the last edit wasn't made by the service account, specifically so the automation never clobbers a manual edit made in the dotCMS backend. This workflow's "Apply doc update to dotCMS" step has no equivalent check — it will overwrite thedocumentationfield unconditionally, and there's no log line or alert anywhere that would tell us it happened. Given Jamie (or anyone) could be hand-editing these pages between Epic closures, I'd want that guardrail before this runs against real content. -
Publish-gate question (also inline below): my changelog automation auto-publishes with no approval gate, but that's safe because the content is deterministic — the GitHub release body IS the site content, mechanically transformed. Here Claude is generating original documentation prose, so there's real hallucination risk. Before this merges I want to confirm what
AUTODOC_DOTCMS_BASE_URLpoints at and what the defaultEDIT/NEWworkflow actions actually do on theDotcmsDocumentationcontent type — does firing them here land the page in Draft/Review, or does it go straight to Published with no human in the loop? If it's the latter, we need either a review gate before publish, or to restrict this to a staging/review instance until there's human sign-off on the draft.
- Add modUser guardrail to the update path: fetch working inode before firing EDIT, skip with a clear log message if a human has an outstanding draft (live==false and modUser != CI Autodoc service account). Safe to proceed when live==true (no pending draft) or when the service account owns the working draft. - Move AUTODOC_DOTCMS_SITE_FOLDER from secrets.* to vars.* — non-sensitive config - Pass AUTODOC_DOTCMS_SITE_FOLDER as a with: input to the claude job Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… map - Pin actions/checkout (both instances) to 8ade135 # v4.2.2 - Pin actions/download-artifact to fa0a91b # v4.1.8 - Replace secrets: inherit on the claude job with an explicit map of only the three secrets autodoc-executor.yml actually declares, satisfying least-privilege (Semgrep secrets-inherit finding) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Not a credential — move from secrets.* to vars.* in both the executor with: block and the finalize job env, matching the AUTODOC_DOTCMS_SITE_FOLDER pattern already in place. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Summary
autodocjob intoprep → claude → finalizeso Claude/Bedrock runs insidedotCMS/ai-workflows/autodoc-executor.ymljob_workflow_refto theai-workflowsref, satisfying the trust condition onGitHubActions-BedrockCodeReviewthat was blocking OIDC assumption withNot authorized to perform sts:AssumeRoleWithWebIdentityprepandfinalizejobs run directly in this workflow and do not touch AWS/tmp/autodoc-report.md; passed between jobs via Actions artifactRoot cause
The IAM role's trust policy requires
job_workflow_refto matchdotCMS/ai-workflows/.github/workflows/*@refs/tags/*. When the Claude step ran directly insideissue_autodoc.yml,job_workflow_refwasdotCMS/core/.github/workflows/issue_autodoc.yml@...— a hard deny. Routing through theai-workflowsreusable workflow fixes the claim.Dependency
Merge
dotCMS/ai-workflows#65and tagv3.5.0before merging this PR. Theclaudejob referencesautodoc-executor.yml@v3.5.0.Test plan
dotCMS/ai-workflows#65is merged and taggedv3.5.0🤖 Generated with Claude Code