Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions tools/api-inventory/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ weko3_api_auth_findings.md
api_snapshot*.json
reconcile_allow.json
reconcile_report.md
detect_allow.json
probe*.json
drift*.md
# fixtures.py が生成する。秘密は入らない(パスワードは fixtures.py の定数、
Expand All @@ -14,3 +15,4 @@ drift*.md
fixtures.json
__pycache__/
*.pyc
.pytest_cache/
36 changes: 28 additions & 8 deletions tools/api-inventory/ci/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
| 置き場所 | 内容 |
|---|---|
| **本リポジトリ `tools/api-inventory/`** | **ツールのみ**(scripts / ci)。データは1件も置かない |
| **`RCOSDP/weko-secret`**(private) | 台帳TSV(57列/24列)、列定義README、`api_snapshot.json`、`reconcile_allow.json`、`reconcile_report.md`、調査記録 |
| **`RCOSDP/weko-secret`**(private) | 台帳TSV(62列/32列)、列定義README、`api_snapshot.json`、`reconcile_allow.json`、`detect_allow.json`、`reconcile_report.md`、調査記録、台帳の検査テスト |

本書では `RCOSDP/weko-secret`(private)を単に**プライベートリポジトリ**と呼ぶ。
スクリプトは環境変数 `WEKO_API_INVENTORY_DIR` でその場所を指す。未設定なら理由を添えて中断する。
Expand All @@ -22,6 +22,19 @@ python3 tools/api-inventory/scripts/reconcile.py --gate

CI の出力は **`--summary-only` で件数のみ**。URI や endpoint 名は出さない。

## ワークフローは2本

| ワークフロー | 見るもの | 要るもの | 所要 |
|---|---|---|---|
| `api-inventory-tests.yml` | **台帳を作る側**(スクリプト・手順書)が壊れていないか | なし | 数秒 |
| `api-inventory-drift.yml` | **台帳の中身**が実機・ソースとずれていないか | Secret + Docker | 60分枠 |

ツールが壊れたまま drift だけ回すと、検知器が黙って死んでいても緑で通る。
**先に tests を通すこと。**

台帳の中身そのものの検査(列数・語彙・派生列の再現・突き合わせゲート)は、
データのある**プライベートリポジトリ側の `tests/`** が持つ。

## 1. 移設するファイル

WEKO3 リポジトリに `tools/api-inventory/` を作り、weko-document の
Expand All @@ -34,27 +47,34 @@ weko/tools/api-inventory/ ← public。ツールのみ
│ ├── paths.py $WEKO_API_INVENTORY_DIR の解決
│ ├── extract_routes.py … Phase 1-2: 静的抽出・観点付与
│ ├── probe.py / asuser.sh Phase 3: 実機Docker実測(参考実装)
│ ├── build_checklist.py Phase 5: 57列 → 24列の再生成
│ ├── schema.py 列定義の唯一の正(62列 / 32列)
│ ├── build_checklist.py Phase 5: 62列 → 32列の再生成
│ ├── snapshot.py Phase 6: 実機url_map → スナップショット
│ ├── diff_snapshot.py Phase 6: スナップショット間の差分 + ゲート
│ ├── reconcile.py Phase 6: スナップショット ↔ 台帳の突き合わせ
│ ├── detect_routes.py ソース(AST)↔ 台帳の突き合わせ。実機不要
│ ├── changed_rows.py Phase 6: git差分 → 再レビュー対象行
│ ├── fixtures.py Phase 7: 到達可否測定用の最小コーパス投入
│ ├── probe_ci.py Phase 7: フィクスチャ駆動の到達可否測定(CI が直接呼ぶ)
│ └── measure.sh 手作業で実測するときの唯一の入口(上記を固定順で回す)
├── tests/ ツールの単体テスト(pytest。データ不要)
├── pytest.ini
├── ci/
│ ├── api-inventory-drift.yml
│ ├── api-inventory-drift.yml 実機を起こして突き合わせる(60分枠)
│ ├── api-inventory-tests.yml ツールの単体テスト(数秒。Secret 不要)
│ └── README.md このファイル
└── .gitignore データ類を誤ってコミットしないための保険

