Files
twenty/.github/workflows/ci-app-docs-drift.yaml
T
martmull 57fb39ba00 ci: add app-docs drift check agent (#22696)
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)_

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/22696?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->

---------

Co-authored-by: Martin <martin@twenty.com>
2026-07-09 09:38:26 +00:00

132 lines
6.6 KiB
YAML

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 `<!-- app-docs-drift-check -->`.
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 }}"
}
}