Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
9e32ff8
ci: GitHub で回っていなかったユニットテストを回す
mhaya Sep 2, 2026
06a072d
ci: ローカルと CI で同じ経路を通す仕組みを入れる
mhaya Sep 2, 2026
7ecb552
ci: ローカル実行を CPU アーキで分岐させない
mhaya Sep 2, 2026
7bd194b
test: CI で初めて走ったユニットテストの失敗を直す (第1弾)
mhaya Sep 3, 2026
c4f611d
test: CI で初めて走ったユニットテストの失敗を直す (第2弾)
mhaya Sep 3, 2026
7093021
test: weko-itemtypes-ui の register ACL / 重複マッピング判定を直す
mhaya Sep 3, 2026
4046d35
test: CI で初めて走ったユニットテストの失敗を直す (第3弾)
mhaya Sep 3, 2026
ecd14da
test: CI で初めて走ったユニットテストの失敗を直す (第4弾)
mhaya Sep 3, 2026
3e5e371
test: CI で初めて走ったユニットテストの失敗を直す (第5弾)
mhaya Sep 3, 2026
449e2c9
test: CI で初めて走ったユニットテストの失敗を直す (第6弾)
mhaya Sep 3, 2026
73422d2
test: CI で初めて走ったユニットテストの失敗を直す (第7弾)
mhaya Sep 3, 2026
b73242d
test: CI で初めて走ったユニットテストの失敗を直す (第8弾)
mhaya Sep 3, 2026
a2d3c5a
test: CI で初めて走ったユニットテストの失敗を直す (第9弾)
mhaya Sep 3, 2026
608d096
test: 残りのユニットテスト失敗を直し、ジョブの制限時間を実測に合わせる
mhaya Sep 3, 2026
01972a3
ci: 5時間かかるモジュールをテスト本数で分割して回す
mhaya Sep 3, 2026
51c092b
ci: 分割の偏りに合わせて分割数と制限時間を見直す
mhaya Sep 4, 2026
8dbb3aa
test: weko-search-ui の NDL JaLC まわりの期待値を実挙動に合わせる
mhaya Sep 4, 2026
0590cc8
test: weko-workflow の残り 15 本を直す
mhaya Sep 4, 2026
e03613f
test: weko-workflow [8/8] が 120 分で打ち切られていた原因を潰す
mhaya Sep 5, 2026
8cd4b70
test: weko-deposit [8/8] が 120 分で打ち切られていた原因を潰す
mhaya Sep 5, 2026
a2e0de7
ci: テストのタイムアウトを実際に効かせる
mhaya Sep 5, 2026
fd2f386
test: weko-deposit の失敗を直す (1/2)
mhaya Sep 5, 2026
1510213
test: weko-deposit の失敗を直す (2/2)
mhaya Sep 5, 2026
e6cd609
test: weko-deposit の残り 3 本を直す
mhaya Sep 5, 2026
d532a5b
test: weko-records-ui の 5 本を直す
mhaya Sep 5, 2026
3d3852c
test: weko-search-ui の 10 本を直す
mhaya Sep 5, 2026
4b38d9e
test: weko-search-ui の最後の1本 (test_check_jsonld_import_items) を直す
mhaya Sep 5, 2026
5a7e6d6
test: CI に残っていた5本を直す
mhaya Sep 5, 2026
d6115d2
test: test_function_issue35902 の比較を並び順に依存させない
mhaya Sep 5, 2026
b69d49b
test: weko-search-ui [6/6] の 3 本を直す
mhaya Sep 5, 2026
cefaa30
test: 時刻依存と werkzeug 依存の2本を直す
mhaya Sep 5, 2026
d7803c6
test: 共有された WEKO_SEARCH_KEYWORDS_DICT の破壊を止める
mhaya Sep 5, 2026
f22d8d1
test: create_export_all_data のレコード数を減らす
mhaya Sep 5, 2026
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
59 changes: 59 additions & 0 deletions .github/workflows/api-inventory-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# WEKO3 リポジトリ(RCOSDP/weko)の .github/workflows/ に配置する。
#
# 台帳ツールの単体テスト。**Docker も実機も台帳も要らない**ので数秒で終わる。
# api-inventory-drift.yml(実機を起こして突き合わせる。60分枠)とは役割が違う:
#
# このワークフロー … 台帳を作る側(スクリプト・手順書)が壊れていないか
# drift ワークフロー … 台帳の中身が実機とずれていないか
#
# ツールが壊れたまま drift だけ回すと、検知器が黙って死んでいても緑で通る。
# 先にこちらを通すこと。Secret も不要なので fork からの PR でも動く。

