モノレポ構成(apps/foo
, apps/bar
, …)の Python プロジェクトで、アプリ単位に SARIF を生成し GitHub Code Scanning にアップロードする方法をご紹介します。
ここでは静的解析ツールとして Ruff を使っていますが、他の SARIF 出力対応ツールでも基本的な構成は同様です。
SARIF 形式での出力とアップロードの流れ
SARIF(Static Analysis Results Interchange Format)は GitHub Code Scanning に対応したレポートフォーマットです。ツールによっては --output-format sarif
などのオプションで SARIF を出力できます。
たとえば Ruff の場合、下記のように指定できます。
ruff check apps/foo --output-format sarif
GitHub Actions でアプリ単位に SARIF をアップロードする方法
複数の SARIF を一括アップロードした場合の注意点
GitHub の upload-sarif
アクションでは、sarif_file
にディレクトリ(例:apps/
)を指定することで複数ファイルを一括アップロードできます。
permissions:
contents: read
security-events: write
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install ruff
run: python -m pip install ruff
- name: Lint and generate SARIF per app
run: |
set +e
for app in apps/*/; do
dir=$(basename "$app")
ruff check "$app" --output-format sarif --output-file "apps/$dir.sarif"
done
- name: Upload SARIF
uses: github/codeql-action/upload-sarif@v3
if: success() || failure()
with:
sarif_file: 'apps/'
ただし、各ファイルの分析結果が 同一の分析実行(run)として扱われるため、以下のような警告が出る可能性があります。
Uploading multiple SARIF runs with the same category is deprecated and will be removed on June 4, 2025. Please update your workflow to upload a single run per category. For more information, see https://github.blog/changelog/2024-05-06-code-scanning-will-stop-combining-runs-from-a-single-upload
これは 2025/7/9 時点で確認できた警告ですが、メッセージに記載の通り、いつ利用できなくなってもおかしくないです
対策:アプリごとに category
を設定して分離アップロード
upload-sarif
アクションには category
オプションがあり、分析結果をグルーピングできます。
これを利用すると、同じコミットに対する複数の解析結果を個別に扱うことが可能です。
以下は、アプリ単位に SARIF を生成・アップロードする構成例です。
Workflow 全体の例
permissions:
contents: read
security-events: write
jobs:
set-matrix:
runs-on: ubuntu-latest
outputs:
apps: ${{ steps.set-apps.outputs.apps }}
steps:
- uses: actions/checkout@v4
- id: set-apps
run: |
apps=$(ls -1 apps | jq -R . | jq -c -s .)
echo "apps=$apps"
echo "apps=$apps" >> $GITHUB_OUTPUT
lint:
needs: set-matrix
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
app: ${{ fromJson(needs.set-matrix.outputs.apps) }}
steps:
- uses: actions/checkout@v4
- name: Install static analysis tool (Ruff example)
run: python -m pip install ruff
- name: Run analysis and generate SARIF
run: |
ruff check apps/${{ matrix.app }}/ --output-format sarif --output-file ruff_output.sarif
- name: Upload SARIF
uses: github/codeql-action/upload-sarif@v3
if: success() || failure()
with:
sarif_file: ruff_output.sarif
category: ${{ matrix.app }}
fail-fast: false
を指定することで、どれかのアプリでエラー終了しても他のアプリの検査を継続するようにしています。
以下は GitHub 上でアプリごとに実行された例です。
まとめ
- モノレポではアプリ単位に SARIF を分けてアップロードすると、スキャン結果をわかりやすく管理できます
-
category
オプションを使うことで、Code Scanning 上でも各アプリの結果が分離され、警告を回避できます - SARIF を出力できるツールであれば、この構成は広く活用可能です