diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml index ec797f62..cde6d6c3 100644 --- a/.github/dependabot.yaml +++ b/.github/dependabot.yaml @@ -13,5 +13,13 @@ updates: labels: [ci] schedule: interval: monthly - time: "05:00" - timezone: Etc/UTC + # Update frozen requirements in repo2docker Dockerfile + - package-ecosystem: pip + directory: / + allow: + # need this to upgrade requirements.txt + # otherwise only direct dependencies in requirements.in will be updated + - dependency-type: all + labels: [dependencies] + schedule: + interval: monthly diff --git a/Dockerfile b/Dockerfile index bb92d164..5e821e02 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,7 +15,7 @@ RUN cd /tmp/src && git clean -xfd && git status RUN mkdir /tmp/wheelhouse \ && cd /tmp/wheelhouse \ && pip install wheel \ - && pip wheel --no-cache-dir /tmp/src \ + && pip wheel --no-cache-dir -r /tmp/src/requirements.txt \ && ls -l /tmp/wheelhouse FROM alpine:${ALPINE_VERSION} diff --git a/pyproject.toml b/pyproject.toml index e6b63e4b..68cb9d7e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -28,6 +28,8 @@ classifiers = [ "Topic :: System :: Systems Administration", ] requires-python = ">=3.10" +# after changing dependencies, run ./scripts/refreeze +# so that the Dockerfile reflects the changes dependencies = [ "charset-normalizer", "docker!=5.0.0", diff --git a/requirements.in b/requirements.in new file mode 100644 index 00000000..a0a961df --- /dev/null +++ b/requirements.in @@ -0,0 +1,2 @@ +# freeze current requirements, used in Dockerfile +. diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 00000000..940b9a80 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,48 @@ +# +# This file is autogenerated by pip-compile with Python 3.12 +# by the following command: +# +# ./scripts/refreeze +# +certifi==2026.2.25 + # via requests +charset-normalizer==3.4.5 + # via + # jupyter-repo2docker + # requests +docker==7.1.0 + # via jupyter-repo2docker +entrypoints==0.4 + # via jupyter-repo2docker +escapism==1.1.0 + # via jupyter-repo2docker +idna==3.11 + # via requests +iso8601==2.1.0 + # via jupyter-repo2docker +jinja2==3.1.6 + # via jupyter-repo2docker +jupyter-repo2docker @ file:///tmp/src + # via -r requirements.in +markupsafe==3.0.3 + # via jinja2 +packaging==26.0 + # via jupyter-repo2docker +python-json-logger==4.0.0 + # via jupyter-repo2docker +requests==2.32.5 + # via + # docker + # jupyter-repo2docker +ruamel-yaml==0.19.1 + # via jupyter-repo2docker +semver==3.0.4 + # via jupyter-repo2docker +toml==0.10.2 + # via jupyter-repo2docker +traitlets==5.14.3 + # via jupyter-repo2docker +urllib3==2.6.3 + # via + # docker + # requests diff --git a/scripts/refreeze b/scripts/refreeze new file mode 100755 index 00000000..eb2c5714 --- /dev/null +++ b/scripts/refreeze @@ -0,0 +1,58 @@ +#!/usr/bin/env python3 +""" +Run pip-compile in docker to generate requirements.txt + +Should only need running when requirements change in pyproject.toml, which is uncommon. +Dependabot should handle updating requirements.txt most of the time. +""" + +from pathlib import Path +from subprocess import run + +repo = Path(__file__).parents[1].resolve() + + +def get_alpine_version(): + """ + Get the alpine version from our dockerfile + + make sure we're running with the same version as the docker image. + """ + dockerfile = repo / "Dockerfile" + with dockerfile.open() as f: + for line in f: + if "ALPINE_VERSION" in line: + return line.partition("=")[2].strip() + raise ValueError(f"Couldn't find ALPINE_VERSION= in {dockerfile}") + + +def refreeze(): + """ + Run pip-compile in docker to generate requirements.txt + """ + + alpine_version = get_alpine_version() + run( + [ + "docker", + "run", + "--rm", + f"-v{repo}:/tmp/src", + "-w/tmp/src", + "-eCUSTOM_COMPILE_COMMAND=./scripts/refreeze", + f"alpine:{alpine_version}", + "sh", + "-c", + """ + apk add py3-pip git + python3 -m venv /tmp/venv + source /tmp/venv/bin/activate + pip install pip-tools + pip-compile + """, + ] + ) + + +if __name__ == "__main__": + refreeze()