func (g *Bash) Write(f *buildfile.Buildfile) { g.Script = append(g.Script, g.Command) for _, cmd := range g.Script { f.WriteCmd(cmd) } }
func (m *Marathon) Write(f *buildfile.Buildfile) { // debugging purposes so we can see if / where something is failing f.WriteCmdSilent("echo 'deploying to Marathon ...'") put := fmt.Sprintf( "curl -X PUT -d @%s http://%s/v2/apps/%s --header \"Content-Type:application/json\"", m.ConfigFile, m.Host, m.App, ) f.WriteCmdSilent(put) }
func (n *Nodejitsu) Write(f *buildfile.Buildfile) { if len(n.Token) == 0 || len(n.User) == 0 { return } f.WriteEnv("username", n.User) f.WriteEnv("apiToken", n.Token) // Install the jitsu command line interface then // deploy the configured app. f.WriteCmdSilent("[ -f /usr/bin/sudo ] || npm install -g jitsu") f.WriteCmdSilent("[ -f /usr/bin/sudo ] && sudo npm install -g jitsu") f.WriteCmd("jitsu deploy") }
func (p *PyPI) Write(f *buildfile.Buildfile) { var indexServer string var repository string if len(p.Username) == 0 || len(p.Password) == 0 { // nothing to do if the config is fundamentally flawed return } // Handle the setting a custom pypi server/repository if len(p.Repository) == 0 { indexServer = "pypi" repository = "" } else { indexServer = "custom" repository = fmt.Sprintf("repository:%s", p.Repository) } f.WriteCmdSilent("echo 'publishing to PyPI...'") // find the setup.py file f.WriteCmdSilent("_PYPI_SETUP_PY=$(find . -name 'setup.py')") // build the .pypirc file that pypi expects f.WriteCmdSilent(fmt.Sprintf(pypirc, indexServer, indexServer, p.Username, p.Password, repository)) formatStr := p.BuildFormatStr() // if we found the setup.py file use it to deploy f.WriteCmdSilent(fmt.Sprintf(deployCmd, formatStr, indexServer)) }
func (cf *CloudFoundry) Write(f *buildfile.Buildfile) { downloadCmd := "curl -sLO http://go-cli.s3-website-us-east-1.amazonaws.com/releases/latest/cf-cli_amd64.deb" installCmd := "dpkg -i cf-cli_amd64.deb 1> /dev/null 2> /dev/null" // download and install the cf tool f.WriteCmdSilent(fmt.Sprintf("[ -f /usr/bin/sudo ] && sudo %s || %s", downloadCmd, downloadCmd)) f.WriteCmdSilent(fmt.Sprintf("[ -f /usr/bin/sudo ] && sudo %s || %s", installCmd, installCmd)) // login loginCmd := "cf login -a %s -u %s -p %s" organization := cf.Org if organization != "" { loginCmd += fmt.Sprintf(" -o %s", organization) } space := cf.Space if space != "" { loginCmd += fmt.Sprintf(" -s %s", space) } f.WriteCmdSilent(fmt.Sprintf(loginCmd, cf.Target, cf.Username, cf.Password)) // push app pushCmd := "cf push %s" f.WriteCmd(fmt.Sprintf(pushCmd, cf.App)) }
// WriteBuild adds only the build steps to the build script, // omitting publish and deploy steps. This is important for // pull requests, where deployment would be undesirable. func (b *Build) WriteBuild(f *buildfile.Buildfile) { // append environment variables for _, env := range b.Env { parts := strings.SplitN(env, "=", 2) if len(parts) != 2 { continue } f.WriteEnv(parts[0], parts[1]) } // append build commands for _, cmd := range b.Script { f.WriteCmd(cmd) } }
func (d *Dropbox) Write(f *buildfile.Buildfile) { if len(d.AccessToken) == 0 || len(d.Source) == 0 || len(d.Target) == 0 { return } if strings.HasPrefix(d.Target, "/") { d.Target = d.Target[1:] } f.WriteCmdSilent("echo 'publishing to Dropbox ...'") cmd := "curl --upload-file %s -H \"Authorization: Bearer %s\" \"https://api-content.dropbox.com/1/files_put/auto/%s?overwrite=true\"" f.WriteCmd(fmt.Sprintf(cmd, d.Source, d.AccessToken, d.Target)) }
// Write adds all the steps to the build script, including // build commands, deploy and publish commands. func (b *Build) Write(f *buildfile.Buildfile, r *repo.Repo) { // append build commands b.WriteBuild(f) // write publish commands if b.Publish != nil { b.Publish.Write(f, r) } // write deployment commands if b.Deploy != nil { b.Deploy.Write(f, r) } // write exit value f.WriteCmd("exit 0") }
func Test_Modulus(t *testing.T) { g := goblin.Goblin(t) g.Describe("Modulus Deploy", func() { g.It("Requires a Project name", func() { b := new(buildfile.Buildfile) m := Modulus{ Project: "foo", } m.Write(b) g.Assert(b.String()).Equal("") }) g.It("Requires a Token", func() { b := new(buildfile.Buildfile) m := Modulus{ Token: "bar", } m.Write(b) g.Assert(b.String()).Equal("") }) g.It("Should execute deploy commands", func() { b := new(buildfile.Buildfile) m := Modulus{ Project: "foo", Token: "bar", } m.Write(b) g.Assert(b.String()).Equal(`export MODULUS_TOKEN="bar" [ -f /usr/bin/npm ] || echo ERROR: npm is required for modulus.io deployments [ -f /usr/bin/npm ] || exit 1 [ -f /usr/bin/sudo ] || npm install -g modulus [ -f /usr/bin/sudo ] && sudo npm install -g modulus echo '#DRONE:6d6f64756c7573206465706c6f79202d702022666f6f22' modulus deploy -p "foo" `) }) }) }
func Test_Modulus(t *testing.T) { g := goblin.Goblin(t) g.Describe("Nodejitsu Deploy", func() { g.It("Requires a User", func() { b := new(buildfile.Buildfile) n := Nodejitsu{ User: "******", } n.Write(b) g.Assert(b.String()).Equal("") }) g.It("Requires a Token", func() { b := new(buildfile.Buildfile) n := Nodejitsu{ Token: "bar", } n.Write(b) g.Assert(b.String()).Equal("") }) g.It("Should execute deploy commands", func() { b := new(buildfile.Buildfile) n := Nodejitsu{ User: "******", Token: "bar", } n.Write(b) g.Assert(b.String()).Equal(`export username="******" export apiToken="bar" [ -f /usr/bin/sudo ] || npm install -g jitsu [ -f /usr/bin/sudo ] && sudo npm install -g jitsu echo '#DRONE:6a69747375206465706c6f79' jitsu deploy `) }) }) }
func (n *NPM) Write(f *buildfile.Buildfile) { // If the yaml doesn't provide a username or password // we should attempt to use the global defaults. if len(n.Email) == 0 || len(n.Username) == 0 || len(n.Password) == 0 { n.Username = *DefaultUser n.Password = *DefaultPass n.Email = *DefaultEmail } // If the yaml doesn't provide a username or password, // and there was not global configuration defined, EXIT. if len(n.Email) == 0 || len(n.Username) == 0 || len(n.Password) == 0 { return } // Setup the npm credentials f.WriteCmdSilent(fmt.Sprintf(CmdLogin, n.Username, n.Password, n.Email)) // Setup custom npm registry if len(n.Registry) != 0 { f.WriteCmd(fmt.Sprintf(CmdSetRegistry, n.Registry)) } // Set npm to always authenticate if n.AlwaysAuth { f.WriteCmd(CmdAlwaysAuth) } if len(n.Folder) == 0 { n.Folder = "." } f.WriteString(fmt.Sprintf(CmdPublish, n.Folder, n.Tag, n.Folder)) }
// Write down the buildfile func (s *SSH) Write(f *buildfile.Buildfile) { host := strings.SplitN(s.Target, " ", 2) if len(host) == 1 { host = append(host, "22") } if _, err := strconv.Atoi(host[1]); err != nil { host[1] = "22" } // Is artifact created? artifact := false for _, a := range s.Artifacts { if a == "GITARCHIVE" { artifact = createGitArchive(f) break } } if !artifact { if len(s.Artifacts) > 1 { artifact = compress(f, s.Artifacts) } else if len(s.Artifacts) == 1 { f.WriteEnv("ARTIFACT", s.Artifacts[0]) artifact = true } } if artifact { scpCmd := "scp -o StrictHostKeyChecking=no -P %s -r ${ARTIFACT} %s" f.WriteCmd(fmt.Sprintf(scpCmd, host[1], host[0])) } if len(s.Cmd) > 0 { sshCmd := "ssh -o StrictHostKeyChecking=no -p %s %s %q" f.WriteCmd(fmt.Sprintf(sshCmd, host[1], strings.SplitN(host[0], ":", 2)[0], s.Cmd)) } }
func (p *Package) upload(username, api_key string, f *buildfile.Buildfile) { f.WriteCmdSilent(fmt.Sprintf(`echo -e "\nUpload %s to %s/%s/%s"`, p.File, p.Owner, p.Repository, p.Package)) f.WriteCmdSilent(fmt.Sprintf("curl -s -T %s -u%s:%s %s\\;publish\\=%d\\;override\\=%d", p.File, username, api_key, p.getEndpoint(), boolToInt(p.Publish), boolToInt(p.Override))) }
func (p *Package) Write(username, api_key string, f *buildfile.Buildfile) { if len(p.File) == 0 || len(p.Owner) == 0 || len(p.Repository) == 0 || len(p.Package) == 0 || len(p.Version) == 0 || len(p.Target) == 0 { f.WriteCmdSilent(`echo -e "Bintray Plugin: Missing argument(s)\n\n"`) if len(p.Package) == 0 { f.WriteCmdSilent(fmt.Sprintf(`echo -e "\tpackage not defined in yaml config"`)) return } if len(p.File) == 0 { f.WriteCmdSilent(fmt.Sprintf(`echo -e "\tpackage %s: file not defined in yaml config"`, p.Package)) } if len(p.Owner) == 0 { f.WriteCmdSilent(fmt.Sprintf(`echo -e "\tpackage %s: owner not defined in yaml config"`, p.Package)) } if len(p.Repository) == 0 { f.WriteCmdSilent(fmt.Sprintf(`echo -e "\tpackage %s: repository not defined in yaml config"`, p.Package)) } if len(p.Version) == 0 { f.WriteCmdSilent(fmt.Sprintf(`echo -e "\tpackage %s: version not defined in yaml config"`, p.Package)) } if len(p.Target) == 0 { f.WriteCmdSilent(fmt.Sprintf(`echo -e "\tpackage %s: target not defined in yaml config"`, p.Package)) } f.WriteCmdSilent("exit 1") return } switch p.Type { case "deb": p.debUpload(username, api_key, f) case "rpm": p.upload(username, api_key, f) case "maven": p.upload(username, api_key, f) default: p.upload(username, api_key, f) } }
func (p *Package) debUpload(username, api_key string, f *buildfile.Buildfile) { if len(p.Distr) == 0 || len(p.Component) == 0 || len(p.Arch) == 0 { f.WriteCmdSilent(`echo -e "Bintray Plugin: Missing argument(s)\n\n"`) if len(p.Distr) == 0 { f.WriteCmdSilent(fmt.Sprintf(`echo -e "\tpackage %s: distr not defined in yaml config"`, p.Package)) } if len(p.Component) == 0 { f.WriteCmdSilent(fmt.Sprintf(`echo -e "\tpackage %s: component not defined in yaml config"`, p.Package)) } if len(p.Arch) == 0 { f.WriteCmdSilent(fmt.Sprintf(`echo -e "\tpackage %s: arch not defined in yaml config"`, p.Package)) } f.WriteCmdSilent("exit 1") return } f.WriteCmdSilent(fmt.Sprintf(`echo -e "\nUpload %s to %s/%s/%s"`, p.File, p.Owner, p.Repository, p.Package)) f.WriteCmdSilent(fmt.Sprintf("curl -s -T %s -u%s:%s %s\\;deb_distribution\\=%s\\;deb_component\\=%s\\;deb_architecture=\\%s\\;publish\\=%d\\;override\\=%d", p.File, username, api_key, p.getEndpoint(), p.Distr, p.Component, strings.Join(p.Arch, ","), boolToInt(p.Publish), boolToInt(p.Override))) }
func (h *Deis) Write(f *buildfile.Buildfile) { f.WriteCmdSilent(CmdRevParse) f.WriteCmdSilent(CmdGlobalUser) f.WriteCmdSilent(CmdGlobalEmail) // [email protected]:2222/drone.git f.WriteCmd(fmt.Sprintf("git remote add deis ssh://git@%s%s.git", h.Deisurl, h.App)) switch h.Force { case true: // this is useful when the there are artifacts generated // by the build script, such as less files converted to css, // that need to be deployed to Deis. f.WriteCmd(fmt.Sprintf("git add -A")) f.WriteCmd(fmt.Sprintf("git commit -m 'adding build artifacts'")) f.WriteCmd(fmt.Sprintf("git push deis HEAD:master --force")) case false: // otherwise we just do a standard git push f.WriteCmd(fmt.Sprintf("git push deis $COMMIT:master")) } }
// Write adds commands to run that will publish a Github release. func (g *Github) Write(f *buildfile.Buildfile) { if len(g.Artifacts) == 0 || g.Tag == "" || g.Token == "" || g.User == "" || g.Repo == "" { f.WriteCmdSilent(`echo -e "Github Plugin: Missing argument(s)"\n\n`) if len(g.Artifacts) == 0 { f.WriteCmdSilent(`echo -e "\tartifacts not defined in yaml config" && false`) } if g.Tag == "" { f.WriteCmdSilent(`echo -e "\ttag not defined in yaml config" && false`) } if g.Token == "" { f.WriteCmdSilent(`echo -e "\ttoken not defined in yaml config" && false`) } if g.User == "" { f.WriteCmdSilent(`echo -e "\tuser not defined in yaml config" && false`) } if g.Repo == "" { f.WriteCmdSilent(`echo -e "\trepo not defined in yaml config" && false`) } return } // Default name is tag if g.Name == "" { g.Name = g.Tag } for _, cmd := range g.Script { f.WriteCmd(cmd) } f.WriteEnv("GITHUB_TOKEN", g.Token) // Install github-release f.WriteCmd("curl -L -o /tmp/github-release.tar.bz2 https://github.com/aktau/github-release/releases/download/v0.5.2/linux-amd64-github-release.tar.bz2") f.WriteCmd("tar jxf /tmp/github-release.tar.bz2 -C /tmp/ && sudo mv /tmp/bin/linux/amd64/github-release /usr/local/bin/github-release") // Create the release. Ignore 422 errors, which indicate the tag has already been created. // Doing otherwise would create the expectation that every commit should be tagged and released, // which is not the norm. draftStr := "" if g.Draft { draftStr = "--draft" } prereleaseStr := "" if g.Prerelease { prereleaseStr = "--pre-release" } f.WriteCmd(fmt.Sprintf(` result=$(github-release release -u %s -r %s -t %s -n "%s" -d "%s" %s %s || true) if [[ $result == *422* ]]; then echo -e "Release already exists for this tag."; exit 0 elif [[ $result == "" ]]; then echo -e "Release created."; else echo -e "Error creating release: $result" exit 1 fi `, g.User, g.Repo, g.Tag, g.Name, g.Description, draftStr, prereleaseStr)) // Upload files artifactStr := strings.Join(g.Artifacts, " ") f.WriteCmd(fmt.Sprintf(` for f in %s; do # treat directories and files differently if [ -d $f ]; then for ff in $(ls $f); do echo -e "uploading $ff" github-release upload -u %s -r %s -t %s -n $ff -f $f/$ff done elif [ -f $f ]; then echo -e "uploading $f" github-release upload -u %s -r %s -t %s -n $f -f $f else echo -e "$f is not a file or directory" exit 1 fi done `, artifactStr, g.User, g.Repo, g.Tag, g.User, g.Repo, g.Tag)) }
func (s *S3) Write(f *buildfile.Buildfile) { // skip if AWS key or SECRET are empty. A good example for this would // be forks building a project. S3 might be configured in the source // repo, but not in the fork if len(s.Key) == 0 || len(s.Secret) == 0 { return } // debugging purposes so we can see if / where something is failing f.WriteCmdSilent("echo 'publishing to Amazon S3 ...'") // install the AWS cli using PIP f.WriteCmdSilent("[ -f /usr/bin/sudo ] || pip install awscli 1> /dev/null 2> /dev/null") f.WriteCmdSilent("[ -f /usr/bin/sudo ] && sudo pip install awscli 1> /dev/null 2> /dev/null") f.WriteEnv("AWS_ACCESS_KEY_ID", s.Key) f.WriteEnv("AWS_SECRET_ACCESS_KEY", s.Secret) // make sure a default region is set if len(s.Region) == 0 { s.Region = "us-east-1" } // make sure a default access is set // let's be conservative and assume private if len(s.Access) == 0 { s.Access = "private" } // if the target starts with a "/" we need // to remove it, otherwise we might adding // a 3rd slash to s3:// if strings.HasPrefix(s.Target, "/") { s.Target = s.Target[1:] } switch s.Recursive { case true: f.WriteCmd(fmt.Sprintf(`aws s3 cp %s s3://%s/%s --recursive --acl %s --region %s`, s.Source, s.Bucket, s.Target, s.Access, s.Region)) case false: f.WriteCmd(fmt.Sprintf(`aws s3 cp %s s3://%s/%s --acl %s --region %s`, s.Source, s.Bucket, s.Target, s.Access, s.Region)) } }
func Test_Tsuru(t *testing.T) { g := goblin.Goblin(t) g.Describe("Tsuru Deploy", func() { g.It("Should set git.config", func() { b := new(buildfile.Buildfile) d := Tsuru{ Remote: "git://foo.com/bar/baz.git", } d.Write(b) out := b.String() g.Assert(strings.Contains(out, CmdRevParse)).Equal(true) g.Assert(strings.Contains(out, CmdGlobalUser)).Equal(true) g.Assert(strings.Contains(out, CmdGlobalEmail)).Equal(true) }) g.It("Should add remote", func() { b := new(buildfile.Buildfile) d := Tsuru{ Remote: "git://foo.com/bar/baz.git", } d.Write(b) out := b.String() g.Assert(strings.Contains(out, "\ngit remote add tsuru git://foo.com/bar/baz.git\n")).Equal(true) }) g.It("Should push to remote", func() { b := new(buildfile.Buildfile) d := Tsuru{ Remote: "git://foo.com/bar/baz.git", } d.Write(b) out := b.String() g.Assert(strings.Contains(out, "\ngit push tsuru $COMMIT:master\n")).Equal(true) }) g.It("Should force push to remote", func() { b := new(buildfile.Buildfile) d := Tsuru{ Force: true, Remote: "git://foo.com/bar/baz.git", } d.Write(b) out := b.String() g.Assert(strings.Contains(out, "\ngit add -A\n")).Equal(true) g.Assert(strings.Contains(out, "\ngit commit -m 'adding build artifacts'\n")).Equal(true) g.Assert(strings.Contains(out, "\ngit push tsuru HEAD:master --force\n")).Equal(true) }) }) }
func (h *Heroku) Write(f *buildfile.Buildfile) { f.WriteCmdSilent(CmdRevParse) f.WriteCmdSilent(CmdGlobalUser) f.WriteCmdSilent(CmdGlobalEmail) f.WriteCmdSilent(fmt.Sprintf(CmdLogin, h.Token)) // add heroku as a git remote f.WriteCmd(fmt.Sprintf("git remote add heroku https://git.heroku.com/%s.git", h.App)) switch h.Force { case true: // this is useful when the there are artifacts generated // by the build script, such as less files converted to css, // that need to be deployed to Heroku. f.WriteCmd(fmt.Sprintf("git add -A")) f.WriteCmd(fmt.Sprintf("git commit -m 'adding build artifacts'")) f.WriteCmd(fmt.Sprintf("git push heroku HEAD:refs/heads/master --force")) case false: // otherwise we just do a standard git push f.WriteCmd(fmt.Sprintf("git push heroku $COMMIT:refs/heads/master")) } }
func Test_Heroku(t *testing.T) { g := goblin.Goblin(t) g.Describe("Heroku Deploy", func() { g.It("Should set git.config", func() { b := new(buildfile.Buildfile) h := Heroku{ App: "drone", } h.Write(b) out := b.String() g.Assert(strings.Contains(out, CmdRevParse)).Equal(true) g.Assert(strings.Contains(out, CmdGlobalUser)).Equal(true) g.Assert(strings.Contains(out, CmdGlobalEmail)).Equal(true) }) g.It("Should write token", func() { b := new(buildfile.Buildfile) h := Heroku{ App: "drone", Token: "mock-token", } h.Write(b) out := b.String() g.Assert(strings.Contains(out, "\necho 'machine git.heroku.com login _ password mock-token' >> ~/.netrc\n")).Equal(true) }) g.It("Should add remote", func() { b := new(buildfile.Buildfile) h := Heroku{ App: "drone", } h.Write(b) out := b.String() g.Assert(strings.Contains(out, "\ngit remote add heroku https://git.heroku.com/drone.git\n")).Equal(true) }) g.It("Should push to remote", func() { b := new(buildfile.Buildfile) d := Heroku{ App: "drone", } d.Write(b) out := b.String() g.Assert(strings.Contains(out, "\ngit push heroku $COMMIT:refs/heads/master\n")).Equal(true) }) g.It("Should force push to remote", func() { b := new(buildfile.Buildfile) h := Heroku{ Force: true, App: "drone", } h.Write(b) out := b.String() g.Assert(strings.Contains(out, "\ngit add -A\n")).Equal(true) g.Assert(strings.Contains(out, "\ngit commit -m 'adding build artifacts'\n")).Equal(true) g.Assert(strings.Contains(out, "\ngit push heroku HEAD:refs/heads/master --force\n")).Equal(true) }) }) }
func (t *Tsuru) Write(f *buildfile.Buildfile) { f.WriteCmdSilent(CmdRevParse) f.WriteCmdSilent(CmdGlobalUser) f.WriteCmdSilent(CmdGlobalEmail) // add tsuru as a git remote f.WriteCmd(fmt.Sprintf("git remote add tsuru %s", t.Remote)) switch t.Force { case true: // this is useful when the there are artifacts generated // by the build script, such as less files converted to css, // that need to be deployed to Tsuru. f.WriteCmd(fmt.Sprintf("git add -A")) f.WriteCmd(fmt.Sprintf("git commit -m 'adding build artifacts'")) f.WriteCmd(fmt.Sprintf("git push tsuru HEAD:master --force")) case false: // otherwise we just do a standard git push f.WriteCmd(fmt.Sprintf("git push tsuru $COMMIT:master")) } }
func (m *Modulus) Write(f *buildfile.Buildfile) { if len(m.Token) == 0 || len(m.Project) == 0 { return } f.WriteEnv("MODULUS_TOKEN", m.Token) // Verify npm exists, otherwise we cannot install the // modulus command line utility. f.WriteCmdSilent("[ -f /usr/bin/npm ] || echo ERROR: npm is required for modulus.io deployments") f.WriteCmdSilent("[ -f /usr/bin/npm ] || exit 1") // Install the Modulus command line interface then deploy the configured // project. f.WriteCmdSilent("[ -f /usr/bin/sudo ] || npm install -g modulus") f.WriteCmdSilent("[ -f /usr/bin/sudo ] && sudo npm install -g modulus") f.WriteCmd(fmt.Sprintf("modulus deploy -p %q", m.Project)) }
func (g *Git) Write(f *buildfile.Buildfile) { f.WriteCmdSilent(CmdRevParse) f.WriteCmdSilent(CmdGlobalUser) f.WriteCmdSilent(CmdGlobalEmail) // add target as a git remote f.WriteCmd(fmt.Sprintf("git remote add deploy %s", g.Target)) dest := g.Branch if len(dest) == 0 { dest = "master" } switch g.Force { case true: // this is useful when the there are artifacts generated // by the build script, such as less files converted to css, // that need to be deployed to git remote. f.WriteCmd(fmt.Sprintf("git add -A")) f.WriteCmd(fmt.Sprintf("git commit -m 'add build artifacts'")) f.WriteCmd(fmt.Sprintf("git push deploy HEAD:%s --force", dest)) case false: // otherwise we just do a standard git push f.WriteCmd(fmt.Sprintf("git push deploy $COMMIT:%s", dest)) } }
func Test_Deis(t *testing.T) { g := goblin.Goblin(t) g.Describe("Deis Deploy", func() { g.It("Should set git.config", func() { b := new(buildfile.Buildfile) h := Deis{ App: "drone", Deisurl: "deis.yourdomain.com:2222", } h.Write(b) out := b.String() g.Assert(strings.Contains(out, CmdRevParse)).Equal(true) g.Assert(strings.Contains(out, CmdGlobalUser)).Equal(true) g.Assert(strings.Contains(out, CmdGlobalEmail)).Equal(true) }) g.It("Should add remote", func() { b := new(buildfile.Buildfile) h := Deis{ App: "drone", Deisurl: "deis.yourdomain.com:2222/", } h.Write(b) out := b.String() g.Assert(strings.Contains(out, "\ngit remote add deis ssh://[email protected]:2222/drone.git\n")).Equal(true) }) g.It("Should push to remote", func() { b := new(buildfile.Buildfile) d := Deis{ App: "drone", } d.Write(b) out := b.String() g.Assert(strings.Contains(out, "\ngit push deis $COMMIT:master\n")).Equal(true) }) g.It("Should force push to remote", func() { b := new(buildfile.Buildfile) h := Deis{ Force: true, App: "drone", } h.Write(b) out := b.String() g.Assert(strings.Contains(out, "\ngit add -A\n")).Equal(true) g.Assert(strings.Contains(out, "\ngit commit -m 'adding build artifacts'\n")).Equal(true) g.Assert(strings.Contains(out, "\ngit push deis HEAD:master --force\n")).Equal(true) }) }) }
func Test_NPM(t *testing.T) { g := goblin.Goblin(t) g.Describe("NPM Publish", func() { g.BeforeEach(func() { var user, pass, email = "", "", "" DefaultEmail = &user DefaultUser = &pass DefaultPass = &email }) g.It("Should run publish", func() { b := new(buildfile.Buildfile) n := NPM{ Email: "*****@*****.**", Username: "******", Password: "******", Folder: "/path/to/repo", } n.Write(b) out := b.String() g.Assert(strings.Contains(out, "npm publish /path/to/repo\n")).Equal(true) g.Assert(strings.Contains(out, "\nnpm set")).Equal(false) g.Assert(strings.Contains(out, "\nnpm config set")).Equal(false) }) g.It("Should use current directory if folder is empty", func() { b := new(buildfile.Buildfile) n := NPM{ Email: "*****@*****.**", Username: "******", Password: "******", } n.Write(b) g.Assert(strings.Contains(b.String(), "npm publish .\n")).Equal(true) }) g.It("Should set tag", func() { b := new(buildfile.Buildfile) n := NPM{ Email: "*****@*****.**", Username: "******", Password: "******", Folder: "/path/to/repo", Tag: "1.0.0", } n.Write(b) g.Assert(strings.Contains(b.String(), "\n_NPM_PACKAGE_TAG=\"1.0.0\"\n")).Equal(true) g.Assert(strings.Contains(b.String(), "npm tag ${_NPM_PACKAGE_NAME} ${_NPM_PACKAGE_TAG}\n")).Equal(true) }) g.It("Should set registry", func() { b := new(buildfile.Buildfile) n := NPM{ Email: "*****@*****.**", Username: "******", Password: "******", Folder: "/path/to/repo", Registry: "https://npmjs.com", } n.Write(b) g.Assert(strings.Contains(b.String(), "\nnpm config set registry https://npmjs.com\n")).Equal(true) }) g.It("Should set always-auth", func() { b := new(buildfile.Buildfile) n := NPM{ Email: "*****@*****.**", Username: "******", Password: "******", Folder: "/path/to/repo", AlwaysAuth: true, } n.Write(b) g.Assert(strings.Contains(b.String(), CmdAlwaysAuth)).Equal(true) }) g.It("Should skip when no username or password", func() { b := new(buildfile.Buildfile) n := new(NPM) n.Write(b) g.Assert(b.String()).Equal("") }) g.It("Should use default username or password", func() { b := new(buildfile.Buildfile) n := new(NPM) expected := `cat <<EOF > ~/.npmrc _auth = $(echo "foo:bar" | tr -d "\r\n" | base64) email = [email protected] EOF` var user, pass, email string = "foo", "bar", "*****@*****.**" DefaultUser = &user DefaultPass = &pass DefaultEmail = &email n.Write(b) g.Assert(strings.Contains(b.String(), expected)).Equal(true) }) g.It("Should create npmrc", func() { b := new(buildfile.Buildfile) n := NPM{ Email: "*****@*****.**", Username: "******", Password: "******", Folder: "/path/to/repo", AlwaysAuth: true, } expected := `cat <<EOF > ~/.npmrc _auth = $(echo "foo:bar" | tr -d "\r\n" | base64) email = [email protected] EOF` n.Write(b) g.Assert(strings.Contains(b.String(), expected)).Equal(true) }) }) }
func Test_Git(t *testing.T) { g := goblin.Goblin(t) g.Describe("Git Deploy", func() { g.It("Should set git.config", func() { b := new(buildfile.Buildfile) d := Git{ Target: "git://foo.com/bar/baz.git", } d.Write(b) out := b.String() g.Assert(strings.Contains(out, CmdRevParse)).Equal(true) g.Assert(strings.Contains(out, CmdGlobalUser)).Equal(true) g.Assert(strings.Contains(out, CmdGlobalEmail)).Equal(true) }) g.It("Should add remote", func() { b := new(buildfile.Buildfile) d := Git{ Target: "git://foo.com/bar/baz.git", } d.Write(b) out := b.String() g.Assert(strings.Contains(out, "\ngit remote add deploy git://foo.com/bar/baz.git\n")).Equal(true) }) g.It("Should push to remote", func() { b := new(buildfile.Buildfile) d := Git{ Target: "git://foo.com/bar/baz.git", } d.Write(b) out := b.String() g.Assert(strings.Contains(out, "\ngit push deploy $COMMIT:master\n")).Equal(true) }) g.It("Should push to alternate branch", func() { b := new(buildfile.Buildfile) d := Git{ Branch: "foo", Target: "git://foo.com/bar/baz.git", } d.Write(b) out := b.String() g.Assert(strings.Contains(out, "\ngit push deploy $COMMIT:foo\n")).Equal(true) }) g.It("Should force push to remote", func() { b := new(buildfile.Buildfile) d := Git{ Force: true, Target: "git://foo.com/bar/baz.git", } d.Write(b) out := b.String() g.Assert(strings.Contains(out, "\ngit add -A\n")).Equal(true) g.Assert(strings.Contains(out, "\ngit commit -m 'add build artifacts'\n")).Equal(true) g.Assert(strings.Contains(out, "\ngit push deploy HEAD:master --force\n")).Equal(true) }) }) }
func (s *Swift) Write(f *buildfile.Buildfile) { var target string // All options are required, so ensure they are present if len(s.Username) == 0 || len(s.Password) == 0 || len(s.AuthURL) == 0 || len(s.Region) == 0 || len(s.Source) == 0 || len(s.Container) == 0 { f.WriteCmdSilent(`echo "Swift: Missing argument(s)"`) return } // If a target was provided, prefix it with a / if len(s.Target) > 0 { target = fmt.Sprintf("/%s", strings.TrimPrefix(s.Target, "/")) } // debugging purposes so we can see if / where something is failing f.WriteCmdSilent(`echo "Swift: Publishing..."`) // install swiftly using PIP f.WriteCmdSilent("[ -f /usr/bin/sudo ] || pip install swiftly 1> /dev/null 2> /dev/null") f.WriteCmdSilent("[ -f /usr/bin/sudo ] && sudo pip install swiftly 1> /dev/null 2> /dev/null") // Write out environment variables f.WriteEnv("SWIFTLY_AUTH_URL", s.AuthURL) f.WriteEnv("SWIFTLY_AUTH_USER", s.Username) f.WriteEnv("SWIFTLY_AUTH_KEY", s.Password) f.WriteEnv("SWIFTLY_REGION", s.Region) f.WriteCmd(fmt.Sprintf(`swiftly put -i %s %s%s`, s.Source, s.Container, target)) }
// Write adds commands to the buildfile to do the following: // 1. Install the docker client in the Drone container if required. // 2. Build a docker image based on the dockerfile defined in the config. // 3. Push that docker image to index.docker.io. // 4. Delete the docker image on the server it was build on so we conserve disk space. func (d *Docker) Write(f *buildfile.Buildfile) { if len(d.DockerHost) == 0 || len(d.ImageName) == 0 { f.WriteCmdSilent(`echo -e "Docker Plugin: Missing argument(s)\n\n"`) if len(d.DockerHost) == 0 { f.WriteCmdSilent(`echo -e "\tdocker_host not defined in yaml"`) } if len(d.ImageName) == 0 { f.WriteCmdSilent(`echo -e "\timage_name not defined in yaml"`) } return } // If docker version is unspecified, download and install the latest client if len(d.DockerVersion) == 0 { d.DockerVersion = "latest" } if len(d.DockerVersion) > 0 { // Download docker binary and install it as /usr/local/bin/docker if it does not exist f.WriteCmd("type -p docker || curl -sSL https://get.docker.io/builds/Linux/x86_64/docker-" + d.DockerVersion + ".tgz |sudo tar zxf - -C /") } // Export docker host once f.WriteCmd("export DOCKER_HOST=" + d.DockerHost) // Login? if d.RegistryLogin == true { // If email is unspecified, pass in -e ' ' to avoid having // registry URL interpreted as email, which will fail cryptically. emailOpt := "' '" if d.Email != "" { emailOpt = d.Email } f.WriteCmdSilent(fmt.Sprintf("docker login -u %s -p %s -e %s %s", d.Username, d.Password, emailOpt, d.RegistryLoginUrl)) } dockerPath := "." if len(d.Dockerfile) != 0 { dockerPath = fmt.Sprintf("- < %s", d.Dockerfile) } // Run the command commands to build and deploy the image. // Add the single tag if one exists if len(d.Tag) > 0 { d.Tags = append(d.Tags, d.Tag) } // If no tags are specified, use the commit hash if len(d.Tags) == 0 { d.Tags = append(d.Tags, "$(git rev-parse --short HEAD)") } // There is always at least 1 tag buildImageTag := d.Tags[0] // Build the image f.WriteCmd(fmt.Sprintf("docker build --pull -t %s:%s %s", d.ImageName, buildImageTag, dockerPath)) // Tag and push all tags for _, tag := range d.Tags { if tag != buildImageTag { var options string if d.ForceTags { options = "-f" } f.WriteCmd(fmt.Sprintf("docker tag %s %s:%s %s:%s", options, d.ImageName, buildImageTag, d.ImageName, tag)) } f.WriteCmd(fmt.Sprintf("docker push %s:%s", d.ImageName, tag)) } // Remove tags after pushing unless keepBuild is set if !d.KeepBuild { for _, tag := range d.Tags { f.WriteCmd(fmt.Sprintf("docker rmi %s:%s", d.ImageName, tag)) } } }
func (a *Azure) Write(f *buildfile.Buildfile) { if len(a.StorageAccount) == 0 || len(a.StorageAccessKey) == 0 || len(a.StorageContainer) == 0 || len(a.Source) == 0 { return } f.WriteCmdSilent("echo 'publishing to Azure Storage ...'") // install Azure xplat CLI f.WriteCmdSilent("[ -f /usr/bin/sudo ] || npm install -g azure-cli 1> /dev/null 2> /dev/null") f.WriteCmdSilent("[ -f /usr/bin/sudo ] && sudo npm install -g azure-cli 1> /dev/null 2> /dev/null") f.WriteEnv("AZURE_STORAGE_ACCOUNT", a.StorageAccount) f.WriteEnv("AZURE_STORAGE_ACCESS_KEY", a.StorageAccessKey) // if target isn't specified, set to source if len(a.Target) == 0 { a.Target = a.Source } f.WriteCmd(fmt.Sprintf(`azure storage blob upload --container %s %s %s`, a.StorageContainer, a.Source, a.Target)) }