mirror of
https://github.com/community-scripts/ProxmoxVE.git
synced 2025-03-08 13:19:05 +00:00
Updated Changelog Workflow (#2632)
This commit is contained in:
parent
599a518cc3
commit
3401b76c44
21
.github/changelog-pr-config.json
vendored
21
.github/changelog-pr-config.json
vendored
@ -7,14 +7,27 @@
|
|||||||
"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"]
|
||||||
|
37
.github/workflows/autolabeler.yml
vendored
37
.github/workflows/autolabeler.yml
vendored
@ -32,7 +32,7 @@ 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();
|
||||||
|
|
||||||
@ -43,6 +43,27 @@ jobs:
|
|||||||
});
|
});
|
||||||
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) => {
|
||||||
@ -59,20 +80,6 @@ jobs:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 regex = new RegExp(`- \\[x\\] ${checkbox}`, "i"); // Match only checked checkboxes
|
|
||||||
if (regex.test(prBody)) {
|
|
||||||
labelsToAdd.add(label);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(`Labels to add: ${Array.from(labelsToAdd).join(", ")}`);
|
console.log(`Labels to add: ${Array.from(labelsToAdd).join(", ")}`);
|
||||||
|
|
||||||
if (labelsToAdd.size > 0) {
|
if (labelsToAdd.size > 0) {
|
||||||
|
75
.github/workflows/changelog-pr.yml
vendored
75
.github/workflows/changelog-pr.yml
vendored
@ -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);
|
||||||
@ -73,38 +80,34 @@ jobs:
|
|||||||
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;
|
const updateScriptsCategory = categorizedPRs.find(category =>
|
||||||
|
category.labels.some(label => prLabels.includes(label))
|
||||||
|
);
|
||||||
|
|
||||||
for (const { labels, notes } of categorizedPRs) {
|
if (updateScriptsCategory) {
|
||||||
// If no labels are specified (e.g., "Unlabelled"), assign to this category
|
|
||||||
if (labels.length === 0 && prLabels.length === 0) {
|
|
||||||
notes.push(prNote);
|
|
||||||
isCategorized = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If labels are specified, check if PR has ALL required labels
|
const subCategory = updateScriptsCategory.subCategories.find(sub =>
|
||||||
if (labels.length > 0 && labels.every(label => prLabels.includes(label.toLowerCase()))) {
|
sub.labels.some(label => prLabels.includes(label))
|
||||||
notes.push(prNote);
|
);
|
||||||
isCategorized = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If PR is not categorized, assign it to the "Unlabelled" category
|
if (subCategory) {
|
||||||
if (!isCategorized) {
|
subCategory.notes.push(prNote);
|
||||||
const unlabelledCategory = categorizedPRs.find(cat => cat.title === "❔ Unlabelled");
|
} else {
|
||||||
if (unlabelledCategory) {
|
updateScriptsCategory.notes.push(prNote);
|
||||||
unlabelledCategory.notes.push(prNote);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
console.log(JSON.stringify(categorizedPRs, null, 2));
|
||||||
|
|
||||||
return categorizedPRs;
|
return categorizedPRs;
|
||||||
|
|
||||||
- name: Update CHANGELOG.md
|
- name: Update CHANGELOG.md
|
||||||
@ -119,10 +122,30 @@ 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 }};
|
||||||
|
|
||||||
|
console.log(JSON.stringify(categorizedPRs, null, 2));
|
||||||
|
|
||||||
let newReleaseNotes = `## ${today}\n\n### Changes\n\n`;
|
let newReleaseNotes = `## ${today}\n\n### Changes\n\n`;
|
||||||
for (const { title, notes } of categorizedPRs) {
|
for (const { title, notes, subCategories } of categorizedPRs) {
|
||||||
if (notes.length > 0) {
|
const hasSubcategories = subCategories && subCategories.length > 0;
|
||||||
newReleaseNotes += `### ${title}\n\n${notes.join("\n")}\n\n`;
|
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`;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user