diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 61280dd..d235443 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,6 +11,8 @@ jobs: BUNDLE_GEMFILE: ${{ github.workspace }}/test/using_bundler/Gemfile steps: - uses: actions/checkout@v4 + with: + fetch-depth: 2 # we are comparing PR merge head with base - uses: ruby/setup-ruby@v1 with: ruby-version: 2.6 diff --git a/README.md b/README.md index 551328c..7817571 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,11 @@ Default is `added`. Optional. Report level for reviewdog [`info`, `warning`, `error`]. It's same as `-level` flag of reviewdog. +### `only_changed` + +Optional. Run Rubocop only on changed (and added) files, for speedup [`true`, `false`]. +Default: `false`. + ### `reporter` Optional. Reporter of reviewdog command [`github-pr-check`, `github-check`, `github-pr-review`]. diff --git a/action.yml b/action.yml index 8999993..3bd5ef3 100644 --- a/action.yml +++ b/action.yml @@ -19,6 +19,9 @@ inputs: level: description: 'Report level for reviewdog [info,warning,error]' default: 'error' + only_changed: + description: "Run Rubocop only on changed (and added) files, for speedup [`true`, `false`]" + default: 'false' reporter: description: | Reporter of reviewdog command [github-pr-check,github-check,github-pr-review]. @@ -61,6 +64,7 @@ runs: INPUT_FILTER_MODE: ${{ inputs.filter_mode }} INPUT_GITHUB_TOKEN: ${{ inputs.github_token }} INPUT_LEVEL: ${{ inputs.level }} + INPUT_ONLY_CHANGED: ${{ inputs.only_changed }} INPUT_REPORTER: ${{ inputs.reporter }} INPUT_REVIEWDOG_FLAGS: ${{ inputs.reviewdog_flags }} INPUT_RUBOCOP_EXTENSIONS: ${{ inputs.rubocop_extensions }} @@ -70,6 +74,8 @@ runs: INPUT_TOOL_NAME: ${{ inputs.tool_name }} INPUT_USE_BUNDLER: ${{ inputs.use_bundler }} INPUT_WORKDIR: ${{ inputs.workdir }} + BASE_REF: ${{ github.event.pull_request.base.sha }} + HEAD_REF: ${{ github.sha }} branding: icon: 'check-circle' color: 'red' diff --git a/script.sh b/script.sh index 81a06bc..be46c4d 100755 --- a/script.sh +++ b/script.sh @@ -1,4 +1,7 @@ -#!/bin/sh -e +#!/usr/bin/env bash + +set -e +set -o pipefail cd "${GITHUB_WORKSPACE}/${INPUT_WORKDIR}" || exit export REVIEWDOG_GITHUB_API_TOKEN="${INPUT_GITHUB_TOKEN}" @@ -85,9 +88,36 @@ else BUNDLE_EXEC="bundle exec " fi +if [ "${INPUT_ONLY_CHANGED}" = "true" ]; then + echo '::group:: Getting changed files list' + + # get intersection of changed files (excluding deleted) with target files for + # rubocop as an array + # shellcheck disable=SC2086 + readarray -t CHANGED_FILES < <( + comm -12 \ + <(git diff --diff-filter=d --name-only "${BASE_REF}..${HEAD_REF}" | sort || kill $$) \ + <(${BUNDLE_EXEC}rubocop --list-target-files | sort || kill $$) + ) + + if (( ${#CHANGED_FILES[@]} == 0 )); then + echo "No relevant files for rubocop, skipping" + exit 0 + fi + + printf '%s\n' "${CHANGED_FILES[@]}" + + if (( ${#CHANGED_FILES[@]} > 100 )); then + echo "More than 100 changed files (${#CHANGED_FILES[@]}), running rubocop on all files" + unset CHANGED_FILES + fi + + echo '::endgroup::' +fi + echo '::group:: Running rubocop with reviewdog 🐶 ...' # shellcheck disable=SC2086 -${BUNDLE_EXEC}rubocop ${INPUT_RUBOCOP_FLAGS} --require ${GITHUB_ACTION_PATH}/rdjson_formatter/rdjson_formatter.rb --format RdjsonFormatter \ +${BUNDLE_EXEC}rubocop ${INPUT_RUBOCOP_FLAGS} --require ${GITHUB_ACTION_PATH}/rdjson_formatter/rdjson_formatter.rb --format RdjsonFormatter "${CHANGED_FILES[@]}" \ | reviewdog -f=rdjson \ -name="${INPUT_TOOL_NAME}" \ -reporter="${INPUT_REPORTER}" \