From 452e16083fd6f76747d4c7de8519ff6eee5106f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mislav=20Marohni=C4=87?= Date: Thu, 24 Oct 2024 11:36:50 +0200 Subject: [PATCH] Add "actions" format to create GitHub annotations Prior to this, specific violations that shellcheck reports are logged in its output, but are not picked up by GitHub in any special way. The new "actions" format will output shellcheck errors, warnings, and notices using respective GitHub "workflow commands" that become annotations in GitHub's Pull Requests view and elsewhere. This helps navigating shellcheck results in GitHub UI. This is an alternative approach to defining GitHub problem matchers for shellcheck output. --- README.md | 7 ++++--- action.yaml | 35 ++++++++++++++++++++++++++++++----- 2 files changed, 34 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index f1aa462..8ab13ca 100644 --- a/README.md +++ b/README.md @@ -142,10 +142,11 @@ If you need to scan for unusual files, you can use the `additional_files` key. ## Change output format -Shellcheck can print output in these formats: `checkstyle`, `diff`, `gcc`, `json`, `json1`, `quiet`, `tty`. See some examples [here](https://github.com/koalaman/shellcheck/wiki/Integration#pick-the-output-format-that-makes-your-life-easier). +Shellcheck can print output [in these formats](https://github.com/koalaman/shellcheck/wiki/Integration): `checkstyle`, `diff`, `gcc`, `json`, `json1`, `quiet`, `tty`. The special output format `actions` will reformat Shellcheck output to appear as _annotations_ in the GitHub UI. -- `tty` has multi-line log messages -- `gcc` has single-line log messages +- `gcc` has single-line log messages (default) +- `tty` has multi-line log messages and color output +- `actions` integrates shellcheck errors into GitHub Pull Requests view ```yaml ... diff --git a/action.yaml b/action.yaml index 130781e..0c943d4 100644 --- a/action.yaml +++ b/action.yaml @@ -37,7 +37,7 @@ inputs: default: "false" deprecationMessage: "There are no problem-matchers, this setting does not do anything." format: - description: "Output format (checkstyle, diff, gcc, json, json1, quiet, tty)" + description: "Output format (checkstyle, diff, gcc, json, json1, quiet, tty, actions)" required: false default: "gcc" version: @@ -91,9 +91,15 @@ runs: run: | declare -a options if [[ -n "${INPUT_SEVERITY}" ]]; then - options+=("-S ${INPUT_SEVERITY}") + options+=(-S "${INPUT_SEVERITY}") + fi + if [ "${INPUT_FORMAT}" = "actions" ]; then + options+=(--format=json1) + elif [ "${INPUT_FORMAT}" = "tty" ]; then + options+=(--format=tty --color=always) + else + options+=(--format="${INPUT_FORMAT}") fi - options+=("--format=${INPUT_FORMAT}") echo "options=${options[@]}" >> $GITHUB_OUTPUT - name: Gather excluded paths @@ -152,6 +158,7 @@ runs: INPUT_EXCLUDE_ARGS: ${{ steps.exclude.outputs.excludes }} INPUT_ADDITIONAL_FILE_ARGS: ${{ steps.additional.outputs.files }} INPUT_SHELLCHECK_OPTIONS: ${{ steps.options.outputs.options }} + INPUT_FORMAT: ${{ inputs.format }} run: | statuscode=0 declare -a filepaths @@ -203,15 +210,33 @@ runs: -type f ! -name '*.*' -perm /111 \ -print0) + # Reformats shellcheck "json1" output as GitHub Actions workflow commands + reformat() { + if [ "${INPUT_FORMAT}" = "actions" ]; then + jq -r ' + def workflow_command: + if . == "note" or . == "info" or . == "style" + then "notice" + else . # error, warning + end; + .comments[] | + "::\(.level | workflow_command) file=\(.file),line=\(.line),endLine=\(.endLine),col=\(.column),endColumn=\(.endColumn)::\(.message) [SC\(.code)]" + ' + else + cat + fi + } + + set -o pipefail if [[ -n "${INPUT_CHECK_TOGETHER}" ]]; then "${{ github.action_path }}/shellcheck" \ ${INPUT_SHELLCHECK_OPTIONS} \ - "${filepaths[@]}" || statuscode=$? + "${filepaths[@]}" | reformat || statuscode=$? else for file in "${filepaths[@]}"; do "${{ github.action_path }}/shellcheck" \ ${INPUT_SHELLCHECK_OPTIONS} \ - "$file" || statuscode=$? + "$file" | reformat || statuscode=$? done fi