Skip to content

Commit 414f86b

Browse files
committed
chore: update all CI stuff
1 parent 86d8b49 commit 414f86b

File tree

10 files changed

+56
-180
lines changed

10 files changed

+56
-180
lines changed

.ci/release

Lines changed: 26 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,48 @@
11
#!/usr/bin/env python3
22
'''
3-
Run [[file:scripts/release][scripts/release]] to deploy Python package onto [[https://pypi.org][PyPi]] and [[https://test.pypi.org][test PyPi]].
3+
Deploys Python package onto [[https://pypi.org][PyPi]] or [[https://test.pypi.org][test PyPi]].
44
5-
The script expects =TWINE_PASSWORD= environment variable to contain the [[https://pypi.org/help/#apitoken][PyPi token]] (not the password!).
5+
- running manually
66
7-
The script can be run manually.
8-
It's also running as =pypi= job in [[file:.github/workflows/main.yml][Github Actions config]]. Packages are deployed on:
9-
- every master commit, onto test pypi
10-
- every new tag, onto production pypi
7+
You'll need =UV_PUBLISH_TOKEN= env variable
118
12-
You'll need to set =TWINE_PASSWORD= and =TWINE_PASSWORD_TEST= in [[https://help.github.com/en/actions/configuring-and-managing-workflows/creating-and-storing-encrypted-secrets#creating-encrypted-secrets][secrets]]
13-
for Github Actions deployment to work.
9+
- running on Github Actions
10+
11+
Instead of env variable, relies on configuring github as Trusted publisher (https://docs.pypi.org/trusted-publishers/) -- both for test and regular pypi
12+
13+
It's running as =pypi= job in [[file:.github/workflows/main.yml][Github Actions config]].
14+
Packages are deployed on:
15+
- every master commit, onto test pypi
16+
- every new tag, onto production pypi
1417
'''
1518

19+
UV_PUBLISH_TOKEN = 'UV_PUBLISH_TOKEN'
20+
21+
import argparse
1622
import os
17-
import sys
1823
from pathlib import Path
1924
from subprocess import check_call
20-
import shutil
2125

2226
is_ci = os.environ.get('CI') is not None
2327

28+
2429
def main() -> None:
25-
import argparse
2630
p = argparse.ArgumentParser()
27-
p.add_argument('--test', action='store_true', help='use test pypi')
31+
p.add_argument('--use-test-pypi', action='store_true')
2832
args = p.parse_args()
2933

30-
extra = []
31-
if args.test:
32-
extra.extend(['--repository', 'testpypi'])
34+
publish_url = ['--publish-url', 'https://test.pypi.org/legacy/'] if args.use_test_pypi else []
3335

3436
root = Path(__file__).absolute().parent.parent
35-
os.chdir(root) # just in case
36-
37-
if is_ci:
38-
# see https://github.com/actions/checkout/issues/217
39-
check_call('git fetch --prune --unshallow'.split())
40-
41-
dist = root / 'dist'
42-
if dist.exists():
43-
shutil.rmtree(dist)
44-
45-
check_call(['python3', '-m', 'build'])
46-
47-
TP = 'TWINE_PASSWORD'
48-
password = os.environ.get(TP)
49-
if password is None:
50-
print(f"WARNING: no {TP} passed", file=sys.stderr)
51-
import pip_secrets
52-
password = pip_secrets.token_test if args.test else pip_secrets.token # meh
53-
54-
check_call([
55-
'python3', '-m', 'twine',
56-
'upload', *dist.iterdir(),
57-
*extra,
58-
], env={
59-
'TWINE_USERNAME': '__token__',
60-
TP: password,
61-
**os.environ,
62-
})
37+
os.chdir(root) # just in case
38+
39+
check_call(['uv', 'build', '--clear'])
40+
41+
if not is_ci:
42+
# CI relies on trusted publishers so doesn't need env variable
43+
assert UV_PUBLISH_TOKEN in os.environ, f'no {UV_PUBLISH_TOKEN} passed'
44+
45+
check_call(['uv', 'publish', *publish_url])
6346

6447

6548
if __name__ == '__main__':

.ci/release-uv

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

.github/workflows/main.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ jobs:
4343
# ugh https://github.com/actions/toolkit/blob/main/docs/commands.md#path-manipulation
4444
- run: echo "$HOME/.local/bin" >> $GITHUB_PATH
4545

