Skip to content

Commit 34d79eb

Browse files
authored
Merge branch 'main' into ios-releases
2 parents 4f6236c + 76e0dd1 commit 34d79eb

38 files changed

Lines changed: 1187 additions & 195 deletions

.github/dependabot.yml

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,31 +3,23 @@ updates:
33
- package-ecosystem: pip
44
directory: "/"
55
schedule:
6-
interval: daily
6+
interval: weekly
7+
cooldown:
8+
default-days: 7
79
open-pull-requests-limit: 10
8-
ignore:
9-
- dependency-name: docutils
10-
versions:
11-
- "0.16"
12-
- "0.17"
13-
- dependency-name: responses
14-
versions:
15-
- 0.12.1
16-
- 0.13.0
17-
- 0.13.1
18-
- 0.13.2
19-
- dependency-name: "boto3"
20-
- dependency-name: "boto3-stubs"
21-
- dependency-name: "botocore"
22-
- dependency-name: "botocore-stubs"
23-
- dependency-name: lxml
24-
versions:
25-
- 4.6.2
2610
- package-ecosystem: github-actions
2711
directory: "/"
2812
groups:
2913
github-actions:
3014
patterns:
3115
- "*" # Group all Actions updates into a single larger pull request
3216
schedule:
33-
interval: daily
17+
interval: weekly
18+
cooldown:
19+
default-days: 7
20+
- package-ecosystem: docker
21+
directory: "/"
22+
schedule:
23+
interval: weekly
24+
cooldown:
25+
default-days: 7

.github/workflows/ci.yml

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,16 @@ jobs:
2020
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
2121

2222
steps:
23-
- uses: actions/checkout@v6
23+
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
24+
with:
25+
persist-credentials: false
2426

25-
- uses: actions/setup-python@v6
27+
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
2628
with:
2729
python-version-file: '.python-version'
2830

2931
- name: Cache pip
30-
uses: actions/cache@v5
32+
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
3133
with:
3234
path: ~/.cache/pip
3335
key: ${{ runner.os }}-pip-${{ hashFiles('pyproject.toml') }}
@@ -56,7 +58,9 @@ jobs:
5658
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
5759

5860
steps:
59-
- uses: actions/checkout@v6
61+
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
62+
with:
63+
persist-credentials: false
6064

6165
- name: Install platform dependencies
6266
run: |
@@ -72,12 +76,12 @@ jobs:
7276
wget https://github.com/jgm/pandoc/releases/download/2.17.1.1/pandoc-2.17.1.1-1-amd64.deb
7377
sudo dpkg -i pandoc-2.17.1.1-1-amd64.deb
7478
75-
- uses: actions/setup-python@v6
79+
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
7680
with:
7781
python-version-file: '.python-version'
7882

7983
- name: Cache pip
80-
uses: actions/cache@v5
84+
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
8185
with:
8286
path: ~/.cache/pip
8387
key: ${{ runner.os }}-pip-${{ hashFiles('pyproject.toml') }}

.github/workflows/lint.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@ jobs:
1313
runs-on: ubuntu-latest
1414

1515
steps:
16-
- uses: actions/checkout@v6
16+
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
1717
with:
1818
persist-credentials: false
1919

20-
- uses: actions/setup-python@v6
20+
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
2121
with:
2222
python-version: "3.x"
2323

24-
- uses: j178/prek-action@v2
24+
- uses: j178/prek-action@bdca6f102f98e2b4c7029491a53dfd366469e33d # v2.0.4

.github/workflows/purge-cache.yml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,11 @@ jobs:
1919
purge:
2020
runs-on: ubuntu-latest
2121
steps:
22-
- uses: actions/checkout@v6
22+
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
2323
if: github.event_name == 'push'
2424
with:
2525
fetch-depth: 0
26+
persist-credentials: false
2627

