Skip to content

Commit 5d1213e

Browse files
authored
chore: Restrict the sdist to an allowlist and verify it in CI (#523)
1 parent 75402e9 commit 5d1213e

2 files changed

Lines changed: 103 additions & 0 deletions

File tree

‎.github/workflows/ci.yml‎

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,91 @@ jobs:
9393
version: v3
9494
enable_persistence_tests: "true"
9595

96+
# Proves the sdist is complete and functional, since the sdist file list is an
97+
# allowlist and an omission there is otherwise invisible. The test-count check
98+
# is what makes this meaningful: without it, an sdist missing half its tests
99+
# would still pass the tests it did ship. The contract-test steps cover the
100+
# other half, since a missing contract-tests directory changes no test count.
101+
sdist:
102+
name: sdist (functional)
103+
runs-on: ubuntu-latest
104+
105+
steps:
106+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
107+
108+
- name: Set up uv
109+
uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
110+
with:
111+
python-version: "3.13"
112+
113+
- name: Count the tests in the checkout
114+
run: |
115+
uv sync --all-extras
116+
count=$(uv run pytest --collect-only -q | grep -oE '[0-9]+ tests? collected' | grep -oE '^[0-9]+')
117+
echo "The checkout collects $count tests."
118+
echo "checkout_tests=$count" >> "$GITHUB_ENV"
119+
120+
- name: Build and unpack the sdist
121+
run: |
122+
uv build --sdist --out-dir dist
123+
mkdir -p "$RUNNER_TEMP/sdist"
124+
tar -xzf dist/*.tar.gz -C "$RUNNER_TEMP/sdist" --strip-components=1
125+
126+
- name: Check that the sdist ships every test
127+
working-directory: ${{ runner.temp }}/sdist
128+
run: |
129+
uv sync --all-extras
130+
count=$(uv run pytest --collect-only -q | grep -oE '[0-9]+ tests? collected' | grep -oE '^[0-9]+')
131+
echo "The sdist collects $count tests; the checkout collected $checkout_tests."
132+
if [ "$count" -lt "$checkout_tests" ]; then
133+
echo "::error::The sdist is missing tests. Add the missing paths to the include list in [tool.hatch.build.targets.sdist]."
134+
exit 1
135+
fi
136+
137+
- name: Run the tests from the sdist
138+
working-directory: ${{ runner.temp }}/sdist
139+
run: make test
140+
env:
141+
# The file-data-source modules skip themselves on this variable
142+
# because they flake in CI. The linux and windows jobs set it, and
143+
# this job must too, or it fails for reasons that say nothing about
144+
# whether the sdist is complete. The tests still get collected, so
145+
# the count check above is unaffected.
146+
LD_SKIP_FLAKY_TESTS: true
147+
148+
- name: Verify typehints from the sdist
149+
working-directory: ${{ runner.temp }}/sdist
150+
run: make lint
151+
152+
# start-contract-test-service depends on install-contract-tests-deps, and
153+
# the -bg target backgrounds the whole chain. Without a blocking install
154+
# first, the dependency sync races the harness connecting to the service.
155+
- name: Install the contract test dependencies from the sdist
156+
working-directory: ${{ runner.temp }}/sdist
157+
run: make install-contract-tests-deps
158+
159+
- name: Start the contract test service from the sdist
160+
working-directory: ${{ runner.temp }}/sdist
161+
run: make start-contract-test-service-bg
162+
163+
- name: Run contract tests against the sdist
164+
uses: launchdarkly/gh-actions/actions/contract-tests@contract-tests-v1
165+
with:
166+
test_service_port: 9000
167+
enable_persistence_tests: "false"
168+
token: ${{ secrets.GITHUB_TOKEN }}
169+
170+
- name: Start the async contract test service from the sdist
171+
working-directory: ${{ runner.temp }}/sdist
172+
run: make start-async-contract-test-service-bg
173+
174+
- name: Run async contract tests against the sdist
175+
uses: launchdarkly/gh-actions/actions/contract-tests@contract-tests-v1
176+
with:
177+
test_service_port: 9001
178+
enable_persistence_tests: "false"
179+
token: ${{ secrets.GITHUB_TOKEN }}
180+
96181
windows:
97182
runs-on: windows-latest
98183

‎pyproject.toml‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,3 +100,21 @@ build-backend = "hatchling.build"
100100
[tool.hatch.build.targets.wheel]
101101
packages = ["ldclient"]
102102
exclude = ["ldclient/testing"]
103+
104+
# An allowlist, so that a new repository-management file cannot leak into the
105+
# sdist by default. The CI sdist job proves the list is complete: it builds the
106+
# sdist, unpacks it, and fails if fewer tests collect there than in the
107+
# checkout. Hatchling force-includes pyproject.toml, README.md, LICENSE.txt,
108+
# PKG-INFO and .gitignore whatever this says, so the sdist always builds.
109+
[tool.hatch.build.targets.sdist]
110+
include = [
111+
"/ldclient",
112+
"/contract-tests",
113+
"/docs",
114+
"/Makefile",
115+
"/setup.cfg",
116+
"/CHANGELOG.md",
117+
"/CONTRIBUTING.md",
118+
"/SECURITY.md",
119+
"/PROVENANCE.md",
120+
]

0 commit comments

Comments
 (0)