From 6e7f07065745e647a1709df5787ede67bed0c9d8 Mon Sep 17 00:00:00 2001 From: David Alberto Adler Date: Wed, 7 May 2025 08:27:44 +0100 Subject: [PATCH 01/12] --- internal/cli/run.go | 5 ---- internal/git/git.go | 71 ++++++++++++++++++++++++++++++--------------- testing/pr-mode.env | 3 +- testing/test.sh | 4 +-- 4 files changed, 50 insertions(+), 33 deletions(-) diff --git a/internal/cli/run.go b/internal/cli/run.go index 6f02ea31..d7e6acaf 100644 --- a/internal/cli/run.go +++ b/internal/cli/run.go @@ -61,11 +61,6 @@ func Run(sourcesOnly bool, installationURLs map[string]string, repoURL string, r args = append(args, "--set-version", environment.SetVersion()) } - // If we are in PR mode we skip testing on generation, this should run as a PR check - if environment.SkipTesting() || (environment.GetMode() == environment.ModePR && !sourcesOnly) { - args = append(args, "--skip-testing") - } - if environment.ForceGeneration() { fmt.Println("\nforce input enabled - setting SPEAKEASY_FORCE_GENERATION=true") os.Setenv("SPEAKEASY_FORCE_GENERATION", "true") diff --git a/internal/git/git.go b/internal/git/git.go index 7e70007c..1dfa4b38 100644 --- a/internal/git/git.go +++ b/internal/git/git.go @@ -368,34 +368,52 @@ func (g *Git) CommitAndPush(openAPIDocVersion, speakeasyVersion, doc string, act return "", fmt.Errorf("error getting worktree: %w", err) } - logging.Info("Commit and pushing changes to git") - - if err := g.Add("."); err != nil { - return "", fmt.Errorf("error adding changes: %w", err) + isSigned := "" + if environment.GetSignedCommits() { + isSigned = " (signed)" } + logging.Info("Commit and pushing changes to git " + isSigned) - var commitMessage string - if action == environment.ActionRunWorkflow { - commitMessage = fmt.Sprintf("ci: regenerated with OpenAPI Doc %s, Speakeasy CLI %s", openAPIDocVersion, speakeasyVersion) - if sourcesOnly { - commitMessage = fmt.Sprintf("ci: regenerated with Speakeasy CLI %s", speakeasyVersion) - } - } else if action == environment.ActionSuggest { - commitMessage = fmt.Sprintf("ci: suggestions for OpenAPI doc %s", doc) + speakeasyVersionSuffix := "(v" + speakeasyVersion + ")" + + commits := []struct { + paths []string + msg string + }{ + {paths: []string{"**/.speakeasy/", "*gen.yaml", "*gen.lock", "*workflow.yaml", "*workflow.lock"}, msg: "build: Speakeasy config and lock files " + speakeasyVersionSuffix}, + {paths: []string{"*.md"}, msg: "docs: regenerate markdown files " + speakeasyVersionSuffix}, + {paths: []string{"."}, msg: "feat: regenerate SDK " + speakeasyVersionSuffix}, } - // Create commit message + var lastCommitHash plumbing.Hash if !environment.GetSignedCommits() { - commitHash, err := w.Commit(commitMessage, &git.CommitOptions{ - Author: &object.Signature{ - Name: "speakeasybot", - Email: "bot@speakeasyapi.dev", - When: time.Now(), - }, - All: true, - }) + var err error + + err = w.Reset(&git.ResetOptions{Mode: git.SoftReset}) if err != nil { - return "", fmt.Errorf("error committing changes: %w", err) + return "", fmt.Errorf("error resetting: %w", err) + } + + for i, commit := range commits { + for _, path := range commit.paths { + if err = g.Add(path); err != nil { + logging.Info(fmt.Errorf("unable to add changes for %v: %w", path, err).Error()) + } + } + + commitHash, err := w.Commit(commit.msg, &git.CommitOptions{ + Author: &object.Signature{ + Name: "speakeasybot", + Email: "bot@speakeasyapi.dev", + When: time.Now(), + }, + AllowEmptyCommits: false, + All: i == len(commits)-1, + }) + if err != nil { + logging.Info(fmt.Errorf("unable to commit changes for %v: %w", commit.paths, err).Error()) + } + lastCommitHash = commitHash } if err := g.repo.Push(&git.PushOptions{ @@ -404,7 +422,11 @@ func (g *Git) CommitAndPush(openAPIDocVersion, speakeasyVersion, doc string, act }); err != nil { return "", pushErr(err) } - return commitHash.String(), nil + return lastCommitHash.String(), nil + } + + if err := g.Add("."); err != nil { + return "", fmt.Errorf("error adding changes: %w", err) } branch, err := g.GetCurrentBranch() @@ -447,7 +469,7 @@ func (g *Git) CommitAndPush(openAPIDocVersion, speakeasyVersion, doc string, act // Commit changes commitResult, _, err := g.client.Git.CreateCommit(context.Background(), owner, repo, &github.Commit{ - Message: github.String(commitMessage), + Message: github.String(commits[len(commits)-1].msg), Tree: &github.Tree{SHA: tree.SHA}, Parents: []*github.Commit{parentCommit}}, &github.CreateCommitOptions{}) if err != nil { @@ -520,6 +542,7 @@ func (g *Git) createAndPushTree(ref *github.Reference, sourceFiles git.Status) ( tree, _, err = g.client.Git.CreateTree(context.Background(), owner, repo, *ref.Object.SHA, entries) return tree, err } + func (g *Git) Add(arg string) error { // We execute this manually because go-git doesn't properly support gitignore cmd := exec.Command("git", "add", arg) diff --git a/testing/pr-mode.env b/testing/pr-mode.env index 1310a31e..3d064e71 100644 --- a/testing/pr-mode.env +++ b/testing/pr-mode.env @@ -1,7 +1,6 @@ INPUT_MODE="pr" -INPUT_ACTION="generate" INPUT_LANGUAGES="- go" GITHUB_REPOSITORY="speakeasy-api/sdk-generation-action-test-repo" INPUT_FORCE=true RUN_FINALIZE=true -INPUT_SIGNED_COMMITS=true \ No newline at end of file +INPUT_SIGNED_COMMITS=false \ No newline at end of file diff --git a/testing/test.sh b/testing/test.sh index 21c2ef1e..55e15084 100755 --- a/testing/test.sh +++ b/testing/test.sh @@ -4,7 +4,7 @@ ENV_FILE=$1 function run_action() { rm -rf ./repo || true - rm ./bin/speakeasy || true + rm -f ./bin/speakeasy || true go run main.go } @@ -20,6 +20,6 @@ fi set -o allexport && source ${ENV_FILE} && set +o allexport -rm output.txt || true +rm -f output.txt INPUT_ACTION="run-workflow" run_action From 5f5a5b52009d1a904aae91135dad119bb23e9519 Mon Sep 17 00:00:00 2001 From: David Alberto Adler Date: Fri, 9 May 2025 12:32:55 +0100 Subject: [PATCH 02/12] --- internal/cli/run.go | 5 +++++ internal/git/git.go | 5 ----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/internal/cli/run.go b/internal/cli/run.go index d7e6acaf..6f02ea31 100644 --- a/internal/cli/run.go +++ b/internal/cli/run.go @@ -61,6 +61,11 @@ func Run(sourcesOnly bool, installationURLs map[string]string, repoURL string, r args = append(args, "--set-version", environment.SetVersion()) } + // If we are in PR mode we skip testing on generation, this should run as a PR check + if environment.SkipTesting() || (environment.GetMode() == environment.ModePR && !sourcesOnly) { + args = append(args, "--skip-testing") + } + if environment.ForceGeneration() { fmt.Println("\nforce input enabled - setting SPEAKEASY_FORCE_GENERATION=true") os.Setenv("SPEAKEASY_FORCE_GENERATION", "true") diff --git a/internal/git/git.go b/internal/git/git.go index 1dfa4b38..b9754c79 100644 --- a/internal/git/git.go +++ b/internal/git/git.go @@ -389,11 +389,6 @@ func (g *Git) CommitAndPush(openAPIDocVersion, speakeasyVersion, doc string, act if !environment.GetSignedCommits() { var err error - err = w.Reset(&git.ResetOptions{Mode: git.SoftReset}) - if err != nil { - return "", fmt.Errorf("error resetting: %w", err) - } - for i, commit := range commits { for _, path := range commit.paths { if err = g.Add(path); err != nil { From 313714b2bb8eb38de1b5872553de6f2649a62a54 Mon Sep 17 00:00:00 2001 From: David Alberto Adler Date: Fri, 9 May 2025 20:27:38 +0100 Subject: [PATCH 03/12] --- internal/git/git.go | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/internal/git/git.go b/internal/git/git.go index b9754c79..fdf20d7e 100644 --- a/internal/git/git.go +++ b/internal/git/git.go @@ -374,15 +374,18 @@ func (g *Git) CommitAndPush(openAPIDocVersion, speakeasyVersion, doc string, act } logging.Info("Commit and pushing changes to git " + isSigned) - speakeasyVersionSuffix := "(v" + speakeasyVersion + ")" + catchAllCommitMessage := "feat: regenerated with Speakeasy CLI" + if action == environment.ActionSuggest { + catchAllCommitMessage = "feat: suggestions for OpenAPI spec" + } commits := []struct { paths []string msg string }{ - {paths: []string{"**/.speakeasy/", "*gen.yaml", "*gen.lock", "*workflow.yaml", "*workflow.lock"}, msg: "build: Speakeasy config and lock files " + speakeasyVersionSuffix}, - {paths: []string{"*.md"}, msg: "docs: regenerate markdown files " + speakeasyVersionSuffix}, - {paths: []string{"."}, msg: "feat: regenerate SDK " + speakeasyVersionSuffix}, + {paths: []string{"**/.speakeasy/", "*gen.yaml", "*gen.lock", "*workflow.yaml", "*workflow.lock"}, msg: "build: Speakeasy config and lock files"}, + {paths: []string{"*.md"}, msg: "docs: regenerate markdown files"}, + {paths: []string{"."}, msg: catchAllCommitMessage}, } var lastCommitHash plumbing.Hash @@ -420,6 +423,8 @@ func (g *Git) CommitAndPush(openAPIDocVersion, speakeasyVersion, doc string, act return lastCommitHash.String(), nil } + // ---- START Signed commits ---- + // TODO: Due to priority constraints we don't split up into multiple commits like we do above if err := g.Add("."); err != nil { return "", fmt.Errorf("error adding changes: %w", err) } @@ -464,7 +469,7 @@ func (g *Git) CommitAndPush(openAPIDocVersion, speakeasyVersion, doc string, act // Commit changes commitResult, _, err := g.client.Git.CreateCommit(context.Background(), owner, repo, &github.Commit{ - Message: github.String(commits[len(commits)-1].msg), + Message: github.String(catchAllCommitMessage), Tree: &github.Tree{SHA: tree.SHA}, Parents: []*github.Commit{parentCommit}}, &github.CreateCommitOptions{}) if err != nil { From 3445eadf4f5698d8781ad6f60a4a021fad4310e6 Mon Sep 17 00:00:00 2001 From: David Alberto Adler Date: Fri, 9 May 2025 20:28:21 +0100 Subject: [PATCH 04/12] --- Makefile | 3 +++ testing/pr-mode-signed-commits.env | 6 ++++++ 2 files changed, 9 insertions(+) create mode 100644 testing/pr-mode-signed-commits.env diff --git a/Makefile b/Makefile index 807e3afd..7ceb29dd 100644 --- a/Makefile +++ b/Makefile @@ -12,6 +12,9 @@ test-direct-mode-multi-sdk: test-pr-mode: docker compose run --rm main ./testing/test.sh ./testing/pr-mode.env +test-pr-mode-signed-commits: + docker compose run --rm main ./testing/test.sh ./testing/pr-mode-signed-commits.env + test-push-code-samples-only: docker compose run --rm main ./testing/test.sh ./testing/push-code-samples-only.env diff --git a/testing/pr-mode-signed-commits.env b/testing/pr-mode-signed-commits.env new file mode 100644 index 00000000..51033be5 --- /dev/null +++ b/testing/pr-mode-signed-commits.env @@ -0,0 +1,6 @@ +INPUT_MODE="pr" +INPUT_LANGUAGES="- go" +GITHUB_REPOSITORY="speakeasy-api/sdk-generation-action-test-repo" +INPUT_FORCE=true +RUN_FINALIZE=true +INPUT_SIGNED_COMMITS=true \ No newline at end of file From b20f82db4dbe3c3d1118310317e05f2b26d95813 Mon Sep 17 00:00:00 2001 From: David Alberto Adler Date: Fri, 9 May 2025 20:37:50 +0100 Subject: [PATCH 05/12] --- internal/git/git.go | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/internal/git/git.go b/internal/git/git.go index fdf20d7e..97597457 100644 --- a/internal/git/git.go +++ b/internal/git/git.go @@ -388,10 +388,10 @@ func (g *Git) CommitAndPush(openAPIDocVersion, speakeasyVersion, doc string, act {paths: []string{"."}, msg: catchAllCommitMessage}, } - var lastCommitHash plumbing.Hash if !environment.GetSignedCommits() { var err error + var commitHash plumbing.Hash for i, commit := range commits { for _, path := range commit.paths { if err = g.Add(path); err != nil { @@ -399,19 +399,20 @@ func (g *Git) CommitAndPush(openAPIDocVersion, speakeasyVersion, doc string, act } } - commitHash, err := w.Commit(commit.msg, &git.CommitOptions{ + h, err := w.Commit(commit.msg, &git.CommitOptions{ Author: &object.Signature{ Name: "speakeasybot", Email: "bot@speakeasyapi.dev", When: time.Now(), }, AllowEmptyCommits: false, - All: i == len(commits)-1, + All: commit.msg == catchAllCommitMessage, }) if err != nil { logging.Info(fmt.Errorf("unable to commit changes for %v: %w", commit.paths, err).Error()) + } else { + commitHash = h } - lastCommitHash = commitHash } if err := g.repo.Push(&git.PushOptions{ @@ -420,7 +421,7 @@ func (g *Git) CommitAndPush(openAPIDocVersion, speakeasyVersion, doc string, act }); err != nil { return "", pushErr(err) } - return lastCommitHash.String(), nil + return commitHash.String(), nil } // ---- START Signed commits ---- From d784e285a9d76e42577728df91f1cd65a01c6c08 Mon Sep 17 00:00:00 2001 From: David Alberto Adler Date: Fri, 9 May 2025 20:39:21 +0100 Subject: [PATCH 06/12] --- internal/git/git.go | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/internal/git/git.go b/internal/git/git.go index 97597457..69171e22 100644 --- a/internal/git/git.go +++ b/internal/git/git.go @@ -368,11 +368,7 @@ func (g *Git) CommitAndPush(openAPIDocVersion, speakeasyVersion, doc string, act return "", fmt.Errorf("error getting worktree: %w", err) } - isSigned := "" - if environment.GetSignedCommits() { - isSigned = " (signed)" - } - logging.Info("Commit and pushing changes to git " + isSigned) + logging.Info("Commit and pushing changes to git") catchAllCommitMessage := "feat: regenerated with Speakeasy CLI" if action == environment.ActionSuggest { From 7c61ab8296a9e6676585a98b5e5e1571d488e991 Mon Sep 17 00:00:00 2001 From: David Alberto Adler Date: Fri, 9 May 2025 20:40:38 +0100 Subject: [PATCH 07/12] --- internal/git/git.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/internal/git/git.go b/internal/git/git.go index 69171e22..3c718816 100644 --- a/internal/git/git.go +++ b/internal/git/git.go @@ -387,8 +387,8 @@ func (g *Git) CommitAndPush(openAPIDocVersion, speakeasyVersion, doc string, act if !environment.GetSignedCommits() { var err error - var commitHash plumbing.Hash - for i, commit := range commits { + var lastCommitHash plumbing.Hash + for _, commit := range commits { for _, path := range commit.paths { if err = g.Add(path); err != nil { logging.Info(fmt.Errorf("unable to add changes for %v: %w", path, err).Error()) @@ -407,7 +407,7 @@ func (g *Git) CommitAndPush(openAPIDocVersion, speakeasyVersion, doc string, act if err != nil { logging.Info(fmt.Errorf("unable to commit changes for %v: %w", commit.paths, err).Error()) } else { - commitHash = h + lastCommitHash = h } } @@ -417,7 +417,7 @@ func (g *Git) CommitAndPush(openAPIDocVersion, speakeasyVersion, doc string, act }); err != nil { return "", pushErr(err) } - return commitHash.String(), nil + return lastCommitHash.String(), nil } // ---- START Signed commits ---- From 643751a6c4dcc11659f36a34b4fe7c4a1fc3a302 Mon Sep 17 00:00:00 2001 From: David Alberto Adler Date: Mon, 19 May 2025 13:28:19 +0100 Subject: [PATCH 08/12] +85 -42 environment.go and git.go --- internal/environment/environment.go | 4 + internal/git/git.go | 123 ++++++++++++++++++---------- 2 files changed, 85 insertions(+), 42 deletions(-) diff --git a/internal/environment/environment.go b/internal/environment/environment.go index a7be5e68..6f1355ff 100644 --- a/internal/environment/environment.go +++ b/internal/environment/environment.go @@ -244,6 +244,10 @@ func GetSignedCommits() bool { return os.Getenv("INPUT_SIGNED_COMMITS") == "true" } +func GetIncrementalCommits() bool { + return os.Getenv("INPUT_INCREMENTAL_COMMITS") == "true" +} + func GetBranchName() string { return os.Getenv("INPUT_BRANCH_NAME") } diff --git a/internal/git/git.go b/internal/git/git.go index 3c718816..ab5fabef 100644 --- a/internal/git/git.go +++ b/internal/git/git.go @@ -370,45 +370,36 @@ func (g *Git) CommitAndPush(openAPIDocVersion, speakeasyVersion, doc string, act logging.Info("Commit and pushing changes to git") - catchAllCommitMessage := "feat: regenerated with Speakeasy CLI" - if action == environment.ActionSuggest { - catchAllCommitMessage = "feat: suggestions for OpenAPI spec" + if environment.GetIncrementalCommits() { + return g.commitAndPushIncremental(openAPIDocVersion, speakeasyVersion, doc, action, sourcesOnly) } - commits := []struct { - paths []string - msg string - }{ - {paths: []string{"**/.speakeasy/", "*gen.yaml", "*gen.lock", "*workflow.yaml", "*workflow.lock"}, msg: "build: Speakeasy config and lock files"}, - {paths: []string{"*.md"}, msg: "docs: regenerate markdown files"}, - {paths: []string{"."}, msg: catchAllCommitMessage}, + if err := g.Add("."); err != nil { + return "", fmt.Errorf("error adding changes: %w", err) } - if !environment.GetSignedCommits() { - var err error - - var lastCommitHash plumbing.Hash - for _, commit := range commits { - for _, path := range commit.paths { - if err = g.Add(path); err != nil { - logging.Info(fmt.Errorf("unable to add changes for %v: %w", path, err).Error()) - } - } + var commitMessage string + if action == environment.ActionRunWorkflow { + commitMessage = fmt.Sprintf("ci: regenerated with OpenAPI Doc %s, Speakeasy CLI %s", openAPIDocVersion, speakeasyVersion) + if sourcesOnly { + commitMessage = fmt.Sprintf("ci: regenerated with Speakeasy CLI %s", speakeasyVersion) + } + } else if action == environment.ActionSuggest { + commitMessage = fmt.Sprintf("ci: suggestions for OpenAPI doc %s", doc) + } - h, err := w.Commit(commit.msg, &git.CommitOptions{ - Author: &object.Signature{ - Name: "speakeasybot", - Email: "bot@speakeasyapi.dev", - When: time.Now(), - }, - AllowEmptyCommits: false, - All: commit.msg == catchAllCommitMessage, - }) - if err != nil { - logging.Info(fmt.Errorf("unable to commit changes for %v: %w", commit.paths, err).Error()) - } else { - lastCommitHash = h - } + // Create commit message + if !environment.GetSignedCommits() { + commitHash, err := w.Commit(commitMessage, &git.CommitOptions{ + Author: &object.Signature{ + Name: "speakeasybot", + Email: "bot@speakeasyapi.dev", + When: time.Now(), + }, + All: true, + }) + if err != nil { + return "", fmt.Errorf("error committing changes: %w", err) } if err := g.repo.Push(&git.PushOptions{ @@ -417,13 +408,7 @@ func (g *Git) CommitAndPush(openAPIDocVersion, speakeasyVersion, doc string, act }); err != nil { return "", pushErr(err) } - return lastCommitHash.String(), nil - } - - // ---- START Signed commits ---- - // TODO: Due to priority constraints we don't split up into multiple commits like we do above - if err := g.Add("."); err != nil { - return "", fmt.Errorf("error adding changes: %w", err) + return commitHash.String(), nil } branch, err := g.GetCurrentBranch() @@ -466,7 +451,7 @@ func (g *Git) CommitAndPush(openAPIDocVersion, speakeasyVersion, doc string, act // Commit changes commitResult, _, err := g.client.Git.CreateCommit(context.Background(), owner, repo, &github.Commit{ - Message: github.String(catchAllCommitMessage), + Message: github.String(commitMessage), Tree: &github.Tree{SHA: tree.SHA}, Parents: []*github.Commit{parentCommit}}, &github.CreateCommitOptions{}) if err != nil { @@ -483,6 +468,60 @@ func (g *Git) CommitAndPush(openAPIDocVersion, speakeasyVersion, doc string, act return *commitResult.SHA, nil } +func (g *Git) commitAndPushIncremental(openAPIDocVersion, speakeasyVersion, doc string, action environment.Action, sourcesOnly bool) (string, error) { + catchAllCommitMessage := "feat: regenerated with Speakeasy CLI" + if action == environment.ActionSuggest { + catchAllCommitMessage = "feat: suggestions for OpenAPI spec" + } + + if environment.GetSignedCommits() { + return "", fmt.Errorf("signed commits are not supported for incremental commits") + } + + commits := []struct { + paths []string + msg string + }{ + {paths: []string{"**/.speakeasy/", "*gen.yaml", "*gen.lock", "*workflow.yaml", "*workflow.lock"}, msg: "build: Speakeasy config and lock files"}, + {paths: []string{"*.md"}, msg: "docs: regenerate markdown files"}, + {paths: []string{"."}, msg: catchAllCommitMessage}, + } + + var err error + + var lastCommitHash plumbing.Hash + for _, commit := range commits { + for _, path := range commit.paths { + if err = g.Add(path); err != nil { + logging.Info(fmt.Errorf("unable to add changes for %v: %w", path, err).Error()) + } + } + + h, err := w.Commit(commit.msg, &git.CommitOptions{ + Author: &object.Signature{ + Name: "speakeasybot", + Email: "bot@speakeasyapi.dev", + When: time.Now(), + }, + AllowEmptyCommits: false, + All: commit.msg == catchAllCommitMessage, + }) + if err != nil { + logging.Info(fmt.Errorf("unable to commit changes for %v: %w", commit.paths, err).Error()) + } else { + lastCommitHash = h + } + } + + if err := g.repo.Push(&git.PushOptions{ + Auth: getGithubAuth(g.accessToken), + Force: true, // This is necessary because at the beginning of the workflow we reset the branch + }); err != nil { + return "", pushErr(err) + } + return lastCommitHash.String(), nil +} + // getOrCreateRef returns the commit branch reference object if it exists or creates it // from the base branch before returning it. func (g *Git) getOrCreateRef(commitRef string) (ref *github.Reference, err error) { From d311d9cd86e4c65ed69f2a122ec9bd7a34cd24c0 Mon Sep 17 00:00:00 2001 From: David Alberto Adler Date: Mon, 19 May 2025 13:37:20 +0100 Subject: [PATCH 09/12] +5 -2 git.go --- internal/git/git.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/internal/git/git.go b/internal/git/git.go index ab5fabef..1296fb99 100644 --- a/internal/git/git.go +++ b/internal/git/git.go @@ -469,6 +469,11 @@ func (g *Git) CommitAndPush(openAPIDocVersion, speakeasyVersion, doc string, act } func (g *Git) commitAndPushIncremental(openAPIDocVersion, speakeasyVersion, doc string, action environment.Action, sourcesOnly bool) (string, error) { + w, err := g.repo.Worktree() + if err != nil { + return "", fmt.Errorf("error getting worktree: %w", err) + } + catchAllCommitMessage := "feat: regenerated with Speakeasy CLI" if action == environment.ActionSuggest { catchAllCommitMessage = "feat: suggestions for OpenAPI spec" @@ -487,8 +492,6 @@ func (g *Git) commitAndPushIncremental(openAPIDocVersion, speakeasyVersion, doc {paths: []string{"."}, msg: catchAllCommitMessage}, } - var err error - var lastCommitHash plumbing.Hash for _, commit := range commits { for _, path := range commit.paths { From 88e26c3539a90311f9cc6e400bdfd471b49c3c68 Mon Sep 17 00:00:00 2001 From: David Alberto Adler Date: Mon, 19 May 2025 13:39:19 +0100 Subject: [PATCH 10/12] +11 -13 environment.go and git.go --- internal/environment/environment.go | 4 ++-- internal/git/git.go | 20 +++++++++----------- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/internal/environment/environment.go b/internal/environment/environment.go index 6f1355ff..ea5602a6 100644 --- a/internal/environment/environment.go +++ b/internal/environment/environment.go @@ -244,8 +244,8 @@ func GetSignedCommits() bool { return os.Getenv("INPUT_SIGNED_COMMITS") == "true" } -func GetIncrementalCommits() bool { - return os.Getenv("INPUT_INCREMENTAL_COMMITS") == "true" +func GetGranularCommits() bool { + return os.Getenv("INPUT_GRANULAR_COMMITS") == "true" } func GetBranchName() string { diff --git a/internal/git/git.go b/internal/git/git.go index 1296fb99..e98330d4 100644 --- a/internal/git/git.go +++ b/internal/git/git.go @@ -363,17 +363,19 @@ func (g *Git) CommitAndPush(openAPIDocVersion, speakeasyVersion, doc string, act return "", nil } + logging.Info("Commit and pushing changes to git") + + if environment.GetGranularCommits() && + // TODO: Support signed commits with granular commits + !environment.GetSignedCommits() { + return g.granularCommitAndPush(openAPIDocVersion, speakeasyVersion, doc, action, sourcesOnly) + } + w, err := g.repo.Worktree() if err != nil { return "", fmt.Errorf("error getting worktree: %w", err) } - logging.Info("Commit and pushing changes to git") - - if environment.GetIncrementalCommits() { - return g.commitAndPushIncremental(openAPIDocVersion, speakeasyVersion, doc, action, sourcesOnly) - } - if err := g.Add("."); err != nil { return "", fmt.Errorf("error adding changes: %w", err) } @@ -468,7 +470,7 @@ func (g *Git) CommitAndPush(openAPIDocVersion, speakeasyVersion, doc string, act return *commitResult.SHA, nil } -func (g *Git) commitAndPushIncremental(openAPIDocVersion, speakeasyVersion, doc string, action environment.Action, sourcesOnly bool) (string, error) { +func (g *Git) granularCommitAndPush(openAPIDocVersion, speakeasyVersion, doc string, action environment.Action, sourcesOnly bool) (string, error) { w, err := g.repo.Worktree() if err != nil { return "", fmt.Errorf("error getting worktree: %w", err) @@ -479,10 +481,6 @@ func (g *Git) commitAndPushIncremental(openAPIDocVersion, speakeasyVersion, doc catchAllCommitMessage = "feat: suggestions for OpenAPI spec" } - if environment.GetSignedCommits() { - return "", fmt.Errorf("signed commits are not supported for incremental commits") - } - commits := []struct { paths []string msg string From f16e829db5c095bbaf51df0bbe2c48424b54e81f Mon Sep 17 00:00:00 2001 From: David Alberto Adler Date: Mon, 19 May 2025 13:42:24 +0100 Subject: [PATCH 11/12] +13 -0 workflow-executor.yaml, Makefile and action.yml --- .github/workflows/workflow-executor.yaml | 5 +++++ Makefile | 3 +++ action.yml | 5 +++++ 3 files changed, 13 insertions(+) diff --git a/.github/workflows/workflow-executor.yaml b/.github/workflows/workflow-executor.yaml index d7c854ab..3238bb24 100644 --- a/.github/workflows/workflow-executor.yaml +++ b/.github/workflows/workflow-executor.yaml @@ -37,6 +37,10 @@ on: required: false description: "This will set commits to be signed and and verified" type: boolean + granular_commits: + required: false + description: "Granular commits to separate config changes from code changes" + type: boolean speakeasy_server_url: required: false description: "Internal use only" @@ -214,6 +218,7 @@ jobs: mode: ${{ inputs.mode }} force: ${{ inputs.force }} signed_commits: ${{ inputs.signed_commits }} + granular_commits: ${{ inputs.granular_commits }} speakeasy_api_key: ${{ secrets.speakeasy_api_key }} pr_creation_pat: ${{ secrets.pr_creation_pat }} output_tests: ${{ inputs.output_tests }} diff --git a/Makefile b/Makefile index 7ceb29dd..c5f770f9 100644 --- a/Makefile +++ b/Makefile @@ -12,6 +12,9 @@ test-direct-mode-multi-sdk: test-pr-mode: docker compose run --rm main ./testing/test.sh ./testing/pr-mode.env +test-pr-mode-granular-commits: + docker compose run --rm main ./testing/test.sh ./testing/pr-mode-granular-commits.env + test-pr-mode-signed-commits: docker compose run --rm main ./testing/test.sh ./testing/pr-mode-signed-commits.env diff --git a/action.yml b/action.yml index 91ca4282..deef8f8d 100644 --- a/action.yml +++ b/action.yml @@ -26,6 +26,10 @@ inputs: description: "Sign commits with GPG" default: "false" required: false + granular_commits: + description: "Commit and push granular changes" + default: "false" + required: false sources: description: "The sources to tag (comma or newline separated)" required: false @@ -202,6 +206,7 @@ runs: - ${{ inputs.branch_name }} - ${{ inputs.cli_output }} - ${{ inputs.signed_commits }} + - ${{ inputs.granular_commits }} - ${{ inputs.previous_gen_version }} - ${{ inputs.openapi_doc_output }} - ${{ inputs.output_tests }} From 5c55bcb8da533480007b21f5d9fa046047fe5b97 Mon Sep 17 00:00:00 2001 From: David Alberto Adler Date: Mon, 19 May 2025 13:42:30 +0100 Subject: [PATCH 12/12] +6 -0 pr-mode-granular-commits.env --- testing/pr-mode-granular-commits.env | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 testing/pr-mode-granular-commits.env diff --git a/testing/pr-mode-granular-commits.env b/testing/pr-mode-granular-commits.env new file mode 100644 index 00000000..8aa9b861 --- /dev/null +++ b/testing/pr-mode-granular-commits.env @@ -0,0 +1,6 @@ +INPUT_MODE="pr" +INPUT_LANGUAGES="- go" +GITHUB_REPOSITORY="speakeasy-api/sdk-generation-action-test-repo" +INPUT_FORCE=true +RUN_FINALIZE=true +INPUT_GRANULAR_COMMITS=true \ No newline at end of file