$WEKO_API_INVENTORY_DIR/ ← プライベートリポジトリ。public リポジトリには置かない
├── weko3_api_list_full.tsv 台帳(57列・所見と実証結果つき)
├── weko3_api_list.tsv 台帳(24列)
├── weko3_api_list_README.md 24列の列定義・運用手順
├── weko3_api_list_full_README.md 57列の列定義
├── weko3_api_list_full.tsv 台帳(62列・所見と実証結果つき)
├── weko3_api_list.tsv 台帳(32列)
├── weko3_api_list_README.md 32列の列定義・運用手順
├── weko3_api_list_full_README.md 62列の列定義
├── api_snapshot.json 経路のベースライン
├── reconcile_allow.json 実機に無い行の許可リスト
├── reconcile_allow.json 実機に無いが台帳に残す行の許可リスト
├── detect_allow.json ソースにあるが経路にならないものの許可リスト
├── reconcile_report.md 突き合わせ結果
├── tests/ 台帳そのものの検査(pytest。実機不要)
└── weko3_api_auth_findings.md 調査記録
```

Expand Down
16 changes: 16 additions & 0 deletions tools/api-inventory/ci/api-inventory-drift.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@
# 個人アカウントに紐づかないため(PAT より事故時の影響が小さい)。
# 未設定なら、このジョブは何もせずスキップする(fork からの PR でも安全)。
#
# 網羅性は二段で見る:
# reconcile.py 実機 url_map ↔ 台帳(この環境で登録されている経路)
# detect_routes.py ソース(AST) ↔ 台帳(config で無効な経路まで含む)
# 前者だけだと、config で無効・プラグイン未導入の経路が台帳から落ちても気付けない。
#
# ツールそのものの単体テストは api-inventory-tests.yml(Secret も Docker も不要)。
#
# 設置手順: tools/api-inventory/ci/README.md

name: API Inventory Drift
Expand Down Expand Up @@ -147,6 +154,13 @@ jobs:
--snapshot /tmp/api_snapshot.new.json \
--summary-only --gate --out /tmp/reconcile.md

# 実機 url_map は「この環境で登録された経路」しか映さない。config で無効・
# プラグイン未導入・設定値が真のときだけ登録される経路は、API として
# 存在するのに reconcile では見えない。ソースからの検知で二段目を張る。
python3 $T/detect_routes.py \
--weko-root "$PWD" --cross-check \
--summary-only --gate --out /tmp/detect.md

- name: Probe changed endpoints
if: always() && steps.cfg.outputs.enabled == 'true'
env:
Expand Down Expand Up @@ -175,6 +189,7 @@ jobs:
path: |
/tmp/drift.md
/tmp/reconcile.md
/tmp/detect.md

- name: Comment on PR (counts only)
if: always() && steps.cfg.outputs.enabled == 'true' && github.event_name == 'pull_request'
Expand Down Expand Up @@ -206,6 +221,7 @@ jobs:
+ '該当箇所はプライベートリポジトリ側の台帳・レポートで確認してください。';
body += read('/tmp/drift.md', 'ベースラインとの差分');
body += read('/tmp/reconcile.md', '台帳との突き合わせ');
body += read('/tmp/detect.md', 'ソース由来の経路検知');
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
Expand Down
57 changes: 57 additions & 0 deletions tools/api-inventory/ci/api-inventory-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# WEKO3 リポジトリ(RCOSDP/weko)の .github/workflows/ に配置する。
#
# 台帳ツールの単体テスト。**Docker も実機も台帳も要らない**ので数秒で終わる。
# api-inventory-drift.yml(実機を起こして突き合わせる。60分枠)とは役割が違う:
#
# このワークフロー … 台帳を作る側(スクリプト・手順書)が壊れていないか
# drift ワークフロー … 台帳の中身が実機とずれていないか
#
# ツールが壊れたまま drift だけ回すと、検知器が黙って死んでいても緑で通る。
# 先にこちらを通すこと。Secret も不要なので fork からの PR でも動く。

name: API Inventory Tests

on:
pull_request:
paths:
- 'tools/api-inventory/**'
- '.github/workflows/api-inventory-tests.yml'
push:
branches: ['**']
paths:
- 'tools/api-inventory/**'
workflow_dispatch:

jobs:
unit:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v4

- uses: actions/setup-python@v5
with:
python-version: '3.11'

- name: Install pytest
run: python3 -m pip install --disable-pip-version-check pytest

- name: Run unit tests
working-directory: tools/api-inventory
run: python3 -m pytest -q

# 台帳が無くても、ソースからの経路検知そのものは動く。
# 検知件数が 0 に落ちていれば、検知器が壊れている。
- name: Smoke check the static detector
run: |
set -o pipefail
python3 tools/api-inventory/scripts/detect_routes.py \
--weko-root "$PWD" --summary-only | tee /tmp/detect.md
python3 - <<'PY'
import re, sys
text = open('/tmp/detect.md', encoding='utf-8').read()
total = int(re.search(r'\*\*計\*\* \| \*\*(\d+)\*\*', text).group(1))
print(f'detections={total}')
# 経路が数百ある前提のリポジトリ。2桁に落ちたら検知器の故障を疑う。
sys.exit(0 if total >= 300 else 1)
PY
11 changes: 11 additions & 0 deletions tools/api-inventory/pytest.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# 台帳ツールの単体テスト。
#
# cd tools/api-inventory && python3 -m pytest
#
# `scripts/test_coverage.py` は名前が test_ で始まるが**テストではない**
# (台帳にテスト観点を付与する本体スクリプト)。testpaths で tests/ に限定して
# 誤収集を防ぐ。
[pytest]
testpaths = tests
python_files = test_*.py
addopts = -q
Loading
Loading