hotpocket/tasks.py
Tomek Wójcik b4338e2769
Some checks failed
CI / Checks (push) Failing after 13m2s
Release v1.0.0
2025-08-20 21:00:50 +02:00

258 lines
5.8 KiB
Python

# -*- coding: utf-8 -*-
from __future__ import annotations
import datetime
from invoke import task
from hotpocket_workspace_tools import get_workspace_mode, WorkspaceMode
class DockerBuildContext:
def __init__(self,
/,
target='deployment',
version=None,
build='01',
machine=None,
):
self._target = target
self._version = version
self._build = build
self._image_arch = None
self._node_arch = None
def __enter__(self, *args, **kwargs):
return self
def __exit__(self, *args, **kwargs):
pass
@property
def target(self) -> str:
return self._target
@property
def version(self) -> str:
return self._version or datetime.date.today().strftime('%Y%m%d')
@property
def build(self) -> str:
return self._build.zfill(2)
@property
def image_arch(self) -> str:
return self._image_arch
@property
def node_arch(self) -> str:
return self._node_arch
@property
def tag(self) -> str:
return '{target}-{version}-{build}'.format(
target=self.target,
version=self.version,
build=self.build,
)
WORKSPACE_MODE = get_workspace_mode()
ALL_SERVICES = ['backend', 'packages']
def _run_in_service(ctx, service, command, **kwargs):
match WORKSPACE_MODE:
case WorkspaceMode.DOCKER:
return ctx.run(
f'docker compose run --rm -it {service}-management {command}',
)
case WorkspaceMode.METAL:
with ctx.cd(f'services/{service}'):
ctx.run(f'direnv exec . {command}')
def _get_version(ctx, service):
with ctx.cd(f'services/{service}'):
run_result = ctx.run('poetry version -s', hide='out')
return run_result.stdout.strip()
def _get_head_sha(ctx):
run_result = ctx.run('git rev-parse HEAD', hide='out')
return run_result.stdout.strip()
@task
def clean(ctx, service):
_run_in_service(ctx, service, 'inv clean')
@task
def test(ctx, service):
_run_in_service(ctx, service, 'inv test')
@task
def lint(ctx, service):
_run_in_service(ctx, service, 'inv lint')
@task
def typecheck(ctx, service):
_run_in_service(ctx, service, 'inv typecheck')
@task
def shell(ctx, service):
assert WORKSPACE_MODE == WorkspaceMode.DOCKER, (
'Just `cd services/{service}` ;)'
)
_run_in_service(ctx, service, '/bin/bash')
@task
def django_shell(ctx, service):
_run_in_service(ctx, service, 'inv django-shell')
@task
def build(ctx,
service,
context=None,
builder=None,
push=False,
target='deployment',
version=None,
build='01',
image_tag=None,
machine=None,
platform=None,
):
image_tag = image_tag or '{target}.{{short_sha}}'.format(target=target)
short_sha = _get_head_sha(ctx)[:8]
image_tag = image_tag.format(
short_sha=short_sha,
)
with DockerBuildContext(target, version, build, machine) as docker_build_ctx: # noqa: E501
commandline = [
'docker',
(
f'--context {context}'
if context is not None
else ''
),
'buildx build',
(
f'--builder {builder}'
if builder is not None
else ''
),
(
'--push'
if push is True
else ''
),
(
f'--platform {platform}'
if platform is not None
else ''
),
f'-t docker-hosted.nexus.bthlabs.pl/hotpocket/{service}:{docker_build_ctx.tag}', # noqa: E501
f'-f services/{service}/Dockerfile',
f'--build-arg IMAGE_ID={image_tag}',
f'--target {docker_build_ctx.target}',
'services/',
]
ctx.run(' '.join(commandline))
@task
def publish(ctx,
service,
context=None,
target='deployment',
version=None,
build='01',
machine=None,
):
with DockerBuildContext(target, version, build, machine) as docker_build_ctx: # noqa: E501
commandline = [
'docker',
(
f'--context {context}'
if context is not None
else ''
),
'push',
f'docker-hosted.nexus.bthlabs.pl/hotpocket/{service}:{docker_build_ctx.tag}', # noqa: E501
]
ctx.run(' '.join(commandline))
@task
def ci(ctx, service):
_run_in_service(ctx, service, 'inv ci')
@task
def setup(ctx, service=None):
services_to_setup = []
services_to_setup = [*ALL_SERVICES]
if service is not None:
services_to_setup = [service]
for service_to_setup in services_to_setup:
_run_in_service(ctx, service_to_setup, 'inv setup')
@task
def install(ctx, service=None):
services_to_setup = []
services_to_setup = [*ALL_SERVICES]
if service is not None:
services_to_setup = [service]
for service_to_setup in services_to_setup:
_run_in_service(ctx, service_to_setup, 'poetry install')
@task
def lock(ctx, service):
_run_in_service(ctx, service, 'poetry lock --no-update')
@task
def start_cloud(ctx):
ctx.run('docker compose -f docker-compose-cloud.yaml up')
@task
def start_web(ctx, service):
_run_in_service(ctx, service, 'inv start-web')
@task
def start_celery_worker(ctx, service):
_run_in_service(ctx, service, 'inv start-worker')
@task
def start_celery_beat(ctx, service):
_run_in_service(ctx, service, 'inv start-beat')
@task
def start_app(ctx, service, app):
_run_in_service(ctx, service, f'inv start-{app}')