Skip to content

Extend object-reference checks to all versions and add bulk-archive action #13384

Extend object-reference checks to all versions and add bulk-archive action

Extend object-reference checks to all versions and add bulk-archive action #13384

Workflow file for this run

name: Claude Code
on:
schedule:
- cron: '0 2 * * *' # Daily at 2am UTC — picks up next incremental task
workflow_dispatch:
inputs:
issue_number:
description: 'Specific issue number to work on (optional)'
required: false
type: string
issue_comment:
types: [created]
pull_request_review_comment:
types: [created]
issues:
types: [labeled]
pull_request_review:
types: [submitted]
concurrency:
group: >-
claude-${{
github.event_name == 'schedule' && 'scheduled' ||
github.event_name == 'workflow_dispatch' && format('dispatch-{0}', inputs.issue_number) ||
github.event.issue.number ||
github.event.pull_request.number ||
github.run_id
}}
cancel-in-progress: false
# Restrict default permissions — jobs override as needed
permissions:
contents: read
issues: read
pull-requests: read
jobs:
# ── Scheduled / manual: find the next issue to work on ──
find-work:
if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest
outputs:
issue_number: ${{ steps.find.outputs.issue_number }}
issue_body: ${{ steps.find.outputs.issue_body }}
issue_title: ${{ steps.find.outputs.issue_title }}
steps:
- name: Find oldest labeled issue without an open PR
id: find
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
INPUT_ISSUE_NUMBER: ${{ inputs.issue_number }}
run: |
REPO="${{ github.repository }}"
# Get head branch names of all open PRs with the label
OPEN_PR_BRANCHES=$(gh pr list --repo "$REPO" --label "claude" --state open --json headRefName --jq '.[].headRefName')
if [ -n "$INPUT_ISSUE_NUMBER" ]; then
# Manual dispatch: use the specified issue but check for existing PR
ISSUE_NUMBER="$INPUT_ISSUE_NUMBER"
if echo "$OPEN_PR_BRANCHES" | grep -q "^claude/${ISSUE_NUMBER}-"; then
echo "::notice::Issue #$ISSUE_NUMBER already has an open PR, skipping"
exit 0
fi
else
# Scheduled: find the oldest issue that doesn't already have an open PR
ISSUES=$(gh issue list --repo "$REPO" --label "claude" --state open --json number,createdAt --jq 'sort_by(.createdAt) | .[].number')
ISSUE_NUMBER=""
for CANDIDATE in $ISSUES; do
if ! echo "$OPEN_PR_BRANCHES" | grep -q "^claude/${CANDIDATE}-"; then
ISSUE_NUMBER="$CANDIDATE"
break
fi
echo "::notice::Issue #$CANDIDATE already has an open PR, skipping"
done
fi
if [ -z "$ISSUE_NUMBER" ]; then
echo "::notice::No eligible issues found"
exit 0
fi
echo "issue_number=$ISSUE_NUMBER" >> $GITHUB_OUTPUT
# Fetch issue details
ISSUE_DATA=$(gh issue view "$ISSUE_NUMBER" --repo "$REPO" --json title,body)
ISSUE_TITLE=$(echo "$ISSUE_DATA" | jq -r '.title')
ISSUE_BODY=$(echo "$ISSUE_DATA" | jq -r '.body')
DELIMITER="ghadelim_$(openssl rand -hex 8)"
echo "issue_title<<$DELIMITER" >> $GITHUB_OUTPUT
echo "$ISSUE_TITLE" >> $GITHUB_OUTPUT
echo "$DELIMITER" >> $GITHUB_OUTPUT
echo "issue_body<<$DELIMITER" >> $GITHUB_OUTPUT
echo "$ISSUE_BODY" >> $GITHUB_OUTPUT
echo "$DELIMITER" >> $GITHUB_OUTPUT
# ── Scheduled / manual: implement the next task on the found issue ──
scheduled:
needs: find-work
if: needs.find-work.outputs.issue_number != ''
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
issues: write
id-token: write
services:
postgres:
image: pgvector/pgvector:pg16
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres_password
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
redis:
image: redis
options: >-
--health-cmd "redis-cli ping"
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 6379:6379
env:
DJANGO_DATABASE_USER: postgres
DJANGO_DATABASE_PASSWORD: postgres_password
SECRET_KEY: secret-test-key
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: '3.13'
- name: Set up uv
uses: astral-sh/setup-uv@v7
with:
enable-cache: true
- name: Install Python dependencies
run: |
uv venv
uv sync --locked --dev
echo "$PWD/.venv/bin" >> $GITHUB_PATH
- name: Set up Node.js
uses: actions/setup-node@v6
with:
node-version: 24.x
- name: Install Node dependencies
run: npm ci
- name: Create branch
id: branch
run: |
BRANCH_NAME="claude/${{ needs.find-work.outputs.issue_number }}-$(date +%Y%m%d-%H%M%S)"
git checkout -b "$BRANCH_NAME"
echo "branch_name=$BRANCH_NAME" >> $GITHUB_OUTPUT
- name: Run Claude Code
id: claude
uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
prompt: |
You are working on an incremental project tracked in issue #${{ needs.find-work.outputs.issue_number }}.
## Issue Title
${{ needs.find-work.outputs.issue_title }}
## Issue Content
${{ needs.find-work.outputs.issue_body }}
## Instructions
1. Read the issue and identify the first unchecked task (- [ ]) that is not marked as blocked
2. Implement that task, making git commits as you go
3. Run lint, type checks, and tests, fix any issues:
- Python lint: ruff check --fix && ruff format
- Python type check: uv run ty check apps/
- JS/TS lint: npm run lint
- Python test: pytest path/to/file.py -v
4. Push the changes you've made to GitHub and create a PR with the 'claude' label.
5. After completing the task, update the issue using gh issue edit to:
- Check off the completed task (change - [ ] to - [x])
- Add any learnings to the ## Learnings section (create if needed)
6. If you cannot complete the task, mark it as blocked (add "blocked:" prefix to the task)
7. Add a comment to the issue summarizing what you did
If all tasks are complete or blocked, comment on the issue explaining the status.
claude_args: '--allowedTools "Bash(npm run lint:*),Bash(npm run type-check:*),Bash(npm run build:*),Bash(ruff check:*),Bash(ruff format:*),Bash(ty check:*),Bash(uv run ty:*),Bash(uv run ruff:*),Bash(uv run pytest:*),Bash(pytest:*),Bash(uv run --no-project zensical build:*),Bash(git add:*),Bash(git commit:*),Bash(git push:*),Bash(git rm:*),Bash(git checkout:*),Bash(git switch:*),Bash(git status:*),Bash(git diff:*),Bash(gh pr create:*),Bash(gh pr edit:*),Bash(gh api:*),Bash(gh issue edit:*),Bash(gh issue comment:*),Bash(ls:*),Bash(grep:*),Bash(sort:*),Bash(tail:*),Grep,Glob,Read,Write,Edit"'
# ── Event-driven: respond to @claude mentions, issue label ──
claude:
if: |
github.event_name != 'schedule' && github.event_name != 'workflow_dispatch' && (
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
(github.event_name == 'issues' && github.event.action == 'labeled' && github.event.label.name == 'claude')
)
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
issues: write
id-token: write
services:
postgres:
image: pgvector/pgvector:pg16
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres_password
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
redis:
image: redis
options: >-
--health-cmd "redis-cli ping"
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 6379:6379
env:
DJANGO_DATABASE_USER: postgres
DJANGO_DATABASE_PASSWORD: postgres_password
SECRET_KEY: secret-test-key
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: '3.13'
- name: Set up uv
uses: astral-sh/setup-uv@v7
with:
enable-cache: true
- name: Install Python dependencies
run: |
uv venv
uv sync --locked --dev
echo "$PWD/.venv/bin" >> $GITHUB_PATH
- name: Set up Node.js
uses: actions/setup-node@v6
with:
node-version: 24.x
- name: Install Node dependencies
run: npm ci
- name: Run Claude Code
id: claude
uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
branch_prefix: "claude/"
claude_args: |
--allowedTools "mcp__github_inline_comment__create_inline_comment,Bash(npm run lint:*),Bash(npm run type-check:*),Bash(npm run build:*),Bash(ruff check:*),Bash(ruff format:*),Bash(ty check:*),Bash(uv run ty:*),Bash(uv run ruff:*),Bash(uv run pytest:*),Bash(pytest:*),Bash(git add:*),Bash(git commit:*),Bash(git push:*),Bash(git checkout:*),Bash(git switch:*),Bash(git status:*),Bash(git diff:*),Bash(git branch:*),Bash(gh pr create:*),Bash(gh pr edit:*),Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*),Bash(gh api:*),Bash(gh issue comment:*),Bash(gh issue edit:*),Read,Write,Edit"