lint を ruff に統一し、CI と Dependabot を新設する - #14
Merged
Merged
Conversation
autopep8 2.3.2 を外して ruff 0.16.3 に統一する。 autopep8 は formatter であって linter ではないため、このリポジトリには これまで lint に相当するものが実質存在しなかった。設定ファイル (setup.cfg / tox.ini など) も1つも無く、autopep8 はデフォルト設定 だったので、移植すべき設定も無い。 main.py の import 構造を手で直した。もともと import 群の途中に app = FastAPI() と app.add_middleware(...) が挟まっていて、その下に io と zipfile と ndc_parser の import が続く形だった (E402 が3件)。 すべての import を先頭にまとめ、app の生成と add_middleware の 順序関係は変えていない。 ruff check --fix が入れた変更は I001 と SIM117 で、SIM117 は 入れ子の with を1つにまとめるもの。意味は変わらない。 --unsafe-fixes は使っていない。 Dockerfile は --no-dev があるので ruff は既定グループの dev に置いた。 コメントの autopep8 への言及も直した。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BsERiWbzZwB6EdGoyyqcpT
これまで .github ディレクトリそのものが存在せず、自動検証も依存更新も まったく動いていなかった。 CI は2ジョブ。静的解析ジョブは ruff check と ruff format --check、 それに読み込み確認。main.py は import するだけで zips を展開して NDC を全件パースする (NDC8 が 10340件、NDC9 が 12388件) ので、 これが実質のスモークテストになる。テストが無いため唯一の実行時チェック。 Docker ジョブは本番と同じ gunicorn と UvicornWorker で起動して /ndc9/123 が応答するところまで見る。Dockerfile が外部認証を必要と しない自己完結した構成なので、起動確認まで入れられる。 uv sync は --frozen ではなく --locked を使う。--frozen はロックの ずれを検出しないため (uv 0.12 のヘルプに "Instead of checking if the lockfile is up-to-date" と明記されている)。Dockerfile 側は --frozen なので、ずれの検出はこの CI でしか行われない。 CI 完了ジョブは、将来ブランチ保護を掛けるときに必須チェックを これ1つだけ指定できるようにするため。 zizmor.yml の unpinned-uses ポリシーには ndc-dev/* を足した。 CALIL/* も残しているのは、ワークフローを org 間でコピーしても判定が 変わらないようにするため。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BsERiWbzZwB6EdGoyyqcpT
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Python の lint を autopep8 から ruff に統一し、あわせて
.githubを新設しました。CALIL org 横断で lint を ruff に寄せる作業の一部です。なぜこのリポジトリが対象になったか
autopep8 は linter ではありません
autopep8 は formatter であって linter ではないので、このリポジトリにはこれまで lint に相当するものが実質存在しませんでした。
setup.cfgもtox.iniも無く autopep8 はデフォルト設定だったので、移植すべき設定もありません。ruff は formatter(
ruff format)と linter(ruff check)の両方を1つで担うので、autopep8 の役割を包含したうえで lint が増えます。設定
CALIL org 共通の形にしました。
ignoreのB008は FastAPI のDepends()を引数の既定値に置くパターンで、このリポジトリでは現在使っていませんが、org 共通の形を崩さないために入れてあります。selectを書かないと危険です。 ruff 0.16.3 のゼロコンフィグ既定は--show-settingsで確認すると 413ルール / 38ファミリまで広がっていて、旧来のE4,E7,E9,Fではありません。明示しないと ruff を上げるたびに指摘が増えて CI が突然赤くなります。main.py の import 構造を手で直しました
ここだけ機械的修正では直せない部分です。もともとこうなっていました。
import 群の途中に
app = FastAPI()とapp.add_middleware(...)が挟まっていて、その下にさらに import が続く形です(E402が3件)。ruff の isort は非 import 文をまたいで import を移動しないので、
--fixでは直りません(E402は報告するだけで fix を持ちません)。逆に言えば、自動修正でこの構造が壊れる心配もありません。実際に--diffを取ってapp = FastAPI()とadd_middlewareの順序が変わらないことを確認したうえで、手で並べ替えました。appの生成とadd_middlewareの順序関係は変えていません。ruff check --fixが入れたのはI001(import 順)とSIM117(入れ子のwithを1つにまとめる)で、後者は意味が変わりません。--unsafe-fixesは使っていません。.githubがまるごと無かったので新設しましたCI も Dependabot も zizmor も、何もありませんでした。
静的解析ジョブは
ruff check --output-format=github(PR の該当行に注釈が出ます)、ruff format --check、それに読み込み確認です。読み込み確認は
import mainです。main.pyは import するだけでzips/を展開して NDC を全件パースするので、これ自体が ndc-parser と FastAPI のスモークテストになります(テストが無いため唯一の実行時チェックです)。手元で実行すると NDC8 が 10,340件、NDC9 が 12,388件でした。Docker ジョブは本番と同じ
gunicorn+UvicornWorkerで起動して/ndc9/123が応答するところまで見ます。Dockerfile が外部認証を必要としない自己完結した構成なので、起動確認まで入れられました。cache-from: type=gha/cache-to: type=gha,mode=maxを付けています。CI 完了ジョブは、将来ブランチ保護を掛けるときに必須チェックをこれ1つだけ指定すれば済むようにするためのものです。ジョブを増減しても保護の設定が腐りません。uv sync --frozenはロックのずれを検出しません新設した CI では
--lockedを使っています。uv 0.12 のヘルプに、--locked… "Requires that the lockfile is up-to-date. If the lockfile is missing or needs to be updated, uv will exit with an error"--frozen… "Instead of checking if the lockfile is up-to-date, uses the versions in the lockfile as the source of truth"と明記されています。Dockerfile 側は
--frozenなので(コメントには「ずれていれば失敗する」と書いてありますが、実際には失敗しません)、ずれの検出はこの CI でしか行われません。zizmor の設定について
unpinned-usesのポリシーにndc-dev/*を足しました。CALIL/*も残しているのは、ワークフローを org 間でコピーしても判定が変わらないようにするためです(理由はファイル内のコメントに書いてあります)。なお
actions-security-check.ymlは CALIL/workflows の雛形をそのままコピーしていますが、ci.ymlには配布元のリポジトリ名を書くコメントを入れていません。 このリポジトリは public なので、private リポジトリを指す記述は避けています。手元で確認したこと
yamllintを回しているのは、重複キーがあると GitHub がワークフロー全体を拒否する(ジョブが1本も作られず failure になり、ログも出ない)のを防ぐためです。PyYAML と zizmor は重複キーを後勝ちで黙って読むので検出できません。Docker ジョブは手元に docker が無いので検証できていません。この PR の実行が初回検証になります。
変更点
pyproject.toml:autopep8>=2.3.2を削除、devにruff>=0.16.3、[tool.ruff]一式を追加Dockerfile:--no-devのコメントの autopep8 への言及を ruff に修正(--no-devは元からあるので ruff は本番イメージに入りません)main.py: import 構造を手で修正(E402 3件)、ruff check --fixとruff formatvalidate.py:ruff check --fixとruff format.github/workflows/ci.yml: 新設.github/workflows/actions-security-check.ymlと.github/zizmor.yml: 新設.github/dependabot.yml: 新設(uv / github-actions / docker / terraform)Dependabot 用のラベル(
python/github-actions/docker/terraform/Actionsのセキュリティ)は事前に作成済みです。Dependabot は存在しないラベルを作らず黙って無視するので、先に作る必要があります。関連
Todoist: Python の lint を ruff に統一する(5リポジトリ)
ブランチ保護(必須チェックの設定)は別タスクにしています。現状このリポジトリは保護が無いので、この CI は赤でもマージできます。
🤖 Generated with Claude Code
https://claude.ai/code/session_01BsERiWbzZwB6EdGoyyqcpT