From 01359fc52a06b4fa7011c26cec0f67b8f6bf3f81 Mon Sep 17 00:00:00 2001 From: Mark Bema Date: Tue, 16 Jun 2026 09:12:21 +0000 Subject: [PATCH] ci: disable upstream issue maintenance workflows --- .github/workflows/close-stale-prs.yml | 236 ------------------ .../close-issues.yml.disabled} | 3 +- .../duplicate-issues.yml.disabled} | 30 +-- script/check-workflows.ts | 3 - 4 files changed, 12 insertions(+), 260 deletions(-) delete mode 100644 .github/workflows/close-stale-prs.yml rename .github/workflows/{close-issues.yml => disabled/close-issues.yml.disabled} (75%) rename .github/workflows/{duplicate-issues.yml => disabled/duplicate-issues.yml.disabled} (88%) diff --git a/.github/workflows/close-stale-prs.yml b/.github/workflows/close-stale-prs.yml deleted file mode 100644 index 3e7b1db14b7..00000000000 --- a/.github/workflows/close-stale-prs.yml +++ /dev/null @@ -1,236 +0,0 @@ -name: close-stale-prs # kilocode_change - -on: - workflow_dispatch: - inputs: - dryRun: - description: "Log actions without closing PRs" - type: boolean - default: false - schedule: - - cron: "0 6 * * *" - -permissions: - contents: read - issues: write - pull-requests: write - -jobs: - close-stale-prs: - if: github.repository == 'anomalyco/opencode' # kilocode_change - Kilo uses kilo-auto-close.yml - runs-on: blacksmith-2vcpu-ubuntu-2404 # kilocode_change - timeout-minutes: 15 - steps: - - name: Close inactive PRs - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - const DAYS_INACTIVE = 60 - const MAX_RETRIES = 3 - - // Adaptive delay: fast for small batches, slower for large to respect - // GitHub's 80 content-generating requests/minute limit - const SMALL_BATCH_THRESHOLD = 10 - const SMALL_BATCH_DELAY_MS = 1000 // 1s for daily operations (≤10 PRs) - const LARGE_BATCH_DELAY_MS = 2000 // 2s for backlog (>10 PRs) = ~30 ops/min, well under 80 limit - - const startTime = Date.now() - const cutoff = new Date(Date.now() - DAYS_INACTIVE * 24 * 60 * 60 * 1000) - const { owner, repo } = context.repo - const dryRun = context.payload.inputs?.dryRun === "true" - - core.info(`Dry run mode: ${dryRun}`) - core.info(`Cutoff date: ${cutoff.toISOString()}`) - - function sleep(ms) { - return new Promise(resolve => setTimeout(resolve, ms)) - } - - async function withRetry(fn, description = 'API call') { - let lastError - for (let attempt = 0; attempt < MAX_RETRIES; attempt++) { - try { - const result = await fn() - return result - } catch (error) { - lastError = error - const isRateLimited = error.status === 403 && - (error.message?.includes('rate limit') || error.message?.includes('secondary')) - - if (!isRateLimited) { - throw error - } - - // Parse retry-after header, default to 60 seconds - const retryAfter = error.response?.headers?.['retry-after'] - ? parseInt(error.response.headers['retry-after']) - : 60 - - // Exponential backoff: retryAfter * 2^attempt - const backoffMs = retryAfter * 1000 * Math.pow(2, attempt) - - core.warning(`${description}: Rate limited (attempt ${attempt + 1}/${MAX_RETRIES}). Waiting ${backoffMs / 1000}s before retry...`) - - await sleep(backoffMs) - } - } - core.error(`${description}: Max retries (${MAX_RETRIES}) exceeded`) - throw lastError - } - - const query = ` - query($owner: String!, $repo: String!, $cursor: String) { - repository(owner: $owner, name: $repo) { - pullRequests(first: 100, states: OPEN, after: $cursor) { - pageInfo { - hasNextPage - endCursor - } - nodes { - number - title - author { - login - } - createdAt - commits(last: 1) { - nodes { - commit { - committedDate - } - } - } - comments(last: 1) { - nodes { - createdAt - } - } - reviews(last: 1) { - nodes { - createdAt - } - } - } - } - } - } - ` - - const allPrs = [] - let cursor = null - let hasNextPage = true - let pageCount = 0 - - while (hasNextPage) { - pageCount++ - core.info(`Fetching page ${pageCount} of open PRs...`) - - const result = await withRetry( - () => github.graphql(query, { owner, repo, cursor }), - `GraphQL page ${pageCount}` - ) - - allPrs.push(...result.repository.pullRequests.nodes) - hasNextPage = result.repository.pullRequests.pageInfo.hasNextPage - cursor = result.repository.pullRequests.pageInfo.endCursor - - core.info(`Page ${pageCount}: fetched ${result.repository.pullRequests.nodes.length} PRs (total: ${allPrs.length})`) - - // Delay between pagination requests (use small batch delay for reads) - if (hasNextPage) { - await sleep(SMALL_BATCH_DELAY_MS) - } - } - - core.info(`Found ${allPrs.length} open pull requests`) - - const stalePrs = allPrs.filter((pr) => { - const dates = [ - new Date(pr.createdAt), - pr.commits.nodes[0] ? new Date(pr.commits.nodes[0].commit.committedDate) : null, - pr.comments.nodes[0] ? new Date(pr.comments.nodes[0].createdAt) : null, - pr.reviews.nodes[0] ? new Date(pr.reviews.nodes[0].createdAt) : null, - ].filter((d) => d !== null) - - const lastActivity = dates.sort((a, b) => b.getTime() - a.getTime())[0] - - if (!lastActivity || lastActivity > cutoff) { - core.info(`PR #${pr.number} is fresh (last activity: ${lastActivity?.toISOString() || "unknown"})`) - return false - } - - core.info(`PR #${pr.number} is STALE (last activity: ${lastActivity.toISOString()})`) - return true - }) - - if (!stalePrs.length) { - core.info("No stale pull requests found.") - return - } - - core.info(`Found ${stalePrs.length} stale pull requests`) - - // ============================================ - // Close stale PRs - // ============================================ - const requestDelayMs = stalePrs.length > SMALL_BATCH_THRESHOLD - ? LARGE_BATCH_DELAY_MS - : SMALL_BATCH_DELAY_MS - - core.info(`Using ${requestDelayMs}ms delay between operations (${stalePrs.length > SMALL_BATCH_THRESHOLD ? 'large' : 'small'} batch mode)`) - - let closedCount = 0 - let skippedCount = 0 - - for (const pr of stalePrs) { - const issue_number = pr.number - const closeComment = `Closing this pull request because it has had no updates for more than ${DAYS_INACTIVE} days. If you plan to continue working on it, feel free to reopen or open a new PR.` - - if (dryRun) { - core.info(`[dry-run] Would close PR #${issue_number} from ${pr.author?.login || 'unknown'}: ${pr.title}`) - continue - } - - try { - // Add comment - await withRetry( - () => github.rest.issues.createComment({ - owner, - repo, - issue_number, - body: closeComment, - }), - `Comment on PR #${issue_number}` - ) - - // Close PR - await withRetry( - () => github.rest.pulls.update({ - owner, - repo, - pull_number: issue_number, - state: "closed", - }), - `Close PR #${issue_number}` - ) - - closedCount++ - core.info(`Closed PR #${issue_number} from ${pr.author?.login || 'unknown'}: ${pr.title}`) - - // Delay before processing next PR - await sleep(requestDelayMs) - } catch (error) { - skippedCount++ - core.error(`Failed to close PR #${issue_number}: ${error.message}`) - } - } - - const elapsed = Math.round((Date.now() - startTime) / 1000) - core.info(`\n========== Summary ==========`) - core.info(`Total open PRs found: ${allPrs.length}`) - core.info(`Stale PRs identified: ${stalePrs.length}`) - core.info(`PRs closed: ${closedCount}`) - core.info(`PRs skipped (errors): ${skippedCount}`) - core.info(`Elapsed time: ${elapsed}s`) - core.info(`=============================`) diff --git a/.github/workflows/close-issues.yml b/.github/workflows/disabled/close-issues.yml.disabled similarity index 75% rename from .github/workflows/close-issues.yml rename to .github/workflows/disabled/close-issues.yml.disabled index c071fd5bc83..b8a2e3f575d 100644 --- a/.github/workflows/close-issues.yml +++ b/.github/workflows/disabled/close-issues.yml.disabled @@ -7,13 +7,12 @@ on: jobs: close: - if: github.repository == 'anomalyco/opencode' # kilocode_change - Kilo uses kilo-auto-close.yml runs-on: ubuntu-latest permissions: contents: read issues: write steps: - - uses: actions/checkout@v6 # kilocode_change + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 with: diff --git a/.github/workflows/duplicate-issues.yml b/.github/workflows/disabled/duplicate-issues.yml.disabled similarity index 88% rename from .github/workflows/duplicate-issues.yml rename to .github/workflows/disabled/duplicate-issues.yml.disabled index cf02d8e0a48..ea2a67cb782 100644 --- a/.github/workflows/duplicate-issues.yml +++ b/.github/workflows/disabled/duplicate-issues.yml.disabled @@ -6,28 +6,25 @@ on: jobs: check-duplicates: - if: false # kilocode_change - disabled: not needed in kilocode repo + if: github.event.action == 'opened' runs-on: blacksmith-4vcpu-ubuntu-2404 permissions: contents: read issues: write steps: - name: Checkout repository - uses: actions/checkout@v6 # kilocode_change + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 with: fetch-depth: 1 - uses: ./.github/actions/setup-bun - # kilocode_change start - - name: Setup Kilo - uses: ./.github/actions/setup-kilo - # kilocode_change end + - name: Install opencode + run: curl -fsSL https://kilo.ai/install | bash - name: Check duplicates and compliance env: - KILO_API_KEY: ${{ secrets.KILO_API_KEY }} - KILO_ORG_ID: ${{ secrets.KILO_ORG_ID }} + OPENCODE_API_KEY: ${{ secrets.OPENCODE_API_KEY }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} KILO_PERMISSION: | { @@ -38,7 +35,7 @@ jobs: "webfetch": "deny" } run: | - kilo run -m "kilo/anthropic/claude-haiku-4.5" "A new issue has been created: + opencode run -m opencode/claude-sonnet-4-6 "A new issue has been created: Issue number: ${{ github.event.issue.number }} @@ -128,23 +125,18 @@ jobs: issues: write steps: - name: Checkout repository - uses: actions/checkout@v6 # kilocode_change + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 with: fetch-depth: 1 - uses: ./.github/actions/setup-bun - # kilocode_change start - - name: Setup Kilo - uses: ./.github/actions/setup-kilo - # kilocode_change end + - name: Install opencode + run: curl -fsSL https://kilo.ai/install | bash - name: Recheck compliance env: - # kilocode_change start - KILO_API_KEY: ${{ secrets.KILO_API_KEY }} - KILO_ORG_ID: ${{ secrets.KILO_ORG_ID }} - # kilocode_change end + OPENCODE_API_KEY: ${{ secrets.OPENCODE_API_KEY }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} KILO_PERMISSION: | { @@ -155,7 +147,7 @@ jobs: "webfetch": "deny" } run: | - kilo run -m "kilo/anthropic/claude-haiku-4.5" "Issue #${{ github.event.issue.number }} was previously flagged as non-compliant and has been edited. + opencode run -m opencode/claude-sonnet-4-6 "Issue #${{ github.event.issue.number }} was previously flagged as non-compliant and has been edited. Lookup this issue with gh issue view ${{ github.event.issue.number }}. diff --git a/script/check-workflows.ts b/script/check-workflows.ts index 0f738cbd1a9..75a0e870f91 100644 --- a/script/check-workflows.ts +++ b/script/check-workflows.ts @@ -34,14 +34,11 @@ const active = new Set([ "check-md-table-padding.yml", "check-opencode-annotations.yml", "check-org-member.yml", - "close-issues.yml", - "close-stale-prs.yml", "codeql-kotlin.yml", "codeql.yml", "containers.yml", "docs-build.yml", "docs-check-links.yml", - "duplicate-issues.yml", "generate.yml", "kilo-auto-close.yml", "nix-eval.yml",