Skip to content

Commit 2a135d7

Browse files
committed
fix: review comments
1 parent 623370c commit 2a135d7

4 files changed

Lines changed: 109 additions & 17 deletions

File tree

.github/dependabot.yml

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,12 @@ updates:
1010
labels:
1111
- "dependencies"
1212

13-
# Keep Python runtime dependencies up-to-date within the bounded ranges
14-
# declared in requirements.txt / pyproject.toml.
15-
# Dependabot opens a PR for each package that has a new version available.
16-
# After merging, regenerate requirements-lock.txt by running the
17-
# "Update dependency lock file" workflow (or locally with pip-compile).
13+
# Keep Python runtime dependencies up-to-date within the bounded ranges in
14+
# pyproject.toml [project.dependencies] (requirements.txt must stay in sync).
15+
# Dependabot opens a PR when a newer version fits those bounds — it does NOT
16+
# refresh requirements-lock.txt. CI installs from the lock, so after merging a
17+
# Dependabot pip PR you must regenerate the lock: run the "Update dependency
18+
# lock file" workflow (Actions tab) or pip-compile locally (see README).
1819
- package-ecosystem: "pip"
1920
directory: "/"
2021
schedule:

.github/workflows/tests.yml

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,58 @@ concurrency:
1616
cancel-in-progress: true
1717

1818
jobs:
19+
# ── Lock file + requirements sync (closes #47) ───────────────────────────
20+
lockfile:
21+
name: Lock file freshness
22+
runs-on: ubuntu-latest
23+
steps:
24+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
25+
26+
- name: Set up Python
27+
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
28+
with:
29+
python-version: "3.12"
30+
31+
- name: Verify requirements.txt matches pyproject.toml
32+
run: |
33+
python <<'PY'
34+
import sys
35+
import tomllib
36+
from pathlib import Path
37+
38+
with open("pyproject.toml", "rb") as f:
39+
py_deps = tomllib.load(f)["project"]["dependencies"]
40+
req_deps = [
41+
line.strip()
42+
for line in Path("requirements.txt").read_text().splitlines()
43+
if line.strip() and not line.strip().startswith("#")
44+
]
45+
if sorted(py_deps) != sorted(req_deps):
46+
print(
47+
"requirements.txt [project.dependencies] drift from pyproject.toml",
48+
file=sys.stderr,
49+
)
50+
print("pyproject.toml:", sorted(py_deps), file=sys.stderr)
51+
print("requirements.txt:", sorted(req_deps), file=sys.stderr)
52+
sys.exit(1)
53+
PY
54+
55+
- name: Install pip-tools
56+
run: python -m pip install pip-tools
57+
58+
- name: Verify requirements-lock.txt is up to date
59+
# Same pip-compile flags as update-lock.yml, without --upgrade.
60+
run: |
61+
pip-compile requirements.txt \
62+
--output-file /tmp/requirements-lock.txt \
63+
--no-header \
64+
--annotation-style=line \
65+
--allow-unsafe \
66+
--quiet
67+
diff -u \
68+
<(grep -E '^[A-Za-z0-9_.-]+==' requirements-lock.txt | sort) \
69+
<(grep -E '^[A-Za-z0-9_.-]+==' /tmp/requirements-lock.txt | sort)
70+
1971
# ── Unit tests: matrix across OS and Python version ───────────────────────
2072
# Closes #13. The unittest suite is the merge gate. Multi-OS catches the
2173
# rare path / line-ending issue that a single-OS run hides; multi-Python

