tj-actions/changed-filesで日本語ファイル名の差分検知が失敗する問題とその解決法



tj-actions/changed-filesで日本語ファイル名の差分検知が失敗する問題とその解決法
はじめに
GitHub Actionsでtj-actions/changed-files
を使用してファイル差分を取得するワークフローを運用していたところ、日本語を含むファイルが適切に検知されない問題に遭遇しました。この記事では、その問題と解決方法について解説します。
この問題は主に以下の2つの要因が重なって発生しました:
- Gitの
core.quotepath
設定による日本語ファイル名のエスケープ処理 - tj-actions/changed-filesのv41.0.0以降で導入された
safe_output
オプションによるセキュリティ対策
日本語のファイルの差分が検知されない問題
このブログのCI/CDパイプラインではtj-actions/changed-files@v46
を使用して変更ファイルを検知するワークフローを構築していました。しかし、ファイル名に日本語が含まれるPull Requestでは、対象のファイルの差分検知がうまくできませんでした。
_posts/drafts/2025-06-08_Javaのマルチプロジェクトのセットアップ方法について.md
原因
ローカルでdiffコマンドを実行してみると以下のアウトプットが出力されました。
- diffコマンド
diff diff --name-only f80c8594aea45f9af4da49b9c878048d989917cd..f12a70f4d8a634d2344cf936d3da6b5490290bba
- Output
.github/workflows/blog-review-ai.yml
.github/workflows/build-test.yml
.github/workflows/code-review-ai.yml
"_posts/drafts/2025-06-08_Java\343\201\256\343\203\236\343\203\253\343\203\201\343\203\227\343\203\255\343\202\270\343\202\247\343\202\257\343\203\210\343\201\256\343\202\273\343\203\203\343\203\210\343\202\242\343\203\203\343\203\227\346\226\271\346\263\225\343\201\253\343\201\244\343\201\204\343\201\246.md"
package-lock.json
package.json
- アクション定義
ファイルの末尾がmd"
になっており、tj-actions/changed-files
のアクション定義では、.md
でファイルのフィルタリングを行っているため、うまく変更が検知できていなかったようです。
# 変更されたファイルをJSON形式で取得する
- name: Get changed files in the drafts folder
id: changed-files-specific
uses: tj-actions/changed-files@v46
with:
files: |
**.md
対処方法
以下の処理をGitHub Actionsに記載したところうまく差分が検知できるようになりました。
# UTF-8エンコーディングとGit設定を調整
- name: Configure Git for Japanese filenames
run: |
git config --local core.quotepath false
git config --global core.quotepath false
export LC_ALL=C.UTF-8
export LANG=C.UTF-8
この設定により、Gitが日本語をエスケープせずにそのまま出力するようになります。
matrixジョブのJSON形式に関するエラー
ファイル差分が検知できるようになった後、後続処理でエラーが発生しました。
原因
以下のエラーが発生しました。
Blog Review with AI
Error when evaluating 'strategy' for job 'review'. .github/workflows/blog-review-ai.yml (Line: 48, Col: 15): Error from function 'fromJSON': String contains invalid escape code: '\�'. Located at line 1 position 2 within JSON., .github/workflows/blog-review-ai.yml (Line: 48, Col: 15): Unexpected value ''
tj-actions/changed-files
には、matrixジョブのインプットとするためのmatrix: true
というプロパティがありますが、そのアウトプットの形式に問題がありそうでした。
safe_outputオプションの詳細
safe_output
はtj-actions/changed-files
v41.0.0で導入されたセキュリティ機能で、true|false
の切り替えにより以下の挙動を示します。
設定値 | 動作 | 用途 |
---|---|---|
true (デフォルト) |
ファイル名をBash用にエスケープ | セキュリティ重視の環境 |
false |
エスケープ処理なし | 日本語など非ASCII文字を含むファイル名 |
日本語を正しく処理するためには、safe_output: false
の設定が必要です。
対策
safe_output: false
を追加したところ、日本語を含むファイルの差分検知が正常に動作するようになりました。
jobs:
# 準備ジョブ: 変更されたファイル一覧をJSON形式で取得
prepare:
permissions:
contents: read
runs-on: ubuntu-latest
outputs:
changed_files: >-
${{ steps.changed-files-specific.outputs.all_changed_files }}
has_changes: ${{ steps.changed-files-specific.outputs.any_changed }}
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
# UTF-8エンコーディングを明示的に設定
- name: Set UTF-8 encoding
run: |
git config --local core.quotepath false
git config --global core.quotepath false
export LC_ALL=C.UTF-8
export LANG=C.UTF-8
# 変更されたファイルをJSON形式で取得する
- name: Get changed files in the drafts folder
id: changed-files-specific
uses: tj-actions/changed-files@v46
with:
files: |
**.md
matrix: true
# 文字エンコーディング問題を回避するオプション
safe_output: false
# レビュージョブ: matrixストラテジーで各ファイルを個別処理
review:
needs: prepare
if: needs.prepare.outputs.has_changes == 'true'
permissions:
models: read # GitHub Models を読み取るための権限
contents: read # ファイルをプロンプトとして渡すために必要な権限
pull-requests: write # プルリクエストにコメントを投稿するための権限
runs-on: ubuntu-latest
strategy:
matrix:
file: ${{ fromJSON(needs.prepare.outputs.changed_files) }}
max-parallel: 3 # レート制限対策として並列実行数を制限
fail-fast: false # 一部失敗時も他のファイル処理を継続
steps:
- name: Checkout
uses: actions/checkout@v4
# UTF-8エンコーディングを明示的に設定
- name: Set UTF-8 encoding
run: |
git config --local core.quotepath false
git config --global core.quotepath false
export LC_ALL=C.UTF-8
export LANG=C.UTF-8
# AI によるレビューを実行(各ファイル個別)
- name: AI Blog Review for ${{ matrix.file }}
id: inference
uses: actions/ai-inference@v1.1.0
with:
system-prompt-file: '.github/prompts/blog-review-ai.prompt.md'
# 個別ファイルの内容をプロンプトとして渡す
prompt-file: '${{ matrix.file }}'
model: openai/gpt-4o
max-tokens: '2000'
注意点
tj-actions/changed-files
の将来バージョンでは、日本語ファイル名を安全に処理できるオプションが追加される可能性があります。定期的にリリースノートを確認し、よりセキュアな解決方法が利用可能になった場合は移行を検討した方が良い気がしています。
"
付きのファイルを処理できるようになるか、もしくは現状でも、"
付きのファイル名を考慮したパターンマッチングをした方が、後続処理を考えるとよりセキュリティ面で堅牢になるのかもしれません。
参考リンク
- tj-actions/changed-files - GitHub - 公式リポジトリ
- tj-actions/changed-files Security Advisory - safe_outputオプション導入の背景
- GitHub Actions+Gitでのマルチバイト文字列表示 | swfz TIL - Gitのマルチバイト対応
- Qiita: GitHub Actionsで差分ファイルを扱う際の設定例 - 実践的な設定例
- Git Documentation - core.quotepath - Git公式ドキュメント