Skip to content

Commit 90e5d26

Browse files
committed
Run stubtest only for newly released third-party package version
Issue: #14838
1 parent 4c4f999 commit 90e5d26

File tree

4 files changed

+90
-58
lines changed

4 files changed

+90
-58
lines changed

.github/workflows/daily.yml

Lines changed: 2 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -53,58 +53,6 @@ jobs:
5353
- name: Run stubtest
5454
run: python tests/stubtest_stdlib.py
5555

56-
stubtest-third-party:
57-
name: "stubtest: third party"
58-
if: ${{ github.repository == 'python/typeshed' || github.event_name != 'schedule' }}
59-
runs-on: ${{ matrix.os }}
60-
strategy:
61-
matrix:
62-
os: ["ubuntu-latest", "windows-latest", "macos-latest"]
63-
shard-index: [0, 1, 2, 3]
64-
fail-fast: false
65-
steps:
66-
- uses: actions/checkout@v5
67-
- uses: actions/setup-python@v6
68-
with:
69-
python-version: "3.13"
70-
cache: pip
71-
cache-dependency-path: |
72-
requirements-tests.txt
73-
stubs/**/METADATA.toml
74-
- name: Install dependencies
75-
run: pip install -r requirements-tests.txt
76-
- name: Install required system packages
77-
shell: bash
78-
run: |
79-
PACKAGES=$(python tests/get_stubtest_system_requirements.py)
80-
81-
if [ "${{ runner.os }}" = "Linux" ]; then
82-
if [ -n "$PACKAGES" ]; then
83-
printf "Installing APT packages:\n $(echo $PACKAGES | sed 's/ /\n /g')\n"
84-
sudo apt-get update -q && sudo apt-get install -qy $PACKAGES
85-
fi
86-
else
87-
if [ "${{ runner.os }}" = "macOS" ] && [ -n "$PACKAGES" ]; then
88-
printf "Installing Homebrew packages:\n $(echo $PACKAGES | sed 's/ /\n /g')\n"
89-
brew install -q $PACKAGES
90-
fi
91-
92-
if [ "${{ runner.os }}" = "Windows" ] && [ -n "$PACKAGES" ]; then
93-
printf "Installing Chocolatey packages:\n $(echo $PACKAGES | sed 's/ /\n /g')\n"
94-
choco install -y $PACKAGES
95-
fi
96-
fi
97-
- name: Run stubtest
98-
shell: bash
99-
run: |
100-
if [ "${{ runner.os }}" = "Linux" ]; then
101-
PYTHON_EXECUTABLE="xvfb-run python"
102-
else
103-
PYTHON_EXECUTABLE="python"
104-
fi
105-
106-
$PYTHON_EXECUTABLE tests/stubtest_third_party.py --ci-platforms-only --num-shards 4 --shard-index ${{ matrix.shard-index }}
107-
10856
stub-uploader:
10957
name: stub_uploader tests
11058
if: ${{ github.repository == 'python/typeshed' || github.event_name != 'schedule' }}
@@ -136,8 +84,8 @@ jobs:
13684
create-issue-on-failure:
13785
name: Create issue on failure
13886
runs-on: ubuntu-latest
139-
needs: [stubtest-stdlib, stubtest-third-party, stub-uploader]
140-
if: ${{ github.repository == 'python/typeshed' && always() && github.event_name == 'schedule' && (needs.stubtest-stdlib.result == 'failure' || needs.stubtest-third-party.result == 'failure' || needs.stub-uploader.result == 'failure') }}
87+
needs: [stubtest-stdlib, stub-uploader]
88+
if: ${{ github.repository == 'python/typeshed' && always() && github.event_name == 'schedule' && (needs.stubtest-stdlib.result == 'failure' || needs.stub-uploader.result == 'failure') }}
14189
permissions:
14290
issues: write
14391
steps:

.github/workflows/stubsabot.yml