name: API Inventory Tests

# 対象は tools/api-inventory/ だけなので、そこを触ったときだけ回す。
# push と pull_request でパスの並びを揃えること(片方だけ古びると、
# 「PR では回るが push では回らない」といった説明のつかない差になる)。
on:
pull_request:
paths: &paths
- 'tools/api-inventory/**'
- '.github/workflows/api-inventory-tests.yml'
push:
branches: ['**']
paths: *paths
Comment on lines +19 to +24

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): GitHub Actions rejects these workflow files because its workflow parser does not support YAML anchors and aliases. The API Inventory Tests workflow therefore fails validation and never starts, so neither the 107 unit tests nor the smoke check runs.

Suggested fix: Spell out the paths list separately for pull_request and push, or generate/synchronize the workflow files outside GitHub Actions rather than using YAML anchors.

Suggested change
paths: &paths
- 'tools/api-inventory/**'
- '.github/workflows/api-inventory-tests.yml'
push:
branches: ['**']
paths: *paths
paths:
- 'tools/api-inventory/**'
- '.github/workflows/api-inventory-tests.yml'
push:
branches: ['**']
paths:
- 'tools/api-inventory/**'
- '.github/workflows/api-inventory-tests.yml'

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
209 changes: 157 additions & 52 deletions .github/workflows/unit-tests.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# ユニットテスト。
#
# 【設計】本体イメージは「1回だけ」ビルドして GHCR に置き、45個のマトリクス
# 【設計】本体イメージは「1回だけ」ビルドして GHCR に置き、47個のマトリクス
# ジョブはそれを pull するだけにしている。
#
# - イメージの用意は ci-images.yml (UIテストと共通) に委譲している。
Expand All @@ -20,6 +20,11 @@
# - tox が毎回 requirements2.txt (約290パッケージ) を入れ直す分は、
# bind mount 済みの .ci-cache/pip を pip のキャッシュにして共有する。
#
# - 手元で同じことをするには scripts/ci/run-local.sh を使う。同じ compose
# オーバレイ・同じ待ち受けスクリプト・同じ run-module-tests.sh・同じマトリクスを
# 読むので、ローカルと CI で結果が食い違わない。
# モジュール一覧はこのファイルの matrix が唯一の正 (scripts/ci/matrix.sh が読む)。
#
# fork からの PR は GHCR に push できない。その場合はビルドキャッシュ
# (type=gha) だけ作り、各ジョブがそこからローカルビルドする。

Expand All @@ -36,6 +41,18 @@ on:
default: false

jobs:
# マトリクスの列挙漏れを止める。数十行のリストは静かに古びる:
# v2.0.5 までに weko-notifications / weko-signposting / weko-workspace の3つが
# 漏れ、テスト一式(283本)を持ちながら一度も実行されていなかった。
# ジョブが立たない以上、赤くもならないので誰も気付けない。
matrix-check:
name: Matrix covers every testable module
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v4
- run: bash scripts/ci/matrix.sh check

images:
uses: ./.github/workflows/ci-images.yml
permissions:
Expand All @@ -45,10 +62,14 @@ jobs:
force_rebuild: ${{ inputs.force_rebuild || false }}

