From 6bc34ff44f9931a77e5e82cff87dc2aa266a41a4 Mon Sep 17 00:00:00 2001 From: Conrad Irwin Date: Thu, 26 Mar 2026 21:39:48 -0600 Subject: [PATCH] Remove PR size notifications (#52373) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These are noisy, and in general I'd prefer people to focus on the quality of the resulting system; not the size of the diff. (Which may require deliberately making changes larger) ## Context ## How to Review ## Self-Review Checklist - [ ] I've reviewed my own diff for quality, security, and reliability - [ ] Unsafe blocks (if any) have justifying comments - [ ] The content is consistent with the [UI/UX checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) - [ ] Tests cover the new/changed behavior - [ ] Performance impact has been considered and is acceptable Release Notes: - N/A --- .github/pull_request_template.md | 21 +-- .github/workflows/pr-size-check.yml | 109 ---------------- .github/workflows/pr-size-label.yml | 195 ---------------------------- 3 files changed, 3 insertions(+), 322 deletions(-) delete mode 100644 .github/workflows/pr-size-check.yml delete mode 100644 .github/workflows/pr-size-label.yml diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index b8b7939813f9cc72da88e75653b6f2933403a239..a56793ad6222e5788621f6c8a430205e9ad848d7 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,28 +1,13 @@ -## Context +Self-Review Checklist: - - -## How to Review - - - -## Self-Review Checklist - - - [ ] I've reviewed my own diff for quality, security, and reliability - [ ] Unsafe blocks (if any) have justifying comments - [ ] The content is consistent with the [UI/UX checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) - [ ] Tests cover the new/changed behavior - [ ] Performance impact has been considered and is acceptable +Closes #ISSUE + Release Notes: - N/A or Added/Fixed/Improved ... diff --git a/.github/workflows/pr-size-check.yml b/.github/workflows/pr-size-check.yml deleted file mode 100644 index 6cbed314e012c66da16fd016dd9b3cdcf9788149..0000000000000000000000000000000000000000 --- a/.github/workflows/pr-size-check.yml +++ /dev/null @@ -1,109 +0,0 @@ -# PR Size Check — Compute -# -# Calculates PR size and saves the result as an artifact. A companion -# workflow (pr-size-label.yml) picks up the artifact via workflow_run -# and applies labels + comments with write permissions. -# -# This two-workflow split is required because fork PRs receive a -# read-only GITHUB_TOKEN. The compute step needs no write access; -# the label/comment step runs via workflow_run on the base repo with -# full write permissions. -# -# Security note: This workflow only reads PR file data via the JS API -# and writes a JSON artifact. No untrusted input is interpolated into -# shell commands. - -name: PR Size Check - -on: - pull_request: - types: [opened, synchronize] - -permissions: - contents: read - pull-requests: read - -jobs: - compute-size: - if: github.repository_owner == 'zed-industries' - runs-on: ubuntu-latest - timeout-minutes: 5 - steps: - - name: Calculate PR size - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 - with: - script: | - const fs = require('fs'); - - const { data: files } = await github.rest.pulls.listFiles({ - owner: context.repo.owner, - repo: context.repo.repo, - pull_number: context.issue.number, - per_page: 300, - }); - - // Sum additions + deletions, excluding generated/lock files - const IGNORED_PATTERNS = [ - /\.lock$/, - /^Cargo\.lock$/, - /pnpm-lock\.yaml$/, - /\.generated\./, - /\/fixtures\//, - /\/snapshots\//, - ]; - - let totalChanges = 0; - for (const file of files) { - const ignored = IGNORED_PATTERNS.some(p => p.test(file.filename)); - if (!ignored) { - totalChanges += file.additions + file.deletions; - } - } - - // Assign size bracket - const SIZE_BRACKETS = [ - ['Size S', 0, 100, '0e8a16'], - ['Size M', 100, 400, 'fbca04'], - ['Size L', 400, 800, 'e99695'], - ['Size XL', 800, Infinity, 'b60205'], - ]; - - let sizeLabel = 'Size S'; - let labelColor = '0e8a16'; - for (const [label, min, max, color] of SIZE_BRACKETS) { - if (totalChanges >= min && totalChanges < max) { - sizeLabel = label; - labelColor = color; - break; - } - } - - // Check if the author wrote content in the "How to Review" section. - const rawBody = context.payload.pull_request.body || ''; - const howToReview = rawBody.match(/## How to Review\s*\n([\s\S]*?)(?=\n## |$)/i); - const hasReviewGuidance = howToReview - ? howToReview[1].replace(//g, '').trim().length > 0 - : false; - - const result = { - pr_number: context.issue.number, - total_changes: totalChanges, - size_label: sizeLabel, - label_color: labelColor, - has_review_guidance: hasReviewGuidance, - }; - - console.log(`PR #${result.pr_number}: ${totalChanges} LOC, ${sizeLabel}`); - - fs.mkdirSync('pr-size', { recursive: true }); - fs.writeFileSync('pr-size/result.json', JSON.stringify(result)); - - - name: Upload size result - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 - with: - name: pr-size-result - path: pr-size/ - retention-days: 1 -defaults: - run: - shell: bash -euxo pipefail {0} diff --git a/.github/workflows/pr-size-label.yml b/.github/workflows/pr-size-label.yml deleted file mode 100644 index 599daf122aac728c469acd45da865e1079c07fb6..0000000000000000000000000000000000000000 --- a/.github/workflows/pr-size-label.yml +++ /dev/null @@ -1,195 +0,0 @@ -# PR Size Check — Label & Comment -# -# Triggered by workflow_run after pr-size-check.yml completes. -# Downloads the size result artifact and applies labels + comments. -# -# This runs on the base repo with full GITHUB_TOKEN write access, -# so it works for both same-repo and fork PRs. -# -# Security note: The artifact is treated as untrusted data — only -# structured JSON fields (PR number, size label, color, boolean) are -# read. No artifact content is executed or interpolated into shell. - -name: PR Size Label - -on: - workflow_run: - workflows: ["PR Size Check"] - types: [completed] - -jobs: - apply-labels: - if: > - github.repository_owner == 'zed-industries' && - github.event.workflow_run.conclusion == 'success' - permissions: - contents: read - pull-requests: write - issues: write - runs-on: ubuntu-latest - timeout-minutes: 5 - steps: - - name: Download size result artifact - id: download - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 - with: - script: | - const fs = require('fs'); - const path = require('path'); - - const allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({ - owner: context.repo.owner, - repo: context.repo.repo, - run_id: context.payload.workflow_run.id, - }); - - const match = allArtifacts.data.artifacts.find(a => a.name === 'pr-size-result'); - if (!match) { - console.log('No pr-size-result artifact found, skipping'); - core.setOutput('found', 'false'); - return; - } - - const download = await github.rest.actions.downloadArtifact({ - owner: context.repo.owner, - repo: context.repo.repo, - artifact_id: match.id, - archive_format: 'zip', - }); - - const temp = path.join(process.env.RUNNER_TEMP, 'pr-size'); - fs.mkdirSync(temp, { recursive: true }); - fs.writeFileSync(path.join(temp, 'result.zip'), Buffer.from(download.data)); - core.setOutput('found', 'true'); - - - name: Unzip artifact - if: steps.download.outputs.found == 'true' - env: - ARTIFACT_DIR: ${{ runner.temp }}/pr-size - run: unzip "$ARTIFACT_DIR/result.zip" -d "$ARTIFACT_DIR" - - - name: Apply labels and comment - if: steps.download.outputs.found == 'true' - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 - with: - script: | - const fs = require('fs'); - const path = require('path'); - - const temp = path.join(process.env.RUNNER_TEMP, 'pr-size'); - const resultPath = path.join(temp, 'result.json'); - if (!fs.existsSync(resultPath)) { - console.log('No result.json found, skipping'); - return; - } - - const result = JSON.parse(fs.readFileSync(resultPath, 'utf8')); - - // Validate artifact data (treat as untrusted) - const prNumber = Number(result.pr_number); - const totalChanges = Number(result.total_changes); - const sizeLabel = String(result.size_label); - const labelColor = String(result.label_color); - const hasReviewGuidance = Boolean(result.has_review_guidance); - - if (!prNumber || !sizeLabel.startsWith('Size ')) { - core.setFailed(`Invalid artifact data: pr=${prNumber}, label=${sizeLabel}`); - return; - } - - console.log(`PR #${prNumber}: ${totalChanges} LOC, ${sizeLabel}`); - - // --- Size label (idempotent) --- - const existingLabels = (await github.rest.issues.listLabelsOnIssue({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: prNumber, - })).data.map(l => l.name); - - const existingSizeLabels = existingLabels.filter(l => l.startsWith('Size ')); - const alreadyCorrect = existingSizeLabels.length === 1 && existingSizeLabels[0] === sizeLabel; - - if (!alreadyCorrect) { - for (const label of existingSizeLabels) { - await github.rest.issues.removeLabel({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: prNumber, - name: label, - }); - } - - try { - await github.rest.issues.createLabel({ - owner: context.repo.owner, - repo: context.repo.repo, - name: sizeLabel, - color: labelColor, - }); - } catch (e) { - if (e.status !== 422) throw e; - } - - await github.rest.issues.addLabels({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: prNumber, - labels: [sizeLabel], - }); - } - - // --- Large PR handling (400+ LOC) --- - if (totalChanges >= 400) { - if (!existingLabels.includes('large-pr')) { - try { - await github.rest.issues.createLabel({ - owner: context.repo.owner, - repo: context.repo.repo, - name: 'large-pr', - color: 'e99695', - }); - } catch (e) { - if (e.status !== 422) throw e; - } - - await github.rest.issues.addLabels({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: prNumber, - labels: ['large-pr'], - }); - } - - // Comment once with guidance - const MARKER = ''; - const { data: comments } = await github.rest.issues.listComments({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: prNumber, - }); - - const alreadyCommented = comments.some(c => c.body.includes(MARKER)); - if (!alreadyCommented) { - let body = `${MARKER}\n`; - body += `### :straight_ruler: PR Size: **${totalChanges} lines changed** (${sizeLabel})\n\n`; - body += `Please note: this PR exceeds the 400 LOC soft limit.\n`; - body += `- Consider **splitting** into separate PRs if the changes are separable\n`; - body += `- Ensure the PR description includes a **guided tour** in the "How to Review" section so reviewers know where to start\n`; - - if (hasReviewGuidance) { - body += `\n:white_check_mark: "How to Review" section appears to include guidance — thank you!\n`; - } - - await github.rest.issues.createComment({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: prNumber, - body: body, - }); - } - } - - console.log(`PR #${prNumber}: labeled ${sizeLabel}, done`); -defaults: - run: - shell: bash -euxo pipefail {0}