common-python-tasks 0.10.2__py3-none-any.whl → 0.10.3__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.
@@ -1,7 +1,7 @@
1
1
  x-common-environment: &common-environment
2
2
  {{ ENV_PREFIX }}_DB_BASE: ${DB_BASE}
3
3
  {{ ENV_PREFIX }}_DB_HOST: db
4
- {{ ENV_PREFIX }}_DB_PORT: ${DB_PORT}
4
+ {{ ENV_PREFIX }}_DB_PORT: 5432
5
5
  {{ ENV_PREFIX }}_DB_PASS: ${DB_PASS}
6
6
  {{ ENV_PREFIX }}_DB_USER: ${DB_USER}
7
7
 
@@ -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
- # Inject custom builder stage environment variables
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.append("")
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)
@@ -537,6 +537,7 @@ def render_container_deps_move_script(mappings: dict[str, str]) -> str:
537
537
  import textwrap
538
538
 
539
539
  script_lines = [
540
+ "#!/usr/bin/env python3",
540
541
  "import pathlib",
541
542
  "import shutil",
542
543
  "import sys",
@@ -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 check_result.returncode == 1:
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
@@ -154,7 +154,9 @@ def get_dependency_update_command(
154
154
  if dependencies is None:
155
155
  dependencies = []
156
156
 
157
- command = ["uv", "sync", "--upgrade"]
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
@@ -430,9 +430,9 @@ def build_image(
430
430
  dockerfile_hook_path: Optional executable script path that can mutate
431
431
  the generated Dockerfile before build. Overrides
432
432
  CONTAINER_DOCKERFILE_HOOK_PATH if provided.
433
- container_env: Builder-stage environment declarations as repeated
433
+ container_env: Builder and runtime environment declarations as repeated
434
434
  KEY=VALUE values.
435
- container_envfile: Optional repeated list of files containing builder-stage
435
+ container_envfile: Optional repeated list of files containing builder and runtime
436
436
  environment declarations.
437
437
 
438
438
  Precedence for container env declarations is: .containerenv, container_envfile,
@@ -524,7 +524,7 @@ def build_image(
524
524
  )
525
525
  if container_env_vars:
526
526
  LOGGER.debug(
527
- "Injecting builder-stage env vars: %s",
527
+ "Injecting builder and runtime env vars: %s",
528
528
  ", ".join(container_env_vars),
529
529
  )
530
530
  top_level_build_args = inject_auto_build_args_from_env(
@@ -1731,26 +1731,49 @@ def fastapi_run_db_migrations() -> None:
1731
1731
  """Run database migrations."""
1732
1732
  from .docker_compose import (
1733
1733
  cleanup_temp_files,
1734
+ ensure_secrets_generated,
1734
1735
  load_and_prepare_compose,
1735
1736
  run_docker_compose_command,
1736
1737
  )
1737
1738
 
1738
- services = ["db", "migrator"]
1739
- fastapi_stack_up(debug=False, detach=True, services=services)
1739
+ container_build = build_image(single_arch=True)
1740
+ ensure_secrets_generated()
1741
+ compose_files, temp_compose_files, temp_config_files, compose_env = (
1742
+ load_and_prepare_compose(image_tag=container_build.commit_tag)
1743
+ )
1740
1744
  try:
1741
- compose_files, temp_compose_files, _, compose_env = load_and_prepare_compose()
1745
+ run_docker_compose_command(
1746
+ "up",
1747
+ "-d",
1748
+ "--no-build",
1749
+ "db",
1750
+ compose_files=compose_files,
1751
+ compose_env=compose_env,
1752
+ tasks=tasks,
1753
+ )
1754
+ run_docker_compose_command(
1755
+ "run",
1756
+ "--rm",
1757
+ "migrator",
1758
+ compose_files=compose_files,
1759
+ compose_env=compose_env,
1760
+ tasks=tasks,
1761
+ )
1762
+ finally:
1742
1763
  try:
1743
1764
  run_docker_compose_command(
1744
- "logs",
1765
+ "rm",
1766
+ "-f",
1767
+ "-s",
1768
+ "-v",
1769
+ "db",
1745
1770
  "migrator",
1746
1771
  compose_files=compose_files,
1747
1772
  compose_env=compose_env,
1748
1773
  tasks=tasks,
1749
1774
  )
1750
1775
  finally:
1751
- cleanup_temp_files(temp_compose_files)
1752
- finally:
1753
- fastapi_stack_down()
1776
+ cleanup_temp_files(temp_compose_files, temp_config_files)
1754
1777
 
1755
1778
 
1756
1779
  @tasks.script(task_name="db-shell", tags=["web", "containers", "database", "fastapi"])
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: common-python-tasks
3
- Version: 0.10.2
3
+ Version: 0.10.3
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
@@ -43,7 +43,7 @@ It supplies sensible defaults for formatting, linting, testing, packaging, relea
43
43
  Add `common-python-tasks` as a development dependency from your project root.
44
44
 
45
45
  ```shell
46
- uv add --dev common-python-tasks==0.10.2
46
+ uv add --dev common-python-tasks==0.10.3
47
47
  ```
48
48
 
49
49
  Configure Poe the Poet to expose the default `common` task set.
@@ -68,7 +68,7 @@ The helper script performs the same development-dependency installation and Poe
68
68
  ```shell
69
69
  curl --fail --silent --show-error --location \
70
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
71
+ https://raw.githubusercontent.com/ci-sourcerer/common-python-tasks/v0.10.3/scripts/add_common_python_tasks.py
72
72
  ```
73
73
 
74
74
  Review the downloaded script before executing it.
@@ -80,10 +80,10 @@ less /tmp/add_common_python_tasks.py
80
80
  Run the reviewed script with the same pinned package version.
81
81
 
82
82
  ```shell
83
- COMMON_PYTHON_TASKS_VERSION=0.10.2 python3 /tmp/add_common_python_tasks.py
83
+ COMMON_PYTHON_TASKS_VERSION=0.10.3 python3 /tmp/add_common_python_tasks.py
84
84
  ```
85
85
 
86
- To install another release, replace both occurrences of `0.10.2` with that release's version.
86
+ To install another release, replace both occurrences of `0.10.3` with that release's version.
87
87
 
88
88
  ## Available tasks
89
89
 
@@ -203,7 +203,7 @@ After installing the package, a minimal project configuration looks like this.
203
203
  ```toml
204
204
  [project]
205
205
  name = "simple-cli-tool"
206
- version = "0.10.2"
206
+ version = "0.10.3"
207
207
 
208
208
  [tool.poe]
209
209
  include_script = "common_python_tasks:tasks()"
@@ -256,7 +256,7 @@ addopts = "-ra"
256
256
  - `CONTAINER_DEPS_IMAGE`: Existing dependency image used when neither `CONTAINER_DEPS_CONTENT` nor `CONTAINER_DEPS_FILE` is configured
257
257
  - `CONTAINER_EXTENSION_FILES`: Colon-delimited local extension Dockerfile paths. Escape literal colons as `\:` or quote the complete path.
258
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.
259
+ - `CONTAINER_ENV`: Colon-delimited `KEY=VALUE` declarations injected into both the builder and runtime stages. These variables are available to package build commands and runtime-stage build commands, and persist in the final and debug images for running containers. The `container_env` and `container_envfile` task arguments use the same behavior. Escape literal colons as `\:` or quote the complete value. Use `run-container --env` or `--envfile` to override values when starting a container.
260
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
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
262
  - `CONTAINER_DEPS_CONTENT`: Inline Dockerfile instructions for a dependency image that installs artifacts into `/tmp/deps`
@@ -291,7 +291,7 @@ addopts = "-ra"
291
291
  - `SECRET_KEY`: Application secret key generated automatically when unset
292
292
  - `ENVIRONMENT`: Environment name with a default of `production`
293
293
  - `DEBUG_PORT`: Python debugger port in debug mode with a default of `5678`
294
- - `DB_PORT`: PostgreSQL port with a default of `5432`
294
+ - `DB_PORT`: Published host port for PostgreSQL, defaulting to `5432`. The API and migrator connect to the database container on port `5432` regardless of this setting.
295
295
  - `DB_USER`: Database user with a default of the package name
296
296
  - `DB_BASE`: Database name with a default of the package name
297
297
  - `DB_PASS`: Database password generated automatically when unset
@@ -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=tEChLNxlcBMQXy2wjZrVsmFxFrvt3CmJYBpc-7Q4bK0,21281
5
- common_python_tasks/env.py,sha256=QSSu4NbnV5oKqMBDBAXPh6oJHYmumoAZRRpRmSQsmvk,19662
6
- common_python_tasks/git.py,sha256=znfLSEwAUYL6nFK4fjLhzdjFu9Pc3ppPdU9m2QCHaKw,11511
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=B3uHA5wgSLfeYVYDQJCCSCr323IX_VpcDILsOxBU7hs,17329
9
- common_python_tasks/tasks.py,sha256=sTG4GtUXVxQ8ZWKWGuWdghI03DFyXLbSee8Xc6g0nv0,59519
8
+ common_python_tasks/project.py,sha256=PQ_GQicTrSQgVDB9cJ9E6pU0UhLPom2xou1sGFscr3E,17377
9
+ common_python_tasks/tasks.py,sha256=h-bPYwTZ3uct4dR8a-NUYKHhSB4EZ-J9iJyhaB3yJc4,60135
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=16i2rrsYPIJIQn4gpopr5-8KBirMS7OwpXHPaAC03k8,1777
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=0K_gNC35wiP1-yOO2UB2WoeCoz0iW5pS7walajsXFPE,6016
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.10.2.dist-info/METADATA,sha256=0dWkJuwdXMGU7CzQEHtzyRvZ47JKdUBbhXEjRhKoMkE,22028
25
- common_python_tasks-0.10.2.dist-info/WHEEL,sha256=zOwg4jB6zX2kU910N-cMawjivD6tO8NEWvE12je1bVk,87
26
- common_python_tasks-0.10.2.dist-info/licenses/LICENSE,sha256=RsSweM-DyzxFPx38fQOJqHrKyeT9Fiz8rO7yox-fOsw,1070
27
- common_python_tasks-0.10.2.dist-info/RECORD,,
24
+ common_python_tasks-0.10.3.dist-info/METADATA,sha256=p9oMXue96WswNU4KsUoG8yBP8GZBsyQqqlFfpkMojHk,22464
25
+ common_python_tasks-0.10.3.dist-info/WHEEL,sha256=zOwg4jB6zX2kU910N-cMawjivD6tO8NEWvE12je1bVk,87
26
+ common_python_tasks-0.10.3.dist-info/licenses/LICENSE,sha256=RsSweM-DyzxFPx38fQOJqHrKyeT9Fiz8rO7yox-fOsw,1070
27
+ common_python_tasks-0.10.3.dist-info/RECORD,,