Compare commits
3 commits
main
...
chore/repl
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1d938a8598 | ||
|
|
16a5c721aa | ||
|
|
bc6d147b85 |
3 changed files with 163 additions and 8 deletions
22
.github/labels.yml
vendored
22
.github/labels.yml
vendored
|
|
@ -21,7 +21,7 @@
|
|||
# area/ subsystem; extensible — add when 3+ open issues exist
|
||||
# do-not-merge/ PR merge blockers
|
||||
# security/ security-finding severity and status (Cozystack-specific)
|
||||
# size: PR size (auto-applied)
|
||||
# size/ PR size (auto-applied)
|
||||
#
|
||||
# `aliases:` lets EndBug/label-sync rename existing labels without losing
|
||||
# references on already-tagged issues and PRs.
|
||||
|
|
@ -295,32 +295,38 @@
|
|||
description: Indicates a non-member PR is safe to run CI on
|
||||
|
||||
# ──────────────────────────────────────────────
|
||||
# size: — PR size (auto-applied by sizing bot)
|
||||
# size/ — PR size (auto-applied by .github/workflows/pr-size.yaml)
|
||||
# ──────────────────────────────────────────────
|
||||
|
||||
- name: 'size:XS'
|
||||
- name: size/XS
|
||||
color: '00ff00'
|
||||
description: This PR changes 0-9 lines, ignoring generated files
|
||||
aliases: ['size:XS']
|
||||
|
||||
- name: 'size:S'
|
||||
- name: size/S
|
||||
color: '77b800'
|
||||
description: This PR changes 10-29 lines, ignoring generated files
|
||||
aliases: ['size:S']
|
||||
|
||||
- name: 'size:M'
|
||||
- name: size/M
|
||||
color: 'ebb800'
|
||||
description: This PR changes 30-99 lines, ignoring generated files
|
||||
aliases: ['size:M']
|
||||
|
||||
- name: 'size:L'
|
||||
- name: size/L
|
||||
color: 'eb9500'
|
||||
description: This PR changes 100-499 lines, ignoring generated files
|
||||
aliases: ['size:L']
|
||||
|
||||
- name: 'size:XL'
|
||||
- name: size/XL
|
||||
color: 'ff823f'
|
||||
description: This PR changes 500-999 lines, ignoring generated files
|
||||
aliases: ['size:XL']
|
||||
|
||||
- name: 'size:XXL'
|
||||
- name: size/XXL
|
||||
color: 'ffb8b8'
|
||||
description: This PR changes 1000+ lines, ignoring generated files
|
||||
aliases: ['size:XXL']
|
||||
|
||||
# ──────────────────────────────────────────────
|
||||
# security/ — security-finding severity and status
|
||||
|
|
|
|||
93
.github/workflows/pr-size.yaml
vendored
Normal file
93
.github/workflows/pr-size.yaml
vendored
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
name: PR size label
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [opened, synchronize, reopened]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
|
||||
concurrency:
|
||||
group: pr-size-${{ github.event.pull_request.number }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
size:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
const pr = context.payload.pull_request;
|
||||
|
||||
// Skip files that should not count as "real diff" — they are produced by tools,
|
||||
// not authored by humans, and including them lies to reviewers about review effort:
|
||||
// - vendored Go deps,
|
||||
// - kubebuilder/openapi inline generated files (zz_generated.{deepcopy,conversion,defaults,openapi}.go),
|
||||
// - whole code-generated trees from client-gen / lister-gen / applyconfiguration-gen
|
||||
// and protobuf (any path under a `generated/` directory or ending in `.pb.go`),
|
||||
// - vendored Helm charts,
|
||||
// - lockfiles.
|
||||
const isIgnored = (path) =>
|
||||
path.startsWith('vendor/') ||
|
||||
/\bzz_generated\.[^/]*\.go$/.test(path) ||
|
||||
/(^|\/)generated\//.test(path) ||
|
||||
path.endsWith('.pb.go') ||
|
||||
/^packages\/system\/[^/]+\/charts\//.test(path) ||
|
||||
path === 'go.sum' || path.endsWith('/go.sum') ||
|
||||
path.endsWith('.lock') || path.endsWith('.lockb');
|
||||
|
||||
const files = await github.paginate(github.rest.pulls.listFiles, {
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
pull_number: pr.number,
|
||||
});
|
||||
const lines = files
|
||||
.filter((f) => !isIgnored(f.filename))
|
||||
.reduce((acc, f) => acc + (f.additions || 0) + (f.deletions || 0), 0);
|
||||
|
||||
// Thresholds match the descriptions of size/* labels in .github/labels.yml.
|
||||
const bucket =
|
||||
lines <= 9 ? 'XS' :
|
||||
lines <= 29 ? 'S' :
|
||||
lines <= 99 ? 'M' :
|
||||
lines <= 499 ? 'L' :
|
||||
lines <= 999 ? 'XL' : 'XXL';
|
||||
const target = `size/${bucket}`;
|
||||
|
||||
// Match both legacy "size:" and canonical "size/" during the migration window.
|
||||
const existing = (pr.labels || []).map((l) => l.name);
|
||||
const oldSizes = existing.filter((n) => n.startsWith('size/') || n.startsWith('size:'));
|
||||
const alreadyTarget = oldSizes.includes(target);
|
||||
|
||||
// Remove every size/* label that is not the target. Tolerate 404 — concurrent
|
||||
// runs or manual edits between event payload and execution can race here.
|
||||
for (const name of oldSizes) {
|
||||
if (name === target) continue;
|
||||
try {
|
||||
await github.rest.issues.removeLabel({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: pr.number,
|
||||
name,
|
||||
});
|
||||
} catch (e) {
|
||||
if (e.status !== 404) throw e;
|
||||
core.info(`label ${name} already gone (404)`);
|
||||
}
|
||||
}
|
||||
|
||||
if (alreadyTarget && oldSizes.length === 1) {
|
||||
core.info(`PR #${pr.number}: ${lines} lines, label already ${target}`);
|
||||
return;
|
||||
}
|
||||
if (!alreadyTarget) {
|
||||
await github.rest.issues.addLabels({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: pr.number,
|
||||
labels: [target],
|
||||
});
|
||||
}
|
||||
core.info(`PR #${pr.number}: ${lines} lines -> ${target}`);
|
||||
56
.github/workflows/stale.yaml
vendored
Normal file
56
.github/workflows/stale.yaml
vendored
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
name: Stale issues
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '37 4 * * *' # daily at 04:37 UTC
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
issues: write
|
||||
pull-requests: write
|
||||
|
||||
concurrency:
|
||||
group: stale
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/stale@v10
|
||||
with:
|
||||
stale-issue-label: lifecycle/stale
|
||||
stale-pr-label: lifecycle/stale
|
||||
close-issue-label: lifecycle/rotten
|
||||
close-pr-label: lifecycle/rotten
|
||||
# Exempt lists differ on purpose: issues sit longer than PRs by nature.
|
||||
# An accepted issue (`triage/accepted`) is a known long-tail task, not stale;
|
||||
# a held PR (`do-not-merge/hold`) is paused intentionally and shouldn't auto-close.
|
||||
# Priority/security/regression labels protect issues that someone explicitly
|
||||
# decided to keep visible.
|
||||
exempt-issue-labels: >-
|
||||
lifecycle/frozen,epic,
|
||||
priority/critical-urgent,priority/important-soon,priority/important-longterm,
|
||||
security/critical,security/high,security/confirmed,
|
||||
security/triage-needed,security/in-progress,
|
||||
triage/accepted,kind/regression
|
||||
exempt-pr-labels: >-
|
||||
lifecycle/frozen,do-not-merge/hold,
|
||||
backport,backport-previous
|
||||
days-before-stale: 60
|
||||
days-before-close: 14
|
||||
operations-per-run: 100
|
||||
remove-stale-when-updated: true
|
||||
stale-issue-message: |
|
||||
This issue has had no activity for 60 days and was marked `lifecycle/stale`.
|
||||
It will be closed in 14 days unless commented or labelled `lifecycle/frozen`.
|
||||
stale-pr-message: |
|
||||
This PR has had no activity for 60 days and was marked `lifecycle/stale`.
|
||||
It will be closed in 14 days unless commented or labelled `lifecycle/frozen`.
|
||||
close-issue-message: |
|
||||
Closed because no activity followed the `lifecycle/stale` warning.
|
||||
Reopen if the issue is still relevant.
|
||||
close-pr-message: |
|
||||
Closed because no activity followed the `lifecycle/stale` warning.
|
||||
Reopen if the change is still wanted.
|
||||
Loading…
Add table
Add a link
Reference in a new issue