diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index bed8045a99885ba83ec971d683e608220fac9ad8..506d74a1665c2d7b657f647a03053cb2d2b030ea 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -14,47 +14,97 @@ yamllint:
   variables:
     CHANGES: "{.gitlab-ci.yml,webhook/{common,defs,graphql,libbz,libjira,owners,rh_metadata,session,session_events}.py,utils/{labels,rh_metadata,rh_webhooks}.yaml}"
     SUPPORTS_STAGING: 'true'
+    SMOKE_TEST_COMMANDS_ACK_NACK: |
+      python3 -m webhook.ack_nack --help
+      python3 -m webhook.utils.owners_validator --help
+      python3 -m webhook.utils.update_git_mirror --help
+      python3 -m webhook.utils.update_owners --help
+    SMOKE_TEST_COMMANDS_FIXES: |
+      python3 -m webhook.fixes --help
+      python3 -m webhook.utils.check_for_fixes --help
+      python3 -m webhook.utils.update_git_mirror --help
+    SMOKE_TEST_COMMANDS_MERGEHOOK: |
+      python3 -m webhook.mergehook --help
+      python3 -m webhook.utils.merge_conflicts_check --help
+      python3 -m webhook.utils.report_generator --help
+      python3 -m webhook.utils.update_git_mirror --help
+      python3 -m webhook.utils.update_owners --help
+    SMOKE_TEST_COMMANDS_SUBSYSTEMS: |
+      python3 -m webhook.subsystems --help
+      python3 -m webhook.utils.update_git_mirror --help
+      python3 -m webhook.utils.update_kernel_watch --help
+      python3 -m webhook.utils.update_owners --help
   parallel:
     matrix:
       - IMAGE_NAME: ack-nack
         CHANGES_EXTRA: "{webhook/{ack_nack,base_mr,cdlib,libjira,utils},utils/*}"
+        SMOKE_TEST_COMMANDS_VARIABLE: SMOKE_TEST_COMMANDS_ACK_NACK
       - IMAGE_NAME: backporter
         CHANGES_EXTRA: "{webhook/{rhissue,libbackport,kgit}.py,webhook/util/backporter.py,utils/*.yml}"
+        SMOKE_TEST_COMMANDS: |
+          python3 -m webhook.utils.backporter --help
+          python3 -m webhook.utils.update_git_mirror --help
       - IMAGE_NAME: buglinker
         CHANGES_EXTRA: "webhook/{buglinker,description,libjira,rhissue,pipelines}"
+        SMOKE_TEST_COMMANDS: |
+          python3 -m webhook.buglinker --help
       - IMAGE_NAME: ckihook
         CHANGES_EXTRA: "{webhook/{ckihook,base_mr,fragments,description,users},templates}"
+        SMOKE_TEST_COMMANDS: |
+          python3 -m webhook.ckihook --help
       - IMAGE_NAME: commit-compare
         CHANGES_EXTRA: "{webhook/{commit_compare,cdlib,utils},utils/upstream_kernel_git_repos.yml}"
+        SMOKE_TEST_COMMANDS: |
+          python3 -m webhook.commit_compare --help
+          python3 -m webhook.utils.update_git_mirror --help
       - IMAGE_NAME: component-webview
         CHANGES_EXTRA: "webhook/component_webview"
       - IMAGE_NAME: fixes
         CHANGES_EXTRA: "webhook/{fixes,base_mr,cdlib,utils}"
+        SMOKE_TEST_COMMANDS_VARIABLE: SMOKE_TEST_COMMANDS_FIXES
       - IMAGE_NAME: jirahook
         CHANGES_EXTRA: "webhook/{jirahook,cpc,rhissue,rhissue_tests,description,fragments,libjira,table}"
+        SMOKE_TEST_COMMANDS: |
+          python3 -m webhook.jirahook --help
       - IMAGE_NAME: mergehook
         CHANGES_EXTRA: "webhook/{mergehook,utils},utils/*"
+        SMOKE_TEST_COMMANDS_VARIABLE: SMOKE_TEST_COMMANDS_MERGEHOOK
       - IMAGE_NAME: metrics
         CHANGES_EXTRA: "webhook/metrics"
+        SMOKE_TEST_COMMANDS: |
+          python3 -m webhook.metrics --help
       - IMAGE_NAME: kwf-utils
         CHANGES_EXTRA: "webhook/utils"
       - IMAGE_NAME: sast
         CHANGES_EXTRA: "webhook/{sast,base_mr,base_mr_mixins}"
+        SMOKE_TEST_COMMANDS: |
+          python3 -m webhook.sast --help
       - IMAGE_NAME: signoff
         CHANGES_EXTRA: "webhook/{signoff,base_mr,fragments,description,users}"
+        SMOKE_TEST_COMMANDS: |
+          python3 -m webhook.signoff --help
       - IMAGE_NAME: limited-ci
         CHANGES_EXTRA: "webhook/limited_ci.py"