test:
name: ${{ matrix.module }}
name: ${{ matrix.module }}${{ matrix.shard && format(' [{0}]', matrix.shard) || '' }}
needs: images
runs-on: ubuntu-latest
timeout-minutes: 60
# 分割後の実測は1ジョブ 5〜47 分。ただし本数で等分しているだけなので
# 重いテストが1本に寄ると伸びる (weko-deposit [4/4] と
# weko-records-ui [4/4] が 90 分で cancelled になった)。上限は 120 分。
# 分割の考え方は下の matrix.include のコメントを参照。
timeout-minutes: 120
permissions:
contents: read
packages: read
Expand All @@ -59,54 +80,137 @@ jobs:
WEKO_NGINX_IMAGE: ${{ needs.images.outputs.nginx }}
strategy:
fail-fast: false
max-parallel: 4
# 分割でジョブ数が 47 → 73 に増えた。1ジョブあたり tox の依存導入
# (約290パッケージ) が乗るので、同時実行を上げないと全体の時間が延びる。
max-parallel: 8
matrix:
module:
- invenio-accounts
- invenio-communities
- invenio-db
- invenio-deposit
- invenio-files-rest
- invenio-iiif
- invenio-indexer
- invenio-mail
- invenio-oaiharvester
- invenio-oaiserver
- invenio-oauth2server
- invenio-previewer
- invenio-queues
- invenio-records-rest
- invenio-records
- invenio-resourcesyncclient
- invenio-resourcesyncserver
- invenio-s3
- invenio-stats
- weko-accounts
- weko-admin
- weko-authors
- weko-bulkupdate
- weko-deposit
- weko-gridlayout
- weko-groups
- weko-handle
- weko-index-tree
- weko-indextree-journal
- weko-items-autofill
- weko-items-ui
- weko-itemtypes-ui
- weko-logging
- weko-plugins
- weko-records-ui
- weko-records
- weko-redis
- weko-schema-ui
- weko-search-ui
- weko-sitemap
- weko-swordserver
- weko-theme
- weko-user-profiles
- weko-workflow

