5a558eb09e
TypeScript SDK Compatibility V1.x E2E Tests / Select Node version matrix (push) Has been cancelled
TypeScript SDK Compatibility V1.x E2E Tests / TypeScript SDK Compatibility V1.x E2E Tests Node ${{matrix.node_version}} (push) Has been cancelled
TypeScript SDK E2E Tests / TypeScript SDK E2E Tests Node ${{matrix.node_version}} (push) Has been cancelled
Opik Optimizer - E2E Tests / build-opik (push) Has been cancelled
TypeScript SDK Compatibility V1.x E2E Tests / build-opik (push) Has been cancelled
Python SDK E2E Tests / Select Python version matrix (push) Has been cancelled
Python SDK E2E Tests / Python SDK E2E Tests ${{matrix.python_version}} (push) Has been cancelled
Python SDK E2E Tests / build-opik (push) Has been cancelled
Python SDK Compatibility V1.x E2E Tests / Select Python version matrix (push) Has been cancelled
Python SDK Compatibility V1.x E2E Tests / Python SDK Compatibility V1.x E2E Tests ${{matrix.python_version}} (push) Has been cancelled
Python SDK Compatibility V1.x E2E Tests / build-opik (push) Has been cancelled
TypeScript SDK E2E Tests / Select Node version matrix (push) Has been cancelled
TypeScript SDK E2E Tests / build-opik (push) Has been cancelled
Opik Optimizer - E2E Tests / Opik Optimizer E2E Tests Python ${{matrix.python_version}} (push) Has been cancelled
Opik Optimizer - E2E Tests / Opik Optimizer Integration Smoke Tests (push) Has been cancelled
🐙 Code Quality / detect (push) Has been cancelled
🐙 Code Quality / lint (${{ matrix.leg.name }}) (push) Has been cancelled
🐙 Code Quality / summary (push) Has been cancelled
TypeScript SDK Library Integration Tests / Check Secrets (push) Has been cancelled
TypeScript SDK Library Integration Tests / opik-vercel (Vercel AI SDK / eve) (push) Has been cancelled
SDK Library Integration Tests Runner / Check Secrets (push) Has been cancelled
SDK Library Integration Tests Runner / Missed OpenAI API Key Warning (push) Has been cancelled
SDK Library Integration Tests Runner / Build (push) Has been cancelled
SDK Library Integration Tests Runner / openai_tests (push) Has been cancelled
SDK Library Integration Tests Runner / langchain_tests (push) Has been cancelled
SDK Library Integration Tests Runner / langchain_legacy_tests (push) Has been cancelled
SDK Library Integration Tests Runner / llama_index_tests (push) Has been cancelled
SDK Library Integration Tests Runner / anthropic_tests (push) Has been cancelled
SDK Library Integration Tests Runner / mistral_tests (push) Has been cancelled
SDK Library Integration Tests Runner / groq_tests (push) Has been cancelled
SDK Library Integration Tests Runner / aisuite_tests (push) Has been cancelled
SDK Library Integration Tests Runner / haystack_tests (push) Has been cancelled
SDK Library Integration Tests Runner / dspy_tests (push) Has been cancelled
SDK Library Integration Tests Runner / crewai_v0_tests (push) Has been cancelled
SDK Library Integration Tests Runner / crewai_v1_tests (push) Has been cancelled
SDK Library Integration Tests Runner / genai_tests (push) Has been cancelled
SDK Library Integration Tests Runner / adk_tests (push) Has been cancelled
SDK Library Integration Tests Runner / adk_legacy_1_3_0_tests (push) Has been cancelled
SDK Library Integration Tests Runner / evaluation_metrics_tests (push) Has been cancelled
SDK Library Integration Tests Runner / bedrock_tests (push) Has been cancelled
SDK Library Integration Tests Runner / litellm_tests (push) Has been cancelled
SDK Library Integration Tests Runner / harbor_tests (push) Has been cancelled
SDK Library Integration Tests Runner / Slack Notification (push) Has been cancelled
Lint Opik Helm Chart / render-equality (push) Has been cancelled
Opik Optimizer - Unit Tests / Opik Optimizer Unit Tests Python ${{matrix.python_version}} (push) Has been cancelled
Python BE E2E Tests / Python BE E2E (push) Has been cancelled
Python Backend Tests / run-python-backend-tests (push) Has been cancelled
Python SDK Unit Tests / Python SDK Unit Tests ${{matrix.python_version}} (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
SDK E2E Libraries Integration Tests / Check Secrets (push) Has been cancelled
SDK E2E Libraries Integration Tests / Missed OpenAI API Key Warning (push) Has been cancelled
SDK E2E Libraries Integration Tests / build-opik (push) Has been cancelled
SDK E2E Libraries Integration Tests / E2E Lib Integration Python ${{matrix.python_version}} (push) Has been cancelled
TypeScript SDK Integration Build & Publish / build-and-publish (opik-gemini) (push) Has been cancelled
TypeScript SDK Integration Build & Publish / build-and-publish (opik-langchain) (push) Has been cancelled
TypeScript SDK Integration Build & Publish / build-and-publish (opik-openai) (push) Has been cancelled
TypeScript SDK Integration Build & Publish / build-and-publish (opik-otel) (push) Has been cancelled
TypeScript SDK Integration Build & Publish / build-and-publish (opik-vercel) (push) Has been cancelled
TypeScript SDK Build & Publish / build-and-publish (push) Has been cancelled
TypeScript SDK Unit Tests / Test on Node ${{ matrix.node-version }} (push) Has been cancelled
Backend Tests / discover-tests (push) Has been cancelled
Backend Tests / ${{ matrix.name }} (push) Has been cancelled
Build and Publish SDK / build-and-publish (push) Has been cancelled
Build Opik Docker Images / set-version (push) Has been cancelled
Build Opik Docker Images / build-backend (push) Has been cancelled
Build Opik Docker Images / build-sandbox-executor-python (push) Has been cancelled
Build Opik Docker Images / build-python-backend (push) Has been cancelled
Build Opik Docker Images / build-frontend (push) Has been cancelled
Build Opik Docker Images / create-git-tag (push) Has been cancelled
ClickHouse Migration Cluster Check / validate-clickhouse-migrations (push) Has been cancelled
Docs - Publish / run (push) Has been cancelled
E2E Tests - Post Merge (v2) / 🧪 E2E v2 Tests (${{ github.event.inputs.tier || 't1' }}) (push) Has been cancelled
E2E Tests - Post Merge (v2) / 📢 Slack Notification (push) Has been cancelled
Frontend Unit Tests / Test on Node 20 (push) Has been cancelled
Guardrails E2E Tests / Select Python version matrix (push) Has been cancelled
Guardrails E2E Tests / Guardrails E2E Tests ${{matrix.python_version}} (push) Has been cancelled
Guardrails E2E Tests / 📢 Slack Notification (push) Has been cancelled
Guardrails Backend Unit Tests / Guardrails Backend Unit Tests (push) Has been cancelled
Guardrails Backend Unit Tests / 📢 Slack Notification (push) Has been cancelled
Lint Opik Helm Chart / lint-helm-chart (Helm v3.21.0) (push) Has been cancelled
Lint Opik Helm Chart / lint-helm-chart (Helm v4.2.0) (push) Has been cancelled
Lint Opik Helm Chart / unittest-helm-chart (push) Has been cancelled
142 lines
5.2 KiB
YAML
142 lines
5.2 KiB
YAML
name: 📏 Auto Label PR Size
|
|
|
|
on:
|
|
pull_request_target:
|
|
types: [opened, reopened, synchronize, ready_for_review]
|
|
|
|
|
|
concurrency:
|
|
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
|
cancel-in-progress: true
|
|
jobs:
|
|
size-labeler:
|
|
name: Label PR by size
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 2
|
|
|
|
permissions:
|
|
contents: read
|
|
pull-requests: write
|
|
issues: write
|
|
|
|
steps:
|
|
- name: Compute size and apply label
|
|
uses: actions/github-script@v7
|
|
with:
|
|
script: |
|
|
const { owner, repo } = context.repo;
|
|
const pr = context.payload.pull_request;
|
|
const prNumber = pr.number;
|
|
|
|
// Uniform charcoal chip for every size label so the size metadata reads as one
|
|
// recessive family and doesn't compete with semantic labels (bug, Frontend, …) on
|
|
// a busy PR list. The cool -> hot ramp lives entirely in the per-bucket emoji
|
|
// (🔵 smallest -> 🔴 largest), which keeps its crisp shape on a neutral background.
|
|
// maxSize is the inclusive upper bound of changed LOC (additions + deletions) for
|
|
// the bucket; the last entry (null) catches everything above it.
|
|
const CHIP_COLOR = "2d3139";
|
|
const BUCKETS = [
|
|
{ name: "🔵 size/XS", color: CHIP_COLOR, maxSize: 19 },
|
|
{ name: "🟢 size/S", color: CHIP_COLOR, maxSize: 100 },
|
|
{ name: "🟡 size/M", color: CHIP_COLOR, maxSize: 300 },
|
|
{ name: "🟠 size/L", color: CHIP_COLOR, maxSize: 600 },
|
|
{ name: "🔴 size/XL", color: CHIP_COLOR, maxSize: null },
|
|
];
|
|
const MANAGED_LABELS = BUCKETS.map((b) => b.name);
|
|
|
|
// Lockfiles and generated clients dwarf the human-reviewed diff, so exclude them
|
|
// from the count — otherwise a lockfile bump mislabels a tiny PR as XL.
|
|
const IGNORE_GLOBS = [
|
|
"**/package-lock.json",
|
|
"**/yarn.lock",
|
|
"**/pnpm-lock.yaml",
|
|
"**/poetry.lock",
|
|
"**/uv.lock",
|
|
"sdks/python/src/opik/rest_api/**",
|
|
"sdks/typescript/src/opik/rest_api/**",
|
|
"**/*.snap",
|
|
"**/*.svg",
|
|
"**/*.png",
|
|
];
|
|
const globToRegExp = (glob) => {
|
|
let re = "";
|
|
for (let i = 0; i < glob.length; i++) {
|
|
if (glob.startsWith("**/", i)) { re += "(?:[^/]+/)*"; i += 2; continue; }
|
|
if (glob.startsWith("**", i)) { re += ".*"; i += 1; continue; }
|
|
const c = glob[i];
|
|
if (c === "*") { re += "[^/]*"; continue; }
|
|
if (".+^${}()|[]\\".includes(c)) { re += "\\" + c; continue; }
|
|
re += c;
|
|
}
|
|
return new RegExp("^" + re + "$");
|
|
};
|
|
const ignoreRes = IGNORE_GLOBS.map(globToRegExp);
|
|
const isIgnored = (path) => ignoreRes.some((re) => re.test(path));
|
|
|
|
const files = await github.paginate(github.rest.pulls.listFiles, {
|
|
owner,
|
|
repo,
|
|
pull_number: prNumber,
|
|
per_page: 100,
|
|
});
|
|
|
|
const total = files
|
|
.filter((f) => !isIgnored(f.filename))
|
|
.reduce((sum, f) => sum + f.additions + f.deletions, 0);
|
|
|
|
const bucket =
|
|
BUCKETS.find((b) => b.maxSize !== null && total <= b.maxSize) ||
|
|
BUCKETS[BUCKETS.length - 1];
|
|
core.info(`PR #${prNumber}: ${total} changed LOC (excluding ignored files) -> ${bucket.name}`);
|
|
|
|
// Keep the label's color/emoji authoritative regardless of how it was first created.
|
|
try {
|
|
const { data: existing } = await github.rest.issues.getLabel({
|
|
owner,
|
|
repo,
|
|
name: bucket.name,
|
|
});
|
|
if (existing.color !== bucket.color) {
|
|
await github.rest.issues.updateLabel({
|
|
owner,
|
|
repo,
|
|
name: bucket.name,
|
|
color: bucket.color,
|
|
});
|
|
}
|
|
} catch (err) {
|
|
if (err.status !== 404) throw err;
|
|
await github.rest.issues.createLabel({
|
|
owner,
|
|
repo,
|
|
name: bucket.name,
|
|
color: bucket.color,
|
|
});
|
|
}
|
|
|
|
const current = pr.labels.map((l) => l.name);
|
|
|
|
for (const stale of current.filter(
|
|
(name) => MANAGED_LABELS.includes(name) && name !== bucket.name
|
|
)) {
|
|
try {
|
|
await github.rest.issues.removeLabel({
|
|
owner,
|
|
repo,
|
|
issue_number: prNumber,
|
|
name: stale,
|
|
});
|
|
} catch (err) {
|
|
if (err.status !== 404) throw err;
|
|
}
|
|
}
|
|
|
|
if (!current.includes(bucket.name)) {
|
|
await github.rest.issues.addLabels({
|
|
owner,
|
|
repo,
|
|
issue_number: prNumber,
|
|
labels: [bucket.name],
|
|
});
|
|
}
|