├── testdata ├── non-sh-test └── test.sh ├── .github ├── renovate.json └── workflows │ ├── update_semver.yml │ ├── depup.yml │ ├── reviewdog.yml │ └── release.yml ├── .gitattributes ├── LICENSE ├── action.yml ├── script.sh └── README.md /testdata/non-sh-test: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ksh 2 | # shellcheck enable=all 3 | 4 | echo "${1}" 5 | -------------------------------------------------------------------------------- /.github/renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "config:base" 4 | ], 5 | "rangeStrategy": "replace" 6 | } 7 | -------------------------------------------------------------------------------- /testdata/test.sh: -------------------------------------------------------------------------------- 1 | echo $1 # Unquoted variables 2 | find . -name *.ogg # Unquoted find/grep patterns 3 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Denote files that are shell scripts and should be normalized (convert crlf -> lf) 2 | # and should be converted to unix line endings on checkout. 3 | *.sh text eol=lf 4 | non-sh-test text eol=lf 5 | -------------------------------------------------------------------------------- /.github/workflows/update_semver.yml: -------------------------------------------------------------------------------- 1 | name: Update Semver 2 | on: 3 | push: 4 | branches-ignore: 5 | - '**' 6 | tags: 7 | - 'v*.*.*' 8 | jobs: 9 | update-semver: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 13 | - uses: haya14busa/action-update-semver@22a3666f9309f0d72ab0ea6c49b7a8019c1eab38 # v1.3.0 14 | with: 15 | github_token: ${{ secrets.github_token }} 16 | -------------------------------------------------------------------------------- /.github/workflows/depup.yml: -------------------------------------------------------------------------------- 1 | name: depup 2 | on: 3 | schedule: 4 | - cron: '14 14 * * *' # Runs at 14:14 UTC every day 5 | repository_dispatch: 6 | types: [depup] 7 | workflow_dispatch: 8 | 9 | jobs: 10 | reviewdog: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 14 | - uses: reviewdog/action-depup/with-pr@94a1aaf4e4923064019214b48a43276218af7ad5 # v1.6.4 15 | with: 16 | file: action.yml 17 | version_name: reviewdog_version 18 | repo: reviewdog/reviewdog 19 | labels: "bump:minor" 20 | 21 | shellcheck: 22 | runs-on: ubuntu-latest 23 | steps: 24 | - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 25 | - uses: reviewdog/action-depup/with-pr@94a1aaf4e4923064019214b48a43276218af7ad5 # v1.6.4 26 | with: 27 | file: action.yml 28 | version_name: SHELLCHECK_VERSION 29 | repo: koalaman/shellcheck 30 | labels: "bump:minor" 31 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 haya14busa 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /.github/workflows/reviewdog.yml: -------------------------------------------------------------------------------- 1 | name: reviewdog 2 | on: [pull_request] 3 | jobs: 4 | shellcheck: 5 | name: runner / shellcheck 6 | runs-on: ${{ matrix.os }} 7 | strategy: 8 | matrix: 9 | os: [ubuntu-latest, macos-latest, windows-latest] 10 | steps: 11 | - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 12 | - name: shellcheck-github-pr-check 13 | uses: ./ 14 | with: 15 | github_token: ${{ secrets.github_token }} 16 | - name: shellcheck-github-check 17 | uses: ./ 18 | with: 19 | github_token: ${{ secrets.github_token }} 20 | reporter: github-check 21 | level: warning 22 | filter_mode: file 23 | pattern: '*.sh' 24 | path: '.' 25 | exclude: './testdata/*' 26 | shellcheck_flags: '--external-sources --severity=style' 27 | - name: shellcheck-github-pr-review 28 | uses: ./ 29 | with: 30 | github_token: ${{ secrets.github_token }} 31 | reporter: github-pr-review 32 | pattern: '*.sh' 33 | path: '.' 34 | exclude: './testdata/*' 35 | - name: shellcheck-shebang-check 36 | uses: ./ 37 | with: 38 | github_token: ${{ secrets.github_token }} 39 | filter_mode: nofilter 40 | pattern: | 41 | *.sh 42 | path: | 43 | . 44 | ./testdata 45 | exclude: | 46 | ./testdata/test.sh 47 | */.git/* 48 | check_all_files_with_shebangs: true 49 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: release 2 | on: 3 | push: 4 | branches: 5 | - master 6 | tags: 7 | - 'v*.*.*' 8 | pull_request: 9 | types: 10 | - labeled 11 | 12 | jobs: 13 | release: 14 | if: github.event.action != 'labeled' 15 | runs-on: ubuntu-latest 16 | steps: 17 | - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 18 | 19 | # Bump version on merging Pull Requests with specific labels. 20 | # (bump:major,bump:minor,bump:patch) 21 | - id: bumpr 22 | if: "!startsWith(github.ref, 'refs/tags/')" 23 | uses: haya14busa/action-bumpr@faf6f474bcb6174125cfc569f0b2e24cbf03d496 # v1.11.4 24 | 25 | # Update corresponding major and minor tag. 26 | # e.g. Update v1 and v1.2 when releasing v1.2.3 27 | - uses: haya14busa/action-update-semver@22a3666f9309f0d72ab0ea6c49b7a8019c1eab38 # v1.3.0 28 | if: "!steps.bumpr.outputs.skip" 29 | with: 30 | tag: ${{ steps.bumpr.outputs.next_version }} 31 | 32 | # Get tag name. 33 | - id: tag 34 | uses: haya14busa/action-cond@94f77f7a80cd666cb3155084e428254fea4281fd # v1.2.1 35 | with: 36 | cond: "${{ startsWith(github.ref, 'refs/tags/') }}" 37 | if_true: ${{ github.ref }} 38 | if_false: ${{ steps.bumpr.outputs.next_version }} 39 | 40 | # Create release 41 | - if: "steps.tag.outputs.value != ''" 42 | env: 43 | TAG_NAME: ${{ steps.tag.outputs.value }} 44 | CURRENT: ${{ steps.bumpr.outputs.current_version }} 45 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 46 | run: | 47 | gh release create "${TAG_NAME}" -t "Release ${TAG_NAME/refs\/tags\//}" --generate-notes --notes-start-tag "${CURRENT}" 48 | 49 | release-check: 50 | if: github.event.action == 'labeled' 51 | runs-on: ubuntu-latest 52 | steps: 53 | - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 54 | - name: Post bumpr status comment 55 | uses: haya14busa/action-bumpr@faf6f474bcb6174125cfc569f0b2e24cbf03d496 # v1.11.4 56 | -------------------------------------------------------------------------------- /action.yml: -------------------------------------------------------------------------------- 1 | name: 'Run shellcheck with reviewdog' 2 | description: '🐶 Run shellcheck with reviewdog on pull requests to improve code review experience.' 3 | author: 'haya14busa (reviewdog)' 4 | inputs: 5 | github_token: 6 | description: 'GITHUB_TOKEN.' 7 | default: '${{ github.token }}' 8 | required: false 9 | level: 10 | description: 'Report level for reviewdog [info,warning,error]' 11 | default: 'error' 12 | required: false 13 | reporter: 14 | description: | 15 | Reporter of reviewdog command [github-pr-check,github-pr-review,github-check]. 16 | Default is github-pr-check. 17 | github-pr-review can use Markdown and add a link to rule page in reviewdog reports. 18 | default: 'github-pr-check' 19 | required: false 20 | filter_mode: 21 | description: | 22 | Filtering mode for the reviewdog command [added,diff_context,file,nofilter]. 23 | Default is `file`. 24 | default: 'file' 25 | required: false 26 | fail_level: 27 | description: | 28 | If set to `none`, always use exit code 0 for reviewdog. 29 | Otherwise, exit code 1 for reviewdog if it finds at least 1 issue with severity greater than or equal to the given level. 30 | Possible values: [none,any,info,warning,error] 31 | Default is `none`. 32 | default: 'none' 33 | fail_on_error: 34 | description: | 35 | Deprecated, use `fail_level` instead. 36 | Exit code for reviewdog when errors are found [true,false] 37 | Default is `false`. 38 | deprecationMessage: Deprecated, use `fail_level` instead. 39 | default: 'false' 40 | required: false 41 | reviewdog_flags: 42 | description: 'Additional reviewdog flags' 43 | default: '' 44 | required: false 45 | path: 46 | description: "Base directory to run shellcheck. Same as `[path]` of `find` command." 47 | default: '.' 48 | required: false 49 | pattern: 50 | description: "File patterns of target files. Same as `-name [pattern]` of `find` command." 51 | default: '*.sh' 52 | required: false 53 | check_all_files_with_shebangs: 54 | description: | 55 | Checks all files with shebangs in the repository even if they do not match the pattern. 56 | Default is `false`. 57 | default: 'false' 58 | required: false 59 | exclude: 60 | description: "Exclude patterns of target files. Same as `-not -path [exclude]` of `find` command." 61 | default: '*/.git/*' 62 | required: false 63 | shellcheck_flags: 64 | description: "Flags of shellcheck command." 65 | default: '--external-sources' 66 | required: false 67 | runs: 68 | using: "composite" 69 | steps: 70 | - uses: reviewdog/action-setup@d8edfce3dd5e1ec6978745e801f9c50b5ef80252 # v1.4.0 71 | with: 72 | reviewdog_version: v0.21.0 73 | - run: $GITHUB_ACTION_PATH/script.sh 74 | shell: bash 75 | env: 76 | SHELLCHECK_VERSION: 0.11.0 77 | # INPUT_ is not available in Composite run steps 78 | # https://github.community/t/input-variable-name-is-not-available-in-composite-run-steps/127611 79 | INPUT_GITHUB_TOKEN: ${{ inputs.github_token }} 80 | INPUT_LEVEL: ${{ inputs.level }} 81 | INPUT_REPORTER: ${{ inputs.reporter }} 82 | INPUT_FILTER_MODE: ${{ inputs.filter_mode }} 83 | INPUT_FAIL_LEVEL: ${{ inputs.fail_level }} 84 | INPUT_FAIL_ON_ERROR: ${{ inputs.fail_on_error }} 85 | INPUT_REVIEWDOG_FLAGS: ${{ inputs.reviewdog_flags }} 86 | INPUT_PATH: ${{ inputs.path }} 87 | INPUT_PATTERN: ${{ inputs.pattern }} 88 | INPUT_EXCLUDE: ${{ inputs.exclude }} 89 | INPUT_CHECK_ALL_FILES_WITH_SHEBANGS: ${{ inputs.check_all_files_with_shebangs }} 90 | INPUT_SHELLCHECK_FLAGS: ${{ inputs.shellcheck_flags }} 91 | 92 | branding: 93 | icon: 'zoom-in' 94 | color: 'purple' 95 | -------------------------------------------------------------------------------- /script.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -u 4 | 5 | echo '::group:: Installing shellcheck ... https://github.com/koalaman/shellcheck' 6 | TEMP_PATH="$(mktemp -d)" 7 | cd "${TEMP_PATH}" || exit 8 | mkdir bin 9 | 10 | WINDOWS_TARGET=zip 11 | 12 | # Get system architecture 13 | ARCH=$(uname -m) 14 | if [[ "${ARCH}" == "arm64" || "${ARCH}" == "aarch64" ]]; then 15 | CPU_ARCH="aarch64" 16 | else 17 | CPU_ARCH="x86_64" 18 | fi 19 | 20 | # Set targets based on OS and architecture 21 | if [[ $(uname -s) == "Linux" ]]; then 22 | LINUX_TARGET="linux.${CPU_ARCH}.tar.xz" 23 | curl -sL "https://github.com/koalaman/shellcheck/releases/download/v${SHELLCHECK_VERSION}/shellcheck-v${SHELLCHECK_VERSION}.${LINUX_TARGET}" | tar -xJf - 24 | cp "shellcheck-v$SHELLCHECK_VERSION/shellcheck" ./bin 25 | elif [[ $(uname -s) == "Darwin" ]]; then 26 | MACOS_TARGET="darwin.${CPU_ARCH}.tar.xz" 27 | curl -sL "https://github.com/koalaman/shellcheck/releases/download/v${SHELLCHECK_VERSION}/shellcheck-v${SHELLCHECK_VERSION}.${MACOS_TARGET}" | tar -xJf - 28 | cp "shellcheck-v$SHELLCHECK_VERSION/shellcheck" ./bin 29 | else 30 | curl -sL "https://github.com/koalaman/shellcheck/releases/download/v${SHELLCHECK_VERSION}/shellcheck-v${SHELLCHECK_VERSION}.${WINDOWS_TARGET}" -o "shellcheck-v${SHELLCHECK_VERSION}.${WINDOWS_TARGET}" && unzip "shellcheck-v${SHELLCHECK_VERSION}.${WINDOWS_TARGET}" && rm "shellcheck-v${SHELLCHECK_VERSION}.${WINDOWS_TARGET}" 31 | cp "shellcheck.exe" ./bin 32 | fi 33 | 34 | PATH="${TEMP_PATH}/bin:$PATH" 35 | shellcheck --version 36 | echo '::endgroup::' 37 | 38 | cd "${GITHUB_WORKSPACE}" || exit 39 | 40 | export REVIEWDOG_GITHUB_API_TOKEN="${INPUT_GITHUB_TOKEN}" 41 | 42 | paths=() 43 | while read -r pattern; do 44 | [[ -n ${pattern} ]] && paths+=("${pattern}") 45 | done <<< "${INPUT_PATH:-.}" 46 | 47 | names=() 48 | if [[ "${INPUT_PATTERN:-*}" != '*' ]]; then 49 | while read -r pattern; do 50 | [[ -n ${pattern} ]] && names+=(-o -name "${pattern}") 51 | done <<< "${INPUT_PATTERN}" 52 | (( ${#names[@]} )) && { names[0]='('; names+=(')'); } 53 | fi 54 | 55 | excludes=() 56 | while read -r pattern; do 57 | [[ -n ${pattern} ]] && excludes+=(-not -path "${pattern}") 58 | done <<< "${INPUT_EXCLUDE:-}" 59 | 60 | # Match all files matching the pattern 61 | files_with_pattern=$(find "${paths[@]}" "${excludes[@]}" -type f "${names[@]}") 62 | 63 | # Match all files with a shebang (e.g. "#!/usr/bin/env zsh" or even "#!bash") in the first line of a file 64 | # Ignore files which match "$pattern" in order to avoid duplicates 65 | if [ "${INPUT_CHECK_ALL_FILES_WITH_SHEBANGS}" = "true" ]; then 66 | files_with_shebang=$(find "${paths[@]}" "${excludes[@]}" -not "${names[@]}" -type f -print0 | xargs -0 awk 'FNR==1 && /^#!.*sh/ { print FILENAME }') 67 | fi 68 | 69 | # Exit early if no files have been found 70 | if [ -z "${files_with_pattern}" ] && [ -z "${files_with_shebang:-}" ]; then 71 | echo "No matching files found to check." 72 | exit 0 73 | fi 74 | 75 | FILES="${files_with_pattern} ${files_with_shebang:-}" 76 | 77 | echo '::group:: Running shellcheck ...' 78 | if [ "${INPUT_REPORTER}" = 'github-pr-review' ]; then 79 | # erroformat: https://git.io/JeGMU 80 | # shellcheck disable=SC2086 81 | shellcheck -f json ${INPUT_SHELLCHECK_FLAGS:-'--external-sources'} ${FILES} \ 82 | | jq -r '.[] | "\(.file):\(.line):\(.column):\(.level):\(.message) [SC\(.code)](https://github.com/koalaman/shellcheck/wiki/SC\(.code))"' \ 83 | | reviewdog \ 84 | -efm="%f:%l:%c:%t%*[^:]:%m" \ 85 | -name="shellcheck" \ 86 | -reporter=github-pr-review \ 87 | -filter-mode="${INPUT_FILTER_MODE}" \ 88 | -fail-level="${INPUT_FAIL_LEVEL}" \ 89 | -fail-on-error="${INPUT_FAIL_ON_ERROR}" \ 90 | -level="${INPUT_LEVEL}" \ 91 | ${INPUT_REVIEWDOG_FLAGS} 92 | EXIT_CODE=$? 93 | else 94 | # github-pr-check,github-check (GitHub Check API) doesn't support markdown annotation. 95 | # shellcheck disable=SC2086 96 | shellcheck -f checkstyle ${INPUT_SHELLCHECK_FLAGS:-'--external-sources'} ${FILES} \ 97 | | reviewdog \ 98 | -f="checkstyle" \ 99 | -name="shellcheck" \ 100 | -reporter="${INPUT_REPORTER:-github-pr-check}" \ 101 | -filter-mode="${INPUT_FILTER_MODE}" \ 102 | -fail-level="${INPUT_FAIL_LEVEL}" \ 103 | -fail-on-error="${INPUT_FAIL_ON_ERROR}" \ 104 | -level="${INPUT_LEVEL}" \ 105 | ${INPUT_REVIEWDOG_FLAGS} 106 | EXIT_CODE=$? 107 | fi 108 | echo '::endgroup::' 109 | 110 | echo '::group:: Running shellcheck (suggestion) ...' 111 | # -reporter must be github-pr-review for the suggestion feature. 112 | # shellcheck disable=SC2086 113 | shellcheck -f diff ${FILES} \ 114 | | reviewdog \ 115 | -name="shellcheck (suggestion)" \ 116 | -f=diff \ 117 | -f.diff.strip=1 \ 118 | -reporter="github-pr-review" \ 119 | -filter-mode="${INPUT_FILTER_MODE}" \ 120 | -fail-level="${INPUT_FAIL_LEVEL}" \ 121 | -fail-on-error="${INPUT_FAIL_ON_ERROR}" \ 122 | ${INPUT_REVIEWDOG_FLAGS} 123 | EXIT_CODE_SUGGESTION=$? 124 | echo '::endgroup::' 125 | 126 | if [ "${EXIT_CODE}" -ne 0 ] || [ "${EXIT_CODE_SUGGESTION}" -ne 0 ]; then 127 | exit $((EXIT_CODE + EXIT_CODE_SUGGESTION)) 128 | fi 129 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GitHub Action: Run shellcheck with reviewdog 2 | 3 | [![Docker Image CI](https://github.com/reviewdog/action-shellcheck/workflows/Docker%20Image%20CI/badge.svg)](https://github.com/reviewdog/action-shellcheck/actions) 4 | [![depup](https://github.com/reviewdog/action-shellcheck/workflows/depup/badge.svg)](https://github.com/reviewdog/action-shellcheck/actions?query=workflow%3Adepup) 5 | [![release](https://github.com/reviewdog/action-shellcheck/workflows/release/badge.svg)](https://github.com/reviewdog/action-shellcheck/actions?query=workflow%3Arelease) 6 | [![GitHub release (latest SemVer)](https://img.shields.io/github/v/release/reviewdog/action-shellcheck?logo=github&sort=semver)](https://github.com/reviewdog/action-shellcheck/releases) 7 | [![action-bumpr supported](https://img.shields.io/badge/bumpr-supported-ff69b4?logo=github&link=https://github.com/haya14busa/action-bumpr)](https://github.com/haya14busa/action-bumpr) 8 | 9 | This action runs [shellcheck](https://github.com/koalaman/shellcheck) with 10 | [reviewdog](https://github.com/reviewdog/reviewdog) on pull requests to improve 11 | code review experience. 12 | 13 | [![github-pr-check sample](https://user-images.githubusercontent.com/3797062/65701219-e828b980-e0bb-11e9-9051-2a1f400fe5e5.png)](https://github.com/reviewdog/action-shellcheck/pull/1) 14 | [![github-pr-review sample](https://user-images.githubusercontent.com/3797062/65700741-1c4faa80-e0bb-11e9-8cbd-9a99aeb38594.png)](https://github.com/reviewdog/action-shellcheck/pull/1) 15 | 16 | ## Inputs 17 | 18 | ### `github_token` 19 | 20 | Optional. `${{ github.token }}` is used by default. 21 | 22 | ### `level` 23 | 24 | Optional. Report level for reviewdog [info,warning,error]. 25 | It's same as `-level` flag of reviewdog. 26 | 27 | ### `reporter` 28 | 29 | Reporter of reviewdog command [github-pr-check,github-pr-review,github-check]. 30 | Default is github-pr-check. 31 | github-pr-review can use Markdown and add a link to rule page in reviewdog reports. 32 | 33 | ### `filter_mode` 34 | 35 | Optional. Filtering mode for the reviewdog command [added,diff_context,file,nofilter]. 36 | Default is `file`. 37 | 38 | ### `fail_level` 39 | 40 | Optional. If set to `none`, always use exit code 0 for reviewdog. 41 | Otherwise, exit code 1 for reviewdog if it finds at least 1 issue with severity greater than or equal to the given level. 42 | Possible values: [`none`, `any`, `info`, `warning`, `error`] 43 | Default is `none`. 44 | 45 | ### `fail_on_error` 46 | 47 | Deprecated, use `fail_level` instead. 48 | Optional. Exit code for reviewdog when errors are found [true,false] 49 | Default is `false`. 50 | 51 | ### `reviewdog_flags` 52 | 53 | Optional. Additional reviewdog flags 54 | 55 | ### `path` 56 | 57 | Optional. Base directory to run shellcheck. Same as `[path]` of `find` command. Default: `.` 58 | 59 | Directories are separated by lines. e.g.: 60 | 61 | ```yml 62 | path: | 63 | tools 64 | src 65 | ``` 66 | 67 | ### `pattern` 68 | 69 | Optional. File patterns of target files. Same as `-name [pattern]` of `find` command. Default: `*.sh` 70 | 71 | Patterns are separated by lines. e.g.: 72 | 73 | ```yml 74 | pattern: | 75 | *.bash 76 | *.sh 77 | ``` 78 | 79 | ### `exclude` 80 | 81 | Optional. Exclude patterns of target files. Same as `-not -path [exclude]` of `find` command. Default: `*/.git/*` 82 | 83 | Patterns are separated by lines. e.g.: 84 | 85 | ```yml 86 | exclude: | 87 | */.git/* 88 | ./.cache/* 89 | ``` 90 | 91 | ### `check_all_files_with_shebangs` 92 | 93 | Optional. Checks all files with shebangs in the repository even if they do not match `pattern`. 94 | Default is `false`. 95 | 96 | ### `shellcheck_flags` 97 | 98 | Optional. Flags of shellcheck command. Default: `--external-sources` 99 | 100 | ## Example usage 101 | 102 | ### [.github/workflows/reviewdog.yml](.github/workflows/reviewdog.yml) 103 | 104 | ```yml 105 | name: reviewdog 106 | on: [pull_request] 107 | jobs: 108 | shellcheck: 109 | name: runner / shellcheck 110 | runs-on: ubuntu-latest 111 | steps: 112 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 113 | - name: shellcheck 114 | uses: reviewdog/action-shellcheck@5ebd09ddbe2ebb471646ce234c6c8dd18663ca7c # v1.30.0 115 | with: 116 | github_token: ${{ secrets.github_token }} 117 | reporter: github-pr-review # Change reporter. 118 | path: "." # Optional. 119 | pattern: "*.sh" # Optional. 120 | exclude: "./.git/*" # Optional. 121 | check_all_files_with_shebangs: "false" # Optional. 122 | ``` 123 | 124 | ## Permissions 125 | 126 | It is recommended to add explicit [`permissions`](https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/controlling-permissions-for-github_token) 127 | to the workflow file so the scope of the `GITHUB_TOKEN` passed to `action-shellcheck` is as narrow as 128 | possible. The required permissions for `action-shellcheck` to read the contents of a PR and post review 129 | comments to it, is: 130 | 131 | ```yaml 132 | permissions: 133 | contents: read 134 | pull-requests: write 135 | checks: write 136 | ``` 137 | 138 | ## Known issue 139 | 140 | Running `shellcheck.exe` on Windows might fail with the following error: 141 | 142 | `SC1017: Literal carriage return. Run script through tr -d '\r'` 143 | 144 | This is due to the presence of a carriage return character (`\r`) in the script. 145 | 146 | To fix this, you can simply create or edit the `.gitattributes` file in the root of your repository with the following contents: 147 | 148 | ``` 149 | *.sh text eol=lf 150 | ``` 151 | This would ensure that the scripts are checked out with the correct line ending. 152 | --------------------------------------------------------------------------------