Lines changed: 72 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ jobs:
1818
name: Upgrade stubs with stubsabot
1919
if: github.repository == 'python/typeshed'
2020
runs-on: ubuntu-latest
21+
outputs:
22+
STUBS: ${{ steps.runstubsabot.outputs.STUBS }}
2123
steps:
2224
- uses: actions/checkout@v5
2325
with:
@@ -37,14 +39,81 @@ jobs:
3739
- name: Install dependencies
3840
run: uv pip install -r requirements-tests.txt --system
3941
- name: Run stubsabot
40-
run: GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }} python scripts/stubsabot.py --action-level everything
42+
id: runstubsabot
43+
run: |
44+
GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }} python scripts/stubsabot.py --action-level everything
45+
echo "Stubs that should be tested by stubtest: $STUBS"
46+
echo "STUBS=$STUBS" >> $GITHUB_OUTPUT
47+
48+
stubtest-third-party:
49+
name: "stubtest: third party"
50+
if: github.repository == 'python/typeshed'
51+
runs-on: ${{ matrix.os }}
52+
needs: [stubsabot]
53+
strategy:
54+
matrix:
55+
os: ["ubuntu-latest", "windows-latest", "macos-latest"]
56+
fail-fast: false
57+
env:
58+
STUBS: ${{ needs.stubsabot.outputs.STUBS }}
59+
steps:
60+
- uses: actions/checkout@v5
61+
with:
62+
fetch-depth: 0
63+
- uses: actions/setup-python@v6
64+
with:
65+
python-version: "3.13"
66+
cache: pip
67+
cache-dependency-path: |
68+
requirements-tests.txt
69+
stubs/**/METADATA.toml
70+
- name: Install dependencies
71+
run: pip install -r requirements-tests.txt
72+
- name: Install required system packages
73+
shell: bash
74+
run: |
75+
if [ -n "$STUBS" ]; then
76+
PACKAGES=$(python tests/get_stubtest_system_requirements.py $STUBS)
77+
if [ "${{ runner.os }}" = "Linux" ]; then
78+
if [ -n "$PACKAGES" ]; then
79+
printf "Installing APT packages:\n $(echo $PACKAGES | sed 's/ /\n /g')\n"
80+
sudo apt-get update -q && sudo apt-get install -qy $PACKAGES
81+
fi
82+
else
83+
if [ "${{ runner.os }}" = "macOS" ] && [ -n "$PACKAGES" ]; then
84+
printf "Installing Homebrew packages:\n $(echo $PACKAGES | sed 's/ /\n /g')\n"
85+
brew install -q $PACKAGES
86+
fi
87+
88+
if [ "${{ runner.os }}" = "Windows" ] && [ -n "$PACKAGES" ]; then
89+
printf "Installing Chocolatey packages:\n $(echo $PACKAGES | sed 's/ /\n /g')\n"
90+
choco install -y $PACKAGES
91+
fi
92+
fi
93+
fi
94+
- name: Run stubtest
95+
shell: bash
96+
run: |
97+
if [ -n "$STUBS" ]; then
98+
echo "Testing $STUBS..."
99+
100+
if [ "${{ runner.os }}" = "Linux" ]; then
101+
PYTHON_EXECUTABLE="xvfb-run python"
102+
else
103+
PYTHON_EXECUTABLE="python"
104+
fi
105+
106+
$PYTHON_EXECUTABLE tests/stubtest_third_party.py --ci-platforms-only $STUBS
107+
else
108+
echo "Nothing to test"
109+
fi
41110
42111
# https://github.community/t/run-github-actions-job-only-if-previous-job-has-failed/174786/2
43112
create-issue-on-failure:
44113
name: Create issue on failure
45114
runs-on: ubuntu-latest
46-
needs: [stubsabot]
47-
if: ${{ github.repository == 'python/typeshed' && always() && (needs.stubsabot.result == 'failure') }}
115+
needs: [stubsabot, stubtest-third-party]
116+
if: ${{ github.repository == 'python/typeshed' && always() && (needs.stubsabot.result == 'failure' || needs.stubtest-third-party.result == 'failure') }}
48117
steps:
49118
- uses: actions/github-script@v8
50119
with:

.github/workflows/stubtest_third_party.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ jobs:
5252
shell: bash
5353
run: |
5454
# This only runs stubtest on changed stubs, because it is much faster.
55-
# Use the daily.yml workflow to run stubtest on all third party stubs.
55+
# Use the stubsabot.yml workflow to run stubtest on third-party stubs.
5656
function find_stubs {
5757
git diff --name-only origin/${{ github.base_ref }} HEAD | \
5858
egrep ^stubs/ | cut -d "/" -f 2 | sort -u | \

scripts/stubsabot.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -620,6 +620,15 @@ async def has_no_longer_updated_release(release_to_download: PypiReleaseDownload
620620
return await with_extracted_archive(release_to_download, session=session, handler=parse_no_longer_updated_from_archive)
621621

622622

623+
def is_new_release(upload_datetime: datetime.datetime) -> bool:
624+
if upload_datetime.tzinfo is None:
625+
upload_datetime = upload_datetime.replace(tzinfo=datetime.timezone.utc)
626+
else:
627+
upload_datetime = upload_datetime.astimezone(datetime.timezone.utc)
628+
yesterday = datetime.datetime.now(tz=datetime.timezone.utc) - datetime.timedelta(days=1)
629+
return upload_datetime > yesterday
630+
631+
623632
async def determine_action(distribution: str, session: aiohttp.ClientSession) -> Update | NoUpdate | Obsolete | Remove | Error:
624633
try:
625634
return await determine_action_no_error_handling(distribution, session)
@@ -663,6 +672,12 @@ async def determine_action_no_error_handling(
663672
latest_version = latest_release.version
664673
obsolete_since = await find_first_release_with_py_typed(pypi_info, session=session)
665674
if obsolete_since is None and latest_version in stub_info.version_spec:
675+
if is_new_release(latest_release.upload_date):
676+
stubs = os.environ.get("STUBS", "").strip()
677+
if stubs:
678+
stubs = f"{stubs} {latest_release.distribution}"
679+
else:
680+
stubs = latest_release.distribution
666681
return NoUpdate(stub_info.distribution, "up to date")
667682

668683
relevant_version = obsolete_since.version if obsolete_since else latest_version

0 commit comments

Comments
 (0)