common-python-tasks 0.5.1__py3-none-any.whl → 0.6.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- common_python_tasks/docker.py +2 -2
- common_python_tasks/docker_compose.py +2 -2
- common_python_tasks/github.py +48 -2
- common_python_tasks/project.py +49 -3
- common_python_tasks/tasks.py +254 -8
- {common_python_tasks-0.5.1.dist-info → common_python_tasks-0.6.0.dist-info}/METADATA +8 -7
- {common_python_tasks-0.5.1.dist-info → common_python_tasks-0.6.0.dist-info}/RECORD +9 -9
- {common_python_tasks-0.5.1.dist-info → common_python_tasks-0.6.0.dist-info}/WHEEL +1 -1
- {common_python_tasks-0.5.1.dist-info → common_python_tasks-0.6.0.dist-info}/licenses/LICENSE +0 -0
common_python_tasks/docker.py
CHANGED
|
@@ -190,7 +190,7 @@ def prune_images_keep(
|
|
|
190
190
|
if line not in lines
|
|
191
191
|
]
|
|
192
192
|
|
|
193
|
-
tags_in_order
|
|
193
|
+
tags_in_order = []
|
|
194
194
|
seen_tags: set[str] = set()
|
|
195
195
|
for entry in lines:
|
|
196
196
|
try:
|
|
@@ -509,7 +509,7 @@ def build_image(
|
|
|
509
509
|
for t in tags_to_use
|
|
510
510
|
]
|
|
511
511
|
|
|
512
|
-
all_tags
|
|
512
|
+
all_tags = []
|
|
513
513
|
for resolved_tag in [*short_tags, *full_tags]:
|
|
514
514
|
if resolved_tag not in all_tags:
|
|
515
515
|
all_tags.append(resolved_tag)
|
|
@@ -414,8 +414,8 @@ def load_compose_files(
|
|
|
414
414
|
)
|
|
415
415
|
]
|
|
416
416
|
|
|
417
|
-
temp_config_files
|
|
418
|
-
addon_template_vars
|
|
417
|
+
temp_config_files = []
|
|
418
|
+
addon_template_vars = {}
|
|
419
419
|
|
|
420
420
|
if "db" in compose_addons and compose_type == "fastapi":
|
|
421
421
|
alembic_path, alembic_cleanup = ensure_alembic_config(compose_type)
|
common_python_tasks/github.py
CHANGED
|
@@ -344,6 +344,52 @@ def github_api_request(
|
|
|
344
344
|
return GitHubClient().api_request(method, path, payload=payload)
|
|
345
345
|
|
|
346
346
|
|
|
347
|
+
def create_pull_request(
|
|
348
|
+
title: str,
|
|
349
|
+
head: str,
|
|
350
|
+
base: str,
|
|
351
|
+
body: str | None = None,
|
|
352
|
+
draft: bool = False,
|
|
353
|
+
) -> dict[str, Any] | None:
|
|
354
|
+
"""Create a GitHub pull request for the current repository.
|
|
355
|
+
|
|
356
|
+
Args:
|
|
357
|
+
title: Pull request title.
|
|
358
|
+
head: Source branch name.
|
|
359
|
+
base: Base branch name.
|
|
360
|
+
body: Optional pull request body.
|
|
361
|
+
draft: Whether to create the pull request as a draft.
|
|
362
|
+
|
|
363
|
+
Returns:
|
|
364
|
+
The GitHub API response for the created pull request, or `None` when
|
|
365
|
+
repository information is unavailable.
|
|
366
|
+
"""
|
|
367
|
+
repository = get_github_repository()
|
|
368
|
+
token = get_github_token()
|
|
369
|
+
|
|
370
|
+
if repository is None:
|
|
371
|
+
LOGGER.debug(
|
|
372
|
+
"Skipping pull request creation because this is not a GitHub repository"
|
|
373
|
+
)
|
|
374
|
+
return None
|
|
375
|
+
if token is None:
|
|
376
|
+
utils.fatal(
|
|
377
|
+
"GITHUB_TOKEN or GH_TOKEN environment variable must be set to open a GitHub pull request"
|
|
378
|
+
)
|
|
379
|
+
|
|
380
|
+
return GitHubClient(repository=repository, token=token).api_request(
|
|
381
|
+
"POST",
|
|
382
|
+
"/pulls",
|
|
383
|
+
payload={
|
|
384
|
+
"title": title,
|
|
385
|
+
"head": head,
|
|
386
|
+
"base": base,
|
|
387
|
+
"body": body or "",
|
|
388
|
+
"draft": draft,
|
|
389
|
+
},
|
|
390
|
+
)
|
|
391
|
+
|
|
392
|
+
|
|
347
393
|
def publish_github_release(
|
|
348
394
|
tag_name: str,
|
|
349
395
|
release_name: str | None = None,
|
|
@@ -497,7 +543,7 @@ def get_github_release_asset_paths(
|
|
|
497
543
|
else:
|
|
498
544
|
source_items = ["dist/*"]
|
|
499
545
|
|
|
500
|
-
asset_paths
|
|
546
|
+
asset_paths = []
|
|
501
547
|
for part in source_items:
|
|
502
548
|
if any(char in part for char in "*?[]"):
|
|
503
549
|
asset_paths.extend(
|
|
@@ -589,7 +635,7 @@ def upload_github_release_assets(
|
|
|
589
635
|
Returns:
|
|
590
636
|
A list of decoded JSON responses for the uploaded assets.
|
|
591
637
|
"""
|
|
592
|
-
uploaded_assets
|
|
638
|
+
uploaded_assets = []
|
|
593
639
|
for asset_path in asset_paths:
|
|
594
640
|
LOGGER.info("Uploading GitHub Release asset: %s", asset_path)
|
|
595
641
|
uploaded = upload_github_release_asset(release_id, asset_path)
|
common_python_tasks/project.py
CHANGED
|
@@ -8,7 +8,7 @@ from enum import StrEnum, auto
|
|
|
8
8
|
from functools import lru_cache
|
|
9
9
|
from importlib import metadata
|
|
10
10
|
from pathlib import Path
|
|
11
|
-
from typing import Any
|
|
11
|
+
from typing import Any, Sequence
|
|
12
12
|
|
|
13
13
|
from packaging.specifiers import SpecifierSet
|
|
14
14
|
from packaging.version import Version
|
|
@@ -179,14 +179,60 @@ def get_package_manager_build_command(wheel_only: bool = False) -> list[str]:
|
|
|
179
179
|
return command
|
|
180
180
|
|
|
181
181
|
|
|
182
|
-
def
|
|
182
|
+
def get_package_manager_update_command(dependencies: Sequence[str] | None = None) -> list[str]:
|
|
183
|
+
"""Return the dependency update command for the selected package manager.
|
|
184
|
+
|
|
185
|
+
Args:
|
|
186
|
+
dependencies: Optional dependency names to update. When omitted, all
|
|
187
|
+
dependencies are updated.
|
|
188
|
+
|
|
189
|
+
Returns:
|
|
190
|
+
Command tokens for the dependency update command.
|
|
191
|
+
"""
|
|
192
|
+
if dependencies is None:
|
|
193
|
+
dependencies = []
|
|
194
|
+
|
|
195
|
+
package_manager = PackageManager(get_package_manager())
|
|
196
|
+
if package_manager == PackageManager.UV:
|
|
197
|
+
command = ["uv", "sync", "--upgrade"]
|
|
198
|
+
for dependency in dependencies:
|
|
199
|
+
command.extend(["--upgrade-package", dependency])
|
|
200
|
+
return command
|
|
201
|
+
|
|
202
|
+
return ["poetry", "update", *dependencies]
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
def get_package_manager_publish_command(
|
|
206
|
+
repository: str | None = None,
|
|
207
|
+
repository_url: str | None = None,
|
|
208
|
+
) -> list[str]:
|
|
183
209
|
"""Return the publish command for the selected package manager.
|
|
184
210
|
|
|
211
|
+
Args:
|
|
212
|
+
repository: Optional configured repository name to publish to.
|
|
213
|
+
repository_url: Optional repository upload URL to publish to.
|
|
214
|
+
|
|
185
215
|
Returns:
|
|
186
216
|
Command tokens for the package publish command.
|
|
187
217
|
"""
|
|
218
|
+
if repository is not None and repository_url is not None:
|
|
219
|
+
utils.fatal("Specify either `repository` or `repository_url`, not both.")
|
|
220
|
+
|
|
188
221
|
package_manager = PackageManager(get_package_manager())
|
|
189
|
-
|
|
222
|
+
command = [package_manager.value, "publish"]
|
|
223
|
+
if repository_url is not None:
|
|
224
|
+
if package_manager == PackageManager.POETRY:
|
|
225
|
+
utils.fatal(
|
|
226
|
+
"Poetry publish only supports configured repository names. "
|
|
227
|
+
"Pass `repository` instead of `repository_url`."
|
|
228
|
+
)
|
|
229
|
+
command += ["--publish-url", repository_url]
|
|
230
|
+
elif repository is not None:
|
|
231
|
+
if package_manager == PackageManager.UV:
|
|
232
|
+
command += ["--index", repository]
|
|
233
|
+
else:
|
|
234
|
+
command += ["-r", repository]
|
|
235
|
+
return command
|
|
190
236
|
|
|
191
237
|
|
|
192
238
|
@lru_cache
|
common_python_tasks/tasks.py
CHANGED
|
@@ -2,8 +2,10 @@ import contextvars
|
|
|
2
2
|
import inspect
|
|
3
3
|
import logging
|
|
4
4
|
import os
|
|
5
|
+
import re
|
|
5
6
|
from functools import partial, wraps
|
|
6
7
|
from pathlib import Path
|
|
8
|
+
from typing import Callable
|
|
7
9
|
|
|
8
10
|
from common_python_tasks.utils import confirm
|
|
9
11
|
from poethepoet_tasks import TaskCollection
|
|
@@ -116,13 +118,17 @@ def _wrap_task_function(func: callable, task_name: str | None) -> callable:
|
|
|
116
118
|
|
|
117
119
|
|
|
118
120
|
def _script(
|
|
119
|
-
func=None,
|
|
121
|
+
func: Callable | None = None,
|
|
120
122
|
task_name: str | None = None,
|
|
121
123
|
help: str | None = None,
|
|
122
124
|
task_args: bool = True,
|
|
123
125
|
options: dict | None = None,
|
|
124
|
-
tags: tuple[str, ...] =
|
|
126
|
+
tags: tuple[str, ...] | None = None,
|
|
125
127
|
):
|
|
128
|
+
|
|
129
|
+
if tags is None:
|
|
130
|
+
tags = ()
|
|
131
|
+
|
|
126
132
|
if func is None:
|
|
127
133
|
return partial(
|
|
128
134
|
_script,
|
|
@@ -956,18 +962,28 @@ def push_image(debug: bool = False) -> None:
|
|
|
956
962
|
|
|
957
963
|
|
|
958
964
|
@tasks.script(task_name="publish-package", tags=["packaging", "common"])
|
|
959
|
-
def publish_package(
|
|
965
|
+
def publish_package(
|
|
966
|
+
build_first: bool = True,
|
|
967
|
+
repository: str | None = None,
|
|
968
|
+
repository_url: str | None = None,
|
|
969
|
+
) -> None:
|
|
960
970
|
"""Publish the package to the PyPI server.
|
|
961
971
|
|
|
962
972
|
Args:
|
|
963
973
|
build_first: If `True`, build the package before publishing.
|
|
974
|
+
repository: Optional configured repository name to publish to.
|
|
975
|
+
repository_url: Optional repository upload URL to publish to.
|
|
964
976
|
"""
|
|
965
977
|
from .project import get_package_manager_publish_command
|
|
966
978
|
from .utils import run_command
|
|
967
979
|
|
|
968
980
|
if build_first:
|
|
969
981
|
build_package(clean_dist=True)
|
|
970
|
-
run_command(
|
|
982
|
+
run_command(
|
|
983
|
+
get_package_manager_publish_command(
|
|
984
|
+
repository=repository, repository_url=repository_url
|
|
985
|
+
)
|
|
986
|
+
)
|
|
971
987
|
|
|
972
988
|
|
|
973
989
|
@tasks.script(
|
|
@@ -1013,6 +1029,205 @@ def publish_github_release(
|
|
|
1013
1029
|
)
|
|
1014
1030
|
|
|
1015
1031
|
|
|
1032
|
+
def _get_default_branch() -> str:
|
|
1033
|
+
from .utils import run_command
|
|
1034
|
+
|
|
1035
|
+
result = run_command(
|
|
1036
|
+
["git", "symbolic-ref", "--quiet", "refs/remotes/origin/HEAD"],
|
|
1037
|
+
capture_output=True,
|
|
1038
|
+
acceptable_returncodes={0, 1},
|
|
1039
|
+
)
|
|
1040
|
+
if result.returncode == 0 and result.stdout.strip():
|
|
1041
|
+
return result.stdout.strip().rsplit("/", 1)[-1]
|
|
1042
|
+
return "main"
|
|
1043
|
+
|
|
1044
|
+
|
|
1045
|
+
def _get_current_branch() -> str:
|
|
1046
|
+
from .utils import fatal, run_command
|
|
1047
|
+
|
|
1048
|
+
result = run_command(["git", "branch", "--show-current"], capture_output=True)
|
|
1049
|
+
if not result.stdout.strip():
|
|
1050
|
+
fatal("Unable to determine current git branch.")
|
|
1051
|
+
return result.stdout.strip()
|
|
1052
|
+
|
|
1053
|
+
|
|
1054
|
+
def _dependency_branch_token(name: str) -> str:
|
|
1055
|
+
return re.sub(r"[^a-z0-9._-]+", "-", name.lower()).strip("-") or "updates"
|
|
1056
|
+
|
|
1057
|
+
|
|
1058
|
+
def _dependency_update_branch_name(dependency_names: list[str]) -> str:
|
|
1059
|
+
if not dependency_names:
|
|
1060
|
+
return "deps/update-dependencies"
|
|
1061
|
+
|
|
1062
|
+
branch_name = "deps/" + "-".join(
|
|
1063
|
+
_dependency_branch_token(name) for name in dependency_names[:5]
|
|
1064
|
+
)
|
|
1065
|
+
if len(dependency_names) > 5:
|
|
1066
|
+
branch_name = f"{branch_name}-and-more"
|
|
1067
|
+
return branch_name[:80].rstrip("-")
|
|
1068
|
+
|
|
1069
|
+
|
|
1070
|
+
def _extract_changed_dependency_names_from_diff(diff_output: str) -> list[str]:
|
|
1071
|
+
dependency_names: set[str] = set()
|
|
1072
|
+
for line in diff_output.splitlines():
|
|
1073
|
+
if not line or line.startswith(("+++", "---", "@@", "diff ", "index ")):
|
|
1074
|
+
continue
|
|
1075
|
+
if line[0] not in {" ", "+", "-"}:
|
|
1076
|
+
continue
|
|
1077
|
+
|
|
1078
|
+
text = line[1:].strip()
|
|
1079
|
+
lock_match = re.match(r'name\s*=\s*"([^"]+)"', text)
|
|
1080
|
+
if lock_match is not None:
|
|
1081
|
+
dependency_names.add(lock_match.group(1))
|
|
1082
|
+
continue
|
|
1083
|
+
|
|
1084
|
+
dependency_match = re.match(r'"([A-Za-z0-9_.-]+)(?:\[|\s|[<>=!~;(),"]|$)', text)
|
|
1085
|
+
if dependency_match is not None:
|
|
1086
|
+
dependency_names.add(dependency_match.group(1))
|
|
1087
|
+
|
|
1088
|
+
return sorted(dependency_names)
|
|
1089
|
+
|
|
1090
|
+
|
|
1091
|
+
def _get_changed_dependency_names() -> list[str]:
|
|
1092
|
+
from .utils import run_command
|
|
1093
|
+
|
|
1094
|
+
return _extract_changed_dependency_names_from_diff(
|
|
1095
|
+
run_command(
|
|
1096
|
+
[
|
|
1097
|
+
"git",
|
|
1098
|
+
"diff",
|
|
1099
|
+
"--unified=3",
|
|
1100
|
+
"--",
|
|
1101
|
+
"pyproject.toml",
|
|
1102
|
+
"poetry.lock",
|
|
1103
|
+
"uv.lock",
|
|
1104
|
+
],
|
|
1105
|
+
capture_output=True,
|
|
1106
|
+
).stdout
|
|
1107
|
+
)
|
|
1108
|
+
|
|
1109
|
+
|
|
1110
|
+
def _get_dependency_update_changed_files() -> list[Path]:
|
|
1111
|
+
from .utils import run_command
|
|
1112
|
+
|
|
1113
|
+
result = run_command(
|
|
1114
|
+
[
|
|
1115
|
+
"git",
|
|
1116
|
+
"status",
|
|
1117
|
+
"--porcelain",
|
|
1118
|
+
"--",
|
|
1119
|
+
"pyproject.toml",
|
|
1120
|
+
"poetry.lock",
|
|
1121
|
+
"uv.lock",
|
|
1122
|
+
],
|
|
1123
|
+
capture_output=True,
|
|
1124
|
+
)
|
|
1125
|
+
return [Path(line[3:]) for line in result.stdout.splitlines() if line]
|
|
1126
|
+
|
|
1127
|
+
|
|
1128
|
+
def _ensure_clean_dependency_update_worktree() -> None:
|
|
1129
|
+
from .git import get_dirty_files
|
|
1130
|
+
from .utils import fatal
|
|
1131
|
+
|
|
1132
|
+
if get_dirty_files():
|
|
1133
|
+
fatal(
|
|
1134
|
+
"Repository has uncommitted changes. "
|
|
1135
|
+
"Commit or stash them before creating a dependency update branch, commit, or pull request."
|
|
1136
|
+
)
|
|
1137
|
+
|
|
1138
|
+
|
|
1139
|
+
def _dependency_update_title(dependency_names: list[str]) -> str:
|
|
1140
|
+
if not dependency_names:
|
|
1141
|
+
return "chore(deps): update dependencies"
|
|
1142
|
+
if len(dependency_names) == 1:
|
|
1143
|
+
return f"chore(deps): update {dependency_names[0]}"
|
|
1144
|
+
return "chore(deps): update " + ", ".join(dependency_names[:5])
|
|
1145
|
+
|
|
1146
|
+
|
|
1147
|
+
@tasks.script(task_name="update-dependencies", tags=["packaging", "common"])
|
|
1148
|
+
def update_dependencies(
|
|
1149
|
+
*dependencies: str,
|
|
1150
|
+
branch: bool = False,
|
|
1151
|
+
branch_name: str | None = None,
|
|
1152
|
+
commit: bool = False,
|
|
1153
|
+
pr: bool = False,
|
|
1154
|
+
draft: bool = False,
|
|
1155
|
+
run_tests: bool = False,
|
|
1156
|
+
) -> None:
|
|
1157
|
+
"""Update project dependencies with Poetry or uv.
|
|
1158
|
+
|
|
1159
|
+
Args:
|
|
1160
|
+
*dependencies: Optional dependency names to update. When omitted, update
|
|
1161
|
+
all dependencies.
|
|
1162
|
+
branch: If `True`, create a dependency update branch after updating.
|
|
1163
|
+
branch_name: Optional branch name to use instead of generating one.
|
|
1164
|
+
commit: If `True`, commit the dependency update files.
|
|
1165
|
+
pr: If `True`, create and push a branch, commit the changes, and open
|
|
1166
|
+
a GitHub pull request.
|
|
1167
|
+
draft: If `True`, create the pull request as a draft.
|
|
1168
|
+
run_tests: If `True`, run the test task before committing.
|
|
1169
|
+
"""
|
|
1170
|
+
from .github import create_pull_request
|
|
1171
|
+
from .project import get_package_manager_update_command
|
|
1172
|
+
from .utils import run_command
|
|
1173
|
+
|
|
1174
|
+
should_create_branch = branch or branch_name is not None or pr
|
|
1175
|
+
if should_create_branch or commit:
|
|
1176
|
+
_ensure_clean_dependency_update_worktree()
|
|
1177
|
+
|
|
1178
|
+
run_command(get_package_manager_update_command(dependencies))
|
|
1179
|
+
if not _get_dependency_update_changed_files():
|
|
1180
|
+
LOGGER.info(
|
|
1181
|
+
"Dependency update completed with no lockfile or pyproject changes."
|
|
1182
|
+
)
|
|
1183
|
+
return
|
|
1184
|
+
|
|
1185
|
+
if run_tests:
|
|
1186
|
+
test()
|
|
1187
|
+
|
|
1188
|
+
changed_dependency_names = _get_changed_dependency_names() or sorted(dependencies)
|
|
1189
|
+
if should_create_branch:
|
|
1190
|
+
run_command(
|
|
1191
|
+
[
|
|
1192
|
+
"git",
|
|
1193
|
+
"checkout",
|
|
1194
|
+
"-b",
|
|
1195
|
+
branch_name or _dependency_update_branch_name(changed_dependency_names),
|
|
1196
|
+
]
|
|
1197
|
+
)
|
|
1198
|
+
|
|
1199
|
+
if commit or pr:
|
|
1200
|
+
run_command(
|
|
1201
|
+
[
|
|
1202
|
+
"git",
|
|
1203
|
+
"add",
|
|
1204
|
+
*[
|
|
1205
|
+
path
|
|
1206
|
+
for path in (
|
|
1207
|
+
Path("pyproject.toml"),
|
|
1208
|
+
Path("poetry.lock"),
|
|
1209
|
+
Path("uv.lock"),
|
|
1210
|
+
)
|
|
1211
|
+
if path.exists()
|
|
1212
|
+
],
|
|
1213
|
+
]
|
|
1214
|
+
)
|
|
1215
|
+
run_command(
|
|
1216
|
+
["git", "commit", "-m", _dependency_update_title(changed_dependency_names)]
|
|
1217
|
+
)
|
|
1218
|
+
|
|
1219
|
+
if pr:
|
|
1220
|
+
current_branch = _get_current_branch()
|
|
1221
|
+
run_command(["git", "push", "-u", "origin", current_branch])
|
|
1222
|
+
create_pull_request(
|
|
1223
|
+
title=_dependency_update_title(changed_dependency_names),
|
|
1224
|
+
head=current_branch,
|
|
1225
|
+
base=_get_default_branch(),
|
|
1226
|
+
body="Automated dependency update.",
|
|
1227
|
+
draft=draft,
|
|
1228
|
+
)
|
|
1229
|
+
|
|
1230
|
+
|
|
1016
1231
|
@tasks.script(task_name="build-package", tags=["packaging", "build", "common"])
|
|
1017
1232
|
def build_package(wheel_only: bool = False, clean_dist: bool = False) -> None:
|
|
1018
1233
|
"""Build the package (wheel and sdist)."""
|
|
@@ -1089,13 +1304,21 @@ def changelog() -> None:
|
|
|
1089
1304
|
print(_changelog())
|
|
1090
1305
|
|
|
1091
1306
|
|
|
1092
|
-
def _build_and_publish_release_package(
|
|
1307
|
+
def _build_and_publish_release_package(
|
|
1308
|
+
release_tag: str,
|
|
1309
|
+
repository: str | None = None,
|
|
1310
|
+
repository_url: str | None = None,
|
|
1311
|
+
) -> None:
|
|
1093
1312
|
from .utils import run_command
|
|
1094
1313
|
|
|
1095
1314
|
package_published = False
|
|
1096
1315
|
try:
|
|
1097
1316
|
build_package(clean_dist=True)
|
|
1098
|
-
publish_package(
|
|
1317
|
+
publish_package(
|
|
1318
|
+
build_first=False,
|
|
1319
|
+
repository=repository,
|
|
1320
|
+
repository_url=repository_url,
|
|
1321
|
+
)
|
|
1099
1322
|
package_published = True
|
|
1100
1323
|
finally:
|
|
1101
1324
|
if not package_published:
|
|
@@ -1122,6 +1345,8 @@ def _run_release_flow(
|
|
|
1122
1345
|
container_env: list[str] | None = None,
|
|
1123
1346
|
container_envfile: list[str] | None = None,
|
|
1124
1347
|
assets: list[str] | None = None,
|
|
1348
|
+
repository: str | None = None,
|
|
1349
|
+
repository_url: str | None = None,
|
|
1125
1350
|
pre_script: str | None = None,
|
|
1126
1351
|
post_script: str | None = None,
|
|
1127
1352
|
) -> None:
|
|
@@ -1171,7 +1396,14 @@ def _run_release_flow(
|
|
|
1171
1396
|
if dry_run:
|
|
1172
1397
|
log_dry_run("Would push tags to origin")
|
|
1173
1398
|
log_dry_run("Would build package with clean_dist=True")
|
|
1174
|
-
|
|
1399
|
+
if repository is None and repository_url is None:
|
|
1400
|
+
log_dry_run("Would publish package with build_first=False")
|
|
1401
|
+
else:
|
|
1402
|
+
log_dry_run(
|
|
1403
|
+
"Would publish package with build_first=False repository=%s repository_url=%s",
|
|
1404
|
+
repository,
|
|
1405
|
+
repository_url,
|
|
1406
|
+
)
|
|
1175
1407
|
if include_containers:
|
|
1176
1408
|
log_dry_run(
|
|
1177
1409
|
"Would build container image with debug=%s no_cache=%s plain=%s single_arch=%s",
|
|
@@ -1188,7 +1420,9 @@ def _run_release_flow(
|
|
|
1188
1420
|
run_command(["sh", "-lc", post_script], env=hook_env, dry_run=False)
|
|
1189
1421
|
return
|
|
1190
1422
|
|
|
1191
|
-
_build_and_publish_release_package(
|
|
1423
|
+
_build_and_publish_release_package(
|
|
1424
|
+
hook_env["RELEASE_TAG"], repository=repository, repository_url=repository_url
|
|
1425
|
+
)
|
|
1192
1426
|
|
|
1193
1427
|
if include_containers:
|
|
1194
1428
|
build_image(
|
|
@@ -1237,6 +1471,8 @@ def release(
|
|
|
1237
1471
|
container_env: list[str] | None = None,
|
|
1238
1472
|
container_envfile: list[str] | None = None,
|
|
1239
1473
|
assets: list[str] | None = None,
|
|
1474
|
+
repository: str | None = None,
|
|
1475
|
+
repository_url: str | None = None,
|
|
1240
1476
|
pre_script: str | None = None,
|
|
1241
1477
|
post_script: str | None = None,
|
|
1242
1478
|
) -> None:
|
|
@@ -1256,6 +1492,8 @@ def release(
|
|
|
1256
1492
|
`KEY=VALUE` values.
|
|
1257
1493
|
container_envfile: Repeated list of container environment files.
|
|
1258
1494
|
assets: Optional repeated list of release asset patterns or paths.
|
|
1495
|
+
repository: Optional configured repository name to publish to.
|
|
1496
|
+
repository_url: Optional repository upload URL to publish to.
|
|
1259
1497
|
pre_script: Optional shell command to run before the release steps.
|
|
1260
1498
|
post_script: Optional shell command to run after the release completes.
|
|
1261
1499
|
"""
|
|
@@ -1272,6 +1510,8 @@ def release(
|
|
|
1272
1510
|
container_env=container_env,
|
|
1273
1511
|
container_envfile=container_envfile,
|
|
1274
1512
|
assets=assets,
|
|
1513
|
+
repository=repository,
|
|
1514
|
+
repository_url=repository_url,
|
|
1275
1515
|
pre_script=pre_script,
|
|
1276
1516
|
post_script=post_script,
|
|
1277
1517
|
)
|
|
@@ -1283,6 +1523,8 @@ def release_without_containers(
|
|
|
1283
1523
|
stage: str | None = None,
|
|
1284
1524
|
dry_run: bool = False,
|
|
1285
1525
|
assets: list[str] | None = None,
|
|
1526
|
+
repository: str | None = None,
|
|
1527
|
+
repository_url: str | None = None,
|
|
1286
1528
|
pre_script: str | None = None,
|
|
1287
1529
|
post_script: str | None = None,
|
|
1288
1530
|
) -> None:
|
|
@@ -1293,6 +1535,8 @@ def release_without_containers(
|
|
|
1293
1535
|
stage: Optional pre-release stage to apply: `alpha`, `beta`, or `rc`.
|
|
1294
1536
|
dry_run: If `True`, only perform a dry-run version bump.
|
|
1295
1537
|
assets: Optional repeated list of release asset patterns or paths.
|
|
1538
|
+
repository: Optional configured repository name to publish to.
|
|
1539
|
+
repository_url: Optional repository upload URL to publish to.
|
|
1296
1540
|
pre_script: Optional shell command to run before the release steps.
|
|
1297
1541
|
post_script: Optional shell command to run after the release completes.
|
|
1298
1542
|
"""
|
|
@@ -1302,6 +1546,8 @@ def release_without_containers(
|
|
|
1302
1546
|
dry_run=dry_run,
|
|
1303
1547
|
include_containers=False,
|
|
1304
1548
|
assets=assets,
|
|
1549
|
+
repository=repository,
|
|
1550
|
+
repository_url=repository_url,
|
|
1305
1551
|
pre_script=pre_script,
|
|
1306
1552
|
post_script=post_script,
|
|
1307
1553
|
)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: common-python-tasks
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.6.0
|
|
4
4
|
Summary: Opinionated Poe the Poet tasks for Python package development.
|
|
5
5
|
Project-URL: Homepage, http://github.com/ci-sourcerer/common-python-tasks
|
|
6
6
|
Project-URL: Source, http://github.com/ci-sourcerer/common-python-tasks.git
|
|
@@ -55,7 +55,7 @@ To install a specific release, set the environment variable `COMMON_PYTHON_TASKS
|
|
|
55
55
|
curl -sSL https://api.github.com/repos/ci-sourcerer/common-python-tasks/contents/scripts/add_common_python_tasks.py \
|
|
56
56
|
| jq -r '.content' \
|
|
57
57
|
| base64 -d \
|
|
58
|
-
| COMMON_PYTHON_TASKS_VERSION=0.
|
|
58
|
+
| COMMON_PYTHON_TASKS_VERSION=0.6.0 python3
|
|
59
59
|
```
|
|
60
60
|
|
|
61
61
|
This will complete the following steps.
|
|
@@ -75,7 +75,7 @@ There's no real reason to run the automated script; I just like automating every
|
|
|
75
75
|
```toml
|
|
76
76
|
[project]
|
|
77
77
|
dependencies = [
|
|
78
|
-
"common-python-tasks==0.
|
|
78
|
+
"common-python-tasks==0.6.0" # Always pin to a specific version
|
|
79
79
|
]
|
|
80
80
|
|
|
81
81
|
[tool.poe]
|
|
@@ -115,6 +115,7 @@ Internal tasks are used by other tasks and are not meant to be run directly.
|
|
|
115
115
|
| `push-image` | Push the Docker image for this project to the container registry. | containers, packaging, release |
|
|
116
116
|
| `publish-package` | Publish the package to the PyPI server. | common, packaging |
|
|
117
117
|
| `publish-github-release` | Publish or update a GitHub Release for the current repository. | common, packaging, release |
|
|
118
|
+
| `update-dependencies` | Update project dependencies with Poetry or uv. | common, packaging |
|
|
118
119
|
| `build-package` | Build the package (wheel and sdist). | build, common, packaging |
|
|
119
120
|
| `bump-version` | Bump the project version. | common, packaging |
|
|
120
121
|
| `changelog` | Print the changelog for the current version based on git history and git-cliff. | common, packaging, release |
|
|
@@ -309,8 +310,8 @@ By default, `tasks()` exposes the common task set. You can still include or excl
|
|
|
309
310
|
```toml
|
|
310
311
|
[project]
|
|
311
312
|
name = "simple-cli-tool"
|
|
312
|
-
version = "0.
|
|
313
|
-
dependencies = ["common-python-tasks==0.
|
|
313
|
+
version = "0.6.0"
|
|
314
|
+
dependencies = ["common-python-tasks==0.6.0"]
|
|
314
315
|
|
|
315
316
|
[tool.poe]
|
|
316
317
|
include_script = "common_python_tasks:tasks()"
|
|
@@ -322,7 +323,7 @@ Available tasks: common defaults such as `format`, `lint`, `test`, and `build`.
|
|
|
322
323
|
|
|
323
324
|
```toml
|
|
324
325
|
[project]
|
|
325
|
-
dependencies = ["common-python-tasks==0.
|
|
326
|
+
dependencies = ["common-python-tasks==0.6.0"]
|
|
326
327
|
|
|
327
328
|
[tool.poe]
|
|
328
329
|
include_script = "common_python_tasks:tasks(include_tags=['common', 'containers'])"
|
|
@@ -338,7 +339,7 @@ Available tasks: All tasks including `build-image` and `push-image`.
|
|
|
338
339
|
|
|
339
340
|
```toml
|
|
340
341
|
[project]
|
|
341
|
-
dependencies = ["common-python-tasks==0.
|
|
342
|
+
dependencies = ["common-python-tasks==0.6.0"]
|
|
342
343
|
|
|
343
344
|
[tool.poe]
|
|
344
345
|
include_script = "common_python_tasks:tasks()"
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
common_python_tasks/__init__.py,sha256=A-qMF818PGbDxM_DH9l1HwQMV-tXn8CZZiVQy-F_sLc,550
|
|
2
2
|
common_python_tasks/__main__.py,sha256=AZiLLusMDs0rZIIBuCDbt6jABlQD-kEwIQIep7GxgEc,3019
|
|
3
|
-
common_python_tasks/docker.py,sha256=
|
|
4
|
-
common_python_tasks/docker_compose.py,sha256=
|
|
3
|
+
common_python_tasks/docker.py,sha256=cbVesXb8PocchkIkvyhhX3XYM38G8MX-_BHFYSRvWNI,19672
|
|
4
|
+
common_python_tasks/docker_compose.py,sha256=P6yaHyG4AUGb8kD0qI8En-gyaZT4gFqP6ocWXWDfnqE,21018
|
|
5
5
|
common_python_tasks/env.py,sha256=X-v2gX6SJluvkjU7M941UbrMZ73vHnxwLeaBWRUxeLc,15678
|
|
6
6
|
common_python_tasks/git.py,sha256=wJ3gePpWE4fhNJYZCEWTDFrhHqaOVkaQveHeiGIbCHo,11188
|
|
7
|
-
common_python_tasks/github.py,sha256=
|
|
8
|
-
common_python_tasks/project.py,sha256=
|
|
9
|
-
common_python_tasks/tasks.py,sha256=
|
|
7
|
+
common_python_tasks/github.py,sha256=UjoL_eJIg6NLQ6kch_uZOjj77PeNguqNKtYmYVSkLX8,20392
|
|
8
|
+
common_python_tasks/project.py,sha256=07dXipGt5ZMqWNcsU_5bFX-CYFzsVNaVP2SN81nWDCk,22442
|
|
9
|
+
common_python_tasks/tasks.py,sha256=BDrWDmKX5_aTMw5JIeXEetlviw1dFkoXQTake6v3dCc,62704
|
|
10
10
|
common_python_tasks/utils.py,sha256=ej4nKFPMFhu1wSgkL9x50DML_sPoPmR6aGcIMyAmfN8,19586
|
|
11
11
|
common_python_tasks/data/dockerfile_extensions/.gitkeep,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
12
12
|
common_python_tasks/data/fastapi/alembic.ini.j2,sha256=IVXmnF1pJvW3o8dXBLIVhmng7DyXu_sWXx_W3VlAcGE,910
|
|
@@ -22,7 +22,7 @@ common_python_tasks/data/generic/Dockerfile.deps.j2,sha256=rCGsBwLHQIRsGFzDbiRi_
|
|
|
22
22
|
common_python_tasks/data/generic/Dockerfile.j2,sha256=UG-QxIuFT27j925LsghPl5Wqcw5wNsPPuqB6rcRngz0,7263
|
|
23
23
|
common_python_tasks/data/generic/cliff.toml,sha256=po1MnEGEEgrpyBz3XLWr0h7emXb6ASX63lrU2r6o240,77
|
|
24
24
|
common_python_tasks/data/generic/pytest.ini,sha256=RHak5QrLzKHvUBjFmaaiOYFrd_8YBRQubXEOT0NJfco,134
|
|
25
|
-
common_python_tasks-0.
|
|
26
|
-
common_python_tasks-0.
|
|
27
|
-
common_python_tasks-0.
|
|
28
|
-
common_python_tasks-0.
|
|
25
|
+
common_python_tasks-0.6.0.dist-info/METADATA,sha256=Kvp10JnUuI_GtW7ex4TeeIa5QAQcMd2qaGGH_EtC21M,22687
|
|
26
|
+
common_python_tasks-0.6.0.dist-info/WHEEL,sha256=lCkmxWfQsSc9CfIClYeavTdQeEX2toPqufh9gI35EQA,87
|
|
27
|
+
common_python_tasks-0.6.0.dist-info/licenses/LICENSE,sha256=RsSweM-DyzxFPx38fQOJqHrKyeT9Fiz8rO7yox-fOsw,1070
|
|
28
|
+
common_python_tasks-0.6.0.dist-info/RECORD,,
|
{common_python_tasks-0.5.1.dist-info → common_python_tasks-0.6.0.dist-info}/licenses/LICENSE
RENAMED
|
File without changes
|