func (a *App) ForkRelease() (*Release, error) { release := structs.NewRelease(a.Name) if a.Release != "" { r, err := Provider().ReleaseGet(a.Name, a.Release) if err != nil { return nil, err } release = r } release.Id = generateId("R", 10) release.Created = time.Now() env, err := Provider().EnvironmentGet(a.Name) if err != nil { fmt.Printf("fn=ForkRelease level=error msg=\"error getting environment: %s\"", err) } release.Env = env.Raw() return &Release{ Id: release.Id, App: release.App, Build: release.Build, Env: release.Env, Manifest: release.Manifest, Created: release.Created, }, nil }
// ForkRelease creates a new release based on the app's release func ForkRelease(app *structs.App) (*structs.Release, error) { release := structs.NewRelease(app.Name) if app.Release != "" { r, err := models.Provider().ReleaseGet(app.Name, app.Release) if err != nil { return nil, err } id := release.Id created := release.Created release = r release.Id = id release.Created = created } env, err := models.Provider().EnvironmentGet(app.Name) if err != nil { fmt.Printf("fn=ForkRelease level=error msg=\"error getting environment: %s\"", err) } release.Env = env.Raw() return &structs.Release{ Id: release.Id, App: release.App, Build: release.Build, Env: release.Env, Manifest: release.Manifest, Created: release.Created, }, nil }
func (p *AWSProvider) BuildRelease(b *structs.Build) (*structs.Release, error) { releases, err := p.ReleaseList(b.App) if err != nil { return nil, err } r := structs.NewRelease(b.App) newId := r.Id if len(releases) > 0 { r = &releases[0] } r.Id = newId r.Created = time.Time{} r.Build = b.Id r.Manifest = b.Manifest a, err := p.AppGet(b.App) if err != nil { return r, err } err = p.ReleaseSave(r, a.Outputs["Settings"], a.Parameters["Key"]) if err != nil { return r, err } b.Release = r.Id err = p.BuildSave(b) if err == nil { p.EventSend(&structs.Event{ Action: "release:create", Data: map[string]string{ "app": r.App, "id": r.Id, }, }, nil) } return r, err }
// BuildImport imports a build artifact func (p *AWSProvider) BuildImport(app string, r io.Reader) (*structs.Build, error) { log := Logger.At("BuildImport").Namespace("app=%s", app).Start() var sourceBuild structs.Build // set up the new build targetBuild := structs.NewBuild(app) targetBuild.Started = time.Now() targetBuild.Status = "complete" if p.IsTest() { targetBuild.Id = "B12345" } repo, err := p.appRepository(app) if err != nil { log.Error(err) return nil, err } if err := p.dockerLogin(); err != nil { log.Error(err) return nil, err } gz, err := gzip.NewReader(r) if err != nil { log.Error(err) return nil, err } tr := tar.NewReader(gz) for { header, err := tr.Next() if err == io.EOF { break } if err != nil { log.Error(err) return nil, err } if header.Typeflag != tar.TypeReg { continue } if header.Name == "build.json" { var buf bytes.Buffer io.Copy(&buf, tr) if err := json.Unmarshal(buf.Bytes(), &sourceBuild); err != nil { log.Error(err) return nil, err } } if strings.HasSuffix(header.Name, ".tar") { log.Step("load").Logf("tar=%q", header.Name) cmd := exec.Command("docker", "load") pr, pw := io.Pipe() tee := io.TeeReader(tr, pw) outb := &bytes.Buffer{} cmd.Stdin = pr cmd.Stdout = outb if err := cmd.Start(); err != nil { log.Error(err) return nil, err } log.Step("manifest").Logf("tar=%q", header.Name) manifest, err := extractImageManifest(tee) if err != nil { log.Error(err) return nil, err } if err := pw.Close(); err != nil { log.Error(err) return nil, err } if err := cmd.Wait(); err != nil { return nil, log.Errorf("%s: %s\n", lastline(outb.Bytes()), err.Error()) } if len(manifest) != 1 || len(manifest[0].RepoTags) != 1 { log.Errorf("invalid image manifest") return nil, fmt.Errorf("invalid image manifest") } image := manifest[0].RepoTags[0] ps := strings.Split(header.Name, ".")[0] target := fmt.Sprintf("%s:%s.%s", repo.URI, ps, targetBuild.Id) log.Step("tag").Logf("from=%q to=%q", image, target) if out, err := exec.Command("docker", "tag", image, target).CombinedOutput(); err != nil { return nil, log.Error(fmt.Errorf("%s: %s\n", lastline(out), err.Error())) } log.Step("push").Logf("to=%q", target) if out, err := exec.Command("docker", "push", target).CombinedOutput(); err != nil { return nil, log.Error(fmt.Errorf("%s: %s\n", lastline(out), err.Error())) } } } env, err := p.EnvironmentGet(app) if err != nil { log.Error(err) return nil, err } release := structs.NewRelease(app) if p.IsTest() { release.Id = "R23456" } targetBuild.Description = sourceBuild.Description targetBuild.Ended = time.Now() targetBuild.Logs = sourceBuild.Logs targetBuild.Manifest = sourceBuild.Manifest targetBuild.Release = release.Id if err := p.BuildSave(targetBuild); err != nil { log.Error(err) return nil, err } release.Env = env.Raw() release.Build = targetBuild.Id release.Manifest = targetBuild.Manifest if err := p.ReleaseSave(release); err != nil { log.Error(err) return nil, err } log.Successf("build=%q release=%q", targetBuild.Id, release.Id) return targetBuild, nil }