Skip to content

Sync Best Practices #15

Sync Best Practices

Sync Best Practices #15

Workflow file for this run

name: Sync Best Practices
on:
schedule:
- cron: '0 10 * * 1-5' # Weekdays at 10am UTC (midi Paris)
workflow_dispatch: {} # Manual trigger
permissions:
contents: write
pull-requests: write
jobs:
check-release:
runs-on: ubuntu-latest
timeout-minutes: 2
outputs:
new_release: ${{ steps.check.outputs.new_release }}
latest_version: ${{ steps.check.outputs.latest_version }}
stored_version: ${{ steps.check.outputs.stored_version }}
steps:
- uses: actions/checkout@v4
- name: Check for new Claude Code release
id: check
run: |
LATEST=$(npm view @anthropic-ai/claude-code version 2>/dev/null || echo "unknown")
STORED=$(grep -oP 'Latest version: v\K[0-9.]+' docs/claude-cookbook-best-practices.md || echo "0.0.0")
echo "latest_version=$LATEST" >> "$GITHUB_OUTPUT"
echo "stored_version=$STORED" >> "$GITHUB_OUTPUT"
if [ "$LATEST" = "$STORED" ]; then
echo "new_release=false" >> "$GITHUB_OUTPUT"
echo "No new release (current: v$STORED)"
else
echo "new_release=true" >> "$GITHUB_OUTPUT"
echo "New release detected: v$STORED -> v$LATEST"
fi
- name: Summary
if: steps.check.outputs.new_release == 'false'
run: |
{
echo "## Sync — $(date +%Y-%m-%d)"
echo ""
echo "**Statut** : Pas de nouvelle release (v${{ steps.check.outputs.stored_version }}). Skipped."
} >> "$GITHUB_STEP_SUMMARY"
sync:
needs: check-release
if: needs.check-release.outputs.new_release == 'true' || github.event_name == 'workflow_dispatch'
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: |
PREV="${{ needs.check-release.outputs.stored_version }}"
NEXT="${{ needs.check-release.outputs.latest_version }}"
claude -p "/sync-cookbook — New release detected: v${PREV} -> v${NEXT}. Update the version header to v${NEXT} and focus changelog fetch on versions after v${PREV}." \
--model claude-sonnet-4-6 \
--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 && [ -z "$(git ls-files --others --exclude-standard)" ]; then
echo "has_changes=false" >> "$GITHUB_OUTPUT"
else
echo "has_changes=true" >> "$GITHUB_OUTPUT"
{
echo "### Changed files:"
git diff --stat
git ls-files --others --exclude-standard | sed 's/^/ new: /'
} > /tmp/sync-summary.txt
fi
- 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 and PRs
git fetch origin
for old_branch in $(git branch -r --list 'origin/chore/sync-*' | sed 's|origin/||' | xargs); do
gh pr close "$old_branch" --delete-branch 2>/dev/null || true
git push origin --delete "$old_branch" 2>/dev/null || true
done
git checkout -b "$BRANCH"
git add -A
git commit -m "chore: sync docs and apply audit improvements"
git push -u origin "$BRANCH"
# Build PR body
{
echo "## Changes"
echo ""
cat /tmp/sync-summary.txt
echo ""
echo "---"
echo ""
echo "## Sync Report"
echo ""
tail -40 /tmp/sync-report.txt
} > /tmp/pr-body.txt
gh pr create \
--title "chore: sync best practices $(date +%Y-%m-%d)" \
--body-file /tmp/pr-body.txt \
--assignee nicolas-codemate
- name: Summary
if: always()
run: |
{
echo "## Sync — $(date +%Y-%m-%d)"
echo ""
echo "**Release** : v${{ needs.check-release.outputs.stored_version }} -> v${{ needs.check-release.outputs.latest_version }}"
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"