diff --git a/.drone.yml b/.drone.yml deleted file mode 100644 index 57b87e4..0000000 --- a/.drone.yml +++ /dev/null @@ -1,181 +0,0 @@ ---- -kind: pipeline -type: docker -name: pre-commit -steps: - - name: pre-commit - image: rg.fr-par.scw.cloud/crocmagnon/pre-commit:latest - pull: always - commands: - - pre-commit run --all-files --color always --show-diff-on-failure - ---- -kind: pipeline -type: docker -name: build test images -environment: - POETRY_OPTIONS: "" -steps: - - name: build deps image - image: plugins/docker - settings: - registry: rg.fr-par.scw.cloud/crocmagnon - username: { from_secret: registry_username } - password: { from_secret: registry_password } - cache_from: - - rg.fr-par.scw.cloud/crocmagnon/blog:tests-deps - repo: rg.fr-par.scw.cloud/crocmagnon/blog - tags: tests-deps - target: venv - build_args_from_env: - - POETRY_OPTIONS - pull_image: true - purge: false - storage_driver: overlay2 - - name: build tests image - image: plugins/docker - settings: - registry: rg.fr-par.scw.cloud/crocmagnon - username: { from_secret: registry_username } - password: { from_secret: registry_password } - cache_from: - - rg.fr-par.scw.cloud/crocmagnon/blog:tests-latest - - rg.fr-par.scw.cloud/crocmagnon/blog:tests-deps - repo: rg.fr-par.scw.cloud/crocmagnon/blog - tags: tests-latest - build_args_from_env: - - POETRY_OPTIONS - pull_image: true - purge: false - storage_driver: overlay2 - ---- -kind: pipeline -type: docker -name: build prod images -environment: - POETRY_OPTIONS: "--no-dev" -steps: - - name: build deps image - image: plugins/docker - settings: - registry: rg.fr-par.scw.cloud/crocmagnon - username: { from_secret: registry_username } - password: { from_secret: registry_password } - cache_from: - - rg.fr-par.scw.cloud/crocmagnon/blog:deps - repo: rg.fr-par.scw.cloud/crocmagnon/blog - tags: deps - build_args_from_env: - - POETRY_OPTIONS - target: venv - pull_image: true - purge: false - storage_driver: overlay2 - when: - branch: - - master - - name: build temp prod image - image: plugins/docker - settings: - registry: rg.fr-par.scw.cloud/crocmagnon - username: { from_secret: registry_username } - password: { from_secret: registry_password } - cache_from: - - rg.fr-par.scw.cloud/crocmagnon/blog:latest-temp - - rg.fr-par.scw.cloud/crocmagnon/blog:deps - repo: rg.fr-par.scw.cloud/crocmagnon/blog - tags: latest-temp - build_args_from_env: - - POETRY_OPTIONS - pull_image: true - purge: false - storage_driver: overlay2 - when: - branch: - - master - ---- -kind: pipeline -type: docker -name: unit tests -depends_on: - - build test images -steps: - - name: unit tests - image: rg.fr-par.scw.cloud/crocmagnon/blog:tests-latest - pull: always - commands: - - cd /app - - python -m pytest - ---- -kind: pipeline -type: docker -name: missing migration -depends_on: - - build test images -steps: - - name: missing migration - image: rg.fr-par.scw.cloud/crocmagnon/blog:tests-latest - pull: always - commands: - - cd /app - - python manage.py makemigrations --check - ---- -kind: pipeline -type: docker -name: publish prod image -depends_on: - - missing migration - - unit tests - - pre-commit - - build prod images -steps: - - name: retag prod image - image: nicolaka/netshoot - environment: - REGISTRY: rg.fr-par.scw.cloud - REGISTRY_USERNAME: { from_secret: registry_username } - REGISTRY_PASSWORD: { from_secret: registry_password } - CRANE_VERSION: 0.4.0 - commands: - - wget "https://github.com/google/go-containerregistry/releases/download/v$CRANE_VERSION/go-containerregistry_Linux_x86_64.tar.gz" - - tar xzf go-containerregistry_Linux_x86_64.tar.gz - - ./crane auth login -u $REGISTRY_USERNAME -p $REGISTRY_PASSWORD $REGISTRY - - ./crane tag $REGISTRY/crocmagnon/blog:latest-temp latest - when: - branch: - - master - ---- -kind: pipeline -type: docker -name: deploy -depends_on: - - publish prod image -steps: - - name: deploy - image: ubuntu - commands: - - 'command -v ssh-agent >/dev/null || ( apt-get update -y && apt-get install openssh-client -y --no-install-recommends )' - - eval $(ssh-agent -s) - - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - - - mkdir -p ~/.ssh - - chmod 700 ~/.ssh - - echo "$SSH_CONFIG" > ~/.ssh/config - - chmod 644 ~/.ssh/config - - echo "$SSH_KNOWN_HOSTS" >> ~/.ssh/known_hosts - - chmod 644 ~/.ssh/known_hosts - - ssh blog "/home/gaugendre/blog/update" - environment: - SSH_PRIVATE_KEY: - from_secret: ssh_private_key - SSH_CONFIG: - from_secret: ssh_config - SSH_KNOWN_HOSTS: - from_secret: ssh_known_hosts - when: - branch: - - master diff --git a/Dockerfile b/Dockerfile index c75fa7e..695a32b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,11 +2,10 @@ FROM python:3.10.1-bullseye AS venv # https://python-poetry.org/docs/#installation -ENV POETRY_VERSION=1.1.4 -RUN curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python +ENV POETRY_VERSION=1.1.11 +RUN curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/install-poetry.py | python - -ENV PATH /root/.poetry/bin:$PATH -ENV PYTHONPATH $PYTHONPATH:/root/.poetry/lib +ENV PATH /root/.local/bin:$PATH ARG POETRY_OPTIONS WORKDIR /app @@ -24,7 +23,7 @@ RUN python -m venv --copies /app/venv \ ## Get git versions -FROM alpine/git:v2.26.2 AS git +FROM alpine/git AS git ADD . /app WORKDIR /app RUN git rev-parse HEAD | tee /version diff --git a/README.md b/README.md index e40bf83..bef36ac 100644 --- a/README.md +++ b/README.md @@ -5,3 +5,10 @@ Simple blog management system. The authoritative source for this repo is at https://git.augendre.info/gaugendre/blog Hosted at https://gabnotes.org + +## Development +```shell +inv test-cov +inv publish +inv deploy +``` diff --git a/docker-compose.yml b/docker-compose.yml index 47e18d2..d1d6ac0 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,7 +1,7 @@ version: '2.4' services: django: - image: rg.fr-par.scw.cloud/crocmagnon/blog:latest + image: crocmagnon/blog:latest build: context: . args: diff --git a/poetry.lock b/poetry.lock index 107d6be..6b615d3 100644 --- a/poetry.lock +++ b/poetry.lock @@ -261,6 +261,14 @@ category = "dev" optional = false python-versions = "*" +[[package]] +name = "invoke" +version = "1.6.0" +description = "Pythonic task execution" +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "lxml" version = "4.7.1" @@ -740,7 +748,7 @@ multidict = ">=4.0" [metadata] lock-version = "1.1" python-versions = "^3.10" -content-hash = "a32976a9a8d29bebdf5783b5948168194249f40ac76772966d525a4c05e7986d" +content-hash = "8ce7193640d549da552b67f5d485214f3e74931c801116164ad21614be32846e" [metadata.files] asgiref = [ @@ -914,6 +922,11 @@ iniconfig = [ {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, ] +invoke = [ + {file = "invoke-1.6.0-py2-none-any.whl", hash = "sha256:e6c9917a1e3e73e7ea91fdf82d5f151ccfe85bf30cc65cdb892444c02dbb5f74"}, + {file = "invoke-1.6.0-py3-none-any.whl", hash = "sha256:769e90caeb1bd07d484821732f931f1ad8916a38e3f3e618644687fc09cb6317"}, + {file = "invoke-1.6.0.tar.gz", hash = "sha256:374d1e2ecf78981da94bfaf95366216aaec27c2d6a7b7d5818d92da55aa258d3"}, +] lxml = [ {file = "lxml-4.7.1-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:d546431636edb1d6a608b348dd58cc9841b81f4116745857b6cb9f8dadb2725f"}, {file = "lxml-4.7.1-cp27-cp27m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6308062534323f0d3edb4e702a0e26a76ca9e0e23ff99be5d82750772df32a9e"}, diff --git a/pyproject.toml b/pyproject.toml index 79b9bf2..77619ee 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -52,6 +52,7 @@ pytest-recording = "^0.12.0" pytest-rerunfailures = "^10.2" pytest-env = "^0.6.2" poetry-deps-scanner = "^1.0.1" +invoke = "^1.6.0" [build-system] requires = ["poetry-core>=1.0.0"] diff --git a/tasks.py b/tasks.py new file mode 100644 index 0000000..bf1a303 --- /dev/null +++ b/tasks.py @@ -0,0 +1,33 @@ +from pathlib import Path + +from invoke import task + +BASE_DIR = Path(__file__).parent.resolve(strict=True) + + +@task +def test(ctx): + with ctx.cd(BASE_DIR): + ctx.run("pytest", pty=True, echo=True) + + +@task +def test_cov(ctx): + with ctx.cd(BASE_DIR): + ctx.run( + "pytest --cov=. --cov-report term-missing:skip-covered", + pty=True, + echo=True, + ) + + +@task +def publish(ctx): + with ctx.cd(BASE_DIR): + ctx.run("docker-compose build django", pty=True, echo=True) + ctx.run("docker-compose push django", pty=True, echo=True) + + +@task +def deploy(ctx): + ctx.run("ssh ubuntu /home/gaugendre/blog/update", pty=True, echo=True)