Skip to content

Commit

Permalink
implement push
Browse files Browse the repository at this point in the history
  • Loading branch information
noamcattan committed Feb 16, 2025
1 parent 305287b commit 9c44257
Show file tree
Hide file tree
Showing 9 changed files with 690 additions and 464 deletions.
878 changes: 442 additions & 436 deletions .github/workflows/ci-go.yaml

Large diffs are not rendered by default.

121 changes: 120 additions & 1 deletion atlasaction/action.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,15 @@ import (
"encoding/json"
"errors"
"fmt"
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing"
"github.com/go-git/go-git/v5/plumbing/object"
"github.com/go-git/go-git/v5/plumbing/transport/http"
"io"
"log"
"net/url"
"os"
"path"
"slices"
"strconv"
"strings"
Expand Down Expand Up @@ -66,6 +72,8 @@ type (
CommentLint(context.Context, *TriggerContext, *atlasexec.SummaryReport) error
// CommentPlan comments on the pull request with the schema plan.
CommentPlan(context.Context, *TriggerContext, *atlasexec.SchemaPlan) error
// IsCoAuthored checks if the given commit is co-authored by a bot.
IsCoAuthored(ctx context.Context, commit string) (bool, error)
}
Logger interface {
// Infof logs an info message.
Expand All @@ -92,6 +100,8 @@ type (
MigrateDown(context.Context, *atlasexec.MigrateDownParams) (*atlasexec.MigrateDown, error)
// MigrateLintError runs the `migrate lint` command and fails if there are lint errors.
MigrateLintError(context.Context, *atlasexec.MigrateLintParams) error
// MigrateHash runs the `migrate lint` command and fails if there are lint errors.
MigrateHash(context.Context, *atlasexec.MigrateHashParams) error
// MigratePush runs the `migrate push` command.
MigratePush(context.Context, *atlasexec.MigratePushParams) (string, error)
// MigrateTest runs the `migrate test` command.
Expand Down Expand Up @@ -474,10 +484,119 @@ func (a *Actions) MigrateLint(ctx context.Context) error {
if dirName == "" {
return errors.New("atlasaction: missing required parameter dir-name")
}
dirURL := a.GetInput("dir")
tc, err := a.GetTriggerContext(ctx)
if err != nil {
return err
}
a.Infof("Branch: %s", tc.Branch)
if a.GetBoolInput("auto-hash") && tc.PullRequest != nil && strings.HasPrefix(dirURL, "file://") {
a.Infof("Checking if scm client exists")
scm, err := tc.SCMClient()
switch {
case errors.Is(err, ErrNoSCM):
case err != nil:
return err
default:
dirPath := strings.TrimPrefix(dirURL, "file://")
a.Infof("SCM client exists. checking if commit is co-authored")
coAuthored, err := scm.IsCoAuthored(ctx, tc.PullRequest.Commit)
if err != nil {
return err
}
if !coAuthored {
break
}
a.Infof("commit is co-authored. running migrate hash")
if err := a.Atlas.MigrateHash(ctx, &atlasexec.MigrateHashParams{
DirURL: dirURL,
ConfigURL: a.GetInput("config"),
Env: a.GetInput("env"),
Vars: a.GetVarsInput("vars"),
}); err != nil {
return err
}
r, err := git.PlainOpen(".")
if err != nil {
return err
}
w, err := r.Worktree()
if err != nil {
return err
}
a.Infof("checking out branch %s", plumbing.NewBranchReferenceName(tc.Branch))
if err := w.Checkout(&git.CheckoutOptions{
Branch: plumbing.NewBranchReferenceName(tc.Branch),
Create: true,
Force: true,
}); err != nil {
return err
}
a.Infof("Pulling from remote")
if err := w.PullContext(ctx, &git.PullOptions{RemoteName: "origin"}); err != nil {
return err
}
status, err := w.Status()
if err != nil {
return err
}
a.Infof("git status: %s", status.String())
if f := status.File(path.Join(dirPath, "atlas.sum")); f == nil || f.Worktree != git.Modified {
break
}
a.Infof("staging file")
if _, err := w.Add(path.Join(dirPath, "atlas.sum")); err != nil {
return err
}
status, err = w.Status()
if err != nil {
return err
}
a.Infof("git status: %s", status.String())
a.Infof("setting git config")
conf, err := r.Config()
if err != nil {
return err
}
conf.Author.Name = "Atlas Action"
conf.Author.Email = "[email protected]"
if err := r.SetConfig(conf); err != nil {
return err
}
a.Infof("committing changes")
if _, err := w.Commit("fix directory sum file [skip ci]", &git.CommitOptions{}); err != nil {
return err
}
status, err = w.Status()
if err != nil {
return err
}
a.Infof("git status: %s", status.String())
headRef, err := r.Head()
if err != nil {
log.Fatalf("Failed to get HEAD reference: %v", err)
}
log.Printf("Current branch: %s\n", headRef.Name().Short())
commitIter, _ := r.Log(&git.LogOptions{})
commitCount := 0
commitIter.ForEach(func(c *object.Commit) error {

Check failure on line 582 in atlasaction/action.go

View workflow job for this annotation

GitHub Actions / golangci-lint

Error return value of `commitIter.ForEach` is not checked (errcheck)
commitCount++
log.Println("Commit:", c.Hash, c.Message)
return nil
})
log.Printf("Total commits: %d", commitCount)
remotes, _ := r.Remotes()
for _, remote := range remotes {
log.Println("Remote:", remote.Config().URLs)
}
a.Infof("pushing changes")
if err := r.PushContext(ctx, &git.PushOptions{
Auth: &http.BasicAuth{Username: "Atlas Action", Password: tc.Act.Getenv("GITHUB_TOKEN")}},
); err != nil {
return err
}
}
}
var (
resp bytes.Buffer
isLintErr bool
Expand All @@ -487,7 +606,7 @@ func (a *Actions) MigrateLint(ctx context.Context) error {
switch err := a.Atlas.MigrateLintError(ctx, &atlasexec.MigrateLintParams{
Context: rc,
DevURL: a.GetInput("dev-url"),
DirURL: a.GetInput("dir"),
DirURL: dirURL,
ConfigURL: a.GetInput("config"),
Env: a.GetInput("env"),
Base: a.GetAtlasURLInput("dir-name", "tag"),
Expand Down
9 changes: 9 additions & 0 deletions atlasaction/action_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,11 @@ func (m *mockAtlas) MigrateLintError(context.Context, *atlasexec.MigrateLintPara
panic("unimplemented")
}

// MigrateHash implements AtlasExec.
func (m *mockAtlas) MigrateHash(context.Context, *atlasexec.MigrateHashParams) error {
panic("unimplemented")
}

// MigratePush implements AtlasExec.
func (m *mockAtlas) MigratePush(context.Context, *atlasexec.MigratePushParams) (string, error) {
panic("unimplemented")
Expand Down Expand Up @@ -2162,6 +2167,10 @@ func (m *mockSCM) comment(_ context.Context, _ *atlasaction.PullRequest, id stri
return err
}

func (m *mockSCM) IsCoAuthored(context.Context, string) (bool, error) {
return false, nil
}

// Why another testscript for templates?
// Because I love to see the output in its full glory.
// Instead of a mess of quotes and escapes, I can see the actual output.
Expand Down
5 changes: 5 additions & 0 deletions atlasaction/bitbucket.go
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,11 @@ func (c *bbClient) upsertComment(ctx context.Context, prID int, id, comment stri
return err
}

func (c *bbClient) IsCoAuthored(context.Context, string) (bool, error) {
// Not implemented.
return false, nil
}

// hash returns the SHA-256 hash of the parts.
// The hash is encoded using base64.RawURLEncoding.
func hash(parts ...string) (string, error) {
Expand Down
5 changes: 0 additions & 5 deletions atlasaction/gh_action.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,11 +181,6 @@ func (c *ghClient) CommentLint(ctx context.Context, tc *TriggerContext, r *atlas
if err != nil {
return err
}
if co, err := c.IsCoAuthored(ctx, tc.PullRequest.Commit); err != nil {
return err
} else {
fmt.Printf("Commit co-authored: %v\n", co)
}
switch files, err := c.ListPullRequestFiles(ctx, tc.PullRequest.Number); {
case err != nil:
tc.Act.Errorf("failed to list pull request files: %w", err)
Expand Down
5 changes: 5 additions & 0 deletions atlasaction/gitlab_ci.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,5 +137,10 @@ func (c *glClient) upsertComment(ctx context.Context, pr *PullRequest, id, comme
return c.CreateNote(ctx, pr.Number, comment)
}

func (c *glClient) IsCoAuthored(context.Context, string) (bool, error) {
// Not implemented.
return false, nil
}

var _ Action = (*gitlabCI)(nil)
var _ SCMClient = (*glClient)(nil)
31 changes: 27 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,57 @@ go 1.23

require (
ariga.io/atlas v0.21.2-0.20240418081819-02b3f6239b04
ariga.io/atlas-go-sdk v0.6.6-0.20250212175821-4ab021f3ab2e
ariga.io/atlas-go-sdk v0.6.6
github.com/alecthomas/kong v0.8.0
github.com/fatih/color v1.17.0
github.com/hashicorp/go-retryablehttp v0.7.7
github.com/mattn/go-sqlite3 v1.14.17
github.com/mitchellh/mapstructure v1.1.2
github.com/rogpeppe/go-internal v1.12.1-0.20240709150035-ccf4b4329d21
github.com/sethvargo/go-githubactions v1.3.0
github.com/stretchr/testify v1.8.4
github.com/stretchr/testify v1.10.0
github.com/vektah/gqlparser v1.3.1
golang.org/x/oauth2 v0.22.0
)

require (
dario.cat/mergo v1.0.0 // indirect
github.com/Microsoft/go-winio v0.6.1 // indirect
github.com/ProtonMail/go-crypto v1.1.5 // indirect
github.com/agext/levenshtein v1.2.3 // indirect
github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect
github.com/cloudflare/circl v1.3.7 // indirect
github.com/cyphar/filepath-securejoin v0.3.6 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/emirpasic/gods v1.18.1 // indirect
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
github.com/go-git/go-billy/v5 v5.6.2 // indirect
github.com/go-git/go-git/v5 v5.13.2 // indirect
github.com/go-openapi/inflect v0.19.0 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/hcl/v2 v2.18.1 // indirect
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
github.com/kevinburke/ssh_config v1.2.0 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
github.com/pjbgf/sha1cd v0.3.2 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect
github.com/skeema/knownhosts v1.3.0 // indirect
github.com/xanzy/ssh-agent v0.3.3 // indirect
github.com/zclconf/go-cty v1.14.1 // indirect
golang.org/x/sys v0.21.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/crypto v0.32.0 // indirect
golang.org/x/mod v0.18.0 // indirect
golang.org/x/net v0.34.0 // indirect
golang.org/x/sync v0.10.0 // indirect
golang.org/x/sys v0.29.0 // indirect
golang.org/x/text v0.21.0 // indirect
golang.org/x/tools v0.22.0 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
Loading

0 comments on commit 9c44257

Please sign in to comment.