[gh] Update Changelog Workflow (#2621)

* Update Workflow

* Update Workflow
This commit is contained in:
Michel Roegl-Brunner 2025-02-25 09:55:17 +02:00 committed by GitHub
parent bef3ccd164
commit 893bff1b59
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 100 additions and 32 deletions

View File

@ -68,4 +68,5 @@
"excludeGlobs": [] "excludeGlobs": []
} }
] ]
} }

View File

@ -7,14 +7,26 @@
"title": "🆕 New Scripts", "title": "🆕 New Scripts",
"labels": ["new script"] "labels": ["new script"]
}, },
{
"title": "🐞 Bug Fixes",
"labels": ["bugfix"]
},
{ {
"title": "✨ New Features", "title": "✨ New Features",
"labels": ["feature"] "labels": ["feature"]
}, },
{
"title": "🚀 Updated Scripts",
"labels": ["update script"],
"subCategories": [
{
"title": "🐞 Bug Fixes",
"labels": ["bugfix"],
"notes" : []
},
{
"title": "General Updates",
"labels": ["general"],
"notes" : []
}
]
},
{ {
"title": "🌐 Website", "title": "🌐 Website",
"labels": ["website"] "labels": ["website"]

View File

@ -32,8 +32,9 @@ jobs:
const autolabelerConfig = JSON.parse(fileContent); const autolabelerConfig = JSON.parse(fileContent);
const prNumber = context.payload.pull_request.number; const prNumber = context.payload.pull_request.number;
const prBody = context.payload.pull_request.body;
const prBody = context.payload.pull_request.body.toLowerCase();
let labelsToAdd = new Set(); let labelsToAdd = new Set();
const prListFilesResponse = await github.rest.pulls.listFiles({ const prListFilesResponse = await github.rest.pulls.listFiles({
@ -42,14 +43,35 @@ jobs:
pull_number: prNumber, pull_number: prNumber,
}); });
const prFiles = prListFilesResponse.data; const prFiles = prListFilesResponse.data;
const templateLabelMappings = {
"🐞 **bug fix**": "bugfix",
"✨ **new feature**": "feature",
"💥 **breaking change**": "breaking change",
"🆕 **new script**": "new script"
};
for (const [checkbox, label] of Object.entries(templateLabelMappings)) {
const escapedCheckbox = checkbox.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1");
const regex = new RegExp(`- \\[(x|X)\\]\\s*.*${escapedCheckbox}`, "i");
const match = prBody.match(regex);
if (match) {
console.log(`Match: ${match}`);
labelsToAdd.add(label);
}
}
if (labelsToAdd.size === 0) {
labelsToAdd.add("general");
}
// Apply labels based on file changes
for (const [label, rules] of Object.entries(autolabelerConfig)) { for (const [label, rules] of Object.entries(autolabelerConfig)) {
const shouldAddLabel = prFiles.some((prFile) => { const shouldAddLabel = prFiles.some((prFile) => {
return rules.some((rule) => { return rules.some((rule) => {
const isFileStatusMatch = rule.fileStatus ? rule.fileStatus === prFile.status : true; const isFileStatusMatch = rule.fileStatus ? rule.fileStatus === prFile.status : true;
const isIncludeGlobMatch = rule.includeGlobs.some((glob) => minimatch(prFile.filename, glob)); const isIncludeGlobMatch = rule.includeGlobs.some((glob) => minimatch(prFile.filename, glob));
const isExcludeGlobMatch = rule.excludeGlobs.some((glob) => minimatch(prFile.filename, glob)); const isExcludeGlobMatch = rule.excludeGlobs.some((glob) => minimatch(prFile.filename, glob));
return isFileStatusMatch && isIncludeGlobMatch && !isExcludeGlobMatch; return isFileStatusMatch && isIncludeGlobMatch && !isExcludeGlobMatch;
}); });
}); });

View File

@ -30,7 +30,6 @@ jobs:
- name: Get latest dates in changelog - name: Get latest dates in changelog
run: | run: |
# Extrahiere die neuesten zwei Daten aus dem Changelog
DATES=$(grep -E '^## [0-9]{4}-[0-9]{2}-[0-9]{2}' CHANGELOG.md | head -n 2 | awk '{print $2}') DATES=$(grep -E '^## [0-9]{4}-[0-9]{2}-[0-9]{2}' CHANGELOG.md | head -n 2 | awk '{print $2}')
LATEST_DATE=$(echo "$DATES" | sed -n '1p') LATEST_DATE=$(echo "$DATES" | sed -n '1p')
@ -55,7 +54,15 @@ jobs:
const configPath = path.resolve(process.env.CONFIG_PATH); const configPath = path.resolve(process.env.CONFIG_PATH);
const fileContent = await fs.readFile(configPath, 'utf-8'); const fileContent = await fs.readFile(configPath, 'utf-8');
const changelogConfig = JSON.parse(fileContent); const changelogConfig = JSON.parse(fileContent);
const categorizedPRs = changelogConfig.map(obj => ({ ...obj, notes: [] }));
const categorizedPRs = changelogConfig.map(obj => ({
...obj,
notes: [],
subCategories: obj.subCategories ?? (obj.labels.includes("update script") ? [
{ title: "🐞 Bug Fixes", labels: ["bugfix"] },
{ title: "✨ Feature Updates", labels: ["feature"] }
] : [])
}));
const latestDateInChangelog = new Date(process.env.LATEST_DATE); const latestDateInChangelog = new Date(process.env.LATEST_DATE);
latestDateInChangelog.setUTCHours(23, 59, 59, 999); latestDateInChangelog.setUTCHours(23, 59, 59, 999);
@ -70,29 +77,33 @@ jobs:
per_page: 100, per_page: 100,
}); });
pulls.filter(pr => pulls.filter(pr =>
pr.merged_at && pr.merged_at &&
new Date(pr.merged_at) > latestDateInChangelog && new Date(pr.merged_at) > latestDateInChangelog &&
!pr.labels.some(label => ["invalid", "wontdo", process.env.AUTOMATED_PR_LABEL].includes(label.name.toLowerCase())) !pr.labels.some(label =>
["invalid", "wontdo", process.env.AUTOMATED_PR_LABEL].includes(label.name.toLowerCase())
)
).forEach(pr => { ).forEach(pr => {
const prLabels = pr.labels.map(label => label.name.toLowerCase()); const prLabels = pr.labels.map(label => label.name.toLowerCase());
const prNote = `- ${pr.title} [@${pr.user.login}](https://github.com/${pr.user.login}) ([#${pr.number}](${pr.html_url}))`; const prNote = `- ${pr.title} [@${pr.user.login}](https://github.com/${pr.user.login}) ([#${pr.number}](${pr.html_url}))`;
let isCategorized = false;
for (const { labels, notes } of categorizedPRs) { const updateScriptsCategory = categorizedPRs.find(category =>
// If no labels are specified (e.g., "Unlabelled"), assign to this category category.labels.some(label => prLabels.includes(label))
if (labels.length === 0 && prLabels.length === 0) { );
notes.push(prNote);
isCategorized = true; if (updateScriptsCategory) {
break;
} const subCategory = updateScriptsCategory.subCategories.find(sub =>
sub.labels.some(label => prLabels.includes(label))
);
if (subCategory) {
subCategory.notes.push(prNote);
} else {
updateScriptsCategory.notes.push(prNote);
// If labels are specified, check if PR has ALL required labels
if (labels.length > 0 && labels.every(label => prLabels.includes(label.toLowerCase()))) {
notes.push(prNote);
isCategorized = true;
break;
} }
} }
@ -104,9 +115,12 @@ jobs:
} }
} }
}); });
console.log(JSON.stringify(categorizedPRs, null, 2));
return categorizedPRs; return categorizedPRs;
- name: Update CHANGELOG.md - name: Update CHANGELOG.md
uses: actions/github-script@v7 uses: actions/github-script@v7
with: with:
@ -119,13 +133,32 @@ jobs:
const changelogPath = path.resolve('CHANGELOG.md'); const changelogPath = path.resolve('CHANGELOG.md');
const categorizedPRs = ${{ steps.get-categorized-prs.outputs.result }}; const categorizedPRs = ${{ steps.get-categorized-prs.outputs.result }};
let newReleaseNotes = `## ${today}\n\n### Changes\n\n`; console.log(JSON.stringify(categorizedPRs, null, 2));
for (const { title, notes } of categorizedPRs) {
if (notes.length > 0) {
newReleaseNotes += `### ${title}\n\n${notes.join("\n")}\n\n`;
}
}
let newReleaseNotes = `## ${today}\n\n### Changes\n\n`;
for (const { title, notes, subCategories } of categorizedPRs) {
const hasSubcategories = subCategories && subCategories.length > 0;
const hasMainNotes = notes.length > 0;
const hasSubNotes = hasSubcategories && subCategories.some(sub => sub.notes && sub.notes.length > 0);
if (hasMainNotes || hasSubNotes) {
newReleaseNotes += `### ${title}\n\n`;
}
if (hasMainNotes) {
newReleaseNotes += `${notes.join("\n")}\n\n`;
}
if (hasSubcategories) {
for (const { title: subTitle, notes: subNotes } of subCategories) {
if (subNotes && subNotes.length > 0) {
newReleaseNotes += ` #### ${subTitle}\n\n`;
newReleaseNotes += ` ${subNotes.join("\n ")}\n\n`;
}
}
}
}
const changelogContent = await fs.readFile(changelogPath, 'utf-8'); const changelogContent = await fs.readFile(changelogPath, 'utf-8');
const changelogIncludesTodaysReleaseNotes = changelogContent.includes(`\n## ${today}`); const changelogIncludesTodaysReleaseNotes = changelogContent.includes(`\n## ${today}`);