packages feed

hapistrano 0.2.1.1 → 0.2.1.2

raw patch · 4 files changed

+195/−24 lines, 4 filesdep ~basePVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependency ranges changed: base

API changes (from Hackage documentation)

- System.Hapistrano: buildScript :: Config -> Maybe FilePath
- System.Hapistrano: deployPath :: Config -> String
- System.Hapistrano: host :: Config -> Maybe String
- System.Hapistrano: releaseFormat :: Config -> ReleaseFormat
- System.Hapistrano: repository :: Config -> String
- System.Hapistrano: restartCommand :: Config -> Maybe String
- System.Hapistrano: revision :: Config -> String
+ System.Hapistrano: [buildScript] :: Config -> Maybe FilePath
+ System.Hapistrano: [deployPath] :: Config -> String
+ System.Hapistrano: [host] :: Config -> Maybe String
+ System.Hapistrano: [releaseFormat] :: Config -> ReleaseFormat
+ System.Hapistrano: [repository] :: Config -> String
+ System.Hapistrano: [restartCommand] :: Config -> Maybe String
+ System.Hapistrano: [revision] :: Config -> String

Files

+ README.md view
@@ -0,0 +1,84 @@+[![Build Status](https://travis-ci.org/stackbuilders/hapistrano.svg?branch=master)](https://travis-ci.org/stackbuilders/hapistrano) [![Hackage version](https://img.shields.io/hackage/v/hapistrano.svg)](http://hackage.haskell.org/package/hapistrano)++# Hapistrano++Hapistrano is a deployment library for Haskell applications similar to+Ruby's [Capistrano](http://capistranorb.com/).++## Purpose++We created Hapistrano because:++* Deploys should be simple, but as close to atomic as possible (eg,+  they shouldn't require much application downtime).+* Rollback should be trivial to achieve to bring the application back+  to the last-deployed state.+* Deploys shouldn't fail because of dependency problems.++## How it Works++Hapistrano (like Capistrano for Ruby) deploys applications to a new+directory marked with a timestamp on the remote host. It creates this+new directory quickly by placing a git repository for caching purposes+on the remote server.++When the build process completes, it switches a symlink to the+'current' release directory, and optionally restarts the web server.++By default, Hapistrano keeps the last five releases on the target host+filesystem and deletes previous releases to avoid filling up the disk.++## Usage++The deploy requires the following environment variables:++* `DEPLOY_PATH` - The root of the deploy target on the remote host+* `HOST` - The target host+* `REPOSITORY` - The origin repository+* `REVISION` - The SHA1 or branch to deploy. If a branch, you will need+  to specify it as origin/branch_name due to the way that the cache+  repo is configured.++The following environment variables are *optional* and affect the+deploy process:++* `BUILD_SCRIPT` - The local path to a file that should be executed on+  the remote server to build the application. The script isn't+  executed verbatim - instead, every line is joined with `&&` so that+  the script aborts if any component fails. See a sample script for a+  clean build of a Haskell/Cabal application in this project under+  [script/clean-build.sh].+* `RESTART_COMMAND` - If you need to restart a remote web server after a+  successful deploy, specify the command that you use in this+  variable. It will be run after both deploy and rollback.++You may want to save the environment variables that you need for your+deploy in a shell script that you `source` before deploy. Make sure+you `export` these variables so that they're available in the shell+after you run the script. For example, you could use the following to+configure your deploy:++    export DEPLOY_PATH="/var/project"+    export HOST="my-app-staging"+    export REPOSITORY="git@github.com:yourorg/yourrepo.com.git"+    export REVISION="origin/staging"+    export BUILD_SCRIPT="/home/you/Code/hapistrano/script/clean-build.sh"+    export RESTART_COMMAND="echo Replace me with your restart command"++After creating a configuration script as above, deploying is as simple as:++    source your-config-script.sh && hap deploy++# License++MIT, see [the LICENSE file](LICENSE).+++# Contributing++Pull requests for modifications to this program are welcome. Fork and+open a PR. Feel free to [email me](mailto:justin@stackbuilders.com) if+you have questions about what may be accepted before working on a PR.++If you're looking for a place to start, you may want to check the+[open issue](https://github.com/stackbuilders/hapistrano/issues).
app/Main.hs view
@@ -1,14 +1,21 @@-module Main where+{-# LANGUAGE RecordWildCards #-} +module Main (main) where+ import qualified System.Hapistrano as Hap import Control.Monad (void)-import System.Environment (getArgs, getEnv) import System.Environment.Compat (lookupEnv)-import System.IO (hPutStrLn, stderr)-import System.Exit (exitFailure)  import System.Hapistrano (ReleaseFormat(..)) +import qualified Control.Monad as Monad+import qualified Data.Maybe as Maybe+import qualified System.Console.GetOpt as GetOpt+import qualified System.Environment as Environment+import qualified System.Exit as Exit+import qualified System.Exit.Compat as Exit+import qualified System.IO as IO+ -- | Rolls back to previous release. rollback :: Hap.Config -> IO () rollback cfg =@@ -36,15 +43,18 @@ -- | Retrieves the configuration from environment variables. configFromEnv :: IO Hap.Config configFromEnv = do-  deployPath     <- getEnv    "DEPLOY_PATH"-  repository     <- getEnv    "REPOSITORY"-  revision       <- getEnv    "REVISION"+  maybeDeployPath <- lookupEnv "DEPLOY_PATH"+  maybeRepository <- lookupEnv "REPOSITORY"+  maybeRevision <- lookupEnv "REVISION" +  deployPath <- maybe (Exit.die (noEnv "DEPLOY_PATH")) return maybeDeployPath+  repository <- maybe (Exit.die (noEnv "REPOSITORY")) return maybeRepository+  revision <- maybe (Exit.die (noEnv "REVISION")) return maybeRevision+   host           <- lookupEnv "HOST"   buildScript    <- lookupEnv "BUILD_SCRIPT"   restartCommand <- lookupEnv "RESTART_COMMAND" -   return Hap.Config { Hap.deployPath     = deployPath                     , Hap.host           = host                     , Hap.releaseFormat  = Short@@ -53,22 +63,85 @@                     , Hap.buildScript    = buildScript                     , Hap.restartCommand = restartCommand                     }+  where+    noEnv env = env ++ " environment variable does not exist" +data HapCommand+  = HapDeploy+  | HapRollback+  deriving Show++parseHapCommand :: String -> Maybe HapCommand+parseHapCommand "deploy" = Just HapDeploy+parseHapCommand "rollback" = Just HapRollback+parseHapCommand _ = Nothing++data HapOptions =+  HapOptions+    { hapCommand :: Maybe HapCommand+    , hapHelp :: Bool+    }+  deriving Show++defaultHapOptions :: HapOptions+defaultHapOptions =+  HapOptions+    { hapCommand = Nothing+    , hapHelp = False+    }++hapOptionDescriptions :: [GetOpt.OptDescr (HapOptions -> HapOptions)]+hapOptionDescriptions =+  [ GetOpt.Option+      ['h']+      ["help"]+      (GetOpt.NoArg (\hapOptions -> hapOptions { hapHelp = True }))+      "Show this help text"++  ]++parseHapOptions :: [String] -> Either String HapOptions+parseHapOptions args =+  case GetOpt.getOpt GetOpt.Permute hapOptionDescriptions args of+    (options, [], []) ->+      Right (foldl (flip id) defaultHapOptions options)++    (options, [command], []) ->+      case parseHapCommand command of+        Nothing ->+          Left ("Invalid argument: " ++ command)++        maybeHC ->+          Right (foldl (flip id) defaultHapOptions {hapCommand = maybeHC} options)++    _ ->+      Left "First argument must be either 'deploy' or 'rollback'."++hapHelpAction :: Maybe HapCommand -> IO ()+hapHelpAction _ =+  putStrLn hapUsage >> Exit.exitSuccess++hapUsage :: String+hapUsage =+  GetOpt.usageInfo hapUsageHeader hapOptionDescriptions++hapUsageHeader :: String+hapUsageHeader =+  "usage: hap [-h | --help] <command>\n"+ main :: IO () main = do-  args <- getArgs-  case args of-    [] -> do-      hPutStrLn stderr-        "First argument must be either 'deploy' or 'rollback'."-      exitFailure+  eitherHapOptions <- fmap parseHapOptions Environment.getArgs -    arg1:_ -> do-      cfg <- configFromEnv+  HapOptions{..} <- either Exit.die return eitherHapOptions -      case arg1 of-        "deploy"   -> deploy cfg-        "rollback" -> rollback cfg-        _ -> do-          hPutStrLn stderr $ "Invalid argument: " ++ arg1-          exitFailure+  Monad.when hapHelp (hapHelpAction hapCommand)++  hapConfiguration <- configFromEnv++  case hapCommand of+    Just HapDeploy -> deploy hapConfiguration++    Just HapRollback -> rollback hapConfiguration++    Nothing -> hapHelpAction Nothing
+ changes.md view
@@ -0,0 +1,13 @@+## Unreleased changes++* Add change log (#23).++## 0.2.1.1++* Fix tests (#31).++## 0.2.1++* Use Stack (#17).+* Clean up package (#20).+* Fix tests (#25).
hapistrano.cabal view
@@ -1,5 +1,5 @@ name:                hapistrano-version:             0.2.1.1+version:             0.2.1.2 synopsis:            A deployment library for Haskell applications description:   .@@ -28,12 +28,13 @@ bug-reports:         https://github.com/stackbuilders/hapistrano/issues build-type:          Simple cabal-version:       >=1.10+extra-source-files:  changes.md README.md  library   hs-source-dirs:      src   exposed-modules:     System.Hapistrano   other-modules:       System.Hapistrano.Types-  build-depends:       base >=4.5 && <4.9+  build-depends:       base >= 4.5 && < 4.10                      , either                      , filepath                      , mtl