GitHub Workflows — CI/CD & Automated Operations

CI/CD & Automated Operations

15 GitHub Actions workflows handling issue triage, duplicate detection, lifecycle management, and Claude Code mentions across the repository.

15
Workflows
YAML
Language
Cron
Schedules
Event
Triggers

⚙️ GitHub Actions🤖 AI Triage🕑 Scheduled🔔 Event-Driven

📚 What is this & why does it exist?

The .github/workflows directory defines the automated operations layer for the Claude Code repository. These 15 YAML workflow files orchestrate everything from AI-powered issue triage (using Claude Opus 4-6 with a 5-minute timeout) to twice-daily stale issue sweeps, duplicate detection pipelines, and permission checks. Together, they form a self-managing issue lifecycle system that scales across thousands of GitHub issues without human bottlenecks.

💡 Real-world analogy

Imagine a hospital’s operations center. When a patient (issue) arrives, the triage nurse (claude-issue-triage.yml) assesses severity and assigns them to the right department. The scheduling system (sweep.yml) runs twice daily to check on patients who haven’t been seen. The records department (log-issue-events.yml) keeps a log of every interaction. And the security desk (non-write-users-check.yml) verifies that only authorized staff can perform sensitive operations. Each workflow is a specialist doing one job well, but they coordinate seamlessly.

Architecture

flowchart TB
    subgraph Events["GitHub Event Sources"]
        ISSUE_OPEN["📄 Issue Opened"]
        ISSUE_LABEL["🏷️ Issue Labeled"]
        PR_COMMENT["💬 PR/Issue Comment"]
        CRON_AM["⏰ Cron 10am UTC"]
        CRON_PM["⏰ Cron 10pm UTC"]
        DISPATCH["📤 Repository Dispatch"]
    end

    subgraph Core["Core Workflows"]
        TRIAGE["claude-issue-triage.yml\n(Opus 4-6, 5min)"]
        CLAUDE["claude.yml\n(@claude mentions)"]
        SWEEP_WF["sweep.yml\n(Twice daily)"]
    end

    subgraph Lifecycle["Lifecycle Workflows"]
        DEDUPE["claude-dedupe-issues.yml"]
        AUTOCLOSE["auto-close-duplicates.yml"]
        LIFECYCLE_C["issue-lifecycle-comment.yml"]
        LOCK["lock-closed-issues.yml"]
        REMOVE_LBL["remove-autoclose-label.yml"]
    end

    subgraph Support["Support Workflows"]
        OPENED_DISP["issue-opened-dispatch.yml"]
        LOG_EVENTS["log-issue-events.yml"]
        PERM_CHECK["non-write-users-check.yml"]
        BACKFILL_WF["backfill-duplicate-comments.yml"]
    end

    subgraph Scripts["scripts/"]
        SWEEP_TS["sweep.ts"]
        CLOSE_TS["auto-close-duplicates.ts"]
        COMMENT_SH["comment-on-duplicates.sh"]
    end

    ISSUE_OPEN --> TRIAGE
    ISSUE_OPEN --> OPENED_DISP
    ISSUE_OPEN --> DEDUPE
    ISSUE_LABEL --> LIFECYCLE_C
    ISSUE_LABEL --> AUTOCLOSE
    PR_COMMENT --> CLAUDE
    CRON_AM --> SWEEP_WF
    CRON_PM --> SWEEP_WF
    DISPATCH --> BACKFILL_WF
    SWEEP_WF --> SWEEP_TS
    AUTOCLOSE --> CLOSE_TS
    DEDUPE --> COMMENT_SH

    style TRIAGE fill:#58a6ff,stroke:#58a6ff,color:#fff
    style CLAUDE fill:#3fb950,stroke:#3fb950,color:#fff
    style SWEEP_WF fill:#d29922,stroke:#d29922,color:#fff

Event Flow

sequenceDiagram
    participant Dev as Developer
    participant GH as GitHub
    participant Triage as claude-issue-triage
    participant Dedupe as claude-dedupe-issues
    participant Sweep as sweep.yml
    participant Lock as lock-closed-issues
    participant Log as log-issue-events

    Dev->>GH: Opens new issue
    GH->>Log: Log issue_opened event
    GH->>Triage: Trigger triage (Opus 4-6)
    Triage->>GH: Apply labels + priority
    GH->>Dedupe: Check for duplicates
    Dedupe->>GH: Post duplicate matches (if any)

    Note over Sweep: Scheduled: 10am + 10pm UTC
    Sweep->>GH: Query all open issues
    GH-->>Sweep: Issue list with activity dates
    Sweep->>GH: Apply stale/autoclose labels

    Note over GH: Issue closed (manual or auto)
    GH->>Lock: Lock after cooling period
    GH->>Log: Log issue_closed event

Workflows Reference

Core Workflows

🤖 claude.ymlAI

