diff --git a/.github/DISCUSSION_TEMPLATE/request-script.yml b/.github/DISCUSSION_TEMPLATE/request-script.yml index aac84df60..44ed9b147 100644 --- a/.github/DISCUSSION_TEMPLATE/request-script.yml +++ b/.github/DISCUSSION_TEMPLATE/request-script.yml @@ -30,8 +30,6 @@ body: required: true - label: "I have searched existing [discussions](https://github.com/community-scripts/ProxmoxVE/discussions?discussions_q=) and found no duplicate requests." required: true - - label: "This is not a game-related request." - required: true - type: markdown attributes: value: "Thanks for submitting your request! The team will review it and reach out if we need more information." diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 7613cf4eb..a08e1a6c8 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,28 +1,28 @@ -## ✍️ Description +## ✍️ Description + +-- - +## 🔗 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 -Please check the relevant options: -- [] Bug fix (non-breaking change that resolves an issue) -- [] New feature (non-breaking change that adds functionality) -- [] Breaking change (fix or feature that would cause existing functionality to change unexpectedly) -- [] New script (a fully functional and thoroughly tested script or set of scripts) +## 🛠️ Type of Change +Select all that apply: +- [] 🐞 **Bug fix** – Resolves an issue without breaking functionality. +- [] ✨ **New feature** – Adds new, non-breaking functionality. +- [] 💥 **Breaking change** – Alters existing functionality in a way that may require updates. +- [] 🆕 **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) + diff --git a/.github/workflows/autolabeler.yml b/.github/workflows/autolabeler.yml index 660135f5c..2f66f3417 100644 --- a/.github/workflows/autolabeler.yml +++ b/.github/workflows/autolabeler.yml @@ -13,50 +13,57 @@ jobs: env: CONFIG_PATH: .github/autolabeler-config.json steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Install minimatch - run: npm install minimatch - - name: Label PR based on config rules uses: actions/github-script@v7 with: script: | const fs = require('fs').promises; - const path = require('path'); const { minimatch } = require('minimatch'); - const configPath = path.resolve(process.env.CONFIG_PATH); - const fileContent = await fs.readFile(configPath, 'utf-8'); - const autolabelerConfig = JSON.parse(fileContent); - + const configPath = process.env.CONFIG_PATH; + let config; + 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 prListFilesResponse = await github.rest.pulls.listFiles({ + const prFiles = (await github.rest.pulls.listFiles({ owner: context.repo.owner, repo: context.repo.repo, pull_number: prNumber, - }); - const prFiles = prListFilesResponse.data; + })).data; - for (const [label, rules] of Object.entries(autolabelerConfig)) { - 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; - }); - }); + let labelsToAdd = new Set(); - if (shouldAddLabel) { - console.log(`Adding label ${label} to PR ${prNumber}`); - await github.rest.issues.addLabels({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: prNumber, - labels: [label], - }); + for (const [label, rules] of Object.entries(config)) { + if (prFiles.some(prFile => + rules.some(rule => + (!rule.fileStatus || rule.fileStatus === prFile.status) && + rule.includeGlobs.some(glob => minimatch(prFile.filename, glob)) && + !rule.excludeGlobs.some(glob => minimatch(prFile.filename, glob)) + ) + )) { + 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, + }); + } diff --git a/.github/workflows/changelog-pr.yml b/.github/workflows/changelog-pr.yml index 48cf49972..5637f5c4f 100644 --- a/.github/workflows/changelog-pr.yml +++ b/.github/workflows/changelog-pr.yml @@ -6,7 +6,7 @@ on: workflow_dispatch: jobs: - update-changelog-pull-request: + update-changelog: runs-on: ubuntu-latest env: CONFIG_PATH: .github/changelog-pr-config.json @@ -28,21 +28,12 @@ jobs: with: fetch-depth: 0 - - name: Get latest dates in changelog + - name: Get latest date in changelog run: | - # Extract the latest and second latest dates from changelog - 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') + LATEST_DATE=$(grep '^## [0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}' CHANGELOG.md | head -n 1 | awk '{print $2}') TODAY=$(date -u +%Y-%m-%d) - + echo "LATEST_DATE=$LATEST_DATE" >> $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 id: get-categorized-prs @@ -57,8 +48,8 @@ jobs: const changelogConfig = JSON.parse(fileContent); const categorizedPRs = changelogConfig.map((obj) => ({ ...obj, notes: [] })); - const latestDateInChangelog = new Date(process.env.LATEST_DATE); - latestDateInChangelog.setUTCHours(23,59,59,999); + const latestDate = new Date(process.env.LATEST_DATE); + latestDate.setUTCHours(23,59,59,999); const { data: pulls } = await github.rest.pulls.list({ owner: context.repo.owner, @@ -70,18 +61,16 @@ jobs: per_page: 100, }); - pulls.filter((pr) => + pulls.filter(pr => pr.merged_at && - new Date(pr.merged_at) > latestDateInChangelog && - !pr.labels.some((label) => ["invalid", "wontdo", process.env.AUTOMATED_PR_LABEL].includes(label.name.toLowerCase())) - ).forEach((pr) => { - const prLabels = pr.labels.map((label) => label.name.toLowerCase()); + new Date(pr.merged_at) > latestDate && + !pr.labels.some(label => ["invalid", "wontdo", process.env.AUTOMATED_PR_LABEL].includes(label.name.toLowerCase())) + ).forEach(pr => { + 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}))`; for (const { labels, notes } of categorizedPRs) { - const prHasCategoryLabel = labels.some((label) => prLabels.includes(label)); - const isUnlabelledCategory = labels.length === 0; - if (prHasCategoryLabel || isUnlabelledCategory) { + if (labels.length === 0 || labels.some(label => prLabels.includes(label))) { notes.push(prNote); break; } @@ -98,11 +87,11 @@ jobs: const path = require('path'); const today = process.env.TODAY; - const latestDateInChangelog = process.env.LATEST_DATE; + const latestDate = process.env.LATEST_DATE; const changelogPath = path.resolve('CHANGELOG.md'); 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) { if (notes.length > 0) { newReleaseNotes += `### ${title}\n\n${notes.join("\n")}\n\n`; @@ -112,21 +101,20 @@ jobs: const changelogContent = await fs.readFile(changelogPath, 'utf-8'); const changelogIncludesTodaysReleaseNotes = changelogContent.includes(`\n## ${today}`); - // Replace todays release notes or insert release notes above previous release notes const regex = changelogIncludesTodaysReleaseNotes ? - new RegExp(`## ${today}.*(?=## ${latestDateInChangelog})`, "gs") : - new RegExp(`(?=## ${latestDateInChangelog})`, "gs"); + new RegExp(`## ${today}.*(?=## ${latestDate})`, "gs") : + new RegExp(`(?=## ${latestDate})`, "gs"); - const newChangelogContent = changelogContent.replace(regex, newReleaseNotes) + const newChangelogContent = changelogContent.replace(regex, newReleaseNotes); await fs.writeFile(changelogPath, newChangelogContent); - - name: Check if there are any changes + - name: Check for changes id: verify-diff 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 - if: steps.verify-diff.outputs.changed == 'true' + - name: Commit and push changes + if: env.changed == 'true' run: | git config --global user.name "github-actions[bot]" git config --global user.email "github-actions[bot]@users.noreply.github.com" @@ -136,7 +124,7 @@ jobs: git push origin $BRANCH_NAME --force - name: Create pull request if not exists - if: steps.verify-diff.outputs.changed == 'true' + if: env.changed == 'true' env: GH_TOKEN: ${{ steps.generate-token.outputs.token }} run: | @@ -150,7 +138,7 @@ jobs: fi - name: Approve pull request - if: steps.verify-diff.outputs.changed == 'true' + if: env.changed == 'true' env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | @@ -158,9 +146,9 @@ jobs: if [ -n "$PR_NUMBER" ]; then gh pr review $PR_NUMBER --approve fi - + - name: Re-approve pull request after update - if: steps.verify-diff.outputs.changed == 'true' + if: env.changed == 'true' env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: |