From f05e7bf0c930d174fb2eaf49c5a8874d2cbe1d77 Mon Sep 17 00:00:00 2001 From: Abderrahmane Smimite Date: Sat, 13 Apr 2024 19:23:25 +0200 Subject: [PATCH] improve version management --- .dockerignore | 1 - .github/workflows/docker-build-and-push.yml | 11 +++-- backend/Dockerfile | 25 ++++++++--- backend/ciso_assistant/settings.py | 50 +++++++++++++-------- backend/requirements.txt | 1 + docker-compose-build.sh | 3 ++ docker-compose-build.yml | 7 ++- docker-compose.sh | 5 +++ docker-compose.yml | 2 + frontend/.dockerignore | 1 - 10 files changed, 76 insertions(+), 30 deletions(-) diff --git a/.dockerignore b/.dockerignore index 22b5ea72b1..b19e3d5537 100644 --- a/.dockerignore +++ b/.dockerignore @@ -2,6 +2,5 @@ *.DS_Store *~$* **/*.mo -.git* .pytest* .idea* diff --git a/.github/workflows/docker-build-and-push.yml b/.github/workflows/docker-build-and-push.yml index 3ea1bb757e..0d8aee55e7 100644 --- a/.github/workflows/docker-build-and-push.yml +++ b/.github/workflows/docker-build-and-push.yml @@ -32,9 +32,11 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Get git version - run: echo "VERSION=$(git describe --tags --always)" >> $GITHUB_ENV - + - name: Get git version and build + run: | + echo "VERSION=$(git describe --tags --always)" >> $GITHUB_ENV + echo "BUILD=$(git rev-parse --short HEAD)" >> $GITHUB_ENV + - name: Build and Push Backend Docker Image uses: docker/build-push-action@v5 with: @@ -45,6 +47,9 @@ jobs: ghcr.io/${{ github.repository }}/backend:${{ env.VERSION }} ghcr.io/${{ github.repository }}/backend:latest platforms: linux/amd64,linux/arm64,linux/arm64/v8 + build-args: | + VERSION=${{ env.VERSION }} + BUILD=${{ env.BUILD }} - name: Build and Push Frontend Docker Image uses: docker/build-push-action@v5 diff --git a/backend/Dockerfile b/backend/Dockerfile index 92a623a605..fd70e73725 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -6,18 +6,31 @@ ENV PYTHONUNBUFFERED 1 ENV PYTHONDONTWRITEBYTECODE=1 WORKDIR /code + +# Remove Git installation steps since you will pass VERSION and BUILD as build-args + +# Configure locales +RUN apt update && \ + apt install -y gettext locales && \ + apt clean && \ + rm -rf /var/lib/apt/lists/* && \ + sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && \ + sed -i -e 's/# fr_FR.UTF-8 UTF-8/fr_FR.UTF-8 UTF-8/' /etc/locale.gen && \ + locale-gen + COPY . /code/ COPY startup.sh /code/ RUN pip install --upgrade pip RUN pip install -r requirements.txt -RUN apt update && \ - apt install -y gettext && \ - apt install -y locales -RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen \ - && sed -i -e 's/# fr_FR.UTF-8 UTF-8/fr_FR.UTF-8 UTF-8/' /etc/locale.gen \ - && locale-gen +# Define ARGs for VERSION and BUILD, which will be passed at build time +ARG VERSION=unknown +ARG BUILD=unknown + +# Set the ARG values as ENV variables so they're available at runtime +ENV CISO_ASSISTANT_VERSION=$VERSION +ENV CISO_ASSISTANT_BUILD=$BUILD ENTRYPOINT ["bash", "startup.sh"] EXPOSE 8000 diff --git a/backend/ciso_assistant/settings.py b/backend/ciso_assistant/settings.py index 00c4e68bb8..a81f56bef5 100644 --- a/backend/ciso_assistant/settings.py +++ b/backend/ciso_assistant/settings.py @@ -11,6 +11,8 @@ from pathlib import Path import os +from dotenv import load_dotenv +import subprocess import json import logging.config import structlog @@ -19,16 +21,40 @@ # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = Path(__file__).resolve().parent.parent +dotenv_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), '.env') +load_dotenv(dotenv_path) + LOG_LEVEL = os.environ.get("LOG_LEVEL", "INFO") LOG_FORMAT = os.environ.get("LOG_FORMAT", "plain") CISO_ASSISTANT_URL = os.environ.get("CISO_ASSISTANT_URL", "http://localhost:5173") - +VERSION = os.getenv("CISO_ASSISTANT_VERSION", "unset") +BUILD = os.getenv("CISO_ASSISTANT_BUILD", "unset") + +def get_git_version_and_build(): + """Fetches version and build information using Git commands.""" + try: + # Get the latest tag or describe output + version = subprocess.check_output(["git", "describe", "--tags", "--always"], stderr=subprocess.STDOUT).strip().decode() + except subprocess.CalledProcessError: + # Default if the command fails + version = "unknown" + + try: + # Get the short commit hash + build = subprocess.check_output(["git", "rev-parse", "--short", "HEAD"], stderr=subprocess.STDOUT).strip().decode() + except subprocess.CalledProcessError: + # Default if the command fails + build = "unknown" + + return version, build def set_ciso_assistant_url(_, __, event_dict): event_dict["ciso_assistant_url"] = CISO_ASSISTANT_URL return event_dict +if VERSION == "unset" or BUILD == "unset": + VERSION, BUILD = get_git_version_and_build() LOGGING = { "version": 1, @@ -63,7 +89,8 @@ def set_ciso_assistant_url(_, __, event_dict): structlog.stdlib.add_logger_name, structlog.stdlib.add_log_level, structlog.stdlib.PositionalArgumentsFormatter(), - structlog.processors.StackInfoRenderer(), # Include stack information in log entries + # Include stack information in log entries + structlog.processors.StackInfoRenderer(), structlog.processors.format_exc_info, structlog.processors.UnicodeDecoder(), structlog.stdlib.ProcessorFormatter.wrap_for_formatter, @@ -76,20 +103,7 @@ def set_ciso_assistant_url(_, __, event_dict): logger = structlog.getLogger(__name__) logger.info("BASE_DIR: %s", BASE_DIR) - -with open(BASE_DIR / "ciso_assistant/VERSION") as f: - VERSION = f.read().strip() - logger.info("CISO Assistant Version: %s" % VERSION) - -try: - with open(BASE_DIR / "ciso_assistant/build.json") as f: - BUILD = json.load(f)["build"] - logger.info("CISO Assistant Build: %s" % BUILD) -except FileNotFoundError: - BUILD = "unset" - logger.warning( - "CISO Assistant Build: unset. Please refer to the documentation to set it." - ) +# TODO: multiple paths are explicit, it should use path join to be more generic # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/4.2/howto/deployment/checklist/ @@ -270,7 +284,7 @@ def set_ciso_assistant_url(_, __, event_dict): # https://docs.djangoproject.com/en/4.2/ref/settings/#databases # SQLIte file can be changed, useful for tests -SQLITE_FILE = os.environ.get('SQLITE_FILE', BASE_DIR / "db/ciso-assistant.sqlite3") +SQLITE_FILE = os.environ.get("SQLITE_FILE", BASE_DIR / "db/ciso-assistant.sqlite3") if "POSTGRES_NAME" in os.environ: @@ -290,7 +304,7 @@ def set_ciso_assistant_url(_, __, event_dict): "ENGINE": "django.db.backends.sqlite3", "NAME": SQLITE_FILE, "OPTIONS": { - 'timeout': 120, + "timeout": 120, }, } } diff --git a/backend/requirements.txt b/backend/requirements.txt index ad3d81b6a6..1ffaaebdab 100644 --- a/backend/requirements.txt +++ b/backend/requirements.txt @@ -15,3 +15,4 @@ django-tailwind==3.8.0 pyyaml==6.0.1 django-structlog==8.0.0 structlog==24.1.0 +python-dotenv==1.0.1 diff --git a/docker-compose-build.sh b/docker-compose-build.sh index 04e8380915..4d391b082f 100755 --- a/docker-compose-build.sh +++ b/docker-compose-build.sh @@ -1,5 +1,8 @@ #! /usr/bin/env bash +export VERSION=$(git describe --tags --always 2> /dev/null || echo "unknown") +export BUILD=$(git rev-parse --short HEAD 2> /dev/null || echo "unknown") + if [ -f db/ciso-assistant.sqlite3 ] ; then echo "the database seems already created" echo "you should launch docker compose up -d" diff --git a/docker-compose-build.yml b/docker-compose-build.yml index b245179a96..6df75b0fb3 100644 --- a/docker-compose-build.yml +++ b/docker-compose-build.yml @@ -3,7 +3,12 @@ version: "3.9" services: backend: container_name: backend - build: ./backend + build: + context: ./backend + dockerfile: Dockerfile + args: + VERSION: ${VERSION:-unknown} + BUILD: ${BUILD:-unknown} restart: always environment: - ALLOWED_HOSTS=backend diff --git a/docker-compose.sh b/docker-compose.sh index ef66436655..c5f8982c3e 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -1,9 +1,14 @@ #! /usr/bin/env bash +export VERSION=$(git describe --tags --always 2> /dev/null || echo "unknown") +export BUILD=$(git rev-parse --short HEAD 2> /dev/null || echo "unknown") + if [ -f db/ciso-assistant.sqlite3 ] ; then echo "the database seems already created" echo "you should launch docker compose up -d" + echo "for clean start, you can remove the database file, run docker compose down and then docker compose rm and start again" else + docker rmi ghcr.io/intuitem/ciso-assistant-community/backend:latest ghcr.io/intuitem/ciso-assistant-community/frontend:latest 2> /dev/null docker compose up -d docker compose exec backend python manage.py migrate echo "initialize your superuser account..." diff --git a/docker-compose.yml b/docker-compose.yml index f7605960b9..1997a42f7e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -9,6 +9,8 @@ services: - ALLOWED_HOSTS=backend - CISO_ASSISTANT_URL=https://localhost:8443 - DJANGO_DEBUG=True + - CISO_ASSISTANT_VERSION=${VERSION:-unknown} + - CISO_ASSISTANT_BUILD=${BUILD:-unknown} volumes: - ./db:/code/db diff --git a/frontend/.dockerignore b/frontend/.dockerignore index a378696ba0..c91d3dba0e 100644 --- a/frontend/.dockerignore +++ b/frontend/.dockerignore @@ -1,6 +1,5 @@ Dockerfile .dockerignore -.git .gitignore .gitattributes README.md