Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
41a3473
feat: implement issue #236 — Phase 5: Remaining gh-aw workflows (Docs…
donpetry-bot May 20, 2026
7ae8c49
Merge branch 'main' into dev-lead/issue-236-20260520-0401
don-petry May 20, 2026
635c79c
Merge branch 'main' into dev-lead/issue-236-20260520-0401
don-petry May 20, 2026
c5ad8aa
Merge branch 'main' into dev-lead/issue-236-20260520-0401
don-petry May 20, 2026
f82593a
Merge branch 'main' into dev-lead/issue-236-20260520-0401
don-petry May 20, 2026
00be1b2
Merge branch 'main' into dev-lead/issue-236-20260520-0401
don-petry May 20, 2026
f0fc9d1
Merge branch 'main' into dev-lead/issue-236-20260520-0401
don-petry May 20, 2026
94bbfd9
Merge branch 'main' into dev-lead/issue-236-20260520-0401
don-petry May 20, 2026
d19a22c
Merge branch 'main' into dev-lead/issue-236-20260520-0401
don-petry May 20, 2026
83d2dc1
fix(reviews): address review comments [skip ci-relay]
donpetry-bot May 20, 2026
3c5bca4
fix(reviews): address review comments [skip ci-relay]
donpetry-bot May 20, 2026
15adf01
fix(reviews): address review comments [skip ci-relay]
donpetry-bot May 20, 2026
c594274
Merge branch 'main' into dev-lead/issue-236-20260520-0401
don-petry May 20, 2026
079e179
Merge branch 'main' into dev-lead/issue-236-20260520-0401
don-petry May 20, 2026
0cd1d8a
Merge branch 'main' into dev-lead/issue-236-20260520-0401
don-petry May 20, 2026
9c707ad
Merge branch 'main' into dev-lead/issue-236-20260520-0401
don-petry May 20, 2026
1d5a912
Merge branch 'main' into dev-lead/issue-236-20260520-0401
don-petry May 20, 2026
a123e9d
Merge branch 'main' into dev-lead/issue-236-20260520-0401
don-petry May 20, 2026
23e1a61
Merge branch 'main' into dev-lead/issue-236-20260520-0401
don-petry May 20, 2026
5fdb3f3
Merge branch 'main' into dev-lead/issue-236-20260520-0401
don-petry May 20, 2026
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
80 changes: 80 additions & 0 deletions .github/workflows/content-twin-audit.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
name: ContentTwin Content Audit

on:
schedule:
# Daily at 07:00 UTC
- cron: '0 7 * * *'
workflow_dispatch:
inputs:
stale_days:
description: "Days without a content commit before flagging as stale"
required: false
default: "7"
type: string

permissions:
contents: read
issues: write

concurrency:
group: content-twin-audit
cancel-in-progress: true

jobs:
audit:
runs-on: ubuntu-latest
timeout-minutes: 20
env:
CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
CONTENT_TWIN_REPO: ${{ vars.CONTENT_TWIN_REPO || 'petry-projects/ContentTwin' }}
STALE_DAYS: ${{ inputs.stale_days || vars.CONTENT_STALE_DAYS || '7' }}
PUBLISH_WORKFLOW: ${{ vars.CONTENT_TWIN_PUBLISH_WORKFLOW || 'publish.yml' }}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
# Pin via vars.CLAUDE_CODE_VERSION for reproducible caching; mirrors pr-review.yml.
CLAUDE_CODE_VERSION: ${{ vars.CLAUDE_CODE_VERSION || 'latest' }}

steps:
- name: Checkout agent repo
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
Comment thread
coderabbitai[bot] marked this conversation as resolved.

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

- name: Cache claude-code CLI
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
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 content audit
env:
GH_TOKEN: ${{ secrets.DON_PETRY_BOT_GH_PAT }}
run: bash scripts/aw-content-twin-audit.sh

- name: Truncate report if needed
run: |
if [ -f content_twin_audit_report.md ]; then
if [ "$(wc -c < content_twin_audit_report.md)" -gt 60000 ]; then
head -c 60000 content_twin_audit_report.md > content_twin_audit_report.md.tmp
Comment thread
don-petry marked this conversation as resolved.
mv content_twin_audit_report.md.tmp content_twin_audit_report.md
printf '\n\n---\n_Report truncated at 60 000 bytes._\n' >> content_twin_audit_report.md
fi
fi