# モジュール一覧はここが唯一の正 (scripts/ci/matrix.sh が読み、
# matrix-check ジョブが列挙漏れを止める)。
#
# shard を付けたものは pytest-split で本数を等分し、1ジョブ1本だけ回す。
# 付けていないモジュールは従来どおり全件を1ジョブで回す。
#
# 【なぜ分割するか】weko-workflow は 794 本で 4時間54分かかり、
# timeout を 60 → 120 分に上げても足りなかった。GitHub のジョブ上限は
# 6 時間なので、上限を上げ続ける形では解決しない。
# 効いているのは各モジュールの conftest.py の db フィクスチャで、
# 1テストごとに WEKO 全モジュール分のテーブルを drop_all()/create_all()
# している (1件あたり約22秒)。フィクスチャのスコープを見直せば
# 分割は不要になるが、テスト間の独立性が変わるので別途 (issues.md C-1)。
#
# 【分割数の決め方】1ジョブ 30 分前後に収まるまで割る。CI 実測:
# weko-workflow 8分割 → 11〜15分 (ローカル通しでは 4時間54分)
# weko-deposit 4分割 → 4〜29分、ただし[4/4]だけ 90分超で cancelled
# weko-records-ui 4分割 → 44〜47分、[4/4]は 90分超で cancelled
# weko-search-ui 4分割 → 11〜29分
# pytest-split は**本数**で等分するだけなので、重いテストが1本に寄ると
# このように偏る。偏った2つは分割数を倍にした。
# (根治は .test_durations を作って時間で割ること。issues.md C-1)
# test_views.py だけで 447 本あるためファイル単位では割れない。
include:
- module: invenio-accounts
- module: invenio-communities
- module: invenio-db
- module: invenio-deposit
- module: invenio-files-rest
- module: invenio-iiif
- module: invenio-indexer
- module: invenio-mail
- module: invenio-oaiharvester
- module: invenio-oaiserver
- module: invenio-oauth2server
- module: invenio-previewer
- module: invenio-queues
- module: invenio-records-rest
- module: invenio-records
- module: invenio-resourcesyncclient
- module: invenio-resourcesyncserver
- module: invenio-s3
- module: invenio-stats
- module: weko-accounts
- module: weko-admin
- module: weko-authors
- module: weko-bulkupdate
- module: weko-deposit
shard: 1/8
- module: weko-deposit
shard: 2/8
- module: weko-deposit
shard: 3/8
- module: weko-deposit
shard: 4/8
- module: weko-deposit
shard: 5/8
- module: weko-deposit
shard: 6/8
- module: weko-deposit
shard: 7/8
- module: weko-deposit
shard: 8/8
- module: weko-gridlayout
- module: weko-groups
- module: weko-handle
- module: weko-index-tree
- module: weko-indextree-journal
- module: weko-items-autofill
- module: weko-items-ui
- module: weko-itemtypes-ui
- module: weko-logging
- module: weko-notifications
- module: weko-plugins
- module: weko-records-ui
shard: 1/8
- module: weko-records-ui
shard: 2/8
- module: weko-records-ui
shard: 3/8
- module: weko-records-ui
shard: 4/8
- module: weko-records-ui
shard: 5/8
- module: weko-records-ui
shard: 6/8
- module: weko-records-ui
shard: 7/8
- module: weko-records-ui
shard: 8/8
- module: weko-records
- module: weko-redis
- module: weko-schema-ui
- module: weko-search-ui
shard: 1/6
- module: weko-search-ui
shard: 2/6
- module: weko-search-ui
shard: 3/6
- module: weko-search-ui
shard: 4/6
- module: weko-search-ui
shard: 5/6
- module: weko-search-ui
shard: 6/6
- module: weko-signposting
- module: weko-sitemap
- module: weko-swordserver
- module: weko-theme
- module: weko-user-profiles
- module: weko-workflow
shard: 1/8
- module: weko-workflow
shard: 2/8
- module: weko-workflow
shard: 3/8
- module: weko-workflow
shard: 4/8
- module: weko-workflow
shard: 5/8
- module: weko-workflow
shard: 6/8
- module: weko-workflow
shard: 7/8
- module: weko-workflow
shard: 8/8
- module: weko-workspace
steps:
- name: Checkout code
uses: actions/checkout@v4
Expand Down Expand Up @@ -185,7 +289,8 @@ jobs:
- name: Run tox in ${{ matrix.module }}
run: |
docker compose run --rm --no-deps -T \
web bash /code/scripts/ci/run-module-tests.sh '${{ matrix.module }}'
web bash /code/scripts/ci/run-module-tests.sh \
'${{ matrix.module }}' '${{ matrix.shard }}'

- name: Show logs if failed
if: failure()
Expand All @@ -199,7 +304,7 @@ jobs:
[ -d .ci-cache ] || exit 0
sudo chown -R "$(id -u):$(id -g)" .ci-cache

# 45ジョブが同じキーで保存を試みるが、先着1つだけが保存され残りは
# 47ジョブが同じキーで保存を試みるが、先着1つだけが保存され残りは
# 予約に失敗してスキップされる(警告のみ)。モジュール間で
# requirements2.txt はほぼ同一なので、1つ保存されれば全体に効く。
- name: Save pip cache
Expand Down
60 changes: 53 additions & 7 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,56 @@
- 環境構築後、`https://127.0.0.1/` でサーバにアクセスすることができる。

## テストの実行方法 / Testing
- ユニットテストを実行: `python manage.py test`
(またはpytest使用時: `pytest`)
- 新機能を追加した際は必ず対応するテストコードを追加してください
- テストが全てパスすることを確認してから変更を確定します

### 手元で回す — **CI と同じ経路を使うこと**

```bash
scripts/ci/run-local.sh weko-records # 1モジュール
scripts/ci/run-local.sh --all # マトリクス全部
scripts/ci/run-local.sh --list # 対象モジュール一覧
```

