func (g *Bash) Write(f *buildfile.Buildfile) { g.Script = append(g.Script, g.Command) for _, cmd := range g.Script { f.WriteCmd(cmd) } }
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)) }
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 (n *NPM) Write(f *buildfile.Buildfile) { if len(n.Email) == 0 || len(n.Username) == 0 || len(n.Password) == 0 { return } npmPublishCmd := "npm publish %s" if n.Tag != "" { npmPublishCmd += fmt.Sprintf(" --tag %s", n.Tag) } if n.Force { npmPublishCmd += " --force" } f.WriteCmdSilent("echo 'publishing to NPM ...'") // Login to registry f.WriteCmdSilent(fmt.Sprintf(npmLoginCmd, n.Username, n.Password, n.Email)) // Setup custom npm registry if n.Registry != "" { f.WriteCmdSilent(fmt.Sprintf("npm config set registry %s", n.Registry)) } f.WriteCmd(fmt.Sprintf(npmPublishCmd, n.Folder)) }
// 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.Split(env, "=") if len(parts) != 2 { continue } f.WriteEnv(parts[0], parts[1]) } // append build commands for _, cmd := range b.Script { f.WriteCmd(cmd) } }
func (m *Modulus) Write(f *buildfile.Buildfile) { f.WriteEnv("MODULUS_TOKEN", m.Token) // 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 '%s'", m.Project)) }
// 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) } // write exit value f.WriteCmd("exit 0") }
// 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.Split(env, "=") if len(parts) != 2 { continue } f.WriteEnv(parts[0], parts[1]) } // add hostfile definitions //for _, mapping := range b.Hosts { // f.WriteCmdSilent(fmt.Sprintf("[ -f /usr/bin/sudo ] || echo %q | tee -a /etc/hosts", mapping)) // f.WriteCmdSilent(fmt.Sprintf("[ -f /usr/bin/sudo ] && echo %q | sudo tee -a /etc/hosts", mapping)) //} // append build commands for _, cmd := range b.Script { f.WriteCmd(cmd) } }
func (p *PyPI) Write(f *buildfile.Buildfile) { if len(p.Username) == 0 || len(p.Password) == 0 { // nothing to do if the config is fundamentally flawed return } 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, p.Username, p.Password)) formatStr := p.BuildFormatStr() // if we found the setup.py file use it to deploy f.WriteCmdSilent(fmt.Sprintf(deployCmd, formatStr)) }
// 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 %s" f.WriteCmd(fmt.Sprintf(sshCmd, host[1], strings.SplitN(host[0], ":", 2)[0], s.Cmd)) } }
func (h *Heroku) Write(f *buildfile.Buildfile) { // get the current commit hash f.WriteCmdSilent("COMMIT=$(git rev-parse HEAD)") // set the git user and email based on the individual // that made the commit. f.WriteCmdSilent("git config --global user.name $(git --no-pager log -1 --pretty=format:'%an')") f.WriteCmdSilent("git config --global user.email $(git --no-pager log -1 --pretty=format:'%ae')") // add heroku as a git remote f.WriteCmd(fmt.Sprintf("git remote add heroku [email protected]:%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 $COMMIT:master --force")) case false: // otherwise we just do a standard git push f.WriteCmd(fmt.Sprintf("git push heroku $COMMIT:master")) } }
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)) }
func (g *Git) Write(f *buildfile.Buildfile) { // get the current commit hash f.WriteCmdSilent("COMMIT=$(git rev-parse HEAD)") // set the git user and email based on the individual // that made the commit. f.WriteCmdSilent("git config --global user.name $(git --no-pager log -1 --pretty=format:'%an')") f.WriteCmdSilent("git config --global user.email $(git --no-pager log -1 --pretty=format:'%ae')") // add target as a git remote f.WriteCmd(fmt.Sprintf("git remote add deploy %s", g.Target)) destinationBranch := g.Branch if destinationBranch == "" { destinationBranch = "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 $COMMIT:%s --force", destinationBranch)) case false: // otherwise we just do a standard git push f.WriteCmd(fmt.Sprintf("git push deploy $COMMIT:%s", destinationBranch)) } }
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 compress(f *buildfile.Buildfile, files []string) bool { cmd := "tar -cf ${ARTIFACT} %s" f.WriteEnv("ARTIFACT", "${PWD##*/}.tar.gz") f.WriteCmdSilent(fmt.Sprintf(cmd, strings.Join(files, " "))) return true }
func createGitArchive(f *buildfile.Buildfile) bool { f.WriteEnv("COMMIT", "$(git rev-parse HEAD)") f.WriteEnv("ARTIFACT", "${PWD##*/}-${COMMIT}.tar.gz") f.WriteCmdSilent("git archive --format=tar.gz --prefix=${PWD##*/}/ ${COMMIT} > ${ARTIFACT}") return true }
// Write adds commands to the buildfile to do the following: // 1. Install the docker client in the Drone container. // 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, r *repo.Repo) { if len(d.DockerServer) == 0 || d.DockerServerPort == 0 || len(d.DockerVersion) == 0 || len(d.ImageName) == 0 { f.WriteCmdSilent(`echo -e "Docker Plugin: Missing argument(s)"\n\n`) if len(d.DockerServer) == 0 { f.WriteCmdSilent(`echo -e "\tdocker_server not defined in yaml`) } if d.DockerServerPort == 0 { f.WriteCmdSilent(`echo -e "\tdocker_port not defined in yaml`) } if len(d.DockerVersion) == 0 { f.WriteCmdSilent(`echo -e "\tdocker_version not defined in yaml`) } if len(d.ImageName) == 0 { f.WriteCmdSilent(`echo -e "\timage_name not defined in yaml`) } return } // Ensure correct apt-get has the https method-driver as per (http://askubuntu.com/questions/165676/) f.WriteCmd("sudo apt-get install apt-transport-https") // Install Docker on the container f.WriteCmd("sudo sh -c \"echo deb https://get.docker.io/ubuntu docker main\\ > " + "/etc/apt/sources.list.d/docker.list\"") f.WriteCmd("sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys " + "36A1D7869245C8950F966E92D8576A8BA88D21E9") f.WriteCmd("sudo apt-get update") f.WriteCmd("sudo apt-get --yes install lxc-docker-" + d.DockerVersion) // Format our Build Server Endpoint dockerServerUrl := d.DockerServer + ":" + strconv.Itoa(d.DockerServerPort) dockerPath := "." if len(d.Dockerfile) != 0 { dockerPath = fmt.Sprintf("- < %s", d.Dockerfile) } // Run the command commands to build and deploy the image. // Are we setting a custom tag, or do we use the git hash? imageTag := "" if len(d.CustomTag) > 0 { imageTag = d.CustomTag } else { imageTag = "$(git rev-parse --short HEAD)" } f.WriteCmd(fmt.Sprintf("docker -H %s build -t %s:%s %s", dockerServerUrl, d.ImageName, imageTag, dockerPath)) // Login? if d.RegistryLogin == true { // Are we logging in to a custom Registry? if len(d.RegistryLoginUrl) > 0 { f.WriteCmdSilent(fmt.Sprintf("docker -H %s login -u %s -p %s -e %s %s", dockerServerUrl, d.Username, d.Password, d.Email, d.RegistryLoginUrl)) } else { // Assume index.docker.io f.WriteCmdSilent(fmt.Sprintf("docker -H %s login -u %s -p %s -e %s", dockerServerUrl, d.Username, d.Password, d.Email)) } } // Are we overriding the "latest" tag? if d.PushLatest { f.WriteCmd(fmt.Sprintf("docker -H %s tag %s:%s %s:latest", dockerServerUrl, d.ImageName, imageTag, d.ImageName)) } f.WriteCmd(fmt.Sprintf("docker -H %s push %s", dockerServerUrl, d.ImageName)) // Delete the image from the docker server we built on. if !d.KeepBuild { f.WriteCmd(fmt.Sprintf("docker -H %s rmi %s:%s", dockerServerUrl, d.ImageName, imageTag)) if d.PushLatest { f.WriteCmd(fmt.Sprintf("docker -H %s rmi %s:latest", dockerServerUrl, d.ImageName)) } } }
func (s *S3) Write(f *buildfile.Buildfile) { // 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.Region) == 0 { s.Region = "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)) } }