1010 types : [completed]
1111
1212permissions :
13+ issues : write
1314 pull-requests : write
1415 actions : read # needed to download artifacts
1516
@@ -30,14 +31,75 @@ jobs:
3031 with :
3132 script : |
3233 const fs = require('fs');
34+ const managedLabels = {
35+ 'skill-check-warning': {
36+ color: 'FBCA04',
37+ description: 'Skill validator reported warnings'
38+ },
39+ 'skill-check-error': {
40+ color: 'B60205',
41+ description: 'Skill validator reported errors'
42+ }
43+ };
44+
45+ async function ensureLabel(name, { color, description }) {
46+ try {
47+ await github.rest.issues.createLabel({
48+ owner: context.repo.owner,
49+ repo: context.repo.repo,
50+ name,
51+ color,
52+ description
53+ });
54+ } catch (error) {
55+ if (error.status !== 422) {
56+ throw error;
57+ }
58+ }
59+ }
3360
34- const total = parseInt(fs.readFileSync('total.txt', 'utf8').trim(), 10);
35- if (total === 0) {
36- console.log('No skills/agents were checked — skipping comment.');
37- return;
61+ async function syncManagedLabels(issueNumber, desiredLabels) {
62+ await Promise.all(
63+ Object.entries(managedLabels).map(([name, config]) => ensureLabel(name, config))
64+ );
65+
66+ const currentLabels = await github.paginate(github.rest.issues.listLabelsOnIssue, {
67+ owner: context.repo.owner,
68+ repo: context.repo.repo,
69+ issue_number: issueNumber,
70+ per_page: 100
71+ });
72+
73+ const currentManagedLabels = currentLabels
74+ .map((label) => label.name)
75+ .filter((name) => Object.prototype.hasOwnProperty.call(managedLabels, name));
76+
77+ const labelsToAdd = [...desiredLabels].filter((name) => !currentManagedLabels.includes(name));
78+ const labelsToRemove = currentManagedLabels.filter((name) => !desiredLabels.has(name));
79+
80+ if (labelsToAdd.length > 0) {
81+ await github.rest.issues.addLabels({
82+ owner: context.repo.owner,
83+ repo: context.repo.repo,
84+ issue_number: issueNumber,
85+ labels: labelsToAdd
86+ });
87+ }
88+
89+ for (const name of labelsToRemove) {
90+ await github.rest.issues.removeLabel({
91+ owner: context.repo.owner,
92+ repo: context.repo.repo,
93+ issue_number: issueNumber,
94+ name
95+ });
96+ }
97+
98+ console.log(`Managed skill check labels: ${[...desiredLabels].sort().join(', ') || 'none'}`);
3899 }
39100
40101 const prNumber = parseInt(fs.readFileSync('pr-number.txt', 'utf8').trim(), 10);
102+ const total = parseInt(fs.readFileSync('total.txt', 'utf8').trim(), 10);
41103 const exitCode = fs.readFileSync('exit-code.txt', 'utf8').trim();
42104 const skillCount = parseInt(fs.readFileSync('skill-count.txt', 'utf8').trim(), 10);
43105 const agentCount = parseInt(fs.readFileSync('agent-count.txt', 'utf8').trim(), 10);
@@ -52,6 +114,22 @@ jobs:
52114 const errorCount = (output.match(/❌/g) || []).length;
53115 const warningCount = (output.match(/⚠/g) || []).length;
54116 const advisoryCount = (output.match(/ℹ/g) || []).length;
117+ const desiredLabels = new Set();
118+
119+ if (warningCount > 0) {
120+ desiredLabels.add('skill-check-warning');
121+ }
122+
123+ if (exitCode !== '0' || errorCount > 0) {
124+ desiredLabels.add('skill-check-error');
125+ }
126+
127+ await syncManagedLabels(prNumber, desiredLabels);
128+
129+ if (total === 0) {
130+ console.log('No skills/agents were checked — skipping comment.');
131+ return;
132+ }
55133
56134 let verdict = '✅ All checks passed';
57135 if (exitCode !== '0' || errorCount > 0) {
0 commit comments