From fbb334b37c97dfd9d1ffc066b385a6fb63f348ad Mon Sep 17 00:00:00 2001 From: Frederico Sabino <3332770+fmrsabino@users.noreply.github.com> Date: Mon, 1 Apr 2024 22:14:18 +0100 Subject: [PATCH] Add Version and Builder Number to Docker image (#1085) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Adds the following build arguments: * `VERSION` – represents the version of the application (e.g.: semver). It is accessible across the app via `settings.APPLICATION_VERSION`. * `BUILD_NUMBER` – represents the build version of the application (e.g.: build hash). It is accessible across the app via `settings.APPLICATION_BUILD_NUMBER` - With the added support for the build arguments, the version of the application can now be set during the docker image building process instead of bundling the version with the application. --- .github/workflows/test.yml | 6 ++++++ Dockerfile | 6 +++++- src/about/tests/test_views.py | 24 +++++++++++++++++++++--- src/about/views.py | 5 +++-- src/config/settings.py | 3 +++ src/version.py | 1 - 6 files changed, 38 insertions(+), 7 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 88693508..aab3fe17 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -170,6 +170,9 @@ jobs: context: . platforms: linux/amd64,linux/arm64 push: true + build-args: | + BUILD_NUMBER=${{ env.BUILD_NUMBER }} + VERSION=${{ github.ref_name }} tags: safeglobal/safe-config-service:staging cache-from: type=local,src=/tmp/.buildx-cache cache-to: type=local,dest=/tmp/.buildx-cache-new @@ -215,6 +218,9 @@ jobs: context: . platforms: linux/amd64,linux/arm64 push: true + build-args: | + BUILD_NUMBER=${{ env.BUILD_NUMBER }} + VERSION=${{ github.ref_name }} tags: | safeglobal/safe-config-service:${{ github.event.release.tag_name }} safeglobal/safe-config-service:latest diff --git a/Dockerfile b/Dockerfile index 1cc5ce45..52f9b031 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,10 +2,14 @@ FROM python:3.12.2-slim # python ENV PYTHONUNBUFFERED=1 - ENV PYTHONUSERBASE=/python-deps ENV PATH="${PATH}:${PYTHONUSERBASE}/bin" +ARG VERSION +ARG BUILD_NUMBER +ENV APPLICATION_VERSION=${VERSION} \ + APPLICATION_BUILD_NUMBER=${BUILD_NUMBER} + WORKDIR /app COPY requirements.txt ./ diff --git a/src/about/tests/test_views.py b/src/about/tests/test_views.py index 1f0cc095..49e36fb6 100644 --- a/src/about/tests/test_views.py +++ b/src/about/tests/test_views.py @@ -1,14 +1,31 @@ +from django.test import override_settings from django.urls import reverse +from faker import Faker from rest_framework import status from rest_framework.test import APITestCase +faker = Faker() + +def generate_semver( + min_major=0, max_major=10, min_minor=0, max_minor=10, min_patch=0, max_patch=10 +): + major = faker.random_int(min=min_major, max=max_major) + minor = faker.random_int(min=min_minor, max=max_minor) + patch = faker.random_int(min=min_patch, max=max_patch) + return f"{major}.{minor}.{patch}" + + +semver = generate_semver() + + +@override_settings(APPLICATION_VERSION=semver) class AboutJsonPayloadFormatViewTests(APITestCase): def test_json_payload_format(self): url = reverse("v1:about:detail") expected_json_response = { "name": "Safe Config Service", - "version": "2.75.0", + "version": semver, "apiVersion": "v1", "secure": False, } @@ -19,12 +36,13 @@ def test_json_payload_format(self): self.assertEqual(response.json(), expected_json_response) +@override_settings(APPLICATION_VERSION=semver) class AboutSecureRequestViewTests(APITestCase): def test_https_request(self): url = reverse("v1:about:detail") expected_json_response = { "name": "Safe Config Service", - "version": "2.75.0", + "version": semver, "api_version": "v1", "secure": True, } @@ -38,7 +56,7 @@ def test_http_request(self): url = reverse("v1:about:detail") expected_json_response = { "name": "Safe Config Service", - "version": "2.75.0", + "version": semver, "api_version": "v1", "secure": False, } diff --git a/src/about/views.py b/src/about/views.py index 30350f11..6538331a 100644 --- a/src/about/views.py +++ b/src/about/views.py @@ -1,14 +1,15 @@ +from django.conf import settings from rest_framework.response import Response from rest_framework.views import APIView -from version import __name__, __version__ +from version import __name__ class AboutView(APIView): def get(self, request, format=None): response = { "name": __name__, - "version": __version__, + "version": settings.APPLICATION_VERSION, "api_version": self.request.version, "secure": self.request.is_secure(), } diff --git a/src/config/settings.py b/src/config/settings.py index f4c465ec..a8ba2887 100644 --- a/src/config/settings.py +++ b/src/config/settings.py @@ -36,6 +36,9 @@ # Application definition +APPLICATION_VERSION = os.getenv("APPLICATION_VERSION") +APPLICATION_BUILD_NUMBER = os.getenv("APPLICATION_BUILD_NUMBER") + REST_FRAMEWORK = { # https://www.django-rest-framework.org/api-guide/renderers/ "DEFAULT_RENDERER_CLASSES": [ diff --git a/src/version.py b/src/version.py index 323768c7..9ad57f2c 100644 --- a/src/version.py +++ b/src/version.py @@ -1,2 +1 @@ __name__ = "Safe Config Service" -__version__ = "2.75.0"