diff --git a/.github/autolabeler-config.json b/.github/autolabeler-config.json deleted file mode 100644 index 4485d62c9..000000000 --- a/.github/autolabeler-config.json +++ /dev/null @@ -1,64 +0,0 @@ - -{ - "breaking change": [ - { - "fileStatus": "renamed", - "includeGlobs": ["ct/**", "install/**", "misc/**", "turnkey/**", "vm/**"], - "excludeGlobs": [] - }, - { - "fileStatus": "removed", - "includeGlobs": ["ct/**", "install/**", "misc/**", "turnkey/**", "vm/**"], - "excludeGlobs": [] - } - ], - "new script": [ - { - "fileStatus": "added", - "includeGlobs": ["ct/**", "install/**", "misc/**", "turnkey/**", "vm/**"], - "excludeGlobs": [] - } - ], - "update script": [ - { - "fileStatus": "modified", - "includeGlobs": ["ct/**", "install/**", "misc/**", "turnkey/**", "vm/**"], - "excludeGlobs": ["misc/build.func", "misc/install.func"] - } - ], - "delete script": [ - { - "fileStatus": "removed", - "includeGlobs": ["ct/**", "install/**", "misc/**", "turnkey/**", "vm/**"], - "excludeGlobs": [] - } - ], - "rename script": [ - { - "fileStatus": "renamed", - "includeGlobs": ["ct/**", "install/**", "misc/**", "turnkey/**", "vm/**"], - "excludeGlobs": [] - } - ], - "website": [ - { - "fileStatus": null, - "includeGlobs": ["frontend/**", "json/**"], - "excludeGlobs": [] - } - ], - "maintenance": [ - { - "fileStatus": null, - "includeGlobs": ["*.md", ".github/**"], - "excludeGlobs": [] - } - ], - "high risk": [ - { - "fileStatus": null, - "includeGlobs": ["misc/build.func", "misc/install.func"], - "excludeGlobs": [] - } - ] -} \ No newline at end of file diff --git a/.github/changelog-pr-config.json b/.github/changelog-pr-config.json deleted file mode 100644 index 5da6b306a..000000000 --- a/.github/changelog-pr-config.json +++ /dev/null @@ -1,30 +0,0 @@ -[ - { - "title": "💥 Breaking Changes", - "labels": ["breaking change"] - }, - { - "title": "✨ New Scripts", - "labels": ["new script"] - }, - { - "title": "🚀 Updated Scripts", - "labels": ["update script"] - }, - { - "title": "🌐 Website", - "labels": ["website"] - }, - { - "title": "🐞 Bug Fixes", - "labels": ["bug fix"] - }, - { - "title": "🧰 Maintenance", - "labels": ["maintenance"] - }, - { - "title": "❔ Unlabelled", - "labels": [] - } -] diff --git a/.github/workflows/autolabeler.yml b/.github/workflows/autolabeler.yml deleted file mode 100644 index 660135f5c..000000000 --- a/.github/workflows/autolabeler.yml +++ /dev/null @@ -1,62 +0,0 @@ -name: Auto Label Pull Requests - -on: - pull_request_target: - branches: ["main"] - types: [opened, synchronize, reopened, edited] - -jobs: - autolabeler: - runs-on: ubuntu-latest - permissions: - pull-requests: write - 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 prNumber = context.payload.pull_request.number; - const prListFilesResponse = await github.rest.pulls.listFiles({ - owner: context.repo.owner, - repo: context.repo.repo, - pull_number: prNumber, - }); - const prFiles = prListFilesResponse.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; - }); - }); - - 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], - }); - } - } diff --git a/.github/workflows/changelog-pr.yml b/.github/workflows/changelog-pr.yml deleted file mode 100644 index ad4e2c587..000000000 --- a/.github/workflows/changelog-pr.yml +++ /dev/null @@ -1,169 +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@v1 - with: - app-id: ${{ vars.APP_ID }} - private-key: ${{ secrets.APP_PRIVATE_KEY }} - - - name: Checkout code - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Get latest dates 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') - 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: [] })); - - 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 - ).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; - const prShouldBeExcluded = prLabels.includes(process.env.AUTOMATED_PR_LABEL); - if ((prHasCategoryLabel || isUnlabelledCategory) && !prShouldBeExcluded) { - notes.push(prNote); - break; - } - }; - }); - - 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 }}; - - let newReleaseNotes = `## ${today}\n\n### Changed\n\n`; - for (const { title, notes } of categorizedPRs) { - if (notes.length > 0) { - newReleaseNotes += `### ${title}\n\n${notes.join("\n")}\n\n`; - } - } - - 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"); - - const newChangelogContent = changelogContent.replace(regex, newReleaseNotes) - await fs.writeFile(changelogPath, newChangelogContent); - - - name: Check if there are any changes - id: verify-diff - run: | - git diff --quiet . || echo "changed=true" >> $GITHUB_OUTPUT - - - name: Commit and push changes to separate branch - if: steps.verify-diff.outputs.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: steps.verify-diff.outputs.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: steps.verify-diff.outputs.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: steps.verify-diff.outputs.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/github-release.yml b/.github/workflows/github-release.yml deleted file mode 100644 index eba622ff9..000000000 --- a/.github/workflows/github-release.yml +++ /dev/null @@ -1,25 +0,0 @@ -name: Create new release - -on: - schedule: - # Runs "At 00:01 every night" (UTC) - - cron: '1 0 * * *' - -jobs: - create-new-release: - runs-on: ubuntu-latest - permissions: - contents: write - steps: - - name: Checkout code - uses: actions/checkout@v4 - - name: Parse CHANGELOG.md for yesterday's entries and create a new release - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - YESTERDAY=$(date -u --date="yesterday" +%Y-%m-%d) - YESTERDAY_CHANGELOG_NOTES=$(awk '/^## '"$YESTERDAY"'/ {f=1; next} f && /^## [0-9]{4}-[0-9]{2}-[0-9]{2}/ {f=0} f && !/^## / {print}' CHANGELOG.md) - - if [ -n "$YESTERDAY_CHANGELOG_NOTES" ]; then - gh release create "$YESTERDAY" -t "$YESTERDAY" -n "$YESTERDAY_CHANGELOG_NOTES" --latest - fi diff --git a/.github/workflows/shellcheck.yml b/.github/workflows/shellcheck.yml deleted file mode 100644 index 394229e6f..000000000 --- a/.github/workflows/shellcheck.yml +++ /dev/null @@ -1,32 +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: changes - run: | - if ${{ github.event_name == 'pull_request' }}; then - echo "files=$(git diff --name-only -r HEAD^1 HEAD | xargs)" >> $GITHUB_OUTPUT - else - echo "files=$(git diff --name-only ${{ github.event.before }} ${{ github.event.after }} | xargs)" >> $GITHUB_OUTPUT - fi - - - name: Run ShellCheck - if: steps.changes.outputs.files != '' - run: | - echo "${{ steps.changes.outputs.files }}" | xargs shellcheck diff --git a/.github/workflows/validate-filenames.yml b/.github/workflows/validate-filenames.yml deleted file mode 100644 index 909c669de..000000000 --- a/.github/workflows/validate-filenames.yml +++ /dev/null @@ -1,157 +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 - 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, - }); - } - } diff --git a/.github/workflows/validate-formatting.yaml b/.github/workflows/validate-formatting.yaml deleted file mode 100644 index 220563976..000000000 --- a/.github/workflows/validate-formatting.yaml +++ /dev/null @@ -1,130 +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/validate-scripts.yml b/.github/workflows/validate-scripts.yml deleted file mode 100644 index 6b71df1c4..000000000 --- a/.github/workflows/validate-scripts.yml +++ /dev/null @@ -1,226 +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: 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 }} | 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/asylumexp/Proxmox/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|asylumexp| asylumexp | asylumexp|asylumexp )$"; 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/asylumexp/Proxmox/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(' ').map(file => `- ${file}`).join('\n')}\n\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.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/install/snipeit-install.sh b/install/snipeit-install.sh deleted file mode 100644 index eca891c5d..000000000 --- a/install/snipeit-install.sh +++ /dev/null @@ -1,108 +0,0 @@ -#!/usr/bin/env bash -#Copyright (c) 2021-2025 community-scripts ORG -# Author: tteck (tteckster) -# License: MIT -# https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE - - -source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" -color -verb_ip6 -catch_errors -setting_up_container -network_check -update_os - -msg_info "Installing Dependencies" -$STD apt-get install -y \ - curl \ - composer \ - git \ - sudo \ - mc \ - nginx \ - php8.2-{bcmath,common,ctype,curl,fileinfo,fpm,gd,iconv,intl,mbstring,mysql,soap,xml,xsl,zip,cli} \ - mariadb-server \ - wget \ - openssh-server -msg_ok "Installed Dependencies" - -msg_info "Setting up database" -DB_NAME=snipeit_db -DB_USER=snipeit -DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13) -mysql -u root -e "CREATE DATABASE $DB_NAME;" -mysql -u root -e "CREATE USER '$DB_USER'@'localhost' IDENTIFIED WITH mysql_native_password AS PASSWORD('$DB_PASS');" -mysql -u root -e "GRANT ALL ON $DB_NAME.* TO '$DB_USER'@'localhost'; FLUSH PRIVILEGES;" -{ - echo "SnipeIT-Credentials" - echo "SnipeIT Database User: $DB_USER" - echo "SnipeIT Database Password: $DB_PASS" - echo "SnipeIT Database Name: $DB_NAME" -} >> ~/snipeit.creds -msg_ok "Set up database" - -msg_info "Installing Snipe-IT" -cd /opt -RELEASE=$(curl -s https://api.github.com/repos/snipe/snipe-it/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') -echo "${RELEASE}" >"/opt/${APPLICATION}_version.txt" -wget -q "https://github.com/snipe/snipe-it/archive/refs/tags/v${RELEASE}.zip" -unzip -q v${RELEASE}.zip -mv snipe-it-${RELEASE} /opt/snipe-it - -cd /opt/snipe-it -cp .env.example .env -IPADDRESS=$(hostname -I | awk '{print $1}') - -sed -i -e "s|^APP_URL=.*|APP_URL=http://$IPADDRESS|" \ - -e "s|^DB_DATABASE=.*|DB_DATABASE=$DB_NAME|" \ - -e "s|^DB_USERNAME=.*|DB_USERNAME=$DB_USER|" \ - -e "s|^DB_PASSWORD=.*|DB_PASSWORD=$DB_PASS|" .env - -chown -R www-data: /opt/snipe-it -chmod -R 755 /opt/snipe-it - - -export COMPOSER_ALLOW_SUPERUSER=1 -$STD composer update --no-plugins --no-scripts -$STD composer install --no-dev --prefer-source --no-plugins --no-scripts - -$STD php artisan key:generate --force -msg_ok "Installed SnipeIT" - -msg_info "Creating Service" - -cat </etc/nginx/conf.d/snipeit.conf -server { - listen 80; - root /opt/snipe-it/public; - server_name $IPADDRESS; - index index.php; - - location / { - try_files \$uri \$uri/ /index.php?\$query_string; - } - - location ~ \.php\$ { - include fastcgi.conf; - include snippets/fastcgi-php.conf; - fastcgi_pass unix:/run/php/php8.2-fpm.sock; - fastcgi_split_path_info ^(.+\.php)(/.+)\$; - fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name; - include fastcgi_params; - } -} -EOF - -systemctl reload nginx -msg_ok "Configured Service" - - -motd_ssh -customize - -msg_info "Cleaning up" -rm -rf /opt/v${RELEASE}.zip -$STD apt-get -y autoremove -$STD apt-get -y autoclean -msg_ok "Cleaned"