diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,13 @@
 # Revision history for releaser
 
+## 0.3.0.2 -- 2023-11-01
+
+* New primitive `assertCommandExists`
+
+* Make sure `git` and `cabal` are available before `releaser` does anything
+
+* Primitive: `assertBasicCommands`, to perform the above check in custom scripts.
+
 ## 0.3.0.1 -- 2023-10-31
 
 * Repo is now [github.com/hercules-ci/haskell-releaser](https://github.com/hercules-ci/haskell-releaser)
diff --git a/releaser.cabal b/releaser.cabal
--- a/releaser.cabal
+++ b/releaser.cabal
@@ -1,7 +1,7 @@
 cabal-version: 2.4
 name: releaser
 synopsis: Automation of Haskell package release process
-version: 0.3.0.1
+version: 0.3.0.2
 license: Apache-2.0
 license-file: LICENSE
 maintainer: info@hercules-ci.com
@@ -23,6 +23,7 @@
     build-depends:
         base >=4.7 && <5,
         bytestring,
+        directory,
         Cabal >=3.6,
         regex-tdfa -any,
         process -any,
diff --git a/releaser/Main.hs b/releaser/Main.hs
--- a/releaser/Main.hs
+++ b/releaser/Main.hs
@@ -8,6 +8,8 @@
   hSetBuffering stdout LineBuffering
   hSetBuffering stderr LineBuffering
 
+  assertBasicCommands
+
   -- prepare release
   -- TODO: pass a list directories
   gitAssertEmptyStaging
diff --git a/src/Releaser/Primitives.hs b/src/Releaser/Primitives.hs
--- a/src/Releaser/Primitives.hs
+++ b/src/Releaser/Primitives.hs
@@ -23,13 +23,18 @@
     abort,
     logStep,
     changelogPrepare,
+    -- checks
+    assertBasicCommands,
+    assertCommandExists,
   )
 where
 
+import Control.Monad (when)
 import qualified Data.ByteString as BS
 import Data.Foldable (toList)
 import Data.Functor (void)
 import Data.List (intercalate)
+import Data.Maybe (isNothing)
 import qualified Data.Text as T
 import qualified Data.Text.IO as T
 import Data.Version (parseVersion)
@@ -43,6 +48,7 @@
 import Distribution.Types.Version (mkVersion', versionNumbers)
 import Distribution.Verbosity (Verbosity, normal, silent)
 import System.Console.Pretty (Color (..), color)
+import System.Directory (findExecutable)
 import System.Environment (lookupEnv)
 import System.Exit (ExitCode (..), exitFailure)
 import System.IO
@@ -238,3 +244,14 @@
   case exitcode of
     ExitSuccess -> return ()
     ExitFailure i -> bad i
+
+assertCommandExists :: String -> IO ()
+assertCommandExists cmd = do
+  exe <- findExecutable cmd
+  when (isNothing exe) $ do
+    abort $ "Command not found: " <> cmd <> ". Make sure it's available in your environment (e.g. nix shell, direnv) or install it."
+
+assertBasicCommands :: IO ()
+assertBasicCommands = do
+  assertCommandExists "git"
+  assertCommandExists "cabal"