2728
- name: Resolve keys
2829
id: keys
@@ -36,8 +37,10 @@ jobs:
3637
fi
3738
3839
- name: Purge ${{ steps.keys.outputs.keys || 'pydotorg-app' }}
40+
env:
41+
PURGE_KEYS: ${{ steps.keys.outputs.keys || 'pydotorg-app' }}
3942
run: |
40-
for KEY in ${{ steps.keys.outputs.keys || 'pydotorg-app' }}; do
43+
for KEY in ${PURGE_KEYS}; do
4144
curl -fsS -X POST \
4245
"https://api.fastly.com/service/${{ secrets.FASTLY_SERVICE_ID }}/purge/$KEY" \
4346
-H "Fastly-Key: ${{ secrets.FASTLY_API_KEY }}"

.github/workflows/static.yml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,15 @@ jobs:
1010
runs-on: ubuntu-latest
1111
steps:
1212
- name: Check out repository
13-
uses: actions/checkout@v6
13+
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
14+
with:
15+
persist-credentials: false
1416

15-
- uses: actions/setup-python@v6
17+
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
1618
with:
1719
python-version-file: '.python-version'
1820
- name: Cache Python dependencies
19-
uses: actions/cache@v5
21+
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
2022
env:
2123
cache-name: pythondotorg-cache-pip
2224
with:

.github/workflows/zizmor.yml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
2+
name: GitHub Actions Security Analysis with zizmor 🌈
3+
4+
on:
5+
push:
6+
branches: ["main"]
7+
pull_request:
8+
branches: ["**"]
9+
10+
permissions: {}
11+
12+
jobs:
13+
zizmor:
14+
name: Run zizmor 🌈
15+
runs-on: ubuntu-latest
16+
permissions:
17+
security-events: write # Required for upload-sarif (used by zizmor-action) to upload SARIF files.
18+
steps:
19+
- name: Checkout repository
20+
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
21+
with:
22+
persist-credentials: false
23+
24+
- name: Run zizmor 🌈
25+
uses: zizmorcore/zizmor-action@5f14fd08f7cf1cb1609c1e344975f152c7ee938d # v0.5.6

Dockerfile

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
FROM python:3.12.6-bookworm
1+
FROM ghcr.io/astral-sh/uv:0.11.20@sha256:eaa5f1a3305307aaf9e67fe2bbba1d85ebbb2d8a63bce23af21797bfafbe0f8b AS uv
2+
3+
FROM python:3.14.6-bookworm
24
ENV PYTHONUNBUFFERED=1
35
ENV PYTHONDONTWRITEBYTECODE=1
46

@@ -32,16 +34,19 @@ RUN case $(uname -m) in \
3234
RUN mkdir /code
3335
WORKDIR /code
3436

35-
RUN pip --no-cache-dir --disable-pip-version-check install --upgrade pip setuptools wheel
37+
COPY --from=uv /uv /uvx /usr/local/bin/
3638

37-
COPY pyproject.toml /code/
39+
COPY pyproject.toml uv.lock /code/
3840

39-
RUN --mount=type=cache,target=/root/.cache/pip \
41+
RUN --mount=type=cache,target=/root/.cache \
4042
set -x \
41-
&& pip --disable-pip-version-check \
42-
install --group dev \
43-
.
43+
&& uv sync \
44+
--frozen \
45+
--no-editable \
46+
--no-install-project
4447

4548
COPY . /code/
4649

47-
RUN pip --disable-pip-version-check install --no-deps -e '.'
50+
RUN uv sync \
51+
--frozen \
52+
--no-editable

Dockerfile.cabotage

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
FROM python:3.12.6-bookworm
1+
FROM ghcr.io/astral-sh/uv:0.11.20@sha256:eaa5f1a3305307aaf9e67fe2bbba1d85ebbb2d8a63bce23af21797bfafbe0f8b AS uv
2+
3+
FROM python:3.14.6-bookworm
24
COPY --from=ewdurbin/nginx-static:1.25.x /usr/bin/nginx /usr/bin/nginx
35
ENV PYTHONUNBUFFERED=1
46
ENV PYTHONDONTWRITEBYTECODE=1
@@ -33,17 +35,28 @@ RUN case $(uname -m) in \
3335
RUN mkdir /code
3436
WORKDIR /code
3537

36-
RUN pip --no-cache-dir --disable-pip-version-check install --upgrade pip setuptools wheel
38+
ENV VIRTUAL_ENV=/code/.venv
39+
ENV PATH="$VIRTUAL_ENV/bin:$PATH"
40+
41+
COPY --from=uv /uv /uvx /usr/local/bin/
3742

