Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,8 @@ jobs:
tests/test_engine_unavailable_notice.bats \
tests/test_batch_skip_reporting.bats \
tests/test_review_one_pr_ci_pending.bats \
tests/test_release_registry.bats
tests/test_release_registry.bats \
tests/test_readme_refresh_helpers.bats

template-drift:
# Drift guard (#969): fail when a file committed in petry-projects/repo-template
Expand Down
69 changes: 69 additions & 0 deletions .github/workflows/readme-refresh.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
name: README Refresh

# Weekly agent that refreshes the org "meta-repo" READMEs from live org state and
# opens (or updates) one rolling PR per repo for human review. Documented repo-specific
# workflow — no corresponding org template in standards/workflows/ (see AGENTS.md).

on:
schedule:
# Weekly — Monday at 09:00 UTC
- cron: '0 9 * * 1'
workflow_dispatch:
inputs:
dry_run:
description: "Generate and diff only; do not create/update branches or PRs"
required: false
default: false
type: boolean

permissions:
contents: read

concurrency:
group: readme-refresh
cancel-in-progress: false

jobs:
refresh:
runs-on: ubuntu-latest
timeout-minutes: 60
env:
CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
ORG: ${{ vars.ORG || 'petry-projects' }}
DRY_RUN: ${{ inputs.dry_run || 'false' }}
# Pin via vars.CLAUDE_CODE_VERSION for reproducible caching; mirrors docs-health-check.yml.
CLAUDE_CODE_VERSION: ${{ vars.CLAUDE_CODE_VERSION || '2.1.138' }}

steps:
- name: Checkout agent repo
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
Comment thread
don-petry marked this conversation as resolved.
with:
persist-credentials: false

- name: Set up Node
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: '20'

- name: Cache claude-code CLI
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: ~/.npm-global
key: claude-code-${{ env.CLAUDE_CODE_VERSION }}-${{ runner.os }}

- name: Install Claude Code CLI
run: |
mkdir -p "$HOME/.npm-global"
npm config set prefix "$HOME/.npm-global"
echo "$HOME/.npm-global/bin" >> "$GITHUB_PATH"
export PATH="$HOME/.npm-global/bin:$PATH"
if command -v claude >/dev/null 2>&1; then
echo "claude-code cache hit: $(claude --version)"
else
npm install -g "@anthropic-ai/claude-code@${CLAUDE_CODE_VERSION}" # NOSONAR
fi

- name: Run README refresh
env:
GH_TOKEN: ${{ secrets.DON_PETRY_BOT_GH_PAT }}
run: bash scripts/aw-readme-refresh.sh
7 changes: 7 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,13 @@ This is the `.github-private` org infrastructure repo for `petry-projects`. It c
≤15-min backstop) and a `workflow_run: completed` fast path (#898) that scopes the sweep to the
completing CI run's PR(s) for near-instant re-review. It must not be removed by template syncs. If the org
template gains an equivalent re-trigger sweep, remove this exception and defer to the template instead.
- **Exception:** `readme-refresh.yml` (weekly org README refresh) is a documented repo-specific workflow
with no corresponding org template in `standards/workflows/`. It regenerates the four org "meta-repo"
READMEs (public + member-only org profiles, and the `.github` / `.github-private` repo landing pages)
from live org state via `scripts/aw-readme-refresh.sh` + `prompts/aw/readme-refresh.md`, then opens or
updates one rolling PR (`chore/readme-refresh`, label `readme-refresh`) per repo for human review. It
never direct-pushes. It must not be removed by template syncs. If the org template gains an equivalent,
remove this exception and defer to the template instead.
- **Exception:** The `bats` test list in `lint.yml` is extended with repo-specific test files (e.g.
`tests/test_push_protection.bats`) beyond the org template baseline. When adding new test files to this
repo, add them to this list. Template syncs must not reset it to the base template list. This includes
Expand Down
59 changes: 59 additions & 0 deletions prompts/aw/readme-refresh.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<!-- VARIABLES: TARGET_LABEL, TARGET_TYPE, LINT_MAXLEN, FACTS_BUNDLE, CURRENT_CONTENT -->
You are the README Refresh agent for the `petry-projects` GitHub organization. Your job is to
produce an accurate, well-structured Markdown body for **${TARGET_LABEL}**.

## Authoritative facts (live org state)

${FACTS_BUNDLE}

## Current content of the target file

The current content is between the markers below. It is **empty** if the file does not yet exist.

<<<CURRENT_CONTENT_START
${CURRENT_CONTENT}
CURRENT_CONTENT_END

## Task

Target type: `${TARGET_TYPE}`. Produce the complete, final Markdown body for this file.

- `org-profile-public` — the org's **public** profile page (`.github/profile/README.md`). A curated
landing page: a short intro, a Projects table (Repository / Description / Language), a Standards &
Practices section, and a Contributing section. Public audience.
- `org-profile-member` — the org's **member-only** profile page (`.github-private/profile/README.md`),
shown to signed-in org members. Similar shape to the public profile but may reference private
automation, internal agents, and operational docs. If the current content is empty, create it fresh,
reusing the tone of the public profile.
- `github-repo-readme` — the landing README for the `.github` repo itself. Describe what the repo holds
(org-wide GitHub config, CI templates in `standards/workflows/`, engineering standards in `standards/`).
If empty, create it fresh.
- `github-private-repo-readme` — the landing README for the `.github-private` repo. Describe the agents,
prompts, scripts, frameworks, and scheduled automation. Keep the existing structure where it is good.

## Rules (follow exactly)

1. **Preserve curated prose.** Keep existing descriptions, tone, and structure where they are accurate.
Improve clarity only where it helps. Do **not** blank or downgrade good existing text.
2. **Only correct what the facts show is wrong or missing:** add repositories present in the facts but
missing from the table; fix stale primary-language values; fix inaccurate framework and agent lists.
3. **Never invent** repositories, agents, or frameworks that are not in the facts bundle above.
4. For repos whose GitHub description is empty (flagged in the facts), **keep any existing curated
description** in the current content — do not replace it with an empty value.
5. **Hard-wrap every prose line to at most ${LINT_MAXLEN} characters** — insert real line breaks so no
line exceeds the limit (a soft break inside a paragraph renders identically). Tables and fenced code
blocks are exempt. This is a strict CI lint rule (markdownlint MD013); overly long lines fail CI.
6. If the target repo is `.github` (types `org-profile-public`, `github-repo-readme`): the first line
of the body MUST be a single top-level `# ` heading, and use `[text](url)` links — **no bare URLs**.
7. Do **not** explain your reasoning, and do **not** add any preamble or trailing commentary.
8. Emit the complete file body **between two marker lines**, exactly like this:

```
===README-BEGIN===
<the full markdown body goes here>
===README-END===
```

Put nothing except the file body between the markers, and nothing after `===README-END===`.
9. If the current content is already fully accurate and needs no change, output exactly `SKIP`
(with no markers, no other text).
Loading
Loading