Skip to content

ci(api-inventory): 台帳をブランチ対応で取得する - #1904

Merged
mhaya merged 1 commit into
develop_v2.0.4from
ci/api-inventory-branch-ref
Aug 28, 2026
Merged

ci(api-inventory): 台帳をブランチ対応で取得する#1904
mhaya merged 1 commit into
develop_v2.0.4from
ci/api-inventory-branch-ref

Conversation

@mhaya

@mhaya mhaya commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

概要 (Summary)

台帳・ベースラインを取りに行く Checkout inventory data (private)ref が無く、
常にプライベートリポジトリの既定ブランチ (main) を見ていた
develop_v2.0.4 への PR でも main の台帳と突き合わせるため、ブランチ間の経路差が
そのまま reconcile の A/B/C/D/E として出続ける。件数が常に非ゼロになれば、誰も読まなくなる。

Resolve inventory ref ステップを追加し、git ls-remote --heads で存在を確かめてから
weko 側と同名のブランチを選ぶようにした。

見るブランチ 使う場面
1 PR の head 台帳更新 PR が未マージの段階。作業ブランチ上の台帳を見る
2 PR の base 台帳を触らない PR。および両方マージ後の定常状態
3 既定ブランチ 1・2 が無い場合。警告を出して続行(件数は当てにならない)

head を先に見るのは、公開リポジトリのコード変更と台帳更新が別 PR になるため。
base 同士だけで対応させると、weko の CI が回る時点で台帳更新はまだプライベート側の
作業ブランチにあり、「プライベート側を先にマージしないと公開側の CI が通らない」という
直列の制約ができる。head 優先なら 2 つの PR を並行してレビューでき、マージ順にも依存しない。

採用したブランチ名は PR コメントの冒頭に出す。どの台帳と比べた件数なのかが
分からなければ、レビュアは数字を判断できない。

変更タイプ (Type of Change)

  • 📚 仕様書・マニュアル・APIリストの更新 (Documentation)

🤖 0. CI 自動チェック (API Inventory Drift)

この PR 自体がこの変更の動作確認を兼ねている。
プライベートリポジトリに同名ブランチ ci/api-inventory-branch-ref
develop_v2.0.4 と同じコミットで作ってある。したがって:

  • 期待する挙動: Resolve inventory refhead 一致
    ci/api-inventory-branch-ref を選び、::notice::台帳ブランチ: ... を出す。
    PR コメント冒頭にも同じブランチ名が出る
  • 比較対象の中身は develop_v2.0.4 と同一なので、この PR がゲートの件数を
    動かすことはない
    (動いたら、それは既存の台帳と実機のズレ)

ゲートが FAIL した場合でも、それは本変更ではなく台帳側の状態を示している。
まず PR コメント冒頭のブランチ名が意図どおりかを見てほしい。

  • コード変更なし(.github/tools/api-inventory/ci/ のみ)

📚 5. ドキュメント・仕様書更新チェック

  • tools/api-inventory/ci/README.md に §3a「ブランチの対応」を追加
  • 同 §3 の「PR ブランチのベースラインを比べる」は実装と食い違っていたので訂正
  • §3c(タグ運用)とバージョンアップ手順に同名ブランチの手順を追加
  • pull_request_template.md §0 に、ブランチ対応の説明と「同名ブランチを切った」チェック項目を追加

📋 6. 動作検証エビデンス

  • YAML パース: yaml.safe_load OK
  • github-script の JS: node --check OK
  • ref 解決ロジック: ローカルで 5 パターン検証済み
    (head 一致 / base 一致 / どちらも無し / head 空 / 前方一致の誤マッチが無いこと)
  • ls-remote は deploy key が要るため、実地確認はこの PR の Actions で行う

🤖 Generated with Claude Code

https://claude.ai/code/session_01CQXqdhUzMHyxhPJbHKw6Zr

台帳とベースラインはプライベートリポジトリ(RCOSDP/weko-secret)から取るが、
checkout に ref を渡していなかったため、常に既定ブランチ(main)を見ていた。
develop_v2.0.4 への PR でも main の台帳と突き合わせるので、ブランチ間の
経路差がそのまま reconcile の A/B/C/D/E として出続ける。件数が常に非ゼロに
なれば誰も読まなくなる。

Resolve inventory ref ステップを足し、ls-remote で存在を確かめてから
head → base → 既定 の順で同名ブランチを選ぶ。head を先に見るのは、
公開リポジトリのコード変更と台帳更新が別 PR になるため。base 同士だけで
対応させると、weko の CI が回る時点で台帳更新はまだ作業ブランチにあり、
「プライベート側を先にマージしないと公開側が通らない」直列の制約ができる。