.github/workflows/update-lock.yml

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,19 @@ jobs:
3636
--allow-unsafe \
3737
--upgrade
3838
39-
- name: Restore header comment
40-
# pip-compile --no-header omits the auto-generated header line but
41-
# we maintain our own documentation header; restore it if missing.
39+
- name: Prepend lock file header
40+
# pip-compile --no-header strips our docs header every run; restore via
41+
# heredoc (single-quoted HEADER=... would leave literal \n characters).
4242
run: |
43-
HEADER='# Pinned lock file — generated by pip-compile (pip-tools).\n# Install: pip install -r requirements-lock.txt\n# Update: pip-compile requirements.txt --output-file requirements-lock.txt --no-header --annotation-style=line --allow-unsafe\n# Run periodically (e.g. via the "Update dependency lock file" CI workflow) to pick up\n# upstream patch / security releases within the bounded ranges in requirements.txt.'
44-
if ! head -1 requirements-lock.txt | grep -q "^#"; then
45-
printf '%s\n' "$HEADER" | cat - requirements-lock.txt > /tmp/lock.tmp
46-
mv /tmp/lock.tmp requirements-lock.txt
47-
fi
43+
cat > /tmp/lock-header <<'EOF'
44+
# Pinned lock file — generated by pip-compile (pip-tools).
45+
# Install: pip install -r requirements-lock.txt
46+
# Update: pip-compile requirements.txt --output-file requirements-lock.txt --no-header --annotation-style=line --allow-unsafe
47+
# Run periodically (e.g. via the "Update dependency lock file" CI workflow) to pick up
48+
# upstream patch / security releases within the bounded ranges in requirements.txt.
49+
EOF
50+
cat /tmp/lock-header requirements-lock.txt > /tmp/lock.tmp
51+
mv /tmp/lock.tmp requirements-lock.txt
4852
4953
- name: Open PR if lock file changed
5054
uses: peter-evans/create-pull-request@22a9089034f40e5a961c8808d113e2c98fb63676 # v7
@@ -57,6 +61,11 @@ jobs:
5761
Automated weekly refresh of `requirements-lock.txt`.
5862
5963
Generated by `pip-compile --upgrade` from the bounded specifiers
60-
in `requirements.txt`. Review the diff to confirm no unexpected
61-
major-version jumps before merging.
64+
in `requirements.txt` (must match `pyproject.toml` `[project.dependencies]`).
65+
66+
**Dependabot pip PRs** may bump bounds in `requirements.txt` / `pyproject.toml`
67+
but do not regenerate this lock file — merge those first, then merge this PR
68+
(or run **Actions → Update dependency lock file → Run workflow**).
69+
70+
Review the diff to confirm no unexpected major-version jumps before merging.
6271
labels: dependencies

README.md

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,34 @@ source venv/bin/activate
6161
pip install -r requirements.txt
6262
```
6363

64+
For reproducible installs (same versions as CI), use the pinned lock file:
65+
66+
```bash
67+
pip install -r requirements-lock.txt
68+
```
69+
70+
### Dependency bounds and lock file
71+
72+
Runtime version **bounds** live in `pyproject.toml` under `[project.dependencies]` (`flask`, `fpdf2`, `pillow`, etc.). `requirements.txt` mirrors those specifiers for backward compatibility — keep them identical when you change deps.
73+
74+
**CI** installs from `requirements-lock.txt`, which pins exact versions (including transitive packages). Regenerate the lock after editing bounds:
75+
76+
```bash
77+
pip install pip-tools
78+
pip-compile requirements.txt \
79+
--output-file requirements-lock.txt \
80+
--no-header \
81+
--annotation-style=line \
82+
--allow-unsafe
83+
```
84+
85+
Then restore the comment header at the top of `requirements-lock.txt` (see the existing file) and commit both `requirements.txt` / `pyproject.toml` and `requirements-lock.txt`.
86+
87+
**Automated updates:**
88+
89+
- **Dependabot** (`.github/dependabot.yml`) — weekly PRs for `pip` and `github-actions` when newer versions fit the declared bounds. Merging a Dependabot **pip** PR does **not** refresh the lock file; run the lock workflow or `pip-compile` locally afterward.
90+
- **Update dependency lock file** (`.github/workflows/update-lock.yml`) — scheduled Mondays 08:00 UTC (and manual **Actions → Run workflow**) runs `pip-compile --upgrade` and opens a PR with an updated `requirements-lock.txt`.
91+
6492
## Quick Start (Web UI)
6593

6694
```bash
@@ -73,7 +101,7 @@ The Werkzeug debugger is **off by default** and must be opted in explicitly via
73101

74102
## Tests
75103

76-
Run the full suite from the repository root (install `requirements.txt` first):
104+
Run the full suite from the repository root (install `requirements-lock.txt` or `requirements.txt` first):
77105

78106
```bash
79107
python -m unittest discover tests -v
@@ -147,7 +175,9 @@ Cursor CLI agent sessions are read from `~/.cursor/chats/` (the default path use
147175
```
148176
cursor-chat-browser-python/
149177
├── app.py # Flask application entry point
150-
├── requirements.txt # Python dependencies
178+
├── requirements.txt # Runtime bounds (mirrors pyproject.toml)
179+
├── requirements-lock.txt # Pinned lock file used by CI
180+
├── pyproject.toml # Package metadata and canonical dependency bounds
151181
├── api/ # API route blueprints
152182
│ ├── workspaces.py # /api/workspaces endpoints
153183
│ ├── composers.py # /api/composers endpoints

0 commit comments

Comments
 (0)