From acebf939d80503d1b1fd964135646d06c7d0cb04 Mon Sep 17 00:00:00 2001 From: Matthew Elwell Date: Thu, 13 Jul 2023 10:02:26 +0100 Subject: [PATCH] feat: Bake enterprise version info into private cloud image (#2420) * Bake enterprise version info into private cloud image * formatting --- ...form-docker-publish-all-features-image.yml | 1 + api/app/urls.py | 2 +- api/app/utils.py | 18 +++++----- api/app/views.py | 3 +- api/tests/unit/app/__init__.py | 0 api/tests/unit/app/test_unit_app_utils.py | 33 +++++++++++++++++++ api/tests/unit/app/test_unit_app_views.py | 19 +++++++++++ 7 files changed, 66 insertions(+), 10 deletions(-) create mode 100644 api/tests/unit/app/__init__.py create mode 100644 api/tests/unit/app/test_unit_app_utils.py create mode 100644 api/tests/unit/app/test_unit_app_views.py diff --git a/.github/workflows/platform-docker-publish-all-features-image.yml b/.github/workflows/platform-docker-publish-all-features-image.yml index 1ee259502f0e..f103a98f4442 100644 --- a/.github/workflows/platform-docker-publish-all-features-image.yml +++ b/.github/workflows/platform-docker-publish-all-features-image.yml @@ -62,6 +62,7 @@ jobs: cd api echo ${{ github.sha }} > CI_COMMIT_SHA echo '${{ steps.meta.outputs.tags }}' > IMAGE_TAG + echo '' > ENTERPRISE_VERSION - name: Docker metadata id: meta diff --git a/api/app/urls.py b/api/app/urls.py index 46f084f8e0dd..fa38b8d7603a 100644 --- a/api/app/urls.py +++ b/api/app/urls.py @@ -15,7 +15,7 @@ url(r"^api/v1/", include("api.urls.v1", namespace="api-v1")), url(r"^admin/", admin.site.urls), url(r"^health", include("health_check.urls", namespace="health")), - url(r"^version", views.version_info), + url(r"^version", views.version_info, name="version-info"), url( r"^sales-dashboard/", include("sales_dashboard.urls", namespace="sales_dashboard"), diff --git a/api/app/utils.py b/api/app/utils.py index baaef7e9401b..4b223cf6ec0c 100644 --- a/api/app/utils.py +++ b/api/app/utils.py @@ -8,19 +8,21 @@ def create_hash(): return shortuuid.uuid() -def get_version_info(): +def get_version_info() -> dict: """Reads the version info baked into src folder of the docker container""" version_json = { - "ci_commit_sha": get_file("./CI_COMMIT_SHA"), - "image_tag": get_file("./IMAGE_TAG"), + "ci_commit_sha": _get_file_contents("./CI_COMMIT_SHA"), + "image_tag": _get_file_contents("./IMAGE_TAG"), + "is_enterprise": pathlib.Path("./ENTERPRISE_VERSION").exists(), } return version_json -def get_file(file_path): +def _get_file_contents(file_path: str) -> str: """Attempts to read a file from the filesystem and return the contents""" - if pathlib.Path(file_path).is_file(): - return open(file_path).read().replace("\n", "") - - return "unknown" + try: + with open(file_path) as f: + return f.read().replace("\n", "") + except FileNotFoundError: + return "unknown" diff --git a/api/app/views.py b/api/app/views.py index 56e8bbdd167d..e968b96ec384 100644 --- a/api/app/views.py +++ b/api/app/views.py @@ -5,13 +5,14 @@ from django.http import HttpResponse, JsonResponse from django.template import loader from django.views.decorators.csrf import csrf_exempt +from rest_framework.request import Request from . import utils logger = logging.getLogger(__name__) -def version_info(request): +def version_info(request: Request) -> JsonResponse: return JsonResponse(utils.get_version_info()) diff --git a/api/tests/unit/app/__init__.py b/api/tests/unit/app/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/api/tests/unit/app/test_unit_app_utils.py b/api/tests/unit/app/test_unit_app_utils.py new file mode 100644 index 000000000000..bc4a68334045 --- /dev/null +++ b/api/tests/unit/app/test_unit_app_utils.py @@ -0,0 +1,33 @@ +import pathlib + +from pytest_mock import MockerFixture + +from app.utils import get_version_info + + +def test_get_version_info(mocker: MockerFixture) -> None: + # Given + mocked_pathlib = mocker.patch("app.utils.pathlib") + + def path_side_effect(file_path: str) -> mocker.MagicMock: + mocked_path_object = mocker.MagicMock(spec=pathlib.Path) + + if file_path == "./ENTERPRISE_VERSION": + mocked_path_object.exists.return_value = True + + return mocked_path_object + + mocked_pathlib.Path.side_effect = path_side_effect + + mock_get_file_contents = mocker.patch("app.utils._get_file_contents") + mock_get_file_contents.side_effect = ("some_sha", "v1.0.0") + + # When + result = get_version_info() + + # Then + assert result == { + "ci_commit_sha": "some_sha", + "image_tag": "v1.0.0", + "is_enterprise": True, + } diff --git a/api/tests/unit/app/test_unit_app_views.py b/api/tests/unit/app/test_unit_app_views.py new file mode 100644 index 000000000000..f59463ceca0c --- /dev/null +++ b/api/tests/unit/app/test_unit_app_views.py @@ -0,0 +1,19 @@ +from django.urls import reverse +from rest_framework import status +from rest_framework.test import APIClient + + +def test_get_version_info(api_client: APIClient) -> None: + # Given + url = reverse("version-info") + + # When + response = api_client.get(url) + + # Then + assert response.status_code == status.HTTP_200_OK + assert response.json() == { + "ci_commit_sha": "unknown", + "image_tag": "unknown", + "is_enterprise": False, + }