mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 19:50:43 +00:00
ci: throttle docs agent workflow
This commit is contained in:
2
.github/codex/prompts/docs-agent.md
vendored
2
.github/codex/prompts/docs-agent.md
vendored
@@ -23,7 +23,7 @@ Allowed paths:
|
|||||||
Required workflow:
|
Required workflow:
|
||||||
|
|
||||||
1. Run `pnpm docs:list` if available and read relevant docs based on `read_when` hints.
|
1. Run `pnpm docs:list` if available and read relevant docs based on `read_when` hints.
|
||||||
2. Inspect the triggering event via `$GITHUB_EVENT_PATH`, then review the relevant commit range and changed files.
|
2. Inspect the triggering event via `$GITHUB_EVENT_PATH`, then review `$DOCS_AGENT_BASE_SHA..$DOCS_AGENT_HEAD_SHA` and its changed files. If either env var is missing, fall back to the event payload.
|
||||||
3. Update stale existing documentation, if needed.
|
3. Update stale existing documentation, if needed.
|
||||||
4. Run `pnpm check:docs` if dependencies are available.
|
4. Run `pnpm check:docs` if dependencies are available.
|
||||||
5. Leave the worktree clean if no docs need changes.
|
5. Leave the worktree clean if no docs need changes.
|
||||||
|
|||||||
93
.github/workflows/docs-agent.yml
vendored
93
.github/workflows/docs-agent.yml
vendored
@@ -1,16 +1,15 @@
|
|||||||
name: Docs Agent
|
name: Docs Agent
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_run: # zizmor: ignore[dangerous-triggers] main-only docs repair after trusted CI; job gates repository, event, branch, actor, conclusion, and exact current main SHA before using write token
|
workflow_run: # zizmor: ignore[dangerous-triggers] main-only docs repair after trusted CI; job gates repository, event, branch, actor, conclusion, exact current main SHA, and hourly cadence before using write token
|
||||||
workflows:
|
workflows:
|
||||||
- CI
|
- CI
|
||||||
types:
|
types:
|
||||||
- completed
|
- completed
|
||||||
schedule:
|
|
||||||
- cron: "17 5 * * *"
|
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
|
actions: read
|
||||||
contents: write
|
contents: write
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
@@ -41,17 +40,24 @@ jobs:
|
|||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
submodules: false
|
submodules: false
|
||||||
|
|
||||||
- name: Skip superseded workflow runs
|
- name: Gate trusted main activity and hourly cadence
|
||||||
id: superseded
|
id: gate
|
||||||
env:
|
env:
|
||||||
EVENT_NAME: ${{ github.event_name }}
|
EVENT_NAME: ${{ github.event_name }}
|
||||||
|
GH_TOKEN: ${{ github.token }}
|
||||||
WORKFLOW_HEAD_SHA: ${{ github.event.workflow_run.head_sha }}
|
WORKFLOW_HEAD_SHA: ${{ github.event.workflow_run.head_sha }}
|
||||||
run: |
|
run: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
if [ "$EVENT_NAME" != "workflow_run" ]; then
|
if [ "$EVENT_NAME" != "workflow_run" ]; then
|
||||||
echo "run_agent=true" >> "$GITHUB_OUTPUT"
|
head_sha="$(git rev-parse HEAD)"
|
||||||
echo "base_sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT"
|
review_base="$(git rev-parse "${head_sha}^" 2>/dev/null || printf '%s' "$head_sha")"
|
||||||
|
{
|
||||||
|
echo "run_agent=true"
|
||||||
|
echo "base_sha=${head_sha}"
|
||||||
|
echo "review_base_sha=${review_base}"
|
||||||
|
echo "review_head_sha=${head_sha}"
|
||||||
|
} >> "$GITHUB_OUTPUT"
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -73,17 +79,65 @@ jobs:
|
|||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "run_agent=true" >> "$GITHUB_OUTPUT"
|
runs_json="$RUNNER_TEMP/docs-agent-runs.json"
|
||||||
echo "base_sha=${remote_main}" >> "$GITHUB_OUTPUT"
|
gh api --method GET "repos/${GITHUB_REPOSITORY}/actions/workflows/docs-agent.yml/runs" \
|
||||||
|
-f branch=main \
|
||||||
|
-f event=workflow_run \
|
||||||
|
-f per_page=100 > "$runs_json"
|
||||||
|
|
||||||
|
one_hour_ago="$(date -u -d '1 hour ago' +%Y-%m-%dT%H:%M:%SZ)"
|
||||||
|
recent_runs="$(
|
||||||
|
jq -r \
|
||||||
|
--argjson current_run_id "$GITHUB_RUN_ID" \
|
||||||
|
--arg one_hour_ago "$one_hour_ago" \
|
||||||
|
'.workflow_runs[]
|
||||||
|
| select(.database_id != $current_run_id)
|
||||||
|
| select(.created_at >= $one_hour_ago)
|
||||||
|
| select(.status != "cancelled")
|
||||||
|
| select((.conclusion // "") != "skipped")
|
||||||
|
| [.database_id, .status, (.conclusion // ""), .created_at, .head_sha]
|
||||||
|
| @tsv' "$runs_json"
|
||||||
|
)"
|
||||||
|
|
||||||
|
if [ -n "$recent_runs" ]; then
|
||||||
|
echo "Docs agent already ran or is running within the last hour; skipping."
|
||||||
|
printf '%s\n' "$recent_runs"
|
||||||
|
echo "run_agent=false" >> "$GITHUB_OUTPUT"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
review_base="$(
|
||||||
|
jq -r \
|
||||||
|
--argjson current_run_id "$GITHUB_RUN_ID" \
|
||||||
|
--arg remote_main "$remote_main" \
|
||||||
|
'.workflow_runs[]
|
||||||
|
| select(.database_id != $current_run_id)
|
||||||
|
| select(.status != "cancelled")
|
||||||
|
| select((.conclusion // "") != "skipped")
|
||||||
|
| .head_sha
|
||||||
|
| select(. != null and . != "")
|
||||||
|
| select(. != $remote_main)
|
||||||
|
' "$runs_json" | head -n 1
|
||||||
|
)"
|
||||||
|
if [ -z "$review_base" ] || ! git cat-file -e "${review_base}^{commit}" 2>/dev/null; then
|
||||||
|
review_base="$(git rev-parse "${remote_main}^" 2>/dev/null || printf '%s' "$remote_main")"
|
||||||
|
fi
|
||||||
|
|
||||||
|
{
|
||||||
|
echo "run_agent=true"
|
||||||
|
echo "base_sha=${remote_main}"
|
||||||
|
echo "review_base_sha=${review_base}"
|
||||||
|
echo "review_head_sha=${remote_main}"
|
||||||
|
} >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
- name: Setup Node environment
|
- name: Setup Node environment
|
||||||
if: steps.superseded.outputs.run_agent == 'true'
|
if: steps.gate.outputs.run_agent == 'true'
|
||||||
uses: ./.github/actions/setup-node-env
|
uses: ./.github/actions/setup-node-env
|
||||||
with:
|
with:
|
||||||
install-bun: "false"
|
install-bun: "false"
|
||||||
|
|
||||||
- name: Ensure docs agent key exists
|
- name: Ensure docs agent key exists
|
||||||
if: steps.superseded.outputs.run_agent == 'true'
|
if: steps.gate.outputs.run_agent == 'true'
|
||||||
env:
|
env:
|
||||||
OPENAI_API_KEY: ${{ secrets.OPENCLAW_DOCS_AGENT_OPENAI_API_KEY || secrets.OPENAI_API_KEY }}
|
OPENAI_API_KEY: ${{ secrets.OPENCLAW_DOCS_AGENT_OPENAI_API_KEY || secrets.OPENAI_API_KEY }}
|
||||||
run: |
|
run: |
|
||||||
@@ -94,8 +148,11 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
- name: Run Codex docs agent
|
- name: Run Codex docs agent
|
||||||
if: steps.superseded.outputs.run_agent == 'true'
|
if: steps.gate.outputs.run_agent == 'true'
|
||||||
uses: openai/codex-action@v1
|
uses: openai/codex-action@v1
|
||||||
|
env:
|
||||||
|
DOCS_AGENT_BASE_SHA: ${{ steps.gate.outputs.review_base_sha }}
|
||||||
|
DOCS_AGENT_HEAD_SHA: ${{ steps.gate.outputs.review_head_sha }}
|
||||||
with:
|
with:
|
||||||
openai-api-key: ${{ secrets.OPENCLAW_DOCS_AGENT_OPENAI_API_KEY || secrets.OPENAI_API_KEY }}
|
openai-api-key: ${{ secrets.OPENCLAW_DOCS_AGENT_OPENAI_API_KEY || secrets.OPENAI_API_KEY }}
|
||||||
prompt-file: .github/codex/prompts/docs-agent.md
|
prompt-file: .github/codex/prompts/docs-agent.md
|
||||||
@@ -106,7 +163,7 @@ jobs:
|
|||||||
codex-args: '["--full-auto"]'
|
codex-args: '["--full-auto"]'
|
||||||
|
|
||||||
- name: Enforce existing-docs-only patch
|
- name: Enforce existing-docs-only patch
|
||||||
if: steps.superseded.outputs.run_agent == 'true'
|
if: steps.gate.outputs.run_agent == 'true'
|
||||||
run: |
|
run: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
@@ -139,8 +196,8 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
- name: Restore Node 24 path
|
- name: Restore Node 24 path
|
||||||
if: steps.superseded.outputs.run_agent == 'true'
|
if: steps.gate.outputs.run_agent == 'true'
|
||||||
run: |
|
run: | # zizmor: ignore[github-env] NODE_BIN is set by the trusted local setup-node-env action in this same job
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
export PATH="${NODE_BIN}:${PATH}"
|
export PATH="${NODE_BIN}:${PATH}"
|
||||||
echo "${NODE_BIN}" >> "$GITHUB_PATH"
|
echo "${NODE_BIN}" >> "$GITHUB_PATH"
|
||||||
@@ -149,13 +206,13 @@ jobs:
|
|||||||
pnpm -v
|
pnpm -v
|
||||||
|
|
||||||
- name: Check docs
|
- name: Check docs
|
||||||
if: steps.superseded.outputs.run_agent == 'true'
|
if: steps.gate.outputs.run_agent == 'true'
|
||||||
run: pnpm check:docs
|
run: pnpm check:docs
|
||||||
|
|
||||||
- name: Commit docs updates
|
- name: Commit docs updates
|
||||||
if: steps.superseded.outputs.run_agent == 'true'
|
if: steps.gate.outputs.run_agent == 'true'
|
||||||
env:
|
env:
|
||||||
BASE_SHA: ${{ steps.superseded.outputs.base_sha }}
|
BASE_SHA: ${{ steps.gate.outputs.base_sha }}
|
||||||
GITHUB_TOKEN: ${{ github.token }}
|
GITHUB_TOKEN: ${{ github.token }}
|
||||||
TARGET_BRANCH: main
|
TARGET_BRANCH: main
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
@@ -23,6 +23,15 @@ listed PRs when `apply=true`. Before mutating GitHub, it verifies that the
|
|||||||
landed PR is merged and that each duplicate has either a shared referenced issue
|
landed PR is merged and that each duplicate has either a shared referenced issue
|
||||||
or overlapping changed hunks.
|
or overlapping changed hunks.
|
||||||
|
|
||||||
|
The `Docs Agent` workflow is an event-driven Codex maintenance lane for keeping
|
||||||
|
existing docs aligned with recently landed changes. It has no pure schedule: a
|
||||||
|
successful non-bot push CI run on `main` can trigger it, and manual dispatch can
|
||||||
|
run it directly. Workflow-run invocations skip when `main` has moved on or when
|
||||||
|
another non-skipped Docs Agent run was created in the last hour. When it runs, it
|
||||||
|
reviews the commit range from the previous non-skipped Docs Agent source SHA to
|
||||||
|
current `main`, so one hourly run can cover all main changes accumulated since
|
||||||
|
the last docs pass.
|
||||||
|
|
||||||
The `Test Performance Agent` workflow is an event-driven Codex maintenance lane
|
The `Test Performance Agent` workflow is an event-driven Codex maintenance lane
|
||||||
for slow tests. It has no pure schedule: a successful non-bot push CI run on
|
for slow tests. It has no pure schedule: a successful non-bot push CI run on
|
||||||
`main` can trigger it, but it skips if another workflow-run invocation already
|
`main` can trigger it, but it skips if another workflow-run invocation already
|
||||||
|
|||||||
Reference in New Issue
Block a user