Skip to content

Commit 4f4420a

Browse files
committed
Refactor deployment checks and update dependencies
- Refactor `wait_for_deploy` to accept `expected_version` argument - Update callers in `bot.py` to pass the version. - Update tests in `wait_for_deploy_test.py` and `bot_test.py`. - Replace deprecated `pkg_resources` with `packaging` for version parsing. - Improve Python package publishing in `publish.py`: - Use `python -m build .` for building sdist and wheel. - Use `check_call` to ensure build errors are raised. - Fix virtual environment handling to ensure `build` module is found. - Update GitHub Actions CI workflow to use `uv` instead of `pip`. - Address various Pylint errors in `publish.py` and `wait_for_deploy.py`.
1 parent ae47c6f commit 4f4420a

File tree

11 files changed

+908
-139
lines changed

11 files changed

+908
-139
lines changed

.github/workflows/ci.yml

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,38 +2,28 @@ name: CI
22
on: [push]
33
jobs:
44
python-tests:
5-
runs-on: ubuntu-24.04
5+
runs-on: ubuntu-latest
66

77
steps:
88
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
99

1010
- name: Set up JS requirements
1111
run: npm install
1212

13-
- name: Set up Python
14-
uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5.5.0
15-
with:
16-
python-version: "3.13"
13+
- name: Install uv
14+
run: curl -LsSf https://astral.sh/uv/install.sh | sh
1715

18-
- id: cache
19-
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
20-
with:
21-
path: ~/.cache/pip
22-
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt', '**/test_requirements.txt') }}
23-
restore-keys: |
24-
${{ runner.os }}-pip-
25-
26-
- name: Install dependencies
27-
run: pip install -r requirements.txt -r test_requirements.txt
16+
- name: Install Python dependencies with uv
17+
run: uv sync --locked
2818

2919
- name: Lint
30-
run: pylint *.py
20+
run: uv run pylint *.py
3121

3222
- name: Black
33-
run: black --version && black . --check
23+
run: uv run black --version && uv run black . --check
3424

3525
- name: Tests
36-
run: pytest . && coverage xml
26+
run: uv run pytest . && uv run coverage xml
3727

3828
# - name: Upload coverage to CodeCov
3929
# uses: codecov/codecov-action@v1