- name: Annotate clean run
if: env.HAS_CONTENT_ISSUES != 'true'
run: |
echo "::notice::ContentTwin audit passed — all signals healthy."
76 changes: 76 additions & 0 deletions .github/workflows/dependency-advisory.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
name: Dependency Advisory

on:
pull_request:
types: [opened, synchronize, reopened]
paths:
- 'package.json'
Comment thread
don-petry marked this conversation as resolved.
- 'package-lock.json'
- 'yarn.lock'
- 'go.mod'
- 'go.sum'
- 'requirements.txt'
- 'Pipfile'
- 'Pipfile.lock'
- 'Gemfile'
- 'Gemfile.lock'
- 'Cargo.toml'
- 'Cargo.lock'
- 'pyproject.toml'
- 'pom.xml'
- 'build.gradle'
- 'build.gradle.kts'

permissions:
contents: read
pull-requests: write

concurrency:
group: dependency-advisory-${{ github.event.pull_request.number }}
cancel-in-progress: true

jobs:
advisory:
runs-on: ubuntu-latest
timeout-minutes: 15
env:
CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
PR_NUMBER: ${{ github.event.pull_request.number }}
REPO: ${{ github.repository }}
SKIP_BOT_PRS: ${{ vars.DEP_ADVISORY_SKIP_BOT_PRS || 'true' }}
# Pin via vars.CLAUDE_CODE_VERSION for reproducible caching; mirrors pr-review.yml.
CLAUDE_CODE_VERSION: ${{ vars.CLAUDE_CODE_VERSION || 'latest' }}

steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
token: ${{ secrets.GH_PAT_WORKFLOWS || secrets.GITHUB_TOKEN }}

Comment thread
coderabbitai[bot] marked this conversation as resolved.
- name: Set up Node
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: '20'

- name: Cache claude-code CLI
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
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 dependency advisory
env:
GH_TOKEN: ${{ secrets.GH_PAT_WORKFLOWS || secrets.GITHUB_TOKEN }}
run: bash scripts/aw-dependency-advisory.sh
103 changes: 103 additions & 0 deletions .github/workflows/docs-health-check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
name: Docs Health Check

on:
schedule:
# Weekly — Sunday at 00:00 UTC
- cron: '0 0 * * 0'
workflow_dispatch:
inputs:
stale_days:
description: "Days without update before a doc is considered stale"
required: false
default: "90"
type: string

permissions:
contents: read
issues: write

concurrency:
group: docs-health-check
cancel-in-progress: true

jobs:
health-check:
runs-on: ubuntu-latest
timeout-minutes: 30
env:
CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
ORG: ${{ vars.ORG || 'petry-projects' }}
STALE_DAYS: ${{ inputs.stale_days || vars.DOCS_STALE_DAYS || '90' }}
DOCS_STALENESS_IGNORE: ${{ vars.DOCS_STALENESS_IGNORE || '' }}
REPORT_REPO: ${{ vars.ORG || 'petry-projects' }}/.github-private
# Pin via vars.CLAUDE_CODE_VERSION for reproducible caching; mirrors pr-review.yml.
CLAUDE_CODE_VERSION: ${{ vars.CLAUDE_CODE_VERSION || 'latest' }}

steps:
- name: Checkout agent repo
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

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

- name: Cache claude-code CLI
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
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 docs health check
env:
GH_TOKEN: ${{ secrets.DON_PETRY_BOT_GH_PAT }}
run: bash scripts/aw-docs-health-check.sh

- name: Truncate report if needed
run: |
if [ -f docs_health_report.md ]; then
if [ "$(wc -c < docs_health_report.md)" -gt 60000 ]; then
head -c 60000 docs_health_report.md > docs_health_report.md.tmp
mv docs_health_report.md.tmp docs_health_report.md
printf '\n\n---\n_Report truncated at 60 000 bytes._\n' >> docs_health_report.md
fi
fi

