Repository navigation
156 lines (144 loc) · 6.31 KB
/
Copy pathpython-forward-compat.yml
File metadata and controls
156 lines (144 loc) · 6.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
name: Python Next
# Weekly, non-blocking run of the backend test suites (default in-process
# and local process system) and the strict type check against the next
# Python minor version (one above backend/.python-version). See
# docs/deployment.md (Python Forward-Compatibility Check) for the full
# rationale, including why no image is built here, and
# docs/conventions.md (Version Bump Checklist) for the manual bump
# procedure this workflow provides early warning for.
#
# This workflow reports forward-compatibility failures through its native
# Actions status and logs. It never touches build-images.yml or the publish
# path and is never a required/blocking status check.
on:
schedule:
# Every Monday at 07:00 UTC (one hour after image-scan.yml's 06:00
# UTC run, to avoid runner contention).
- cron: "0 7 * * 1"
workflow_dispatch:
concurrency:
group: python-forward-compat
cancel-in-progress: false
permissions:
contents: read
jobs:
forward-compat:
name: Test Against Next Python Version
runs-on: ubuntu-latest
timeout-minutes: 30
defaults:
run:
working-directory: backend
services:
postgres:
image: postgres:18
env:
POSTGRES_USER: sentinel
POSTGRES_PASSWORD: sentinel
POSTGRES_DB: sentinel_test
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
redis:
image: redis:8
ports:
- 6379:6379
options: >-
--health-cmd "redis-cli ping"
--health-interval 10s
--health-timeout 5s
--health-retries 5
env:
TEST_DATABASE_URL: postgresql+asyncpg://sentinel:sentinel@localhost:5432/sentinel_test
DATABASE_URL: postgresql+asyncpg://sentinel:sentinel@localhost:5432/sentinel_test
REDIS_URL: redis://localhost:6379/0
CELERY_BROKER_URL: redis://localhost:6379/1
TEST_REDIS_URL: redis://localhost:6379/2
JWT_SECRET_KEY: ci-test-secret-key-not-for-production-min-32-chars
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Compute current and next Python minor version
id: python-version
run: |
set -euo pipefail
current=$(cat .python-version)
major="${current%%.*}"
minor="${current#*.}"
next="${major}.$((minor + 1))"
echo "current=${current}" >>"${GITHUB_OUTPUT}"
echo "next=${next}" >>"${GITHUB_OUTPUT}"
- uses: astral-sh/setup-uv@07a047e608db84b3d8c06cd9a7c7dcc9c355c18e # v10.3.2
with:
version: "0.13.5"
enable-cache: true
# Guards against a false-positive forward-compatibility failure:
# right after a Runtime Version bump, the next minor may have no
# published build yet (no alpha/beta/rc available). That is not
# an incompatibility signal — it just means there is nothing to
# test yet. `--only-downloads` lists only installable builds, so
# empty output means the version does not exist for this
# platform/architecture.
- name: Check next Python version is available for download
id: availability
run: |
set -euo pipefail
next="${{ steps.python-version.outputs.next }}"
if uv python list "${next}" --only-downloads 2>/dev/null | grep -q .; then
echo "available=true" >>"${GITHUB_OUTPUT}"
else
echo "::notice::Python ${next} has no published build yet — skipping this run."
echo "available=false" >>"${GITHUB_OUTPUT}"
fi
# Any failure below (interpreter installation, dependency resolution,
# a test failure, or a type error) fails the workflow so its native
# status badge reflects the forward-compatibility result. Unlike
# ci.yml's reproducible jobs, this run intentionally allows
# re-resolution (`uv sync` without `--locked`) since the goal is to
# surface breakage against a still-unreleased interpreter.
- name: Install next Python version and sync dependencies
id: sync
if: steps.availability.outputs.available == 'true'
env:
NEXT_PYTHON: ${{ steps.python-version.outputs.next }}
run: |
set -euo pipefail
uv python install "${NEXT_PYTHON}"
uv sync --python "${NEXT_PYTHON}"
# Same as ci.yml's backend-test job: the service container is
# discarded with the job. See docs/features/platform/testing-strategy.md
# (Parallel Execution; CI Pipeline).
- name: Disable durability on the ephemeral PostgreSQL service
if: steps.sync.outcome == 'success'
env:
POSTGRES_CONTAINER: ${{ job.services.postgres.id }}
run: >-
docker exec "${POSTGRES_CONTAINER}"
psql -v ON_ERROR_STOP=1 -U sentinel -d sentinel_test
-c "ALTER SYSTEM SET fsync = off"
-c "ALTER SYSTEM SET synchronous_commit = off"
-c "ALTER SYSTEM SET full_page_writes = off"
-c "SELECT pg_reload_conf()"
# The worker options of ci.yml's backend-test invocation, without
# coverage: -m "not image" overrides the pyproject default marker
# filter so the local process system suite runs in the same
# invocation. See docs/features/platform/testing-strategy.md
# (Parallel Execution; Local Process System Testing, Execution).
# A step timeout fails only this step, so the type check below still
# runs after a hung suite; the job timeout would cancel it instead.
- name: Run default in-process and local process system suites against next Python version
if: steps.sync.outcome == 'success'
timeout-minutes: 20
env:
NEXT_PYTHON: ${{ steps.python-version.outputs.next }}
run: uv run --python "${NEXT_PYTHON}" pytest -m "not image" -n 4 --max-worker-restart 0 -v
# Runs even when the test step failed, so the logs report both
# results; skipped only when the environment could not be prepared.
- name: Run strict type check against next Python version
if: ${{ !cancelled() && steps.sync.outcome == 'success' }}
env:
NEXT_PYTHON: ${{ steps.python-version.outputs.next }}
run: uv run --python "${NEXT_PYTHON}" mypy app tests alembic