blob: 223373d21c735bdd80e1e6dd7e5293e2232a8472 [file]
// Activities to access Chromium git repositories.
package internal
import (
"context"
"fmt"
"os"
"go.skia.org/infra/go/auth"
"go.skia.org/infra/go/exec"
"go.skia.org/infra/go/gerrit"
"go.skia.org/infra/go/git"
"go.skia.org/infra/go/gitiles"
"go.skia.org/infra/go/httputils"
"go.skia.org/infra/go/skerr"
"go.skia.org/infra/go/sklog"
"go.skia.org/infra/pinpoint/go/common"
pb "go.skia.org/infra/pinpoint/proto/v1"
"golang.org/x/oauth2/google"
)
const (
REPO_CHROMIUM = "https://chromium.googlesource.com/chromium/src.git"
GERRIT_CHROMIUM = "https://chromium-review.googlesource.com"
)
// gitClient info.
type gitClient struct {
// TODO(b/515025206): Consider removing the context from this structure.
// Instead, pass the context as the first parameter to the structure methods.
ctx context.Context
repo *gitiles.Repo
repoUrl string
gerritClient *gerrit.Gerrit
gitExec string
repoDir string
}
func NewGitChromium(ctx context.Context) (*gitClient, error) {
return NewGitClient(ctx, REPO_CHROMIUM, GERRIT_CHROMIUM)
}
func NewGitClient(ctx context.Context, repoUrl, gerritUrl string) (*gitClient, error) {
ts, err := google.DefaultTokenSource(ctx, auth.ScopeGerrit)
if err != nil {
return nil, skerr.Wrap(err)
}
client := httputils.DefaultClientConfig().WithTokenSource(ts).Client()
repo, err := gitiles.NewRepoWithClient(repoUrl, client)
if err != nil {
return nil, skerr.Wrap(err)
}
gerritClient, err := gerrit.NewGerrit(gerritUrl, client)
if err != nil {
return nil, skerr.Wrap(err)
}
git, err := git.Executable(ctx)
if err != nil {
return nil, skerr.Wrap(err)
}
return &gitClient{
ctx: ctx,
repo: repo,
repoUrl: repoUrl,
gerritClient: gerritClient,
gitExec: git,
}, nil
}
// ReadGitFileActivity is an Activity that reads the contents of a file from a git commit.
func ReadGitFileActivity(ctx context.Context, combinedCommit *common.CombinedCommit, path string) ([]byte, error) {
sklog.Info("ReadGitFileActivity started")
var commit *pb.Commit
if len(combinedCommit.ModifiedDeps) > 0 {
commit = combinedCommit.ModifiedDeps[len(combinedCommit.ModifiedDeps)-1]
} else {
commit = combinedCommit.Main
}
repo, err := gitiles.NewRepo(ctx, commit.Repository)
if err != nil {
return nil, skerr.Wrap(err)
}
b, err := repo.ReadFileAtRef(ctx, path, commit.GitHash)
if err != nil {
return nil, skerr.Wrap(err)
}
return b, nil
}
// ShallowClone creates a shallow clone of the given repo at the given commit.
func (client *gitClient) ShallowClone(branchName string, isDev bool) error {
dirNamePattern := fmt.Sprintf("%s-*", branchName)
checkoutDir, err := os.MkdirTemp("", dirNamePattern)
if err != nil {
return skerr.Wrapf(err, "Failed to create folder: %s", checkoutDir)
}
sklog.Infof("Repository temp dir: %s", checkoutDir)
if _, err := exec.RunCwd(client.ctx, checkoutDir, client.gitExec, "init"); err != nil {
return skerr.Wrapf(err, "Failed to init Git")
}
if !isDev {
if _, err := exec.RunCwd(client.ctx, checkoutDir, client.gitExec, "config",
"user.email", "pinpoint-worker@skia-infra-corp.iam.gserviceaccount.com"); err != nil {
return skerr.Wrapf(err, "Failed to config user email")
}
if _, err := exec.RunCwd(client.ctx, checkoutDir, client.gitExec, "config", "user.name", "Pinpoint Worker"); err != nil {
return skerr.Wrapf(err, "Failed to config user name")
}
}
if _, err := exec.RunCwd(client.ctx, checkoutDir, client.gitExec, "remote", "add", "origin", client.repoUrl); err != nil {
return skerr.Wrapf(err, "Failed to add remote Git")
}
sklog.Info("Git fetch --depth=1 origin/main")
if _, err := exec.RunCwd(client.ctx, checkoutDir, client.gitExec, "fetch", "--depth=1", "origin", "main"); err != nil {
return skerr.Wrapf(err, "Failed to fetch origin/main")
}
sklog.Info("Git checkout FETCH_HEAD")
if _, err := exec.RunCwd(client.ctx, checkoutDir, client.gitExec, "checkout", "FETCH_HEAD"); err != nil {
return skerr.Wrapf(err, "Failed to checkout FETCH_HEAD")
}
if _, err := exec.RunCwd(
client.ctx, checkoutDir, client.gitExec, "checkout", "-b",
branchName, "-t", "origin/main"); err != nil {
return skerr.Wrapf(err, "Failed to create a new branch")
}
client.repoDir = checkoutDir
sklog.Infof("Git clone of %s to %s was successful!", client.repoUrl, checkoutDir)
return nil
}