46-
- uses: actions/checkout@v5
46+
- uses: actions/checkout@v6
4747
with:
4848
submodules: recursive
4949
fetch-depth: 0 # nicer to have all git history when debugging/for tests
@@ -93,7 +93,7 @@ jobs:
9393
# ugh https://github.com/actions/toolkit/blob/main/docs/commands.md#path-manipulation
9494
- run: echo "$HOME/.local/bin" >> $GITHUB_PATH
9595

96-
- uses: actions/checkout@v5
96+
- uses: actions/checkout@v6
9797
with:
9898
submodules: recursive
9999
fetch-depth: 0 # pull all commits to correctly infer vcs version
@@ -109,9 +109,9 @@ jobs:
109109
- name: 'release to test pypi'
110110
# always deploy merged master to test pypi
111111
if: github.event.ref == format('refs/heads/{0}', github.event.repository.master_branch)
112-
run: .ci/release-uv --use-test-pypi
112+
run: .ci/release --use-test-pypi
113113

114114
- name: 'release to prod pypi'
115115
# always deploy tags to release pypi
116116
if: startsWith(github.event.ref, 'refs/tags/')
117-
run: .ci/release-uv
117+
run: .ci/release

conftest.py

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

pyproject.toml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,13 @@ Homepage = "https://github.com/karlicoss/cachew"
3434
optional = [
3535
"colorlog",
3636
]
37+
3738
[dependency-groups]
3839
# TODO: not sure, on the one hand could just use 'standard' dev dependency group
3940
# On the other hand, it's a bit annoying that it's always included by default?
4041
# To make sure it's not included, need to use `uv run --exact --no-default-groups ...`
4142
testing = [
42-
"pytest",
43+
"pytest>=9", # need version 9 for proper namespace package support
4344
"ruff",
4445

4546
"pytz",
@@ -53,10 +54,9 @@ testing = [
5354
]
5455
typecheck = [
5556
{ include-group = "testing" },
56-
5757
"mypy",
58-
"lxml", # for mypy coverage
59-
"ty>=0.0.1a22",
58+
"lxml", # for mypy html coverage
59+
"ty>=0.0.3",
6060

6161
"types-pytz", # optional runtime only dependency
6262

pytest.ini

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@
22
# discover files that don't follow test_ naming. Useful to keep tests along with the source code
33
python_files = *.py
44

5-
# this setting only impacts package/module naming under pytest, not the discovery
5+
# this is necessary for --pyargs to discover implicit namespace packages correctly
66
consider_namespace_packages = true
77

8+
# see https://docs.pytest.org/en/stable/reference/reference.html#confval-strict
9+
strict = true
10+
811
addopts =
912
# prevent pytest cache from being created... it craps into project dir and I never use it anyway
1013
-p no:cacheprovider

src/cachew/__init__.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -278,11 +278,11 @@ def cachew_error(e: Exception, *, logger: logging.Logger) -> None:
278278
@doublewrap
279279
def cachew_impl[**P](
280280
func=None, # TODO should probably type it after switch to python 3.10/proper paramspec
281-
cache_path: PathProvider[P] | None = use_default_path, # ty: ignore[too-many-positional-arguments] # see https://github.com/astral-sh/ty/issues/157
281+
cache_path: PathProvider[P] | None = use_default_path,
282282
*,
283283
force_file: bool = False,
284284
cls: type | tuple[Kind, type] | None = None,
285-
depends_on: HashFunction[P] = default_hash, # ty: ignore[too-many-positional-arguments]
285+
depends_on: HashFunction[P] = default_hash,
286286
logger: logging.Logger | None = None,
287287
chunk_by: int = 100,
288288
# NOTE: allowed values for chunk_by depend on the system.
@@ -435,7 +435,7 @@ def _func(*args, **kwargs):
435435
@functools.wraps(func)
436436
def binder(*args, **kwargs):
437437
kwargs['_cachew_context'] = ctx
438-
res = cachew_wrapper(*args, **kwargs) # ty: ignore[missing-argument]
438+
res = cachew_wrapper(*args, **kwargs)
439439

440440
if use_kind == 'single':
441441
lres = list(res)
@@ -457,11 +457,11 @@ def cachew[F: Callable](fun: F) -> F: ...
457457
# but at least it works for checking that cachew_path and depdns_on have the same args :shrug:
458458
@overload
459459
def cachew[F, **P](
460-
cache_path: PathProvider[P] | None = ..., # ty: ignore[too-many-positional-arguments]
460+
cache_path: PathProvider[P] | None = ...,
461461
*,
462462
force_file: bool = ...,
463463
cls: type | tuple[Kind, type] | None = ...,
464-
depends_on: HashFunction[P] = ..., # ty: ignore[too-many-positional-arguments]
464+
depends_on: HashFunction[P] = ...,
465465
logger: logging.Logger | None = ...,
466466
chunk_by: int = ...,
467467
synthetic_key: str | None = ...,
@@ -568,10 +568,10 @@ def _module_is_disabled(module_name: str, logger: logging.Logger) -> bool:
568568
class Context[**P]:
569569
# fmt: off
570570
func : Callable
571-
cache_path : PathProvider[P] # ty: ignore[too-many-positional-arguments]
571+
cache_path : PathProvider[P]
572572
force_file : bool
573573
cls_ : type
574-
depends_on : HashFunction[P] # ty: ignore[too-many-positional-arguments]
574+
depends_on : HashFunction[P]
575575
logger : logging.Logger
576576
chunk_by : int
577577
synthetic_key: str | None
@@ -612,7 +612,7 @@ def composite_hash(self, *args, **kwargs) -> dict[str, Any]:
612612

613613
def cachew_wrapper[**P](
614614
*args,
615-
_cachew_context: Context[P], # ty: ignore[too-many-positional-arguments]
615+
_cachew_context: Context[P],
616616
**kwargs,
617617
):
618618
C = _cachew_context

src/cachew/legacy.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ def get_union_args(cls) -> Optional[tuple[type]]:
2828
args = cls.__args__
2929
args = tuple(e for e in args if e is not type(None))
3030
assert len(args) > 0
31-
return args
31+
return args # ty: ignore[invalid-return-type]
3232

3333

3434
def is_union(cls) -> bool:
@@ -313,7 +313,7 @@ class NTBinder(Generic[NT]):
313313

314314
@staticmethod
315315
def make(tp: type[NT], name: Optional[str] = None) -> 'NTBinder[NT]':
316-
tp, optional = strip_optional(tp)
316+
tp, optional = strip_optional(tp) # ty: ignore[invalid-assignment]
317317
union: Optional[type]
318318
fields: tuple[Any, ...]
319319
primitive: bool

src/cachew/tests/marshall.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ def union_hook(data, type_):
110110
jsons: list[Json] = [None for _ in range(count)]
111111
with profile(test_name + ':serialize'), timer(f'serializing {count} objects of type {Type}'):
112112
for i in range(count):
113-
jsons[i] = to_json(objects[i])
113+
jsons[i] = to_json(objects[i]) # ty: ignore[invalid-assignment]
114114

115115
strs: list[bytes] = [None for _ in range(count)] # type: ignore[misc]
116116
with profile(test_name + ':json_dump'), timer(f'json dump {count} objects of type {Type}'):
@@ -165,7 +165,7 @@ def union_hook(data, type_):
165165
objects2 = [None for _ in range(count)]
166166
with profile(test_name + ':deserialize'), timer(f'deserializing {count} objects of type {Type}'):
167167
for i in range(count):
168-
objects2[i] = from_json(jsons2[i])
168+
objects2[i] = from_json(jsons2[i]) # ty: ignore[invalid-argument-type]
169169

170170
assert objects[:100] + objects[-100:] == objects2[:100] + objects2[-100:]
171171

tox.ini

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
[tox]
2-
minversion = 3.21
2+
minversion = 4
3+
34
# relies on the correct version of Python installed
5+
# (we rely on CI for the test matrix)
46
envlist = ruff,tests,mypy,ty
7+
58
# https://github.com/tox-dev/tox/issues/20#issuecomment-247788333
69
# hack to prevent .tox from crapping to the project directory
710
toxworkdir = {env:TOXWORKDIR_BASE:}{toxinidir}/.tox
@@ -23,8 +26,8 @@ set_env =
2326
# generally this is more robust and safer, prevents weird issues later on
2427
PYTHONSAFEPATH=1
2528

26-
# default is 'editable', in which tox builds wheel first for some reason? not sure if makes much sense
27-
package = uv-editable
29+
runner = uv-venv-lock-runner
30+
uv_sync_locked = false
2831

2932

3033
[testenv:ruff]

0 commit comments

Comments
 (0)