diff --git a/.github/workflows/check-lowercase.yml b/.github/workflows/check-lowercase.yml deleted file mode 100644 index b570204b..00000000 --- a/.github/workflows/check-lowercase.yml +++ /dev/null @@ -1,92 +0,0 @@ -name: Check Lowercase Filenames - -on: - pull_request: - paths: - - 'ct/*.sh' - - 'install/*.sh' - - 'json/*.json' - -jobs: - check_lowercase: - runs-on: ubuntu-latest - - steps: - # Step 1: Checkout the code - - name: Checkout code - uses: actions/checkout@v4 - with: - fetch-depth: 0 # Ensure the full history is fetched for accurate diffing - - # Step 2: Fetch the base branch - - name: Fetch base branch - run: git fetch origin ${{ github.base_ref }} - - # Step 3a: Validate filenames in ct directory - - name: "Validate filenames in ct directory" - run: | - changed_files=$(git diff --name-only origin/${{ github.base_ref }}...HEAD | grep -E '^ct/.*\.sh$') - - ERROR_COUNT=0 - - for FILE in $changed_files; do - BASENAME=$(basename "$FILE") - if [[ "$BASENAME" =~ ^[a-z0-9._-]+$ ]]; then - echo "$FILE: Check for lowercase in filename passed." - else - echo "Error in $FILE. Change filename to lowercase." - ERROR_COUNT=$((ERROR_COUNT + 1)) - fi - done - - if [ "$ERROR_COUNT" -ne 0 ]; then - exit 1 - else - echo "All filenames in ct directory passed the lowercase check." - fi - - # Step 3b: Validate filenames in install directory - - name: "Validate filenames in install directory" - run: | - changed_files=$(git diff --name-only origin/${{ github.base_ref }}...HEAD | grep -E '^install/.*\.sh$') - - ERROR_COUNT=0 - - for FILE in $changed_files; do - BASENAME=$(basename "$FILE") - if [[ "$BASENAME" =~ ^[a-z0-9._-]+$ ]]; then - echo "$FILE: Check for lowercase in filename passed." - else - echo "Error in $FILE. Change filename to lowercase." - ERROR_COUNT=$((ERROR_COUNT + 1)) - fi - done - - if [ "$ERROR_COUNT" -ne 0 ]; then - exit 1 - else - echo "All filenames in install directory passed the lowercase check." - fi - - # Step 3c: Validate filenames in json directory - - name: "Validate filenames in json directory." - run: | - changed_files=$(git diff --name-only origin/${{ github.base_ref }}...HEAD | grep -E '^json/.*\.json$') - - ERROR_COUNT=0 - - for FILE in $changed_files; do - BASENAME=$(basename "$FILE") - if [[ "$BASENAME" =~ ^[a-z0-9._-]+$ ]]; then - echo "$FILE: Check for lowercase in filename passed." - else - echo "Error in $FILE. Change filename to lowercase." - ERROR_COUNT=$((ERROR_COUNT + 1)) - fi - done - - if [ "$ERROR_COUNT" -ne 0 ]; then - exit 1 - else - echo "All filenames in json directory passed the lowercase check." - fi diff --git a/.github/workflows/validate-filenames.yml b/.github/workflows/validate-filenames.yml new file mode 100644 index 00000000..704715f5 --- /dev/null +++ b/.github/workflows/validate-filenames.yml @@ -0,0 +1,143 @@ +name: Validate filenames + +on: + pull_request: + paths: + - "ct/*.sh" + - "install/*.sh" + - "json/*.json" + - ".github/workflows/validate-filenames.yml" + +jobs: + check-files: + name: Check changed files + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 # Ensure the full history is fetched for accurate diffing + + - name: Get changed files + id: changed-files + run: | + if ${{ github.event_name == 'pull_request' }}; then + echo "files=$(git diff --name-only ${{ github.event.pull_request.base.sha }} ${{ github.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' + 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, + }); + } + }