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
5 changes: 4 additions & 1 deletion .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ updates:
patterns:
- "*"

# Python dependencies declared in requirements.txt and requirements-test.txt
# Python dependencies. The ranges live in requirements.in /
# requirements-test.in; requirements.txt / requirements-test.txt are the
# pip-compile locks. Dependabot recognizes that layout and regenerates the
# hashed lock alongside any bump it makes to the input file.
- package-ecosystem: "pip"
directory: "/"
schedule:
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,8 @@ jobs:
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install --only-binary :all: -r requirements.txt
pip install --only-binary :all: -r requirements-test.txt
pip install --only-binary :all: --require-hashes -r requirements.txt
pip install --only-binary :all: --require-hashes -r requirements-test.txt

- name: Cache Playwright browsers
if: ${{ matrix.needs_playwright }}
Expand Down Expand Up @@ -601,8 +601,8 @@ jobs:
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install --only-binary :all: -r requirements.txt
pip install --only-binary :all: -r requirements-test.txt
pip install --only-binary :all: --require-hashes -r requirements.txt
pip install --only-binary :all: --require-hashes -r requirements-test.txt

- name: Cache Playwright browsers
if: ${{ matrix.needs_playwright }}
Expand Down
29 changes: 27 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,37 @@ cd QuadletManager

python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
pip install -r requirements-test.txt
pip install --only-binary :all: --require-hashes -r requirements.txt
pip install --only-binary :all: --require-hashes -r requirements-test.txt

npm ci
```

### Changing a Python dependency

`requirements.in` and `requirements-test.in` hold the hand-edited version
ranges. `requirements.txt` and `requirements-test.txt` are generated locks:
every direct and transitive dependency pinned with `==` and hashed, which is
what lets every install path pass `--require-hashes` and fail on a substituted
PyPI artifact rather than executing it.

Edit the `.in` file, never the lock, then regenerate both locks in order (the
second reads the first, so their shared packages cannot drift apart):

```bash
pip install pip-tools
pip-compile --generate-hashes --allow-unsafe --strip-extras \
--output-file requirements.txt requirements.in
pip-compile --generate-hashes --allow-unsafe --strip-extras \
-c requirements.txt --output-file requirements-test.txt requirements-test.in
```

Compile on Linux with Python 3.12, matching CI and the container image. The
locks carry no environment markers, so a lock generated elsewhere will pin the
wrong platform's wheels. (This is why `start.bat` installs from
`requirements.in` instead: no Windows wheel exists for the `uvloop` the Linux
lock pins.)

`npm ci` is not optional, even though this is mostly a Python project. Its
`postinstall` hook runs `npm run copy-assets`, which copies Monaco, xterm and
quadlet-lint out of `node_modules/` into `static/vendor/`. That directory is
Expand Down
7 changes: 6 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,13 @@ FROM python:3.12-slim AS builder

WORKDIR /build

# requirements.txt is the pip-compile lock: every direct and transitive
# dependency pinned with hashes. --require-hashes makes a substituted or
# tampered-with PyPI artifact fail the build instead of being installed, and
# --only-binary :all: keeps any sdist's setup.py from executing.
COPY requirements.txt .
RUN pip install --no-cache-dir --prefix=/install -r requirements.txt
RUN pip install --no-cache-dir --prefix=/install \
--only-binary :all: --require-hashes -r requirements.txt

# Stage 2: Runtime image
FROM python:3.12-slim
Expand Down
4 changes: 2 additions & 2 deletions README.MD
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ cd QuadletManager
git checkout v0.1.0
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
pip install --only-binary :all: --require-hashes -r requirements.txt
```

Omit the `git checkout` to track `main`, which is the development branch.
Expand Down Expand Up @@ -203,7 +203,7 @@ See [docs/TESTING.md](docs/TESTING.md) for the full testing guide.
### Unit Tests

```bash
pip install -r requirements-test.txt
pip install --only-binary :all: --require-hashes -r requirements-test.txt
PYTHONPATH=. pytest tests/ --ignore=tests/e2e/
```

Expand Down
9 changes: 8 additions & 1 deletion docs/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -873,9 +873,16 @@ HTTP-on-`:8000` deployment would make login appear to succeed but never stick.

### Running the Application

`requirements.txt` is a generated lock: every direct and transitive dependency
pinned with `==` and hashed. `--require-hashes` therefore fails the install on
a substituted or tampered-with PyPI artifact, and `--only-binary :all:` keeps
any sdist's `setup.py` from executing. The editable version ranges live in
`requirements.in`; see [CONTRIBUTING.md](../CONTRIBUTING.md) for how to
regenerate the lock.

```bash
# Install dependencies
pip install -r requirements.txt
pip install --only-binary :all: --require-hashes -r requirements.txt

# Set master key
export QUADLET_MASTER_KEY=$(openssl rand -hex 32)
Expand Down
2 changes: 1 addition & 1 deletion docs/SETUP.MD
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ Before running the application, you need to set up a Python virtual environment
```bash
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
pip install --only-binary :all: --require-hashes -r requirements.txt
```

## 5. Setting the Master Key
Expand Down
2 changes: 1 addition & 1 deletion docs/TESTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ were never executed before it existed. See [Podman tests](#podman-tests).
## Installation

```bash
pip install -r requirements-test.txt
pip install --only-binary :all: --require-hashes -r requirements-test.txt
```

For E2E tests, also install the Playwright browser binaries (one-time):
Expand Down
16 changes: 16 additions & 0 deletions requirements-test.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Hand-edited test-only dependencies. requirements-test.txt is the resolved,
# hash-pinned lock compiled from this file against requirements.txt, so the
# two locks always agree on any package they share. See requirements.in for
# the regeneration commands.
pytest>=9.1.1
pytest-asyncio>=1.4.0
pytest-xdist
pytest-rerunfailures
pytest-timeout
playwright==1.61.0
pytest-playwright==0.8.0
pytest-cov
coverage
httpx2
filelock
pylint
Loading