Skip to content

feat(ci): 週次 schedule と workflow_dispatch を追加し外界の変化を検知する (v1.8.169) #938

feat(ci): 週次 schedule と workflow_dispatch を追加し外界の変化を検知する (v1.8.169)

feat(ci): 週次 schedule と workflow_dispatch を追加し外界の変化を検知する (v1.8.169) #938

Workflow file for this run

name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
# 週次で main をフル実行する(push とは独立に)。
#
# 検知したいのは「コードの変化」ではなく **外界の変化** — 上流の advisory データである。
# 2026-05-30 から 2026-08-12 までの 74 日間、このリポジトリには 1 コミットも無く、
# CI も一度も走らなかった。その間にコードは 1 行も変わっていないのに `pip-audit` の
# 検出数は 0 → 22 件(pyjwt / cryptography / starlette を含む=認証と TLS の面)へ増えていた。
# advisory は我々のコミットではなく、それ自身の時計で公開されるためである。
#
# ここでの検知器は `pip-audit`。`uv.lock` をコミットしていて `uv sync` がそれを尊重するので、
# 週次実行は「いま固定している版に対する既知脆弱性」を正確に測る。
#
# 毎時 00 分は GitHub Actions の高負荷帯で schedule が遅延しやすいと公式に明記されているため、
# 意図的に 30 分にずらしている。月曜 00:30 UTC = 09:30 JST(週明けの始業時刻)。
#
# 🔴 既知の限界: public リポジトリの scheduled workflow は、リポジトリの活動が 60 日間
# 無いと GitHub により **自動的に無効化される**。上記の空白は 74 日で、しきい値を 14 日
# 超えている。つまりこの装置は、それが検知しようとしている状態そのものによって止められうる。
# 「週次が動いている」ことを外側から確かめる仕組みは、この workflow では解決できない
# (docs/review/2026-08-12.md の後続タスク)。
schedule:
- cron: '30 0 * * 1'
# schedule の初回発火を待たずに動作確認・再実行するための手動トリガー。
workflow_dispatch:
# 同一 ref への連続 push で古い実行を打ち切り、CI 時間を無駄にしない。
# 🔴 `github.event_name` を必ず group に含めること。含めないと schedule / workflow_dispatch の
# 実行が push の実行に cancel され、「設定したのに走らない」状態になる。設定ファイルは
# 正しく見えるのに動かないため気づきにくい(nene-origin で実測された罠)。
concurrency:
group: ci-${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}
cancel-in-progress: true
jobs:
check:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.12", "3.14"]
steps:
- uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v5
with:
version: "latest"
enable-cache: true
- name: Set up Python ${{ matrix.python-version }}
run: uv python install ${{ matrix.python-version }}
- name: Install dependencies
run: uv sync --all-extras
- name: pytest (with coverage)
run: uv run pytest
- name: coverage gate — domain/use_case layers (90%)
run: |
uv run coverage report \
--include="src/example/*/use_case.py,src/example/*/async_use_case.py,src/example/*/entity.py" \
--fail-under=90
- name: mypy
run: uv run mypy src/
- name: ruff check
run: uv run ruff check src/ tests/
- name: ruff format
run: uv run ruff format --check src/ tests/
- name: pip-audit
# PYSEC-2025-183: pyjwt weak-key-length — disputed by supplier, no fix version available.
# Transitive via mcp>=1.0. Re-evaluate when pyjwt releases a fix. (#280)
run: uv run pip-audit --ignore-vuln PYSEC-2025-183
integration-db:
name: Real-DB integration tests
runs-on: ubuntu-latest
# 実 PostgreSQL / MySQL に対してリポジトリ層を検証する(#747)。
# SQLite だけでは露見しなかった lastrowid 由来の採番バグを CI で恒常的に防ぐ。
services:
postgres:
image: postgres:16-alpine
env:
POSTGRES_PASSWORD: nene2
POSTGRES_DB: nene2_test
ports:
- 5432:5432
options: >-
--health-cmd "pg_isready -U postgres"
--health-interval 5s --health-timeout 5s --health-retries 10
mysql:
image: mysql:8
env:
MYSQL_ROOT_PASSWORD: nene2
MYSQL_DATABASE: nene2_test
ports:
- 3306:3306
options: >-
--health-cmd "mysqladmin ping -uroot -pnene2"
--health-interval 5s --health-timeout 5s --health-retries 20
steps:
- uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v5
with:
version: "latest"
enable-cache: true
- name: Set up Python
run: uv python install 3.14
- name: Install dependencies
run: uv sync --all-extras
- name: integration tests (PostgreSQL + MySQL)
env:
NENE2_TEST_POSTGRES_URL: postgresql+psycopg2://postgres:nene2@127.0.0.1:5432/nene2_test
NENE2_TEST_MYSQL_URL: mysql+pymysql://root:nene2@127.0.0.1:3306/nene2_test
run: uv run pytest tests/integration/ -v --no-cov
package-build:
name: Package build verification
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v5
with:
version: "latest"
# publish.yml と同じ uv build を PR ごとに走らせ、配布物の壊れを早期検出する(#541)。
- name: Build sdist + wheel
run: uv build
- name: Validate distribution metadata (twine check)
run: uvx twine check dist/*
- name: Verify clean install + import (no example/tests leakage)
run: |
uv venv /tmp/verify
uv pip install --python /tmp/verify/bin/python dist/*.whl
/tmp/verify/bin/python -c "import nene2; from nene2.http import PaginationResponse; print('import OK')"
# フレームワーク以外(example/tests)が配布物に混入していないことを保証
if /tmp/verify/bin/python -c "import example" 2>/dev/null; then
echo "ERROR: example package leaked into wheel"; exit 1
fi