SBT deploy plugin
Allows you to setup deploy configuration for your project.
You will be able to deploy your project with deploy-ssh
task
Usage example:
deploy-ssh yourServerName1 yourServerName2 ...
or
deploySsh yourServerName1 yourServerName2 ...
autoplugin (sbt >= 0.13.5)
Please read sbt documentation before start to work with plugin
- Installation
- Configuration
- Configs
- Locations
- Artifacts
- Execute scripts before/after deploy
- Link to task
- Start deploy
Add to your project/plugins.sbt
file:
addSbtPlugin("com.github.shmishleniy" % "sbt-deploy-ssh" % "0.1.3")
Add resolver to project/plugins.sbt
:
resolvers += "JAnalyse Repository" at "http://www.janalyse.fr/repository/"
Add import to your project build file
import deployssh.DeploySSH._
Enable plugin in your project.
For example in your build.sbt
lazy val myProject = project.enablePlugins(DeploySSH)
You can specify configs that will be used for deployment.
You can use .conf
files or set configs directly in project settings.
Allowed config fields:
name
- your server name. Should be unique in all loaded configs. (Duplication will be overridden)host
- ip adress or hostname of the serveruser
- ssh username. If missing or empty will be used your current user (user.name
)password
- ssh password. If missing or empty will be used ssh keypassphrase
- passphrase for ssh key. Remove or leave empty for ssh key without passphraseport
- ssh port. If missing or empty will be used22
sshDir
- directory with you ssh keys. This directory should containidentity
,id_dsa
,id_ecdsa
,id_ed25519
orid_rsa
(the first matched file in the folder will be used for auth). By defaultuser.name/.ssh
directory. This field is not allowed to be empty in.conf
file. You should remove this field from config in.conf
file to use default value.sshKeyFile
- add additional private key file name that will be used for ssh connection. This file name will be added to head of the default list [identity
,id_dsa
,id_ecdsa
,id_ed25519
,id_rsa
]. This field is not allowed to be empty in.conf
file. You should remove this field from config in.conf
file to use default value.
name
and host
fields are mandatory
To set server configs in project settings use ServerConfig
class and deployConfigs
task key (see details below in Locations
section)
case class ServerConfig(name: String,
host: String,
user: Option[String] = None,
password: Option[String] = None,
passphrase: Option[String] = None,
port: Option[Int] = None,
sshDir: Option[String] = None,
sshKeyFile: Option[String] = None)
Example of the .conf
servers = [
#connect to the server via `22` port and ssh key that located in `user.name/.ssh/` directory, user is current `user.name`
{
name = "server_0"
host = "127.0.0.1"
},
#connect to the server via `22` port and ssh key with name `id_a12` that located in `/tmp/.sshKeys/` directory, user is `ssh_test`
{
name = "server_1"
host = "169.254.0.2"
user = "ssh_test"
sshDir = "/tmp/.sshKeys"
sshKeyFile = "id_a12" #custom private key file name
}
]
There are four places where you can store your server config (All configs will be loaded and merged).
- External config file that located somewhere on your PC
- Config file located in your project directory
- Config file located in user home directory
- Set server configs directly in project settings
lazy val myProject = project.enablePlugins(DeploySSH).settings(
//load build.conf from external path
deployExternalConfigFiles ++= Seq("/home/myUser/Documents/build.conf"),
//load build2.conf from `myProjectDir` and load build3.conf from `myProjectDir/project`
deployResourceConfigFiles ++= Seq("build2.conf", "project/build3.conf"),
//load build4.conf from user home directory (in example `/home/myUser/build4.conf`)
deployHomeConfigFiles ++= Seq("build4.conf"),
//configuration in project setttings
deployConfigs ++= mySettings,
deployConfigs ++= Seq(
ServerConfig("server_6", "169.254.0.3"),
ServerConfig("server_7", "169.254.0.4")
)
)
lazy val mySettings = Seq(
ServerConfig("server_5", "169.254.0.2")
)
Set artifacts to deploy
lazy val myProject = project.enablePlugins(DeploySSH).settings(
version := "1.1",
deployConfigs ++= Seq(
ServerConfig("server_5", "169.254.0.2")
),
deployArtifacts ++= Seq(
//`jar` file from `packageBin in Compile` task will be deployed to `/tmp/` directory
ArtifactSSH((packageBin in Compile).value, "/tmp/"),
//directory `stage` generated by `sbt-native-packager` will be deployed to `~/stage_1.1_release/` directory
ArtifactSSH((stage in Universal).value), s"stage_${version.value}_release/")
)
)
Deploy execution for this config:
deploy-ssh server_5
or
deploySsh server_5
Use deploySshExecBefore
and deploySshExecAfter
to execute any bash commands before and after deploy.
Any exception in deploySshExecBefore
and deploySshExecAfter
will abort deploy for all servers.
To skip deploy only for current server you should wrap exception to SkipDeployException
.
For example stop and update and run your app, copy with scp needed application.conf depends on server name:
lazy val myProject = project.enablePlugins(DeploySSH).settings(
deployConfigs ++= Seq(
ServerConfig("server_5", "169.254.0.2")
),
deploySshExecBefore ++= Seq(
(ssh: SSH) => {
ssh.execOnce("touch pid")
val pid = ssh.execOnceAndTrim("cat pid")
if ("".equals(pid)) {
//skip deploy to current server
throw new SkipDeployException(new RuntimeException("missing pid"))
}
ssh.execOnceAndTrim(s"kill $pid")
}
),
deploySshExecAfter ++= Seq(
(ssh: SSH) => {
ssh.scp { scp =>
scp.send(file(s"./src/main/resources/application-${ssh.options.name.get}.conf"), s"/home/app/application.conf")))
}
ssh.execOnce("nohup ./myApp/run & echo $! > ~/pid")
ssh.execOnce("touch pid")
val pid = ssh.execOnceAndTrim("cat pid")
if ("".equals(pid)) {
//stop deploy to all servers
throw new RuntimeException("missing pid. please check package")
}
}
)
)
If you need execute deploy in your task you can use deploySshTask
and deploySshServersNames
to config args for deploySsh
. Or cast deploySsh
to task.
lazy val myProject = project.enablePlugins(DeploySSH).settings(
deployConfigs ++= Seq(
ServerConfig("server_5", "169.254.0.2"),
ServerConfig("server_6", "169.254.0.3")
),
deploySshServersNames ++= Seq("server_5", "server_6"),
publishLocal := deploySshTask //or deploySsh.toTask(" server_5 server_6")
)
After confuguration you will be able to:
deploy-ssh yourServerName1 yourServerName2 ...
or
deploySsh yourServerName1 yourServerName2 ...
You should set deploySshServersNames
list of server names that will be deployed and execute deploySshTask
from console or link it to other task.