backport improvements from hulpvraag

- tasks: fetch tags before bump, auto-push tag, add version() task
- tasks(service): pre=[ci] on build_image, :latest tag, interactive deploy prompt
- pyproject.toml: add ruff isort known-first-party section
- Dockerfile: add smoke-test import after install

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Jev
2026-06-12 21:56:07 +02:00
parent 7188b20797
commit 5d1172b172
3 changed files with 25 additions and 14 deletions
+1
View File
@@ -13,6 +13,7 @@ WORKDIR /app
COPY --from=builder /app/requirements.txt /app/dist/*.whl ./ COPY --from=builder /app/requirements.txt /app/dist/*.whl ./
RUN pip install --no-cache-dir -r requirements.txt \ RUN pip install --no-cache-dir -r requirements.txt \
&& pip install --no-cache-dir --no-deps *.whl \ && pip install --no-cache-dir --no-deps *.whl \
&& python -c "import {{ cookiecutter.package_name }}" \
&& rm -f *.whl requirements.txt && rm -f *.whl requirements.txt
USER 1000:1000 USER 1000:1000
ENTRYPOINT ["python", "-m", "{{ cookiecutter.package_name }}"] ENTRYPOINT ["python", "-m", "{{ cookiecutter.package_name }}"]
@@ -65,3 +65,6 @@ ignore = [
[tool.ruff.lint.per-file-ignores] [tool.ruff.lint.per-file-ignores]
"tests/*" = ["ARG001"] # Allow unused arguments in tests "tests/*" = ["ARG001"] # Allow unused arguments in tests
[tool.ruff.lint.isort]
known-first-party = ["{{ cookiecutter.package_name }}"]
+21 -14
View File
@@ -58,6 +58,7 @@ def bump(c, part):
if c.run("git status --porcelain", hide=True).stdout.strip(): if c.run("git status --porcelain", hide=True).stdout.strip():
raise SystemExit("Working tree is dirty. Commit or stash changes first.") raise SystemExit("Working tree is dirty. Commit or stash changes first.")
c.run("git fetch --tags", hide=True)
major, minor, patch = (int(x) for x in _latest_tag(c).lstrip("v").split(".")) major, minor, patch = (int(x) for x in _latest_tag(c).lstrip("v").split("."))
if part == "major": if part == "major":
major, minor, patch = major + 1, 0, 0 major, minor, patch = major + 1, 0, 0
@@ -68,7 +69,8 @@ def bump(c, part):
tag = f"v{major}.{minor}.{patch}" tag = f"v{major}.{minor}.{patch}"
c.run(f"git tag {tag}") c.run(f"git tag {tag}")
print(f"Tagged {tag}. Push it with: git push origin {tag}") c.run(f"git push origin {tag}")
print(f"Tagged and pushed {tag}.")
{%- if cookiecutter.project_type == "service" %} {%- if cookiecutter.project_type == "service" %}
@@ -77,25 +79,30 @@ def _version(c) -> str:
@task @task
def version(c):
"""Print the current version (latest git tag)."""
print(_version(c))
@task(pre=[ci])
def build_image(c): def build_image(c):
"""Build the runtime image, tagged with the current version.""" """Build the runtime image tagged as latest."""
c.run(f"docker build --network=host -t {IMAGE}:{_version(c)} .") c.run(f"docker build --network=host -t {IMAGE}:latest .")
@task @task
def deploy(c): def deploy(c):
"""Build image, copy to VPS over SSH, restart the compose service.""" """Build image, copy to VPS over SSH, then prompt before restarting the compose service."""
version = _version(c)
build_image(c) build_image(c)
print(f"Transferring {IMAGE}:{version} to {VPS}...") print(f"Transferring {IMAGE}:latest to {VPS}...")
c.run(f"docker save {IMAGE}:{version} | ssh {VPS} docker load", pty=True) c.run(f"docker save {IMAGE}:latest | ssh {VPS} docker load", pty=True)
print("Updating docker-compose and restarting service...") print("Image transferred.")
c.run( answer = input("Restart service on VPS? [y/N] ").strip().lower()
f'ssh {VPS} "cd {REMOTE_DIR} && ' if answer != "y":
f"sed -i 's|image: {IMAGE}:.*|image: {IMAGE}:{version}|' docker-compose.yml && " print("Skipping restart. Image is available on the VPS.")
f'docker compose up -d {SERVICE}"' return
) c.run(f'ssh {VPS} "cd {REMOTE_DIR} && docker compose down {SERVICE} && docker compose up -d {SERVICE}"')
print(f"Deployed {IMAGE}:{version}") print("Service restarted.")
{%- endif %} {%- endif %}