+        SMOKE_TEST_COMMANDS: |
+          python3 -m webhook.limited_ci --help
       - IMAGE_NAME: sprinter
         CHANGES_EXTRA: "webhook/sprinter.py"
+        SMOKE_TEST_COMMANDS: |
+          python3 -m webhook.sprinter --help
       - IMAGE_NAME: subsystems
         CHANGES_EXTRA: "{webhook/{subsystems,base_mr,cdlib,utils},utils/upstream_subsystems_repo.yml}"
+        SMOKE_TEST_COMMANDS_VARIABLE: SMOKE_TEST_COMMANDS_SUBSYSTEMS
       - IMAGE_NAME: umb-bridge
         CHANGES_EXTRA: "webhook/{umb_bridge,description,users}"
+        SMOKE_TEST_COMMANDS: |
+          python3 -m webhook.umb_bridge --help
       - IMAGE_NAME: terminator
         CHANGES_EXTRA: "webhook/terminator.py"
+        SMOKE_TEST_COMMANDS: |
+          python3 -m webhook.terminator --help
 
-publish:
-  extends: [.publish, .images]
+build:
+  extends: [.build, .images]
 
 tag:
   extends: [.tag, .images]
diff --git a/webhook/limited_ci.py b/webhook/limited_ci.py
index 112ef15ec0319488fb2660cfdfa01cfe2115006e..24a3cb18f5016e12276dafd160553be2eb7722c9 100644
--- a/webhook/limited_ci.py
+++ b/webhook/limited_ci.py
@@ -1,6 +1,5 @@
 """Event handlers."""
 import copy
-import sys
 from time import sleep
 import typing
 
@@ -330,16 +329,16 @@ HANDLERS = {
 }
 
 
-def main(args):
+def main(args: list[str] | None = None) -> None:
     """Set up and start consuming messages or handle manual requests."""
-    load_config(cki_lib.misc.get_env_var_or_raise('CONFIG_PATH'))
-
     parser = common.get_arg_parser('LIMITED_CI')
-    args = parser.parse_args(args)
-    session = SessionRunner.new('limited_ci', args=args, handlers=HANDLERS)
+    parsed_args = parser.parse_args(args)
+
+    load_config(cki_lib.misc.get_env_var_or_raise('CONFIG_PATH'))
+    session = SessionRunner.new('limited_ci', args=parsed_args, handlers=HANDLERS)
 
-    if args.merge_request:
-        namespace, mr_id = common.parse_mr_url(args.merge_request)
+    if parsed_args.merge_request:
+        namespace, mr_id = common.parse_mr_url(parsed_args.merge_request)
         mr_object = session.gl_instance.projects.get(namespace, lazy=True).mergerequests.get(mr_id)
         manual_hook_data = get_manual_hook_data(session.gl_instance, mr_object, namespace)
         faux_event = create_event(session, {'message-type': 'gitlab'}, manual_hook_data)
@@ -347,11 +346,11 @@ def main(args):
         return
 
     # Always run with the bot user check disabled
-    args.disable_user_check = True
+    parsed_args.disable_user_check = True
     # Disable kernel branch checks as we often operate on non-kernel projects.
-    args.disable_inactive_branch_check = True
+    parsed_args.disable_inactive_branch_check = True
     session.run()
 
 
 if __name__ == '__main__':
-    main(sys.argv[1:])
+    main()
diff --git a/webhook/metrics/__init__.py b/webhook/metrics/__init__.py
index 0f5928ee52a773bef1e18441b1d3f98064d0637d..131988f7fa73526e98aa62d15fb99ca1a67c024d 100644
--- a/webhook/metrics/__init__.py
+++ b/webhook/metrics/__init__.py
@@ -1,11 +1,11 @@
 """kmaint metrics."""
+import argparse
 import os
 
 from cki_lib import cronjob
 from cki_lib import misc
 from cki_lib.logger import get_logger
 from cki_lib.metrics import prometheus_init
-import sentry_sdk
 import yaml
 
 from .koji import KojiMetrics
@@ -28,11 +28,11 @@ def get_enabled_metrics():
     ]
 
 
-def run():
+def run(args: list[str] | None = None) -> None:
     """Loop and update metrics."""
-    misc.sentry_init(sentry_sdk)
-    prometheus_init()
+    parser = argparse.ArgumentParser()
+    parser.parse_args(args)
 
+    prometheus_init()
     enabled_metrics = get_enabled_metrics()
-
     cronjob.run(enabled_metrics, LOOP_PERIOD_S)
diff --git a/webhook/metrics/__main__.py b/webhook/metrics/__main__.py
index 4f2031cc8b1e9dbc88b73089e6b4f17960e9dc20..e10d40022f4a61d78f5b33b2edc87b6cb3b9f78f 100644
--- a/webhook/metrics/__main__.py
+++ b/webhook/metrics/__main__.py
@@ -1,5 +1,9 @@
 """Expose service metrics."""
+from cki_lib import misc
+import sentry_sdk
+
 from . import run
 
 if __name__ == '__main__':
+    misc.sentry_init(sentry_sdk)
     run()