Skip to content

Commit 6e60bb0

Browse files
SeanMeyerclaude
andcommitted
docs: Add Python dependency lockfile with CI validation
Add proper lockfile generation and CI validation for Python dependencies used in documentation building. Changes: - Rename requirements-min/requirements.txt to requirements.in (unpinned deps) - Replace pip freeze with uv pip compile for lockfile generation - Add update-deps target for regenerating lockfile - Add verify-deps target for CI validation - Add CI job to verify lockfile stays in sync with requirements.in The lockfile (requirements.txt) is generated using uv with: make -C Documentation update-deps Developer workflow: 1. Edit requirements.in to add/update dependencies 2. Run: make -C Documentation update-deps 3. Commit both requirements.in and requirements.txt This enables: - Security vulnerability management via exact version tracking - Build reproducibility across environments - Audit trail for dependency changes Co-Authored-By: Claude <noreply@anthropic.com>
1 parent e27cc7d commit 6e60bb0

4 files changed

Lines changed: 208 additions & 68 deletions

File tree

.github/workflows/documentation.yaml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,20 @@ jobs:
6969
entrypoint: ./Documentation/check-build.sh
7070
args: html
7171

72+
verify-deps:
73+
name: Verify Python lockfile
74+
runs-on: ubuntu-24.04
75+
steps:
76+
- name: Checkout
77+
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
78+
with:
79+
persist-credentials: false
80+
- name: Install uv
81+
uses: astral-sh/setup-uv@6b9c6063abd6010835644d4c2e1bef4cf5cd0fca # v6.0.1
82+
- name: Verify lockfile is in sync
83+
run: |
84+
make -C Documentation verify-deps
85+
7286
check-generated-documentation:
7387
name: Check generated documentation
7488
if: ${{ github.event_name != 'merge_group' }}

Documentation/Makefile

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ include ../Makefile.defs
55
include ../Makefile.quiet
66

77
HELM_VALUES := helm-values.rst
8-
REQUIREMENTS_NODEP := requirements-min/requirements.txt
8+
REQUIREMENTS_IN := requirements.in
99
REQUIREMENTS := requirements.txt
1010
SPHINX_OPTS := "-j=auto"
1111

@@ -28,7 +28,7 @@ endef
2828
##@ Development Images
2929

3030
DOCS_BASE_IMG ?= cilium/docs-base
31-
base-image: Dockerfile ## Build the docs-base image for updating the requirements.txt file.
31+
base-image: Dockerfile ## Build the docs-base image for documentation building.
3232
$(call build_image,$<,docs-base,$(DOCS_BASE_IMG))
3333

3434
DOCS_BUILDER_IMG ?= cilium/docs-builder
@@ -163,10 +163,25 @@ update-redirects: builder-image ## Build and serve the documentation locally.
163163

164164
##@ Development
165165

166-
update-requirements: base-image $(REQUIREMENTS_NODEP) ## Regenerate the requirements.txt file from requirements-min/requirements.txt.
167-
@echo '## Auto-generated from $(REQUIREMENTS_NODEP) with "make update-requirements"' > $(REQUIREMENTS)
168-
$(QUIET)$(DOCKER_CTR_BASE) $(DOCS_BASE_IMG) \
169-
bash -c "export HOME=/tmp && pip install --no-warn-script-location -r $(REQUIREMENTS_NODEP) && pip freeze -r $(REQUIREMENTS_NODEP) >> $(REQUIREMENTS)"
166+
.PHONY: update-deps
167+
update-deps: $(REQUIREMENTS_IN) ## Regenerate the requirements.txt lockfile from requirements.in using uv.
168+
uv pip compile --upgrade --python-version 3.11 --python-platform linux $(REQUIREMENTS_IN) -o $(REQUIREMENTS)
169+
170+
.PHONY: verify-deps
171+
verify-deps: $(REQUIREMENTS_IN) $(REQUIREMENTS) ## Verify requirements.txt is in sync with requirements.in.
172+
@echo "Verifying requirements.txt is in sync with requirements.in..."
173+
$(QUIET)TMP=$$(mktemp) && \
174+
TMP_CURRENT=$$(mktemp) && \
175+
TMP_NEW=$$(mktemp) && \
176+
uv pip compile --upgrade --python-version 3.11 --python-platform linux $(REQUIREMENTS_IN) -o "$$TMP" 2>/dev/null && \
177+
grep -v '^#' $(REQUIREMENTS) | grep -v '^\s*#' | grep -v '^\s*$$' > "$$TMP_CURRENT" && \
178+
grep -v '^#' "$$TMP" | grep -v '^\s*#' | grep -v '^\s*$$' > "$$TMP_NEW" && \
179+
diff -q "$$TMP_CURRENT" "$$TMP_NEW" > /dev/null || \
180+
(echo "ERROR: requirements.txt is out of sync with requirements.in" && \
181+
echo "Run 'make -C Documentation update-deps' to regenerate" && \
182+
rm -f "$$TMP" "$$TMP_CURRENT" "$$TMP_NEW" && exit 1) && \
183+
rm -f "$$TMP" "$$TMP_CURRENT" "$$TMP_NEW"
184+
@echo "requirements.txt is in sync"
170185

