134 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			YAML
		
	
	
	
	
	
			
		
		
	
	
			134 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			YAML
		
	
	
	
	
	
| 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 = `<!-- ${commentIdentifier}-start -->\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<!-- ${commentIdentifier}-end -->`;
 | |
| 
 | |
|             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`<!-- ${commentIdentifier}-start -->[\s\S]*?<!-- ${commentIdentifier}-end -->`,
 | |
|                     "",
 | |
|                   );
 | |
|                   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,
 | |
|                 });
 | |
|               }
 | |
|             }
 | 
