diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6394579..113965b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,12 +19,12 @@ jobs: - uses: actions/checkout@v4 with: repository: Automattic/docs-agent - ref: 972ceb8a9ebcfafa1f88edc4fba173065415698a + ref: a39d9db230eb9e0b72ed84465f4d61bd8dda1bab path: .producer/docs-agent - uses: actions/checkout@v4 with: repository: Automattic/wp-codebox - ref: 6457dcae4cb8cf8e76cd174377de8cbee3ee12cb + ref: 12a5bb19a97b89d0a78b502fc71adede5b122359 path: .producer/wp-codebox - uses: pnpm/action-setup@v4 with: diff --git a/.github/workflows/developer-docs-agent.yml b/.github/workflows/developer-docs-agent.yml index 238646c..2d64b03 100644 --- a/.github/workflows/developer-docs-agent.yml +++ b/.github/workflows/developer-docs-agent.yml @@ -27,7 +27,7 @@ concurrency: jobs: developer-docs-agent: name: Maintain Developer Docs - uses: Automattic/docs-agent/.github/workflows/maintain-docs.yml@972ceb8a9ebcfafa1f88edc4fba173065415698a + uses: Automattic/docs-agent/.github/workflows/maintain-docs.yml@a39d9db230eb9e0b72ed84465f4d61bd8dda1bab with: audience: technical run_kind: ${{ github.event.inputs.run_kind || 'maintenance' }} @@ -35,6 +35,25 @@ jobs: base_ref: trunk docs_branch: docs-agent/build-with-wordpress-developer-docs writable_paths: README.md,docs/**,plugins/**/README.md + bootstrap_contract: | + { + "required_paths": ["README.md", "docs/README.md"], + "required_globs": [{"pattern": "docs/**/*.md", "min_count": 3}], + "entry_points": [{"path": "README.md", "must_link_to": ["docs/README.md"]}] + } + source_delta: | + [ + { + "id": "figma-studio-handoff-diagnostics", + "source_refs": [ + "https://github.com/Automattic/build-with-wordpress/pull/100", + "plugins/figma-to-wordpress-studio/src/payload.ts", + "plugins/figma-to-wordpress-studio/src/ui.ts", + "plugins/figma-to-wordpress-studio/tests/generate-artifact.test.mjs" + ], + "requires_documentation_change": true + } + ] verification_commands: | [ "pnpm install --frozen-lockfile", diff --git a/.github/workflows/skills-agent.yml b/.github/workflows/skills-agent.yml index 617effa..5cee21a 100644 --- a/.github/workflows/skills-agent.yml +++ b/.github/workflows/skills-agent.yml @@ -17,12 +17,13 @@ concurrency: jobs: skills-agent: name: Maintain Live Skills - uses: Automattic/docs-agent/.github/workflows/maintain-docs.yml@main + uses: Automattic/docs-agent/.github/workflows/maintain-docs.yml@a39d9db230eb9e0b72ed84465f4d61bd8dda1bab with: audience: skills base_ref: trunk docs_branch: docs-agent/build-with-wordpress-skills writable_paths: skills/**,plugins/**/skills/**,plugins/**/README.md + source_delta: '[{"id":"skills-source","source_refs":["skills/**","scripts/**","plugins/**/skills/**"],"requires_documentation_change":false}]' verification_commands: | [ "pnpm install --frozen-lockfile", diff --git a/docs/contributor-workflows.md b/docs/contributor-workflows.md index 05c2536..84a4ae0 100644 --- a/docs/contributor-workflows.md +++ b/docs/contributor-workflows.md @@ -156,7 +156,8 @@ Manual documentation runs default to maintenance and should make the smallest so - `workflow_dispatch` offers `run_kind` choices of `maintenance` (the default) and `bootstrap`; pushes to `trunk` run with `run_kind: maintenance`. - `docs_branch` is `docs-agent/build-with-wordpress-developer-docs` and `base_ref` is `trunk`. - writable documentation paths are limited to `README.md`, `docs/**`, and `plugins/**/README.md`. -- Docs Agent selects its native package from the reusable workflow revision pinned in this file: `Automattic/docs-agent/.github/workflows/maintain-docs.yml@972ceb8a9ebcfafa1f88edc4fba173065415698a`. +- Docs Agent selects its native package from the reusable workflow revision pinned in this file: `Automattic/docs-agent/.github/workflows/maintain-docs.yml@a39d9db230eb9e0b72ed84465f4d61bd8dda1bab`. +- maintenance is bounded to the known Figma Studio handoff diagnostics drift from [PR #100](https://github.com/Automattic/build-with-wordpress/pull/100) and requires an evidence-backed documentation update; bootstrap requires `README.md`, `docs/README.md`, at least three topic pages, and a README link to the docs index. - manual `workflow_dispatch` runs set `require_pr: true`; push-triggered maintenance runs do not require a PR and may finish with no changes when the documentation already matches source behavior. - verification commands are `pnpm install --frozen-lockfile`, `pnpm build`, and `pnpm verify`. - the developer-docs drift check is scoped to non-documentation paths: `git diff --exit-code -- . ':(top,exclude)README.md' ':(top,glob,exclude)docs/**' ':(top,glob,exclude)plugins/**/README.md'`. This means the build must not produce uncommitted generated-package or source changes outside the workflow's writable documentation paths. @@ -165,9 +166,9 @@ When changing the docs workflow, keep this contract aligned with the repository ### Skills workflow contract -`skills-agent.yml` uses the same reusable Docs Agent workflow with `audience: skills` from `Automattic/docs-agent/.github/workflows/maintain-docs.yml@main`. It is triggered manually and on a weekly Monday schedule, writes only to `skills/**`, generated skill copies under `plugins/**/skills/**`, and plugin README files, and runs the same install, build, and verify commands as the developer-docs workflow. Its drift check is intentionally broad: `git diff --exit-code`, so generated skill package output must be committed after the build. The workflow does not pass `run_kind` or `require_pr`; the native skills lane should make the smallest source-grounded skill update needed or finish with no changes when skills are current. Keep this workflow focused on live skill content; generated package structure and developer documentation belong in the technical docs workflow and the generator/verifier source. +`skills-agent.yml` uses the same pinned reusable Docs Agent workflow with `audience: skills`. It is triggered manually and on a weekly Monday schedule, writes only to `skills/**`, generated skill copies under `plugins/**/skills/**`, and plugin README files, and runs the same install, build, and verify commands as the developer-docs workflow. Its bounded source delta covers the live skill sources, package generator scripts, and packaged skill outputs, and permits an evidence-backed no-change result when those surfaces are current. Its drift check is intentionally broad: `git diff --exit-code`, so generated skill package output must be committed after the build. The workflow does not pass `run_kind` or `require_pr`; the native skills lane should make the smallest source-grounded skill update needed or finish with no changes when skills are current. Keep this workflow focused on live skill content; generated package structure and developer documentation belong in the technical docs workflow and the generator/verifier source. -The `CI` workflow provides automated validation for pull requests and pushes to `trunk` and `feat/native-docs-agent`. It checks out Docs Agent at `972ceb8a9ebcfafa1f88edc4fba173065415698a` and WP Codebox at `6457dcae4cb8cf8e76cd174377de8cbee3ee12cb`, installs pnpm 10.8.1, runs `pnpm test`, then runs `pnpm build` and `pnpm verify`. The workflow contract test rejects producer revision, reusable workflow, secret forwarding, writable path, verification command, drift check, or schema drift. This repository does not currently require the workflow as a merge gate. +The `CI` workflow provides automated validation for pull requests and pushes to `trunk` and `feat/native-docs-agent`. It checks out Docs Agent at `a39d9db230eb9e0b72ed84465f4d61bd8dda1bab` and the accepted WP Codebox reusable-workflow producer at `12a5bb19a97b89d0a78b502fc71adede5b122359`, installs pnpm 10.8.1, runs `pnpm test`, then runs `pnpm build` and `pnpm verify`. The workflow contract test rejects producer revision, reusable workflow, source-delta, bootstrap, secret forwarding, writable path, verification command, drift check, or schema drift. This repository does not currently require the workflow as a merge gate. ## Pull request checklist diff --git a/tests/docs-agent-workflows.test.mjs b/tests/docs-agent-workflows.test.mjs index 559da53..19d448d 100644 --- a/tests/docs-agent-workflows.test.mjs +++ b/tests/docs-agent-workflows.test.mjs @@ -4,10 +4,11 @@ import { readFile } from "node:fs/promises" import { resolve } from "node:path" const root = resolve(new URL("..", import.meta.url).pathname) -const docsAgentRevision = "972ceb8a9ebcfafa1f88edc4fba173065415698a" -const docsAgentPackageRevision = "85443eb91c12b2759d8e207f1ae4421407b4cc5e" -const wpCodeboxProducerRevision = "6457dcae4cb8cf8e76cd174377de8cbee3ee12cb" -const wpCodeboxWorkflowRef = "v0.12.28" +const docsAgentRevision = "a39d9db230eb9e0b72ed84465f4d61bd8dda1bab" +const docsAgentPackageRevision = "85f0d162a7d499fdc1286891371342727d084c88" +const wpCodeboxProducerRevision = "12a5bb19a97b89d0a78b502fc71adede5b122359" +const wpCodeboxWorkflowRef = wpCodeboxProducerRevision +const wpCodeboxReleaseRef = "v0.12.29" const docsAgentDir = process.env.DOCS_AGENT_DIR const wpCodeboxDir = process.env.WP_CODEBOX_DIR @@ -24,7 +25,7 @@ const docsAgentWorkflow = await readFile(resolve(docsAgentDir, ".github/workflow const wpCodeboxContract = await readJson(wpCodeboxDir, "contracts/run-agent-task-reusable-workflow-interface.v1.json") assert.equal(wpCodeboxContract.schema, "wp-codebox/reusable-workflow-interface/v1") assert.match(docsAgentWorkflow, new RegExp(`uses: Automattic/wp-codebox/.github/workflows/run-agent-task.yml@${wpCodeboxWorkflowRef}`)) -assert.match(docsAgentWorkflow, new RegExp(`wp_codebox_release_ref: ${wpCodeboxWorkflowRef}`)) +assert.match(docsAgentWorkflow, new RegExp(`wp_codebox_release_ref: ${wpCodeboxReleaseRef}`)) assert.match(docsAgentWorkflow, new RegExp(`DOCS_AGENT_PACKAGE_REVISION: ${docsAgentPackageRevision}`)) assert.match(docsAgentWorkflow, /OPENAI_API_KEY: \$\{\{ secrets\.OPENAI_API_KEY \}\}/) assert.match(docsAgentWorkflow, /ACCESS_TOKEN: \$\{\{ github\.token \}\}/) @@ -48,14 +49,18 @@ const workflows = [ revision: docsAgentRevision, writablePaths: "README.md,docs/**,plugins/**/README.md", driftCheck: "git diff --exit-code -- . ':(top,exclude)README.md' ':(top,glob,exclude)docs/**' ':(top,glob,exclude)plugins/**/README.md'", + sourceDelta: /"id": "figma-studio-handoff-diagnostics"[\s\S]*"https:\/\/github\.com\/Automattic\/build-with-wordpress\/pull\/100"[\s\S]*"requires_documentation_change": true/, + bootstrapContract: true, }, { path: ".github/workflows/skills-agent.yml", audience: "skills", runKind: false, - revision: "main", + revision: docsAgentRevision, writablePaths: "skills/**,plugins/**/skills/**,plugins/**/README.md", driftCheck: "git diff --exit-code", + sourceDelta: /"id":"skills-source".*"requires_documentation_change":false/, + bootstrapContract: false, }, ] @@ -84,6 +89,7 @@ for (const workflow of workflows) { assert.match(source, /pnpm verify/) assert.match(source, /validation_dependencies: npm install --global pnpm@10\.8\.1/) assert.ok(source.includes(`"command": "${workflow.driftCheck}"`), `${workflow.path} must use its scoped drift check`) + assert.match(source, workflow.sourceDelta, `${workflow.path} must declare its bounded source delta`) assert.match(source, /permissions:\n contents: write\n pull-requests: write\n issues: write/) assert.match(source, /OPENAI_API_KEY: \$\{\{ secrets\.OPENAI_API_KEY \}\}/) assert.match(source, /EXTERNAL_PACKAGE_SOURCE_POLICY: \$\{\{ secrets\.EXTERNAL_PACKAGE_SOURCE_POLICY \}\}/) @@ -97,9 +103,11 @@ for (const workflow of workflows) { assert.match(dispatchInputs, / run_kind:\n description: Documentation run mode\n required: false\n default: maintenance\n type: choice\n options:\n - maintenance\n - bootstrap/) assert.match(source, /run_kind: \$\{\{ github\.event\.inputs\.run_kind \|\| 'maintenance' \}\}/) assert.match(source, /require_pr: \$\{\{ github\.event_name == 'workflow_dispatch' \}\}/) + assert.match(source, /bootstrap_contract:[\s\S]*"required_paths": \["README\.md", "docs\/README\.md"\][\s\S]*"pattern": "docs\/\*\*\/\*\.md"[\s\S]*"path": "README\.md", "must_link_to": \["docs\/README\.md"\]/) } else { assert.doesNotMatch(source, /^ run_kind:/m) assert.doesNotMatch(source, /^ require_pr:/m) + assert.doesNotMatch(source, /^ bootstrap_contract:/m) } }