diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index badf33f0d073c001e0e1616b21296912954af4be..8d2e2c7cdd208fd6f9fcc07228c37190cf3b0a91 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -527,7 +527,8 @@ xenon:
 shellcheck:
   stage: static-analysis
   script:
-#     TODO(Corne): Ignore shell files in submodules
+#     TODO(Corne): L2SS-962: Ignore shell files in submodules
+    - shellcheck --version
     - shellcheck **/*.sh
 sphinx-documentation:
   stage: documentation
diff --git a/tangostationcontrol/tox.ini b/tangostationcontrol/tox.ini
index 1431b618acbd0dcb0b3dfbdb412bf874c811ac2d..52d27b6eae221651e0c526a3e09552cb6129168e 100644
--- a/tangostationcontrol/tox.ini
+++ b/tangostationcontrol/tox.ini
@@ -24,7 +24,11 @@ deps =
     -r{toxinidir}/requirements.txt
     -r{toxinidir}/../docker-compose/lofar-device-base/lofar-requirements.txt
     -r{toxinidir}/test-requirements.txt
-commands = {envpython} -m stestr run {posargs}
+commands_pre =
+    {envpython} --version
+commands =
+    {envpython} -m stestr --version
+    {envpython} -m stestr run {posargs}
 
 [testenv:integration]
 ; Warning running integration tests will make changes to your docker system!
@@ -37,6 +41,8 @@ setenv =
     PYTHON={envpython} -m coverage run --source tangostationcontrol --parallel-mode
 commands =
     echo "Integration test directory configured for{env:TESTS_DIR} ({env:TEST_MODULE:default})"
+    {envpython} -m stestr --version
+    {envpython} -m coverage --version
     {envpython} -m stestr run --serial {posargs}
     {envpython} -m coverage combine
     {envpython} -m coverage html --omit='*test*' -d cover
@@ -54,16 +60,20 @@ deps =
     -r{toxinidir}/../docker-compose/lofar-device-base/lofar-requirements.txt
     -r{toxinidir}/test-requirements.txt
 commands =
-  {envpython} -m coverage erase
-  {envpython} -m stestr run {posargs}
-  {envpython} -m coverage combine
-  {envpython} -m coverage html --omit='*test*' -d cover
-  {envpython} -m coverage xml -o coverage.xml
-  {envpython} -m coverage report --omit='*test*'
+    {envpython} -m stestr --version
+    {envpython} -m coverage --version
+    {envpython} -m coverage erase
+    {envpython} -m stestr run {posargs}
+    {envpython} -m coverage combine
+    {envpython} -m coverage html --omit='*test*' -d cover
+    {envpython} -m coverage xml -o coverage.xml
+    {envpython} -m coverage report --omit='*test*'
 
 ; TODO(Corne): Integrate Hacking to customize pep8 rules
 [testenv:pep8]
 commands =
+    {envpython} -m doc8 --version
+    {envpython} -m flake8 --version
     {envpython} -m doc8 docs/source/ --ignore D001
     {envpython} -m flake8
 
@@ -73,18 +83,21 @@ commands =
 ;             It thus matters what interfaces Docker will bind our
 ;             containers to, not what our containers listen on.
 commands =
+    {envpython} -m bandit --version
     {envpython} -m bandit -r devices/ -n5 -ll -s B104
 
 [testenv:xenon];
 commands =
-     {envpython} -m xenon tangostationcontrol -b B -m A -a A -i libhdbpp-python
+    {envpython} -m xenon --version
+    {envpython} -m xenon tangostationcontrol -b B -m A -a A -i libhdbpp-python
 
 [testenv:docs]
 deps =
     -r{toxinidir}/../docker-compose/lofar-device-base/lofar-requirements.txt
     -r{toxinidir}/docs/docs-requirements.txt
 commands =
-     sphinx-build -W -b html docs/source docs/build/html
+    sphinx-build --version
+    sphinx-build -W -b html docs/source docs/build/html
 
 [flake8]
 filename = *.py,.stestr.conf,.txt