Skip to content

Commit e156430

Browse files
authored
Merge pull request #123 from opensafely-core/workflow-permissions
Workflow updates and fix for removed pkg_resources
2 parents 092209f + 7cfd323 commit e156430

File tree

5 files changed

+35
-45
lines changed

5 files changed

+35
-45
lines changed

.github/workflows/automerge.yaml

Lines changed: 0 additions & 28 deletions
This file was deleted.

.github/workflows/build_and_publish.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ on:
55
branches: [main]
66
env:
77
UBUNTU_PRO_TOKEN: ${{ secrets.UBUNTU_PRO_TOKEN }}
8+
permissions:
9+
contents: read
10+
packages: write
811
jobs:
912
publish:
1013
# note: this builds/tests all versions in serial for two reasons. Firstly we

.github/workflows/tests.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
name: Run tests
22
on:
33
pull_request:
4+
permissions:
5+
contents: read
46
env:
57
UBUNTU_PRO_TOKEN: ${{ secrets.UBUNTU_PRO_TOKEN }}
68
jobs:

Dockerfile

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,13 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
3535
RUN python3 -m venv /opt/venv
3636
# "activate" the venv
3737
ENV VIRTUAL_ENV=/opt/venv/ PATH="/opt/venv/bin:$PATH"
38-
# We ensure up-to-date build tools (which why we ignore DL3013)
39-
# hadolint ignore=DL3013,DL3042
40-
RUN --mount=type=cache,target=/root/.cache python -m pip install -U pip setuptools wheel pip-tools
41-
38+
# Ensure recent build tools
39+
# Pin setuptools to <82.0.0 (which removed pkg_resources, which some dependencies require)
40+
# Pin others to next major/minor version as of 2026-03-05 (major/minor depending on where
41+
# the package tends to include breaking changes)
42+
# hadolint ignore=DL3042
43+
RUN --mount=type=cache,target=/root/.cache python -m pip install -U "pip<27.0.0" "wheel<0.47.0" "pip-tools<7.6.0" "setuptools<82.0.0"
44+
RUN pip freeze
4245

4346
#################################################
4447
#

tests/test_import.py

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import os
2-
import subprocess
2+
import re
3+
34
from importlib import import_module
45
from pathlib import Path
5-
import re
6+
from importlib.metadata import distribution
7+
68

79
import pytest
8-
from pkg_resources import Requirement, get_provider
910

1011

1112
# packages that have no way to detect their importable name
@@ -15,33 +16,42 @@
1516
"qtpy": None, # required dependency of jupyter-lab
1617
}
1718

19+
1820
def get_module_names(pkg_name):
19-
"""Load pkg metadata to find out its importable module name(s)."""
21+
"""Load distribution to find out its importable module name(s)."""
2022
# remove any extras
21-
pkg_name = re.sub(r'\[.*\]', '', pkg_name)
23+
pkg_name = re.sub(r"\[.*\]", "", pkg_name)
2224
modules = set()
23-
provider = get_provider(Requirement.parse(pkg_name))
2425
# top level package name is typically all we need
26+
dist = distribution(pkg_name)
2527
if pkg_name in BAD_PACKAGES:
2628
name = BAD_PACKAGES[pkg_name]
27-
if name is None: # unimportably package
29+
if name is None: # unimportable package
2830
return []
2931
modules.add(BAD_PACKAGES[pkg_name])
30-
elif provider.has_metadata("top_level.txt"):
31-
first_line = list(provider.get_metadata_lines("top_level.txt"))[0]
32-
modules.add(first_line)
32+
elif top_level_names := dist.read_text("top_level.txt"):
33+
# Find the first non-_ prefixed module
34+
if first_public_name := next(
35+
(
36+
name
37+
for name in top_level_names.strip().split("\n")
38+
if not name.startswith("_")
39+
),
40+
None,
41+
):
42+
modules.add(first_public_name)
3343
else:
3444
# badly packaged dependency, make an educated guess
3545
name = pkg_name
3646
if pkg_name.endswith("-cffi"):
3747
name = pkg_name[:-5]
3848
elif pkg_name.endswith("-py"):
3949
name = pkg_name[:-3]
40-
50+
4151
modules.add(name.replace("-", "_"))
4252

43-
if provider.has_metadata("namespace_packages.txt"):
44-
modules |= set(provider.get_metadata_lines("namespace_packages.txt"))
53+
if namespace_packages := dist.read_text("namespace_packages.txt"):
54+
modules |= set(namespace_packages.strip().split("\n"))
4555

4656
# _ prefixed modules are typically C modules and not directly importable
4757
return [n for n in modules if n[0] != "_"]

0 commit comments

Comments
 (0)