採用したブランチ名は PR コメントの冒頭に出す。どの台帳と比べた件数かが
分からなければ、レビュアは数字を判断できない。対応ブランチが無い場合は
既定ブランチと比較したうえで警告を出す。FAIL にしないのは、対応ブランチの
無いリリースラインで全 PR が止まるのを避けるため。

ci/README.md の「PR ブランチのベースラインを比べる」は実装と食い違って
いたので、対応の決め方(§3a)を書いて訂正した。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CQXqdhUzMHyxhPJbHKw6Zr
@github-actions

Copy link
Copy Markdown

🔍 Claude によるレビュー

指摘 1 件 — 🔴 高 0 / 🟠 中 0 / 🟡 低 1 / 🔎 未確認 2 件


🟡 [低] プライベートリポジトリのブランチ存在有無がPRコメント/ログでオラクル化する

.github/workflows/api-inventory-drift.yml:84 (1/3 パス)

HEAD_REF(PR作成者が自由に決められる自リポジトリのブランチ名)がプライベートリポジトリ(weko-secret)に存在するかどうかが、採用ブランチ名の表示(notice/PRコメント)を通じて外部から判別可能になる。pick===HEAD_REFなら存在確認、pick===BASE_REFやfallback警告なら不存在確認となり、二値オラクルとして機能する。fork PRはジョブ自体がスキップされるため悪用には対象リポジトリへのpush権限(同一リポジトリの非forkブランチ作成)が前提だが、README自体が「Actionsのログ・PRコメントは誰でも読める」ことを設計上の懸念点として明記しており、プライベートリポジトリの内部ブランチ名(例: 未公表のissue番号を含む作業ブランチ)の存在を外部に漏らす経路になる。

提案

採用ブランチ名の表示は「head/base/defaultのいずれを採用したか」という区分のみに留め、具体的なブランチ名そのもの(特にHEAD_REF由来の値)はログ/PRコメントに出さない、または既定ブランチ以外を採用した旨だけを表示する形にする。

根拠
echo "::notice::台帳ブランチ: $pick"  (workflow line 84)
body += `> 台帳ブランチ: \`${ref}\`\n\n`;  (workflow line 201, PRコメント本文)

確認: .github/workflows/api-inventory-drift.yml:58-89,179-214 を読み、Resolve inventory ref のロジックとPRコメント生成コードを確認。また同ファイルのpull_request_template.md記載やREADME(tools/api-inventory/ci/README.md)の「Actionsログ・PRコメントは誰でも読める」という前提説明と突き合わせた。


🔎 未確認 — 裏が取れなかったもの 2 件
  • Resolve inventory ref 失敗時に後続ステップがどこまで自動スキップされるか未実機検証 .github/workflows/api-inventory-drift.yml:92 (1/3 パス)
    • 「Resolve inventory ref」がset -euで失敗した場合、GitHub Actionsの暗黙のsuccess()により素のif条件を持つ後続ステップ(Checkout inventory data等)はスキップされ、always()付きのステップ(Probe changed endpoints, Comment on PR等)だけが実行される、という理解で矛盾はなさそうだが、実際にCIを走らせて確認したわけではない。想定通りならComment on PRでINVENTORY_REF/FALLBACKが空になり「解決できませんでした」の分岐に入るはずだが、Probe changed endpoints等がコンテナ未起動のまま実行されてどう失敗するかは未確認。
    • 確認できなかった理由: GitHub Actionsのif条件とsuccess()の暗黙付与に関するドキュメント上の挙動から推測しただけで、実際にワークフローを実行して確認していないため。
  • 攻撃者が制御可能なブランチ名がPRコメント本文にそのまま埋め込まれる .github/workflows/api-inventory-drift.yml:198 (1/3 パス)
    • steps.ref.outputs.refはgithub.event.pull_request.head.ref(同一リポジトリ内のブランチ名、PR作成者が自由に付けられる)に由来し、それが> 台帳ブランチ: \${ref}`\n\n`としてエスケープなしでコメント本文に挿入される。Markdown崩し程度は起こり得るが、フォークではなく同一リポジトリ内のブランチ(=書き込み権限保有者)しか到達しないため実害は乏しいと考えられる。
    • 確認できなかった理由: 同一リポジトリからのPRに限定されており(head.repo.full_name == repositoryのジョブ条件)、実際に問題になる権限昇格シナリオを具体的に構成できなかったため、確信を持って重大度を付けられなかった。

