reviewdog/action-rubocop実行時に起きたGem::FilePermissionErrorの対処
現象
reviewdog/action-rubocopを使用してGitHub Actionsを実行したところ、Gem::FilePermissionErrorが発生しました。
GitHub Acitonsのログ
Run reviewdog/action-rubocop@v1
🐶 Installing reviewdog ... https://github.com/reviewdog/reviewdog
Installing rubocop with extensions ... https://github.com/rubocop/rubocop
ERROR: While executing gem ... (Gem::FilePermissionError)
You don't have write permissions for the /var/lib/gems/2.7.0 directory.
Error: Process completed with exit code 1.
このときのワークフローファイルは、以下のymlとなっています。
name: reviewdog
on: [pull_request]
jobs:
rubocop:
name: runner / rubocop
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v1
- name: rubocop
uses: reviewdog/action-rubocop@v1
with:
rubocop_version: 1.8.1
# rubocop_extensions: rubocop-rails:gemfile rubocop-rspec:gemfile
github_token: ${{ secrets.github_token }}
reporter: github-pr-review # Default is github-pr-check
調査
問題の発生場所の特定
まずは問題が起きている場所の特定です。Reviewdogのコードを調べたところ、action.ymlでscript.shを実行しているようです。
・・・略・・・
runs:
using: 'composite'
steps:
- run: $GITHUB_ACTION_PATH/script.sh
・・・略・・・
このscirpt.shと現象のログを合わせて確認すると、Installing rubocop with extensions ... https://github.com/rubocop/rubocop
のログのあとに失敗しているので、gem installに失敗しているようです。
・・・略・・・
echo '::group::🐶 Installing reviewdog ... https://github.com/reviewdog/reviewdog'
curl -sfL https://raw.githubusercontent.com/reviewdog/reviewdog/master/install.sh | sh -s -- -b "${TEMP_PATH}" "${REVIEWDOG_VERSION}" 2>&1
echo '::endgroup::'
echo '::group:: Installing rubocop with extensions ... https://github.com/rubocop/rubocop'
# if 'gemfile' rubocop version selected
if [ "${INPUT_RUBOCOP_VERSION}" = "gemfile" ]; then
# if Gemfile.lock is here
if [ -f 'Gemfile.lock' ]; then
# grep for rubocop version
RUBOCOP_GEMFILE_VERSION=$(ruby -ne 'print $& if /^\s{4}rubocop\s\(\K.*(?=\))/' Gemfile.lock)
# if rubocop version found, then pass it to the gem install
# left it empty otherwise, so no version will be passed
if [ -n "$RUBOCOP_GEMFILE_VERSION" ]; then
RUBOCOP_VERSION=$RUBOCOP_GEMFILE_VERSION
else
printf "Cannot get the rubocop's version from Gemfile.lock. The latest version will be installed."
fi
else
printf 'Gemfile.lock not found. The latest version will be installed.'
fi
else
# set desired rubocop version
RUBOCOP_VERSION=$INPUT_RUBOCOP_VERSION
fi
gem install -N rubocop --version "${RUBOCOP_VERSION}"
# Traverse over list of rubocop extensions
for extension in $INPUT_RUBOCOP_EXTENSIONS; do
# grep for name and version
INPUT_RUBOCOP_EXTENSION_NAME=$(echo "$extension" |awk 'BEGIN { FS = ":" } ; { print $1 }')
INPUT_RUBOCOP_EXTENSION_VERSION=$(echo "$extension" |awk 'BEGIN { FS = ":" } ; { print $2 }')
# if version is 'gemfile'
if [ "${INPUT_RUBOCOP_EXTENSION_VERSION}" = "gemfile" ]; then
# if Gemfile.lock is here
if [ -f 'Gemfile.lock' ]; then
# grep for rubocop extension version
RUBOCOP_EXTENSION_GEMFILE_VERSION=$(ruby -ne "print $& if /^\s{4}$INPUT_RUBOCOP_EXTENSION_NAME\s\(\K.*(?=\))/" Gemfile.lock)
# if rubocop extension version found, then pass it to the gem install
# left it empty otherwise, so no version will be passed
if [ -n "$RUBOCOP_EXTENSION_GEMFILE_VERSION" ]; then
RUBOCOP_EXTENSION_VERSION=$RUBOCOP_EXTENSION_GEMFILE_VERSION
else
printf "Cannot get the rubocop extension version from Gemfile.lock. The latest version will be installed."
fi
else
printf 'Gemfile.lock not found. The latest version will be installed.'
fi
else
# set desired rubocop extension version
RUBOCOP_EXTENSION_VERSION=$INPUT_RUBOCOP_EXTENSION_VERSION
fi
# Handle extensions with no version qualifier
if [ -z "${RUBOCOP_EXTENSION_VERSION}" ]; then
unset RUBOCOP_EXTENSION_VERSION_FLAG
else
RUBOCOP_EXTENSION_VERSION_FLAG="--version ${RUBOCOP_EXTENSION_VERSION}"
fi
# shellcheck disable=SC2086
gem install -N "${INPUT_RUBOCOP_EXTENSION_NAME}" ${RUBOCOP_EXTENSION_VERSION_FLAG}
done
echo '::endgroup::'
export REVIEWDOG_GITHUB_API_TOKEN="${INPUT_GITHUB_TOKEN}"
echo '::group:: Running rubocop with reviewdog 🐶 ...'
・・・略・・・
このgemのインストール失敗と、今回のエラーログについて調べたところ、以下の2つの記事を見つけました。
この2つの記事と今回の現象から、原因と対策は以下の通りであると思われます。
「GitHub Actions上でgemを使用してRubocopのインストールを行う際、GitHub Actionsのシステム側のRubyを参照していたようです。そのため、この参照がPermissionErrorとなり、この現象が発生していました。
ワークフローにruby/setup-rubyのアクションを追加することで、GitHub Actionsのローカル側のRubyを参照するようになり、PermissionErrorが発生せずにgemのインストールができると考えられます。」
対応
ワークフローファイルにruby/setup-rubyのアクションを追加し、Rubyバージョン(3.0.0)を指定することで、この問題を解決できました。
name: reviewdog
on: [pull_request]
jobs:
rubocop:
name: runner / rubocop
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v1
- uses: ruby/setup-ruby@v1
with:
ruby-version: 3.0.0
- name: rubocop
uses: reviewdog/action-rubocop@v1
with:
rubocop_version: 1.8.1
github_token: ${{ secrets.github_token }}
reporter: github-pr-review # Default is github-pr-check
Discussion