Responds to @claude mentions on issues and pull requests. Uses Sonnet 4.5 for fast, contextual responses.

  • Trigger: issue_comment, pull_request_review_comment
  • Model: Claude Sonnet 4.5
  • Filters: only activates on @claude mention

🔍 claude-issue-triage.ymlAI

Auto-triages newly opened issues using Claude Opus 4-6. Applies priority labels, categorization, and initial assessment with a 5-minute timeout.

  • Trigger: issues.opened
  • Model: Claude Opus 4-6
  • Timeout: 5 minutes

⏰ sweep.yml

Twice-daily lifecycle sweep running at 10am and 10pm UTC. Invokes sweep.ts to mark stale issues and close expired ones.

  • Trigger: schedule (cron)
  • Schedule: 0 10,22 * * *
  • Script: scripts/sweep.ts
Lifecycle Workflows

🔎 claude-dedupe-issues.yml

Detects duplicate issues when new issues are opened. Uses embedding similarity to find matches and posts formatted comments.

  • Trigger: issues.opened, workflow_dispatch
  • Script: comment-on-duplicates.sh

🗑️ auto-close-duplicates.yml

Closes issues confirmed as duplicates after a 3-day grace period. Runs the TypeScript closer script.

  • Trigger: schedule, workflow_dispatch
  • Script: auto-close-duplicates.ts

💬 issue-lifecycle-comment.yml

Posts warning comments when lifecycle labels (stale, needs-info, etc.) are applied to issues.

  • Trigger: issues.labeled
  • Script: lifecycle-comment.ts

🔒 lock-closed-issues.yml

Locks closed issues after a cooling-off period to prevent drive-by comments on resolved issues.

  • Trigger: schedule
  • Locks conversation thread

🏷️ remove-autoclose-label.yml

Removes the autoclose label when an issue receives new activity, resetting the closure timer.

  • Trigger: issue_comment
  • Checks comment author vs. bot
Support Workflows

📤 issue-opened-dispatch.yml

Dispatches a repository_dispatch event when issues are opened, enabling downstream workflow chaining.

  • Trigger: issues.opened
  • Emits: issue-opened dispatch

📋 log-issue-events.yml

Logs all issue lifecycle events for auditing and debugging the automation pipeline.

  • Trigger: multiple issue events
  • Outputs: structured event log

🛡️ non-write-users-check.yml

Verifies that workflow triggers come from users with appropriate repository permissions.

  • Trigger: pull_request_target
  • Checks: write/admin permission

🔄 backfill-duplicate-comments.yml

Retroactively processes older issues through the duplicate detection pipeline.

  • Trigger: workflow_dispatch
  • Script: backfill-duplicate-comments.ts

Trigger Matrix

WorkflowTrigger TypeTrigger DetailInvokes Script
claude.ymlEventissue_comment with @claude—
claude-issue-triage.ymlEventissues.opened—
sweep.ymlCron0 10,22 * * *sweep.ts
claude-dedupe-issues.ymlEventissues.openedcomment-on-duplicates.sh
auto-close-duplicates.ymlCron + DispatchScheduledauto-close-duplicates.ts
issue-lifecycle-comment.ymlEventissues.labeledlifecycle-comment.ts
lock-closed-issues.ymlCronScheduled—
issue-opened-dispatch.ymlEventissues.opened—
log-issue-events.ymlEventMultiple issue events—
non-write-users-check.ymlEventpull_request_target—
remove-autoclose-label.ymlEventissue_comment—
backfill-duplicate-comments.ymlDispatchworkflow_dispatchbackfill-duplicate-comments.ts

Interactions

ModuleInterfaceData Exchanged
scripts/Direct invocationTypeScript/shell scripts called with npx tsx or bash
Claude Code AIAPI callsIssue triage results, @claude responses via Anthropic API
GitHub APIREST / GraphQLIssue CRUD, label management, comment posting
Repository secretsEnvironment variablesGITHUB_TOKEN, ANTHROPIC_API_KEY, CLAUDE_CODE_*

Directory Map

Source tree for GitHub Workflows
.github/workflows/
├── claude.yml                        ← @claude mention handler (Sonnet 4.5)
├── claude-issue-triage.yml            ← AI issue triage (Opus 4-6, 5min)
├── sweep.yml                         ← Twice-daily lifecycle sweep
├── claude-dedupe-issues.yml           ← Duplicate detection pipeline
├── auto-close-duplicates.yml          ← Close confirmed duplicates (3d)
├── issue-opened-dispatch.yml          ← Event dispatch for new issues
├── issue-lifecycle-comment.yml        ← Post lifecycle warning comments
├── lock-closed-issues.yml             ← Lock old closed issues
├── log-issue-events.yml               ← Event logging / audit trail
├── non-write-users-check.yml          ← Permission verification
├── remove-autoclose-label.yml         ← Label cleanup on activity
└── backfill-duplicate-comments.yml    ← Backfill duplicate comments