GitHub Actions の Unit Tests ジョブと同じ compose オーバレイ・同じ待ち受け
スクリプト・同じ `run-module-tests.sh`(= tox)・同じモジュール一覧を使う。
**別の回し方をしないこと。** 違う回し方をすると、テストは正常なのに落ちる:

- 手元の無関係な `weko-web` イメージを流用 → イメージに焼き付いた古い egg-info の
entry_point を `invenio_assets` が読みにいって大量の ImportError
- invenio の venv で直接 `pytest` → `pytest-mock` / `mock` が無く
`fixture 'mocker' not found`

`run-local.sh` は起動前に「別の WEKO スタックとのポート衝突」と
「イメージの egg-info が古くないか」を確認して、この2つを事前に落とす。

CI との差は Elasticsearch を `discovery.type=single-node` で起動する1点だけ
(AMD / ARM を問わず同じ。理由は `scripts/ci/compose.local.yml`)。
**最終的な合否は CI で確認する。**

詳細は `README-TEST.md`。

### 台帳ツール(tools/api-inventory)のテスト

```bash
cd tools/api-inventory && python3 -m pytest # 数秒。Docker も台帳も不要
```

### 新しいモジュールを足したとき

`.github/workflows/unit-tests.yml` の `matrix.module` が**モジュール一覧の唯一の正**。
`tests/` と `tox.ini` を持つのに未登録だと、CI の `matrix-check` ジョブが落とす
(ジョブが立たない = 赤くもならない、という静かな漏れを防ぐため。実際に3モジュール
283本がこの状態で放置されていた)。手元では次で確認する。

```bash
scripts/ci/matrix.sh check
```

### 変更を確定する前に

- 新機能を追加した際は必ず対応するテストコードを追加する
- 触ったモジュールを `run-local.sh` で回し、パスすることを確認する
- 既存の失敗と自分の変更による失敗を必ず区別する。develop_v2.0.5 時点で
ベースラインに複数の失敗が残っているため、「赤い = 自分のせい」とは限らない

## コードスタイル / Code Style
- コーディング規約: **PEP8**に準拠 (スタイルガイドの遵守)
Expand All @@ -28,12 +74,12 @@

## セキュリティ方針 / Security
- **秘密情報は厳重に管理**: APIキーやパスワードなど秘密情報は`.env`や環境変数から読み込み、絶対にGitに含めないでください
- **ユーザ入力の検証**: フォームやAPIで受け取る入力はDjangoのバリデーション機構で適切に検証してください
- **デバッグ設定**: 開発中以外では`DEBUG = False`に設定し、エラーページや機密情報が漏洩しないようにします
- **ユーザ入力の検証**: フォームやAPIで受け取る入力は Flask-WTF / marshmallow / JSON Schema など、そのモジュールで既に使われている検証機構で必ず検証してください(本プロジェクトは Django ではありません)
- **デバッグ設定**: 開発中以外では `FLASK_ENV=production` / `DEBUG = False` とし、エラーページや機密情報が漏洩しないようにします
- **依存パッケージ**: 新しいパッケージを導入する際はセキュリティ面を確認し、必要に応じてチームの承認を得てください

## プルリクエストガイドライン / PR Guidelines
- **タイトル形式**: `feat: 機能概要` のように、プレフィックスと簡潔な説明を書いてください
- **事前チェック**: コードを提出する前に `flake8` や `pytest` を実行し、エラーやテスト失敗がないことを確認しましょう
- **事前チェック**: コードを提出する前に `flake8` と `scripts/ci/run-local.sh <触ったモジュール>` を実行し、エラーやテスト失敗がないことを確認しましょう
- **差分の範囲**: 1つのPRは関連する変更に留め、小さくまとまった変更を心がけてください(大規模な変更は分割を検討)
- **説明コメント**: PRの説明欄には変更内容と目的、動作確認の方法を簡潔に記述してください
Loading
Loading