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:
@@ -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 }}"]
|
||||||
|
|||||||
@@ -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 %}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user