- name: Create issue with findings
if: env.HAS_STALE_DOCS == 'true' && hashFiles('docs_health_report.md') != ''
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
github-token: ${{ github.token }}
script: |
const fs = require('fs');
const report = fs.readFileSync('docs_health_report.md', 'utf8');
if (!report.trim()) {
core.setFailed('Report file is empty');
return;
}
const today = new Date().toISOString().split('T')[0];
const issue = await github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: `Docs Health Check — stale files detected ${today}`,
body: report,
labels: ['health-check', 'automated-report'],
});
core.notice(`Issue created: ${issue.data.html_url}`);

- name: Annotate clean run
if: env.HAS_STALE_DOCS != 'true'
run: |
echo "::notice::Docs health check passed — no stale files found (threshold: ${STALE_DAYS} days)."
53 changes: 53 additions & 0 deletions .github/workflows/standards-sync.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
name: Standards Sync

on:
schedule:
# Every Monday at 09:00 UTC; the guard step below enforces first-Monday-only
- cron: '0 9 * * 1'
workflow_dispatch: {}

permissions:
contents: read
issues: write

Comment thread
coderabbitai[bot] marked this conversation as resolved.
concurrency:
group: standards-sync
cancel-in-progress: false

jobs:
sync:
runs-on: ubuntu-latest
timeout-minutes: 30
env:
ORG: ${{ vars.ORG || 'petry-projects' }}
STANDARDS_REPO: ${{ vars.STANDARDS_REPO || 'petry-projects/.github' }}
SYNC_LABEL: ${{ vars.STANDARDS_SYNC_LABEL || 'standards-sync' }}
SKIP_REPOS: ${{ vars.STANDARDS_SYNC_SKIP_REPOS || '' }}

steps:
- name: Guard — first Monday of month only
id: guard
run: |
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
echo "Manual trigger — bypassing first-Monday guard."
echo "proceed=true" >> "$GITHUB_OUTPUT"
else
day=$(date -u +%-d)
if [ "$day" -gt 7 ]; then
echo "Not the first Monday of the month (day=$day) — skipping."
echo "proceed=false" >> "$GITHUB_OUTPUT"
else
echo "First Monday confirmed (day=$day) — proceeding."
echo "proceed=true" >> "$GITHUB_OUTPUT"
fi
fi

- name: Checkout agent repo
if: steps.guard.outputs.proceed == 'true'
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
Comment thread
coderabbitai[bot] marked this conversation as resolved.

- name: Run standards sync
if: steps.guard.outputs.proceed == 'true'
env:
GH_TOKEN: ${{ secrets.DON_PETRY_BOT_GH_PAT }}
run: bash scripts/aw-standards-sync.sh
52 changes: 52 additions & 0 deletions .github/workflows/test-aw.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: Test AW Workflows

on:
pull_request:
paths:
- 'tests/aw/**'
- 'docs/aw/**'
- 'scripts/aw-*.sh'
- '.github/workflows/docs-health-check.yml'
- '.github/workflows/dependency-advisory.yml'
- '.github/workflows/standards-sync.yml'
- '.github/workflows/content-twin-audit.yml'
- '.github/workflows/test-aw.yml'
Comment on lines +1 to +13
push:
branches: [main]
paths:
- 'tests/aw/**'
- 'docs/aw/**'
- 'scripts/aw-*.sh'
workflow_dispatch: {}

permissions:
contents: read

jobs:
validate-specs:
name: Validate AW specs, docs, and workflows
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
Comment thread
coderabbitai[bot] marked this conversation as resolved.

- name: Install PyYAML
run: pip install --quiet pyyaml

- name: Run spec validator
run: bash tests/aw/validate-specs.sh

shellcheck-aw-scripts:
name: shellcheck aw-*.sh scripts
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- name: shellcheck
run: |
# SC2016: single-quoted strings with $vars inside heredocs are intentional
shellcheck --severity=warning scripts/aw-docs-health-check.sh \
scripts/aw-dependency-advisory.sh \
scripts/aw-standards-sync.sh \
scripts/aw-content-twin-audit.sh
Loading
Loading