bot_test.py

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,7 @@ async def test_release(
444444
repo_url=test_repo.repo_url,
445445
hash_url=test_repo.rc_hash_url,
446446
watch_branch="release-candidate",
447+
expected_version=pr.version,
447448
timeout_seconds=3600,
448449
)
449450
assert doof.said("Now deploying to RC...")
@@ -519,6 +520,7 @@ async def test_hotfix_release(
519520
repo_url=test_repo.repo_url,
520521
hash_url=test_repo.rc_hash_url,
521522
watch_branch="release-candidate",
523+
expected_version=pr.version,
522524
timeout_seconds=3600,
523525
)
524526
assert doof.said("Now deploying to RC...")
@@ -1219,6 +1221,7 @@ async def test_wait_for_deploy_rc(
12191221
repo_url=test_repo.repo_url,
12201222
hash_url=test_repo.rc_hash_url,
12211223
watch_branch="release-candidate",
1224+
expected_version=release_pr.version,
12221225
timeout_seconds=3600,
12231226
)
12241227
get_unchecked.assert_called_once_with(
@@ -1239,26 +1242,17 @@ async def test_wait_for_deploy_prod(
12391242
): # pylint: disable=unused-argument
12401243
"""Bot._wait_for_deploy_prod should wait until repo has been deployed to production"""
12411244
wait_for_deploy_mock = mocker.async_patch("bot.wait_for_deploy")
1242-
version = "1.2.345"
1243-
get_version_tag_mock = mocker.async_patch(
1244-
"bot.get_version_tag", return_value=f"v{version}"
1245-
)
12461245
channel_id = test_repo.channel_id
12471246
release_pr = ReleasePR(
1248-
"version", "https://github.com/org/repo/pulls/123456", "body", 123456, False
1247+
"1.2.345", "https://github.com/org/repo/pulls/123456", "body", 123456, False
12491248
)
12501249

12511250
await doof._wait_for_deploy_prod( # pylint: disable=protected-access
12521251
repo_info=test_repo, manager="me", release_pr=release_pr
12531252
)
12541253

1255-
get_version_tag_mock.assert_called_once_with(
1256-
github_access_token=GITHUB_ACCESS,
1257-
repo_url=test_repo.repo_url,
1258-
commit_hash="origin/release",
1259-
)
12601254
assert doof.said(
1261-
f"My evil scheme v{version} for {test_repo.name} has been released "
1255+
f"My evil scheme {release_pr.version} for {test_repo.name} has been released " # Use release_pr.version
12621256
f"to production at {remove_path_from_url(test_repo.prod_hash_url)}. "
12631257
"And by 'released', I mean completely...um...leased.",
12641258
channel_id=channel_id,
@@ -1268,6 +1262,7 @@ async def test_wait_for_deploy_prod(
12681262
repo_url=test_repo.repo_url,
12691263
hash_url=test_repo.prod_hash_url,
12701264
watch_branch="release",
1265+
expected_version=release_pr.version, # Pass expected_version from PR
12711266
timeout_seconds=3600,
12721267
)
12731268

publish.py

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
"""Functions for publishing"""
2-
32
import os
43
from pathlib import Path
54

65
from async_subprocess import (
7-
call,
86
check_call,
97
)
108
from constants import (
@@ -28,13 +26,6 @@ async def upload_to_pypi(project_dir):
2826
# Heroku has both Python 2 and 3 installed but the system libraries aren't configured for our use,
2927
# so make a virtualenv.
3028
async with virtualenv("python3", outer_environ) as (virtualenv_dir, environ):
31-
# Use the virtualenv binaries to act within that environment
32-
pip_path = os.path.join(virtualenv_dir, "bin", "pip")
33-
34-
# Install dependencies. wheel is needed for Python 2. twine uploads the package.
35-
await check_call(
36-
[pip_path, "install", "twine"], env=environ, cwd=project_dir
37-
)
3829
await upload_with_twine(
3930
project_dir=project_dir, virtualenv_dir=virtualenv_dir, environ=environ
4031
)
@@ -56,15 +47,18 @@ async def upload_with_twine(
5647
"TWINE_USERNAME": os.environ["PYPI_USERNAME"],
5748
"TWINE_PASSWORD": os.environ["PYPI_PASSWORD"],
5849
}
59-
60-
python_path = os.path.join(virtualenv_dir, "bin", "python")
50+
# Use the virtualenv binaries to act within that environment
6151
pip_path = os.path.join(virtualenv_dir, "bin", "pip")
52+
python_path = os.path.join(virtualenv_dir, "bin", "python")
53+
# Install dependencies. wheel is needed for Python 2. twine uploads the package.
54+
await check_call([pip_path, "install", "setuptools"], env=environ, cwd=project_dir)
55+
await check_call([pip_path, "install", "build"], env=environ, cwd=project_dir)
56+
await check_call([pip_path, "install", "twine"], env=environ, cwd=project_dir)
6257
twine_path = os.path.join(virtualenv_dir, "bin", "twine")
6358

64-
# Create source distribution and wheel.
65-
await call([pip_path, "install", "setuptools"], env=environ, cwd=project_dir)
66-
await call([python_path, "setup.py", "sdist"], env=environ, cwd=project_dir)
67-
await call([python_path, "setup.py", "bdist_wheel"], env=environ, cwd=project_dir)
59+
# Create source distribution and wheel using the virtualenv's python executable
60+
# and explicitly passing the virtualenv's environment.
61+
await check_call([python_path, "-m", "build", "."], env=environ, cwd=project_dir)
6862
dist_files = os.listdir(os.path.join(project_dir, "dist"))
6963
if len(dist_files) != 2:
7064
raise Exception("Expected to find one tarball and one wheel in directory")

publish_test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ def _call(command, *args, **kwargs):
5555
virtualenv_dir=virtualenv_dir,
5656
environ=environ,
5757
)
58-
assert call_mock.call_count == 1
58+
assert call_mock.call_count == 5
5959

6060

6161
async def test_upload_to_npm(mocker, test_repo_directory, library_test_repo):

pyproject.toml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
[project]
2+
name = "doof"
3+
requires-python = "~=3.13"
4+
version = "0.0.1"
5+
dependencies = [
6+
"python-dateutil",
7+
"pytz",
8+
"requests",
9+
"sentry-sdk",
10+
"setuptools>=78.1.0",
11+
"tornado",
12+
"virtualenv",
13+
]
14+
15+
[dependency-groups]
16+
dev = [
17+
"black==22.3.0",
18+
"codecov",
19+
"pdbpp",
20+
"pylint",
21+
"pytest",
22+
"pytest-asyncio",
23+
"pytest-cov",
24+
"pytest-mock",
25+
]
26+
27+
[tool.uv]
28+
package = false

requirements.txt

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

runtime.txt

Lines changed: 0 additions & 1 deletion
This file was deleted.

test_requirements.txt

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

0 commit comments

Comments
 (0)