common-python-tasks 0.10.2__py3-none-any.whl → 0.11.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/data/fastapi/compose-db.yml.j2 +1 -1
- common_python_tasks/data/generic/Dockerfile.j2 +8 -1
- common_python_tasks/docker_compose.py +2 -1
- common_python_tasks/env.py +1 -0
- common_python_tasks/git.py +8 -1
- common_python_tasks/project.py +3 -1
- common_python_tasks/tasks.py +85 -10
- common_python_tasks-0.11.0.dist-info/METADATA +94 -0
- {common_python_tasks-0.10.2.dist-info → common_python_tasks-0.11.0.dist-info}/RECORD +11 -11
- common_python_tasks-0.10.2.dist-info/METADATA +0 -442
- {common_python_tasks-0.10.2.dist-info → common_python_tasks-0.11.0.dist-info}/WHEEL +0 -0
- {common_python_tasks-0.10.2.dist-info → common_python_tasks-0.11.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -12,6 +12,13 @@ FROM python:${PYTHON_VERSION} AS builder
|
|
|
12
12
|
ARG PACKAGE_VERSION
|
|
13
13
|
ARG UV_VERSION
|
|
14
14
|
|
|
15
|
+
{% if CONTAINER_ENV_VARS %}
|
|
16
|
+
# Make configured variables available to package build commands.
|
|
17
|
+
{% for env_var in CONTAINER_ENV_VARS -%}
|
|
18
|
+
ENV {{ env_var }}
|
|
19
|
+
{% endfor %}
|
|
20
|
+
{%- endif %}
|
|
21
|
+
|
|
15
22
|
# Bypass VCS-based version detection: use the host-computed version directly.
|
|
16
23
|
# This avoids requiring a .git directory in the build context and prevents
|
|
17
24
|
# false dirty-version detection from a partial working tree.
|
|
@@ -60,7 +67,7 @@ ARG NONROOT_UID=1000
|
|
|
60
67
|
ARG NONROOT_GID=1000
|
|
61
68
|
|
|
62
69
|
{% if CONTAINER_ENV_VARS %}
|
|
63
|
-
#
|
|
70
|
+
# Persist the same variables for runtime build commands and running containers.
|
|
64
71
|
{% for env_var in CONTAINER_ENV_VARS -%}
|
|
65
72
|
ENV {{ env_var }}
|
|
66
73
|
{% endfor %}
|
|
@@ -606,6 +606,7 @@ def build_exec_script(
|
|
|
606
606
|
"trap 'rm -f \"$SCRIPT_PATH\"' EXIT",
|
|
607
607
|
"",
|
|
608
608
|
" ".join(quote(str(arg)) for arg in command),
|
|
609
|
+
"command_status=$?",
|
|
609
610
|
]
|
|
610
611
|
|
|
611
612
|
if teardown_command:
|
|
@@ -619,7 +620,7 @@ def build_exec_script(
|
|
|
619
620
|
for path in cleanup_paths:
|
|
620
621
|
lines.append(f"rm -f {quote(str(path))}")
|
|
621
622
|
|
|
622
|
-
lines.
|
|
623
|
+
lines.extend(['exit "$command_status"', ""])
|
|
623
624
|
|
|
624
625
|
script_path.write_text("\n".join(lines), encoding="utf-8")
|
|
625
626
|
script_path.chmod(0o700)
|
common_python_tasks/env.py
CHANGED
common_python_tasks/git.py
CHANGED
|
@@ -335,7 +335,14 @@ def has_tags_later_in_history() -> bool:
|
|
|
335
335
|
capture_output=True,
|
|
336
336
|
acceptable_returncodes={0, 1},
|
|
337
337
|
)
|
|
338
|
-
if
|
|
338
|
+
if (
|
|
339
|
+
check_result.returncode == 0
|
|
340
|
+
and utils.run_command(
|
|
341
|
+
["git", "rev-list", "--count", f"HEAD..{tag}"],
|
|
342
|
+
capture_output=True,
|
|
343
|
+
).stdout.strip()
|
|
344
|
+
!= "0"
|
|
345
|
+
):
|
|
339
346
|
return True
|
|
340
347
|
|
|
341
348
|
return False
|
common_python_tasks/project.py
CHANGED
|
@@ -154,7 +154,9 @@ def get_dependency_update_command(
|
|
|
154
154
|
if dependencies is None:
|
|
155
155
|
dependencies = []
|
|
156
156
|
|
|
157
|
-
command = ["uv", "sync"
|
|
157
|
+
command = ["uv", "sync"]
|
|
158
|
+
if not dependencies:
|
|
159
|
+
command.append("--upgrade")
|
|
158
160
|
for dependency in dependencies:
|
|
159
161
|
command.extend(["--upgrade-package", dependency])
|
|
160
162
|
return command
|
common_python_tasks/tasks.py
CHANGED
|
@@ -406,6 +406,58 @@ def lint_all() -> None:
|
|
|
406
406
|
run_command(_get_ruff_command("format", "--check", Path(".")))
|
|
407
407
|
|
|
408
408
|
|
|
409
|
+
@tasks.script(task_name="docs-build", tags=["docs"])
|
|
410
|
+
def docs_build(config_file: str | None = None, clean: bool = False) -> None:
|
|
411
|
+
"""Build the Zensical documentation site in strict mode.
|
|
412
|
+
|
|
413
|
+
Args:
|
|
414
|
+
config_file: Optional path to a Zensical configuration file.
|
|
415
|
+
clean: Remove cached files before building the site.
|
|
416
|
+
"""
|
|
417
|
+
from .utils import require_package, run_command
|
|
418
|
+
|
|
419
|
+
require_package("zensical")
|
|
420
|
+
run_command(
|
|
421
|
+
[
|
|
422
|
+
"zensical",
|
|
423
|
+
"build",
|
|
424
|
+
"--strict",
|
|
425
|
+
"--clean" if clean else None,
|
|
426
|
+
"--config-file" if config_file else None,
|
|
427
|
+
config_file,
|
|
428
|
+
]
|
|
429
|
+
)
|
|
430
|
+
|
|
431
|
+
|
|
432
|
+
@tasks.script(task_name="docs-serve", tags=["docs"])
|
|
433
|
+
def docs_serve(
|
|
434
|
+
config_file: str | None = None,
|
|
435
|
+
dev_addr: str | None = None,
|
|
436
|
+
open_browser: bool = False,
|
|
437
|
+
) -> None:
|
|
438
|
+
"""Serve the Zensical documentation site for local preview.
|
|
439
|
+
|
|
440
|
+
Args:
|
|
441
|
+
config_file: Optional path to a Zensical configuration file.
|
|
442
|
+
dev_addr: Optional development server address in `IP:PORT` form.
|
|
443
|
+
open_browser: Open the preview in the default browser.
|
|
444
|
+
"""
|
|
445
|
+
from .utils import require_package, run_command
|
|
446
|
+
|
|
447
|
+
require_package("zensical")
|
|
448
|
+
run_command(
|
|
449
|
+
[
|
|
450
|
+
"zensical",
|
|
451
|
+
"serve",
|
|
452
|
+
"--config-file" if config_file else None,
|
|
453
|
+
config_file,
|
|
454
|
+
"--dev-addr" if dev_addr else None,
|
|
455
|
+
dev_addr,
|
|
456
|
+
"--open" if open_browser else None,
|
|
457
|
+
]
|
|
458
|
+
)
|
|
459
|
+
|
|
460
|
+
|
|
409
461
|
@tasks.script(tags=["containers", "build"])
|
|
410
462
|
def build_image(
|
|
411
463
|
*docker_build_args: str,
|
|
@@ -430,9 +482,9 @@ def build_image(
|
|
|
430
482
|
dockerfile_hook_path: Optional executable script path that can mutate
|
|
431
483
|
the generated Dockerfile before build. Overrides
|
|
432
484
|
CONTAINER_DOCKERFILE_HOOK_PATH if provided.
|
|
433
|
-
container_env: Builder
|
|
485
|
+
container_env: Builder and runtime environment declarations as repeated
|
|
434
486
|
KEY=VALUE values.
|
|
435
|
-
container_envfile: Optional repeated list of files containing builder
|
|
487
|
+
container_envfile: Optional repeated list of files containing builder and runtime
|
|
436
488
|
environment declarations.
|
|
437
489
|
|
|
438
490
|
Precedence for container env declarations is: .containerenv, container_envfile,
|
|
@@ -524,7 +576,7 @@ def build_image(
|
|
|
524
576
|
)
|
|
525
577
|
if container_env_vars:
|
|
526
578
|
LOGGER.debug(
|
|
527
|
-
"Injecting builder
|
|
579
|
+
"Injecting builder and runtime env vars: %s",
|
|
528
580
|
", ".join(container_env_vars),
|
|
529
581
|
)
|
|
530
582
|
top_level_build_args = inject_auto_build_args_from_env(
|
|
@@ -1731,26 +1783,49 @@ def fastapi_run_db_migrations() -> None:
|
|
|
1731
1783
|
"""Run database migrations."""
|
|
1732
1784
|
from .docker_compose import (
|
|
1733
1785
|
cleanup_temp_files,
|
|
1786
|
+
ensure_secrets_generated,
|
|
1734
1787
|
load_and_prepare_compose,
|
|
1735
1788
|
run_docker_compose_command,
|
|
1736
1789
|
)
|
|
1737
1790
|
|
|
1738
|
-
|
|
1739
|
-
|
|
1791
|
+
container_build = build_image(single_arch=True)
|
|
1792
|
+
ensure_secrets_generated()
|
|
1793
|
+
compose_files, temp_compose_files, temp_config_files, compose_env = (
|
|
1794
|
+
load_and_prepare_compose(image_tag=container_build.commit_tag)
|
|
1795
|
+
)
|
|
1740
1796
|
try:
|
|
1741
|
-
|
|
1797
|
+
run_docker_compose_command(
|
|
1798
|
+
"up",
|
|
1799
|
+
"-d",
|
|
1800
|
+
"--no-build",
|
|
1801
|
+
"db",
|
|
1802
|
+
compose_files=compose_files,
|
|
1803
|
+
compose_env=compose_env,
|
|
1804
|
+
tasks=tasks,
|
|
1805
|
+
)
|
|
1806
|
+
run_docker_compose_command(
|
|
1807
|
+
"run",
|
|
1808
|
+
"--rm",
|
|
1809
|
+
"migrator",
|
|
1810
|
+
compose_files=compose_files,
|
|
1811
|
+
compose_env=compose_env,
|
|
1812
|
+
tasks=tasks,
|
|
1813
|
+
)
|
|
1814
|
+
finally:
|
|
1742
1815
|
try:
|
|
1743
1816
|
run_docker_compose_command(
|
|
1744
|
-
"
|
|
1817
|
+
"rm",
|
|
1818
|
+
"-f",
|
|
1819
|
+
"-s",
|
|
1820
|
+
"-v",
|
|
1821
|
+
"db",
|
|
1745
1822
|
"migrator",
|
|
1746
1823
|
compose_files=compose_files,
|
|
1747
1824
|
compose_env=compose_env,
|
|
1748
1825
|
tasks=tasks,
|
|
1749
1826
|
)
|
|
1750
1827
|
finally:
|
|
1751
|
-
cleanup_temp_files(temp_compose_files)
|
|
1752
|
-
finally:
|
|
1753
|
-
fastapi_stack_down()
|
|
1828
|
+
cleanup_temp_files(temp_compose_files, temp_config_files)
|
|
1754
1829
|
|
|
1755
1830
|
|
|
1756
1831
|
@tasks.script(task_name="db-shell", tags=["web", "containers", "database", "fastapi"])
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: common-python-tasks
|
|
3
|
+
Version: 0.11.0
|
|
4
|
+
Summary: Opinionated Poe the Poet tasks for Python package development.
|
|
5
|
+
Project-URL: Homepage, http://github.com/ci-sourcerer/common-python-tasks
|
|
6
|
+
Project-URL: Source, http://github.com/ci-sourcerer/common-python-tasks.git
|
|
7
|
+
Project-URL: Issues, http://github.com/ci-sourcerer/common-python-tasks/issues
|
|
8
|
+
Author-email: Joseph Asbury <ci_sourcerer@yahoo.com>
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
18
|
+
Classifier: Topic :: Software Development :: Build Tools
|
|
19
|
+
Requires-Python: <4.0,>=3.11
|
|
20
|
+
Requires-Dist: docker<8.0.0,>=7.1.0
|
|
21
|
+
Requires-Dist: dunamai<2.0.0,>=1.25.0
|
|
22
|
+
Requires-Dist: git-cliff<3.0.0,>=2.12.0
|
|
23
|
+
Requires-Dist: jinja2<4.0.0,>=3.1.6
|
|
24
|
+
Requires-Dist: packaging<27.0,>=26.2
|
|
25
|
+
Requires-Dist: poethepoet-tasks<0.4.0,>=0.3.0
|
|
26
|
+
Requires-Dist: pytest-cov<8.0.0,>=7.0.0
|
|
27
|
+
Requires-Dist: pytest<10.0.0,>=9.0.3
|
|
28
|
+
Requires-Dist: requests<3.0.0,>=2.34.2
|
|
29
|
+
Requires-Dist: ruff<0.17.0,>=0.16.1
|
|
30
|
+
Requires-Dist: tomlkit<0.14.0,>=0.13.3
|
|
31
|
+
Requires-Dist: zensical<0.1.0,>=0.0.59
|
|
32
|
+
Description-Content-Type: text/markdown
|
|
33
|
+
|
|
34
|
+
# Common Python Tasks
|
|
35
|
+
|
|
36
|
+
`common-python-tasks` provides reusable, opinionated [Poe the Poet](https://poethepoet.natn.io/guides/packaged_tasks.html) tasks for Python development, packaging, releases, containers, and documentation.
|
|
37
|
+
|
|
38
|
+
Read the [complete documentation](https://ci-sourcerer.github.io/common-python-tasks/) for the task reference, configuration options, and deployment guidance.
|
|
39
|
+
|
|
40
|
+
## Quick start
|
|
41
|
+
|
|
42
|
+
Add the package as a development dependency.
|
|
43
|
+
|
|
44
|
+
```shell
|
|
45
|
+
uv add --dev common-python-tasks==0.11.0
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Expose the default task set in `pyproject.toml`.
|
|
49
|
+
|
|
50
|
+
```toml
|
|
51
|
+
[tool.poe]
|
|
52
|
+
include_script = "common_python_tasks:tasks()"
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Run the everyday development tasks.
|
|
56
|
+
|
|
57
|
+
```shell
|
|
58
|
+
poe format
|
|
59
|
+
poe lint
|
|
60
|
+
poe test
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Optional workflows
|
|
64
|
+
|
|
65
|
+
Select additional task groups with `include_tags`.
|
|
66
|
+
|
|
67
|
+
```toml
|
|
68
|
+
[tool.poe]
|
|
69
|
+
include_script = "common_python_tasks:tasks(include_tags=['common', 'docs', 'containers'])"
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
| Tag | Purpose |
|
|
73
|
+
| - | - |
|
|
74
|
+
| `common` | Formatting, linting, testing, packaging, and releases |
|
|
75
|
+
| `docs` | Build and serve Zensical documentation |
|
|
76
|
+
| `containers` | Build, run, inspect, and publish container images |
|
|
77
|
+
| `fastapi` | Run the FastAPI and PostgreSQL development stack |
|
|
78
|
+
|
|
79
|
+
Documentation projects can build locally or start a development server.
|
|
80
|
+
|
|
81
|
+
```shell
|
|
82
|
+
poe docs-build
|
|
83
|
+
poe docs-serve
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
The [documentation workflow guide](https://ci-sourcerer.github.io/common-python-tasks/documentation-workflows/) covers GitHub Actions artifacts, optional Cloudflare Pages previews, and GitHub Pages deployment.
|
|
87
|
+
|
|
88
|
+
## Learn more
|
|
89
|
+
|
|
90
|
+
- [Getting started](https://ci-sourcerer.github.io/common-python-tasks/getting-started/)
|
|
91
|
+
- [Task reference](https://ci-sourcerer.github.io/common-python-tasks/tasks/)
|
|
92
|
+
- [Configuration reference](https://ci-sourcerer.github.io/common-python-tasks/configuration/)
|
|
93
|
+
|
|
94
|
+
The project is in alpha, so minor releases may contain breaking changes. It is distributed under the [MIT license](LICENSE).
|
|
@@ -1,27 +1,27 @@
|
|
|
1
1
|
common_python_tasks/__init__.py,sha256=tqRLgOwmMQHDb1A84XbML9sWfzMymkSPhJjoF6aCHgA,916
|
|
2
2
|
common_python_tasks/__main__.py,sha256=GpgSd_toMbEaWA_cZvgsZE7jo4XpzuI-awBVm2uhVyw,3512
|
|
3
3
|
common_python_tasks/docker.py,sha256=_YW-hyHWlUK-kMCvI6QTgxSfmXQQKhYLOKRBPfUmtHA,24176
|
|
4
|
-
common_python_tasks/docker_compose.py,sha256=
|
|
5
|
-
common_python_tasks/env.py,sha256=
|
|
6
|
-
common_python_tasks/git.py,sha256=
|
|
4
|
+
common_python_tasks/docker_compose.py,sha256=NGgMei3oCYS0RbNaQXE-2veXFylO3XtZ7lU-PTtocik,21338
|
|
5
|
+
common_python_tasks/env.py,sha256=1YLSxsUP9lPn51_zraM3nAiN1J7aKdUHzjzDzxXLo34,19696
|
|
6
|
+
common_python_tasks/git.py,sha256=0X472w_vHdtbrHHxCmJ85NoQjjogEEDs_0SRXfxbWi0,11719
|
|
7
7
|
common_python_tasks/github.py,sha256=_LVanl-z4PsdLM94L8y7tkX-AZO2n3Qy39FRY7reDhA,21589
|
|
8
|
-
common_python_tasks/project.py,sha256=
|
|
9
|
-
common_python_tasks/tasks.py,sha256=
|
|
8
|
+
common_python_tasks/project.py,sha256=PQ_GQicTrSQgVDB9cJ9E6pU0UhLPom2xou1sGFscr3E,17377
|
|
9
|
+
common_python_tasks/tasks.py,sha256=Ajqw7mnfMwfiOdTuVGvGJQAp_DQxEnqDc9e8y3VFcT8,61636
|
|
10
10
|
common_python_tasks/utils.py,sha256=hR7w0Cb7uQ7ILyIegTQ4znWHVoWANlCgxrOnO-Rh5oE,20798
|
|
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=dOiAmZngzX6eyVXeM6BhzgQmes2zwUEdKwOgm8mxjMs,985
|
|
13
13
|
common_python_tasks/data/fastapi/compose-base.yml.j2,sha256=vDLPAdRJ66lsWZdsKbYqEvY_liXaHZ0ly4ljzqmJsyY,910
|
|
14
14
|
common_python_tasks/data/fastapi/compose-db-debug.yml.j2,sha256=iREdSy4F8tJ5m9rlB6CROBkj9OtDFVuGphqIuDvHhww,1193
|
|
15
|
-
common_python_tasks/data/fastapi/compose-db.yml.j2,sha256=
|
|
15
|
+
common_python_tasks/data/fastapi/compose-db.yml.j2,sha256=G1vdAqy8Cxa-8DDz6eHNuD2xigpTxINACxrs2eY4KkU,1771
|
|
16
16
|
common_python_tasks/data/fastapi/compose-debug.yml.j2,sha256=sIH9IFvmRAszN6wSejpGVQygXh1g2lVmlzOgPhTx5CY,661
|
|
17
17
|
common_python_tasks/data/generic/.coveragerc,sha256=8zXwDq18wIKQV4NtW2NJYpo3nxCO4LsAChyluYTUoJc,85
|
|
18
18
|
common_python_tasks/data/generic/.dockerignore,sha256=8kHwNa6Ct-6y3EvRjNuhOKfquuGEywq3P2BHIbG4uXo,53
|
|
19
19
|
common_python_tasks/data/generic/Dockerfile.deps.j2,sha256=fBmcytyUd4LsC26y0IgZ09QPxrFp0gx0d3OlKNqZ-KM,663
|
|
20
|
-
common_python_tasks/data/generic/Dockerfile.j2,sha256=
|
|
20
|
+
common_python_tasks/data/generic/Dockerfile.j2,sha256=hgLrIRU5xvS2xqw9Xm4kfkcBGHH-mghFPlWv3KSNaz4,6223
|
|
21
21
|
common_python_tasks/data/generic/cliff.toml,sha256=po1MnEGEEgrpyBz3XLWr0h7emXb6ASX63lrU2r6o240,77
|
|
22
22
|
common_python_tasks/data/generic/pytest.ini,sha256=RHak5QrLzKHvUBjFmaaiOYFrd_8YBRQubXEOT0NJfco,134
|
|
23
23
|
common_python_tasks/data/generic/ruff.toml,sha256=njvd-5inSGmgY865SWCT4SR9IrKlzS7JQFZmAG2UT_E,53
|
|
24
|
-
common_python_tasks-0.
|
|
25
|
-
common_python_tasks-0.
|
|
26
|
-
common_python_tasks-0.
|
|
27
|
-
common_python_tasks-0.
|
|
24
|
+
common_python_tasks-0.11.0.dist-info/METADATA,sha256=00ugE5R39fK6NpEH2LDIaUm87vNhxC2jVTGoa_FI4aI,3307
|
|
25
|
+
common_python_tasks-0.11.0.dist-info/WHEEL,sha256=zOwg4jB6zX2kU910N-cMawjivD6tO8NEWvE12je1bVk,87
|
|
26
|
+
common_python_tasks-0.11.0.dist-info/licenses/LICENSE,sha256=RsSweM-DyzxFPx38fQOJqHrKyeT9Fiz8rO7yox-fOsw,1070
|
|
27
|
+
common_python_tasks-0.11.0.dist-info/RECORD,,
|
|
@@ -1,442 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.5
|
|
2
|
-
Name: common-python-tasks
|
|
3
|
-
Version: 0.10.2
|
|
4
|
-
Summary: Opinionated Poe the Poet tasks for Python package development.
|
|
5
|
-
Project-URL: Homepage, http://github.com/ci-sourcerer/common-python-tasks
|
|
6
|
-
Project-URL: Source, http://github.com/ci-sourcerer/common-python-tasks.git
|
|
7
|
-
Project-URL: Issues, http://github.com/ci-sourcerer/common-python-tasks/issues
|
|
8
|
-
Author-email: Joseph Asbury <ci_sourcerer@yahoo.com>
|
|
9
|
-
License-Expression: MIT
|
|
10
|
-
License-File: LICENSE
|
|
11
|
-
Classifier: Development Status :: 3 - Alpha
|
|
12
|
-
Classifier: Intended Audience :: Developers
|
|
13
|
-
Classifier: Programming Language :: Python :: 3
|
|
14
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
-
Classifier: Programming Language :: Python :: 3.13
|
|
17
|
-
Classifier: Programming Language :: Python :: 3.14
|
|
18
|
-
Classifier: Topic :: Software Development :: Build Tools
|
|
19
|
-
Requires-Python: <4.0,>=3.11
|
|
20
|
-
Requires-Dist: docker<8.0.0,>=7.1.0
|
|
21
|
-
Requires-Dist: dunamai<2.0.0,>=1.25.0
|
|
22
|
-
Requires-Dist: git-cliff<3.0.0,>=2.12.0
|
|
23
|
-
Requires-Dist: jinja2<4.0.0,>=3.1.6
|
|
24
|
-
Requires-Dist: packaging<27.0,>=26.2
|
|
25
|
-
Requires-Dist: poethepoet-tasks<0.4.0,>=0.3.0
|
|
26
|
-
Requires-Dist: pytest-cov<8.0.0,>=7.0.0
|
|
27
|
-
Requires-Dist: pytest<10.0.0,>=9.0.3
|
|
28
|
-
Requires-Dist: requests<3.0.0,>=2.34.2
|
|
29
|
-
Requires-Dist: ruff<0.17.0,>=0.16.1
|
|
30
|
-
Requires-Dist: tomlkit<0.14.0,>=0.13.3
|
|
31
|
-
Description-Content-Type: text/markdown
|
|
32
|
-
|
|
33
|
-
# Common Python Tasks
|
|
34
|
-
|
|
35
|
-
`common-python-tasks` provides reusable, opinionated [Poe the Poet](https://poethepoet.natn.io/guides/packaged_tasks.html) tasks for common Python development workflows.
|
|
36
|
-
|
|
37
|
-
It supplies sensible defaults for formatting, linting, testing, packaging, releases, and container workflows while allowing projects to override configuration when needed.
|
|
38
|
-
|
|
39
|
-
## Quick start
|
|
40
|
-
|
|
41
|
-
### Manual setup
|
|
42
|
-
|
|
43
|
-
Add `common-python-tasks` as a development dependency from your project root.
|
|
44
|
-
|
|
45
|
-
```shell
|
|
46
|
-
uv add --dev common-python-tasks==0.10.2
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
Configure Poe the Poet to expose the default `common` task set.
|
|
50
|
-
|
|
51
|
-
```toml
|
|
52
|
-
[tool.poe]
|
|
53
|
-
include_script = "common_python_tasks:tasks()"
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
Run the common development tasks.
|
|
57
|
-
|
|
58
|
-
```shell
|
|
59
|
-
poe format
|
|
60
|
-
poe lint
|
|
61
|
-
poe test
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
### Automated setup
|
|
65
|
-
|
|
66
|
-
The helper script performs the same development-dependency installation and Poe configuration. Download the script for the exact release you want, review it, then run it from your project root.
|
|
67
|
-
|
|
68
|
-
```shell
|
|
69
|
-
curl --fail --silent --show-error --location \
|
|
70
|
-
--output /tmp/add_common_python_tasks.py \
|
|
71
|
-
https://raw.githubusercontent.com/ci-sourcerer/common-python-tasks/v0.10.2/scripts/add_common_python_tasks.py
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
Review the downloaded script before executing it.
|
|
75
|
-
|
|
76
|
-
```shell
|
|
77
|
-
less /tmp/add_common_python_tasks.py
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
Run the reviewed script with the same pinned package version.
|
|
81
|
-
|
|
82
|
-
```shell
|
|
83
|
-
COMMON_PYTHON_TASKS_VERSION=0.10.2 python3 /tmp/add_common_python_tasks.py
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
To install another release, replace both occurrences of `0.10.2` with that release's version.
|
|
87
|
-
|
|
88
|
-
## Available tasks
|
|
89
|
-
|
|
90
|
-
The generated tables below list public tasks only. Tags identify which tasks are selected by `include_tags` and `exclude_tags`.
|
|
91
|
-
|
|
92
|
-
<!-- tasks-table -->
|
|
93
|
-
|
|
94
|
-
### Daily development
|
|
95
|
-
|
|
96
|
-
| Task | Description | Tags |
|
|
97
|
-
| --- | --- | --- |
|
|
98
|
-
| `test` | Run the test suite with coverage (if pytest-cov is installed). | common, test |
|
|
99
|
-
| `clean` | Clean up temporary files and directories. | clean, common |
|
|
100
|
-
| `format` | Fix import issues and format Python code with Ruff. | common, format |
|
|
101
|
-
| `lint` | Check Python lint and formatting with Ruff. | common, lint |
|
|
102
|
-
|
|
103
|
-
### Packaging and releases
|
|
104
|
-
|
|
105
|
-
| Task | Description | Tags |
|
|
106
|
-
| --- | --- | --- |
|
|
107
|
-
| `publish-package` | Publish the package to the PyPI server. | common, packaging |
|
|
108
|
-
| `publish-github-release` | Publish or update a GitHub Release for the current repository. | common, packaging, release |
|
|
109
|
-
| `update-dependencies` | Update project dependencies with uv. | common, packaging |
|
|
110
|
-
| `build-package` | Build the package (wheel and sdist). | build, common, packaging |
|
|
111
|
-
| `bump-version` | Bump the project version. | common, packaging |
|
|
112
|
-
| `changelog` | Print the changelog for the current version based on git history and git-cliff. | common, packaging, release |
|
|
113
|
-
| `release` | Run a full release flow for package and containers. | common, containers, packaging, release |
|
|
114
|
-
|
|
115
|
-
### Container images
|
|
116
|
-
|
|
117
|
-
| Task | Description | Tags |
|
|
118
|
-
| --- | --- | --- |
|
|
119
|
-
| `build-image` | Build the container image for this project using the Dockerfile template. | build, containers |
|
|
120
|
-
| `build-deps-image` | Build only the container dependency collector image for this project. | build, containers |
|
|
121
|
-
| `run-container` | Run the Docker image as a container for this project. By default, this will run the most-recently-built tag for the project's image. | containers |
|
|
122
|
-
| `push-image` | Push the Docker image for this project to the container registry. | containers, packaging, release |
|
|
123
|
-
| `build` | Build the project and its containers. | common, containers, packaging |
|
|
124
|
-
| `container-shell` | Run the debug image with an interactive shell. | containers, debug |
|
|
125
|
-
|
|
126
|
-
### Development stacks
|
|
127
|
-
|
|
128
|
-
| Task | Description | Tags |
|
|
129
|
-
| --- | --- | --- |
|
|
130
|
-
| `stack-up` | Bring up the development stack for the application. | containers, fastapi, web |
|
|
131
|
-
| `stack-down` | Bring down the development stack for the application. | containers, fastapi, web |
|
|
132
|
-
| `reset-db` | Reset the database by deleting the database volume. | containers, database, fastapi, web |
|
|
133
|
-
| `run-db-migrations` | Run database migrations. | containers, database, fastapi, web |
|
|
134
|
-
| `db-shell` | Open a psql shell to the database container. | containers, database, fastapi, web |
|
|
135
|
-
|
|
136
|
-
<!-- end-tasks-table -->
|
|
137
|
-
|
|
138
|
-
## Configuration and requirements
|
|
139
|
-
|
|
140
|
-
### Requirements
|
|
141
|
-
|
|
142
|
-
Every project needs a `pyproject.toml` file at its root and Poe the Poet available in its development environment.
|
|
143
|
-
|
|
144
|
-
Tasks that install, build, publish, or update dependencies require uv. Package and release tasks need a resolvable project version from `project.version` or Git tags. Dynamic versioning is supported but is not a baseline requirement.
|
|
145
|
-
|
|
146
|
-
### Task selection
|
|
147
|
-
|
|
148
|
-
Calling `tasks()` without arguments exposes the default `common` task set.
|
|
149
|
-
|
|
150
|
-
```toml
|
|
151
|
-
[tool.poe]
|
|
152
|
-
include_script = "common_python_tasks:tasks()"
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
Select optional task groups with tags when your project needs them.
|
|
156
|
-
|
|
157
|
-
```toml
|
|
158
|
-
[tool.poe]
|
|
159
|
-
include_script = "common_python_tasks:tasks(include_tags=['common', 'containers'])"
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
The `containers` tag also includes container-based development-stack tasks. Use the tags in the task tables to tailor a smaller task set.
|
|
163
|
-
|
|
164
|
-
### Package management
|
|
165
|
-
|
|
166
|
-
Packaging-related tasks, including `build-package`, `publish-package`, dependency updates, release version resolution, and container build metadata, use uv exclusively. The `uv` executable must be available on `PATH`.
|
|
167
|
-
|
|
168
|
-
### Publish target selection
|
|
169
|
-
|
|
170
|
-
The `publish-package` task resolves publish targets with this precedence.
|
|
171
|
-
|
|
172
|
-
1. Explicit task arguments (`repository` or `repository_url`)
|
|
173
|
-
2. Environment-variable fallback
|
|
174
|
-
3. uv project configuration fallback from `[[tool.uv.index]]`
|
|
175
|
-
4. The `uv publish` default
|
|
176
|
-
|
|
177
|
-
uv prefers named publish indexes.
|
|
178
|
-
|
|
179
|
-
- `COMMON_PYTHON_TASKS_PUBLISH_REPOSITORY`
|
|
180
|
-
- `UV_PUBLISH_INDEX`
|
|
181
|
-
- `COMMON_PYTHON_TASKS_PUBLISH_URL`
|
|
182
|
-
- `UV_PUBLISH_URL`
|
|
183
|
-
|
|
184
|
-
When using uv project configuration fallback, `[[tool.uv.index]]` must include both `name` and `publish-url` for publish selection. If multiple publishable indexes exist, set exactly one `default = true` or pass an explicit repository.
|
|
185
|
-
|
|
186
|
-
### Configuration precedence
|
|
187
|
-
|
|
188
|
-
For pytest and coverage, configuration resolves in the following order.
|
|
189
|
-
|
|
190
|
-
1. Matching `pyproject.toml` sections such as `[tool.pytest.ini_options]` and `[tool.coverage]`
|
|
191
|
-
2. Environment variables that specify a configuration path
|
|
192
|
-
3. Local configuration files in the project root
|
|
193
|
-
4. Bundled defaults from [`src/common_python_tasks/data`](src/common_python_tasks/data)
|
|
194
|
-
|
|
195
|
-
Ruff uses `RUFF_CONFIG` when set. Otherwise it discovers `.ruff.toml`, `ruff.toml`, or a `[tool.ruff]` section in `pyproject.toml`. When no project configuration is available, the tasks use the bundled Ruff defaults. Ruff configuration follows Ruff's native file precedence, so `.ruff.toml` takes precedence over `ruff.toml`, which takes precedence over `pyproject.toml` in the same directory.
|
|
196
|
-
|
|
197
|
-
The `format` task first applies safe fixes for unused imports and import sorting, then runs the Ruff formatter. The `lint` task checks both Ruff lint rules and formatting without changing files.
|
|
198
|
-
|
|
199
|
-
### Configuration examples
|
|
200
|
-
|
|
201
|
-
After installing the package, a minimal project configuration looks like this.
|
|
202
|
-
|
|
203
|
-
```toml
|
|
204
|
-
[project]
|
|
205
|
-
name = "simple-cli-tool"
|
|
206
|
-
version = "0.10.2"
|
|
207
|
-
|
|
208
|
-
[tool.poe]
|
|
209
|
-
include_script = "common_python_tasks:tasks()"
|
|
210
|
-
```
|
|
211
|
-
|
|
212
|
-
A container-based project can select the container task group and set its image details.
|
|
213
|
-
|
|
214
|
-
```toml
|
|
215
|
-
[tool.poe]
|
|
216
|
-
include_script = "common_python_tasks:tasks(include_tags=['common', 'containers'])"
|
|
217
|
-
|
|
218
|
-
[tool.poe.env]
|
|
219
|
-
CONTAINER_REGISTRY_USERNAME = "myusername"
|
|
220
|
-
PACKAGE_NAME = "containerized-app"
|
|
221
|
-
```
|
|
222
|
-
|
|
223
|
-
The `test` task automatically uses pytest configuration in `pyproject.toml`.
|
|
224
|
-
|
|
225
|
-
```toml
|
|
226
|
-
[tool.pytest.ini_options]
|
|
227
|
-
testpaths = ["tests", "integration"]
|
|
228
|
-
addopts = "-ra"
|
|
229
|
-
```
|
|
230
|
-
|
|
231
|
-
### Environment variables
|
|
232
|
-
|
|
233
|
-
#### Task configuration files
|
|
234
|
-
|
|
235
|
-
- `PYTEST_CONFIG`: Path to the pytest configuration file
|
|
236
|
-
- `COVERAGE_RCFILE`: Path to the coverage configuration file
|
|
237
|
-
- `RUFF_CONFIG`: Path to a Ruff TOML configuration file
|
|
238
|
-
|
|
239
|
-
#### Project and package settings
|
|
240
|
-
|
|
241
|
-
- `PACKAGE_NAME`: Overrides the package name inferred from `pyproject.toml`
|
|
242
|
-
- `COMMON_PYTHON_TASKS_PUBLISH_REPOSITORY`: Preferred publish repository/index name for `publish-package`
|
|
243
|
-
- `COMMON_PYTHON_TASKS_PUBLISH_URL`: Preferred uv publish upload URL for `publish-package` when no repository/index is selected
|
|
244
|
-
- `UV_PUBLISH_INDEX`: uv publish-index fallback for `publish-package`
|
|
245
|
-
- `UV_PUBLISH_URL`: uv publish upload-url fallback for `publish-package`
|
|
246
|
-
|
|
247
|
-
#### Container image settings
|
|
248
|
-
|
|
249
|
-
- `CONTAINER_REGISTRY_USERNAME`: Container-registry username for image tagging; the default is the current local user
|
|
250
|
-
- `CONTAINER_REGISTRY_URL`: Registry URL with a default of `docker.io/{username}`
|
|
251
|
-
- `CONTAINER_PYTHON_VARIANT`: Python base-image variant such as `slim`, `alpine`, etc. See <https://hub.docker.com/_/python> for available options. Defaults to `slim`; set to empty string for no variant (e.g., `FROM python:3.11`). The value is passed as the `PYTHON_VARIANT` Docker build argument and recorded in the `org.opencontainers.image.python.variant` image label.
|
|
252
|
-
- `CONTAINER_DOCKER_BUILD_ARGS`: Additional arguments passed directly to `docker build`, parsed using shell quoting rules. Free arguments provided to the task after `--` take precedence.
|
|
253
|
-
- `CONTAINER_DOCKERFILE_HOOK_PATH`: Optional host path to an executable hook script that receives the generated Dockerfile path and can modify the file before `docker build` runs.
|
|
254
|
-
- `CONTAINER_APT_PACKAGES`: Space-delimited system packages installed in the generated image
|
|
255
|
-
- `CONTAINER_CUSTOM_ENTRYPOINT`: Custom container entrypoint script. The value must match a key in `[project].scripts`.
|
|
256
|
-
- `CONTAINER_DEPS_IMAGE`: Existing dependency image used when neither `CONTAINER_DEPS_CONTENT` nor `CONTAINER_DEPS_FILE` is configured
|
|
257
|
-
- `CONTAINER_EXTENSION_FILES`: Colon-delimited local extension Dockerfile paths. Escape literal colons as `\:` or quote the complete path.
|
|
258
|
-
- `CONTAINER_EXTENSIONS`: Colon-delimited extension-bundle names or parameterized values. Escape literal colons as `\:` or quote the complete value.
|
|
259
|
-
- `CONTAINER_ENV`: Colon-delimited `KEY=VALUE` declarations injected into the rendered Dockerfile's builder stage. Escape literal colons as `\:` or quote the complete value.
|
|
260
|
-
- `.containerenv`: A project-root file that can supply the same declarations. It is loaded before the `container_envfile` task argument, `CONTAINER_ENV`, and the `container_env` task argument.
|
|
261
|
-
- `CONTAINER_PRUNE_KEEP`: Image-pruning policy after builds. `-1` keeps all images, `0` keeps only the latest, and `N` keeps the latest plus `N` prior images.
|
|
262
|
-
- `CONTAINER_DEPS_CONTENT`: Inline Dockerfile instructions for a dependency image that installs artifacts into `/tmp/deps`
|
|
263
|
-
- `CONTAINER_DEPS_FILE`: One or more dependency-image Dockerfiles. It accepts colon-delimited paths with literal colons escaped as `\:` and is used only when `CONTAINER_DEPS_CONTENT` is unset.
|
|
264
|
-
- `CONTAINER_DEPS_MAPPINGS`: Space-delimited `name:/target/path` entries for copying items from `/tmp/deps`. It is used only when no dependency move script is set.
|
|
265
|
-
- `CONTAINER_DEPS_MOVE_SCRIPT`: Raw executable script to run after `/tmp/deps` is copied into the image
|
|
266
|
-
- `CONTAINER_DEPS_MOVE_SCRIPT_PATH`: Host path to a dependency move script. This takes precedence over `CONTAINER_DEPS_MOVE_SCRIPT`.
|
|
267
|
-
- `UV_INDEX_{name}_USERNAME` and `UV_INDEX_{name}_PASSWORD`: Private Python index credentials consumed by uv during the Docker build. When any of these are set, the task automatically passes them as BuildKit secrets (`--secret id=uv_index_{name}_username,env=...`) and renders matching `--mount=type=secret` directives in the builder stage so uv can authenticate without baking credentials into the image. Multiple indices are supported; replace `{name}` with the uppercase index name (hyphens as underscores). These can be set in `tool.poe.env` for CI/CD or in the local environment for development.
|
|
268
|
-
|
|
269
|
-
#### Release settings
|
|
270
|
-
|
|
271
|
-
- `GITHUB_RELEASE_ASSETS`: Colon-delimited file paths or glob patterns to attach to a GitHub Release. The default is `dist/*`; escape literal colons as `\:` or quote the complete path.
|
|
272
|
-
- `SKIP_GITHUB_RELEASE`: Truthy value that skips GitHub Release publication
|
|
273
|
-
- `GITHUB_TOKEN` or `GH_TOKEN`: GitHub authentication token for releases and assets
|
|
274
|
-
- `GITHUB_REPOSITORY`: Optional repository-slug override for GitHub Release publication
|
|
275
|
-
- `GITHUB_API_URL` and `GITHUB_SERVER_URL`: GitHub Enterprise API-host settings
|
|
276
|
-
- `GITHUB_RELEASE_TAG`: Optional release tag name
|
|
277
|
-
- `GITHUB_RELEASE_NAME`: Optional release title
|
|
278
|
-
- `GITHUB_RELEASE_BODY`: Optional release body
|
|
279
|
-
- `RELEASE_UPDATE_CHANGELOG`: Truthy value that prepends `git-cliff --unreleased --tag "$RELEASE_TAG"` output to `CHANGELOG.md` before the release tag is created. It is enabled by default.
|
|
280
|
-
- `RELEASE_PRE_SCRIPT`: Optional shell command to run before release steps
|
|
281
|
-
- `RELEASE_POST_SCRIPT`: Optional shell command to run after release completion
|
|
282
|
-
- Release hooks receive `RELEASE_SCRIPT_PHASE`, `RELEASE_TAG`, `RELEASE_VERSION`, `RELEASE_STAGE`, `RELEASE_COMPONENT`, and `RELEASE_DRY_RUN`.
|
|
283
|
-
|
|
284
|
-
#### Docker Compose settings
|
|
285
|
-
|
|
286
|
-
- `COMPOSE_TYPE`: Application-stack type, such as `fastapi`
|
|
287
|
-
- `COMPOSE_ADDONS`: Colon-delimited services to include, such as `db`
|
|
288
|
-
- `COMPOSE_FILE`: Override for all compose files with colon-delimited paths
|
|
289
|
-
- `COMPOSE_OVERLAY_FILES`: Additional compose files to merge with colon-delimited paths
|
|
290
|
-
- `API_PORT`: API server port with a default of `8080`
|
|
291
|
-
- `SECRET_KEY`: Application secret key generated automatically when unset
|
|
292
|
-
- `ENVIRONMENT`: Environment name with a default of `production`
|
|
293
|
-
- `DEBUG_PORT`: Python debugger port in debug mode with a default of `5678`
|
|
294
|
-
- `DB_PORT`: PostgreSQL port with a default of `5432`
|
|
295
|
-
- `DB_USER`: Database user with a default of the package name
|
|
296
|
-
- `DB_BASE`: Database name with a default of the package name
|
|
297
|
-
- `DB_PASS`: Database password generated automatically when unset
|
|
298
|
-
- `POSTGRES_VERSION`: PostgreSQL version with a default of `17`
|
|
299
|
-
- `ADMINER_PORT`: Adminer web UI port with a default of `8081`
|
|
300
|
-
|
|
301
|
-
#### Debugging
|
|
302
|
-
|
|
303
|
-
- `COMMON_PYTHON_TASKS_LOG_LEVEL`: Set to `DEBUG` to show detailed configuration resolution
|
|
304
|
-
|
|
305
|
-
## Containers and development stacks
|
|
306
|
-
|
|
307
|
-
Docker Compose development-stack tasks are available when the `containers` tag is selected. The current stack supports FastAPI applications and an optional PostgreSQL database.
|
|
308
|
-
|
|
309
|
-
### Native Docker build arguments
|
|
310
|
-
|
|
311
|
-
Arguments after the task's `--` separator are passed directly to `docker build`. Docker performs option validation, so any supported build option and its value can be used without a package-specific allowlist.
|
|
312
|
-
|
|
313
|
-
```shell
|
|
314
|
-
poe build-image --single-arch -- \
|
|
315
|
-
--secret id=pip_conf,env=PIP_CONF \
|
|
316
|
-
--ssh default \
|
|
317
|
-
--add-host example:127.0.0.1
|
|
318
|
-
```
|
|
319
|
-
|
|
320
|
-
Set `CONTAINER_DOCKER_BUILD_ARGS` to provide the same arguments through the environment. The value uses shell quoting rules, and task arguments provided after `--` take precedence.
|
|
321
|
-
|
|
322
|
-
Settings that affect generated Dockerfile content or dependency-image orchestration can be persisted directly in the project configuration.
|
|
323
|
-
|
|
324
|
-
```toml
|
|
325
|
-
[tool.poe.env]
|
|
326
|
-
CONTAINER_APT_PACKAGES = "curl jq"
|
|
327
|
-
CONTAINER_CUSTOM_ENTRYPOINT = "serve"
|
|
328
|
-
CONTAINER_DEPS_IMAGE = "example/dependencies:latest"
|
|
329
|
-
```
|
|
330
|
-
|
|
331
|
-
### Stack configuration
|
|
332
|
-
|
|
333
|
-
Set `COMPOSE_TYPE` to select the application stack. `fastapi` is currently supported and includes optional database support and Alembic migrations.
|
|
334
|
-
|
|
335
|
-
```toml
|
|
336
|
-
[tool.poe.env]
|
|
337
|
-
COMPOSE_TYPE = "fastapi"
|
|
338
|
-
```
|
|
339
|
-
|
|
340
|
-
Set `COMPOSE_ADDONS` to select extra services. Addon names are colon-delimited, and `db` is the currently available addon.
|
|
341
|
-
|
|
342
|
-
```toml
|
|
343
|
-
[tool.poe.env]
|
|
344
|
-
COMPOSE_ADDONS = "db"
|
|
345
|
-
```
|
|
346
|
-
|
|
347
|
-
### Compose-file customization
|
|
348
|
-
|
|
349
|
-
The compose setup resolves files in this precedence order.
|
|
350
|
-
|
|
351
|
-
1. **Environment override** uses `COMPOSE_FILE` with colon-delimited paths.
|
|
352
|
-
2. **Automatically loaded files** are based on `COMPOSE_TYPE` and `COMPOSE_ADDONS`.
|
|
353
|
-
- `compose-base.yml` provides the core application service.
|
|
354
|
-
- `compose-{addon}.yml` adds one file per addon, such as `compose-db.yml`.
|
|
355
|
-
- `compose-debug.yml` is used when the `--debug` flag is present.
|
|
356
|
-
- `compose-{addon}-debug.yml` provides debug overlays for addons.
|
|
357
|
-
3. **Additional overlays** use `COMPOSE_OVERLAY_FILES` with colon-delimited paths.
|
|
358
|
-
|
|
359
|
-
You can provide local compose files or allow the tasks to use bundled templates.
|
|
360
|
-
|
|
361
|
-
### FastAPI stack
|
|
362
|
-
|
|
363
|
-
The FastAPI stack uses the standard Dockerfile supplied by this package. Configure its ports, credentials, and database settings through the [Docker Compose settings](#docker-compose-settings) reference.
|
|
364
|
-
|
|
365
|
-
## Troubleshooting
|
|
366
|
-
|
|
367
|
-
### Tasks not showing up with `poe --help`
|
|
368
|
-
|
|
369
|
-
Check the `[tool.poe]` configuration in `pyproject.toml` and use `include_script`.
|
|
370
|
-
|
|
371
|
-
```toml
|
|
372
|
-
# Correct
|
|
373
|
-
[tool.poe]
|
|
374
|
-
include_script = "common_python_tasks:tasks(exclude_tags=['internal'])"
|
|
375
|
-
|
|
376
|
-
# Incorrect
|
|
377
|
-
[tool.poe]
|
|
378
|
-
includes = "common_python_tasks:tasks"
|
|
379
|
-
```
|
|
380
|
-
|
|
381
|
-
### Config files not being used
|
|
382
|
-
|
|
383
|
-
Review the [configuration precedence](#configuration-precedence) and enable debug logging to see the selected configuration.
|
|
384
|
-
|
|
385
|
-
```shell
|
|
386
|
-
COMMON_PYTHON_TASKS_LOG_LEVEL=DEBUG poe test
|
|
387
|
-
```
|
|
388
|
-
|
|
389
|
-
### GitHub Release assets not uploading
|
|
390
|
-
|
|
391
|
-
Confirm that `dist/` contains the built wheels and source distributions. You can override the default asset selection with `GITHUB_RELEASE_ASSETS`.
|
|
392
|
-
|
|
393
|
-
```shell
|
|
394
|
-
GITHUB_RELEASE_ASSETS="dist/*.whl:dist/*.tar.gz" poe publish-github-release
|
|
395
|
-
```
|
|
396
|
-
|
|
397
|
-
### Container build fails with "unable to find package"
|
|
398
|
-
|
|
399
|
-
Check that `pyproject.toml` has a correct package name and the package-discovery settings required by its build backend. For a `src` layout built with Hatch, configure `[tool.hatch.build.targets.wheel] packages = ["src/your_package"]`.
|
|
400
|
-
|
|
401
|
-
### Stack fails to start or services cannot connect
|
|
402
|
-
|
|
403
|
-
Check the following conditions.
|
|
404
|
-
|
|
405
|
-
- `COMPOSE_TYPE` is set and the required addon is selected.
|
|
406
|
-
- Default ports are available, including `8080` for the API, `5432` for PostgreSQL, and `8081` for Adminer.
|
|
407
|
-
- The Docker daemon is running, as verified with `docker info`.
|
|
408
|
-
- Service logs are available through `docker compose logs` in the project directory.
|
|
409
|
-
|
|
410
|
-
### Database migrations fail
|
|
411
|
-
|
|
412
|
-
Verify that the `db` addon is selected, Alembic is configured at the expected location, and its credentials match the generated `.env` values. Use `poe db-shell` to inspect the database manually.
|
|
413
|
-
|
|
414
|
-
### Secrets are not generated
|
|
415
|
-
|
|
416
|
-
Ensure the project-root `.env` file is writable and inspect its permissions with `ls -la .env`. You can also generate a value manually with `python -c "import secrets; print(secrets.token_hex(32))"`.
|
|
417
|
-
|
|
418
|
-
## Design choices
|
|
419
|
-
|
|
420
|
-
### Dockerfile design
|
|
421
|
-
|
|
422
|
-
See the [standard Dockerfile template](src/common_python_tasks/data/generic/Dockerfile.j2) for the implementation.
|
|
423
|
-
|
|
424
|
-
- Multi-stage build: The build stage installs uv and builds a wheel. The runtime stage installs only the wheel to keep the final image slim and reproducible.
|
|
425
|
-
- Cache mounts: Pip and uv cache mounts speed up iterative builds without bloating the final image.
|
|
426
|
-
- Explicit build metadata: `PYTHON_VERSION`, `UV_VERSION`, `PACKAGE_VERSION`, `PACKAGE_NAME`, `AUTHORS`, and `GIT_COMMIT` make image metadata predictable and auditable.
|
|
427
|
-
- Project-level build settings: `CONTAINER_APT_PACKAGES`, `CONTAINER_CUSTOM_ENTRYPOINT`, and `CONTAINER_DEPS_IMAGE` configure generated image behavior without being encoded as generic Docker arguments.
|
|
428
|
-
- Optional debug stage: The image exports and installs the `debug` dependency group only when present and does not include it in the default final image.
|
|
429
|
-
- Stable package path: Symlinks give entrypoints and consumers consistent `/pkg` and `/_$PACKAGE_NAME` paths regardless of wheel layout.
|
|
430
|
-
- Safe entrypoint selection: The default entrypoint resolves the console script matching the package name and falls back to `python`. `CONTAINER_CUSTOM_ENTRYPOINT` is validated against `[project].scripts`.
|
|
431
|
-
- Minimal final image: The standard slim Python base, cache cleanup, and explicit `runtime` final target keep the default image small.
|
|
432
|
-
|
|
433
|
-
## Project notes
|
|
434
|
-
|
|
435
|
-
- This project dogfoods itself. Set `PYTHONPATH=src` when running its tasks locally so Poe uses the local package rather than the installed version.
|
|
436
|
-
- `RELEASE_UPDATE_CHANGELOG` is enabled by default and prepends the generated changelog section before the release tag is created. Set it to a falsy value to manage changelog commits yourself.
|
|
437
|
-
- `RELEASE_PRE_SCRIPT` and `RELEASE_POST_SCRIPT` are advanced hooks for release-specific work, such as updating a version reference in another file.
|
|
438
|
-
- The project is in alpha status, so breaking changes may occur between minor versions before 1.0.0.
|
|
439
|
-
|
|
440
|
-
## Contributing
|
|
441
|
-
|
|
442
|
-
Contributions and feedback are welcome. Please open an issue or discussion to talk through a change before submitting a pull request.
|
|
File without changes
|
{common_python_tasks-0.10.2.dist-info → common_python_tasks-0.11.0.dist-info}/licenses/LICENSE
RENAMED
|
File without changes
|