Skip to content

Commit fc16eca

Browse files
authored
Merge pull request #743 from maykinmedia/feature/728-version-number
[#728] Add endpoint with version number
2 parents 605729e + 4bad04a commit fc16eca

File tree

10 files changed

+148
-25
lines changed

10 files changed

+148
-25
lines changed

backend/requirements/base.in

+2-1
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,5 @@ celery
3939
zgw-consumers[setup-configuration]
4040
furl
4141
python-slugify
42-
XlsxWriter
42+
XlsxWriter
43+
GitPython

backend/requirements/base.txt

+6
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,10 @@ furl==2.1.3
161161
# via
162162
# -r requirements/base.in
163163
# ape-pie
164+
gitdb==4.0.12
165+
# via gitpython
166+
gitpython==3.1.44
167+
# via -r requirements/base.in
164168
glom==23.5.0
165169
# via mozilla-django-oidc-db
166170
idna==3.7
@@ -256,6 +260,8 @@ six==1.16.0
256260
# furl
257261
# orderedmultidict
258262
# python-dateutil
263+
smmap==5.0.2
264+
# via gitdb
259265
sqlparse==0.5.0
260266
# via django
261267
text-unidecode==1.3

backend/requirements/ci.txt

+14
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,15 @@ furl==2.1.3
313313
# -c requirements/base.txt
314314
# -r requirements/base.txt
315315
# ape-pie
316+
gitdb==4.0.12
317+
# via
318+
# -c requirements/base.txt
319+
# -r requirements/base.txt
320+
# gitpython
321+
gitpython==3.1.44
322+
# via
323+
# -c requirements/base.txt
324+
# -r requirements/base.txt
316325
glom==23.5.0
317326
# via
318327
# -c requirements/base.txt
@@ -573,6 +582,11 @@ six==1.16.0
573582
# furl
574583
# orderedmultidict
575584
# python-dateutil
585+
smmap==5.0.2
586+
# via
587+
# -c requirements/base.txt
588+
# -r requirements/base.txt
589+
# gitdb
576590
snowballstemmer==2.2.0
577591
# via sphinx
578592
soupsieve==2.5

backend/requirements/dev.txt

+15-6
Original file line numberDiff line numberDiff line change
@@ -367,10 +367,16 @@ furl==2.1.3
367367
# -c requirements/ci.txt
368368
# -r requirements/ci.txt
369369
# ape-pie
370-
gitdb==4.0.11
371-
# via gitpython
372-
gitpython==3.1.43
373-
# via -r requirements/dev.in
370+
gitdb==4.0.12
371+
# via
372+
# -c requirements/ci.txt
373+
# -r requirements/ci.txt
374+
# gitpython
375+
gitpython==3.1.44
376+
# via
377+
# -c requirements/ci.txt
378+
# -r requirements/ci.txt
379+
# -r requirements/dev.in
374380
glom==23.5.0
375381
# via
376382
# -c requirements/ci.txt
@@ -711,8 +717,11 @@ six==1.16.0
711717
# furl
712718
# orderedmultidict
713719
# python-dateutil
714-
smmap==5.0.1
715-
# via gitdb
720+
smmap==5.0.2
721+
# via
722+
# -c requirements/ci.txt
723+
# -r requirements/ci.txt
724+
# gitdb
716725
snowballstemmer==2.2.0
717726
# via
718727
# -c requirements/ci.txt

backend/src/openarchiefbeheer/api/urls.py

+2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
from openarchiefbeheer.accounts.api.views import UsersView, WhoAmIView
1111
from openarchiefbeheer.config.api.views import (
12+
ApplicationInfoView,
1213
ArchiveConfigView,
1314
HealthCheckView,
1415
OIDCInfoView,
@@ -123,6 +124,7 @@
123124
name="users",
124125
),
125126
path("whoami/", WhoAmIView.as_view(), name="whoami"),
127+
path("app-info/", ApplicationInfoView.as_view(), name="app-info"),
126128
path(
127129
"destruction-list-statuses/",
128130
ListStatusesListView.as_view(),

backend/src/openarchiefbeheer/conf/base.py

+8-17
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from celery.schedules import crontab
99
from corsheaders.defaults import default_headers
1010

11-
from .utils import config, get_sentry_integrations
11+
from .utils import config, get_git_sha, get_release, get_sentry_integrations
1212

1313
# Build paths inside the project, so further paths can be defined relative to
1414
# the code root.
@@ -378,26 +378,17 @@
378378
# multiple login urls defined.
379379
LOGIN_URLS = [reverse_lazy("admin:login")]
380380

381+
381382
if "GIT_SHA" in os.environ:
382383
GIT_SHA = config("GIT_SHA", "")
383-
# in docker (build) context, there is no .git directory
384-
elif (BASE_DIR / ".git").exists():
385-
try:
386-
import git
387-
except ImportError:
388-
GIT_SHA = None
389-
else:
390-
repo = git.Repo(search_parent_directories=True)
391-
try:
392-
GIT_SHA = repo.head.object.hexsha
393-
except (
394-
ValueError
395-
): # on startproject initial runs before any git commits have been made
396-
GIT_SHA = repo.active_branch.name
397384
else:
398-
GIT_SHA = None
385+
GIT_SHA = get_git_sha()
386+
387+
if "RELEASE" in os.environ:
388+
RELEASE = config("RELEASE", "")
389+
else:
390+
RELEASE = get_release() or GIT_SHA
399391

400-
RELEASE = config("RELEASE", GIT_SHA)
401392

402393
REQUESTS_READ_TIMEOUT = config("REQUESTS_READ_TIMEOUT", 30)
403394
# Default (connection timeout, read timeout) for the requests library (in seconds)

backend/src/openarchiefbeheer/conf/utils.py

+35
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,38 @@ def get_sentry_integrations() -> list:
4848
extra.append(celery.CeleryIntegration())
4949

5050
return [*default, *extra]
51+
52+
53+
def get_git_sha() -> str:
54+
from git import InvalidGitRepositoryError, Repo
55+
56+
try:
57+
# in docker (build) context, there is no .git directory
58+
repo = Repo(search_parent_directories=True)
59+
except InvalidGitRepositoryError:
60+
return ""
61+
62+
try:
63+
return repo.head.object.hexsha
64+
except (
65+
ValueError
66+
): # on startproject initial runs before any git commits have been made
67+
return repo.active_branch.name
68+
69+
70+
def get_release() -> str:
71+
from git import InvalidGitRepositoryError, Repo
72+
73+
try:
74+
# in docker (build) context, there is no .git directory
75+
repo = Repo(search_parent_directories=True)
76+
except InvalidGitRepositoryError:
77+
return ""
78+
79+
if not len(repo.tags):
80+
return ""
81+
82+
current_tag = next(
83+
(tag for tag in repo.tags if tag.commit == repo.head.commit), None
84+
)
85+
return current_tag.name if current_tag else ""

backend/src/openarchiefbeheer/config/api/serializers.py

+24
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from django.conf import settings
12
from django.utils.translation import gettext_lazy as _
23

34
from drf_spectacular.utils import extend_schema_field
@@ -52,3 +53,26 @@ def get_login_url(self, config: OpenIDConnectConfig) -> str:
5253

5354
request = self.context.get("request")
5455
return reverse("oidc_authentication_init", request=request)
56+
57+
58+
class ApplicationInfoSerializer(serializers.Serializer):
59+
release = serializers.SerializerMethodField(
60+
label=_("Application version"),
61+
help_text=_(
62+
"This uses the git tag if one is present, otherwise it defaults to the git commit hash. "
63+
"If the commit hash cannot be resolved, it will be empty."
64+
),
65+
)
66+
git_sha = serializers.SerializerMethodField(
67+
label=_("Application git commit hash"),
68+
help_text=_(
69+
"This returns the git commit hash if it can be resolved. "
70+
"Otherwise, it will be empty."
71+
),
72+
)
73+
74+
def get_release(self, data) -> str:
75+
return settings.RELEASE
76+
77+
def get_git_sha(self, data) -> str:
78+
return settings.GIT_SHA

backend/src/openarchiefbeheer/config/api/views.py

+21-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,11 @@
1111

1212
from ..health_checks import is_configuration_complete
1313
from ..models import ArchiveConfig
14-
from .serializers import ArchiveConfigSerializer, OIDCInfoSerializer
14+
from .serializers import (
15+
ApplicationInfoSerializer,
16+
ArchiveConfigSerializer,
17+
OIDCInfoSerializer,
18+
)
1519

1620

1721
class ArchiveConfigView(APIView):
@@ -128,3 +132,19 @@ class HealthCheckView(APIView):
128132
def get(self, request: Request, *args, **kwargs):
129133
results = is_configuration_complete()
130134
return Response(results)
135+
136+
137+
@extend_schema(
138+
tags=["Configuration"],
139+
summary=_("App info"),
140+
description=_("Returns information about the application."),
141+
responses={
142+
200: ApplicationInfoSerializer(),
143+
},
144+
)
145+
class ApplicationInfoView(APIView):
146+
def get(self, request: Request, *args, **kwargs):
147+
serializer = ApplicationInfoSerializer(data={})
148+
serializer.is_valid()
149+
150+
return Response(serializer.data)

backend/src/openarchiefbeheer/config/tests/test_views.py

+21
Original file line numberDiff line numberDiff line change
@@ -190,3 +190,24 @@ def test_health_check(self):
190190

191191
self.assertEqual(response.status_code, status.HTTP_200_OK)
192192
self.assertFalse(response.json()["success"])
193+
194+
195+
@override_settings(RELEASE="1.0.0", GIT_SHA="123")
196+
class ApplicationInfoTests(APITestCase):
197+
def test_not_logged_in(self):
198+
response = self.client.get(reverse("api:app-info"))
199+
200+
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
201+
202+
def test_get_app_info(self):
203+
user = UserFactory.create()
204+
self.client.force_login(user)
205+
206+
response = self.client.get(reverse("api:app-info"))
207+
208+
self.assertEqual(response.status_code, status.HTTP_200_OK)
209+
210+
data = response.json()
211+
212+
self.assertEqual(data["release"], "1.0.0")
213+
self.assertEqual(data["gitSha"], "123")

0 commit comments

Comments
 (0)