38-
COPY pyproject.toml /code/
43+
COPY pyproject.toml uv.lock /code/
3944

40-
RUN --mount=type=cache,target=/root/.cache/pip \
45+
RUN --mount=type=cache,target=/root/.cache \
4146
set -x \
42-
&& pip --disable-pip-version-check \
43-
install \
44-
'.[prod]'
47+
&& uv sync \
48+
--frozen \
49+
--no-editable \
50+
--no-dev \
51+
--extra prod \
52+
--no-install-project
4553

4654
COPY . /code/
4755

48-
RUN pip --disable-pip-version-check install --no-deps '.'
49-
RUN DJANGO_SETTINGS_MODULE=pydotorg.settings.static python manage.py collectstatic --noinput
56+
RUN uv sync \
57+
--frozen \
58+
--no-editable \
59+
--no-dev \
60+
--extra prod
61+
62+
RUN DJANGO_SETTINGS_MODULE=pydotorg.settings.static uv run python manage.py collectstatic --noinput

Makefile

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ help: ## Display this help text
1616
mkdir -p .state && touch .state/db-migrated
1717

1818
.state/db-initialized: .state/docker-build-web .state/db-migrated
19-
docker compose run --rm web ./manage.py createcachetable
20-
docker compose run --rm web ./manage.py loaddata fixtures/*.json
19+
docker compose run --rm web uv run ./manage.py createcachetable
20+
docker compose run --rm web uv run ./manage.py loaddata fixtures/*.json
2121
mkdir -p .state && touch .state/db-initialized
2222

2323
# =============================================================================
@@ -30,16 +30,16 @@ serve: .state/db-initialized ## Start the application
3030
docker compose up --remove-orphans
3131

3232
migrations: .state/db-initialized ## Generate migrations from models
33-
docker compose run --rm web ./manage.py makemigrations
33+
docker compose run --rm web uv run ./manage.py makemigrations
3434

3535
migrate: .state/docker-build-web ## Run Django migrate
36-
docker compose run --rm web ./manage.py migrate
36+
docker compose run --rm web uv run ./manage.py migrate
3737

3838
manage: .state/db-initialized ## Run arbitrary manage.py commands
39-
docker compose run --rm web ./manage.py $(filter-out $@,$(MAKECMDGOALS))
39+
docker compose run --rm web uv run ./manage.py $(filter-out $@,$(MAKECMDGOALS))
4040

4141
shell: .state/db-initialized ## Open Django interactive shell
42-
docker compose run --rm web ./manage.py shell
42+
docker compose run --rm web uv run ./manage.py shell
4343

4444
docker_shell: .state/db-initialized ## Open bash in web container
4545
docker compose run --rm web /bin/bash
@@ -61,7 +61,7 @@ fmt: ## Run ruff formatter
6161
@if command -v ruff >/dev/null 2>&1; then ruff format .; else docker compose run --rm web ruff format .; fi
6262

6363
test: .state/db-initialized ## Run test suite
64-
docker compose run --rm web ./manage.py test
64+
docker compose run --rm web uv run python ./manage.py test
6565

6666
ci: lint fmt test ## Run lint, fmt, then tests
6767

apps/cms/tests.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,15 @@ class Test404(TestCase):
8181
def test_legacy_path(self):
8282
self.assertEqual(legacy_path("/any/thing"), "http://legacy.python.org/any/thing")
8383

84+
def test_legacy_path_without_leading_slash(self):
85+
self.assertEqual(legacy_path("any/thing"), "http://legacy.python.org/any/thing")
86+
87+
def test_legacy_path_with_encoded_slash(self):
88+
self.assertEqual(legacy_path("/%2Fevil.test/x"), "http://legacy.python.org/%2Fevil.test/x")
89+
90+
def test_legacy_path_with_decoded_encoded_slash(self):
91+
self.assertEqual(legacy_path("//evil.test/x"), "http://legacy.python.org//evil.test/x")
92+
8493
def test_custom_404(self):
8594
"""Ensure custom 404 is set to 5 minutes"""
8695
response = self.client.get("/foo-bar/baz/9876")

0 commit comments

Comments
 (0)