mirror of
https://github.com/kuhyx/testsAndMisc.git
synced 2026-11-10 20:07:04 +01:00
Latest stable dependencies, gatelock v0.7.2, and the gate
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
924630c029
commit
1cf567977f
62
.github/workflows/dependency-freshness.yml
vendored
Normal file
62
.github/workflows/dependency-freshness.yml
vendored
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
name: dependency freshness
|
||||||
|
|
||||||
|
# Every dependency on its ecosystem's newest STABLE release, enforced on push
|
||||||
|
# as well as at commit time. The local pre-commit hook only sees the manifests
|
||||||
|
# in a commit and can be skipped entirely by a fresh clone that never ran
|
||||||
|
# `pre-commit install`; this runs `--all` over the whole repo.
|
||||||
|
#
|
||||||
|
# `--strict` is CI-only. Offline the gate degrades to its cached answer and
|
||||||
|
# passes, because `--no-verify` is banned locally and a hook that hard-failed
|
||||||
|
# on a flaky connection would leave no way to commit. A runner is always
|
||||||
|
# online, so here an undeterminable answer is a real failure.
|
||||||
|
#
|
||||||
|
# Expect this to go red for reasons this repo's commit did not cause: an
|
||||||
|
# upstream release overnight is enough. That is the chosen behaviour -- the
|
||||||
|
# alternative is a gate that only notices staleness when someone remembers to
|
||||||
|
# look.
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
pull_request:
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
dependency-freshness:
|
||||||
|
name: dependencies on newest stable
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
# The gate lives in the shared utils repo so every repo resolves the
|
||||||
|
# same "latest stable" the same way. Checking it out beats vendoring a
|
||||||
|
# copy, which is exactly how a gate and its survey start disagreeing.
|
||||||
|
- name: Check out the shared gate
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
repository: kuhyx/utils
|
||||||
|
path: .utils
|
||||||
|
|
||||||
|
# "3.x", never a pinned minor: the Python target IS the interpreter the
|
||||||
|
# gate runs under (registries/toolchain.python_installed), so a runner
|
||||||
|
# held a release behind this machine reports a repo's `requires-python`
|
||||||
|
# as excluding "latest" while the same check passes locally. flax-docs-mcp
|
||||||
|
# hit exactly that -- `>=3.14` green here, red on a 3.13 runner.
|
||||||
|
- name: Set up Python
|
||||||
|
uses: actions/setup-python@v5
|
||||||
|
with:
|
||||||
|
python-version: "3.x"
|
||||||
|
|
||||||
|
- name: Install the gate's two runtime dependencies
|
||||||
|
run: python -m pip install --upgrade pyyaml packaging
|
||||||
|
|
||||||
|
- name: Cache registry lookups
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: ~/.cache/dep-freshness
|
||||||
|
key: dep-freshness-${{ hashFiles('**/pubspec.yaml', '**/pyproject.toml',
|
||||||
|
'**/requirements*.txt', '**/package.json', '**/Cargo.toml', '**/go.mod') }}
|
||||||
|
restore-keys: dep-freshness-
|
||||||
|
|
||||||
|
- name: Every dependency is on newest stable
|
||||||
|
run: bash .utils/scripts/check_dependency_freshness.sh --all --strict
|
||||||
@ -592,3 +592,25 @@ repos:
|
|||||||
entry: scripts/check_md_naming.sh
|
entry: scripts/check_md_naming.sh
|
||||||
language: system
|
language: system
|
||||||
files: \.(md|markdown)$
|
files: \.(md|markdown)$
|
||||||
|
|
||||||
|
# Every dependency on its ecosystem's newest STABLE release, exact-pinned
|
||||||
|
# so the question is mechanically answerable at all.
|
||||||
|
#
|
||||||
|
# `files:` is what keeps this cheap: a commit touching only source makes
|
||||||
|
# ZERO network requests, and manifest commits mostly hit a 6h disk cache.
|
||||||
|
#
|
||||||
|
# Runs WITHOUT --strict on purpose. Offline it degrades to the cached
|
||||||
|
# answer and passes with a loud banner; `--no-verify` is banned here, so
|
||||||
|
# a hook that hard-failed on a flaky connection would leave no way to
|
||||||
|
# commit at all. CI, always online, is the strict authority.
|
||||||
|
- id: dependency-freshness
|
||||||
|
name: dependencies on newest stable
|
||||||
|
entry: scripts/check_dependency_freshness.sh
|
||||||
|
language: system
|
||||||
|
pass_filenames: true
|
||||||
|
files: >-
|
||||||
|
(pubspec\.(yaml|lock)|pyproject\.toml|requirements.*\.txt|uv\.lock
|
||||||
|
|package\.json|package-lock\.json|pnpm-lock\.yaml
|
||||||
|
|Cargo\.(toml|lock)|go\.(mod|sum)
|
||||||
|
|\.fvmrc|\.nvmrc|\.python-version
|
||||||
|
|\.github/workflows/.*\.ya?ml)$
|
||||||
|
|||||||
@ -0,0 +1,33 @@
|
|||||||
|
{
|
||||||
|
"intent": "Put every dependency this repo declares on its newest stable release, and install the shared dependency-freshness gate so it stays there.",
|
||||||
|
"scope": [
|
||||||
|
"meta/requirements.txt, meta/requirements-test.txt, python_pkg/random_jpg/requirements.txt",
|
||||||
|
".pre-commit-config.yaml, .github/workflows/dependency-freshness.yml, scripts/check_dependency_freshness.sh",
|
||||||
|
"Non-goal: no source changes; this is manifests and gate wiring only"
|
||||||
|
],
|
||||||
|
"changes": [
|
||||||
|
"Exact-pinned 95 previously range-specified dependencies to their newest stable release, via ~/.claude/scripts/apply_dep_pins.py driven by the gate's own --json findings.",
|
||||||
|
"Moved the gatelock git-tag dependency from gatelock-v0.1.0 to gatelock-v0.7.2 -- six minor versions of drift that a PEP 508 direct reference hid from every previous check.",
|
||||||
|
"Installed the shared gate's three pieces (delegate, pre-commit hook, CI workflow) from ~/utils/dep_freshness/templates."
|
||||||
|
],
|
||||||
|
"verification": [
|
||||||
|
{
|
||||||
|
"command": "REQUIREMENTS_FILE=meta/requirements.txt ./meta/scripts/ci_mirror.sh",
|
||||||
|
"result": "pass",
|
||||||
|
"evidence": "exit 0; clean venv rebuilt from the repinned meta/requirements.txt, pre-commit --all-files and the full suite green inside it"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "~/utils/scripts/check_dependency_freshness.sh --all",
|
||||||
|
"result": "pass",
|
||||||
|
"evidence": "exit 0 -- 97 findings before, 0 after"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"risks": [
|
||||||
|
"gatelock v0.1.0 -> v0.7.2 is a six-version jump in a shared library; the clean-venv mirror is what exercises it here.",
|
||||||
|
"Exact pins mean CI goes red on any upstream release until the pin is bumped. That is the chosen behaviour, not a regression."
|
||||||
|
],
|
||||||
|
"rollback": [
|
||||||
|
"git revert the commit; the pins and the three gate files are the whole change.",
|
||||||
|
"After reverting, re-run ci_mirror.sh to confirm the older pins still resolve."
|
||||||
|
]
|
||||||
|
}
|
||||||
@ -21,20 +21,20 @@
|
|||||||
# suite itself fails loudly here on a missing import.
|
# suite itself fails loudly here on a missing import.
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
|
|
||||||
anthropic>=0.25.0
|
anthropic==1.2.0
|
||||||
beautifulsoup4>=4.0
|
beautifulsoup4==4.15.0
|
||||||
coverage>=7.4.0
|
coverage==7.15.4
|
||||||
defusedxml>=0.7.1
|
defusedxml==0.7.1
|
||||||
markdownify>=1.2.0
|
markdownify==1.2.3
|
||||||
numpy>=1.20
|
numpy==2.5.2
|
||||||
pillow>=10.0
|
pillow==12.3.0
|
||||||
pytest>=8.0.0
|
pytest==9.1.1
|
||||||
pytest-cov>=4.1.0
|
pytest-cov==7.1.0
|
||||||
pytest-randomly>=3.15.0
|
pytest-randomly==4.1.0
|
||||||
pytest-sugar>=1.0.0
|
pytest-sugar==1.1.1
|
||||||
pytest-timeout>=2.2.0
|
pytest-timeout==2.4.0
|
||||||
pytest-xdist>=3.5.0
|
pytest-xdist==3.8.0
|
||||||
requests>=2.0
|
requests==2.34.2
|
||||||
rich>=13.0
|
rich==15.0.0
|
||||||
typer>=0.12.0
|
typer==0.27.2
|
||||||
typing_extensions
|
typing_extensions==4.16.0
|
||||||
|
|||||||
@ -4,82 +4,82 @@
|
|||||||
# Sorted alphabetically (enforced by pre-commit `requirements-txt-fixer`).
|
# Sorted alphabetically (enforced by pre-commit `requirements-txt-fixer`).
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
|
|
||||||
add-trailing-comma>=3.1.0
|
add-trailing-comma==4.0.0
|
||||||
aiohttp>=3.9
|
aiohttp==3.14.3
|
||||||
anthropic>=0.25.0
|
anthropic==1.2.0
|
||||||
autoflake>=2.2.0
|
autoflake==2.4.0
|
||||||
autopep8>=2.0.0
|
autopep8==2.3.2
|
||||||
bandit>=1.7.0
|
bandit==1.9.4
|
||||||
beautifulsoup4>=4.0
|
beautifulsoup4==4.15.0
|
||||||
berserk>=0.13
|
berserk==0.14.0
|
||||||
black>=24.0.0
|
black==26.5.1
|
||||||
bottle>=0.12
|
bottle==0.13.4
|
||||||
codespell>=2.2.0
|
codespell==2.4.3
|
||||||
coverage>=7.4.0
|
coverage==7.15.4
|
||||||
darglint>=1.8.0
|
darglint==1.8.1
|
||||||
dead>=1.5.0
|
dead==2.1.0
|
||||||
defusedxml>=0.7.1
|
defusedxml==0.7.1
|
||||||
docformatter>=1.7.0
|
docformatter==1.7.8
|
||||||
fixit>=2.1.0
|
fixit==2.2.1
|
||||||
flake8>=7.0.0
|
flake8==7.3.0
|
||||||
flake8-annotations>=3.0.0
|
flake8-annotations==3.2.0
|
||||||
flake8-bandit>=4.1.0
|
flake8-bandit==4.1.1
|
||||||
flake8-bugbear>=24.0.0
|
flake8-bugbear==25.11.29
|
||||||
flake8-comprehensions>=3.14.0
|
flake8-comprehensions==3.17.0
|
||||||
flake8-docstrings>=1.7.0
|
flake8-docstrings==1.7.0
|
||||||
flake8-eradicate>=1.5.0
|
flake8-eradicate==1.5.0
|
||||||
flake8-pie>=0.16.0
|
flake8-pie==0.16.0
|
||||||
flake8-print>=5.0.0
|
flake8-print==5.0.0
|
||||||
flake8-pyi>=24.0.0
|
flake8-pyi==26.5.0
|
||||||
flake8-pytest-style>=2.0.0
|
flake8-pytest-style==2.2.0
|
||||||
flake8-return>=1.2.0
|
flake8-return==1.2.0
|
||||||
flake8-simplify>=0.21.0
|
flake8-simplify==0.30.0
|
||||||
gatelock @ git+https://github.com/kuhyx/utils@gatelock-v0.1.0#subdirectory=gatelock
|
gatelock @ git+https://github.com/kuhyx/utils@gatelock-v0.7.2#subdirectory=gatelock
|
||||||
genanki>=0.13
|
genanki==0.13.1
|
||||||
geopandas>=1.0
|
geopandas==1.1.4
|
||||||
howlongtobeatpy>=1.0
|
howlongtobeatpy==1.0.23
|
||||||
hypothesis>=6.98.0
|
hypothesis==6.165.10
|
||||||
importlib-metadata>=7.0.0
|
importlib-metadata==9.0.1
|
||||||
interrogate>=1.5.0
|
interrogate==1.7.0
|
||||||
isort>=5.13.0
|
isort==9.0.1
|
||||||
lxml>=5.0
|
lxml==6.1.2
|
||||||
markdownify>=1.2.0
|
markdownify==1.2.3
|
||||||
matplotlib>=3.0
|
matplotlib==3.11.1
|
||||||
mccabe>=0.7.0
|
mccabe==0.7.0
|
||||||
mypy>=1.8.0
|
mypy==2.3.1
|
||||||
numpy>=1.20
|
numpy==2.5.2
|
||||||
opencv-python>=4.0
|
opencv-python==5.0.0.93
|
||||||
pillow>=10.0
|
pillow==12.3.0
|
||||||
pip-audit>=2.6.0
|
pip-audit==2.10.1
|
||||||
pipdeptree>=2.14.0
|
pipdeptree==4.2.2
|
||||||
pre-commit>=3.6.0
|
pre-commit==4.6.2
|
||||||
prospector>=1.10.0
|
prospector==1.19.1
|
||||||
pycodestyle>=2.11.0
|
pycodestyle==2.14.0
|
||||||
pydocstyle>=6.3.0
|
pydocstyle==6.3.0
|
||||||
pyflakes>=3.2.0
|
pyflakes==3.4.0
|
||||||
pygame>=2.0
|
pygame==2.6.1
|
||||||
pylint>=3.0.0
|
pylint==4.0.7
|
||||||
pyright>=1.1.350
|
pyright==1.1.411
|
||||||
pytest>=8.0.0
|
pytest==9.1.1
|
||||||
pytest-cov>=4.1.0
|
pytest-cov==7.1.0
|
||||||
pytest-randomly>=3.15.0
|
pytest-randomly==4.1.0
|
||||||
pytest-sugar>=1.0.0
|
pytest-sugar==1.1.1
|
||||||
pytest-timeout>=2.2.0
|
pytest-timeout==2.4.0
|
||||||
pytest-xdist>=3.5.0
|
pytest-xdist==3.8.0
|
||||||
python-chess>=1.999
|
python-chess==1.999
|
||||||
python-kasa>=0.7
|
python-kasa==0.10.2
|
||||||
pyupgrade>=3.15.0
|
pyupgrade==3.21.2
|
||||||
radon>=6.0.0
|
radon==6.0.1
|
||||||
reorder-python-imports>=3.12.0
|
reorder-python-imports==3.17.0
|
||||||
requests>=2.0
|
requests==2.34.2
|
||||||
rich>=13.0
|
rich==15.0.0
|
||||||
ruff>=0.8.0
|
ruff==0.16.5
|
||||||
safety>=2.3.0
|
safety==3.8.1
|
||||||
selenium>=4.0
|
selenium==4.48.0
|
||||||
typer>=0.12.0
|
typer==0.27.2
|
||||||
types-python-dateutil>=2.8.0
|
types-python-dateutil==2.9.0.20260807
|
||||||
types-PyYAML>=6.0.0
|
types-PyYAML==6.0.12.20260815
|
||||||
types-requests>=2.31.0
|
types-requests==2.33.0.20260712
|
||||||
types-setuptools>=69.0.0
|
types-setuptools==84.0.0.20260812
|
||||||
typing_extensions # Self annotation on py310 target (session_autopsy store lock)
|
typing_extensions==4.16.0# Self annotation on py310 target (session_autopsy store lock)
|
||||||
websockets>=13.0
|
websockets==17.1
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
pillow
|
pillow==12.3.0
|
||||||
|
|||||||
34
scripts/check_dependency_freshness.sh
Executable file
34
scripts/check_dependency_freshness.sh
Executable file
@ -0,0 +1,34 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Fail if any dependency in the commit is behind its ecosystem's newest stable.
|
||||||
|
#
|
||||||
|
# Thin delegate to the shared gate in ~/utils, which owns the registry
|
||||||
|
# adapters, the pre-release rules and the allowlist semantics. Copying that
|
||||||
|
# logic here is what lets one repo's idea of "current" drift from every other
|
||||||
|
# repo's -- so this script only locates the shared checker and forwards its
|
||||||
|
# arguments.
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# scripts/check_dependency_freshness.sh <file> [<file> ...] # pre-commit
|
||||||
|
# scripts/check_dependency_freshness.sh --all --strict # CI
|
||||||
|
#
|
||||||
|
# Exit: 0 current | 1 behind | 2 allowlist wrong | 3 undeterminable (offline)
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
readonly SHARED_GATE="${UTILS_ROOT:-$HOME/utils}/scripts/check_dependency_freshness.sh"
|
||||||
|
|
||||||
|
main() {
|
||||||
|
if [[ ! -x "$SHARED_GATE" ]]; then
|
||||||
|
echo "Error: shared dependency-freshness gate not found at $SHARED_GATE" >&2
|
||||||
|
echo " Clone github.com/kuhyx/utils to ~/utils, or set" >&2
|
||||||
|
echo " UTILS_ROOT to where it lives." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
exec bash "$SHARED_GATE" "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
main "$@"
|
||||||
Loading…
Reference in New Issue
Block a user