Skip to content

Commit 7acc24d

Browse files
committed
Update label management for GitLab
1 parent d5307f2 commit 7acc24d

File tree

1 file changed

+82
-1
lines changed

1 file changed

+82
-1
lines changed

src/reporter/gitlab/index.js

Lines changed: 82 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,28 @@ export default class GitLab {
5757
}
5858

5959
const updatedExistingLabels = labelsToRemove.length ? await this.getRepositoryLabels() : existingLabels; // Refresh labels after deletion, only if needed
60-
const existingLabelsNames = updatedExistingLabels.map(label => label.name);
60+
const managedLabelsNames = this.MANAGED_LABELS.map(label => label.name);
61+
62+
// Remove managed labels that are no longer in the MANAGED_LABELS list
63+
const obsoleteManagedLabels = updatedExistingLabels.filter(label =>
64+
label.description
65+
&& label.description.includes(MANAGED_BY_OTA_MARKER)
66+
&& !managedLabelsNames.includes(label.name));
67+
68+
if (obsoleteManagedLabels.length) {
69+
logger.info(`Removing obsolete managed labels: ${obsoleteManagedLabels.map(label => `"${label.name}"`).join(', ')}`);
70+
71+
for (const label of obsoleteManagedLabels) {
72+
await this.deleteLabel(label.name); /* eslint-disable-line no-await-in-loop */
73+
}
74+
}
75+
76+
// Refresh labels after obsolete removal
77+
const finalExistingLabels = obsoleteManagedLabels.length ? await this.getRepositoryLabels() : updatedExistingLabels;
78+
const existingLabelsNames = finalExistingLabels.map(label => label.name);
79+
const existingLabelsMap = new Map(finalExistingLabels.map(label => [ label.name, label ]));
80+
81+
// Find labels that need to be created
6182
const missingLabels = this.MANAGED_LABELS.filter(label => !existingLabelsNames.includes(label.name));
6283

6384
if (missingLabels.length) {
@@ -71,6 +92,32 @@ export default class GitLab {
7192
});
7293
}
7394
}
95+
96+
// Update existing labels if description or color changed
97+
const labelsToUpdate = this.MANAGED_LABELS.filter(label => {
98+
const existingLabel = existingLabelsMap.get(label.name);
99+
100+
if (!existingLabel) {
101+
return false;
102+
}
103+
104+
const expectedDescription = `${label.description} ${MANAGED_BY_OTA_MARKER}`;
105+
const expectedColor = `#${label.color}`;
106+
107+
return existingLabel.description !== expectedDescription || existingLabel.color !== expectedColor;
108+
});
109+
110+
if (labelsToUpdate.length) {
111+
logger.info(`Updating labels with changed descriptions: ${labelsToUpdate.map(label => `"${label.name}"`).join(', ')}`);
112+
113+
for (const label of labelsToUpdate) {
114+
await this.updateLabel({ /* eslint-disable-line no-await-in-loop */
115+
name: label.name,
116+
color: `#${label.color}`,
117+
description: `${label.description} ${MANAGED_BY_OTA_MARKER}`,
118+
});
119+
}
120+
}
74121
} catch (error) {
75122
logger.error(`Failed to handle repository labels: ${error.message}`);
76123
}
@@ -155,6 +202,40 @@ export default class GitLab {
155202
}
156203
}
157204

205+
async updateLabel({ name, color, description }) {
206+
try {
207+
const label = {
208+
name,
209+
color,
210+
description,
211+
};
212+
213+
const options = GitLab.baseOptionsHttpReq();
214+
215+
options.method = 'PUT';
216+
options.body = JSON.stringify(label);
217+
options.headers = {
218+
'Content-Type': 'application/json',
219+
...options.headers,
220+
};
221+
222+
const response = await nodeFetch(
223+
`${this.apiBaseURL}/projects/${this.projectId}/labels/${encodeURIComponent(name)}`,
224+
options,
225+
);
226+
227+
const res = await response.json();
228+
229+
if (response.ok) {
230+
logger.info(`Label updated: ${res.name}, color: ${res.color}`);
231+
} else {
232+
logger.error(`updateLabel response: ${JSON.stringify(res)}`);
233+
}
234+
} catch (error) {
235+
logger.error(`Failed to update label: ${error}`);
236+
}
237+
}
238+
158239
async createIssue({ title, description, labels }) {
159240
try {
160241
const issue = {

0 commit comments

Comments
 (0)