From 9b7fbdf7d73a91598480d2f4b9ae4463f8d92cb1 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 25 Aug 2025 14:25:18 +0200 Subject: [PATCH] cleanup --- .../backup/check_and_update_json_date.yml | 60 ---- .github/workflows/backup/shellcheck.yml | 60 ---- .../workflows/backup/update_json_date.yml.bak | 90 ------ .../backup/validate-formatting.yaml.bak | 133 -------- .../workflows/backup/validate-scripts.yml.bak | 234 -------------- .github/workflows/changelog-pr.yaml | 286 ------------------ .github/workflows/close-discussion.yaml | 164 ---------- .github/workflows/close-ttek-issue.yaml | 53 ---- .github/workflows/live/changelog-pr.yml | 228 -------------- .github/workflows/live/close-discussion.yml | 122 -------- .../live/create-docker-for-runner.yml | 37 --- .github/workflows/live/delete-json-branch.yml | 28 -- .github/workflows/live/github-release.yml | 57 ---- .github/workflows/live/script-test.yml | 177 ----------- .github/workflows/live/script_format.yml | 243 --------------- .github/workflows/live/update-json-date.yml | 133 -------- .github/workflows/live/validate-filenames.yml | 161 ---------- 17 files changed, 2266 deletions(-) delete mode 100644 .github/workflows/backup/check_and_update_json_date.yml delete mode 100644 .github/workflows/backup/shellcheck.yml delete mode 100644 .github/workflows/backup/update_json_date.yml.bak delete mode 100644 .github/workflows/backup/validate-formatting.yaml.bak delete mode 100644 .github/workflows/backup/validate-scripts.yml.bak delete mode 100644 .github/workflows/changelog-pr.yaml delete mode 100644 .github/workflows/close-discussion.yaml delete mode 100644 .github/workflows/close-ttek-issue.yaml delete mode 100644 .github/workflows/live/changelog-pr.yml delete mode 100644 .github/workflows/live/close-discussion.yml delete mode 100644 .github/workflows/live/create-docker-for-runner.yml delete mode 100644 .github/workflows/live/delete-json-branch.yml delete mode 100644 .github/workflows/live/github-release.yml delete mode 100644 .github/workflows/live/script-test.yml delete mode 100644 .github/workflows/live/script_format.yml delete mode 100644 .github/workflows/live/update-json-date.yml delete mode 100644 .github/workflows/live/validate-filenames.yml diff --git a/.github/workflows/backup/check_and_update_json_date.yml b/.github/workflows/backup/check_and_update_json_date.yml deleted file mode 100644 index cde3cbba..00000000 --- a/.github/workflows/backup/check_and_update_json_date.yml +++ /dev/null @@ -1,60 +0,0 @@ -name: Update date_created in JSON files - -on: - # Dieser Trigger wird für das Öffnen von PRs sowie für das Aktualisieren von offenen PRs verwendet - pull_request: - types: [opened, synchronize] - schedule: - # Dieser Trigger wird 4x am Tag ausgelöst, um sicherzustellen, dass das Datum aktualisiert wird - - cron: "0 0,6,12,18 * * *" # Führt alle 6 Stunden aus - workflow_dispatch: # Manuelle Ausführung des Workflows möglich - -jobs: - update-date: - runs-on: ubuntu-latest - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Install yq - run: | - sudo apt-get update - sudo apt-get install -y yq - - - name: Set the current date - id: set_date - run: echo "TODAY=$(date -u +%Y-%m-%d)" >> $GITHUB_ENV - - - name: Check for changes in PR - run: | - # Hole den PR-Branch - PR_BRANCH="refs/pull/${{ github.event.pull_request.number }}/merge" - git fetch origin $PR_BRANCH - - # Liste alle JSON-Dateien im PR auf, die geändert wurden - CHANGED_JSON_FILES=$(git diff --name-only origin/main...$PR_BRANCH | grep '.json') - - if [ -z "$CHANGED_JSON_FILES" ]; then - echo "No JSON files changed in this PR." - exit 0 - fi - - # Gehe alle geänderten JSON-Dateien durch und aktualisiere das Datum - for file in $CHANGED_JSON_FILES; do - echo "Updating date_created in $file" - # Setze das aktuelle Datum - yq eval ".date_created = \"${{ env.TODAY }}\"" -i "$file" - git add "$file" - done - - - name: Commit and push changes - run: | - # Prüfe, ob es Änderungen gibt und committe sie - git config user.name "json-updater-bot" - git config user.email "github-actions[bot]@users.noreply.github.com" - - git commit -m "Update date_created to ${{ env.TODAY }}" || echo "No changes to commit" - - # Push zurück in den PR-Branch - git push origin $PR_BRANCH diff --git a/.github/workflows/backup/shellcheck.yml b/.github/workflows/backup/shellcheck.yml deleted file mode 100644 index 4385fc8e..00000000 --- a/.github/workflows/backup/shellcheck.yml +++ /dev/null @@ -1,60 +0,0 @@ -name: Shellcheck - -on: - push: - branches: - - main - pull_request: - workflow_dispatch: - schedule: - - cron: "5 1 * * *" - -jobs: - shellcheck: - name: Shellcheck - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - - - name: Get changed files - id: changed-files - uses: tj-actions/changed-files@v45 - with: - files: | - **.sh - - - name: Download ShellCheck - shell: bash - env: - INPUT_VERSION: "v0.10.0" - run: | - set -euo pipefail - if [[ "${{ runner.os }}" == "macOS" ]]; then - osvariant="darwin" - else - osvariant="linux" - fi - - baseurl="https://github.com/koalaman/shellcheck/releases/download" - curl -Lso "${{ github.workspace }}/sc.tar.xz" \ - "${baseurl}/${INPUT_VERSION}/shellcheck-${INPUT_VERSION}.${osvariant}.x86_64.tar.xz" - - tar -xf "${{ github.workspace }}/sc.tar.xz" -C "${{ github.workspace }}" - mv "${{ github.workspace }}/shellcheck-${INPUT_VERSION}/shellcheck" \ - "${{ github.workspace }}/shellcheck" - - - name: Verify ShellCheck binary - run: | - ls -l "${{ github.workspace }}/shellcheck" - - - name: Display ShellCheck version - run: | - "${{ github.workspace }}/shellcheck" --version - - - name: Run ShellCheck - if: steps.changed-files.outputs.any_changed == 'true' - env: - ALL_CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }} - run: | - echo "${ALL_CHANGED_FILES}" | xargs "${{ github.workspace }}/shellcheck" diff --git a/.github/workflows/backup/update_json_date.yml.bak b/.github/workflows/backup/update_json_date.yml.bak deleted file mode 100644 index 71012528..00000000 --- a/.github/workflows/backup/update_json_date.yml.bak +++ /dev/null @@ -1,90 +0,0 @@ -name: Auto Update JSON-Date - -on: - push: - branches: - - main - workflow_dispatch: - -jobs: - update-json-dates: - runs-on: ubuntu-latest - - permissions: - contents: write - pull-requests: write - - steps: - - name: Generate a token - id: generate-token - uses: actions/create-github-app-token@v2 - with: - app-id: ${{ vars.APP_ID }} - private-key: ${{ secrets.APP_PRIVATE_KEY }} - owner: community-scripts - repositories: ProxmoxVED - - - name: Checkout repository - uses: actions/checkout@v4 - with: - fetch-depth: 0 # Full history for proper detection - - - name: Set up Git - run: | - git config --global user.name "GitHub Actions" - git config --global user.email "github-actions[bot]@users.noreply.github.com" - - - name: Find JSON files with incorrect date_created - id: find_wrong_json - run: | - TODAY=$(date -u +"%Y-%m-%d") - > incorrect_json_files.txt - - for FILE in json/*.json; do - if [[ -f "$FILE" ]]; then - DATE_IN_JSON=$(jq -r '.date_created' "$FILE" 2>/dev/null || echo "") - - if [[ "$DATE_IN_JSON" != "$TODAY" ]]; then - echo "$FILE" >> incorrect_json_files.txt - fi - fi - done - - if [[ -s incorrect_json_files.txt ]]; then - echo "CHANGED=true" >> $GITHUB_ENV - else - echo "CHANGED=false" >> $GITHUB_ENV - fi - - - name: Run update script - if: env.CHANGED == 'true' - run: | - chmod +x .github/workflows/scripts/update-json.sh - while read -r FILE; do - .github/workflows/scripts/update-json.sh "$FILE" - done < incorrect_json_files.txt - - - name: Commit and create PR if changes exist - if: env.CHANGED == 'true' - run: | - git add json/*.json - git commit -m "Auto-update date_created in incorrect JSON files" - git checkout -b pr-fix-json-dates - git push origin pr-fix-json-dates --force - gh pr create --title "[core] Fix incorrect JSON date_created fields" \ - --body "This PR is auto-generated to fix incorrect `date_created` fields in JSON files." \ - --head pr-fix-json-dates \ - --base main \ - --label "automated pr" - env: - GH_TOKEN: ${{ steps.generate-token.outputs.token }} - - - name: Approve pull request - if: env.CHANGED == 'true' - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - PR_NUMBER=$(gh pr list --head "pr-fix-json-dates" --json number --jq '.[].number') - if [ -n "$PR_NUMBER" ]; then - gh pr review $PR_NUMBER --approve - fi diff --git a/.github/workflows/backup/validate-formatting.yaml.bak b/.github/workflows/backup/validate-formatting.yaml.bak deleted file mode 100644 index 8eadd0ac..00000000 --- a/.github/workflows/backup/validate-formatting.yaml.bak +++ /dev/null @@ -1,133 +0,0 @@ -name: Validate script formatting - -on: - push: - branches: - - main - pull_request_target: - paths: - - "**/*.sh" - - "**/*.func" - -jobs: - shfmt: - name: Check changed files - runs-on: ubuntu-latest - permissions: - - pull-requests: write - - steps: - - name: Get pull request information - if: github.event_name == 'pull_request_target' - uses: actions/github-script@v7 - id: pr - with: - script: | - const { data: pullRequest } = await github.rest.pulls.get({ - ...context.repo, - pull_number: context.payload.pull_request.number, - }); - return pullRequest; - - - name: Checkout code - uses: actions/checkout@v4 - with: - fetch-depth: 0 # Ensure the full history is fetched for accurate diffing - ref: ${{ github.event_name == 'pull_request_target' && fromJSON(steps.pr.outputs.result).merge_commit_sha || '' }} - - - name: Get changed files - id: changed-files - run: | - if ${{ github.event_name == 'pull_request_target' }}; then - echo "files=$(git diff --name-only ${{ github.event.pull_request.base.sha }} ${{ steps.pr.outputs.result && fromJSON(steps.pr.outputs.result).merge_commit_sha }} | grep -E '\.(sh|func)$' | xargs)" >> $GITHUB_OUTPUT - else - echo "files=$(git diff --name-only ${{ github.event.before }} ${{ github.event.after }} | grep -E '\.(sh|func)$' | xargs)" >> $GITHUB_OUTPUT - fi - - - name: Set up Go - if: steps.changed-files.outputs.files != '' - uses: actions/setup-go@v5 - - - name: Install shfmt - if: steps.changed-files.outputs.files != '' - run: | - go install mvdan.cc/sh/v3/cmd/shfmt@latest - echo "$GOPATH/bin" >> $GITHUB_PATH - - - name: Run shfmt - if: steps.changed-files.outputs.files != '' - id: shfmt - run: | - set +e - - - shfmt_output=$(shfmt -d ${{ steps.changed-files.outputs.files }}) - if [[ $? -eq 0 ]]; then - exit 0 - else - echo "diff=\"$(echo -n "$shfmt_output" | base64 -w 0)\"" >> $GITHUB_OUTPUT - printf "%s" "$shfmt_output" - exit 1 - fi - - - name: Post comment with results - if: always() && steps.changed-files.outputs.files != '' && github.event_name == 'pull_request_target' - uses: actions/github-script@v7 - with: - script: | - const result = "${{ job.status }}" === "success" ? "success" : "failure"; - const diff = Buffer.from( - ${{ steps.shfmt.outputs.diff }}, - "base64", - ).toString(); - const issueNumber = context.payload.pull_request - ? context.payload.pull_request.number - : null; - const commentIdentifier = "validate-formatting"; - let newCommentBody = `\n### Script formatting\n\n`; - - if (result === "failure") { - newCommentBody += - `:x: We found issues in the formatting of the following changed files:\n\n\`\`\`diff\n${diff}\n\`\`\`\n`; - } else { - newCommentBody += `:rocket: All changed shell scripts are formatted correctly!\n`; - } - - newCommentBody += `\n\n`; - - if (issueNumber) { - const { data: comments } = await github.rest.issues.listComments({ - ...context.repo, - issue_number: issueNumber, - }); - - const existingComment = comments.find( - (comment) => comment.user.login === "github-actions[bot]", - - ); - - if (existingComment) { - if (existingComment.body.includes(commentIdentifier)) { - const re = new RegExp( - String.raw`[\s\S]*?`, - "", - ); - newCommentBody = existingComment.body.replace(re, newCommentBody); - } else { - newCommentBody = existingComment.body + "\n\n---\n\n" + newCommentBody; - } - - await github.rest.issues.updateComment({ - ...context.repo, - comment_id: existingComment.id, - body: newCommentBody, - }); - } else { - await github.rest.issues.createComment({ - ...context.repo, - issue_number: issueNumber, - body: newCommentBody, - }); - } - } diff --git a/.github/workflows/backup/validate-scripts.yml.bak b/.github/workflows/backup/validate-scripts.yml.bak deleted file mode 100644 index acb86132..00000000 --- a/.github/workflows/backup/validate-scripts.yml.bak +++ /dev/null @@ -1,234 +0,0 @@ -name: Validate scripts -on: - push: - branches: - - main - pull_request_target: - paths: - - "ct/*.sh" - - "install/*.sh" - -jobs: - check-scripts: - name: Check changed files - runs-on: ubuntu-latest - permissions: - pull-requests: write - - steps: - - name: Debug event payload - run: | - echo "Event name: ${{ github.event_name }}" - echo "Payload: $(cat $GITHUB_EVENT_PATH)" - - - name: Get pull request information - if: github.event_name == 'pull_request_target' - uses: actions/github-script@v7 - id: pr - with: - script: | - const { data: pullRequest } = await github.rest.pulls.get({ - ...context.repo, - pull_number: context.payload.pull_request.number, - }); - return pullRequest; - - - name: Checkout code - uses: actions/checkout@v4 - with: - fetch-depth: 0 - ref: ${{ github.event_name == 'pull_request_target' && fromJSON(steps.pr.outputs.result).merge_commit_sha || '' }} - - - name: Get changed files - id: changed-files - run: | - if [ "${{ github.event_name }}" == "pull_request_target" ]; then - echo "files=$(git diff --name-only ${{ github.event.pull_request.base.sha }} ${{ steps.pr.outputs.result && fromJSON(steps.pr.outputs.result).merge_commit_sha }} | grep -E '\.(sh|func)$' | xargs)" >> $GITHUB_OUTPUT - else - echo "files=$(git diff --name-only ${{ github.event.before }} ${{ github.event.after }} | grep -E '\.(sh|func)$' | xargs)" >> $GITHUB_OUTPUT - fi - - - name: Check build.func line - if: always() && steps.changed-files.outputs.files != '' - id: build-func - run: | - NON_COMPLIANT_FILES="" - for FILE in ${{ steps.changed-files.outputs.files }}; do - if [[ "$FILE" == ct/* ]] && [[ $(sed -n '2p' "$FILE") != "source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)" ]]; then - NON_COMPLIANT_FILES="$NON_COMPLIANT_FILES $FILE" - fi - done - - if [ -n "$NON_COMPLIANT_FILES" ]; then - echo "files=$NON_COMPLIANT_FILES" >> $GITHUB_OUTPUT - echo "Build.func line missing or incorrect in files:" - for FILE in $NON_COMPLIANT_FILES; do - echo "$FILE" - done - exit 1 - fi - - - name: Check executable permissions - if: always() && steps.changed-files.outputs.files != '' - id: check-executable - run: | - NON_COMPLIANT_FILES="" - for FILE in ${{ steps.changed-files.outputs.files }}; do - if [[ ! -x "$FILE" ]]; then - NON_COMPLIANT_FILES="$NON_COMPLIANT_FILES $FILE" - fi - done - - if [ -n "$NON_COMPLIANT_FILES" ]; then - echo "files=$NON_COMPLIANT_FILES" >> $GITHUB_OUTPUT - echo "Files not executable:" - for FILE in $NON_COMPLIANT_FILES; do - echo "$FILE" - done - exit 1 - fi - - - name: Check copyright - if: always() && steps.changed-files.outputs.files != '' - id: check-copyright - run: | - NON_COMPLIANT_FILES="" - for FILE in ${{ steps.changed-files.outputs.files }}; do - if ! sed -n '3p' "$FILE" | grep -qE "^# Copyright \(c\) [0-9]{4}(-[0-9]{4})? (tteck \| community-scripts ORG|community-scripts ORG|tteck)$"; then - NON_COMPLIANT_FILES="$NON_COMPLIANT_FILES $FILE" - fi - done - - if [ -n "$NON_COMPLIANT_FILES" ]; then - echo "files=$NON_COMPLIANT_FILES" >> $GITHUB_OUTPUT - echo "Copyright header missing or not on line 3 in files:" - for FILE in $NON_COMPLIANT_FILES; do - echo "$FILE" - done - exit 1 - fi - - - name: Check author - if: always() && steps.changed-files.outputs.files != '' - id: check-author - run: | - NON_COMPLIANT_FILES="" - for FILE in ${{ steps.changed-files.outputs.files }}; do - if ! sed -n '4p' "$FILE" | grep -qE "^# Author: .+"; then - NON_COMPLIANT_FILES="$NON_COMPLIANT_FILES $FILE" - fi - done - - if [ -n "$NON_COMPLIANT_FILES" ]; then - echo "files=$NON_COMPLIANT_FILES" >> $GITHUB_OUTPUT - echo "Author header missing or invalid on line 4 in files:" - for FILE in $NON_COMPLIANT_FILES; do - echo "$FILE" - done - exit 1 - fi - - - name: Check license - if: always() && steps.changed-files.outputs.files != '' - id: check-license - run: | - NON_COMPLIANT_FILES="" - for FILE in ${{ steps.changed-files.outputs.files }}; do - if [[ "$(sed -n '5p' "$FILE")" != "# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE" ]]; then - NON_COMPLIANT_FILES="$NON_COMPLIANT_FILES $FILE" - fi - done - - if [ -n "$NON_COMPLIANT_FILES" ]; then - echo "files=$NON_COMPLIANT_FILES" >> $GITHUB_OUTPUT - echo "License header missing or not on line 5 in files:" - for FILE in $NON_COMPLIANT_FILES; do - echo "$FILE" - done - exit 1 - fi - - - name: Check source - if: always() && steps.changed-files.outputs.files != '' - id: check-source - run: | - NON_COMPLIANT_FILES="" - for FILE in ${{ steps.changed-files.outputs.files }}; do - if ! sed -n '6p' "$FILE" | grep -qE "^# Source: .+"; then - NON_COMPLIANT_FILES="$NON_COMPLIANT_FILES $FILE" - fi - done - - if [ -n "$NON_COMPLIANT_FILES" ]; then - echo "files=$NON_COMPLIANT_FILES" >> $GITHUB_OUTPUT - echo "Source header missing or not on line 6 in files:" - for FILE in $NON_COMPLIANT_FILES; do - echo "$FILE" - done - exit 1 - fi - - - name: Post results and comment - if: always() && steps.changed-files.outputs.files != '' && github.event_name == 'pull_request_target' - uses: actions/github-script@v7 - with: - script: | - const result = '${{ job.status }}' === 'success' ? 'success' : 'failure'; - const nonCompliantFiles = { - 'Invalid build.func source': "${{ steps.build-func.outputs.files || '' }}", - 'Not executable': "${{ steps.check-executable.outputs.files || '' }}", - 'Copyright header line missing or invalid': "${{ steps.check-copyright.outputs.files || '' }}", - 'Author header line missing or invalid': "${{ steps.check-author.outputs.files || '' }}", - 'License header line missing or invalid': "${{ steps.check-license.outputs.files || '' }}", - 'Source header line missing or invalid': "${{ steps.check-source.outputs.files || '' }}" - }; - - const issueNumber = context.payload.pull_request ? context.payload.pull_request.number : null; - const commentIdentifier = 'validate-scripts'; - let newCommentBody = `\n### Script validation\n\n`; - - if (result === 'failure') { - newCommentBody += ':x: We found issues in the following changed files:\n\n'; - for (const [check, files] of Object.entries(nonCompliantFiles)) { - if (files) { - newCommentBody += `**${check}:**\n`; - files.trim().split(' ').forEach(file => { - newCommentBody += `- ${file}: ${check}\n`; - }); - newCommentBody += `\n`; - } - } - } else { - newCommentBody += `:rocket: All changed shell scripts passed validation!\n`; - } - - newCommentBody += `\n\n`; - - if (issueNumber) { - const { data: comments } = await github.rest.issues.listComments({ - ...context.repo, - issue_number: issueNumber - }); - - const existingComment = comments.find(comment => - comment.body.includes(``) && - comment.user.login === 'github-actions[bot]' - ); - - if (existingComment) { - const re = new RegExp(String.raw`[\\s\\S]*?`, "m"); - newCommentBody = existingComment.body.replace(re, newCommentBody); - - await github.rest.issues.updateComment({ - ...context.repo, - comment_id: existingComment.id, - body: newCommentBody - }); - } else { - await github.rest.issues.createComment({ - ...context.repo, - issue_number: issueNumber, - body: newCommentBody - }); - } - } diff --git a/.github/workflows/changelog-pr.yaml b/.github/workflows/changelog-pr.yaml deleted file mode 100644 index 80959d54..00000000 --- a/.github/workflows/changelog-pr.yaml +++ /dev/null @@ -1,286 +0,0 @@ -name: Create Changelog Pull Request - -on: - push: - branches: ["main"] - workflow_dispatch: - -jobs: - update-changelog-pull-request: - if: github.repository == 'community-scripts/ProxmoxVED' - runs-on: ubuntu-latest - env: - CONFIG_PATH: .github/changelog-pr-config.json - BRANCH_NAME: github-action-update-changelog - AUTOMATED_PR_LABEL: "automated pr" - permissions: - contents: write - pull-requests: write - steps: - - name: Generate a token for PR creation - id: generate-token - uses: actions/create-github-app-token@v2 - with: - app-id: ${{ vars.APP_ID }} - private-key: ${{ secrets.APP_PRIVATE_KEY }} - owner: community-scripts - repositories: ProxmoxVED - - - name: Generate a token for PR approval and merge - id: generate-token-merge - uses: actions/create-github-app-token@v2 - with: - app-id: ${{ secrets.APP_ID_APPROVE_AND_MERGE }} - private-key: ${{ secrets.APP_KEY_APPROVE_AND_MERGE }} - owner: community-scripts - repositories: ProxmoxVED - - - name: Checkout code - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Get latest dates in changelog - run: | - 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') - SECOND_LATEST_DATE=$(echo "$DATES" | sed -n '2p') - TODAY=$(date -u +%Y-%m-%d) - - 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 - uses: actions/github-script@v7 - with: - script: | - async function main() { - const fs = require('fs').promises; - const path = require('path'); - - const configPath = path.resolve(process.env.CONFIG_PATH); - const fileContent = await fs.readFile(configPath, 'utf-8'); - const changelogConfig = JSON.parse(fileContent); - - const categorizedPRs = changelogConfig.map(obj => ({ - ...obj, - notes: [], - subCategories: obj.subCategories ?? ( - obj.labels.includes("update script") ? [ - { title: "🐞 Bug Fixes", labels: ["bugfix"], notes: [] }, - { title: "✨ New Features", labels: ["feature"], notes: [] }, - { title: "💥 Breaking Changes", labels: ["breaking change"], notes: [] }, - { title: "🔧 Refactor", labels: ["refactor"], notes: [] }, - ] : - obj.labels.includes("maintenance") ? [ - { title: "🐞 Bug Fixes", labels: ["bugfix"], notes: [] }, - { title: "✨ New Features", labels: ["feature"], notes: [] }, - { title: "💥 Breaking Changes", labels: ["breaking change"], notes: [] }, - { title: "📡 API", labels: ["api"], notes: [] }, - { title: "Github", labels: ["github"], notes: [] }, - { title: "📝 Documentation", labels: ["documentation"], notes: [] }, - { title: "🔧 Refactor", labels: ["refactor"], notes: [] } - ] : - obj.labels.includes("website") ? [ - { title: "🐞 Bug Fixes", labels: ["bugfix"], notes: [] }, - { title: "✨ New Features", labels: ["feature"], notes: [] }, - { title: "💥 Breaking Changes", labels: ["breaking change"], notes: [] }, - { title: "Script Information", labels: ["json"], notes: [] } - ] : [] - ) - })); - - const latestDateInChangelog = new Date(process.env.LATEST_DATE); - latestDateInChangelog.setUTCHours(23, 59, 59, 999); - - const { data: pulls } = await github.rest.pulls.list({ - owner: context.repo.owner, - repo: "ProxmoxVE", - base: "main", - state: "closed", - sort: "updated", - direction: "desc", - per_page: 100, - }); - - const filteredPRs = 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()) - ) - ); - - for (const pr of filteredPRs) { - const prLabels = pr.labels.map(label => label.name.toLowerCase()); - if (pr.user.login.includes("push-app-to-main[bot]")) { - - const scriptName = pr.title; - try { - const { data: relatedIssues } = await github.rest.issues.listForRepo({ - owner: context.repo.owner, - repo: "ProxmoxVED", - state: "all", - labels: ["Started Migration To ProxmoxVE"] - }); - - const matchingIssue = relatedIssues.find(issue => - issue.title.toLowerCase().includes(scriptName.toLowerCase()) - ); - - if (matchingIssue) { - const issueAuthor = matchingIssue.user.login; - const issueAuthorUrl = `https://github.com/${issueAuthor}`; - prNote = `- ${pr.title} [@${issueAuthor}](${issueAuthorUrl}) ([#${pr.number}](${pr.html_url}))`; - } - else { - prNote = `- ${pr.title} ([#${pr.number}](${pr.html_url}))`; - } - } catch (error) { - console.error(`Error fetching related issues: ${error}`); - prNote = `- ${pr.title} ([#${pr.number}](${pr.html_url}))`; - } - }else{ - prNote = `- ${pr.title} [@${pr.user.login}](https://github.com/${pr.user.login}) ([#${pr.number}](${pr.html_url}))`; - } - - - if (prLabels.includes("new script")) { - const newScriptCategory = categorizedPRs.find(category => - category.title === "New Scripts" || category.labels.includes("new script")); - if (newScriptCategory) { - newScriptCategory.notes.push(prNote); - } - } else { - - let categorized = false; - const priorityCategories = categorizedPRs.slice(); - for (const category of priorityCategories) { - if (categorized) break; - if (category.labels.some(label => prLabels.includes(label))) { - if (category.subCategories && category.subCategories.length > 0) { - const subCategory = category.subCategories.find(sub => - sub.labels.some(label => prLabels.includes(label)) - ); - - if (subCategory) { - subCategory.notes.push(prNote); - } else { - category.notes.push(prNote); - } - } else { - category.notes.push(prNote); - } - categorized = true; - } - } - } - - } - - return categorizedPRs; - } - - return await main(); - - - name: Update CHANGELOG.md - uses: actions/github-script@v7 - with: - script: | - const fs = require('fs').promises; - const path = require('path'); - - const today = process.env.TODAY; - const latestDateInChangelog = process.env.LATEST_DATE; - const changelogPath = path.resolve('CHANGELOG.md'); - const categorizedPRs = ${{ steps.get-categorized-prs.outputs.result }}; - - let newReleaseNotes = `## ${today}\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 changelogIncludesTodaysReleaseNotes = changelogContent.includes(`\n## ${today}`); - - const regex = changelogIncludesTodaysReleaseNotes - ? new RegExp(`## ${today}.*(?=## ${latestDateInChangelog})`, "gs") - : new RegExp(`(?=## ${latestDateInChangelog})`, "gs"); - - const newChangelogContent = changelogContent.replace(regex, newReleaseNotes); - await fs.writeFile(changelogPath, newChangelogContent); - - - name: Check for changes - id: verify-diff - run: | - git diff --quiet . || echo "changed=true" >> $GITHUB_ENV - - - 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" - git add CHANGELOG.md - git commit -m "Update CHANGELOG.md" - git checkout -b $BRANCH_NAME || git checkout $BRANCH_NAME - git push origin $BRANCH_NAME --force - - - name: Create pull request if not exists - if: env.changed == 'true' - env: - GH_TOKEN: ${{ steps.generate-token.outputs.token }} - run: | - PR_EXISTS=$(gh pr list --head "${BRANCH_NAME}" --json number --jq '.[].number') - if [ -z "$PR_EXISTS" ]; then - gh pr create --title "[Github Action] Update CHANGELOG.md" \ - --body "This PR is auto-generated by a Github Action to update the CHANGELOG.md file." \ - --head $BRANCH_NAME \ - --base main \ - --label "$AUTOMATED_PR_LABEL" - fi - - - name: Approve pull request - if: env.changed == 'true' - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - PR_NUMBER=$(gh pr list --head "${BRANCH_NAME}" --json number --jq '.[].number') - if [ -n "$PR_NUMBER" ]; then - gh pr review $PR_NUMBER --approve - fi - - - name: Approve pull request and merge - if: env.changed == 'true' - env: - GH_TOKEN: ${{ steps.generate-token-merge.outputs.token }} - run: | - git config --global user.name "github-actions-automege[bot]" - git config --global user.email "github-actions-automege[bot]@users.noreply.github.com" - PR_NUMBER=$(gh pr list --head "${BRANCH_NAME}" --json number --jq '.[].number') - if [ -n "$PR_NUMBER" ]; then - gh pr review $PR_NUMBER --approve - gh pr merge $PR_NUMBER --squash --admin - fi diff --git a/.github/workflows/close-discussion.yaml b/.github/workflows/close-discussion.yaml deleted file mode 100644 index 9b0352f4..00000000 --- a/.github/workflows/close-discussion.yaml +++ /dev/null @@ -1,164 +0,0 @@ -name: Close Discussion on PR Merge - -on: - push: - branches: - - main - -permissions: - contents: read - discussions: write - -jobs: - close-discussion: - if: github.repository == 'community-scripts/ProxmoxVED' - runs-on: ubuntu-latest - - steps: - - name: Checkout Repository - uses: actions/checkout@v4 - - - name: Set Up Node.js - uses: actions/setup-node@v4 - with: - node-version: "20" - - - name: Install Dependencies - run: npm install zx @octokit/graphql - - - name: Close Discussion - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - GITHUB_SHA: ${{ github.sha }} - GITHUB_REPOSITORY: ${{ github.repository }} - run: | - npx zx << 'EOF' - import { graphql } from "@octokit/graphql"; - - (async function () { - try { - const token = process.env.GITHUB_TOKEN; - const commitSha = process.env.GITHUB_SHA; - const [owner, repo] = process.env.GITHUB_REPOSITORY.split("/"); - - if (!token || !commitSha || !owner || !repo) { - console.log("Missing required environment variables."); - process.exit(1); - } - - const graphqlWithAuth = graphql.defaults({ - headers: { authorization: `Bearer ${token}` }, - }); - - // Find PR from commit SHA - const searchQuery = ` - query($owner: String!, $repo: String!, $sha: GitObjectID!) { - repository(owner: $owner, name: $repo) { - object(oid: $sha) { - ... on Commit { - associatedPullRequests(first: 1) { - nodes { - number - body - } - } - } - } - } - } - `; - - const prResult = await graphqlWithAuth(searchQuery, { - owner, - repo, - sha: commitSha, - }); - - const pr = prResult.repository.object.associatedPullRequests.nodes[0]; - if (!pr) { - console.log("No PR found for this commit."); - return; - } - - const prNumber = pr.number; - const prBody = pr.body; - - const match = prBody.match(/#(\d+)/); - if (!match) { - console.log("No discussion ID found in PR body."); - return; - } - - const discussionNumber = match[1]; - console.log(`Extracted Discussion Number: ${discussionNumber}`); - - // Fetch GraphQL discussion ID - const discussionQuery = ` - query($owner: String!, $repo: String!, $number: Int!) { - repository(owner: $owner, name: $repo) { - discussion(number: $number) { - id - } - } - } - `; - - // - try { - const discussionResponse = await graphqlWithAuth(discussionQuery, { - owner, - repo, - number: parseInt(discussionNumber, 10), - }); - - const discussionQLId = discussionResponse.repository.discussion.id; - if (!discussionQLId) { - console.log("Failed to fetch discussion GraphQL ID."); - return; - } - } catch (error) { - console.error("Discussion not found or error occurred while fetching discussion:", error); - return; - } - - // Post comment - const commentMutation = ` - mutation($discussionId: ID!, $body: String!) { - addDiscussionComment(input: { discussionId: $discussionId, body: $body }) { - comment { id body } - } - } - `; - - const commentResponse = await graphqlWithAuth(commentMutation, { - discussionId: discussionQLId, - body: `Merged with PR #${prNumber}`, - }); - - const commentId = commentResponse.addDiscussionComment.comment.id; - if (!commentId) { - console.log("Failed to post the comment."); - return; - } - - console.log(`Comment Posted Successfully! Comment ID: ${commentId}`); - - // Mark comment as answer - const markAnswerMutation = ` - mutation($id: ID!) { - markDiscussionCommentAsAnswer(input: { id: $id }) { - discussion { id title } - } - } - `; - - await graphqlWithAuth(markAnswerMutation, { id: commentId }); - - console.log("Comment marked as answer successfully!"); - - } catch (error) { - console.error("Error:", error); - process.exit(1); - } - })(); - EOF diff --git a/.github/workflows/close-ttek-issue.yaml b/.github/workflows/close-ttek-issue.yaml deleted file mode 100644 index 037d6075..00000000 --- a/.github/workflows/close-ttek-issue.yaml +++ /dev/null @@ -1,53 +0,0 @@ -name: Auto-Close tteck Issues - -on: - issues: - types: [opened] - -jobs: - close_tteck_issues: - if: github.repository == 'community-scripts/ProxmoxVED' - runs-on: ubuntu-latest - steps: - - name: Auto-close if tteck script detected - uses: actions/github-script@v7 - with: - script: | - const issue = context.payload.issue; - const content = `${issue.title}\n${issue.body}`; - const issueNumber = issue.number; - - // Check for tteck script mention - if (content.includes("tteck") || content.includes("tteck/Proxmox")) { - const message = `Hello, it looks like you are referencing the **old tteck repo**. - - This repository is no longer used for active scripts. - **Please update your bookmarks** and use: [https://helper-scripts.com](https://helper-scripts.com) - - Also make sure your Bash command starts with: - \`\`\`bash - bash <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/...) - \`\`\` - - This issue is being closed automatically.`; - - await github.rest.issues.createComment({ - ...context.repo, - issue_number: issueNumber, - body: message - }); - - // Optionally apply a label like "not planned" - await github.rest.issues.addLabels({ - ...context.repo, - issue_number: issueNumber, - labels: ["not planned"] - }); - - // Close the issue - await github.rest.issues.update({ - ...context.repo, - issue_number: issueNumber, - state: "closed" - }); - } diff --git a/.github/workflows/live/changelog-pr.yml b/.github/workflows/live/changelog-pr.yml deleted file mode 100644 index 87da5514..00000000 --- a/.github/workflows/live/changelog-pr.yml +++ /dev/null @@ -1,228 +0,0 @@ -name: Create Changelog Pull Request - -on: - push: - branches: ["main"] - workflow_dispatch: - -jobs: - update-changelog-pull-request: - runs-on: ubuntu-latest - env: - CONFIG_PATH: .github/changelog-pr-config.json - BRANCH_NAME: github-action-update-changelog - AUTOMATED_PR_LABEL: "automated pr" - permissions: - contents: write - pull-requests: write - steps: - - name: Generate a token - id: generate-token - uses: actions/create-github-app-token@v2 - with: - app-id: ${{ vars.APP_ID }} - private-key: ${{ secrets.APP_PRIVATE_KEY }} - owner: community-scripts - repositories: ProxmoxVED - - - name: Checkout code - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Get latest dates in changelog - run: | - 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') - SECOND_LATEST_DATE=$(echo "$DATES" | sed -n '2p') - TODAY=$(date -u +%Y-%m-%d) - - 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 - uses: actions/github-script@v7 - with: - script: | - const fs = require('fs').promises; - const path = require('path'); - - const configPath = path.resolve(process.env.CONFIG_PATH); - const fileContent = await fs.readFile(configPath, 'utf-8'); - const changelogConfig = JSON.parse(fileContent); - - const categorizedPRs = changelogConfig.map(obj => ({ - ...obj, - notes: [], - subCategories: obj.subCategories ?? ( - obj.labels.includes("update script") ? [ - { title: "🐞 Bug Fixes", labels: ["bugfix"], notes: [] }, - { title: "✨ New Features", labels: ["feature"], notes: [] }, - { title: "💥 Breaking Changes", labels: ["breaking change"], notes: [] } - ] : - obj.labels.includes("maintenance") ? [ - { title: "🐞 Bug Fixes", labels: ["bugfix"], notes: [] }, - { title: "✨ New Features", labels: ["feature"], notes: [] }, - { title: "💥 Breaking Changes", labels: ["breaking change"], notes: [] }, - { title: "📡 API", labels: ["api"], notes: [] }, - { title: "Github", labels: ["github"], notes: [] } - ] : - obj.labels.includes("website") ? [ - { title: "🐞 Bug Fixes", labels: ["bugfix"], notes: [] }, - { title: "✨ New Features", labels: ["feature"], notes: [] }, - { title: "💥 Breaking Changes", labels: ["breaking change"], notes: [] }, - { title: "Script Information", labels: ["json"], notes: [] } - ] : [] - ) - })); - - const latestDateInChangelog = new Date(process.env.LATEST_DATE); - latestDateInChangelog.setUTCHours(23, 59, 59, 999); - - const { data: pulls } = await github.rest.pulls.list({ - owner: context.repo.owner, - repo: context.repo.repo, - base: "main", - state: "closed", - sort: "updated", - direction: "desc", - per_page: 100, - }); - - 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()); - const prNote = `- ${pr.title} [@${pr.user.login}](https://github.com/${pr.user.login}) ([#${pr.number}](${pr.html_url}))`; - - const updateScriptsCategory = categorizedPRs.find(category => - category.labels.some(label => prLabels.includes(label)) - ); - - if (updateScriptsCategory) { - - const subCategory = updateScriptsCategory.subCategories.find(sub => - sub.labels.some(label => prLabels.includes(label)) - ); - - if (subCategory) { - subCategory.notes.push(prNote); - } else { - updateScriptsCategory.notes.push(prNote); - } - } - }); - - console.log(JSON.stringify(categorizedPRs, null, 2)); - - return categorizedPRs; - - - - name: Update CHANGELOG.md - uses: actions/github-script@v7 - with: - script: | - const fs = require('fs').promises; - const path = require('path'); - - const today = process.env.TODAY; - const latestDateInChangelog = process.env.LATEST_DATE; - const changelogPath = path.resolve('CHANGELOG.md'); - const categorizedPRs = ${{ steps.get-categorized-prs.outputs.result }}; - - console.log(JSON.stringify(categorizedPRs, null, 2)); - - - let newReleaseNotes = `## ${today}\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 changelogIncludesTodaysReleaseNotes = changelogContent.includes(`\n## ${today}`); - - const regex = changelogIncludesTodaysReleaseNotes - ? new RegExp(`## ${today}.*(?=## ${latestDateInChangelog})`, "gs") - : new RegExp(`(?=## ${latestDateInChangelog})`, "gs"); - - const newChangelogContent = changelogContent.replace(regex, newReleaseNotes); - await fs.writeFile(changelogPath, newChangelogContent); - - - name: Check for changes - id: verify-diff - run: | - git diff --quiet . || echo "changed=true" >> $GITHUB_ENV - - - 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" - git add CHANGELOG.md - git commit -m "Update CHANGELOG.md" - git checkout -b $BRANCH_NAME || git checkout $BRANCH_NAME - git push origin $BRANCH_NAME --force - - - name: Create pull request if not exists - if: env.changed == 'true' - env: - GH_TOKEN: ${{ steps.generate-token.outputs.token }} - run: | - PR_EXISTS=$(gh pr list --head "${BRANCH_NAME}" --json number --jq '.[].number') - if [ -z "$PR_EXISTS" ]; then - gh pr create --title "[Github Action] Update CHANGELOG.md" \ - --body "This PR is auto-generated by a Github Action to update the CHANGELOG.md file." \ - --head $BRANCH_NAME \ - --base main \ - --label "$AUTOMATED_PR_LABEL" - fi - - - name: Approve pull request - if: env.changed == 'true' - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - PR_NUMBER=$(gh pr list --head "${BRANCH_NAME}" --json number --jq '.[].number') - if [ -n "$PR_NUMBER" ]; then - gh pr review $PR_NUMBER --approve - fi - - - name: Re-approve pull request after update - if: env.changed == 'true' - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - PR_NUMBER=$(gh pr list --head "${BRANCH_NAME}" --json number --jq '.[].number') - if [ -n "$PR_NUMBER" ]; then - gh pr review $PR_NUMBER --approve - fi diff --git a/.github/workflows/live/close-discussion.yml b/.github/workflows/live/close-discussion.yml deleted file mode 100644 index 4b39fbf9..00000000 --- a/.github/workflows/live/close-discussion.yml +++ /dev/null @@ -1,122 +0,0 @@ -name: Close Discussion on PR Merge - -on: - pull_request: - types: [closed] - -jobs: - close-discussion: - runs-on: ubuntu-latest - - steps: - - name: Checkout Repository - uses: actions/checkout@v4 - - - name: Set Up Node.js - uses: actions/setup-node@v4 - with: - node-version: "20" - - name: Install Dependencies - run: npm install zx @octokit/graphql - - - name: Close Discussion - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - PR_BODY: ${{ github.event.pull_request.body }} - PR_NUMBER: ${{ github.event.pull_request.number }} - REPO_OWNER: ${{ github.repository_owner }} - REPO_NAME: ${{ github.event.repository.name }} - run: | - npx zx << 'EOF' - import { graphql } from "@octokit/graphql"; - (async function() { - try { - const token = process.env.GITHUB_TOKEN; - const prBody = process.env.PR_BODY; - const prNumber = process.env.PR_NUMBER; - const owner = process.env.REPO_OWNER; - const repo = process.env.REPO_NAME; - - if (!token || !prBody || !prNumber || !owner || !repo) { - console.log("Missing required environment variables."); - process.exit(1); - } - - const match = prBody.match(/#(\d+)/); - if (!match) { - console.log("No discussion ID found in PR body."); - return; - } - const discussionNumber = match[1]; - - console.log(`Extracted Discussion Number: ${discussionNumber}`); - console.log(`PR Number: ${prNumber}`); - console.log(`Repository: ${owner}/${repo}`); - - const graphqlWithAuth = graphql.defaults({ - headers: { authorization: `Bearer ${token}` }, - }); - - const discussionQuery = ` - query($owner: String!, $repo: String!, $number: Int!) { - repository(owner: $owner, name: $repo) { - discussion(number: $number) { - id - } - } - } - `; - - const discussionResponse = await graphqlWithAuth(discussionQuery, { - owner, - repo, - number: parseInt(discussionNumber, 10), - }); - - const discussionQLId = discussionResponse.repository.discussion.id; - if (!discussionQLId) { - console.log("Failed to fetch discussion GraphQL ID."); - return; - } - - console.log(`GraphQL Discussion ID: ${discussionQLId}`); - - const commentMutation = ` - mutation($discussionId: ID!, $body: String!) { - addDiscussionComment(input: { discussionId: $discussionId, body: $body }) { - comment { id body } - } - } - `; - - const commentResponse = await graphqlWithAuth(commentMutation, { - discussionId: discussionQLId, - body: `Merged with PR #${prNumber}`, - }); - - const commentId = commentResponse.addDiscussionComment.comment.id; - if (!commentId) { - console.log("Failed to post the comment."); - return; - } - - console.log(`Comment Posted Successfully! Comment ID: ${commentId}`); - - const markAnswerMutation = ` - mutation($id: ID!) { - markDiscussionCommentAsAnswer(input: { id: $id }) { - discussion { id title } - } - } - `; - - await graphqlWithAuth(markAnswerMutation, { id: commentId }); - - console.log("Comment marked as answer successfully!"); - - } catch (error) { - console.error("Error:", error); - return; - } - })(); - EOF \ No newline at end of file diff --git a/.github/workflows/live/create-docker-for-runner.yml b/.github/workflows/live/create-docker-for-runner.yml deleted file mode 100644 index c9fef0a5..00000000 --- a/.github/workflows/live/create-docker-for-runner.yml +++ /dev/null @@ -1,37 +0,0 @@ -name: Build and Publish Docker Image - -on: - push: - branches: - - main - paths: - - '.github/runner/docker/**' - schedule: - - cron: '0 0 * * *' - -jobs: - build: - runs-on: ubuntu-latest #To ensure it always builds we use the github runner with all the right tooling - - steps: - - name: Checkout code - uses: actions/checkout@v3 - - - name: Log in to GHCR - uses: docker/login-action@v2 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Build Docker image - run: | - repo_name=${{ github.repository }} # Get repository name - repo_name_lower=$(echo $repo_name | tr '[:upper:]' '[:lower:]') # Convert to lowercase - docker build -t ghcr.io/$repo_name_lower/gh-runner-self:latest -f .github/runner/docker/gh-runner-self.dockerfile . - - - name: Push Docker image to GHCR - run: | - repo_name=${{ github.repository }} # Get repository name - repo_name_lower=$(echo $repo_name | tr '[:upper:]' '[:lower:]') # Convert to lowercase - docker push ghcr.io/$repo_name_lower/gh-runner-self:latest diff --git a/.github/workflows/live/delete-json-branch.yml b/.github/workflows/live/delete-json-branch.yml deleted file mode 100644 index e4cdcf24..00000000 --- a/.github/workflows/live/delete-json-branch.yml +++ /dev/null @@ -1,28 +0,0 @@ - -name: Delete JSON date PR Branch - -on: - pull_request: - types: [closed] - branches: - - main - -jobs: - delete_branch: - runs-on: ubuntu-latest - steps: - - name: Checkout the code - uses: actions/checkout@v3 - - - name: Delete PR Update Branch - if: github.event.pull_request.merged == true && startsWith(github.event.pull_request.head.ref, 'pr-update-json-') - run: | - PR_BRANCH="${{ github.event.pull_request.head.ref }}" - echo "Deleting branch $PR_BRANCH..." - - # Avoid deleting the default branch (e.g., main) - if [[ "$PR_BRANCH" != "main" ]]; then - git push origin --delete "$PR_BRANCH" - else - echo "Skipping deletion of the main branch" - fi \ No newline at end of file diff --git a/.github/workflows/live/github-release.yml b/.github/workflows/live/github-release.yml deleted file mode 100644 index 482d88a0..00000000 --- a/.github/workflows/live/github-release.yml +++ /dev/null @@ -1,57 +0,0 @@ -name: Create Daily Release - -on: - schedule: - - cron: '1 0 * * *' # Runs daily at 00:01 UTC - workflow_dispatch: - -jobs: - create-daily-release: - runs-on: ubuntu-latest - permissions: - contents: write - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Extract first 5000 characters from CHANGELOG.md - run: head -c 5000 CHANGELOG.md > changelog_cropped.md - - - name: Debugging - Show extracted changelog - run: | - echo "=== CHANGELOG EXCERPT ===" - cat changelog_cropped.md - echo "=========================" - - - name: Parse CHANGELOG.md and create release - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - YESTERDAY=$(date -u --date="yesterday" +%Y-%m-%d) - echo "Checking for changes on: $YESTERDAY" - - # Ensure yesterday's date exists in the changelog - if ! grep -q "## $YESTERDAY" changelog_cropped.md; then - echo "No entry found for $YESTERDAY, skipping release." - exit 0 - fi - - # Extract section for yesterday's date - awk -v date="## $YESTERDAY" ' - $0 ~ date {found=1; next} - found && /^## [0-9]{4}-[0-9]{2}-[0-9]{2}/ {exit} - found - ' changelog_cropped.md > changelog_tmp.md - - echo "=== Extracted Changelog ===" - cat changelog_tmp.md - echo "===========================" - - # Skip if no content was found - if [ ! -s changelog_tmp.md ]; then - echo "No changes found for $YESTERDAY, skipping release." - exit 0 - fi - - # Create GitHub release - gh release create "$YESTERDAY" -t "$YESTERDAY" -F changelog_tmp.md diff --git a/.github/workflows/live/script-test.yml b/.github/workflows/live/script-test.yml deleted file mode 100644 index 272a1272..00000000 --- a/.github/workflows/live/script-test.yml +++ /dev/null @@ -1,177 +0,0 @@ -name: Run Scripts on PVE Node for testing -permissions: - pull-requests: write -on: - pull_request_target: - branches: - - main - paths: - - 'install/**.sh' - - 'ct/**.sh' - -jobs: - run-install-script: - runs-on: pvenode - steps: - - name: Checkout PR branch - uses: actions/checkout@v4 - with: - ref: ${{ github.event.pull_request.head.ref }} - repository: ${{ github.event.pull_request.head.repo.full_name }} - fetch-depth: 0 - - - name: Add Git safe directory - run: | - git config --global --add safe.directory /__w/ProxmoxVED/ProxmoxVE - - - name: Set up GH_TOKEN - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - echo "GH_TOKEN=${GH_TOKEN}" >> $GITHUB_ENV - - - name: Get Changed Files - run: | - CHANGED_FILES=$(gh pr diff ${{ github.event.pull_request.number }} --repo ${{ github.repository }} --name-only) - CHANGED_FILES=$(echo "$CHANGED_FILES" | tr '\n' ' ') - echo "Changed files: $CHANGED_FILES" - echo "SCRIPT=$CHANGED_FILES" >> $GITHUB_ENV - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - - name: Get scripts - id: check-install-script - run: | - ALL_FILES=() - ADDED_FILES=() - for FILE in ${{ env.SCRIPT }}; do - if [[ $FILE =~ ^install/.*-install\.sh$ ]] || [[ $FILE =~ ^ct/.*\.sh$ ]]; then - STRIPPED_NAME=$(basename "$FILE" | sed 's/-install//' | sed 's/\.sh$//') - if [[ ! " ${ADDED_FILES[@]} " =~ " $STRIPPED_NAME " ]]; then - ALL_FILES+=("$FILE") - ADDED_FILES+=("$STRIPPED_NAME") # Mark this base file as added (without the path) - fi - fi - done - ALL_FILES=$(echo "${ALL_FILES[@]}" | xargs) - echo "$ALL_FILES" - echo "ALL_FILES=$ALL_FILES" >> $GITHUB_ENV - - - name: Run scripts - id: run-install - continue-on-error: true - run: | - set +e - #run for each files in /ct - for FILE in ${{ env.ALL_FILES }}; do - STRIPPED_NAME=$(basename "$FILE" | sed 's/-install//' | sed 's/\.sh$//') - echo "Running Test for: $STRIPPED_NAME" - if grep -E -q 'read\s+-r\s+-p\s+".*"\s+\w+' "$FILE"; then - echo "The script contains an interactive prompt. Skipping execution." - continue - fi - if [[ $FILE =~ ^install/.*-install\.sh$ ]]; then - CT_SCRIPT="ct/$STRIPPED_NAME.sh" - if [[ ! -f $CT_SCRIPT ]]; then - echo "No CT script found for $STRIPPED_NAME" - ERROR_MSG="No CT script found for $FILE" - echo "$ERROR_MSG" > result_$STRIPPED_NAME.log - continue - fi - if grep -E -q 'read\s+-r\s+-p\s+".*"\s+\w+' "install/$STRIPPED_NAME-install.sh"; then - echo "The script contains an interactive prompt. Skipping execution." - continue - fi - echo "Found CT script for $STRIPPED_NAME" - chmod +x "$CT_SCRIPT" - RUNNING_FILE=$CT_SCRIPT - elif [[ $FILE =~ ^ct/.*\.sh$ ]]; then - INSTALL_SCRIPT="install/$STRIPPED_NAME-install.sh" - if [[ ! -f $INSTALL_SCRIPT ]]; then - echo "No install script found for $STRIPPED_NAME" - ERROR_MSG="No install script found for $FILE" - echo "$ERROR_MSG" > result_$STRIPPED_NAME.log - continue - fi - echo "Found install script for $STRIPPED_NAME" - chmod +x "$INSTALL_SCRIPT" - RUNNING_FILE=$FILE - if grep -E -q 'read\s+-r\s+-p\s+".*"\s+\w+' "ct/$STRIPPED_NAME.sh"; then - echo "The script contains an interactive prompt. Skipping execution." - continue - fi - fi - git remote add community-scripts https://github.com/community-scripts/ProxmoxVE.git - git fetch community-scripts - rm -f .github/workflows/scripts/app-test/pr-build.func || true - rm -f .github/workflows/scripts/app-test/pr-install.func || true - rm -f .github/workflows/scripts/app-test/pr-alpine-install.func || true - rm -f .github/workflows/scripts/app-test/pr-create-lxc.sh || true - git checkout community-scripts/main -- .github/workflows/scripts/app-test/pr-build.func - git checkout community-scripts/main -- .github/workflows/scripts/app-test/pr-install.func - git checkout community-scripts/main -- .github/workflows/scripts/app-test/pr-alpine-install.func - git checkout community-scripts/main -- .github/workflows/scripts/app-test/pr-create-lxc.sh - chmod +x $RUNNING_FILE - chmod +x .github/workflows/scripts/app-test/pr-create-lxc.sh - chmod +x .github/workflows/scripts/app-test/pr-install.func - chmod +x .github/workflows/scripts/app-test/pr-alpine-install.func - chmod +x .github/workflows/scripts/app-test/pr-build.func - sed -i 's|source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)|source .github/workflows/scripts/app-test/pr-build.func|g' "$RUNNING_FILE" - echo "Executing $RUNNING_FILE" - ERROR_MSG=$(./$RUNNING_FILE 2>&1 > /dev/null) - echo "Finished running $FILE" - if [ -n "$ERROR_MSG" ]; then - echo "ERROR in $STRIPPED_NAME: $ERROR_MSG" - echo "$ERROR_MSG" > result_$STRIPPED_NAME.log - fi - done - set -e # Restore exit-on-error - - - name: Cleanup PVE Node - run: | - containers=$(pct list | tail -n +2 | awk '{print $0 " " $4}' | awk '{print $1}') - - for container_id in $containers; do - status=$(pct status $container_id | awk '{print $2}') - if [[ $status == "running" ]]; then - pct stop $container_id - pct destroy $container_id - fi - done - - - name: Post error comments - run: | - ERROR="false" - SEARCH_LINE=".github/workflows/scripts/app-test/pr-build.func: line 255:" - - # Get all existing comments on the PR - EXISTING_COMMENTS=$(gh pr view ${{ github.event.pull_request.number }} --repo ${{ github.repository }} --json comments --jq '.comments[].body') - - for FILE in ${{ env.ALL_FILES }}; do - STRIPPED_NAME=$(basename "$FILE" | sed 's/-install//' | sed 's/\.sh$//') - if [[ ! -f result_$STRIPPED_NAME.log ]]; then - continue - fi - ERROR_MSG=$(cat result_$STRIPPED_NAME.log) - - if [ -n "$ERROR_MSG" ]; then - CLEANED_ERROR_MSG=$(echo "$ERROR_MSG" | sed "s|$SEARCH_LINE.*||") - COMMENT_BODY=":warning: The script _**$FILE**_ failed with the following message:
${CLEANED_ERROR_MSG}
" - - # Check if the comment already exists - if echo "$EXISTING_COMMENTS" | grep -qF "$COMMENT_BODY"; then - echo "Skipping duplicate comment for $FILE" - else - echo "Posting error message for $FILE" - gh pr comment ${{ github.event.pull_request.number }} \ - --repo ${{ github.repository }} \ - --body "$COMMENT_BODY" - ERROR="true" - fi - fi - done - - echo "ERROR=$ERROR" >> $GITHUB_ENV - - diff --git a/.github/workflows/live/script_format.yml b/.github/workflows/live/script_format.yml deleted file mode 100644 index c8ea7a4d..00000000 --- a/.github/workflows/live/script_format.yml +++ /dev/null @@ -1,243 +0,0 @@ -name: Script Format Check -permissions: - pull-requests: write -on: - pull_request_target: - branches: - - main - paths: - - 'install/*.sh' - - 'ct/*.sh' - -jobs: - run-install-script: - runs-on: pvenode - steps: - - name: Checkout PR branch (supports forks) - uses: actions/checkout@v4 - with: - ref: ${{ github.event.pull_request.head.ref }} - repository: ${{ github.event.pull_request.head.repo.full_name }} - fetch-depth: 0 - - - name: Add Git safe directory - run: | - git config --global --add safe.directory /__w/ProxmoxVED/ProxmoxVE - - - name: Set up GH_TOKEN - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - echo "GH_TOKEN=${GH_TOKEN}" >> $GITHUB_ENV - - - name: Get Changed Files - run: | - CHANGED_FILES=$(gh pr diff ${{ github.event.pull_request.number }} --repo ${{ github.repository }} --name-only) - CHANGED_FILES=$(echo "$CHANGED_FILES" | tr '\n' ' ') - echo "Changed files: $CHANGED_FILES" - echo "SCRIPT=$CHANGED_FILES" >> $GITHUB_ENV - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Check scripts - id: run-install - continue-on-error: true - run: | - for FILE in ${{ env.SCRIPT }}; do - STRIPPED_NAME=$(basename "$FILE" | sed 's/-install//' | sed 's/\.sh$//') - echo "Running Test for: $STRIPPED_NAME" - FILE_STRIPPED="${FILE##*/}" - LOG_FILE="result_$FILE_STRIPPED.log" - - if [[ $FILE =~ ^ct/.*\.sh$ ]]; then - - FIRST_LINE=$(sed -n '1p' "$FILE") - [[ "$FIRST_LINE" != "#!/usr/bin/env bash" ]] && echo "Line 1 was $FIRST_LINE | Should be: #!/usr/bin/env bash" >> "$LOG_FILE" - SECOND_LINE=$(sed -n '2p' "$FILE") - [[ "$SECOND_LINE" != "source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)" ]] && - echo "Line 2 was $SECOND_LINE | Should be: source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)" >> "$LOG_FILE" - THIRD_LINE=$(sed -n '3p' "$FILE") - if ! [[ "$THIRD_LINE" =~ ^#\ Copyright\ \(c\)\ [0-9]{4}-[0-9]{4}\ community-scripts\ ORG$ || "$THIRD_LINE" =~ ^Copyright\ \(c\)\ [0-9]{4}-[0-9]{4}\ tteck$ ]]; then - echo "Line 3 was $THIRD_LINE | Should be: # Copyright (c) 2021-2025 community-scripts ORG" >> "$LOG_FILE" - fi - - EXPECTED_AUTHOR="# Author:" - EXPECTED_LICENSE="# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE" - EXPECTED_SOURCE="# Source:" - EXPECTED_EMPTY="" - - for i in {4..7}; do - LINE=$(sed -n "${i}p" "$FILE") - - case $i in - 4) - [[ $LINE == $EXPECTED_AUTHOR* ]] || printf "Line %d was: '%s' | Should start with: '%s'\n" "$i" "$LINE" "$EXPECTED_AUTHOR" >> $LOG_FILE - ;; - 5) - [[ "$LINE" == "$EXPECTED_LICENSE" ]] || printf "Line %d was: '%s' | Should be: '%s'\n" "$i" "$LINE" "$EXPECTED_LICENSE" >> $LOG_FILE - ;; - 6) - [[ $LINE == $EXPECTED_SOURCE* ]] || printf "Line %d was: '%s' | Should start with: '%s'\n" "$i" "$LINE" "$EXPECTED_SOURCE" >> $LOG_FILE - ;; - 7) - [[ -z $LINE ]] || printf "Line %d was: '%s' | Should be empty\n" "$i" "$LINE" >> $LOG_FILE - ;; - esac - done - - - EXPECTED_PREFIXES=( - "APP=" - "var_tags=" - "var_cpu=" # Must be a number - "var_ram=" # Must be a number - "var_disk=" # Must be a number - "var_os=" # Must be debian, alpine, or ubuntu - "var_version=" - "var_unprivileged=" # Must be 0 or 1 - ) - - - for i in {8..15}; do - LINE=$(sed -n "${i}p" "$FILE") - INDEX=$((i - 8)) - - case $INDEX in - 2|3|4) # var_cpu, var_ram, var_disk (must be numbers) - if [[ "$LINE" =~ ^${EXPECTED_PREFIXES[$INDEX]}([0-9]+)$ ]]; then - continue # Valid - else - echo "Line $i was '$LINE' | Should be: '${EXPECTED_PREFIXES[$INDEX]}'" >> "$LOG_FILE" - fi - ;; - 5) # var_os (must be debian, alpine, or ubuntu) - if [[ "$LINE" =~ ^var_os=(debian|alpine|ubuntu)$ ]]; then - continue # Valid - else - echo "Line $i was '$LINE' | Should be: 'var_os=[debian|alpine|ubuntu]'" >> "$LOG_FILE" - fi - ;; - 7) # var_unprivileged (must be 0 or 1) - if [[ "$LINE" =~ ^var_unprivileged=[01]$ ]]; then - continue # Valid - else - echo "Line $i was '$LINE' | Should be: 'var_unprivileged=[0|1]'" >> "$LOG_FILE" - fi - ;; - *) # Other lines (must start with expected prefix) - if [[ "$LINE" == ${EXPECTED_PREFIXES[$INDEX]}* ]]; then - continue # Valid - else - echo "Line $i was '$LINE' | Should start with '${EXPECTED_PREFIXES[$INDEX]}'" >> "$LOG_FILE" - fi - ;; - esac - done - - for i in {16..20}; do - LINE=$(sed -n "${i}p" "$FILE") - EXPECTED=( - "header_info \"$APP\"" - "variables" - "color" - "catch_errors" - "function update_script() {" - ) - [[ "$LINE" != "${EXPECTED[$((i-16))]}" ]] && echo "Line $i was $LINE | Should be: ${EXPECTED[$((i-16))]}" >> "$LOG_FILE" - done - cat "$LOG_FILE" - elif [[ $FILE =~ ^install/.*-install\.sh$ ]]; then - - FIRST_LINE=$(sed -n '1p' "$FILE") - [[ "$FIRST_LINE" != "#!/usr/bin/env bash" ]] && echo "Line 1 was $FIRST_LINE | Should be: #!/usr/bin/env bash" >> "$LOG_FILE" - - SECOND_LINE=$(sed -n '2p' "$FILE") - [[ -n "$SECOND_LINE" ]] && echo "Line 2 should be empty" >> "$LOG_FILE" - - THIRD_LINE=$(sed -n '3p' "$FILE") - if ! [[ "$THIRD_LINE" =~ ^#\ Copyright\ \(c\)\ [0-9]{4}-[0-9]{4}\ community-scripts\ ORG$ || "$THIRD_LINE" =~ ^Copyright\ \(c\)\ [0-9]{4}-[0-9]{4}\ tteck$ ]]; then - echo "Line 3 was $THIRD_LINE | Should be: # Copyright (c) 2021-2025 community-scripts ORG" >> "$LOG_FILE" - fi - - EXPECTED_AUTHOR="# Author:" - EXPECTED_LICENSE="# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE" - EXPECTED_SOURCE="# Source:" - EXPECTED_EMPTY="" - - for i in {4..7}; do - LINE=$(sed -n "${i}p" "$FILE") - - case $i in - 4) - [[ $LINE == $EXPECTED_AUTHOR* ]] || printf "Line %d was: '%s' | Should start with: '%s'\n" "$i" "$LINE" "$EXPECTED_AUTHOR" >> $LOG_FILE - ;; - 5) - [[ "$LINE" == "$EXPECTED_LICENSE" ]] || printf "Line %d was: '%s' | Should be: '%s'\n" "$i" "$LINE" "$EXPECTED_LICENSE" >> $LOG_FILE - ;; - 6) - [[ $LINE == $EXPECTED_SOURCE* ]] || printf "Line %d was: '%s' | Should start with: '%s'\n" "$i" "$LINE" "$EXPECTED_SOURCE" >> $LOG_FILE - ;; - 7) - [[ -z $LINE ]] || printf "Line %d was: '%s' | Should be empty\n" "$i" "$LINE" >> $LOG_FILE - ;; - esac - done - - [[ "$(sed -n '8p' "$FILE")" != 'source /dev/stdin <<< "$FUNCTIONS_FILE_PATH"' ]] && echo 'Line 8 should be: source /dev/stdin <<< "$FUNCTIONS_FILE_PATH"' >> "$LOG_FILE" - - for i in {9..14}; do - LINE=$(sed -n "${i}p" "$FILE") - EXPECTED=( - "color" - "verb_ip6" - "catch_errors" - "setting_up_container" - "network_check" - "update_os" - ) - [[ "$LINE" != "${EXPECTED[$((i-9))]}" ]] && echo "Line $i was $LINE | Should be: ${EXPECTED[$((i-9))]}" >> "$LOG_FILE" - done - - [[ -n "$(sed -n '15p' "$FILE")" ]] && echo "Line 15 should be empty" >> "$LOG_FILE" - [[ "$(sed -n '16p' "$FILE")" != 'msg_info "Installing Dependencies"' ]] && echo 'Line 16 should be: msg_info "Installing Dependencies"' >> "$LOG_FILE" - - LAST_3_LINES=$(tail -n 3 "$FILE") - [[ "$LAST_3_LINES" != *"$STD apt-get -y autoremove"* ]] && echo 'Third to last line should be: $STD apt-get -y autoremove' >> "$LOG_FILE" - [[ "$LAST_3_LINES" != *"$STD apt-get -y autoclean"* ]] && echo 'Second to last line should be: $STD apt-get -y clean' >> "$LOG_FILE" - [[ "$LAST_3_LINES" != *'msg_ok "Cleaned"'* ]] && echo 'Last line should be: msg_ok "Cleaned"' >> "$LOG_FILE" - cat "$LOG_FILE" - fi - - done - - - - name: Post error comments - run: | - ERROR="false" - for FILE in ${{ env.SCRIPT }}; do - FILE_STRIPPED="${FILE##*/}" - LOG_FILE="result_$FILE_STRIPPED.log" - echo $LOG_FILE - if [[ ! -f $LOG_FILE ]]; then - continue - fi - ERROR_MSG=$(cat $LOG_FILE) - - if [ -n "$ERROR_MSG" ]; then - echo "Posting error message for $FILE" - echo ${ERROR_MSG} - gh pr comment ${{ github.event.pull_request.number }} \ - --repo ${{ github.repository }} \ - --body ":warning: The script _**$FILE**_ has the following formatting errors:
${ERROR_MSG}
" - - - ERROR="true" - fi - done - echo "ERROR=$ERROR" >> $GITHUB_ENV - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Fail if error - if: ${{ env.ERROR == 'true' }} - run: exit 1 diff --git a/.github/workflows/live/update-json-date.yml b/.github/workflows/live/update-json-date.yml deleted file mode 100644 index 1bf965a4..00000000 --- a/.github/workflows/live/update-json-date.yml +++ /dev/null @@ -1,133 +0,0 @@ -name: Update JSON Date - -on: - push: - branches: - - main - paths: - - 'json/**.json' - workflow_dispatch: - -jobs: - update-app-files: - runs-on: ubuntu-latest - - permissions: - contents: write - pull-requests: write - - steps: - - name: Generate a token - id: generate-token - uses: actions/create-github-app-token@v2 - with: - app-id: ${{ vars.APP_ID }} - private-key: ${{ secrets.APP_PRIVATE_KEY }} - owner: community-scripts - repositories: ProxmoxVED - - - name: Generate dynamic branch name - id: timestamp - run: echo "BRANCH_NAME=pr-update-json-$(date +'%Y%m%d%H%M%S')" >> $GITHUB_ENV - - - name: Set up GH_TOKEN - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - echo "GH_TOKEN=${GH_TOKEN}" >> $GITHUB_ENV - - - name: Checkout Repository - uses: actions/checkout@v4 - with: - fetch-depth: 2 # Ensure we have the last two commits - - - name: Get Previous Commit - id: prev_commit - run: | - PREV_COMMIT=$(git rev-parse HEAD^) - echo "Previous commit: $PREV_COMMIT" - echo "prev_commit=$PREV_COMMIT" >> $GITHUB_ENV - - - name: Get Newly Added JSON Files - id: new_json_files - run: | - git diff --name-only --diff-filter=A ${{ env.prev_commit }} HEAD | grep '^json/.*\.json$' > new_files.txt || true - echo "New files detected:" - cat new_files.txt || echo "No new files." - - - name: Disable file mode changes - run: git config core.fileMode false - - - name: Set up Git - run: | - git config --global user.name "GitHub Actions" - git config --global user.email "github-actions[bot]@users.noreply.github.com" - - - name: Change JSON Date - id: change-json-date - run: | - current_date=$(date +"%Y-%m-%d") - while IFS= read -r file; do - # Skip empty lines - [[ -z "$file" ]] && continue - - if [[ -f "$file" ]]; then - echo "Processing $file..." - current_json_date=$(jq -r '.date_created // empty' "$file") - if [[ -z "$current_json_date" || "$current_json_date" != "$current_date" ]]; then - echo "Updating $file with date $current_date" - jq --arg date "$current_date" '.date_created = $date' "$file" > temp.json && mv temp.json "$file" - else - echo "Date in $file is already up to date." - fi - else - echo "Warning: File $file not found!" - fi - done < new_files.txt - rm new_files.txt - - - name: Check if there are any changes - run: | - echo "Checking for changes..." - git add -A # Untracked Dateien aufnehmen - git status - if git diff --cached --quiet; then - echo "No changes detected." - echo "changed=false" >> "$GITHUB_ENV" - else - echo "Changes detected:" - git diff --stat --cached - echo "changed=true" >> "$GITHUB_ENV" - fi - - # Step 7: Commit and create PR if changes exist - - name: Commit and create PR if changes exist - if: env.changed == 'true' - run: | - - - git commit -m "Update date in json" - git checkout -b ${{ env.BRANCH_NAME }} - git push origin ${{ env.BRANCH_NAME }} - - gh pr create --title "[core] update date in json" \ - --body "This PR is auto-generated by a GitHub Action to update the date in json." \ - --head ${{ env.BRANCH_NAME }} \ - --base main \ - --label "automated pr" - env: - GH_TOKEN: ${{ steps.generate-token.outputs.token }} - - - name: Approve pull request - if: env.changed == 'true' - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - PR_NUMBER=$(gh pr list --head "${{ env.BRANCH_NAME }}" --json number --jq '.[].number') - if [ -n "$PR_NUMBER" ]; then - gh pr review $PR_NUMBER --approve - fi - - - name: No changes detected - if: env.changed == 'false' - run: echo "No changes to commit. Workflow completed successfully." diff --git a/.github/workflows/live/validate-filenames.yml b/.github/workflows/live/validate-filenames.yml deleted file mode 100644 index 16f2f710..00000000 --- a/.github/workflows/live/validate-filenames.yml +++ /dev/null @@ -1,161 +0,0 @@ -name: Validate filenames - -on: - pull_request_target: - paths: - - "ct/*.sh" - - "install/*.sh" - - "json/*.json" - -jobs: - check-files: - name: Check changed files - runs-on: ubuntu-latest - permissions: - pull-requests: write - - steps: - - name: Get pull request information - if: github.event_name == 'pull_request_target' - uses: actions/github-script@v7 - id: pr - with: - script: | - const { data: pullRequest } = await github.rest.pulls.get({ - ...context.repo, - pull_number: context.payload.pull_request.number, - }); - return pullRequest; - - - name: Checkout code - uses: actions/checkout@v4 - with: - fetch-depth: 0 # Ensure the full history is fetched for accurate diffing - ref: ${{ github.event_name == 'pull_request_target' && fromJSON(steps.pr.outputs.result).merge_commit_sha || '' }} - - - name: Get changed files - id: changed-files - run: | - if ${{ github.event_name == 'pull_request_target' }}; then - echo "files=$(git diff --name-only ${{ github.event.pull_request.base.sha }} ${{ steps.pr.outputs.result && fromJSON(steps.pr.outputs.result).merge_commit_sha }} | xargs)" >> $GITHUB_OUTPUT - else - echo "files=$(git diff --name-only ${{ github.event.before }} ${{ github.event.after }} | xargs)" >> $GITHUB_OUTPUT - fi - - - name: "Validate filenames in ct and install directory" - if: always() && steps.changed-files.outputs.files != '' - id: check-scripts - run: | - CHANGED_FILES=$(printf "%s\n" ${{ steps.changed-files.outputs.files }} | { grep -E '^(ct|install)/.*\.sh$' || true; }) - - NON_COMPLIANT_FILES="" - for FILE in $CHANGED_FILES; do - # Datei "misc/create_lxc.sh" explizit überspringen - if [[ "$FILE" == "misc/create_lxc.sh" ]]; then - continue - fi - BASENAME=$(echo "$(basename "${FILE%.*}")") - if [[ ! "$BASENAME" =~ ^[a-z0-9-]+$ ]]; then - NON_COMPLIANT_FILES="$NON_COMPLIANT_FILES $FILE" - fi - done - - if [ -n "$NON_COMPLIANT_FILES" ]; then - echo "files=$NON_COMPLIANT_FILES" >> $GITHUB_OUTPUT - echo "Non-compliant filenames found, change to lowercase:" - for FILE in $NON_COMPLIANT_FILES; do - echo "$FILE" - done - exit 1 - fi - - - name: "Validate filenames in json directory." - if: always() && steps.changed-files.outputs.files != '' - id: check-json - run: | - CHANGED_FILES=$(printf "%s\n" ${{ steps.changed-files.outputs.files }} | { grep -E '^json/.*\.json$' || true; }) - - NON_COMPLIANT_FILES="" - for FILE in $CHANGED_FILES; do - BASENAME=$(echo "$(basename "${FILE%.*}")") - if [[ ! "$BASENAME" =~ ^[a-z0-9-]+$ ]]; then - NON_COMPLIANT_FILES="$NON_COMPLIANT_FILES $FILE" - fi - done - - if [ -n "$NON_COMPLIANT_FILES" ]; then - echo "files=$NON_COMPLIANT_FILES" >> $GITHUB_OUTPUT - echo "Non-compliant filenames found, change to lowercase:" - for FILE in $NON_COMPLIANT_FILES; do - echo "$FILE" - done - exit 1 - fi - - - name: Post results and comment - if: always() && steps.check-scripts.outputs.files != '' && steps.check-json.outputs.files != '' && github.event_name == 'pull_request_target' - uses: actions/github-script@v7 - with: - script: | - const result = "${{ job.status }}" === "success" ? "success" : "failure"; - const nonCompliantFiles = { - script: "${{ steps.check-scripts.outputs.files }}", - JSON: "${{ steps.check-json.outputs.files }}", - }; - - const issueNumber = context.payload.pull_request - ? context.payload.pull_request.number - : null; - const commentIdentifier = "validate-filenames"; - let newCommentBody = `\n### Filename validation\n\n`; - - if (result === "failure") { - newCommentBody += ":x: We found issues in the following changed files:\n\n"; - for (const [check, files] of Object.entries(nonCompliantFiles)) { - if (files) { - newCommentBody += `**${check.charAt(0).toUpperCase() + check.slice(1)} filename invalid:**\n${files - .trim() - .split(" ") - .map((file) => `- ${file}`) - .join("\n")}\n\n`; - } - } - newCommentBody += - "Please change the filenames to lowercase and use only alphanumeric characters and dashes.\n"; - } else { - newCommentBody += `:rocket: All files passed filename validation!\n`; - } - - newCommentBody += `\n\n`; - - if (issueNumber) { - const { data: comments } = await github.rest.issues.listComments({ - ...context.repo, - issue_number: issueNumber, - }); - - const existingComment = comments.find( - (comment) => comment.user.login === "github-actions[bot]", - ); - - if (existingComment) { - if (existingComment.body.includes(commentIdentifier)) { - const re = new RegExp(String.raw`[\s\S]*?`, ""); - newCommentBody = existingComment.body.replace(re, newCommentBody); - } else { - newCommentBody = existingComment.body + '\n\n---\n\n' + newCommentBody; - } - - await github.rest.issues.updateComment({ - ...context.repo, - comment_id: existingComment.id, - body: newCommentBody, - }); - } else { - await github.rest.issues.createComment({ - ...context.repo, - issue_number: issueNumber, - body: newCommentBody, - }); - } - }