Skip to content

Commit

Permalink
wip: implement clone directive
Browse files Browse the repository at this point in the history
Signed-off-by: Kent Rancourt <[email protected]>
  • Loading branch information
krancour committed Aug 28, 2024
1 parent 141a5f1 commit 2904485
Showing 1 changed file with 87 additions and 3 deletions.
90 changes: 87 additions & 3 deletions internal/directives/git_clone_directive.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,14 @@ package directives
import (
"context"
"fmt"
"path/filepath"

"github.com/xeipuuv/gojsonschema"

kargoapi "github.com/akuity/kargo/api/v1alpha1"
"github.com/akuity/kargo/internal/controller/freight"
"github.com/akuity/kargo/internal/controller/git"
"github.com/akuity/kargo/internal/credentials"
)

func init() {
Expand Down Expand Up @@ -38,7 +44,7 @@ func (g *gitCloneDirective) Name() string {

// Run implements the Directive interface.
func (g *gitCloneDirective) Run(
_ context.Context,
ctx context.Context,
stepCtx *StepContext,
) (Result, error) {
// Validate the configuration against the JSON Schema
Expand All @@ -49,10 +55,88 @@ func (g *gitCloneDirective) Run(
); err != nil {
return ResultFailure, err
}
if _, err := configToStruct[GitCloneConfig](stepCtx.Config); err != nil {
cfg, err := configToStruct[GitCloneConfig](stepCtx.Config)
if err != nil {
return ResultFailure,
fmt.Errorf("could not convert config into git-clone config: %w", err)
}
// TODO: Add implementation here
if err = g.run(ctx, stepCtx, cfg); err != nil {
return ResultFailure, err
}
return ResultSuccess, nil
}

func (g *gitCloneDirective) run(
ctx context.Context,
stepCtx *StepContext,
cfg GitCloneConfig,
) error {
var repoCreds *git.RepoCredentials
if creds, found, err := stepCtx.CredentialsDB.Get(
ctx,
stepCtx.Project,
credentials.TypeGit,
cfg.RepoURL,
); err != nil {
return fmt.Errorf("error getting credentials for %s: %w", cfg.RepoURL, err)
} else if found {
repoCreds = &git.RepoCredentials{
Username: creds.Username,
Password: creds.Password,
SSHPrivateKey: creds.SSHPrivateKey,
}
}
clientOpts := &git.ClientOptions{
Credentials: repoCreds,
}
cloneOpts := &git.CloneOptions{
Bare: true,
BaseDir: stepCtx.WorkDir,
InsecureSkipTLSVerify: cfg.InsecureSkipTLSVerify,
}
repo, err := git.Clone(cfg.RepoURL, clientOpts, cloneOpts)
if err != nil {
return fmt.Errorf("error cloning %s: %w", cfg.RepoURL, err)
}
for _, checkout := range cfg.Checkout {
var ref string
switch {
case checkout.Branch != "":
ref = checkout.Branch
case checkout.FromFreight:
var desiredOrigin *kargoapi.FreightOrigin
if checkout.FromOrigin == nil {
desiredOrigin = &kargoapi.FreightOrigin{
Kind: kargoapi.FreightOriginKind(checkout.FromOrigin.Kind),
}
}
var commit *kargoapi.GitCommit
if commit, err = freight.FindCommit(
ctx,
stepCtx.KargoClient,
stepCtx.Project,
stepCtx.FreightRequests,
desiredOrigin,
stepCtx.Freight.References(),
cfg.RepoURL,
); err != nil {
return fmt.Errorf("error finding commit from repo %s: %w", cfg.RepoURL, err)
}
ref = commit.ID
case checkout.Tag != "":
ref = checkout.Tag
}
// TODO: Make this safer using github.com/cyphar/filepath-securejoin
path := filepath.Join(stepCtx.WorkDir, checkout.Path)
if err = repo.AddWorkTree(path, ref); err != nil {
return fmt.Errorf(
"error adding work tree %s to repo %s: %w",
checkout.Path, cfg.RepoURL, err,
)
}
}
// Note: We do NOT defer repo.Close() because we want to keep the repository
// around for subsequent directives to use. The directive execution engine
// will handle all cleanup.
return nil
}

0 comments on commit 2904485

Please sign in to comment.