Skip to content

Instantly share code, notes, and snippets.

@ShaneDelmore
Created August 9, 2016 20:29
Show Gist options
  • Select an option

  • Save ShaneDelmore/237cb530c8ba0bd1b8bdce720a532759 to your computer and use it in GitHub Desktop.

Select an option

Save ShaneDelmore/237cb530c8ba0bd1b8bdce720a532759 to your computer and use it in GitHub Desktop.
Download an artifact on OSX from Atlassian Bamboo
#!/usr/bin/env amm
//Requirements:
// This only runs on OSX as it uses OSX Keychain to store your Bamboo login credentials
// Tested with Ammonite 0.7.0
import ammonite.ops._
import $ivy.`org.scalaj::scalaj-http:2.2.0`, scalaj.http._
import $ivy.`org.json4s::json4s-native:3.4.0`, org.json4s._, native.JsonMethods._
import java.net.SocketTimeoutException
implicit val formats = DefaultFormats //Bring default json formats into scope
implicit val wd = cwd //set working directory to current working directory
val (scheme, bambooHost, planKey, artifact) = ("https", "bamboo.yourDomain.com", "PlanKey", "artifactFileName")
println(s"attempting to update $artifact")
//wrap script in try catch to enable printing help instructions on failure
try {
//No attempt is made to handle multiple sets of credentials in the keychain for the same resource
//regex used to extract username from OSX security output
val usernameExtractor = """(?s).*acct"<blob>="([A-Za-z]+).*""".r
//Call native security function to find login for bambooHost and extract the username
val usernameExtractor(username) = (%%('security, "find-generic-password", "-gs", bambooHost).out.toString)
//Call the security function with -w this time to output just the password
val password = (%%('security, "find-generic-password", "-s", bambooHost, "-w").out.lines.head)
//Build a url to grab the latest successful build result for the supplied playKey
val latestSuccessfulQuery = s"https://$bambooHost/rest/api/latest/result/$planKey/.json?max-results=1&buildstate=Successful"
//Grab the json from Bamboo as text
val latestSuccessfulBuild = Http(latestSuccessfulQuery).auth(username, password).asString.body
//Parse it into json and extract buildNumber
val json = parse(latestSuccessfulBuild)
val buildNumber = ((json \ "results" \ "result")(0) \ "buildNumber").extract[Int]
//Use buildNumber to build the url used to locate artifacts for the build
val artifactLocation = s"https://$bambooHost/artifact/$planKey/shared/build-$buildNumber/Artifacts/$artifact"
//Download the file contents and write them to the current working directory, overwriting if the file exists
val fileContents = Http(artifactLocation).auth(username, password).asString.body
write.over(cwd/artifact, fileContents)
println(s"successfully updated $artifact from build $buildNumber")
}
catch {
case ex: SocketTimeoutException => println(s"Unable to communicate with $bambooHost")
case ex: ShelloutException =>
println("Failed to retrieve credentials from Keychain")
println("Before running this script add your credentials to your OSX Keychain using:\n")
println(s"\tsecurity add-generic-password -U -s $bambooHost -a yourBambooUsername -w yourBambooPassword\n")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment