Sync Best Practices #2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Sync & Audit Config | |
| on: | |
| schedule: | |
| - cron: '0 10 * * 1-5' # Weekdays at 10am UTC (midi Paris) | |
| workflow_dispatch: {} # Manual trigger | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| jobs: | |
| sync-audit: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: '22' | |
| - name: Install Claude Code | |
| run: npm install -g @anthropic-ai/claude-code | |
| - name: Setup workspace | |
| run: | | |
| # Symlink checkout to ~/.claude so commands resolve correctly | |
| ln -sfn "$GITHUB_WORKSPACE" "$HOME/.claude" | |
| # Git identity for commits | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| - name: Sync best practices | |
| env: | |
| ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| claude -p "/sync-cookbook" \ | |
| --model claude-haiku-4-5 \ | |
| --dangerously-skip-permissions \ | |
| --max-turns 30 \ | |
| --output-format text \ | |
| | tee /tmp/sync-report.txt | |
| # Fail if Claude wasn't authenticated | |
| if grep -qi "not logged in\|please run /login\|authentication" /tmp/sync-report.txt; then | |
| echo "::error::Claude authentication failed. Check ANTHROPIC_API_KEY secret." | |
| exit 1 | |
| fi | |
| - name: Check for changes | |
| id: changes | |
| run: | | |
| if git diff --quiet docs/; then | |
| echo "has_changes=false" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "has_changes=true" >> "$GITHUB_OUTPUT" | |
| echo "### Changed files:" >> /tmp/sync-summary.txt | |
| git diff --stat docs/ >> /tmp/sync-summary.txt | |
| fi | |
| - name: Run audit | |
| if: steps.changes.outputs.has_changes == 'true' | |
| env: | |
| ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} | |
| run: | | |
| claude -p "$(cat <<'PROMPT' | |
| You are auditing a Claude Code configuration repository. | |
| Read these files: | |
| 1. docs/claude-cookbook-best-practices.md (just synced - reference for latest features) | |
| 2. settings.json | |
| 3. CLAUDE.md | |
| 4. All agents: agents/*.md | |
| 5. All skills: use Glob for skills/*/SKILL.md, then read each | |
| 6. All commands: commands/*.md | |
| Produce a concise markdown audit report. For each actionable finding: | |
| **[CATEGORY] `file`** — recommendation (impact: high/medium/low) | |
| Categories: AGENT, SKILL, COMMAND, SETTING, HOOK, CLAUDE.MD, CONFLICT | |
| Rules: | |
| - Only flag things that would concretely improve the workflow | |
| - Skip anything that works fine as-is | |
| - Check for conflicts with new bundled commands | |
| - Check for new features agents/skills could leverage | |
| - Check for CLAUDE.md rules that could be settings/hooks instead | |
| - Keep the report under 100 lines | |
| PROMPT | |
| )" \ | |
| --model claude-sonnet-4-6 \ | |
| --dangerously-skip-permissions \ | |
| --max-turns 30 \ | |
| --output-format text \ | |
| | tee /tmp/audit-report.txt | |
| - name: Create PR | |
| if: steps.changes.outputs.has_changes == 'true' | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| BRANCH="chore/sync-$(date +%Y-%m-%d)" | |
| # Clean up old sync branches | |
| git fetch origin | |
| for old_branch in $(git branch -r --list 'origin/chore/sync-*' | sed 's|origin/||'); do | |
| gh pr close "$old_branch" --delete-branch 2>/dev/null || true | |
| done | |
| git checkout -b "$BRANCH" | |
| git add docs/ | |
| git commit -m "chore: sync best practices docs" | |
| git push -u origin "$BRANCH" | |
| # Build PR body | |
| { | |
| echo "## Sync" | |
| echo "" | |
| cat /tmp/sync-summary.txt | |
| echo "" | |
| echo "---" | |
| echo "" | |
| echo "## Audit" | |
| echo "" | |
| if [ -f /tmp/audit-report.txt ]; then | |
| # Extract just the last meaningful section (skip Claude's verbose output) | |
| cat /tmp/audit-report.txt | tail -80 | |
| else | |
| echo "No audit report generated." | |
| fi | |
| } > /tmp/pr-body.txt | |
| gh pr create \ | |
| --title "chore: sync best practices $(date +%Y-%m-%d)" \ | |
| --body-file /tmp/pr-body.txt \ | |
| --reviewer nicolas-codemate | |
| - name: Summary | |
| if: always() | |
| run: | | |
| { | |
| echo "## Sync & Audit — $(date +%Y-%m-%d)" | |
| echo "" | |
| if [ "${{ steps.changes.outputs.has_changes }}" = "true" ]; then | |
| echo "**Statut** : PR cree avec changements" | |
| echo "" | |
| cat /tmp/sync-summary.txt | |
| else | |
| echo "**Statut** : Aucun changement detecte. Pas de PR." | |
| fi | |
| echo "" | |
| echo "---" | |
| echo "" | |
| echo "### Sync report (derniere 20 lignes)" | |
| echo "" | |
| if [ -f /tmp/sync-report.txt ]; then | |
| echo '```' | |
| tail -20 /tmp/sync-report.txt | |
| echo '```' | |
| else | |
| echo "Sync non execute ou echoue." | |
| fi | |
| } >> "$GITHUB_STEP_SUMMARY" |