171186
clean: ## Clean up all artefacts from documentation.
172187
-$(QUIET)rm -rf _build _exts/__pycache__ _preview Pipfile Pipfile.lock

Documentation/requirements-min/requirements.txt renamed to Documentation/requirements.in

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
1+
# Generate lockfile with: make -C Documentation update-deps
2+
# Requires: uv (https://docs.astral.sh/uv/)
3+
#
4+
# Docs dependencies pinned per Cilium documentation build requirements
5+
# Python 3.11 is used (see Dockerfile)
6+
17
sphinx==7.1.2
28
sphinx-autobuild==2021.3.14
39

410
# Custom theme, forked from Read the Docs
5-
git+https://github.com/cilium/sphinx_rtd_theme.git@cilium/rebase-2023-09#egg=sphinx-rtd-theme-cilium
11+
sphinx-rtd-theme-cilium @ git+https://github.com/cilium/sphinx_rtd_theme.git@cilium/rebase-2023-09
612

713
# We use semver to parse Cilium's version in the config file
814
semver==3.0.1

Documentation/requirements.txt

Lines changed: 166 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,71 +1,176 @@
1-
## Auto-generated from requirements-min/requirements.txt with "make update-requirements"
2-
Sphinx==7.1.2
1+
# This file was autogenerated by uv via the following command:
2+
# uv pip compile --python-version 3.11 --python-platform linux requirements.in -o requirements.txt
3+
alabaster==0.7.16
4+
# via sphinx
5+
annotated-types==0.7.0
6+
# via pydantic
7+
attrs==25.4.0
8+
# via
9+
# jsonschema
10+
# referencing
11+
babel==2.17.0
12+
# via sphinx
13+
certifi==2026.1.4
14+
# via requests
15+
charset-normalizer==3.4.4
16+
# via requests
17+
click==8.3.1
18+
# via typer
19+
colorama==0.4.6
20+
# via sphinx-autobuild
21+
deepmerge==2.0
22+
# via sphinxcontrib-openapi
23+
docutils==0.18.1
24+
# via
25+
# myst-parser
26+
# rstcheck-core
27+
# sphinx
28+
# sphinx-mdinclude
29+
# sphinx-rtd-theme-cilium
30+
# sphinx-tabs
31+
idna==3.11
32+
# via requests
33+
imagesize==1.4.1
34+
# via sphinx
35+
jinja2==3.1.6
36+
# via
37+
# myst-parser
38+
# sphinx
39+
jsonschema==4.26.0
40+
# via sphinxcontrib-openapi
41+
jsonschema-specifications==2025.9.1
42+
# via jsonschema
43+
livereload==2.7.1
44+
# via sphinx-autobuild
45+
markdown-it-py==3.0.0
46+
# via
47+
# mdit-py-plugins
48+
# myst-parser
49+
# rich
50+
markupsafe==3.0.3
51+
# via jinja2
52+
mdit-py-plugins==0.5.0
53+
# via myst-parser
54+
mdurl==0.1.2
55+
# via markdown-it-py
56+
mistune==3.2.0
57+
# via sphinx-mdinclude
58+
myst-parser==2.0.0
59+
# via -r requirements.in
60+
packaging==25.0
61+
# via sphinx
62+
pathspec==1.0.3
63+
# via yamllint
64+
picobox==4.0.0
65+
# via sphinxcontrib-openapi
66+
pydantic==2.12.5
67+
# via rstcheck-core
68+
pydantic-core==2.41.5
69+
# via pydantic
70+
pyenchant==3.3.0
71+
# via sphinxcontrib-spelling
72+
pygments==2.19.2
73+
# via
74+
# rich
75+
# sphinx
76+
# sphinx-mdinclude
77+
# sphinx-tabs
78+
pyyaml==6.0.3
79+
# via
80+
# myst-parser
81+
# sphinxcontrib-openapi
82+
# yamllint
83+
referencing==0.37.0
84+
# via
85+
# jsonschema
86+
# jsonschema-specifications
87+
requests==2.32.5
88+
# via sphinx
89+
rich==14.2.0
90+
# via typer
91+
rpds-py==0.30.0
92+
# via
93+
# jsonschema
94+
# referencing
95+
rstcheck==6.2.0
96+
# via -r requirements.in
97+
rstcheck-core==1.2.2
98+
# via rstcheck
99+
semver==3.0.1
100+
# via -r requirements.in
101+
shellingham==1.5.4
102+
# via typer
103+
six==1.17.0
104+
# via sphinxcontrib-httpdomain
105+
snowballstemmer==3.0.1
106+
# via sphinx
107+
sphinx==7.1.2
108+
# via
109+
# -r requirements.in
110+
# myst-parser
111+
# sphinx-autobuild
112+
# sphinx-mdinclude
113+
# sphinx-rtd-theme-cilium
114+
# sphinx-tabs
115+
# sphinx-version-warning
116+
# sphinxcontrib-googleanalytics
117+
# sphinxcontrib-httpdomain
118+
# sphinxcontrib-jquery
119+
# sphinxcontrib-openapi
120+
# sphinxcontrib-spelling
121+
# sphinxext-rediraffe
3122
sphinx-autobuild==2021.3.14
4-
5-
# Custom theme, forked from Read the Docs
123+
# via -r requirements.in
124+
sphinx-mdinclude==0.6.1
125+
# via sphinxcontrib-openapi
6126
sphinx-rtd-theme-cilium @ git+https://github.com/cilium/sphinx_rtd_theme.git@5e45810d0af338f8a7a6337b0377412ddf973dbc
7-
# We use semver to parse Cilium's version in the config file
8-
semver==3.0.1
9-
# Sphinx extensions
10-
myst-parser==2.0.0
127+
# via -r requirements.in
11128
sphinx-tabs==3.4.1
129+
# via -r requirements.in
12130
sphinx-version-warning==1.1.2
131+
# via -r requirements.in
132+
sphinxcontrib-applehelp==2.0.0
133+
# via sphinx
134+
sphinxcontrib-devhelp==2.0.0
135+
# via sphinx
13136
sphinxcontrib-googleanalytics==0.4
137+
# via -r requirements.in
138+
sphinxcontrib-htmlhelp==2.1.0
139+
# via sphinx
140+
sphinxcontrib-httpdomain==1.8.1
141+
# via sphinxcontrib-openapi
142+
sphinxcontrib-jquery==4.1
143+
# via sphinx-rtd-theme-cilium
144+
sphinxcontrib-jsmath==1.0.1
145+
# via sphinx
14146
sphinxcontrib-openapi==0.8.1
147+
# via -r requirements.in
148+
sphinxcontrib-qthelp==2.0.0
149+
# via sphinx
150+
sphinxcontrib-serializinghtml==2.0.0
151+
# via
152+
# sphinx
153+
# sphinxcontrib-websupport
15154
sphinxcontrib-spelling==8.0.0
155+
# via -r requirements.in
16156
sphinxcontrib-websupport==1.2.4
157+
# via -r requirements.in
17158
sphinxext-rediraffe==0.2.7
18-
# Linters
19-
rstcheck==6.2.0
159+
# via -r requirements.in
160+
tornado==6.5.4
161+
# via livereload
162+
typer==0.21.1
163+
# via rstcheck
164+
typing-extensions==4.15.0
165+
# via
166+
# pydantic
167+
# pydantic-core
168+
# referencing
169+
# typer
170+
# typing-inspection
171+
typing-inspection==0.4.2
172+
# via pydantic
173+
urllib3==2.6.3
174+
# via requests
20175
yamllint==1.32.0
21-
## The following requirements were added by pip freeze:
22-
alabaster==0.7.13
23-
annotated-types==0.5.0
24-
attrs==23.1.0
25-
Babel==2.12.1
26-
certifi==2024.7.4
27-
charset-normalizer==3.2.0
28-
click==8.1.7
29-
colorama==0.4.6
30-
deepmerge==1.1.0
31-
docutils==0.18.1
32-
idna==3.7
33-
imagesize==1.4.1
34-
Jinja2==3.1.6
35-
jsonschema==4.19.0
36-
jsonschema-specifications==2023.7.1
37-
livereload==2.6.3
38-
markdown-it-py==3.0.0
39-
MarkupSafe==2.1.3
40-
mdit-py-plugins==0.4.0
41-
mdurl==0.1.2
42-
mistune==2.0.5
43-
packaging==23.1
44-
pathspec==0.11.2
45-
picobox==3.0.0
46-
pydantic==2.7.1
47-
pydantic_core==2.18.2
48-
pyenchant==3.2.2
49-
Pygments==2.16.1
50-
PyYAML==6.0.1
51-
referencing==0.30.2
52-
requests==2.32.4
53-
rich==13.5.2
54-
rpds-py==0.10.3
55-
rstcheck-core==1.1.1
56-
shellingham==1.5.3
57-
six==1.16.0
58-
snowballstemmer==2.2.0
59-
sphinx_mdinclude==0.5.3
60-
sphinxcontrib-applehelp==1.0.4
61-
sphinxcontrib-devhelp==1.0.2
62-
sphinxcontrib-htmlhelp==2.0.1
63-
sphinxcontrib-httpdomain==1.8.1
64-
sphinxcontrib-jquery==4.1
65-
sphinxcontrib-jsmath==1.0.1
66-
sphinxcontrib-qthelp==1.0.3
67-
sphinxcontrib-serializinghtml==1.1.5
68-
tornado==6.5
69-
typer==0.9.0
70-
typing_extensions==4.7.1
71-
urllib3==2.5.0
176+
# via -r requirements.in

0 commit comments

Comments
 (0)