func()

in cmd/publishing-bot/publisher.go [228:349]


func (p *PublisherMunger) construct() error {
	sourceRemote := filepath.Join(p.baseRepoPath, p.config.SourceRepo, ".git")

	if err := golang.InstallGoVersions(&p.reposRules); err != nil {
		return err
	}

	for _, repoRule := range p.reposRules.Rules {
		if repoRule.Skip {
			continue
		}

		// clone the destination repo
		dstDir := filepath.Join(p.baseRepoPath, repoRule.DestinationRepository, "")
		dstURL := fmt.Sprintf("https://%s/%s/%s.git", p.config.GithubHost, p.config.TargetOrg, repoRule.DestinationRepository)
		if err := p.ensureCloned(dstDir, dstURL); err != nil {
			p.plog.Errorf("%v", err)
			return err
		}
		p.plog.Infof("Successfully ensured %s exists", dstDir)
		if err := os.Chdir(dstDir); err != nil {
			return err
		}

		// delete tags
		cmd := exec.Command("/bin/bash", "-c", "git tag | xargs git tag -d >/dev/null")
		if err := p.plog.Run(cmd); err != nil {
			return err
		}

		formatDeps := func(deps []config.Dependency) string {
			var depStrings []string
			for _, dep := range deps {
				depStrings = append(depStrings, fmt.Sprintf("%s:%s", dep.Repository, dep.Branch))
			}
			return strings.Join(depStrings, ",")
		}

		// construct branches
		for _, branchRule := range repoRule.Branches {
			if p.skippedBranch(branchRule.Source.Branch) {
				continue
			}
			if branchRule.Source.Dir == "" {
				branchRule.Source.Dir = "."
				p.plog.Infof("%v: 'dir' cannot be empty, defaulting to '.'", branchRule)
			}

			// get old HEAD. Ignore errors as the branch might be non-existent
			// nolint: errcheck
			oldHead, _ := exec.Command("git", "rev-parse", fmt.Sprintf("origin/%s", branchRule.Name)).Output()

			goPath := os.Getenv("GOPATH")
			branchEnv := append([]string(nil), os.Environ()...) // make mutable
			if branchRule.GoVersion != "" {
				goRoot := filepath.Join(goPath, "go-"+branchRule.GoVersion)
				branchEnv = append(branchEnv, "GOROOT="+goRoot)
				goBin := filepath.Join(goRoot, "bin")
				branchEnv = updateEnv(branchEnv, "PATH", prependPath(goBin), goBin)
			}

			skipTags := ""
			if p.reposRules.SkipTags {
				skipTags = "true"
				p.plog.Infof("synchronizing tags is disabled")
			}

			// get old published hash to eventually skip cherry picking
			var lastPublishedUpstreamHash string
			bs, err := ioutil.ReadFile(path.Join(p.baseRepoPath, publishedFileName(repoRule.DestinationRepository, branchRule.Name)))
			if err != nil && !os.IsNotExist(err) {
				return err
			}
			if err == nil {
				lastPublishedUpstreamHash = string(bs)
			}

			// TODO: Refactor this to use environment variables instead
			repoPublishScriptPath := filepath.Join(p.config.BasePublishScriptPath, "construct.sh")
			cmd := exec.Command(repoPublishScriptPath,
				repoRule.DestinationRepository,
				branchRule.Source.Branch,
				branchRule.Name,
				formatDeps(branchRule.Dependencies),
				strings.Join(branchRule.RequiredPackages, ":"),
				sourceRemote,
				branchRule.Source.Dir,
				p.config.SourceRepo,
				p.config.SourceRepo,
				p.config.BasePackage,
				fmt.Sprintf("%v", repoRule.Library),
				strings.Join(p.reposRules.RecursiveDeletePatterns, " "),
				skipTags,
				lastPublishedUpstreamHash,
			)
			cmd.Env = append([]string(nil), branchEnv...) // make mutable
			if p.reposRules.SkipGomod {
				cmd.Env = append(cmd.Env, "PUBLISHER_BOT_SKIP_GOMOD=true")
			}
			if err := p.plog.Run(cmd); err != nil {
				return err
			}

			// TODO(lint): Should we be checking errors here?
			// nolint: errcheck
			newHead, _ := exec.Command("git", "rev-parse", "HEAD").Output()

			p.plog.Infof("Running branch-specific smoke tests for branch %s", branchRule.Name)
			if err := p.runSmokeTests(branchRule.SmokeTest, string(oldHead), string(newHead), branchEnv); err != nil {
				return err
			}

			p.plog.Infof("Running repo-specific smoke tests for branch %s", branchRule.Name)
			if err := p.runSmokeTests(repoRule.SmokeTest, string(oldHead), string(newHead), branchEnv); err != nil {
				return err
			}

			p.plog.Infof("Successfully constructed %s", branchRule.Name)
		}
	}
	return nil
}