diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -5,6 +5,11 @@
 
 ## [Unreleased]
 
+## [1.2.2] - 2021-04-14
+- Always performing upcase of a token secret #12 (maksar)
+- Simplified build #13
+- Upgraded to latest LTS
+
 ## [1.2.1] - 2020-05-31
 - Upgraded to latest stackage LTS
 
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-[![Build Status](https://travis-ci.org/rkaippully/gamgee.svg?branch=master)](https://travis-ci.org/rkaippully/gamgee)
+[![Build Status](https://img.shields.io/github/workflow/status/rkaippully/gamgee/Haskell%20CI/master)](https://github.com/rkaippully/gamgee/actions?query=workflow%3A%22Haskell+CI%22+branch%3Amaster)
 [![Release](https://img.shields.io/github/release/rkaippully/gamgee.svg)](https://github.com/rkaippully/gamgee/releases)
 [![Hackage](https://img.shields.io/hackage/v/gamgee.svg)](https://hackage.haskell.org/package/gamgee)
 
diff --git a/app/Gamgee/Program/CommandLine.hs b/app/Gamgee/Program/CommandLine.hs
--- a/app/Gamgee/Program/CommandLine.hs
+++ b/app/Gamgee/Program/CommandLine.hs
@@ -41,9 +41,8 @@
 addToken = AddToken <$> tokenSpec
 
 tokenSpec :: Parser Token.TokenSpec
-tokenSpec = Token.TokenSpec
-            <$> pure Token.TOTP
-            <*> strOption (long "label" <> short 'l'
+tokenSpec = Token.TokenSpec Token.TOTP
+            <$> strOption (long "label" <> short 'l'
                            <> help "Label of the token")
             <*> (Token.TokenSecretPlainText <$> strOption (long "secret" <> short 's'
                                                            <> help "Secret of the token"))
diff --git a/gamgee.cabal b/gamgee.cabal
--- a/gamgee.cabal
+++ b/gamgee.cabal
@@ -1,13 +1,7 @@
 cabal-version: 1.12
 
--- This file has been generated from package.yaml by hpack version 0.33.0.
---
--- see: https://github.com/sol/hpack
---
--- hash: 5b2412c7134563a0b717c9d86f64ba764f4eeaba70587cdabef925ac3855e820
-
 name:           gamgee
-version:        1.2.1
+version:        1.2.2
 synopsis:       Tool for generating TOTP MFA tokens.
 description:    Tool for generating TOTP MFA tokens. Please see the README on GitHub at <https://github.com/rkaippully/gamgee#readme>
 category:       Authentication, Command Line
@@ -15,7 +9,7 @@
 bug-reports:    https://github.com/rkaippully/gamgee/issues
 author:         Raghu Kaippully
 maintainer:     rkaippully@gmail.com
-copyright:      2018 Raghu Kaippully
+copyright:      2018-2021 Raghu Kaippully, Alexander Shestakov
 license:        MPL-2.0
 license-file:   LICENSE
 build-type:     Simple
@@ -47,17 +41,17 @@
   default-extensions: ApplicativeDo BangPatterns ConstraintKinds DataKinds DefaultSignatures DeriveAnyClass DeriveFoldable DeriveFunctor DeriveGeneric DeriveLift DeriveTraversable DerivingStrategies EmptyCase ExistentialQuantification FlexibleContexts FlexibleInstances FunctionalDependencies GADTs GeneralizedNewtypeDeriving InstanceSigs KindSignatures LambdaCase MultiParamTypeClasses MultiWayIf NamedFieldPuns NoImplicitPrelude OverloadedStrings PatternSynonyms PolyKinds RankNTypes ScopedTypeVariables StandaloneDeriving TemplateHaskell TupleSections TypeApplications TypeFamilies TypeFamilyDependencies TypeOperators
   ghc-options: -Wall -Wcompat -Wredundant-constraints -Wincomplete-record-updates -Wincomplete-uni-patterns
   build-depends:
-      aeson >=1.4.4.0 && <1.5
-    , base >=4.13.0.0 && <4.14
-    , base64-bytestring >=1.0.0.2 && <1.1
-    , bytestring >=0.10.8.2 && <0.11
-    , cryptonite >=0.26 && <0.27
-    , memory >=0.15.0 && <0.16
-    , polysemy >=1.2.3.0 && <1.3
-    , relude >=0.6.0.0 && <0.7
-    , safe-exceptions >=0.1.7.0 && <0.2
-    , text >=1.2.3.1 && <1.3
-    , time >=1.9.3 && <1.10
+      aeson ==1.5.6.0
+    , base ==4.14.1.0
+    , base64-bytestring ==1.1.0.0
+    , bytestring ==0.10.12.0
+    , cryptonite ==0.27
+    , memory ==0.15.0
+    , polysemy ==1.5.0.0
+    , relude ==0.7.0.0
+    , safe-exceptions ==0.1.7.1
+    , text ==1.2.4.1
+    , time ==1.9.3
   default-language: Haskell2010
 
 executable gamgee
@@ -72,18 +66,18 @@
   ghc-options: -Wall -Wcompat -Wredundant-constraints -Wincomplete-record-updates -Wincomplete-uni-patterns -threaded -rtsopts -with-rtsopts=-N
   build-depends:
       Hclip ==3.0.0.4
-    , aeson >=1.4.4.0 && <1.5
-    , base >=4.13.0.0 && <4.14
-    , directory >=1.3.3.0 && <1.4
-    , filepath >=1.4.2.1 && <1.5
+    , aeson ==1.5.6.0
+    , base ==4.14.1.0
+    , directory ==1.3.6.0
+    , filepath ==1.4.2.1
     , gamgee
-    , optparse-applicative >=0.15.1.0 && <0.16
-    , polysemy >=1.2.3.0 && <1.3
-    , relude >=0.6.0.0 && <0.7
-    , safe-exceptions >=0.1.7.0 && <0.2
-    , text >=1.2.3.1 && <1.3
-    , time >=1.9.3 && <1.10
-    , unix >=2.7.2.2 && <2.8
+    , optparse-applicative ==0.15.1.0
+    , polysemy ==1.5.0.0
+    , relude ==0.7.0.0
+    , safe-exceptions ==0.1.7.1
+    , text ==1.2.4.1
+    , time ==1.9.3
+    , unix ==2.7.2.2
   default-language: Haskell2010
 
 test-suite gamgee-test
@@ -100,20 +94,20 @@
   default-extensions: ApplicativeDo BangPatterns ConstraintKinds DataKinds DefaultSignatures DeriveAnyClass DeriveFoldable DeriveFunctor DeriveGeneric DeriveLift DeriveTraversable DerivingStrategies EmptyCase ExistentialQuantification FlexibleContexts FlexibleInstances FunctionalDependencies GADTs GeneralizedNewtypeDeriving InstanceSigs KindSignatures LambdaCase MultiParamTypeClasses MultiWayIf NamedFieldPuns NoImplicitPrelude OverloadedStrings PatternSynonyms PolyKinds RankNTypes ScopedTypeVariables StandaloneDeriving TemplateHaskell TupleSections TypeApplications TypeFamilies TypeFamilyDependencies TypeOperators
   ghc-options: -Wall -Wcompat -Wredundant-constraints -Wincomplete-record-updates -Wincomplete-uni-patterns -threaded -rtsopts -with-rtsopts=-N
   build-depends:
-      QuickCheck >=2.13.2 && <2.14
-    , aeson >=1.4.4.0 && <1.5
-    , base >=4.13.0.0 && <4.14
-    , bytestring >=0.10.8.2 && <0.11
-    , cryptonite >=0.26 && <0.27
-    , filepath >=1.4.2.1 && <1.5
+      QuickCheck ==2.14.2
+    , aeson ==1.5.6.0
+    , base ==4.14.1.0
+    , bytestring ==0.10.12.0
+    , cryptonite ==0.27
+    , filepath ==1.4.2.1
     , gamgee
-    , memory >=0.15.0 && <0.16
-    , polysemy >=1.2.3.0 && <1.3
-    , quickcheck-instances >=0.3.22 && <0.4
-    , relude >=0.6.0.0 && <0.7
-    , tasty >=1.2.3 && <1.3
-    , tasty-golden >=2.3.2 && <2.4
-    , tasty-quickcheck >=0.10.1 && <0.11
-    , text >=1.2.3.1 && <1.3
-    , time >=1.9.3 && <1.10
+    , memory ==0.15.0
+    , polysemy ==1.5.0.0
+    , quickcheck-instances ==0.3.25.2
+    , relude ==0.7.0.0
+    , tasty ==1.2.3
+    , tasty-golden ==2.3.3.2
+    , tasty-quickcheck ==0.10.1.2
+    , text ==1.2.4.1
+    , time ==1.9.3
   default-language: Haskell2010
diff --git a/src/Gamgee/Effects/Crypto.hs b/src/Gamgee/Effects/Crypto.hs
--- a/src/Gamgee/Effects/Crypto.hs
+++ b/src/Gamgee/Effects/Crypto.hs
@@ -62,14 +62,14 @@
       -- Ask the user for a password
       password <- SI.secretInput "Password to encrypt (leave blank to skip encryption): "
 
-      if Text.null password
-      then return spec
-      else do
-        -- Sometimes the secret may contain extraneous chars - '=', '-', space etc. Clear those.
-        let secret = (Text.toUpper . Text.dropWhileEnd (== '=') . Text.replace " " "" . Text.replace "-" "" . Text.strip) plainSecret
+      -- Sometimes the secret may contain extraneous chars - '=', '-', space etc. Clear those.
+      let secret = (Text.toUpper . Text.dropWhileEnd (== '=') . Text.replace " " "" . Text.replace "-" "" . Text.strip) plainSecret
 
-        secret' <- encrypt secret password
-        return spec { Token.tokenSecret = secret' }
+      secret' <- if Text.null password
+                 then pure $ Token.TokenSecretPlainText secret
+                 else encrypt secret password
+
+      return spec { Token.tokenSecret = secret' }
 
 decryptSecret :: Members [SI.SecretInput Text, Crypto] r
               => Token.TokenSpec
diff --git a/src/Gamgee/Effects/TOTP.hs b/src/Gamgee/Effects/TOTP.hs
--- a/src/Gamgee/Effects/TOTP.hs
+++ b/src/Gamgee/Effects/TOTP.hs
@@ -44,7 +44,7 @@
 runTOTP :: Members [SecretInput Text, Crypto, P.Error Err.EffError] r => Sem (TOTP : r) a -> Sem r a
 runTOTP = P.interpret $ \case
   GetSecret spec    -> snd <$> retrieveKeyAndSecret spec
-  GetTOTP spec time -> fst <$> retrieveKeyAndSecret spec >>= computeTOTP spec time
+  GetTOTP spec time -> retrieveKeyAndSecret spec >>= computeTOTP spec time . fst
 
 retrieveKeyAndSecret :: Members [SecretInput Text, Crypto, P.Error Err.EffError] r
                      => Token.TokenSpec
diff --git a/src/Gamgee/Operation.hs b/src/Gamgee/Operation.hs
--- a/src/Gamgee/Operation.hs
+++ b/src/Gamgee/Operation.hs
@@ -99,5 +99,5 @@
     Nothing   -> P.throw $ Eff.NoSuchToken ident
     Just spec -> do
       secret <- Eff.getSecret spec
-      spec' <- Eff.encryptSecret spec{ Token.tokenSecret = Token.TokenSecretPlainText secret }
+      spec' <- Eff.encryptSecret spec { Token.tokenSecret = Token.TokenSecretPlainText secret }
       P.put $ Map.insert ident spec' tokens
diff --git a/test/Gamgee/Test/Property.hs b/test/Gamgee/Test/Property.hs
--- a/test/Gamgee/Test/Property.hs
+++ b/test/Gamgee/Test/Property.hs
@@ -47,9 +47,8 @@
   arbitrary = Token.TokenPeriod <$> T.choose (10, 120)
 
 instance T.Arbitrary Token.TokenSpec where
-  arbitrary = Token.TokenSpec
-              <$> pure Token.TOTP
-              <*> T.arbitrary
+  arbitrary = Token.TokenSpec Token.TOTP
+              <$> T.arbitrary
               <*> T.arbitrary
               <*> T.arbitrary
               <*> T.arbitrary
