mirror of
https://github.com/community-scripts/ProxmoxVE.git
synced 2025-03-08 13:19:05 +00:00
[gh]: Improve Workflows, Templates, Handling (#2214)
* Remove Game-Relevant in RequestScript * Update pull_request_template.md * Update pull_request_template.md * Update changelog-pr.yml * Update autolabeler.yml * Update autolabeler.yml * Update changelog-pr.yml * Update changelog-pr.yml
This commit is contained in:
parent
35547c4316
commit
7105f67145
@ -30,8 +30,6 @@ body:
|
|||||||
required: true
|
required: true
|
||||||
- label: "I have searched existing [discussions](https://github.com/community-scripts/ProxmoxVE/discussions?discussions_q=) and found no duplicate requests."
|
- label: "I have searched existing [discussions](https://github.com/community-scripts/ProxmoxVE/discussions?discussions_q=) and found no duplicate requests."
|
||||||
required: true
|
required: true
|
||||||
- label: "This is not a game-related request."
|
|
||||||
required: true
|
|
||||||
- type: markdown
|
- type: markdown
|
||||||
attributes:
|
attributes:
|
||||||
value: "Thanks for submitting your request! The team will review it and reach out if we need more information."
|
value: "Thanks for submitting your request! The team will review it and reach out if we need more information."
|
||||||
|
38
.github/pull_request_template.md
vendored
38
.github/pull_request_template.md
vendored
@ -1,28 +1,28 @@
|
|||||||
## ✍️ Description
|
## ✍️ Description
|
||||||
|
<!-- Provide a clear and concise description of your changes. -->
|
||||||
|
|
||||||
|
--
|
||||||
|
|
||||||
|
## 🔗 Related PR / Discussion / Issue
|
||||||
|
Link: #
|
||||||
|
|
||||||
- - -
|
--
|
||||||
- Related Issue: #
|
|
||||||
- Related PR: #
|
|
||||||
- Related Discussion: #
|
|
||||||
- - -
|
|
||||||
|
|
||||||
|
## ✅ Prerequisites
|
||||||
|
Before this PR can be reviewed, the following must be completed:
|
||||||
|
- [] **Self-review performed** – Code follows established patterns and conventions.
|
||||||
|
- [] **Testing performed** – Changes have been thoroughly tested and verified.
|
||||||
|
|
||||||
## ✅ Prerequisites
|
--
|
||||||
The following steps must be completed for the pull request to be considered:
|
|
||||||
- [] Self-review performed (I have reviewed my code to ensure it follows established patterns and conventions.)
|
|
||||||
- [] Testing performed (I have thoroughly tested my changes and verified expected functionality.)
|
|
||||||
|
|
||||||
## 🛠️ Type of Change
|
## 🛠️ Type of Change
|
||||||
Please check the relevant options:
|
Select all that apply:
|
||||||
- [] Bug fix (non-breaking change that resolves an issue)
|
- [] 🐞 **Bug fix** – Resolves an issue without breaking functionality.
|
||||||
- [] New feature (non-breaking change that adds functionality)
|
- [] ✨ **New feature** – Adds new, non-breaking functionality.
|
||||||
- [] Breaking change (fix or feature that would cause existing functionality to change unexpectedly)
|
- [] 💥 **Breaking change** – Alters existing functionality in a way that may require updates.
|
||||||
- [] New script (a fully functional and thoroughly tested script or set of scripts)
|
- [] 🆕 **New script** – A fully functional and tested script or script set.
|
||||||
|
|
||||||
---
|
---
|
||||||
## 📋 Additional Information (optional)
|
|
||||||
Provide any extra context or screenshots about the feature or fix here.
|
|
||||||
|
|
||||||
|
## 📋 Additional Information (optional)
|
||||||
|
<!-- Provide extra context, screenshots, or references if needed. -->
|
||||||
|
71
.github/workflows/autolabeler.yml
vendored
71
.github/workflows/autolabeler.yml
vendored
@ -13,50 +13,57 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
CONFIG_PATH: .github/autolabeler-config.json
|
CONFIG_PATH: .github/autolabeler-config.json
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Install minimatch
|
|
||||||
run: npm install minimatch
|
|
||||||
|
|
||||||
- name: Label PR based on config rules
|
- name: Label PR based on config rules
|
||||||
uses: actions/github-script@v7
|
uses: actions/github-script@v7
|
||||||
with:
|
with:
|
||||||
script: |
|
script: |
|
||||||
const fs = require('fs').promises;
|
const fs = require('fs').promises;
|
||||||
const path = require('path');
|
|
||||||
const { minimatch } = require('minimatch');
|
const { minimatch } = require('minimatch');
|
||||||
|
|
||||||
const configPath = path.resolve(process.env.CONFIG_PATH);
|
const configPath = process.env.CONFIG_PATH;
|
||||||
const fileContent = await fs.readFile(configPath, 'utf-8');
|
let config;
|
||||||
const autolabelerConfig = JSON.parse(fileContent);
|
try {
|
||||||
|
const fileContent = await fs.readFile(configPath, 'utf-8');
|
||||||
|
config = JSON.parse(fileContent);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`❌ Issue while load config file: ${error.message}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const prNumber = context.payload.pull_request.number;
|
const prNumber = context.payload.pull_request.number;
|
||||||
const prListFilesResponse = await github.rest.pulls.listFiles({
|
const prFiles = (await github.rest.pulls.listFiles({
|
||||||
owner: context.repo.owner,
|
owner: context.repo.owner,
|
||||||
repo: context.repo.repo,
|
repo: context.repo.repo,
|
||||||
pull_number: prNumber,
|
pull_number: prNumber,
|
||||||
});
|
})).data;
|
||||||
const prFiles = prListFilesResponse.data;
|
|
||||||
|
|
||||||
for (const [label, rules] of Object.entries(autolabelerConfig)) {
|
let labelsToAdd = new Set();
|
||||||
const shouldAddLabel = prFiles.some((prFile) => {
|
|
||||||
return rules.some((rule) => {
|
|
||||||
const isFileStatusMatch = rule.fileStatus ? rule.fileStatus === prFile.status : true;
|
|
||||||
const isIncludeGlobMatch = rule.includeGlobs.some((glob) => minimatch(prFile.filename, glob));
|
|
||||||
const isExcludeGlobMatch = rule.excludeGlobs.some((glob) => minimatch(prFile.filename, glob));
|
|
||||||
|
|
||||||
return isFileStatusMatch && isIncludeGlobMatch && !isExcludeGlobMatch;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
if (shouldAddLabel) {
|
for (const [label, rules] of Object.entries(config)) {
|
||||||
console.log(`Adding label ${label} to PR ${prNumber}`);
|
if (prFiles.some(prFile =>
|
||||||
await github.rest.issues.addLabels({
|
rules.some(rule =>
|
||||||
owner: context.repo.owner,
|
(!rule.fileStatus || rule.fileStatus === prFile.status) &&
|
||||||
repo: context.repo.repo,
|
rule.includeGlobs.some(glob => minimatch(prFile.filename, glob)) &&
|
||||||
issue_number: prNumber,
|
!rule.excludeGlobs.some(glob => minimatch(prFile.filename, glob))
|
||||||
labels: [label],
|
)
|
||||||
});
|
)) {
|
||||||
|
labelsToAdd.add(label);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const existingLabels = new Set((await github.rest.issues.listLabelsOnIssue({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
issue_number: prNumber,
|
||||||
|
})).data.map(l => l.name));
|
||||||
|
|
||||||
|
labelsToAdd = [...labelsToAdd].filter(label => !existingLabels.has(label));
|
||||||
|
|
||||||
|
if (labelsToAdd.length > 0) {
|
||||||
|
await github.rest.issues.addLabels({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
issue_number: prNumber,
|
||||||
|
labels: labelsToAdd,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
62
.github/workflows/changelog-pr.yml
vendored
62
.github/workflows/changelog-pr.yml
vendored
@ -6,7 +6,7 @@ on:
|
|||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
update-changelog-pull-request:
|
update-changelog:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
env:
|
env:
|
||||||
CONFIG_PATH: .github/changelog-pr-config.json
|
CONFIG_PATH: .github/changelog-pr-config.json
|
||||||
@ -28,21 +28,12 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Get latest dates in changelog
|
- name: Get latest date in changelog
|
||||||
run: |
|
run: |
|
||||||
# Extract the latest and second latest dates from changelog
|
LATEST_DATE=$(grep '^## [0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}' CHANGELOG.md | head -n 1 | awk '{print $2}')
|
||||||
DATES=$(grep '^## [0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}' CHANGELOG.md | head -n 2 | awk '{print $2}')
|
|
||||||
|
|
||||||
LATEST_DATE=$(echo "$DATES" | sed -n '1p')
|
|
||||||
SECOND_LATEST_DATE=$(echo "$DATES" | sed -n '2p')
|
|
||||||
TODAY=$(date -u +%Y-%m-%d)
|
TODAY=$(date -u +%Y-%m-%d)
|
||||||
|
echo "LATEST_DATE=$LATEST_DATE" >> $GITHUB_ENV
|
||||||
echo "TODAY=$TODAY" >> $GITHUB_ENV
|
echo "TODAY=$TODAY" >> $GITHUB_ENV
|
||||||
if [ "$LATEST_DATE" == "$TODAY" ]; then
|
|
||||||
echo "LATEST_DATE=$SECOND_LATEST_DATE" >> $GITHUB_ENV
|
|
||||||
else
|
|
||||||
echo "LATEST_DATE=$LATEST_DATE" >> $GITHUB_ENV
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: Get categorized pull requests
|
- name: Get categorized pull requests
|
||||||
id: get-categorized-prs
|
id: get-categorized-prs
|
||||||
@ -57,8 +48,8 @@ jobs:
|
|||||||
const changelogConfig = JSON.parse(fileContent);
|
const changelogConfig = JSON.parse(fileContent);
|
||||||
const categorizedPRs = changelogConfig.map((obj) => ({ ...obj, notes: [] }));
|
const categorizedPRs = changelogConfig.map((obj) => ({ ...obj, notes: [] }));
|
||||||
|
|
||||||
const latestDateInChangelog = new Date(process.env.LATEST_DATE);
|
const latestDate = new Date(process.env.LATEST_DATE);
|
||||||
latestDateInChangelog.setUTCHours(23,59,59,999);
|
latestDate.setUTCHours(23,59,59,999);
|
||||||
|
|
||||||
const { data: pulls } = await github.rest.pulls.list({
|
const { data: pulls } = await github.rest.pulls.list({
|
||||||
owner: context.repo.owner,
|
owner: context.repo.owner,
|
||||||
@ -70,18 +61,16 @@ 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) > latestDate &&
|
||||||
!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}))`;
|
||||||
|
|
||||||
for (const { labels, notes } of categorizedPRs) {
|
for (const { labels, notes } of categorizedPRs) {
|
||||||
const prHasCategoryLabel = labels.some((label) => prLabels.includes(label));
|
if (labels.length === 0 || labels.some(label => prLabels.includes(label))) {
|
||||||
const isUnlabelledCategory = labels.length === 0;
|
|
||||||
if (prHasCategoryLabel || isUnlabelledCategory) {
|
|
||||||
notes.push(prNote);
|
notes.push(prNote);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -98,11 +87,11 @@ jobs:
|
|||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
|
||||||
const today = process.env.TODAY;
|
const today = process.env.TODAY;
|
||||||
const latestDateInChangelog = process.env.LATEST_DATE;
|
const latestDate = process.env.LATEST_DATE;
|
||||||
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### Changed\n\n`;
|
let newReleaseNotes = `## ${today}\n\n`;
|
||||||
for (const { title, notes } of categorizedPRs) {
|
for (const { title, notes } of categorizedPRs) {
|
||||||
if (notes.length > 0) {
|
if (notes.length > 0) {
|
||||||
newReleaseNotes += `### ${title}\n\n${notes.join("\n")}\n\n`;
|
newReleaseNotes += `### ${title}\n\n${notes.join("\n")}\n\n`;
|
||||||
@ -112,21 +101,20 @@ jobs:
|
|||||||
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}`);
|
||||||
|
|
||||||
// Replace todays release notes or insert release notes above previous release notes
|
|
||||||
const regex = changelogIncludesTodaysReleaseNotes ?
|
const regex = changelogIncludesTodaysReleaseNotes ?
|
||||||
new RegExp(`## ${today}.*(?=## ${latestDateInChangelog})`, "gs") :
|
new RegExp(`## ${today}.*(?=## ${latestDate})`, "gs") :
|
||||||
new RegExp(`(?=## ${latestDateInChangelog})`, "gs");
|
new RegExp(`(?=## ${latestDate})`, "gs");
|
||||||
|
|
||||||
const newChangelogContent = changelogContent.replace(regex, newReleaseNotes)
|
const newChangelogContent = changelogContent.replace(regex, newReleaseNotes);
|
||||||
await fs.writeFile(changelogPath, newChangelogContent);
|
await fs.writeFile(changelogPath, newChangelogContent);
|
||||||
|
|
||||||
- name: Check if there are any changes
|
- name: Check for changes
|
||||||
id: verify-diff
|
id: verify-diff
|
||||||
run: |
|
run: |
|
||||||
git diff --quiet . || echo "changed=true" >> $GITHUB_OUTPUT
|
git diff --quiet . || echo "changed=true" >> $GITHUB_ENV
|
||||||
|
|
||||||
- name: Commit and push changes to separate branch
|
- name: Commit and push changes
|
||||||
if: steps.verify-diff.outputs.changed == 'true'
|
if: env.changed == 'true'
|
||||||
run: |
|
run: |
|
||||||
git config --global user.name "github-actions[bot]"
|
git config --global user.name "github-actions[bot]"
|
||||||
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
||||||
@ -136,7 +124,7 @@ jobs:
|
|||||||
git push origin $BRANCH_NAME --force
|
git push origin $BRANCH_NAME --force
|
||||||
|
|
||||||
- name: Create pull request if not exists
|
- name: Create pull request if not exists
|
||||||
if: steps.verify-diff.outputs.changed == 'true'
|
if: env.changed == 'true'
|
||||||
env:
|
env:
|
||||||
GH_TOKEN: ${{ steps.generate-token.outputs.token }}
|
GH_TOKEN: ${{ steps.generate-token.outputs.token }}
|
||||||
run: |
|
run: |
|
||||||
@ -150,7 +138,7 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
- name: Approve pull request
|
- name: Approve pull request
|
||||||
if: steps.verify-diff.outputs.changed == 'true'
|
if: env.changed == 'true'
|
||||||
env:
|
env:
|
||||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
run: |
|
run: |
|
||||||
@ -158,9 +146,9 @@ jobs:
|
|||||||
if [ -n "$PR_NUMBER" ]; then
|
if [ -n "$PR_NUMBER" ]; then
|
||||||
gh pr review $PR_NUMBER --approve
|
gh pr review $PR_NUMBER --approve
|
||||||
fi
|
fi
|
||||||
|
|
||||||
- name: Re-approve pull request after update
|
- name: Re-approve pull request after update
|
||||||
if: steps.verify-diff.outputs.changed == 'true'
|
if: env.changed == 'true'
|
||||||
env:
|
env:
|
||||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
run: |
|
run: |
|
||||||
|
Loading…
x
Reference in New Issue
Block a user