From 57fb39ba00f84056772cba5f2292a8cc9cdeaae7 Mon Sep 17 00:00:00 2001 From: martmull Date: Thu, 9 Jul 2026 11:38:26 +0200 Subject: [PATCH] ci: add app-docs drift check agent (#22696) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Part 8 (final) of the app-docs audit series. The preceding PRs (#22688–#22695) fixed the drift that had already accumulated between the app platform and its docs — wrong commands, nonexistent import paths, missing enum values, stale scaffold descriptions. This PR adds the guardrail that keeps it from accumulating again. ## What it does `ci-app-docs-drift.yaml` runs on PRs that touch the app-development surface: - `packages/twenty-sdk/**` (CLI commands/flags, `define*` configs, front-component runtime) - `packages/create-twenty-app/**` (scaffold template and flags) - `packages/twenty-client-sdk/**` (public client surface) - `packages/twenty-shared/src/application/**` and `src/types/**` (manifest types and enum value sets) It launches a Claude agent (same `anthropics/claude-code-action` + `CLAUDE_CODE_OAUTH_TOKEN` setup as the existing `claude.yml`) with a prompt that: 1. Reads the PR diff and filters for genuinely user-facing changes (new/renamed commands or flags, config properties, enum values, exports, env vars, template files) — implementation-only changes short-circuit to "no impact". 2. Follows a source-area → docs-page mapping to read the relevant pages under `packages/twenty-docs/developers/extend/apps/`, and checks whether the PR already updates them correctly. 3. Posts **one sticky comment** (marker-based, updated in place on subsequent pushes): either "no documentation impact" or a table of `Change / Docs page / Status / Suggested fix`. ## Guardrails - Read-only tool allowlist plus `gh pr comment` / `gh api` — the agent cannot edit code or docs, only report. - Skips fork PRs (secrets unavailable) and bot-authored PRs. - `--max-turns 60`, 30-minute timeout, per-ref concurrency with cancel-in-progress. The exhaustive audit that motivated this (every command, flag, export, and enum cross-checked between docs and source, plus a scaffolded app tested against a live server) is exactly the loop this workflow automates in miniature on every relevant PR. --- _Generated by [Claude Code](https://claude.ai/code/session_01ExboyDAT19khDuKXaYXETT)_ Review in cubic --------- Co-authored-by: Martin --- .github/workflows/ci-app-docs-drift.yaml | 131 +++++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 .github/workflows/ci-app-docs-drift.yaml diff --git a/.github/workflows/ci-app-docs-drift.yaml b/.github/workflows/ci-app-docs-drift.yaml new file mode 100644 index 0000000000..84130ad699 --- /dev/null +++ b/.github/workflows/ci-app-docs-drift.yaml @@ -0,0 +1,131 @@ +name: CI App Docs Drift + +# When a PR changes the app-development surface (twenty-sdk, create-twenty-app, +# twenty-client-sdk, or the shared manifest types), an agent checks whether the +# app documentation under packages/twenty-docs/developers/extend/apps is +# impacted and posts a single sticky comment with its findings. + +on: + pull_request: + +permissions: + contents: read + id-token: write + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + changed-files-check: + uses: ./.github/workflows/changed-files.yaml + with: + files: | + packages/twenty-sdk/** + packages/create-twenty-app/** + packages/twenty-client-sdk/** + packages/twenty-shared/src/application/** + packages/twenty-shared/src/types/** + + docs-drift-check: + needs: changed-files-check + # Secrets are unavailable on fork PRs; skip there and on bot PRs. + if: >- + needs.changed-files-check.outputs.any_changed == 'true' && + github.event.pull_request.head.repo.full_name == github.repository && + github.event.pull_request.user.type != 'Bot' + timeout-minutes: 30 + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: write + id-token: write + steps: + - name: Checkout repository + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 + with: + fetch-depth: 0 + + - name: Run docs drift agent + uses: anthropics/claude-code-action@ac7e24bf2938964b8ab203e417a2773802392ddd # v1.0.146 + with: + claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} + claude_args: '--max-turns 60 --allowedTools "Bash(git diff *),Bash(git log *),Bash(git show *),Bash(grep *),Bash(cat *),Bash(ls *),Bash(find *),Bash(head *),Bash(tail *),Bash(gh pr comment *)"' + prompt: | + You are the app-documentation drift checker for the twenty repository. + + A pull request changed files in the app-development platform. Your job is to + decide whether the documentation under + `packages/twenty-docs/developers/extend/apps/` (English pages only — ignore + `packages/twenty-docs/l/`) is impacted, and report your findings as ONE pull + request comment. + + ## Step 1 — Understand the change + + The PR branch is checked out with full history; the base branch is + `origin/${{ github.base_ref }}`. Inspect what the PR changes however you + see fit. Only these kinds of changes are documentation-relevant: + + - CLI commands, subcommands, flags, defaults, or help text + (`packages/twenty-sdk/src/cli/commands/**`) + - `define*` function signatures, config properties, validation rules, + or their warnings (`packages/twenty-sdk/src/sdk/define/**`) + - Enum / string-union values and manifest types + (`packages/twenty-shared/src/application/**`, `packages/twenty-shared/src/types/**`) + - Exports added/removed/renamed in the `exports` maps of `twenty-sdk` or + `twenty-client-sdk` package.json, or in their public entry points + - Front-component runtime hooks and host API + (`packages/twenty-sdk/src/sdk/front-component/**`) + - The scaffold template (`packages/create-twenty-app/src/constants/template/**`) + and scaffolder flags/prompts (`packages/create-twenty-app/src/cli.ts`, + `create-app.command.ts`) + - Environment variables injected into logic functions or front components + - Error codes surfaced to app developers + + Internal refactors, tests, and implementation-only changes are NOT relevant — + if the changes contain only those, say so and stop. + + ## Step 2 — Map to documentation + + Use this mapping to know which pages to check (read the actual pages): + + | Source area | Docs pages | + |---|---| + | CLI commands (`src/cli/commands`) | `operations/cli.mdx`, `getting-started/quick-start.mdx`, `operations/sync-and-recovery.mdx`, `getting-started/local-server.mdx`, `getting-started/scaffolding.mdx` | + | `defineObject`/`defineField`/relations/indexes | `data/*.mdx` | + | `defineApplication`/roles/install hooks/variables | `config/*.mdx` | + | Logic functions, triggers, connections, agents/skills | `logic/*.mdx` | + | Views, navigation, page layouts, front components, command menu | `layout/*.mdx` | + | Publish/install/deploy, versioning, engines | `operations/publishing.mdx`, `operations/sync-and-recovery.mdx` | + | Testing APIs (`twenty-sdk/cli` operations) | `operations/testing.mdx` | + | Scaffold template | `getting-started/project-structure.mdx`, `getting-started/quick-start.mdx`, `operations/testing.mdx`, `operations/publishing.mdx` | + | client SDK (`core`/`metadata`/`rest`/`generate`) | `logic/logic-functions.mdx`, `layout/front-components.mdx`, `operations/cli.mdx` | + | Enum value sets (FieldType, ViewType, availabilityType, NavigationMenuItemType, ...) | the page documenting that value set (search for the enum name) | + + Also check whether the PR already updates the impacted docs pages — if it + does, verify the update matches the code change. + + ## Step 3 — Report + + Post exactly one comment on PR #${{ github.event.pull_request.number }} with: + `gh pr comment ${{ github.event.pull_request.number }} --edit-last --create-if-none --body ...` + (this updates the previous drift-check comment in place on subsequent runs). + Start the comment body with the marker ``. + + Comment format: + - Title line: `### App docs drift check` + - If no documentation impact: one sentence saying so and why. + - If impacted: a table with columns **Change** (what changed in the code), + **Docs page** (repo-relative path), **Status** (`✅ already updated in this PR` + / `⚠️ needs update`), and **Suggested fix** (one concrete sentence, e.g. the + exact value to add to a table). + - Be terse. No preamble, no sign-off. Only report genuine drift — if unsure + whether something is user-facing, say it's uncertain rather than asserting. + + Environment: GH_TOKEN is available for `gh`. The PR branch is checked out. + settings: | + { + "env": { + "GH_TOKEN": "${{ secrets.GITHUB_TOKEN }}" + } + }