モデル sonnet / 3 回実行して和集合 / コスト $1.1213。同じ差分でも結果が揺れるため複数回まわし、一部のパスでしか挙がらなかったものには回数を添えています

差分のみを対象にした自動レビューです。誤りが含まれることがあります。

@github-actions

Copy link
Copy Markdown

API インベントリ差分(件数のみ)

台帳ブランチ: ci/api-inventory-branch-ref

明細は公開できないため件数のみ表示しています。該当箇所はプライベートリポジトリ側の台帳・レポートで確認してください。

ベースラインとの差分

API インベントリ差分レポート

  • 旧: e9c5b2b51 v2.0.3-69-ge9c5b2b51 (profile=default) endpoints=928 (外部ライブラリ由来 359)
  • 新: 25307b227 v2.0.3-77-g25307b227 (profile=default) endpoints=928 (外部ライブラリ由来 359)

判定: ✅ PASS (FAIL 0 / WARN 1)

サマリ

分類 件数
ADDED 0
REMOVED 0
RULE_CHANGED 0
METHODS_CHANGED 0
AUTH_CHANGED 0
IMPL_CHANGED 0
ATTRS_UNKNOWN_NEW 0
ModelView 追加 0
ModelView 削除 0
ModelView フラグ変化 1
config 変化 0
コメントアウト認証の増加 0
依存パッケージの版変化 40

[WARN] W6 依存パッケージの版が変化した — 40件

  • attrs — 22.2.0 -> 17.4.0
  • botocore — 1.12.209 -> 1.12.253
  • cffi — 1.15.1 -> 1.11.2
  • click — 8.0.4 -> 6.7
  • cryptography — 40.0.2 -> 2.1.4
  • pyld — 3.1.0 -> 3.2.0
  • pytest — 7.0.1 -> 4.2.0
  • Docker-Services-CLI — 0.8.0 -> (削除)
  • aws-xray-sdk — 0.95 -> (削除)
  • build — 0.9.0 -> (削除)
  • check-manifest — 0.48 -> (削除)
  • cookies — 2.2.1 -> (削除)
  • coverage — 4.5.4 -> (削除)
  • docker — 5.0.3 -> (削除)
  • ecdsa — 0.19.2 -> (削除)
  • execnet — 1.9.0 -> (削除)
  • iniconfig — 1.1.1 -> (削除)
  • isort — 5.10.1 -> (削除)
  • jsondiff — 1.1.1 -> (削除)
  • jsonpickle — 2.2.0 -> (削除)
  • mock — 3.0.5 -> (削除)
  • moto — 1.3.7 -> (削除)
  • pep517 — 0.13.1 -> (削除)
  • pep8 — 1.7.1 -> (削除)
  • pyaml — 23.5.8 -> (削除)
  • pycryptodome — 3.21.0 -> (削除)
  • pydocstyle — 6.3.0 -> (削除)
  • pytest-cache — 1.0 -> (削除)
  • pytest-cov — 2.10.1 -> (削除)
  • pytest-flask — 0.15.1 -> (削除)
  • pytest-invenio — 1.3.4 -> (削除)
  • pytest-mock — 3.6.1 -> (削除)
  • pytest-pep8 — 1.0.6 -> (削除)
  • python-jose — 2.0.2 -> (削除)
  • responses — 0.10.15 -> (削除)
  • selenium — 3.141.0 -> (削除)
  • tomli — 1.2.3 -> (削除)
  • websocket-client — 1.3.1 -> (削除)
  • weko-redis — 0.1.0.dev20170000 -> (削除)
  • wrapt — 1.16.0 -> (削除)

台帳との突き合わせ

スナップショット ↔ インベントリ 突き合わせ

  • リビジョン: 25307b227 v2.0.3-77-g25307b227 経路URI=908
  • 台帳: 行=1048 URI=919

件数のみ。詳細はプライベートリポジトリ側の完全版レポートを参照。

判定: ✅ 一致 (0件)

検出 件数
A. インベントリ未収載(抽出漏れ) 0
B. 実機に無い(未説明) 0
B'. 実機に無い(既知・許容) 11
C. メソッド不一致 0
D. app列の不一致 0
E. endpoint 未収載 0
E'. endpoint が実機に無い(参考) 1

@mhaya
mhaya merged commit 1d6640c into develop_v2.0.4 Aug 28, 2026
30 of 96 checks passed
@mhaya
mhaya deleted the ci/api-inventory-branch-ref branch August 28, 2026 04:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant