From 1b093b5776f036f7e1eb81f4679fa4ca5660532c Mon Sep 17 00:00:00 2001 From: Edmund Kohlwey Date: Thu, 18 Jun 2026 22:10:36 -0400 Subject: [PATCH 1/2] msggen: AI message generation via shared script protocol --- .../unreleased/Added-20260321-072917.yaml | 3 + branch_create.go | 41 +++- commit_amend.go | 43 +++- commit_create.go | 30 +++ commit_fill.go | 46 ++++ doc/includes/cli-reference.md | 66 +++--- doc/mkdocs.yml | 1 + doc/src/cli/config.md | 43 ++++ doc/src/guide/ai-messages.md | 148 ++++++++++++ internal/forge/bitbucket/edit.go | 26 +++ internal/forge/bitbucket/find.go | 1 + internal/forge/forge.go | 11 + internal/forge/github/edit.go | 16 +- internal/forge/github/find.go | 2 + .../FindChangesByBranchDoesNotExist.yaml | 12 +- .../SubmitEditAssignees/AddAssignee.yaml | 44 ++-- .../AddAssigneesOneByOne.yaml | 2 +- .../SubmitWithAssignee.yaml | 44 ++-- .../TestIntegration/SubmitEditBase.yaml | 32 +-- .../TestIntegration/SubmitEditChange.yaml | 28 +-- .../TestIntegration/SubmitEditDraft.yaml | 48 ++-- .../TestIntegration/SubmitEditLabels.yaml | 86 +++---- .../SubmitEditReviewers/AddReviewer.yaml | 42 ++-- .../SubmitWithReviewer.yaml | 34 +-- ...Repository_SubmitEditChangeWIthLabels.yaml | 4 +- internal/forge/gitlab/edit.go | 14 ++ internal/forge/gitlab/find.go | 2 + internal/forge/shamhub/edit.go | 10 + internal/forge/shamhub/find.go | 1 + .../UpdateComment/updated-comment | 2 +- .../TestIntegration/ChangeComments/branch | 2 +- .../TestIntegration/ChangeComments/comments | 20 +- .../ChangesStates/closedBranch | 2 +- .../ChangesStates/mergedBranch | 2 +- .../TestIntegration/ChangesStates/openBranch | 2 +- .../CommentCountsByChange/branch | 2 +- .../TemplatesPresent/empty-template | 2 +- .../TemplatesPresent/non-empty-template | 2 +- .../SubmitBaseDoesNotExist/base-branch | 2 +- .../SubmitBaseDoesNotExist/branch | 2 +- .../AddAssignee/branch-no-assignee | 2 +- .../branch-no-assignee-one-by-one | 2 +- .../SubmitWithAssignee/branch-with-assignee | 2 +- .../TestIntegration/SubmitEditBase/base | 2 +- .../TestIntegration/SubmitEditBase/branch | 2 +- .../TestIntegration/SubmitEditChange/branch | 2 +- .../SubmitEditChange/firstCommitHash | 2 +- .../TestIntegration/SubmitEditDraft/branch | 2 +- .../TestIntegration/SubmitEditLabels/branch | 2 +- .../TestIntegration/SubmitEditLabels/label1 | 2 +- .../TestIntegration/SubmitEditLabels/label2 | 2 +- .../TestIntegration/SubmitEditLabels/label3 | 2 +- .../AddReviewer/branch-no-reviewer | 2 +- .../branch-no-reviewer-one-by-one | 2 +- .../SubmitWithReviewer/branch-with-reviewer | 2 +- .../shamhub/testdata/TestIntegration/apiURL | 2 +- .../shamhub/testdata/TestIntegration/gitURL | 2 +- .../shamhub/testdata/TestIntegration/repoURL | 2 +- .../shamhub/testdata/TestIntegration/token | 2 +- .../TestIntegration/ChangeComments.yaml | 180 +++++++-------- .../TestIntegration/ChangesStates.yaml | 56 ++--- .../CommentCountsByChange.yaml | 26 +-- .../FindChangesByBranchDoesNotExist.yaml | 6 +- .../ListChangeTemplates/NoTemplates.yaml | 6 +- .../ListChangeTemplates/TemplatesPresent.yaml | 14 +- .../SubmitBaseDoesNotExist.yaml | 16 +- .../SubmitEditAssignees/AddAssignee.yaml | 54 ++--- .../AddAssigneesOneByOne.yaml | 42 ++-- .../SubmitWithAssignee.yaml | 48 ++-- .../TestIntegration/SubmitEditBase.yaml | 68 +++--- .../TestIntegration/SubmitEditChange.yaml | 42 ++-- .../TestIntegration/SubmitEditDraft.yaml | 94 ++++---- .../TestIntegration/SubmitEditLabels.yaml | 72 +++--- .../SubmitEditReviewers/AddReviewer.yaml | 54 ++--- .../AddReviewersOneByOne.yaml | 72 +++--- .../SubmitWithReviewer.yaml | 38 +-- internal/gateway/gitlab/api.go | 2 + internal/git/commit.go | 15 ++ internal/handler/squash/handler.go | 61 ++++- internal/handler/squash/handler_test.go | 49 ++++ internal/handler/submit/handler.go | 90 +++++++- internal/msggen/msggen.go | 160 +++++++++++++ internal/msggen/msggen_test.go | 217 ++++++++++++++++++ internal/spice/config.go | 37 +++ internal/spice/config_test.go | 65 ++++++ main.go | 10 +- testdata/help/branch_create.txt | 3 + testdata/help/branch_squash.txt | 2 + testdata/help/branch_submit.txt | 12 +- testdata/help/commit_amend.txt | 3 + testdata/help/commit_create.txt | 3 + testdata/help/downstack_submit.txt | 12 +- testdata/help/stack_submit.txt | 12 +- testdata/help/upstack_submit.txt | 12 +- testdata/script/branch_squash_fill.txt | 35 +++ .../branch_squash_fill_no_generator.txt | 25 ++ testdata/script/branch_submit_fill_env.txt | 56 +++++ .../script/branch_submit_fill_generator.txt | 69 ++++++ .../script/branch_submit_fill_updater.txt | 78 +++++++ .../branch_submit_regenerate_message.txt | 68 ++++++ .../script/commit_amend_fill_no_generator.txt | 25 ++ testdata/script/commit_amend_fill_updater.txt | 35 +++ testdata/script/commit_create_fill_env.txt | 34 +++ .../script/commit_create_fill_generator.txt | 28 +++ .../commit_create_fill_generator_fallback.txt | 28 +++ .../script/stack_submit_fill_generator.txt | 126 ++++++++++ testdata/script/stack_submit_fill_updater.txt | 120 ++++++++++ 107 files changed, 2607 insertions(+), 731 deletions(-) create mode 100644 .changes/unreleased/Added-20260321-072917.yaml create mode 100644 commit_fill.go create mode 100644 doc/src/guide/ai-messages.md create mode 100644 internal/msggen/msggen.go create mode 100644 internal/msggen/msggen_test.go create mode 100644 testdata/script/branch_squash_fill.txt create mode 100644 testdata/script/branch_squash_fill_no_generator.txt create mode 100644 testdata/script/branch_submit_fill_env.txt create mode 100644 testdata/script/branch_submit_fill_generator.txt create mode 100644 testdata/script/branch_submit_fill_updater.txt create mode 100644 testdata/script/branch_submit_regenerate_message.txt create mode 100644 testdata/script/commit_amend_fill_no_generator.txt create mode 100644 testdata/script/commit_amend_fill_updater.txt create mode 100644 testdata/script/commit_create_fill_env.txt create mode 100644 testdata/script/commit_create_fill_generator.txt create mode 100644 testdata/script/commit_create_fill_generator_fallback.txt create mode 100644 testdata/script/stack_submit_fill_generator.txt create mode 100644 testdata/script/stack_submit_fill_updater.txt diff --git a/.changes/unreleased/Added-20260321-072917.yaml b/.changes/unreleased/Added-20260321-072917.yaml new file mode 100644 index 000000000..7738300a8 --- /dev/null +++ b/.changes/unreleased/Added-20260321-072917.yaml @@ -0,0 +1,3 @@ +kind: Added +body: 'commit/submit/squash: Add AI message generation via spice.message.generator config option, activated with --fill. For branch submit, --fill and spice.message.autoFill only generate messages for new change requests; use --regenerate-message to rewrite an existing description. Scripts receive GS_OPERATION, GS_MESSAGE_KIND, and GS_MESSAGE_UPDATE environment variables, plus the full gs command as positional args.' +time: 2026-03-21T07:29:17.2847-04:00 diff --git a/branch_create.go b/branch_create.go index 1238f6479..6d6ea2a42 100644 --- a/branch_create.go +++ b/branch_create.go @@ -5,9 +5,12 @@ import ( "encoding/json" "errors" "fmt" + "os" "go.abhg.dev/gs/internal/cli" "go.abhg.dev/gs/internal/git" + "go.abhg.dev/gs/internal/msggen" + "go.abhg.dev/gs/internal/scriptrun" "go.abhg.dev/gs/internal/silog" "go.abhg.dev/gs/internal/spice" "go.abhg.dev/gs/internal/spice/state" @@ -29,6 +32,7 @@ type branchCreateCmd struct { Target string `short:"t" placeholder:"BRANCH" help:"Branch to create the new branch above/below"` All bool `short:"a" help:"Automatically stage modified and deleted files"` + Fill bool `short:"c" negatable:"" config:"message.autoFill" help:"Fill the commit message using the configured message generator. Defaults to spice.message.autoFill."` Message string `short:"m" xor:"commit-message-source" placeholder:"MSG" help:"Commit message"` MessageFile string `short:"F" xor:"commit-message-source" placeholder:"FILE" help:"Read the commit message from the given file."` @@ -100,6 +104,7 @@ func (*branchCreateCmd) Help() string { func (cmd *branchCreateCmd) Run( ctx context.Context, log *silog.Logger, + cfg *spice.Config, repo *git.Repository, wt *git.Worktree, store *state.Store, @@ -111,6 +116,11 @@ func (cmd *branchCreateCmd) Run( cmd.Commit = true } + // If --fill is set, automatically enable commits. + if cmd.Fill { + cmd.Commit = true + } + if cmd.Name == "" && !cmd.Commit { return errors.New("a branch name is required with --no-commit") } @@ -209,7 +219,7 @@ func (cmd *branchCreateCmd) Run( ) branchAt := baseHash if cmd.Commit { - commitHash, restore, err := cmd.commit(ctx, wt, baseName, log) + commitHash, restore, err := cmd.commit(ctx, cfg, wt, baseName, log) if err != nil { return err } @@ -337,10 +347,39 @@ func (cmd *branchCreateCmd) Run( // the repository to its original state if an error occurs. func (cmd *branchCreateCmd) commit( ctx context.Context, + cfg *spice.Config, wt *git.Worktree, baseName string, log *silog.Logger, ) (commitHash git.Hash, restore func() error, err error) { + // If --fill is set and no message was provided, + // try to generate one using the configured script. + if cmd.Fill && cmd.Message == "" { + script := cfg.MessageGenerator() + if script == "" { + return "", nil, msggen.ErrNoGenerator + } + + branch := "" + if b, err := wt.CurrentBranch(ctx); err == nil { + branch = b + } + env := msggenEnv(scriptrun.OpBranchCreate, false, branch, baseName) + result, err := (&msggen.Runner{ + Log: log, + Args: os.Args, + }).Run( + ctx, script, wt.RootDir(), env, + ) + if err != nil { + log.Warn("Message generator failed, "+ + "falling back to editor", + "error", err) + } else { + cmd.Message = result.Message() + } + } + // We'll need --allow-empty if there are no staged changes. diff, err := wt.DiffIndex(ctx, "HEAD") if err != nil { diff --git a/commit_amend.go b/commit_amend.go index 6cfa4ff79..a78a17cc8 100644 --- a/commit_amend.go +++ b/commit_amend.go @@ -4,10 +4,13 @@ import ( "context" "errors" "fmt" + "os" "go.abhg.dev/gs/internal/cli" "go.abhg.dev/gs/internal/git" "go.abhg.dev/gs/internal/handler/restack" + "go.abhg.dev/gs/internal/msggen" + "go.abhg.dev/gs/internal/scriptrun" "go.abhg.dev/gs/internal/silog" "go.abhg.dev/gs/internal/spice" "go.abhg.dev/gs/internal/spice/state" @@ -20,6 +23,7 @@ type commitAmendCmd struct { All bool `short:"a" help:"Stage all changes before committing."` AllowEmpty bool `help:"Create a commit even if it contains no changes."` + Fill bool `short:"c" negatable:"" config:"message.autoFill" help:"Fill the commit message using the configured message updater. Defaults to spice.message.autoFill."` Message string `short:"m" xor:"commit-message-source" placeholder:"MSG" help:"Use the given message as the commit message."` MessageFile string `short:"F" xor:"commit-message-source" placeholder:"FILE" help:"Read the commit message from the given file."` @@ -56,6 +60,7 @@ func (*commitAmendCmd) Help() string { func (cmd *commitAmendCmd) Run( ctx context.Context, log *silog.Logger, + cfg *spice.Config, view ui.View, repo *git.Repository, wt *git.Worktree, @@ -128,7 +133,7 @@ func (cmd *commitAmendCmd) Run( MessageFile: cmd.MessageFile, Signoff: cmd.Signoff, Commit: true, - }).Run(ctx, log, repo, wt, store, svc, restackHandler) + }).Run(ctx, log, cfg, repo, wt, store, svc, restackHandler) } } } @@ -218,6 +223,42 @@ func (cmd *commitAmendCmd) Run( } } + // If --fill is set and no message was provided, + // try to update the existing message + // using the configured script. + if cmd.Fill && cmd.Message == "" { + script := cfg.MessageGenerator() + if script == "" { + return msggen.ErrNoGenerator + } + + var extras []string + existingMsg, err := repo.CommitMessageFull( + ctx, "HEAD", + ) + if err == nil { + extras = append(extras, + "GS_MESSAGE="+existingMsg, + ) + } + env := commitEnv(ctx, wt, scriptrun.OpCommitAmend, true, extras...) + + result, err := (&msggen.Runner{ + Log: log, + Args: os.Args, + }).Run( + ctx, script, wt.RootDir(), env, + ) + if err != nil { + log.Warn("Message generator failed, "+ + "falling back to editor", + "error", err) + } else { + cmd.Message = result.Message() + cmd.NoEdit = true + } + } + if err := wt.Commit(ctx, git.CommitRequest{ Message: cmd.Message, MessageFile: cmd.MessageFile, diff --git a/commit_create.go b/commit_create.go index 4ba090a64..7cc65bc66 100644 --- a/commit_create.go +++ b/commit_create.go @@ -4,17 +4,22 @@ import ( "context" "errors" "fmt" + "os" "go.abhg.dev/gs/internal/cli" "go.abhg.dev/gs/internal/git" "go.abhg.dev/gs/internal/handler/restack" + "go.abhg.dev/gs/internal/msggen" + "go.abhg.dev/gs/internal/scriptrun" "go.abhg.dev/gs/internal/silog" + "go.abhg.dev/gs/internal/spice" "go.abhg.dev/gs/internal/text" ) type commitCreateCmd struct { All bool `short:"a" help:"Stage all changes before committing."` AllowEmpty bool `help:"Create a new commit even if it contains no changes."` + Fill bool `short:"c" negatable:"" config:"message.autoFill" help:"Fill the commit message using the configured message generator. Defaults to spice.message.autoFill."` Fixup string `help:"Create a fixup commit. See also 'git-spice commit fixup'." placeholder:"COMMIT"` Message string `short:"m" xor:"commit-message-source" placeholder:"MSG" help:"Use the given message as the commit message."` MessageFile string `short:"F" xor:"commit-message-source" placeholder:"FILE" help:"Read the commit message from the given file."` @@ -47,9 +52,34 @@ func (*commitCreateCmd) Help() string { func (cmd *commitCreateCmd) Run( ctx context.Context, log *silog.Logger, + cfg *spice.Config, wt *git.Worktree, restackHandler RestackHandler, ) error { + // If --fill is set and no message was provided, + // try to generate one using the configured script. + if cmd.Fill && cmd.Message == "" { + script := cfg.MessageGenerator() + if script == "" { + return msggen.ErrNoGenerator + } + + result, err := (&msggen.Runner{ + Log: log, + Args: os.Args, + }).Run( + ctx, script, wt.RootDir(), + commitEnv(ctx, wt, scriptrun.OpCommitCreate, false), + ) + if err != nil { + log.Warn("Message generator failed, "+ + "falling back to editor", + "error", err) + } else { + cmd.Message = result.Message() + } + } + if err := wt.Commit(ctx, git.CommitRequest{ Message: cmd.Message, MessageFile: cmd.MessageFile, diff --git a/commit_fill.go b/commit_fill.go new file mode 100644 index 000000000..57652abdf --- /dev/null +++ b/commit_fill.go @@ -0,0 +1,46 @@ +package main + +import ( + "context" + "strconv" + + "go.abhg.dev/gs/internal/git" + "go.abhg.dev/gs/internal/scriptrun" +) + +// msggenEnv builds the base environment for a message-generation +// script. It layers the message-specific GS_MESSAGE_* variables on +// top of the shared GS_OPERATION / GS_BRANCH / GS_BASE env that every +// gs-driven script receives. +// +// kind names the operation (one of [scriptrun.Operation]). update +// indicates whether this is an update of an existing message (e.g. +// 'gs commit amend --fill', 'gs branch submit --fill' updating an +// existing CR). branch is the active branch when known; base is the +// branch's base when applicable. extras are appended verbatim. +func msggenEnv( + op scriptrun.Operation, + update bool, + branch, base string, + extras ...string, +) []string { + env := scriptrun.EnvFor(op, branch, base) + env = append(env, "GS_MESSAGE_UPDATE="+strconv.FormatBool(update)) + return append(env, extras...) +} + +// commitEnv builds the environment for a commit-message script. +// update is true when amending an existing message. +func commitEnv( + ctx context.Context, + wt *git.Worktree, + op scriptrun.Operation, + update bool, + extras ...string, +) []string { + branch := "" + if b, err := wt.CurrentBranch(ctx); err == nil { + branch = b + } + return msggenEnv(op, update, branch, "", extras...) +} diff --git a/doc/includes/cli-reference.md b/doc/includes/cli-reference.md index 507c9d1c6..ea298acfb 100644 --- a/doc/includes/cli-reference.md +++ b/doc/includes/cli-reference.md @@ -271,7 +271,8 @@ only if there are multiple CRs in the stack. **Flags** * `-n`, `--dry-run`: Don't actually submit the stack -* `-c`, `--fill`: Fill in the change title and body from the commit messages +* `-c`, `--[no-]fill` ([:material-wrench:{ .middle title="spice.message.autoFill" }](/cli/config.md#spicemessageautofill)): Fill in the title and body of new change requests via the configured message generator. Defaults to spice.message.autoFill. Use --regenerate-message to also update existing change requests. +* `--regenerate-message`: Regenerate the title and body of existing change requests via the configured message generator. Unlike --fill, this is never implied by configuration: overwriting an existing description is always explicit. * `--[no-]draft`: Whether to mark change requests as drafts * `--[no-]publish` ([:material-wrench:{ .middle title="spice.submit.publish" }](/cli/config.md#spicesubmitpublish)): Whether to create CRs for pushed branches. Defaults to true. * `-w`, `--web` ([:material-wrench:{ .middle title="spice.submit.web" }](/cli/config.md#spicesubmitweb)): Open submitted changes in a web browser. Accepts an optional argument: 'true', 'false', 'created'. @@ -284,7 +285,7 @@ only if there are multiple CRs in the stack. * `-a`, `--assign=ASSIGNEE,...`: Assign the change request to these users. Pass multiple times or separate with commas. :material-tag:{ title="Released in version" }[v0.21.0](/changelog.md#v0.21.0) * `--no-web`: Alias for --web=false. -**Configuration**: [spice.submit.assignees](/cli/config.md#spicesubmitassignees), [spice.submit.draft](/cli/config.md#spicesubmitdraft), [spice.submit.labels](/cli/config.md#spicesubmitlabels), [spice.submit.labels.addWhen](/cli/config.md#spicesubmitlabelsaddwhen), [spice.submit.listTemplatesTimeout](/cli/config.md#spicesubmitlisttemplatestimeout), [spice.submit.navigationComment](/cli/config.md#spicesubmitnavigationcomment), [spice.submit.navigationComment.downstack](/cli/config.md#spicesubmitnavigationcommentdownstack), [spice.submit.navigationCommentStyle.marker](/cli/config.md#spicesubmitnavigationcommentstylemarker), [spice.submit.navigationCommentSync](/cli/config.md#spicesubmitnavigationcommentsync), [spice.submit.publish](/cli/config.md#spicesubmitpublish), [spice.submit.reviewers](/cli/config.md#spicesubmitreviewers), [spice.submit.reviewers.addWhen](/cli/config.md#spicesubmitreviewersaddwhen), [spice.submit.skipRestackCheck](/cli/config.md#spicesubmitskiprestackcheck), [spice.submit.template](/cli/config.md#spicesubmittemplate), [spice.submit.updateOnly](/cli/config.md#spicesubmitupdateonly), [spice.submit.web](/cli/config.md#spicesubmitweb) +**Configuration**: [spice.message.autoFill](/cli/config.md#spicemessageautofill), [spice.submit.assignees](/cli/config.md#spicesubmitassignees), [spice.submit.draft](/cli/config.md#spicesubmitdraft), [spice.submit.labels](/cli/config.md#spicesubmitlabels), [spice.submit.labels.addWhen](/cli/config.md#spicesubmitlabelsaddwhen), [spice.submit.listTemplatesTimeout](/cli/config.md#spicesubmitlisttemplatestimeout), [spice.submit.navigationComment](/cli/config.md#spicesubmitnavigationcomment), [spice.submit.navigationComment.downstack](/cli/config.md#spicesubmitnavigationcommentdownstack), [spice.submit.navigationCommentStyle.marker](/cli/config.md#spicesubmitnavigationcommentstylemarker), [spice.submit.navigationCommentSync](/cli/config.md#spicesubmitnavigationcommentsync), [spice.submit.publish](/cli/config.md#spicesubmitpublish), [spice.submit.reviewers](/cli/config.md#spicesubmitreviewers), [spice.submit.reviewers.addWhen](/cli/config.md#spicesubmitreviewersaddwhen), [spice.submit.skipRestackCheck](/cli/config.md#spicesubmitskiprestackcheck), [spice.submit.template](/cli/config.md#spicesubmittemplate), [spice.submit.updateOnly](/cli/config.md#spicesubmitupdateonly), [spice.submit.web](/cli/config.md#spicesubmitweb) ### git-spice stack merge {#gs-stack-merge} @@ -310,11 +311,9 @@ Before merging, the stack is checked for branches whose base PR was already merged on the forge. Use --no-branch-check to skip this validation. -Before each merge, waits for merge readiness: -the forge must observe the pushed head -and report that the CR is ready to merge. -Use --ready-timeout to configure the maximum wait -before failing if merge readiness is not reached. +Before each merge, waits for CI checks to pass. +Use --build-timeout to configure the maximum wait +before failing if checks are not ready. By default, a branch failure skips that branch's upstack descendants, but independent sibling branches continue. @@ -323,12 +322,12 @@ Use --fail-fast to stop the queue after the first branch failure. **Flags** * `--method=METHOD` ([:material-wrench:{ .middle title="spice.merge.method" }](/cli/config.md#spicemergemethod)): Preferred merge method. One of 'merge', 'squash', and 'rebase'. -* `--ready-timeout=30m` ([:material-wrench:{ .middle title="spice.merge.readyTimeout" }](/cli/config.md#spicemergereadytimeout)): Max time to wait for merge readiness before each merge. 0 means check once. +* `--build-timeout=30m` ([:material-wrench:{ .middle title="spice.merge.buildTimeout" }](/cli/config.md#spicemergebuildtimeout)): Max time to wait for CI checks before each merge. 0 means check once. * `--no-branch-check`: Skip stale base validation before merging. * `--fail-fast`: Stop the merge queue after the first branch failure. * `--branch=NAME`: Branch whose stack to merge -**Configuration**: [spice.merge.method](/cli/config.md#spicemergemethod), [spice.merge.readyTimeout](/cli/config.md#spicemergereadytimeout) +**Configuration**: [spice.merge.buildTimeout](/cli/config.md#spicemergebuildtimeout), [spice.merge.method](/cli/config.md#spicemergemethod) ### git-spice stack restack {#gs-stack-restack} @@ -437,7 +436,8 @@ only if there are multiple CRs in the stack. **Flags** * `-n`, `--dry-run`: Don't actually submit the stack -* `-c`, `--fill`: Fill in the change title and body from the commit messages +* `-c`, `--[no-]fill` ([:material-wrench:{ .middle title="spice.message.autoFill" }](/cli/config.md#spicemessageautofill)): Fill in the title and body of new change requests via the configured message generator. Defaults to spice.message.autoFill. Use --regenerate-message to also update existing change requests. +* `--regenerate-message`: Regenerate the title and body of existing change requests via the configured message generator. Unlike --fill, this is never implied by configuration: overwriting an existing description is always explicit. * `--[no-]draft`: Whether to mark change requests as drafts * `--[no-]publish` ([:material-wrench:{ .middle title="spice.submit.publish" }](/cli/config.md#spicesubmitpublish)): Whether to create CRs for pushed branches. Defaults to true. * `-w`, `--web` ([:material-wrench:{ .middle title="spice.submit.web" }](/cli/config.md#spicesubmitweb)): Open submitted changes in a web browser. Accepts an optional argument: 'true', 'false', 'created'. @@ -451,7 +451,7 @@ only if there are multiple CRs in the stack. * `--no-web`: Alias for --web=false. * `--branch=NAME`: Branch to start at -**Configuration**: [spice.submit.assignees](/cli/config.md#spicesubmitassignees), [spice.submit.draft](/cli/config.md#spicesubmitdraft), [spice.submit.labels](/cli/config.md#spicesubmitlabels), [spice.submit.labels.addWhen](/cli/config.md#spicesubmitlabelsaddwhen), [spice.submit.listTemplatesTimeout](/cli/config.md#spicesubmitlisttemplatestimeout), [spice.submit.navigationComment](/cli/config.md#spicesubmitnavigationcomment), [spice.submit.navigationComment.downstack](/cli/config.md#spicesubmitnavigationcommentdownstack), [spice.submit.navigationCommentStyle.marker](/cli/config.md#spicesubmitnavigationcommentstylemarker), [spice.submit.navigationCommentSync](/cli/config.md#spicesubmitnavigationcommentsync), [spice.submit.publish](/cli/config.md#spicesubmitpublish), [spice.submit.reviewers](/cli/config.md#spicesubmitreviewers), [spice.submit.reviewers.addWhen](/cli/config.md#spicesubmitreviewersaddwhen), [spice.submit.skipRestackCheck](/cli/config.md#spicesubmitskiprestackcheck), [spice.submit.template](/cli/config.md#spicesubmittemplate), [spice.submit.updateOnly](/cli/config.md#spicesubmitupdateonly), [spice.submit.web](/cli/config.md#spicesubmitweb) +**Configuration**: [spice.message.autoFill](/cli/config.md#spicemessageautofill), [spice.submit.assignees](/cli/config.md#spicesubmitassignees), [spice.submit.draft](/cli/config.md#spicesubmitdraft), [spice.submit.labels](/cli/config.md#spicesubmitlabels), [spice.submit.labels.addWhen](/cli/config.md#spicesubmitlabelsaddwhen), [spice.submit.listTemplatesTimeout](/cli/config.md#spicesubmitlisttemplatestimeout), [spice.submit.navigationComment](/cli/config.md#spicesubmitnavigationcomment), [spice.submit.navigationComment.downstack](/cli/config.md#spicesubmitnavigationcommentdownstack), [spice.submit.navigationCommentStyle.marker](/cli/config.md#spicesubmitnavigationcommentstylemarker), [spice.submit.navigationCommentSync](/cli/config.md#spicesubmitnavigationcommentsync), [spice.submit.publish](/cli/config.md#spicesubmitpublish), [spice.submit.reviewers](/cli/config.md#spicesubmitreviewers), [spice.submit.reviewers.addWhen](/cli/config.md#spicesubmitreviewersaddwhen), [spice.submit.skipRestackCheck](/cli/config.md#spicesubmitskiprestackcheck), [spice.submit.template](/cli/config.md#spicesubmittemplate), [spice.submit.updateOnly](/cli/config.md#spicesubmitupdateonly), [spice.submit.web](/cli/config.md#spicesubmitweb) ### git-spice upstack restack {#gs-upstack-restack} @@ -592,7 +592,8 @@ only if there are multiple CRs in the stack. **Flags** * `-n`, `--dry-run`: Don't actually submit the stack -* `-c`, `--fill`: Fill in the change title and body from the commit messages +* `-c`, `--[no-]fill` ([:material-wrench:{ .middle title="spice.message.autoFill" }](/cli/config.md#spicemessageautofill)): Fill in the title and body of new change requests via the configured message generator. Defaults to spice.message.autoFill. Use --regenerate-message to also update existing change requests. +* `--regenerate-message`: Regenerate the title and body of existing change requests via the configured message generator. Unlike --fill, this is never implied by configuration: overwriting an existing description is always explicit. * `--[no-]draft`: Whether to mark change requests as drafts * `--[no-]publish` ([:material-wrench:{ .middle title="spice.submit.publish" }](/cli/config.md#spicesubmitpublish)): Whether to create CRs for pushed branches. Defaults to true. * `-w`, `--web` ([:material-wrench:{ .middle title="spice.submit.web" }](/cli/config.md#spicesubmitweb)): Open submitted changes in a web browser. Accepts an optional argument: 'true', 'false', 'created'. @@ -606,7 +607,7 @@ only if there are multiple CRs in the stack. * `--no-web`: Alias for --web=false. * `--branch=NAME`: Branch to start at -**Configuration**: [spice.submit.assignees](/cli/config.md#spicesubmitassignees), [spice.submit.draft](/cli/config.md#spicesubmitdraft), [spice.submit.labels](/cli/config.md#spicesubmitlabels), [spice.submit.labels.addWhen](/cli/config.md#spicesubmitlabelsaddwhen), [spice.submit.listTemplatesTimeout](/cli/config.md#spicesubmitlisttemplatestimeout), [spice.submit.navigationComment](/cli/config.md#spicesubmitnavigationcomment), [spice.submit.navigationComment.downstack](/cli/config.md#spicesubmitnavigationcommentdownstack), [spice.submit.navigationCommentStyle.marker](/cli/config.md#spicesubmitnavigationcommentstylemarker), [spice.submit.navigationCommentSync](/cli/config.md#spicesubmitnavigationcommentsync), [spice.submit.publish](/cli/config.md#spicesubmitpublish), [spice.submit.reviewers](/cli/config.md#spicesubmitreviewers), [spice.submit.reviewers.addWhen](/cli/config.md#spicesubmitreviewersaddwhen), [spice.submit.skipRestackCheck](/cli/config.md#spicesubmitskiprestackcheck), [spice.submit.template](/cli/config.md#spicesubmittemplate), [spice.submit.updateOnly](/cli/config.md#spicesubmitupdateonly), [spice.submit.web](/cli/config.md#spicesubmitweb) +**Configuration**: [spice.message.autoFill](/cli/config.md#spicemessageautofill), [spice.submit.assignees](/cli/config.md#spicesubmitassignees), [spice.submit.draft](/cli/config.md#spicesubmitdraft), [spice.submit.labels](/cli/config.md#spicesubmitlabels), [spice.submit.labels.addWhen](/cli/config.md#spicesubmitlabelsaddwhen), [spice.submit.listTemplatesTimeout](/cli/config.md#spicesubmitlisttemplatestimeout), [spice.submit.navigationComment](/cli/config.md#spicesubmitnavigationcomment), [spice.submit.navigationComment.downstack](/cli/config.md#spicesubmitnavigationcommentdownstack), [spice.submit.navigationCommentStyle.marker](/cli/config.md#spicesubmitnavigationcommentstylemarker), [spice.submit.navigationCommentSync](/cli/config.md#spicesubmitnavigationcommentsync), [spice.submit.publish](/cli/config.md#spicesubmitpublish), [spice.submit.reviewers](/cli/config.md#spicesubmitreviewers), [spice.submit.reviewers.addWhen](/cli/config.md#spicesubmitreviewersaddwhen), [spice.submit.skipRestackCheck](/cli/config.md#spicesubmitskiprestackcheck), [spice.submit.template](/cli/config.md#spicesubmittemplate), [spice.submit.updateOnly](/cli/config.md#spicesubmitupdateonly), [spice.submit.web](/cli/config.md#spicesubmitweb) ### git-spice downstack merge {#gs-downstack-merge} @@ -626,7 +627,7 @@ This command acts as a local merge queue: it merges one Change Request, waits for that merge to finish, restacks and updates the next Change Request, -waits for merge readiness on the updated Change Request, +waits for its CI checks to pass, and then repeats the process. For a stack like this: @@ -644,15 +645,13 @@ Before merging, the downstack is checked for branches whose base PR was already merged on the forge. Use --no-branch-check to skip this validation. -Before each merge, waits for merge readiness: -the forge must observe the pushed head -and report that the CR is ready to merge. -Use --ready-timeout to configure the maximum wait +Before each merge, waits for CI checks to pass. +Use --build-timeout to configure the maximum wait (default: 30m, 0 means fail immediately if not ready). Between merges, the command waits for each merge to complete, restacks and updates the next PR, -waits for merge readiness on the updated PR, +waits for CI checks on the updated PR, and syncs merged branch cleanup. Use --no-wait for single branch merging @@ -662,12 +661,12 @@ when you don't want to wait for the merge to propagate. **Flags** * `--method=METHOD` ([:material-wrench:{ .middle title="spice.merge.method" }](/cli/config.md#spicemergemethod)): Preferred merge method. One of 'merge', 'squash', and 'rebase'. -* `--ready-timeout=30m` ([:material-wrench:{ .middle title="spice.merge.readyTimeout" }](/cli/config.md#spicemergereadytimeout)): Max time to wait for merge readiness before each merge. 0 means check once. +* `--build-timeout=30m` ([:material-wrench:{ .middle title="spice.merge.buildTimeout" }](/cli/config.md#spicemergebuildtimeout)): Max time to wait for CI checks before each merge. 0 means check once. * `--no-wait`: Skip polling for a single branch merge to propagate. * `--no-branch-check`: Skip stale base validation before merging. * `--branch=NAME`: Branch to start merging from -**Configuration**: [spice.merge.method](/cli/config.md#spicemergemethod), [spice.merge.readyTimeout](/cli/config.md#spicemergereadytimeout) +**Configuration**: [spice.merge.buildTimeout](/cli/config.md#spicemergebuildtimeout), [spice.merge.method](/cli/config.md#spicemergemethod) ### git-spice downstack edit {#gs-downstack-edit} @@ -858,13 +857,14 @@ target (A) to the specified branch: * `--below`: Place the branch below the target branch and restack its upstack * `-t`, `--target=BRANCH`: Branch to create the new branch above/below * `-a`, `--all`: Automatically stage modified and deleted files +* `-c`, `--[no-]fill` ([:material-wrench:{ .middle title="spice.message.autoFill" }](/cli/config.md#spicemessageautofill)): Fill the commit message using the configured message generator. Defaults to spice.message.autoFill. * `-m`, `--message=MSG`: Commit message * `-F`, `--message-file=FILE`: Read the commit message from the given file. * `--no-verify`: Bypass pre-commit and commit-msg hooks. * `--signoff` ([:material-wrench:{ .middle title="spice.commit.signoff" }](/cli/config.md#spicecommitsignoff)): Add Signed-off-by trailer to the commit message * `--[no-]commit` ([:material-wrench:{ .middle title="spice.branchCreate.commit" }](/cli/config.md#spicebranchcreatecommit)): Commit staged changes to the new branch, or create an empty commit -**Configuration**: [spice.branchCreate.commit](/cli/config.md#spicebranchcreatecommit), [spice.branchCreate.generatedBranchNameLimit](/cli/config.md#spicebranchcreategeneratedbranchnamelimit), [spice.branchCreate.prefix](/cli/config.md#spicebranchcreateprefix), [spice.commit.signoff](/cli/config.md#spicecommitsignoff) +**Configuration**: [spice.branchCreate.commit](/cli/config.md#spicebranchcreatecommit), [spice.branchCreate.generatedBranchNameLimit](/cli/config.md#spicebranchcreategeneratedbranchnamelimit), [spice.branchCreate.prefix](/cli/config.md#spicebranchcreateprefix), [spice.commit.signoff](/cli/config.md#spicecommitsignoff), [spice.message.autoFill](/cli/config.md#spicemessageautofill) ### git-spice branch delete {#gs-branch-delete} @@ -988,6 +988,7 @@ to specify a commit message without editing. **Flags** +* `-c`, `--fill`: Fill the commit message using the configured message generator. * `--no-verify`: Bypass pre-commit and commit-msg hooks. * `--no-edit`: Do not open an editor to edit the squashed commit message. Only applicable if --message is not used. :material-tag:{ title="Released in version" }[v0.16.0](/changelog.md#v0.16.0) * `-m`, `--message=MSG`: Use the given message as the commit message. @@ -1137,18 +1138,16 @@ Use --branch to merge a different branch. The branch must be based directly on trunk. To merge a stacked branch, use 'gs downstack merge'. -Before merging, waits for merge readiness: -the forge must observe the pushed head -and report that the CR is ready to merge. -Use --ready-timeout to configure the maximum wait. +Before merging, waits for CI checks to pass. +Use --build-timeout to configure the maximum wait. **Flags** * `--method=METHOD` ([:material-wrench:{ .middle title="spice.merge.method" }](/cli/config.md#spicemergemethod)): Preferred merge method. One of 'merge', 'squash', and 'rebase'. -* `--ready-timeout=30m` ([:material-wrench:{ .middle title="spice.merge.readyTimeout" }](/cli/config.md#spicemergereadytimeout)): Max time to wait for merge readiness before each merge. 0 means check once. +* `--build-timeout=30m` ([:material-wrench:{ .middle title="spice.merge.buildTimeout" }](/cli/config.md#spicemergebuildtimeout)): Max time to wait for CI checks before each merge. 0 means check once. * `--branch=NAME`: Branch to merge -**Configuration**: [spice.merge.method](/cli/config.md#spicemergemethod), [spice.merge.readyTimeout](/cli/config.md#spicemergereadytimeout) +**Configuration**: [spice.merge.buildTimeout](/cli/config.md#spicemergebuildtimeout), [spice.merge.method](/cli/config.md#spicemergemethod) ### git-spice branch submit {#gs-branch-submit} @@ -1187,7 +1186,8 @@ only if there are multiple CRs in the stack. **Flags** * `-n`, `--dry-run`: Don't actually submit the stack -* `-c`, `--fill`: Fill in the change title and body from the commit messages +* `-c`, `--[no-]fill` ([:material-wrench:{ .middle title="spice.message.autoFill" }](/cli/config.md#spicemessageautofill)): Fill in the title and body of new change requests via the configured message generator. Defaults to spice.message.autoFill. Use --regenerate-message to also update existing change requests. +* `--regenerate-message`: Regenerate the title and body of existing change requests via the configured message generator. Unlike --fill, this is never implied by configuration: overwriting an existing description is always explicit. * `--[no-]draft`: Whether to mark change requests as drafts * `--[no-]publish` ([:material-wrench:{ .middle title="spice.submit.publish" }](/cli/config.md#spicesubmitpublish)): Whether to create CRs for pushed branches. Defaults to true. * `-w`, `--web` ([:material-wrench:{ .middle title="spice.submit.web" }](/cli/config.md#spicesubmitweb)): Open submitted changes in a web browser. Accepts an optional argument: 'true', 'false', 'created'. @@ -1203,7 +1203,7 @@ only if there are multiple CRs in the stack. * `--body=BODY`: Body of the change request * `--branch=NAME`: Branch to submit -**Configuration**: [spice.submit.assignees](/cli/config.md#spicesubmitassignees), [spice.submit.draft](/cli/config.md#spicesubmitdraft), [spice.submit.labels](/cli/config.md#spicesubmitlabels), [spice.submit.labels.addWhen](/cli/config.md#spicesubmitlabelsaddwhen), [spice.submit.listTemplatesTimeout](/cli/config.md#spicesubmitlisttemplatestimeout), [spice.submit.navigationComment](/cli/config.md#spicesubmitnavigationcomment), [spice.submit.navigationComment.downstack](/cli/config.md#spicesubmitnavigationcommentdownstack), [spice.submit.navigationCommentStyle.marker](/cli/config.md#spicesubmitnavigationcommentstylemarker), [spice.submit.navigationCommentSync](/cli/config.md#spicesubmitnavigationcommentsync), [spice.submit.publish](/cli/config.md#spicesubmitpublish), [spice.submit.reviewers](/cli/config.md#spicesubmitreviewers), [spice.submit.reviewers.addWhen](/cli/config.md#spicesubmitreviewersaddwhen), [spice.submit.skipRestackCheck](/cli/config.md#spicesubmitskiprestackcheck), [spice.submit.template](/cli/config.md#spicesubmittemplate), [spice.submit.web](/cli/config.md#spicesubmitweb) +**Configuration**: [spice.message.autoFill](/cli/config.md#spicemessageautofill), [spice.submit.assignees](/cli/config.md#spicesubmitassignees), [spice.submit.draft](/cli/config.md#spicesubmitdraft), [spice.submit.labels](/cli/config.md#spicesubmitlabels), [spice.submit.labels.addWhen](/cli/config.md#spicesubmitlabelsaddwhen), [spice.submit.listTemplatesTimeout](/cli/config.md#spicesubmitlisttemplatestimeout), [spice.submit.navigationComment](/cli/config.md#spicesubmitnavigationcomment), [spice.submit.navigationComment.downstack](/cli/config.md#spicesubmitnavigationcommentdownstack), [spice.submit.navigationCommentStyle.marker](/cli/config.md#spicesubmitnavigationcommentstylemarker), [spice.submit.navigationCommentSync](/cli/config.md#spicesubmitnavigationcommentsync), [spice.submit.publish](/cli/config.md#spicesubmitpublish), [spice.submit.reviewers](/cli/config.md#spicesubmitreviewers), [spice.submit.reviewers.addWhen](/cli/config.md#spicesubmitreviewersaddwhen), [spice.submit.skipRestackCheck](/cli/config.md#spicesubmitskiprestackcheck), [spice.submit.template](/cli/config.md#spicesubmittemplate), [spice.submit.web](/cli/config.md#spicesubmitweb) ## Commit @@ -1236,13 +1236,14 @@ when you want to apply changes to an older commit. * `-a`, `--all`: Stage all changes before committing. * `--allow-empty`: Create a new commit even if it contains no changes. +* `-c`, `--[no-]fill` ([:material-wrench:{ .middle title="spice.message.autoFill" }](/cli/config.md#spicemessageautofill)): Fill the commit message using the configured message generator. Defaults to spice.message.autoFill. * `--fixup=COMMIT`: Create a fixup commit. See also 'git-spice commit fixup'. * `-m`, `--message=MSG`: Use the given message as the commit message. * `-F`, `--message-file=FILE`: Read the commit message from the given file. * `--no-verify`: Bypass pre-commit and commit-msg hooks. * `--signoff` ([:material-wrench:{ .middle title="spice.commit.signoff" }](/cli/config.md#spicecommitsignoff)): Add Signed-off-by trailer to the commit message -**Configuration**: [spice.commit.signoff](/cli/config.md#spicecommitsignoff) +**Configuration**: [spice.commit.signoff](/cli/config.md#spicecommitsignoff), [spice.message.autoFill](/cli/config.md#spicemessageautofill) ### git-spice commit amend {#gs-commit-amend} @@ -1276,13 +1277,14 @@ The --no-prompt flag can be used to skip this prompt in scripts. * `-a`, `--all`: Stage all changes before committing. * `--allow-empty`: Create a commit even if it contains no changes. +* `-c`, `--[no-]fill` ([:material-wrench:{ .middle title="spice.message.autoFill" }](/cli/config.md#spicemessageautofill)): Fill the commit message using the configured message updater. Defaults to spice.message.autoFill. * `-m`, `--message=MSG`: Use the given message as the commit message. * `-F`, `--message-file=FILE`: Read the commit message from the given file. * `--no-edit`: Don't edit the commit message * `--no-verify`: Bypass pre-commit and commit-msg hooks. * `--signoff` ([:material-wrench:{ .middle title="spice.commit.signoff" }](/cli/config.md#spicecommitsignoff)): Add Signed-off-by trailer to the commit message -**Configuration**: [spice.branchCreate.generatedBranchNameLimit](/cli/config.md#spicebranchcreategeneratedbranchnamelimit), [spice.branchCreate.prefix](/cli/config.md#spicebranchcreateprefix), [spice.commit.signoff](/cli/config.md#spicecommitsignoff) +**Configuration**: [spice.branchCreate.generatedBranchNameLimit](/cli/config.md#spicebranchcreategeneratedbranchnamelimit), [spice.branchCreate.prefix](/cli/config.md#spicebranchcreateprefix), [spice.commit.signoff](/cli/config.md#spicecommitsignoff), [spice.message.autoFill](/cli/config.md#spicemessageautofill) ### git-spice commit split {#gs-commit-split} diff --git a/doc/mkdocs.yml b/doc/mkdocs.yml index 806738d93..43509296f 100644 --- a/doc/mkdocs.yml +++ b/doc/mkdocs.yml @@ -77,6 +77,7 @@ nav: - guide/branch.md - guide/cr.md - guide/scripts.md + - guide/ai-messages.md - guide/limits.md - guide/troubleshooting.md - guide/internals.md diff --git a/doc/src/cli/config.md b/doc/src/cli/config.md index bf283c603..57acb0267 100644 --- a/doc/src/cli/config.md +++ b/doc/src/cli/config.md @@ -170,6 +170,49 @@ The maximum length of branch names which are automatically generated by $$gs bra - Any integer (defaults to 32) +### spice.messageGenerator + + + +Command to generate or update messages. +When set and `--fill` is passed to a supported command, +this script runs to produce the message. + +Supported commands: +$$gs commit create$$, $$gs commit amend$$, +$$gs branch create$$, $$gs branch submit$$, +and $$gs branch squash$$. + +The command runs in the repository root +and receives the following environment variables: + +- `GS_MESSAGE_KIND`: `commit` or `branch` +- `GS_MESSAGE_UPDATE`: `true` if updating, `false` if new +- `GS_BRANCH`: current or submitting branch name +- `GS_BASE`: base branch name (when applicable) +- `GS_MESSAGE`: existing commit message + (commit amend, squash) +- `GS_TITLE`: existing CR title (branch updater) +- `GS_BODY`: existing CR body (branch updater) + +The invoking process's argument vector +is forwarded to the script as positional parameters. + +For commit messages, +the output is used as the full commit message. +For branch messages (CR title and body), +the first line of output becomes the title +and everything after the first blank line becomes the body. + +If the command fails or produces empty output, +git-spice falls back to the default behavior +(opening the editor or using commit messages). + +If the value starts with `#!`, +it is written to a temporary file and executed +with the interpreter specified in the shebang line. +Otherwise, it is passed to `sh -c`. + ### spice.commit.signoff diff --git a/doc/src/guide/ai-messages.md b/doc/src/guide/ai-messages.md new file mode 100644 index 000000000..df2f25358 --- /dev/null +++ b/doc/src/guide/ai-messages.md @@ -0,0 +1,148 @@ +--- +title: AI-powered messages +icon: material/robot +description: >- + Use AI tools to generate and update + commit messages and CR descriptions. +--- + +# AI-powered messages + + + +git-spice can invoke an external script to generate or update commit +messages and CR descriptions. The script speaks the shared script +protocol — see **[Script integrations](scripts.md)** for the +JSON output schema, environment contract, and failure semantics. +This page only documents what is message-generation-specific. + +## Configuration + +Two git-config keys control the feature: + +- $$spice.message.generator$$ — the generator script body. The value + is the script itself (not a path); git-spice runs it via `sh -c`, + or executes it directly if it starts with `#!`. Typically set at + `--global` scope. +- $$spice.message.autoFill$$ — when `true`, the generator runs by + default and `--no-fill` opts out per invocation. Defaults to + `false`; `--fill` is the explicit opt-in. + +Per-invocation overrides on every fill-aware command: + +- `--fill` runs the generator for this invocation. +- `--no-fill` skips it, even when $$spice.message.autoFill$$ is on. + +For `gs branch submit` (and the stack/upstack/downstack variants), +`--fill` and $$spice.message.autoFill$$ only generate the message when +*creating* a change request. They never overwrite the title and body +of an existing change request — that would clobber descriptions you +may have edited by hand, and on a batch submit would do so for every +change at once. To deliberately regenerate the description of an +existing change request, pass `--regenerate-message`. It runs the +generator regardless of $$spice.message.autoFill$$, because +overwriting an existing description is always an explicit choice. + +## Supported commands and operation values + +`GS_OPERATION` (from the +[shared env contract](scripts.md#environment-contract)) is set per +caller: + +| Command | `GS_OPERATION` | `GS_MESSAGE_UPDATE` | +|---------|----------------|---------------------| +| `gs commit create --fill` | `commit-create` | `false` | +| `gs commit amend --fill` | `commit-amend` | `true` | +| `gs branch create --fill` | `branch-create` | `false` | +| `gs branch submit --fill` (new CR) | `branch-submit` | `false` | +| `gs branch submit --fill` (existing CR) | `branch-submit` | `true` | +| `gs branch squash --fill` | `branch-squash` | `true` | + +## Message-specific environment + +In addition to the shared +[`GS_OPERATION` / `GS_BRANCH` / `GS_BASE`](scripts.md#environment-contract) +values, message-generation scripts also receive: + +| Variable | Available in | Meaning | +|---|---|---| +| `GS_MESSAGE_UPDATE` | All scripts | `true` if updating an existing message | +| `GS_MESSAGE` | Commit amend, squash | Existing commit message | +| `GS_TITLE` | Branch submit (existing CR) | Existing CR title | +| `GS_BODY` | Branch submit (existing CR) | Existing CR body | + +## Output + +Scripts emit the [shared JSON +protocol](scripts.md#output-contract). For message generation the +relevant fields are: + +- `title` (required) — the first-line commit subject or CR title. +- `body` (optional) — multi-line message body. +- `assumptions` (optional) — surfaced in the gs log. +- `questions` (optional) — drive an interactive Q&A loop; answers + persist in `.spice/resolutions/message.json` and are reused on + subsequent runs for the same branch. + +## Examples + +### Using Claude Code + +Configure a single generator that handles all message types. The +prompt uses `` delimiters so that only the intended JSON +payload is extracted from the output, discarding any reasoning or +explanation. + +```bash +git config --global spice.message.generator '#!/bin/sh + +# Compute the relevant diff based on context. +if [ "${GS_OPERATION%-*}" = "branch" ]; then + DIFF=$(git diff "$GS_BASE"..."$GS_BRANCH") +elif [ "$GS_MESSAGE_UPDATE" = "true" ]; then + DIFF=$(git diff HEAD~1) +else + DIFF=$(git diff --cached) +fi + +claude --no-session-persistence -p " +You are helping write a git message. GS_OPERATION=$GS_OPERATION, +GS_MESSAGE_UPDATE=$GS_MESSAGE_UPDATE. + +Operations starting with commit- or branch-create expect a commit +message; operations starting with branch- (submit/squash) expect a +CR title and body. Describe ONLY the changes shown in the diff. +Do not describe the broader feature or changes from other branches +in the stack. + +If updating, improve the existing message: +$GS_MESSAGE $GS_TITLE $GS_BODY + +Here is the diff: +$DIFF + +Output a JSON document between and tags +matching the shared script-integration protocol: + + + {\"title\":\"\",\"body\":\"\"} + +" --output-format text 2>/dev/null \ + | sed -n "//,/<\/message>/{//d;/<\/message>/d;p;}" +' +``` + +!!! tip + + `--no-session-persistence` prevents each invocation + from cluttering your session log. + For faster startup, add `--bare` and set `ANTHROPIC_API_KEY` + in your environment (`--bare` skips keychain/OAuth reads). + +### Using a simple shell script + +```bash +git config --global spice.message.generator \ + '#!/bin/sh +printf '\''{"title":"feat: auto-generated for %s"}'\'' "$GS_OPERATION"' +``` diff --git a/internal/forge/bitbucket/edit.go b/internal/forge/bitbucket/edit.go index c12aa4515..909e8e45c 100644 --- a/internal/forge/bitbucket/edit.go +++ b/internal/forge/bitbucket/edit.go @@ -24,6 +24,12 @@ func (r *Repository) EditChange( return err } + if err := r.updatePRSubjectBody( + ctx, prID, opts.Subject, opts.Body, + ); err != nil { + return err + } + if err := r.addPRReviewers(ctx, prID, opts.AddReviewers); err != nil { return err } @@ -44,6 +50,26 @@ func (r *Repository) updatePRBase(ctx context.Context, prID int64, base string) }) } +func (r *Repository) updatePRSubjectBody( + ctx context.Context, + prID int64, + subject string, + body *string, +) error { + if subject == "" && body == nil { + return nil + } + + req := &bitbucket.PullRequestUpdateRequest{} + if subject != "" { + req.Title = &subject + } + if body != nil { + req.Description = body + } + return r.updatePullRequest(ctx, prID, req) +} + func (r *Repository) updatePRDraft(ctx context.Context, prID int64, draft *bool) error { if draft == nil { return nil diff --git a/internal/forge/bitbucket/find.go b/internal/forge/bitbucket/find.go index f629e3ae7..d78800eb3 100644 --- a/internal/forge/bitbucket/find.go +++ b/internal/forge/bitbucket/find.go @@ -92,6 +92,7 @@ func (r *Repository) convertPRToFindItem(pr *bitbucket.PullRequest) *forge.FindC URL: pr.Links.HTML.Href, State: stateFromAPI(pr.State), Subject: pr.Title, + Body: pr.Description, BaseName: pr.Destination.Branch.Name, HeadHash: extractHeadHash(pr), Draft: pr.Draft, diff --git a/internal/forge/forge.go b/internal/forge/forge.go index 3c855cc5d..2debd87db 100644 --- a/internal/forge/forge.go +++ b/internal/forge/forge.go @@ -499,6 +499,14 @@ type EditChangeOptions struct { // AddAssignees are new users to assign to the change. // Existing assignees associated with the change will not be modified. AddAssignees []string + + // Subject specifies a new title for the change. + // If empty, the title is not changed. + Subject string + + // Body specifies a new description for the change. + // If nil, the description is not changed. + Body *string } // MergeChangeOptions specifies options for a merge operation. @@ -765,6 +773,9 @@ type FindChangeItem struct { // Subject is the title of the change. Subject string // required + // Body is the description of the change. + Body string + // HeadHash is the hash of the commit at the top of the change. HeadHash git.Hash // required diff --git a/internal/forge/github/edit.go b/internal/forge/github/edit.go index 197f2b7d8..13d0d7175 100644 --- a/internal/forge/github/edit.go +++ b/internal/forge/github/edit.go @@ -13,6 +13,8 @@ import ( func (r *Repository) EditChange(ctx context.Context, fid forge.ChangeID, opts forge.EditChangeOptions) error { if cmputil.Zero(opts.Base) && cmputil.Zero(opts.Draft) && + cmputil.Zero(opts.Subject) && + cmputil.Zero(opts.Body) && len(opts.AddLabels) == 0 && len(opts.AddReviewers) == 0 && len(opts.AddAssignees) == 0 { @@ -26,7 +28,7 @@ func (r *Repository) EditChange(ctx context.Context, fid forge.ChangeID, opts fo return fmt.Errorf("get pull request ID: %w", err) } - if opts.Base != "" { + if opts.Base != "" || opts.Subject != "" || opts.Body != nil { var m struct { UpdatePullRequest struct { // We don't need any information back, @@ -37,13 +39,21 @@ func (r *Repository) EditChange(ctx context.Context, fid forge.ChangeID, opts fo input := githubv4.UpdatePullRequestInput{ PullRequestID: graphQLID, - BaseRefName: (*githubv4.String)(&opts.Base), + } + if opts.Base != "" { + input.BaseRefName = (*githubv4.String)(&opts.Base) + } + if opts.Subject != "" { + input.Title = (*githubv4.String)(&opts.Subject) + } + if opts.Body != nil { + input.Body = (*githubv4.String)(opts.Body) } if err := r.client.Mutate(ctx, &m, input, nil); err != nil { return fmt.Errorf("edit pull request: %w", err) } - r.log.Debug("Changed base branch for PR", "new.base", opts.Base) + r.log.Debug("Updated PR", "pr", pr.Number) } // Draft status is a separate API call for some reason. diff --git a/internal/forge/github/find.go b/internal/forge/github/find.go index 94dddb60b..a6093e869 100644 --- a/internal/forge/github/find.go +++ b/internal/forge/github/find.go @@ -14,6 +14,7 @@ type findPRNode struct { Number githubv4.Int `graphql:"number"` URL githubv4.URI `graphql:"url"` Title githubv4.String `graphql:"title"` + Body githubv4.String `graphql:"body"` State githubv4.PullRequestState `graphql:"state"` HeadRefOid githubv4.GitObjectID `graphql:"headRefOid"` BaseRefName githubv4.String `graphql:"baseRefName"` @@ -80,6 +81,7 @@ func (n *findPRNode) toFindChangeItem() *forge.FindChangeItem { URL: n.URL.String(), State: forgeChangeState(n.State), Subject: string(n.Title), + Body: string(n.Body), BaseName: string(n.BaseRefName), HeadHash: git.Hash(n.HeadRefOid), Draft: bool(n.IsDraft), diff --git a/internal/forge/github/testdata/fixtures/TestIntegration/FindChangesByBranchDoesNotExist.yaml b/internal/forge/github/testdata/fixtures/TestIntegration/FindChangesByBranchDoesNotExist.yaml index 0a3aa7ee2..cdbcdfda8 100644 --- a/internal/forge/github/testdata/fixtures/TestIntegration/FindChangesByBranchDoesNotExist.yaml +++ b/internal/forge/github/testdata/fixtures/TestIntegration/FindChangesByBranchDoesNotExist.yaml @@ -6,7 +6,7 @@ interactions: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 - content_length: 142 + content_length: 146 host: api.github.com body: | {"query":"query($owner:String!$repo:String!){repository(owner: $owner, name: $repo){id}}","variables":{"owner":"test-owner","repo":"test-repo"}} @@ -21,22 +21,22 @@ interactions: proto_minor: 0 content_length: -1 uncompressed: true - body: '{"data":{"repository":{"id":"R_kgDOMVd0xg"}}}' + body: '{"data":{"repository":{"id":"R_kgDORFeuHw"}}}' headers: Content-Type: - application/json; charset=utf-8 status: 200 OK code: 200 - duration: 438.32575ms + duration: 784.213708ms - id: 1 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 - content_length: 621 + content_length: 591 host: api.github.com body: | - {"query":"query($branch:String!$limit:Int!$owner:String!$repo:String!$states:[PullRequestState!]!){repository(owner: $owner, name: $repo){pullRequests(first: $limit, headRefName: $branch, states: $states, orderBy: {field: UPDATED_AT, direction: DESC}){nodes{id,number,url,title,state,headRefOid,baseRefName,isDraft,headRepository{owner{login},name},labels(first: 100){nodes{name}},reviewRequests(first: 100){nodes{requestedReviewer{... on Actor{login}}}},assignees(first: 100){nodes{login}}}}}}","variables":{"branch":"does-not-exist","limit":10,"owner":"test-owner","repo":"test-repo","states":["OPEN","CLOSED","MERGED"]}} + {"query":"query($branch:String!$limit:Int!$owner:String!$repo:String!$states:[PullRequestState!]!){repository(owner: $owner, name: $repo){pullRequests(first: $limit, headRefName: $branch, states: $states, orderBy: {field: UPDATED_AT, direction: DESC}){nodes{id,number,url,title,body,state,headRefOid,baseRefName,isDraft,labels(first: 100){nodes{name}},reviewRequests(first: 100){nodes{requestedReviewer{... on Actor{login}}}},assignees(first: 100){nodes{login}}}}}}","variables":{"branch":"does-not-exist","limit":10,"owner":"test-owner","repo":"test-repo","states":["OPEN","CLOSED","MERGED"]}} headers: Content-Type: - application/json @@ -54,4 +54,4 @@ interactions: - application/json; charset=utf-8 status: 200 OK code: 200 - duration: 270.861459ms + duration: 192.812375ms diff --git a/internal/forge/github/testdata/fixtures/TestIntegration/SubmitEditAssignees/AddAssignee.yaml b/internal/forge/github/testdata/fixtures/TestIntegration/SubmitEditAssignees/AddAssignee.yaml index aa954eb69..b50d7b0e7 100644 --- a/internal/forge/github/testdata/fixtures/TestIntegration/SubmitEditAssignees/AddAssignee.yaml +++ b/internal/forge/github/testdata/fixtures/TestIntegration/SubmitEditAssignees/AddAssignee.yaml @@ -6,7 +6,7 @@ interactions: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 - content_length: 142 + content_length: 146 host: api.github.com body: | {"query":"query($owner:String!$repo:String!){repository(owner: $owner, name: $repo){id}}","variables":{"owner":"test-owner","repo":"test-repo"}} @@ -21,13 +21,13 @@ interactions: proto_minor: 0 content_length: -1 uncompressed: true - body: '{"data":{"repository":{"id":"R_kgDOMVd0xg"}}}' + body: '{"data":{"repository":{"id":"R_kgDORFeuHw"}}}' headers: Content-Type: - application/json; charset=utf-8 status: 200 OK code: 200 - duration: 226.9605ms + duration: 132.208583ms - id: 1 request: proto: HTTP/1.1 @@ -36,7 +36,7 @@ interactions: content_length: 277 host: api.github.com body: | - {"query":"mutation($input:CreatePullRequestInput!){createPullRequest(input: $input){pullRequest{id,number,url}}}","variables":{"input":{"repositoryId":"R_kgDOMVd0xg","baseRefName":"main","headRefName":"YzGo60Kw","title":"Testing YzGo60Kw","body":"Test PR without assignees"}}} + {"query":"mutation($input:CreatePullRequestInput!){createPullRequest(input: $input){pullRequest{id,number,url}}}","variables":{"input":{"repositoryId":"R_kgDORFeuHw","baseRefName":"main","headRefName":"JqOjEYLO","title":"Testing JqOjEYLO","body":"Test PR without assignees"}}} headers: Content-Type: - application/json @@ -48,22 +48,22 @@ interactions: proto_minor: 0 content_length: -1 uncompressed: true - body: '{"data":{"createPullRequest":{"pullRequest":{"id":"PR_kwDOMVd0xs7XrmCc","number":82,"url":"https://github.com/test-owner/test-repo/pull/82"}}}}' + body: '{"data":{"createPullRequest":{"pullRequest":{"id":"PR_kwDORFeuH87AtaAy","number":61,"url":"https://github.com/test-owner/test-repo/pull/61"}}}}' headers: Content-Type: - application/json; charset=utf-8 status: 200 OK code: 200 - duration: 825.8385ms + duration: 931.040792ms - id: 2 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 - content_length: 426 + content_length: 396 host: api.github.com body: | - {"query":"query($number:Int!$owner:String!$repo:String!){repository(owner: $owner, name: $repo){pullRequest(number: $number){id,number,url,title,state,headRefOid,baseRefName,isDraft,headRepository{owner{login},name},labels(first: 100){nodes{name}},reviewRequests(first: 100){nodes{requestedReviewer{... on Actor{login}}}},assignees(first: 100){nodes{login}}}}}","variables":{"number":82,"owner":"test-owner","repo":"test-repo"}} + {"query":"query($number:Int!$owner:String!$repo:String!){repository(owner: $owner, name: $repo){pullRequest(number: $number){id,number,url,title,body,state,headRefOid,baseRefName,isDraft,labels(first: 100){nodes{name}},reviewRequests(first: 100){nodes{requestedReviewer{... on Actor{login}}}},assignees(first: 100){nodes{login}}}}}","variables":{"number":61,"owner":"test-owner","repo":"test-repo"}} headers: Content-Type: - application/json @@ -75,22 +75,22 @@ interactions: proto_minor: 0 content_length: -1 uncompressed: true - body: '{"data":{"repository":{"pullRequest":{"id":"PR_kwDOMVd0xs7XrmCc","number":82,"url":"https://github.com/test-owner/test-repo/pull/82","title":"Testing YzGo60Kw","state":"OPEN","headRefOid":"5283cc32fb924518fe9608b2bcdfe76b59f2a315","baseRefName":"main","isDraft":false,"headRepository":{"owner":{"login":"test-owner"},"name":"test-repo"},"labels":{"nodes":[]},"reviewRequests":{"nodes":[]},"assignees":{"nodes":[]}}}}}' + body: '{"data":{"repository":{"pullRequest":{"id":"PR_kwDORFeuH87AtaAy","number":61,"url":"https://github.com/test-owner/test-repo/pull/61","title":"Testing JqOjEYLO","state":"OPEN","headRefOid":"dc804c62331ab8dc86f236906e4d7b06163c3e5b","baseRefName":"main","isDraft":false,"labels":{"nodes":[]},"reviewRequests":{"nodes":[]},"assignees":{"nodes":[]}}}}}' headers: Content-Type: - application/json; charset=utf-8 status: 200 OK code: 200 - duration: 263.56125ms + duration: 187.659208ms - id: 3 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 - content_length: 91 + content_length: 92 host: api.github.com body: | - {"query":"query($login:String!){user(login: $login){id}}","variables":{"login":"test-owner"}} + {"query":"query($login:String!){user(login: $login){id}}","variables":{"login":"test-owner-robot"}} headers: Content-Type: - application/json @@ -102,22 +102,22 @@ interactions: proto_minor: 0 content_length: -1 uncompressed: true - body: '{"data":{"user":{"id":"MDQ6VXNlcjQxNzMw"}}}' + body: '{"data":{"user":{"id":"MDQ6VXNlcjQ3MjUzNw=="}}}' headers: Content-Type: - application/json; charset=utf-8 status: 200 OK code: 200 - duration: 181.914417ms + duration: 140.613792ms - id: 4 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 - content_length: 215 + content_length: 219 host: api.github.com body: | - {"query":"mutation($input:AddAssigneesToAssignableInput!){addAssigneesToAssignable(input: $input){clientMutationId}}","variables":{"input":{"assignableId":"PR_kwDOMVd0xs7XrmCc","assigneeIds":["MDQ6VXNlcjQxNzMw"]}}} + {"query":"mutation($input:AddAssigneesToAssignableInput!){addAssigneesToAssignable(input: $input){clientMutationId}}","variables":{"input":{"assignableId":"PR_kwDORFeuH87AtaAy","assigneeIds":["MDQ6VXNlcjQ3MjUzNw=="]}}} headers: Content-Type: - application/json @@ -129,22 +129,22 @@ interactions: proto_minor: 0 content_length: -1 uncompressed: true - body: '{"data":{"addAssigneesToAssignable":{"clientMutationId":null}},"extensions":{"warnings":[{"type":"DEPRECATION","message":"The id MDQ6VXNlcjQxNzMw is deprecated. Update your cache to use the next_global_id from the data payload.","data":{"legacy_global_id":"MDQ6VXNlcjQxNzMw","next_global_id":"U_kgDNowI"},"link":"https://docs.github.com"}]}}' + body: '{"data":{"addAssigneesToAssignable":{"clientMutationId":null}},"extensions":{"warnings":[{"type":"DEPRECATION","message":"The id MDQ6VXNlcjQ3MjUzNw== is deprecated. Update your cache to use the next_global_id from the data payload.","data":{"legacy_global_id":"MDQ6VXNlcjQ3MjUzNw==","next_global_id":"U_kgDOAAc12Q"},"link":"https://docs.github.com"}]}}' headers: Content-Type: - application/json; charset=utf-8 status: 200 OK code: 200 - duration: 664.769625ms + duration: 541.864125ms - id: 5 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 - content_length: 426 + content_length: 396 host: api.github.com body: | - {"query":"query($number:Int!$owner:String!$repo:String!){repository(owner: $owner, name: $repo){pullRequest(number: $number){id,number,url,title,state,headRefOid,baseRefName,isDraft,headRepository{owner{login},name},labels(first: 100){nodes{name}},reviewRequests(first: 100){nodes{requestedReviewer{... on Actor{login}}}},assignees(first: 100){nodes{login}}}}}","variables":{"number":82,"owner":"test-owner","repo":"test-repo"}} + {"query":"query($number:Int!$owner:String!$repo:String!){repository(owner: $owner, name: $repo){pullRequest(number: $number){id,number,url,title,body,state,headRefOid,baseRefName,isDraft,labels(first: 100){nodes{name}},reviewRequests(first: 100){nodes{requestedReviewer{... on Actor{login}}}},assignees(first: 100){nodes{login}}}}}","variables":{"number":61,"owner":"test-owner","repo":"test-repo"}} headers: Content-Type: - application/json @@ -156,10 +156,10 @@ interactions: proto_minor: 0 content_length: -1 uncompressed: true - body: '{"data":{"repository":{"pullRequest":{"id":"PR_kwDOMVd0xs7XrmCc","number":82,"url":"https://github.com/test-owner/test-repo/pull/82","title":"Testing YzGo60Kw","state":"OPEN","headRefOid":"5283cc32fb924518fe9608b2bcdfe76b59f2a315","baseRefName":"main","isDraft":false,"headRepository":{"owner":{"login":"test-owner"},"name":"test-repo"},"labels":{"nodes":[]},"reviewRequests":{"nodes":[]},"assignees":{"nodes":[{"login":"test-owner"}]}}}}}' + body: '{"data":{"repository":{"pullRequest":{"id":"PR_kwDORFeuH87AtaAy","number":61,"url":"https://github.com/test-owner/test-repo/pull/61","title":"Testing JqOjEYLO","state":"OPEN","headRefOid":"dc804c62331ab8dc86f236906e4d7b06163c3e5b","baseRefName":"main","isDraft":false,"labels":{"nodes":[]},"reviewRequests":{"nodes":[]},"assignees":{"nodes":[{"login":"test-owner-robot"}]}}}}}' headers: Content-Type: - application/json; charset=utf-8 status: 200 OK code: 200 - duration: 375.316875ms + duration: 164.632542ms diff --git a/internal/forge/github/testdata/fixtures/TestIntegration/SubmitEditAssignees/AddAssigneesOneByOne.yaml b/internal/forge/github/testdata/fixtures/TestIntegration/SubmitEditAssignees/AddAssigneesOneByOne.yaml index 8f36d168c..78d0e42da 100644 --- a/internal/forge/github/testdata/fixtures/TestIntegration/SubmitEditAssignees/AddAssigneesOneByOne.yaml +++ b/internal/forge/github/testdata/fixtures/TestIntegration/SubmitEditAssignees/AddAssigneesOneByOne.yaml @@ -144,7 +144,7 @@ interactions: content_length: 392 host: api.github.com body: | - {"query":"query($number:Int!$owner:String!$repo:String!){repository(owner: $owner, name: $repo){pullRequest(number: $number){id,number,url,title,state,headRefOid,baseRefName,isDraft,labels(first: 100){nodes{name}},reviewRequests(first: 100){nodes{requestedReviewer{... on Actor{login}}}},assignees(first: 100){nodes{login}}}}}","variables":{"number":58,"owner":"test-owner","repo":"test-repo"}} + {"query":"query($number:Int!$owner:String!$repo:String!){repository(owner: $owner, name: $repo){pullRequest(number: $number){id,number,url,title,body,state,headRefOid,baseRefName,isDraft,labels(first: 100){nodes{name}},reviewRequests(first: 100){nodes{requestedReviewer{... on Actor{login}}}},assignees(first: 100){nodes{login}}}}}","variables":{"number":58,"owner":"test-owner","repo":"test-repo"}} headers: Content-Type: - application/json diff --git a/internal/forge/github/testdata/fixtures/TestIntegration/SubmitEditAssignees/SubmitWithAssignee.yaml b/internal/forge/github/testdata/fixtures/TestIntegration/SubmitEditAssignees/SubmitWithAssignee.yaml index 48697a99c..4e30c322d 100644 --- a/internal/forge/github/testdata/fixtures/TestIntegration/SubmitEditAssignees/SubmitWithAssignee.yaml +++ b/internal/forge/github/testdata/fixtures/TestIntegration/SubmitEditAssignees/SubmitWithAssignee.yaml @@ -6,7 +6,7 @@ interactions: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 - content_length: 142 + content_length: 146 host: api.github.com body: | {"query":"query($owner:String!$repo:String!){repository(owner: $owner, name: $repo){id}}","variables":{"owner":"test-owner","repo":"test-repo"}} @@ -21,13 +21,13 @@ interactions: proto_minor: 0 content_length: -1 uncompressed: true - body: '{"data":{"repository":{"id":"R_kgDOMVd0xg"}}}' + body: '{"data":{"repository":{"id":"R_kgDORFeuHw"}}}' headers: Content-Type: - application/json; charset=utf-8 status: 200 OK code: 200 - duration: 321.043625ms + duration: 215.350958ms - id: 1 request: proto: HTTP/1.1 @@ -36,7 +36,7 @@ interactions: content_length: 273 host: api.github.com body: | - {"query":"mutation($input:CreatePullRequestInput!){createPullRequest(input: $input){pullRequest{id,number,url}}}","variables":{"input":{"repositoryId":"R_kgDOMVd0xg","baseRefName":"main","headRefName":"KbHQmhqp","title":"Testing KbHQmhqp","body":"Test PR with assignee"}}} + {"query":"mutation($input:CreatePullRequestInput!){createPullRequest(input: $input){pullRequest{id,number,url}}}","variables":{"input":{"repositoryId":"R_kgDORFeuHw","baseRefName":"main","headRefName":"ly4mqLzC","title":"Testing ly4mqLzC","body":"Test PR with assignee"}}} headers: Content-Type: - application/json @@ -48,22 +48,22 @@ interactions: proto_minor: 0 content_length: -1 uncompressed: true - body: '{"data":{"createPullRequest":{"pullRequest":{"id":"PR_kwDOMVd0xs7XrmCS","number":81,"url":"https://github.com/test-owner/test-repo/pull/81"}}}}' + body: '{"data":{"createPullRequest":{"pullRequest":{"id":"PR_kwDORFeuH87AtZ_A","number":58,"url":"https://github.com/test-owner/test-repo/pull/58"}}}}' headers: Content-Type: - application/json; charset=utf-8 status: 200 OK code: 200 - duration: 1.006462875s + duration: 663.888708ms - id: 2 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 - content_length: 91 + content_length: 92 host: api.github.com body: | - {"query":"query($login:String!){user(login: $login){id}}","variables":{"login":"test-owner"}} + {"query":"query($login:String!){user(login: $login){id}}","variables":{"login":"test-owner-robot"}} headers: Content-Type: - application/json @@ -75,22 +75,22 @@ interactions: proto_minor: 0 content_length: -1 uncompressed: true - body: '{"data":{"user":{"id":"MDQ6VXNlcjQxNzMw"}}}' + body: '{"data":{"user":{"id":"MDQ6VXNlcjQ3MjUzNw=="}}}' headers: Content-Type: - application/json; charset=utf-8 status: 200 OK code: 200 - duration: 215.445709ms + duration: 126.167791ms - id: 3 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 - content_length: 215 + content_length: 219 host: api.github.com body: | - {"query":"mutation($input:AddAssigneesToAssignableInput!){addAssigneesToAssignable(input: $input){clientMutationId}}","variables":{"input":{"assignableId":"PR_kwDOMVd0xs7XrmCS","assigneeIds":["MDQ6VXNlcjQxNzMw"]}}} + {"query":"mutation($input:AddAssigneesToAssignableInput!){addAssigneesToAssignable(input: $input){clientMutationId}}","variables":{"input":{"assignableId":"PR_kwDORFeuH87AtZ_A","assigneeIds":["MDQ6VXNlcjQ3MjUzNw=="]}}} headers: Content-Type: - application/json @@ -102,22 +102,22 @@ interactions: proto_minor: 0 content_length: -1 uncompressed: true - body: '{"data":{"addAssigneesToAssignable":{"clientMutationId":null}},"extensions":{"warnings":[{"type":"DEPRECATION","message":"The id MDQ6VXNlcjQxNzMw is deprecated. Update your cache to use the next_global_id from the data payload.","data":{"legacy_global_id":"MDQ6VXNlcjQxNzMw","next_global_id":"U_kgDNowI"},"link":"https://docs.github.com"}]}}' + body: '{"data":{"addAssigneesToAssignable":{"clientMutationId":null}},"extensions":{"warnings":[{"type":"DEPRECATION","message":"The id MDQ6VXNlcjQ3MjUzNw== is deprecated. Update your cache to use the next_global_id from the data payload.","data":{"legacy_global_id":"MDQ6VXNlcjQ3MjUzNw==","next_global_id":"U_kgDOAAc12Q"},"link":"https://docs.github.com"}]}}' headers: Content-Type: - application/json; charset=utf-8 status: 200 OK code: 200 - duration: 826.706834ms + duration: 522.887875ms - id: 4 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 - content_length: 426 + content_length: 396 host: api.github.com body: | - {"query":"query($number:Int!$owner:String!$repo:String!){repository(owner: $owner, name: $repo){pullRequest(number: $number){id,number,url,title,state,headRefOid,baseRefName,isDraft,headRepository{owner{login},name},labels(first: 100){nodes{name}},reviewRequests(first: 100){nodes{requestedReviewer{... on Actor{login}}}},assignees(first: 100){nodes{login}}}}}","variables":{"number":81,"owner":"test-owner","repo":"test-repo"}} + {"query":"query($number:Int!$owner:String!$repo:String!){repository(owner: $owner, name: $repo){pullRequest(number: $number){id,number,url,title,body,state,headRefOid,baseRefName,isDraft,labels(first: 100){nodes{name}},reviewRequests(first: 100){nodes{requestedReviewer{... on Actor{login}}}},assignees(first: 100){nodes{login}}}}}","variables":{"number":58,"owner":"test-owner","repo":"test-repo"}} headers: Content-Type: - application/json @@ -129,22 +129,22 @@ interactions: proto_minor: 0 content_length: -1 uncompressed: true - body: '{"data":{"repository":{"pullRequest":{"id":"PR_kwDOMVd0xs7XrmCS","number":81,"url":"https://github.com/test-owner/test-repo/pull/81","title":"Testing KbHQmhqp","state":"OPEN","headRefOid":"78103ab8c69e880a4b7c85bfac02743eb0d63c48","baseRefName":"main","isDraft":false,"headRepository":{"owner":{"login":"test-owner"},"name":"test-repo"},"labels":{"nodes":[]},"reviewRequests":{"nodes":[]},"assignees":{"nodes":[{"login":"test-owner"}]}}}}}' + body: '{"data":{"repository":{"pullRequest":{"id":"PR_kwDORFeuH87AtZ_A","number":58,"url":"https://github.com/test-owner/test-repo/pull/58","title":"Testing ly4mqLzC","state":"OPEN","headRefOid":"beadec4bb26673c26af712e9f50a8abc8b81382a","baseRefName":"main","isDraft":false,"labels":{"nodes":[]},"reviewRequests":{"nodes":[]},"assignees":{"nodes":[{"login":"test-owner-robot"}]}}}}}' headers: Content-Type: - application/json; charset=utf-8 status: 200 OK code: 200 - duration: 275.43125ms + duration: 258.815375ms - id: 5 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 - content_length: 615 + content_length: 585 host: api.github.com body: | - {"query":"query($branch:String!$limit:Int!$owner:String!$repo:String!$states:[PullRequestState!]!){repository(owner: $owner, name: $repo){pullRequests(first: $limit, headRefName: $branch, states: $states, orderBy: {field: UPDATED_AT, direction: DESC}){nodes{id,number,url,title,state,headRefOid,baseRefName,isDraft,headRepository{owner{login},name},labels(first: 100){nodes{name}},reviewRequests(first: 100){nodes{requestedReviewer{... on Actor{login}}}},assignees(first: 100){nodes{login}}}}}}","variables":{"branch":"KbHQmhqp","limit":10,"owner":"test-owner","repo":"test-repo","states":["OPEN","CLOSED","MERGED"]}} + {"query":"query($branch:String!$limit:Int!$owner:String!$repo:String!$states:[PullRequestState!]!){repository(owner: $owner, name: $repo){pullRequests(first: $limit, headRefName: $branch, states: $states, orderBy: {field: UPDATED_AT, direction: DESC}){nodes{id,number,url,title,body,state,headRefOid,baseRefName,isDraft,labels(first: 100){nodes{name}},reviewRequests(first: 100){nodes{requestedReviewer{... on Actor{login}}}},assignees(first: 100){nodes{login}}}}}}","variables":{"branch":"ly4mqLzC","limit":10,"owner":"test-owner","repo":"test-repo","states":["OPEN","CLOSED","MERGED"]}} headers: Content-Type: - application/json @@ -156,10 +156,10 @@ interactions: proto_minor: 0 content_length: -1 uncompressed: true - body: '{"data":{"repository":{"pullRequests":{"nodes":[{"id":"PR_kwDOMVd0xs7XrmCS","number":81,"url":"https://github.com/test-owner/test-repo/pull/81","title":"Testing KbHQmhqp","state":"OPEN","headRefOid":"78103ab8c69e880a4b7c85bfac02743eb0d63c48","baseRefName":"main","isDraft":false,"headRepository":{"owner":{"login":"test-owner"},"name":"test-repo"},"labels":{"nodes":[]},"reviewRequests":{"nodes":[]},"assignees":{"nodes":[{"login":"test-owner"}]}}]}}}}' + body: '{"data":{"repository":{"pullRequests":{"nodes":[{"id":"PR_kwDORFeuH87AtZ_A","number":58,"url":"https://github.com/test-owner/test-repo/pull/58","title":"Testing ly4mqLzC","state":"OPEN","headRefOid":"beadec4bb26673c26af712e9f50a8abc8b81382a","baseRefName":"main","isDraft":false,"labels":{"nodes":[]},"reviewRequests":{"nodes":[]},"assignees":{"nodes":[{"login":"test-owner-robot"}]}}]}}}}' headers: Content-Type: - application/json; charset=utf-8 status: 200 OK code: 200 - duration: 419.090792ms + duration: 523.299458ms diff --git a/internal/forge/github/testdata/fixtures/TestIntegration/SubmitEditBase.yaml b/internal/forge/github/testdata/fixtures/TestIntegration/SubmitEditBase.yaml index b5d9d585c..702e4b5c0 100644 --- a/internal/forge/github/testdata/fixtures/TestIntegration/SubmitEditBase.yaml +++ b/internal/forge/github/testdata/fixtures/TestIntegration/SubmitEditBase.yaml @@ -6,7 +6,7 @@ interactions: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 - content_length: 142 + content_length: 146 host: api.github.com body: | {"query":"query($owner:String!$repo:String!){repository(owner: $owner, name: $repo){id}}","variables":{"owner":"test-owner","repo":"test-repo"}} @@ -21,13 +21,13 @@ interactions: proto_minor: 0 content_length: -1 uncompressed: true - body: '{"data":{"repository":{"id":"R_kgDOMVd0xg"}}}' + body: '{"data":{"repository":{"id":"R_kgDORFeuHw"}}}' headers: Content-Type: - application/json; charset=utf-8 status: 200 OK code: 200 - duration: 191.899208ms + duration: 131.6815ms - id: 1 request: proto: HTTP/1.1 @@ -36,7 +36,7 @@ interactions: content_length: 280 host: api.github.com body: | - {"query":"mutation($input:CreatePullRequestInput!){createPullRequest(input: $input){pullRequest{id,number,url}}}","variables":{"input":{"repositoryId":"R_kgDOMVd0xg","baseRefName":"jBRWbr4z","headRefName":"i1gtMB9v","title":"Testing i1gtMB9v","body":"Test PR with custom base"}}} + {"query":"mutation($input:CreatePullRequestInput!){createPullRequest(input: $input){pullRequest{id,number,url}}}","variables":{"input":{"repositoryId":"R_kgDORFeuHw","baseRefName":"UyUn1CLo","headRefName":"paOKBXEp","title":"Testing paOKBXEp","body":"Test PR with custom base"}}} headers: Content-Type: - application/json @@ -48,22 +48,22 @@ interactions: proto_minor: 0 content_length: -1 uncompressed: true - body: '{"data":{"createPullRequest":{"pullRequest":{"id":"PR_kwDOMVd0xs7Xrlja","number":78,"url":"https://github.com/test-owner/test-repo/pull/78"}}}}' + body: '{"data":{"createPullRequest":{"pullRequest":{"id":"PR_kwDORFeuH87AtZ_M","number":59,"url":"https://github.com/test-owner/test-repo/pull/59"}}}}' headers: Content-Type: - application/json; charset=utf-8 status: 200 OK code: 200 - duration: 855.685916ms + duration: 875.4475ms - id: 2 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 - content_length: 426 + content_length: 396 host: api.github.com body: | - {"query":"query($number:Int!$owner:String!$repo:String!){repository(owner: $owner, name: $repo){pullRequest(number: $number){id,number,url,title,state,headRefOid,baseRefName,isDraft,headRepository{owner{login},name},labels(first: 100){nodes{name}},reviewRequests(first: 100){nodes{requestedReviewer{... on Actor{login}}}},assignees(first: 100){nodes{login}}}}}","variables":{"number":78,"owner":"test-owner","repo":"test-repo"}} + {"query":"query($number:Int!$owner:String!$repo:String!){repository(owner: $owner, name: $repo){pullRequest(number: $number){id,number,url,title,body,state,headRefOid,baseRefName,isDraft,labels(first: 100){nodes{name}},reviewRequests(first: 100){nodes{requestedReviewer{... on Actor{login}}}},assignees(first: 100){nodes{login}}}}}","variables":{"number":59,"owner":"test-owner","repo":"test-repo"}} headers: Content-Type: - application/json @@ -75,13 +75,13 @@ interactions: proto_minor: 0 content_length: -1 uncompressed: true - body: '{"data":{"repository":{"pullRequest":{"id":"PR_kwDOMVd0xs7Xrlja","number":78,"url":"https://github.com/test-owner/test-repo/pull/78","title":"Testing i1gtMB9v","state":"OPEN","headRefOid":"057795c4d1a7f448f0dd94d2af597ea07b1c1ee1","baseRefName":"jBRWbr4z","isDraft":false,"headRepository":{"owner":{"login":"test-owner"},"name":"test-repo"},"labels":{"nodes":[]},"reviewRequests":{"nodes":[]},"assignees":{"nodes":[]}}}}}' + body: '{"data":{"repository":{"pullRequest":{"id":"PR_kwDORFeuH87AtZ_M","number":59,"url":"https://github.com/test-owner/test-repo/pull/59","title":"Testing paOKBXEp","state":"OPEN","headRefOid":"0d7ce867d4bf85f6e0940d6d1fa7a3a5a8e53b97","baseRefName":"UyUn1CLo","isDraft":false,"labels":{"nodes":[]},"reviewRequests":{"nodes":[]},"assignees":{"nodes":[]}}}}}' headers: Content-Type: - application/json; charset=utf-8 status: 200 OK code: 200 - duration: 406.354583ms + duration: 171.370542ms - id: 3 request: proto: HTTP/1.1 @@ -90,7 +90,7 @@ interactions: content_length: 188 host: api.github.com body: | - {"query":"mutation($input:UpdatePullRequestInput!){updatePullRequest(input: $input){clientMutationId}}","variables":{"input":{"pullRequestId":"PR_kwDOMVd0xs7Xrlja","baseRefName":"main"}}} + {"query":"mutation($input:UpdatePullRequestInput!){updatePullRequest(input: $input){clientMutationId}}","variables":{"input":{"pullRequestId":"PR_kwDORFeuH87AtZ_M","baseRefName":"main"}}} headers: Content-Type: - application/json @@ -108,16 +108,16 @@ interactions: - application/json; charset=utf-8 status: 200 OK code: 200 - duration: 959.44825ms + duration: 656.527625ms - id: 4 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 - content_length: 426 + content_length: 396 host: api.github.com body: | - {"query":"query($number:Int!$owner:String!$repo:String!){repository(owner: $owner, name: $repo){pullRequest(number: $number){id,number,url,title,state,headRefOid,baseRefName,isDraft,headRepository{owner{login},name},labels(first: 100){nodes{name}},reviewRequests(first: 100){nodes{requestedReviewer{... on Actor{login}}}},assignees(first: 100){nodes{login}}}}}","variables":{"number":78,"owner":"test-owner","repo":"test-repo"}} + {"query":"query($number:Int!$owner:String!$repo:String!){repository(owner: $owner, name: $repo){pullRequest(number: $number){id,number,url,title,body,state,headRefOid,baseRefName,isDraft,labels(first: 100){nodes{name}},reviewRequests(first: 100){nodes{requestedReviewer{... on Actor{login}}}},assignees(first: 100){nodes{login}}}}}","variables":{"number":59,"owner":"test-owner","repo":"test-repo"}} headers: Content-Type: - application/json @@ -129,10 +129,10 @@ interactions: proto_minor: 0 content_length: -1 uncompressed: true - body: '{"data":{"repository":{"pullRequest":{"id":"PR_kwDOMVd0xs7Xrlja","number":78,"url":"https://github.com/test-owner/test-repo/pull/78","title":"Testing i1gtMB9v","state":"OPEN","headRefOid":"057795c4d1a7f448f0dd94d2af597ea07b1c1ee1","baseRefName":"main","isDraft":false,"headRepository":{"owner":{"login":"test-owner"},"name":"test-repo"},"labels":{"nodes":[]},"reviewRequests":{"nodes":[]},"assignees":{"nodes":[]}}}}}' + body: '{"data":{"repository":{"pullRequest":{"id":"PR_kwDORFeuH87AtZ_M","number":59,"url":"https://github.com/test-owner/test-repo/pull/59","title":"Testing paOKBXEp","state":"OPEN","headRefOid":"0d7ce867d4bf85f6e0940d6d1fa7a3a5a8e53b97","baseRefName":"main","isDraft":false,"labels":{"nodes":[]},"reviewRequests":{"nodes":[]},"assignees":{"nodes":[]}}}}}' headers: Content-Type: - application/json; charset=utf-8 status: 200 OK code: 200 - duration: 251.703375ms + duration: 187.781042ms diff --git a/internal/forge/github/testdata/fixtures/TestIntegration/SubmitEditChange.yaml b/internal/forge/github/testdata/fixtures/TestIntegration/SubmitEditChange.yaml index bd90a7355..8b8c7a81b 100644 --- a/internal/forge/github/testdata/fixtures/TestIntegration/SubmitEditChange.yaml +++ b/internal/forge/github/testdata/fixtures/TestIntegration/SubmitEditChange.yaml @@ -6,7 +6,7 @@ interactions: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 - content_length: 142 + content_length: 146 host: api.github.com body: | {"query":"query($owner:String!$repo:String!){repository(owner: $owner, name: $repo){id}}","variables":{"owner":"test-owner","repo":"test-repo"}} @@ -21,13 +21,13 @@ interactions: proto_minor: 0 content_length: -1 uncompressed: true - body: '{"data":{"repository":{"id":"R_kgDOMVd0xg"}}}' + body: '{"data":{"repository":{"id":"R_kgDORFeuHw"}}}' headers: Content-Type: - application/json; charset=utf-8 status: 200 OK code: 200 - duration: 208.3815ms + duration: 152.204458ms - id: 1 request: proto: HTTP/1.1 @@ -36,7 +36,7 @@ interactions: content_length: 259 host: api.github.com body: | - {"query":"mutation($input:CreatePullRequestInput!){createPullRequest(input: $input){pullRequest{id,number,url}}}","variables":{"input":{"repositoryId":"R_kgDOMVd0xg","baseRefName":"main","headRefName":"FePcGHUa","title":"Testing FePcGHUa","body":"Test PR"}}} + {"query":"mutation($input:CreatePullRequestInput!){createPullRequest(input: $input){pullRequest{id,number,url}}}","variables":{"input":{"repositoryId":"R_kgDORFeuHw","baseRefName":"main","headRefName":"jXp7YszV","title":"Testing jXp7YszV","body":"Test PR"}}} headers: Content-Type: - application/json @@ -48,22 +48,22 @@ interactions: proto_minor: 0 content_length: -1 uncompressed: true - body: '{"data":{"createPullRequest":{"pullRequest":{"id":"PR_kwDOMVd0xs7XrljW","number":77,"url":"https://github.com/test-owner/test-repo/pull/77"}}}}' + body: '{"data":{"createPullRequest":{"pullRequest":{"id":"PR_kwDORFeuH87AtZ9f","number":55,"url":"https://github.com/test-owner/test-repo/pull/55"}}}}' headers: Content-Type: - application/json; charset=utf-8 status: 200 OK code: 200 - duration: 1.324138875s + duration: 713.143875ms - id: 2 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 - content_length: 426 + content_length: 396 host: api.github.com body: | - {"query":"query($number:Int!$owner:String!$repo:String!){repository(owner: $owner, name: $repo){pullRequest(number: $number){id,number,url,title,state,headRefOid,baseRefName,isDraft,headRepository{owner{login},name},labels(first: 100){nodes{name}},reviewRequests(first: 100){nodes{requestedReviewer{... on Actor{login}}}},assignees(first: 100){nodes{login}}}}}","variables":{"number":77,"owner":"test-owner","repo":"test-repo"}} + {"query":"query($number:Int!$owner:String!$repo:String!){repository(owner: $owner, name: $repo){pullRequest(number: $number){id,number,url,title,body,state,headRefOid,baseRefName,isDraft,labels(first: 100){nodes{name}},reviewRequests(first: 100){nodes{requestedReviewer{... on Actor{login}}}},assignees(first: 100){nodes{login}}}}}","variables":{"number":55,"owner":"test-owner","repo":"test-repo"}} headers: Content-Type: - application/json @@ -75,22 +75,22 @@ interactions: proto_minor: 0 content_length: -1 uncompressed: true - body: '{"data":{"repository":{"pullRequest":{"id":"PR_kwDOMVd0xs7XrljW","number":77,"url":"https://github.com/test-owner/test-repo/pull/77","title":"Testing FePcGHUa","state":"OPEN","headRefOid":"8cf88ce2a42d0dd3bbf8e06581320a3d4c201091","baseRefName":"main","isDraft":false,"headRepository":{"owner":{"login":"test-owner"},"name":"test-repo"},"labels":{"nodes":[]},"reviewRequests":{"nodes":[]},"assignees":{"nodes":[]}}}}}' + body: '{"data":{"repository":{"pullRequest":{"id":"PR_kwDORFeuH87AtZ9f","number":55,"url":"https://github.com/test-owner/test-repo/pull/55","title":"Testing jXp7YszV","state":"OPEN","headRefOid":"c5dfa2155324db7e323e4229013fdd41874ba188","baseRefName":"main","isDraft":false,"labels":{"nodes":[]},"reviewRequests":{"nodes":[]},"assignees":{"nodes":[]}}}}}' headers: Content-Type: - application/json; charset=utf-8 status: 200 OK code: 200 - duration: 262.59625ms + duration: 143.680417ms - id: 3 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 - content_length: 615 + content_length: 585 host: api.github.com body: | - {"query":"query($branch:String!$limit:Int!$owner:String!$repo:String!$states:[PullRequestState!]!){repository(owner: $owner, name: $repo){pullRequests(first: $limit, headRefName: $branch, states: $states, orderBy: {field: UPDATED_AT, direction: DESC}){nodes{id,number,url,title,state,headRefOid,baseRefName,isDraft,headRepository{owner{login},name},labels(first: 100){nodes{name}},reviewRequests(first: 100){nodes{requestedReviewer{... on Actor{login}}}},assignees(first: 100){nodes{login}}}}}}","variables":{"branch":"FePcGHUa","limit":10,"owner":"test-owner","repo":"test-repo","states":["OPEN","CLOSED","MERGED"]}} + {"query":"query($branch:String!$limit:Int!$owner:String!$repo:String!$states:[PullRequestState!]!){repository(owner: $owner, name: $repo){pullRequests(first: $limit, headRefName: $branch, states: $states, orderBy: {field: UPDATED_AT, direction: DESC}){nodes{id,number,url,title,body,state,headRefOid,baseRefName,isDraft,labels(first: 100){nodes{name}},reviewRequests(first: 100){nodes{requestedReviewer{... on Actor{login}}}},assignees(first: 100){nodes{login}}}}}}","variables":{"branch":"jXp7YszV","limit":10,"owner":"test-owner","repo":"test-repo","states":["OPEN","CLOSED","MERGED"]}} headers: Content-Type: - application/json @@ -102,10 +102,10 @@ interactions: proto_minor: 0 content_length: -1 uncompressed: true - body: '{"data":{"repository":{"pullRequests":{"nodes":[{"id":"PR_kwDOMVd0xs7XrljW","number":77,"url":"https://github.com/test-owner/test-repo/pull/77","title":"Testing FePcGHUa","state":"OPEN","headRefOid":"8cf88ce2a42d0dd3bbf8e06581320a3d4c201091","baseRefName":"main","isDraft":false,"headRepository":{"owner":{"login":"test-owner"},"name":"test-repo"},"labels":{"nodes":[]},"reviewRequests":{"nodes":[]},"assignees":{"nodes":[]}}]}}}}' + body: '{"data":{"repository":{"pullRequests":{"nodes":[{"id":"PR_kwDORFeuH87AtZ9f","number":55,"url":"https://github.com/test-owner/test-repo/pull/55","title":"Testing jXp7YszV","state":"OPEN","headRefOid":"c5dfa2155324db7e323e4229013fdd41874ba188","baseRefName":"main","isDraft":false,"labels":{"nodes":[]},"reviewRequests":{"nodes":[]},"assignees":{"nodes":[]}}]}}}}' headers: Content-Type: - application/json; charset=utf-8 status: 200 OK code: 200 - duration: 254.60025ms + duration: 206.002208ms diff --git a/internal/forge/github/testdata/fixtures/TestIntegration/SubmitEditDraft.yaml b/internal/forge/github/testdata/fixtures/TestIntegration/SubmitEditDraft.yaml index 0ebeae56f..05c28d853 100644 --- a/internal/forge/github/testdata/fixtures/TestIntegration/SubmitEditDraft.yaml +++ b/internal/forge/github/testdata/fixtures/TestIntegration/SubmitEditDraft.yaml @@ -6,7 +6,7 @@ interactions: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 - content_length: 142 + content_length: 146 host: api.github.com body: | {"query":"query($owner:String!$repo:String!){repository(owner: $owner, name: $repo){id}}","variables":{"owner":"test-owner","repo":"test-repo"}} @@ -21,13 +21,13 @@ interactions: proto_minor: 0 content_length: -1 uncompressed: true - body: '{"data":{"repository":{"id":"R_kgDOMVd0xg"}}}' + body: '{"data":{"repository":{"id":"R_kgDORFeuHw"}}}' headers: Content-Type: - application/json; charset=utf-8 status: 200 OK code: 200 - duration: 191.557542ms + duration: 234.658458ms - id: 1 request: proto: HTTP/1.1 @@ -36,7 +36,7 @@ interactions: content_length: 278 host: api.github.com body: | - {"query":"mutation($input:CreatePullRequestInput!){createPullRequest(input: $input){pullRequest{id,number,url}}}","variables":{"input":{"repositoryId":"R_kgDOMVd0xg","baseRefName":"main","headRefName":"iFvgAV6I","title":"Testing iFvgAV6I","body":"Test draft PR","draft":true}}} + {"query":"mutation($input:CreatePullRequestInput!){createPullRequest(input: $input){pullRequest{id,number,url}}}","variables":{"input":{"repositoryId":"R_kgDORFeuHw","baseRefName":"main","headRefName":"23TQcaj4","title":"Testing 23TQcaj4","body":"Test draft PR","draft":true}}} headers: Content-Type: - application/json @@ -48,22 +48,22 @@ interactions: proto_minor: 0 content_length: -1 uncompressed: true - body: '{"data":{"createPullRequest":{"pullRequest":{"id":"PR_kwDOMVd0xs7Xrli4","number":71,"url":"https://github.com/test-owner/test-repo/pull/71"}}}}' + body: '{"data":{"createPullRequest":{"pullRequest":{"id":"PR_kwDORFeuH87AtZ9j","number":57,"url":"https://github.com/test-owner/test-repo/pull/57"}}}}' headers: Content-Type: - application/json; charset=utf-8 status: 200 OK code: 200 - duration: 759.359084ms + duration: 741.811708ms - id: 2 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 - content_length: 426 + content_length: 396 host: api.github.com body: | - {"query":"query($number:Int!$owner:String!$repo:String!){repository(owner: $owner, name: $repo){pullRequest(number: $number){id,number,url,title,state,headRefOid,baseRefName,isDraft,headRepository{owner{login},name},labels(first: 100){nodes{name}},reviewRequests(first: 100){nodes{requestedReviewer{... on Actor{login}}}},assignees(first: 100){nodes{login}}}}}","variables":{"number":71,"owner":"test-owner","repo":"test-repo"}} + {"query":"query($number:Int!$owner:String!$repo:String!){repository(owner: $owner, name: $repo){pullRequest(number: $number){id,number,url,title,body,state,headRefOid,baseRefName,isDraft,labels(first: 100){nodes{name}},reviewRequests(first: 100){nodes{requestedReviewer{... on Actor{login}}}},assignees(first: 100){nodes{login}}}}}","variables":{"number":57,"owner":"test-owner","repo":"test-repo"}} headers: Content-Type: - application/json @@ -75,13 +75,13 @@ interactions: proto_minor: 0 content_length: -1 uncompressed: true - body: '{"data":{"repository":{"pullRequest":{"id":"PR_kwDOMVd0xs7Xrli4","number":71,"url":"https://github.com/test-owner/test-repo/pull/71","title":"Testing iFvgAV6I","state":"OPEN","headRefOid":"ea1d5ad0021e1c5408d2c2b335a701b165772fbb","baseRefName":"main","isDraft":true,"headRepository":{"owner":{"login":"test-owner"},"name":"test-repo"},"labels":{"nodes":[]},"reviewRequests":{"nodes":[]},"assignees":{"nodes":[]}}}}}' + body: '{"data":{"repository":{"pullRequest":{"id":"PR_kwDORFeuH87AtZ9j","number":57,"url":"https://github.com/test-owner/test-repo/pull/57","title":"Testing 23TQcaj4","state":"OPEN","headRefOid":"c521b0ae750caa58a742363d6eec74206389e95c","baseRefName":"main","isDraft":true,"labels":{"nodes":[]},"reviewRequests":{"nodes":[]},"assignees":{"nodes":[]}}}}}' headers: Content-Type: - application/json; charset=utf-8 status: 200 OK code: 200 - duration: 271.839459ms + duration: 170.140292ms - id: 3 request: proto: HTTP/1.1 @@ -90,7 +90,7 @@ interactions: content_length: 190 host: api.github.com body: | - {"query":"mutation($input:MarkPullRequestReadyForReviewInput!){markPullRequestReadyForReview(input: $input){pullRequest{id}}}","variables":{"input":{"pullRequestId":"PR_kwDOMVd0xs7Xrli4"}}} + {"query":"mutation($input:MarkPullRequestReadyForReviewInput!){markPullRequestReadyForReview(input: $input){pullRequest{id}}}","variables":{"input":{"pullRequestId":"PR_kwDORFeuH87AtZ9j"}}} headers: Content-Type: - application/json @@ -102,22 +102,22 @@ interactions: proto_minor: 0 content_length: -1 uncompressed: true - body: '{"data":{"markPullRequestReadyForReview":{"pullRequest":{"id":"PR_kwDOMVd0xs7Xrli4"}}}}' + body: '{"data":{"markPullRequestReadyForReview":{"pullRequest":{"id":"PR_kwDORFeuH87AtZ9j"}}}}' headers: Content-Type: - application/json; charset=utf-8 status: 200 OK code: 200 - duration: 481.697542ms + duration: 347.041375ms - id: 4 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 - content_length: 426 + content_length: 396 host: api.github.com body: | - {"query":"query($number:Int!$owner:String!$repo:String!){repository(owner: $owner, name: $repo){pullRequest(number: $number){id,number,url,title,state,headRefOid,baseRefName,isDraft,headRepository{owner{login},name},labels(first: 100){nodes{name}},reviewRequests(first: 100){nodes{requestedReviewer{... on Actor{login}}}},assignees(first: 100){nodes{login}}}}}","variables":{"number":71,"owner":"test-owner","repo":"test-repo"}} + {"query":"query($number:Int!$owner:String!$repo:String!){repository(owner: $owner, name: $repo){pullRequest(number: $number){id,number,url,title,body,state,headRefOid,baseRefName,isDraft,labels(first: 100){nodes{name}},reviewRequests(first: 100){nodes{requestedReviewer{... on Actor{login}}}},assignees(first: 100){nodes{login}}}}}","variables":{"number":57,"owner":"test-owner","repo":"test-repo"}} headers: Content-Type: - application/json @@ -129,13 +129,13 @@ interactions: proto_minor: 0 content_length: -1 uncompressed: true - body: '{"data":{"repository":{"pullRequest":{"id":"PR_kwDOMVd0xs7Xrli4","number":71,"url":"https://github.com/test-owner/test-repo/pull/71","title":"Testing iFvgAV6I","state":"OPEN","headRefOid":"ea1d5ad0021e1c5408d2c2b335a701b165772fbb","baseRefName":"main","isDraft":false,"headRepository":{"owner":{"login":"test-owner"},"name":"test-repo"},"labels":{"nodes":[]},"reviewRequests":{"nodes":[]},"assignees":{"nodes":[]}}}}}' + body: '{"data":{"repository":{"pullRequest":{"id":"PR_kwDORFeuH87AtZ9j","number":57,"url":"https://github.com/test-owner/test-repo/pull/57","title":"Testing 23TQcaj4","state":"OPEN","headRefOid":"c521b0ae750caa58a742363d6eec74206389e95c","baseRefName":"main","isDraft":false,"labels":{"nodes":[]},"reviewRequests":{"nodes":[]},"assignees":{"nodes":[]}}}}}' headers: Content-Type: - application/json; charset=utf-8 status: 200 OK code: 200 - duration: 777.6185ms + duration: 164.431208ms - id: 5 request: proto: HTTP/1.1 @@ -144,7 +144,7 @@ interactions: content_length: 182 host: api.github.com body: | - {"query":"mutation($input:ConvertPullRequestToDraftInput!){convertPullRequestToDraft(input: $input){pullRequest{id}}}","variables":{"input":{"pullRequestId":"PR_kwDOMVd0xs7Xrli4"}}} + {"query":"mutation($input:ConvertPullRequestToDraftInput!){convertPullRequestToDraft(input: $input){pullRequest{id}}}","variables":{"input":{"pullRequestId":"PR_kwDORFeuH87AtZ9j"}}} headers: Content-Type: - application/json @@ -156,22 +156,22 @@ interactions: proto_minor: 0 content_length: -1 uncompressed: true - body: '{"data":{"convertPullRequestToDraft":{"pullRequest":{"id":"PR_kwDOMVd0xs7Xrli4"}}}}' + body: '{"data":{"convertPullRequestToDraft":{"pullRequest":{"id":"PR_kwDORFeuH87AtZ9j"}}}}' headers: Content-Type: - application/json; charset=utf-8 status: 200 OK code: 200 - duration: 612.187917ms + duration: 630.821459ms - id: 6 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 - content_length: 426 + content_length: 396 host: api.github.com body: | - {"query":"query($number:Int!$owner:String!$repo:String!){repository(owner: $owner, name: $repo){pullRequest(number: $number){id,number,url,title,state,headRefOid,baseRefName,isDraft,headRepository{owner{login},name},labels(first: 100){nodes{name}},reviewRequests(first: 100){nodes{requestedReviewer{... on Actor{login}}}},assignees(first: 100){nodes{login}}}}}","variables":{"number":71,"owner":"test-owner","repo":"test-repo"}} + {"query":"query($number:Int!$owner:String!$repo:String!){repository(owner: $owner, name: $repo){pullRequest(number: $number){id,number,url,title,body,state,headRefOid,baseRefName,isDraft,labels(first: 100){nodes{name}},reviewRequests(first: 100){nodes{requestedReviewer{... on Actor{login}}}},assignees(first: 100){nodes{login}}}}}","variables":{"number":57,"owner":"test-owner","repo":"test-repo"}} headers: Content-Type: - application/json @@ -183,10 +183,10 @@ interactions: proto_minor: 0 content_length: -1 uncompressed: true - body: '{"data":{"repository":{"pullRequest":{"id":"PR_kwDOMVd0xs7Xrli4","number":71,"url":"https://github.com/test-owner/test-repo/pull/71","title":"Testing iFvgAV6I","state":"OPEN","headRefOid":"ea1d5ad0021e1c5408d2c2b335a701b165772fbb","baseRefName":"main","isDraft":true,"headRepository":{"owner":{"login":"test-owner"},"name":"test-repo"},"labels":{"nodes":[]},"reviewRequests":{"nodes":[]},"assignees":{"nodes":[]}}}}}' + body: '{"data":{"repository":{"pullRequest":{"id":"PR_kwDORFeuH87AtZ9j","number":57,"url":"https://github.com/test-owner/test-repo/pull/57","title":"Testing 23TQcaj4","state":"OPEN","headRefOid":"c521b0ae750caa58a742363d6eec74206389e95c","baseRefName":"main","isDraft":true,"labels":{"nodes":[]},"reviewRequests":{"nodes":[]},"assignees":{"nodes":[]}}}}}' headers: Content-Type: - application/json; charset=utf-8 status: 200 OK code: 200 - duration: 321.245208ms + duration: 449.4475ms diff --git a/internal/forge/github/testdata/fixtures/TestIntegration/SubmitEditLabels.yaml b/internal/forge/github/testdata/fixtures/TestIntegration/SubmitEditLabels.yaml index 051ac23ef..b6f1d8570 100644 --- a/internal/forge/github/testdata/fixtures/TestIntegration/SubmitEditLabels.yaml +++ b/internal/forge/github/testdata/fixtures/TestIntegration/SubmitEditLabels.yaml @@ -6,7 +6,7 @@ interactions: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 - content_length: 142 + content_length: 146 host: api.github.com body: | {"query":"query($owner:String!$repo:String!){repository(owner: $owner, name: $repo){id}}","variables":{"owner":"test-owner","repo":"test-repo"}} @@ -21,13 +21,13 @@ interactions: proto_minor: 0 content_length: -1 uncompressed: true - body: '{"data":{"repository":{"id":"R_kgDOMVd0xg"}}}' + body: '{"data":{"repository":{"id":"R_kgDORFeuHw"}}}' headers: Content-Type: - application/json; charset=utf-8 status: 200 OK code: 200 - duration: 268.693708ms + duration: 148.711667ms - id: 1 request: proto: HTTP/1.1 @@ -36,7 +36,7 @@ interactions: content_length: 271 host: api.github.com body: | - {"query":"mutation($input:CreatePullRequestInput!){createPullRequest(input: $input){pullRequest{id,number,url}}}","variables":{"input":{"repositoryId":"R_kgDOMVd0xg","baseRefName":"main","headRefName":"Jq9JrN2F","title":"Testing Jq9JrN2F","body":"Test PR with labels"}}} + {"query":"mutation($input:CreatePullRequestInput!){createPullRequest(input: $input){pullRequest{id,number,url}}}","variables":{"input":{"repositoryId":"R_kgDORFeuHw","baseRefName":"main","headRefName":"1GFWEtGx","title":"Testing 1GFWEtGx","body":"Test PR with labels"}}} headers: Content-Type: - application/json @@ -48,22 +48,22 @@ interactions: proto_minor: 0 content_length: -1 uncompressed: true - body: '{"data":{"createPullRequest":{"pullRequest":{"id":"PR_kwDOMVd0xs7XrljC","number":74,"url":"https://github.com/test-owner/test-repo/pull/74"}}}}' + body: '{"data":{"createPullRequest":{"pullRequest":{"id":"PR_kwDORFeuH87AtZ9e","number":54,"url":"https://github.com/test-owner/test-repo/pull/54"}}}}' headers: Content-Type: - application/json; charset=utf-8 status: 200 OK code: 200 - duration: 870.605708ms + duration: 916.090875ms - id: 2 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 - content_length: 196 + content_length: 200 host: api.github.com body: | - {"query":"query($label:String!$name:String!$owner:String!){repository(owner: $owner, name: $name){label(name: $label){id}}}","variables":{"label":"PRjo2q19","name":"test-repo","owner":"test-owner"}} + {"query":"query($label:String!$name:String!$owner:String!){repository(owner: $owner, name: $name){label(name: $label){id}}}","variables":{"label":"Yo9Vqnff","name":"test-repo","owner":"test-owner"}} headers: Content-Type: - application/json @@ -81,7 +81,7 @@ interactions: - application/json; charset=utf-8 status: 200 OK code: 200 - duration: 224.532917ms + duration: 262.529458ms - id: 3 request: proto: HTTP/1.1 @@ -90,7 +90,7 @@ interactions: content_length: 175 host: api.github.com body: | - {"query":"mutation($input:CreateLabelInput!){createLabel(input: $input){label{id}}}","variables":{"input":{"repositoryId":"R_kgDOMVd0xg","color":"EDEDED","name":"PRjo2q19"}}} + {"query":"mutation($input:CreateLabelInput!){createLabel(input: $input){label{id}}}","variables":{"input":{"repositoryId":"R_kgDORFeuHw","color":"EDEDED","name":"Yo9Vqnff"}}} headers: Content-Type: - application/json @@ -102,13 +102,13 @@ interactions: proto_minor: 0 content_length: -1 uncompressed: true - body: '{"data":{"createLabel":{"label":{"id":"LA_kwDOMVd0xs8AAAAChpLQ6w"}}}}' + body: '{"data":{"createLabel":{"label":{"id":"LA_kwDORFeuH88AAAACWqjKIA"}}}}' headers: Content-Type: - application/json; charset=utf-8 status: 200 OK code: 200 - duration: 335.693667ms + duration: 254.669209ms - id: 4 request: proto: HTTP/1.1 @@ -117,7 +117,7 @@ interactions: content_length: 212 host: api.github.com body: | - {"query":"mutation($input:AddLabelsToLabelableInput!){addLabelsToLabelable(input: $input){clientMutationId}}","variables":{"input":{"labelableId":"PR_kwDOMVd0xs7XrljC","labelIds":["LA_kwDOMVd0xs8AAAAChpLQ6w"]}}} + {"query":"mutation($input:AddLabelsToLabelableInput!){addLabelsToLabelable(input: $input){clientMutationId}}","variables":{"input":{"labelableId":"PR_kwDORFeuH87AtZ9e","labelIds":["LA_kwDORFeuH88AAAACWqjKIA"]}}} headers: Content-Type: - application/json @@ -135,16 +135,16 @@ interactions: - application/json; charset=utf-8 status: 200 OK code: 200 - duration: 771.573833ms + duration: 826.950292ms - id: 5 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 - content_length: 426 + content_length: 396 host: api.github.com body: | - {"query":"query($number:Int!$owner:String!$repo:String!){repository(owner: $owner, name: $repo){pullRequest(number: $number){id,number,url,title,state,headRefOid,baseRefName,isDraft,headRepository{owner{login},name},labels(first: 100){nodes{name}},reviewRequests(first: 100){nodes{requestedReviewer{... on Actor{login}}}},assignees(first: 100){nodes{login}}}}}","variables":{"number":74,"owner":"test-owner","repo":"test-repo"}} + {"query":"query($number:Int!$owner:String!$repo:String!){repository(owner: $owner, name: $repo){pullRequest(number: $number){id,number,url,title,body,state,headRefOid,baseRefName,isDraft,labels(first: 100){nodes{name}},reviewRequests(first: 100){nodes{requestedReviewer{... on Actor{login}}}},assignees(first: 100){nodes{login}}}}}","variables":{"number":54,"owner":"test-owner","repo":"test-repo"}} headers: Content-Type: - application/json @@ -156,22 +156,22 @@ interactions: proto_minor: 0 content_length: -1 uncompressed: true - body: '{"data":{"repository":{"pullRequest":{"id":"PR_kwDOMVd0xs7XrljC","number":74,"url":"https://github.com/test-owner/test-repo/pull/74","title":"Testing Jq9JrN2F","state":"OPEN","headRefOid":"9f8868111ceef2ecfb1400569938d5a292899bbb","baseRefName":"main","isDraft":false,"headRepository":{"owner":{"login":"test-owner"},"name":"test-repo"},"labels":{"nodes":[{"name":"PRjo2q19"}]},"reviewRequests":{"nodes":[]},"assignees":{"nodes":[]}}}}}' + body: '{"data":{"repository":{"pullRequest":{"id":"PR_kwDORFeuH87AtZ9e","number":54,"url":"https://github.com/test-owner/test-repo/pull/54","title":"Testing 1GFWEtGx","state":"OPEN","headRefOid":"dbeff1bf3160c6df6d312b6e0bd1c8460a7d19d2","baseRefName":"main","isDraft":false,"labels":{"nodes":[{"name":"Yo9Vqnff"}]},"reviewRequests":{"nodes":[]},"assignees":{"nodes":[]}}}}}' headers: Content-Type: - application/json; charset=utf-8 status: 200 OK code: 200 - duration: 258.373834ms + duration: 332.464084ms - id: 6 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 - content_length: 196 + content_length: 200 host: api.github.com body: | - {"query":"query($label:String!$name:String!$owner:String!){repository(owner: $owner, name: $name){label(name: $label){id}}}","variables":{"label":"szXgPUIa","name":"test-repo","owner":"test-owner"}} + {"query":"query($label:String!$name:String!$owner:String!){repository(owner: $owner, name: $name){label(name: $label){id}}}","variables":{"label":"SKgSpfhn","name":"test-repo","owner":"test-owner"}} headers: Content-Type: - application/json @@ -189,7 +189,7 @@ interactions: - application/json; charset=utf-8 status: 200 OK code: 200 - duration: 215.25925ms + duration: 158.646541ms - id: 7 request: proto: HTTP/1.1 @@ -198,7 +198,7 @@ interactions: content_length: 175 host: api.github.com body: | - {"query":"mutation($input:CreateLabelInput!){createLabel(input: $input){label{id}}}","variables":{"input":{"repositoryId":"R_kgDOMVd0xg","color":"EDEDED","name":"szXgPUIa"}}} + {"query":"mutation($input:CreateLabelInput!){createLabel(input: $input){label{id}}}","variables":{"input":{"repositoryId":"R_kgDORFeuHw","color":"EDEDED","name":"SKgSpfhn"}}} headers: Content-Type: - application/json @@ -210,13 +210,13 @@ interactions: proto_minor: 0 content_length: -1 uncompressed: true - body: '{"data":{"createLabel":{"label":{"id":"LA_kwDOMVd0xs8AAAAChpLRmw"}}}}' + body: '{"data":{"createLabel":{"label":{"id":"LA_kwDORFeuH88AAAACWqjKtw"}}}}' headers: Content-Type: - application/json; charset=utf-8 status: 200 OK code: 200 - duration: 320.791292ms + duration: 523.40475ms - id: 8 request: proto: HTTP/1.1 @@ -225,7 +225,7 @@ interactions: content_length: 212 host: api.github.com body: | - {"query":"mutation($input:AddLabelsToLabelableInput!){addLabelsToLabelable(input: $input){clientMutationId}}","variables":{"input":{"labelableId":"PR_kwDOMVd0xs7XrljC","labelIds":["LA_kwDOMVd0xs8AAAAChpLRmw"]}}} + {"query":"mutation($input:AddLabelsToLabelableInput!){addLabelsToLabelable(input: $input){clientMutationId}}","variables":{"input":{"labelableId":"PR_kwDORFeuH87AtZ9e","labelIds":["LA_kwDORFeuH88AAAACWqjKtw"]}}} headers: Content-Type: - application/json @@ -243,16 +243,16 @@ interactions: - application/json; charset=utf-8 status: 200 OK code: 200 - duration: 592.234917ms + duration: 523.760459ms - id: 9 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 - content_length: 196 + content_length: 200 host: api.github.com body: | - {"query":"query($label:String!$name:String!$owner:String!){repository(owner: $owner, name: $name){label(name: $label){id}}}","variables":{"label":"Itfxhjgu","name":"test-repo","owner":"test-owner"}} + {"query":"query($label:String!$name:String!$owner:String!){repository(owner: $owner, name: $name){label(name: $label){id}}}","variables":{"label":"SKgSpfhn","name":"test-repo","owner":"test-owner"}} headers: Content-Type: - application/json @@ -264,22 +264,22 @@ interactions: proto_minor: 0 content_length: -1 uncompressed: true - body: '{"data":{"repository":{"label":null}}}' + body: '{"data":{"repository":{"label":{"id":"LA_kwDORFeuH88AAAACWqjKtw"}}}}' headers: Content-Type: - application/json; charset=utf-8 status: 200 OK code: 200 - duration: 205.747166ms + duration: 156.944625ms - id: 10 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 - content_length: 196 + content_length: 200 host: api.github.com body: | - {"query":"query($label:String!$name:String!$owner:String!){repository(owner: $owner, name: $name){label(name: $label){id}}}","variables":{"label":"szXgPUIa","name":"test-repo","owner":"test-owner"}} + {"query":"query($label:String!$name:String!$owner:String!){repository(owner: $owner, name: $name){label(name: $label){id}}}","variables":{"label":"NcF468dW","name":"test-repo","owner":"test-owner"}} headers: Content-Type: - application/json @@ -291,13 +291,13 @@ interactions: proto_minor: 0 content_length: -1 uncompressed: true - body: '{"data":{"repository":{"label":{"id":"LA_kwDOMVd0xs8AAAAChpLRmw"}}}}' + body: '{"data":{"repository":{"label":null}}}' headers: Content-Type: - application/json; charset=utf-8 status: 200 OK code: 200 - duration: 243.461125ms + duration: 526.084625ms - id: 11 request: proto: HTTP/1.1 @@ -306,7 +306,7 @@ interactions: content_length: 175 host: api.github.com body: | - {"query":"mutation($input:CreateLabelInput!){createLabel(input: $input){label{id}}}","variables":{"input":{"repositoryId":"R_kgDOMVd0xg","color":"EDEDED","name":"Itfxhjgu"}}} + {"query":"mutation($input:CreateLabelInput!){createLabel(input: $input){label{id}}}","variables":{"input":{"repositoryId":"R_kgDORFeuHw","color":"EDEDED","name":"NcF468dW"}}} headers: Content-Type: - application/json @@ -318,13 +318,13 @@ interactions: proto_minor: 0 content_length: -1 uncompressed: true - body: '{"data":{"createLabel":{"label":{"id":"LA_kwDOMVd0xs8AAAAChpLR5A"}}}}' + body: '{"data":{"createLabel":{"label":{"id":"LA_kwDORFeuH88AAAACWqjK8w"}}}}' headers: Content-Type: - application/json; charset=utf-8 status: 200 OK code: 200 - duration: 458.752208ms + duration: 225.37725ms - id: 12 request: proto: HTTP/1.1 @@ -333,7 +333,7 @@ interactions: content_length: 240 host: api.github.com body: | - {"query":"mutation($input:AddLabelsToLabelableInput!){addLabelsToLabelable(input: $input){clientMutationId}}","variables":{"input":{"labelableId":"PR_kwDOMVd0xs7XrljC","labelIds":["LA_kwDOMVd0xs8AAAAChpLRmw","LA_kwDOMVd0xs8AAAAChpLR5A"]}}} + {"query":"mutation($input:AddLabelsToLabelableInput!){addLabelsToLabelable(input: $input){clientMutationId}}","variables":{"input":{"labelableId":"PR_kwDORFeuH87AtZ9e","labelIds":["LA_kwDORFeuH88AAAACWqjKtw","LA_kwDORFeuH88AAAACWqjK8w"]}}} headers: Content-Type: - application/json @@ -351,16 +351,16 @@ interactions: - application/json; charset=utf-8 status: 200 OK code: 200 - duration: 748.621667ms + duration: 366.824917ms - id: 13 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 - content_length: 615 + content_length: 585 host: api.github.com body: | - {"query":"query($branch:String!$limit:Int!$owner:String!$repo:String!$states:[PullRequestState!]!){repository(owner: $owner, name: $repo){pullRequests(first: $limit, headRefName: $branch, states: $states, orderBy: {field: UPDATED_AT, direction: DESC}){nodes{id,number,url,title,state,headRefOid,baseRefName,isDraft,headRepository{owner{login},name},labels(first: 100){nodes{name}},reviewRequests(first: 100){nodes{requestedReviewer{... on Actor{login}}}},assignees(first: 100){nodes{login}}}}}}","variables":{"branch":"Jq9JrN2F","limit":10,"owner":"test-owner","repo":"test-repo","states":["OPEN","CLOSED","MERGED"]}} + {"query":"query($branch:String!$limit:Int!$owner:String!$repo:String!$states:[PullRequestState!]!){repository(owner: $owner, name: $repo){pullRequests(first: $limit, headRefName: $branch, states: $states, orderBy: {field: UPDATED_AT, direction: DESC}){nodes{id,number,url,title,body,state,headRefOid,baseRefName,isDraft,labels(first: 100){nodes{name}},reviewRequests(first: 100){nodes{requestedReviewer{... on Actor{login}}}},assignees(first: 100){nodes{login}}}}}}","variables":{"branch":"1GFWEtGx","limit":10,"owner":"test-owner","repo":"test-repo","states":["OPEN","CLOSED","MERGED"]}} headers: Content-Type: - application/json @@ -372,10 +372,10 @@ interactions: proto_minor: 0 content_length: -1 uncompressed: true - body: '{"data":{"repository":{"pullRequests":{"nodes":[{"id":"PR_kwDOMVd0xs7XrljC","number":74,"url":"https://github.com/test-owner/test-repo/pull/74","title":"Testing Jq9JrN2F","state":"OPEN","headRefOid":"9f8868111ceef2ecfb1400569938d5a292899bbb","baseRefName":"main","isDraft":false,"headRepository":{"owner":{"login":"test-owner"},"name":"test-repo"},"labels":{"nodes":[{"name":"PRjo2q19"},{"name":"szXgPUIa"},{"name":"Itfxhjgu"}]},"reviewRequests":{"nodes":[]},"assignees":{"nodes":[]}}]}}}}' + body: '{"data":{"repository":{"pullRequests":{"nodes":[{"id":"PR_kwDORFeuH87AtZ9e","number":54,"url":"https://github.com/test-owner/test-repo/pull/54","title":"Testing 1GFWEtGx","state":"OPEN","headRefOid":"dbeff1bf3160c6df6d312b6e0bd1c8460a7d19d2","baseRefName":"main","isDraft":false,"labels":{"nodes":[{"name":"Yo9Vqnff"},{"name":"SKgSpfhn"},{"name":"NcF468dW"}]},"reviewRequests":{"nodes":[]},"assignees":{"nodes":[]}}]}}}}' headers: Content-Type: - application/json; charset=utf-8 status: 200 OK code: 200 - duration: 307.757916ms + duration: 210.788708ms diff --git a/internal/forge/github/testdata/fixtures/TestIntegration/SubmitEditReviewers/AddReviewer.yaml b/internal/forge/github/testdata/fixtures/TestIntegration/SubmitEditReviewers/AddReviewer.yaml index 575e74669..c488dc5aa 100644 --- a/internal/forge/github/testdata/fixtures/TestIntegration/SubmitEditReviewers/AddReviewer.yaml +++ b/internal/forge/github/testdata/fixtures/TestIntegration/SubmitEditReviewers/AddReviewer.yaml @@ -6,7 +6,7 @@ interactions: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 - content_length: 142 + content_length: 146 host: api.github.com body: | {"query":"query($owner:String!$repo:String!){repository(owner: $owner, name: $repo){id}}","variables":{"owner":"test-owner","repo":"test-repo"}} @@ -21,13 +21,13 @@ interactions: proto_minor: 0 content_length: -1 uncompressed: true - body: '{"data":{"repository":{"id":"R_kgDOMVd0xg"}}}' + body: '{"data":{"repository":{"id":"R_kgDORFeuHw"}}}' headers: Content-Type: - application/json; charset=utf-8 status: 200 OK code: 200 - duration: 234.461333ms + duration: 107.698583ms - id: 1 request: proto: HTTP/1.1 @@ -36,7 +36,7 @@ interactions: content_length: 277 host: api.github.com body: | - {"query":"mutation($input:CreatePullRequestInput!){createPullRequest(input: $input){pullRequest{id,number,url}}}","variables":{"input":{"repositoryId":"R_kgDOMVd0xg","baseRefName":"main","headRefName":"f4fqEb9C","title":"Testing f4fqEb9C","body":"Test PR without reviewers"}}} + {"query":"mutation($input:CreatePullRequestInput!){createPullRequest(input: $input){pullRequest{id,number,url}}}","variables":{"input":{"repositoryId":"R_kgDORFeuHw","baseRefName":"main","headRefName":"0W9K9lnj","title":"Testing 0W9K9lnj","body":"Test PR without reviewers"}}} headers: Content-Type: - application/json @@ -48,22 +48,22 @@ interactions: proto_minor: 0 content_length: -1 uncompressed: true - body: '{"data":{"createPullRequest":{"pullRequest":{"id":"PR_kwDOMVd0xs7XrljJ","number":75,"url":"https://github.com/test-owner/test-repo/pull/75"}}}}' + body: '{"data":{"createPullRequest":{"pullRequest":{"id":"PR_kwDORFeuH87AtZ9d","number":53,"url":"https://github.com/test-owner/test-repo/pull/53"}}}}' headers: Content-Type: - application/json; charset=utf-8 status: 200 OK code: 200 - duration: 787.09375ms + duration: 778.346166ms - id: 2 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 - content_length: 426 + content_length: 396 host: api.github.com body: | - {"query":"query($number:Int!$owner:String!$repo:String!){repository(owner: $owner, name: $repo){pullRequest(number: $number){id,number,url,title,state,headRefOid,baseRefName,isDraft,headRepository{owner{login},name},labels(first: 100){nodes{name}},reviewRequests(first: 100){nodes{requestedReviewer{... on Actor{login}}}},assignees(first: 100){nodes{login}}}}}","variables":{"number":75,"owner":"test-owner","repo":"test-repo"}} + {"query":"query($number:Int!$owner:String!$repo:String!){repository(owner: $owner, name: $repo){pullRequest(number: $number){id,number,url,title,body,state,headRefOid,baseRefName,isDraft,labels(first: 100){nodes{name}},reviewRequests(first: 100){nodes{requestedReviewer{... on Actor{login}}}},assignees(first: 100){nodes{login}}}}}","variables":{"number":53,"owner":"test-owner","repo":"test-repo"}} headers: Content-Type: - application/json @@ -75,19 +75,19 @@ interactions: proto_minor: 0 content_length: -1 uncompressed: true - body: '{"data":{"repository":{"pullRequest":{"id":"PR_kwDOMVd0xs7XrljJ","number":75,"url":"https://github.com/test-owner/test-repo/pull/75","title":"Testing f4fqEb9C","state":"OPEN","headRefOid":"9ca0860d6f10b375b4d5d57cf43d445d07522341","baseRefName":"main","isDraft":false,"headRepository":{"owner":{"login":"test-owner"},"name":"test-repo"},"labels":{"nodes":[]},"reviewRequests":{"nodes":[]},"assignees":{"nodes":[]}}}}}' + body: '{"data":{"repository":{"pullRequest":{"id":"PR_kwDORFeuH87AtZ9d","number":53,"url":"https://github.com/test-owner/test-repo/pull/53","title":"Testing 0W9K9lnj","state":"OPEN","headRefOid":"a355ab66d327b9f56f5a7528d7321c09b2a91ca1","baseRefName":"main","isDraft":false,"labels":{"nodes":[]},"reviewRequests":{"nodes":[]},"assignees":{"nodes":[]}}}}}' headers: Content-Type: - application/json; charset=utf-8 status: 200 OK code: 200 - duration: 243.585583ms + duration: 165.773584ms - id: 3 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 - content_length: 97 + content_length: 92 host: api.github.com body: | {"query":"query($login:String!){user(login: $login){id}}","variables":{"login":"test-owner-robot"}} @@ -102,22 +102,22 @@ interactions: proto_minor: 0 content_length: -1 uncompressed: true - body: '{"data":{"user":{"id":"U_kgDOCzNVWQ"}}}' + body: '{"data":{"user":{"id":"MDQ6VXNlcjQ3MjUzNw=="}}}' headers: Content-Type: - application/json; charset=utf-8 status: 200 OK code: 200 - duration: 182.531959ms + duration: 105.688333ms - id: 4 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 - content_length: 201 + content_length: 209 host: api.github.com body: | - {"query":"mutation($input:RequestReviewsInput!){requestReviews(input: $input){clientMutationId}}","variables":{"input":{"pullRequestId":"PR_kwDOMVd0xs7XrljJ","userIds":["U_kgDOCzNVWQ"],"union":true}}} + {"query":"mutation($input:RequestReviewsInput!){requestReviews(input: $input){clientMutationId}}","variables":{"input":{"pullRequestId":"PR_kwDORFeuH87AtZ9d","userIds":["MDQ6VXNlcjQ3MjUzNw=="],"union":true}}} headers: Content-Type: - application/json @@ -129,22 +129,22 @@ interactions: proto_minor: 0 content_length: -1 uncompressed: true - body: '{"data":{"requestReviews":{"clientMutationId":null}}}' + body: '{"data":{"requestReviews":{"clientMutationId":null}},"extensions":{"warnings":[{"type":"DEPRECATION","message":"The id MDQ6VXNlcjQ3MjUzNw== is deprecated. Update your cache to use the next_global_id from the data payload.","data":{"legacy_global_id":"MDQ6VXNlcjQ3MjUzNw==","next_global_id":"U_kgDOAAc12Q"},"link":"https://docs.github.com"}]}}' headers: Content-Type: - application/json; charset=utf-8 status: 200 OK code: 200 - duration: 531.640792ms + duration: 736.130416ms - id: 5 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 - content_length: 426 + content_length: 396 host: api.github.com body: | - {"query":"query($number:Int!$owner:String!$repo:String!){repository(owner: $owner, name: $repo){pullRequest(number: $number){id,number,url,title,state,headRefOid,baseRefName,isDraft,headRepository{owner{login},name},labels(first: 100){nodes{name}},reviewRequests(first: 100){nodes{requestedReviewer{... on Actor{login}}}},assignees(first: 100){nodes{login}}}}}","variables":{"number":75,"owner":"test-owner","repo":"test-repo"}} + {"query":"query($number:Int!$owner:String!$repo:String!){repository(owner: $owner, name: $repo){pullRequest(number: $number){id,number,url,title,body,state,headRefOid,baseRefName,isDraft,labels(first: 100){nodes{name}},reviewRequests(first: 100){nodes{requestedReviewer{... on Actor{login}}}},assignees(first: 100){nodes{login}}}}}","variables":{"number":53,"owner":"test-owner","repo":"test-repo"}} headers: Content-Type: - application/json @@ -156,10 +156,10 @@ interactions: proto_minor: 0 content_length: -1 uncompressed: true - body: '{"data":{"repository":{"pullRequest":{"id":"PR_kwDOMVd0xs7XrljJ","number":75,"url":"https://github.com/test-owner/test-repo/pull/75","title":"Testing f4fqEb9C","state":"OPEN","headRefOid":"9ca0860d6f10b375b4d5d57cf43d445d07522341","baseRefName":"main","isDraft":false,"headRepository":{"owner":{"login":"test-owner"},"name":"test-repo"},"labels":{"nodes":[]},"reviewRequests":{"nodes":[{"requestedReviewer":{"login":"test-owner-robot"}}]},"assignees":{"nodes":[]}}}}}' + body: '{"data":{"repository":{"pullRequest":{"id":"PR_kwDORFeuH87AtZ9d","number":53,"url":"https://github.com/test-owner/test-repo/pull/53","title":"Testing 0W9K9lnj","state":"OPEN","headRefOid":"a355ab66d327b9f56f5a7528d7321c09b2a91ca1","baseRefName":"main","isDraft":false,"labels":{"nodes":[]},"reviewRequests":{"nodes":[{"requestedReviewer":{"login":"test-owner-robot"}}]},"assignees":{"nodes":[]}}}}}' headers: Content-Type: - application/json; charset=utf-8 status: 200 OK code: 200 - duration: 264.140542ms + duration: 173.40575ms diff --git a/internal/forge/github/testdata/fixtures/TestIntegration/SubmitEditReviewers/SubmitWithReviewer.yaml b/internal/forge/github/testdata/fixtures/TestIntegration/SubmitEditReviewers/SubmitWithReviewer.yaml index 38f7f348e..d370a4b43 100644 --- a/internal/forge/github/testdata/fixtures/TestIntegration/SubmitEditReviewers/SubmitWithReviewer.yaml +++ b/internal/forge/github/testdata/fixtures/TestIntegration/SubmitEditReviewers/SubmitWithReviewer.yaml @@ -6,7 +6,7 @@ interactions: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 - content_length: 142 + content_length: 146 host: api.github.com body: | {"query":"query($owner:String!$repo:String!){repository(owner: $owner, name: $repo){id}}","variables":{"owner":"test-owner","repo":"test-repo"}} @@ -21,13 +21,13 @@ interactions: proto_minor: 0 content_length: -1 uncompressed: true - body: '{"data":{"repository":{"id":"R_kgDOMVd0xg"}}}' + body: '{"data":{"repository":{"id":"R_kgDORFeuHw"}}}' headers: Content-Type: - application/json; charset=utf-8 status: 200 OK code: 200 - duration: 244.771ms + duration: 228.927417ms - id: 1 request: proto: HTTP/1.1 @@ -36,7 +36,7 @@ interactions: content_length: 273 host: api.github.com body: | - {"query":"mutation($input:CreatePullRequestInput!){createPullRequest(input: $input){pullRequest{id,number,url}}}","variables":{"input":{"repositoryId":"R_kgDOMVd0xg","baseRefName":"main","headRefName":"4IUzIjwL","title":"Testing 4IUzIjwL","body":"Test PR with reviewer"}}} + {"query":"mutation($input:CreatePullRequestInput!){createPullRequest(input: $input){pullRequest{id,number,url}}}","variables":{"input":{"repositoryId":"R_kgDORFeuHw","baseRefName":"main","headRefName":"B9Zm3NL6","title":"Testing B9Zm3NL6","body":"Test PR with reviewer"}}} headers: Content-Type: - application/json @@ -48,19 +48,19 @@ interactions: proto_minor: 0 content_length: -1 uncompressed: true - body: '{"data":{"createPullRequest":{"pullRequest":{"id":"PR_kwDOMVd0xs7Xrli3","number":73,"url":"https://github.com/test-owner/test-repo/pull/73"}}}}' + body: '{"data":{"createPullRequest":{"pullRequest":{"id":"PR_kwDORFeuH87AtZ9h","number":56,"url":"https://github.com/test-owner/test-repo/pull/56"}}}}' headers: Content-Type: - application/json; charset=utf-8 status: 200 OK code: 200 - duration: 915.4875ms + duration: 824.919042ms - id: 2 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 - content_length: 97 + content_length: 92 host: api.github.com body: | {"query":"query($login:String!){user(login: $login){id}}","variables":{"login":"test-owner-robot"}} @@ -75,22 +75,22 @@ interactions: proto_minor: 0 content_length: -1 uncompressed: true - body: '{"data":{"user":{"id":"U_kgDOCzNVWQ"}}}' + body: '{"data":{"user":{"id":"MDQ6VXNlcjQ3MjUzNw=="}}}' headers: Content-Type: - application/json; charset=utf-8 status: 200 OK code: 200 - duration: 222.630666ms + duration: 117.92275ms - id: 3 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 - content_length: 201 + content_length: 209 host: api.github.com body: | - {"query":"mutation($input:RequestReviewsInput!){requestReviews(input: $input){clientMutationId}}","variables":{"input":{"pullRequestId":"PR_kwDOMVd0xs7Xrli3","userIds":["U_kgDOCzNVWQ"],"union":true}}} + {"query":"mutation($input:RequestReviewsInput!){requestReviews(input: $input){clientMutationId}}","variables":{"input":{"pullRequestId":"PR_kwDORFeuH87AtZ9h","userIds":["MDQ6VXNlcjQ3MjUzNw=="],"union":true}}} headers: Content-Type: - application/json @@ -102,22 +102,22 @@ interactions: proto_minor: 0 content_length: -1 uncompressed: true - body: '{"data":{"requestReviews":{"clientMutationId":null}}}' + body: '{"data":{"requestReviews":{"clientMutationId":null}},"extensions":{"warnings":[{"type":"DEPRECATION","message":"The id MDQ6VXNlcjQ3MjUzNw== is deprecated. Update your cache to use the next_global_id from the data payload.","data":{"legacy_global_id":"MDQ6VXNlcjQ3MjUzNw==","next_global_id":"U_kgDOAAc12Q"},"link":"https://docs.github.com"}]}}' headers: Content-Type: - application/json; charset=utf-8 status: 200 OK code: 200 - duration: 623.937333ms + duration: 628.114ms - id: 4 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 - content_length: 615 + content_length: 585 host: api.github.com body: | - {"query":"query($branch:String!$limit:Int!$owner:String!$repo:String!$states:[PullRequestState!]!){repository(owner: $owner, name: $repo){pullRequests(first: $limit, headRefName: $branch, states: $states, orderBy: {field: UPDATED_AT, direction: DESC}){nodes{id,number,url,title,state,headRefOid,baseRefName,isDraft,headRepository{owner{login},name},labels(first: 100){nodes{name}},reviewRequests(first: 100){nodes{requestedReviewer{... on Actor{login}}}},assignees(first: 100){nodes{login}}}}}}","variables":{"branch":"4IUzIjwL","limit":10,"owner":"test-owner","repo":"test-repo","states":["OPEN","CLOSED","MERGED"]}} + {"query":"query($branch:String!$limit:Int!$owner:String!$repo:String!$states:[PullRequestState!]!){repository(owner: $owner, name: $repo){pullRequests(first: $limit, headRefName: $branch, states: $states, orderBy: {field: UPDATED_AT, direction: DESC}){nodes{id,number,url,title,body,state,headRefOid,baseRefName,isDraft,labels(first: 100){nodes{name}},reviewRequests(first: 100){nodes{requestedReviewer{... on Actor{login}}}},assignees(first: 100){nodes{login}}}}}}","variables":{"branch":"B9Zm3NL6","limit":10,"owner":"test-owner","repo":"test-repo","states":["OPEN","CLOSED","MERGED"]}} headers: Content-Type: - application/json @@ -129,10 +129,10 @@ interactions: proto_minor: 0 content_length: -1 uncompressed: true - body: '{"data":{"repository":{"pullRequests":{"nodes":[{"id":"PR_kwDOMVd0xs7Xrli3","number":73,"url":"https://github.com/test-owner/test-repo/pull/73","title":"Testing 4IUzIjwL","state":"OPEN","headRefOid":"90ec1928f53d0d67eff62f828c471c935f7d9660","baseRefName":"main","isDraft":false,"headRepository":{"owner":{"login":"test-owner"},"name":"test-repo"},"labels":{"nodes":[]},"reviewRequests":{"nodes":[{"requestedReviewer":{"login":"test-owner-robot"}}]},"assignees":{"nodes":[]}}]}}}}' + body: '{"data":{"repository":{"pullRequests":{"nodes":[{"id":"PR_kwDORFeuH87AtZ9h","number":56,"url":"https://github.com/test-owner/test-repo/pull/56","title":"Testing B9Zm3NL6","state":"OPEN","headRefOid":"ff0384a577a3f05e095b32d4323dcce946c8f420","baseRefName":"main","isDraft":false,"labels":{"nodes":[]},"reviewRequests":{"nodes":[{"requestedReviewer":{"login":"test-owner-robot"}}]},"assignees":{"nodes":[]}}]}}}}' headers: Content-Type: - application/json; charset=utf-8 status: 200 OK code: 200 - duration: 302.3805ms + duration: 202.197125ms diff --git a/internal/forge/github/testdata/fixtures/TestIntegration_Repository_SubmitEditChangeWIthLabels.yaml b/internal/forge/github/testdata/fixtures/TestIntegration_Repository_SubmitEditChangeWIthLabels.yaml index 8374d5322..05df190b1 100644 --- a/internal/forge/github/testdata/fixtures/TestIntegration_Repository_SubmitEditChangeWIthLabels.yaml +++ b/internal/forge/github/testdata/fixtures/TestIntegration_Repository_SubmitEditChangeWIthLabels.yaml @@ -81,7 +81,7 @@ interactions: remote_addr: "" request_uri: "" body: | - {"query":"query($number:Int!$owner:String!$repo:String!){repository(owner: $owner, name: $repo){pullRequest(number: $number){id,number,url,title,state,headRefOid,baseRefName,isDraft}}}","variables":{"number":4,"owner":"test-owner","repo":"test-repo"}} + {"query":"query($number:Int!$owner:String!$repo:String!){repository(owner: $owner, name: $repo){pullRequest(number: $number){id,number,url,title,body,state,headRefOid,baseRefName,isDraft}}}","variables":{"number":4,"owner":"test-owner","repo":"test-repo"}} form: {} headers: Content-Type: @@ -183,7 +183,7 @@ interactions: remote_addr: "" request_uri: "" body: | - {"query":"query($number:Int!$owner:String!$repo:String!){repository(owner: $owner, name: $repo){pullRequest(number: $number){id,number,url,title,state,headRefOid,baseRefName,isDraft}}}","variables":{"number":4,"owner":"test-owner","repo":"test-repo"}} + {"query":"query($number:Int!$owner:String!$repo:String!){repository(owner: $owner, name: $repo){pullRequest(number: $number){id,number,url,title,body,state,headRefOid,baseRefName,isDraft}}}","variables":{"number":4,"owner":"test-owner","repo":"test-repo"}} form: {} headers: Content-Type: diff --git a/internal/forge/gitlab/edit.go b/internal/forge/gitlab/edit.go index 715b6380e..e0dd814ea 100644 --- a/internal/forge/gitlab/edit.go +++ b/internal/forge/gitlab/edit.go @@ -23,6 +23,8 @@ var _draftRegex = regexp.MustCompile(`(?i)^\s*(\[Draft]|Draft:|\(Draft\))\s*`) func (r *Repository) EditChange(ctx context.Context, id forge.ChangeID, opts forge.EditChangeOptions) error { if cmputil.Zero(opts.Base) && cmputil.Zero(opts.Draft) && + cmputil.Zero(opts.Subject) && + cmputil.Zero(opts.Body) && len(opts.AddLabels) == 0 && len(opts.AddReviewers) == 0 && len(opts.AddAssignees) == 0 { @@ -59,6 +61,18 @@ func (r *Repository) EditChange(ctx context.Context, id forge.ChangeID, opts for logUpdates = append(logUpdates, slog.String("base", opts.Base)) } + if opts.Subject != "" { + updateOptions.Title = &opts.Subject + logUpdates = append(logUpdates, + slog.String("subject", opts.Subject)) + } + + if opts.Body != nil { + updateOptions.Description = opts.Body + logUpdates = append(logUpdates, + slog.String("body", *opts.Body)) + } + // TODO: // As part of submit, we've likely already fetched this information. // Cache it in memory. diff --git a/internal/forge/gitlab/find.go b/internal/forge/gitlab/find.go index ff31aa69b..d98ab7102 100644 --- a/internal/forge/gitlab/find.go +++ b/internal/forge/gitlab/find.go @@ -38,6 +38,7 @@ func basicMergeRequestToFindChangeItem(mr *gitlab.BasicMergeRequest) *forge.Find URL: mr.WebURL, State: forgeChangeState(mr.State), Subject: mr.Title, + Body: mr.Description, BaseName: mr.TargetBranch, HeadHash: git.Hash(mr.SHA), Draft: mr.Draft, @@ -76,6 +77,7 @@ func mergeRequestToFindChangeItem(mr *gitlab.MergeRequest) *forge.FindChangeItem URL: mr.WebURL, State: forgeChangeState(mr.State), Subject: mr.Title, + Body: mr.Description, BaseName: mr.TargetBranch, HeadHash: git.Hash(mr.SHA), Draft: mr.Draft, diff --git a/internal/forge/shamhub/edit.go b/internal/forge/shamhub/edit.go index e9c8cdc1e..200a11a51 100644 --- a/internal/forge/shamhub/edit.go +++ b/internal/forge/shamhub/edit.go @@ -16,6 +16,8 @@ type editChangeRequest struct { Base *string `json:"base,omitempty"` Draft *bool `json:"draft,omitempty"` + Subject string `json:"subject,omitempty"` + Body *string `json:"body,omitempty"` Labels []string `json:"labels,omitempty"` Reviewers []string `json:"reviewers,omitempty"` Assignees []string `json:"assignees,omitempty"` @@ -47,6 +49,12 @@ func (sh *ShamHub) handleEditChange(_ context.Context, req *editChangeRequest) ( if d := req.Draft; d != nil { sh.changes[changeIdx].Draft = *d } + if req.Subject != "" { + sh.changes[changeIdx].Subject = req.Subject + } + if req.Body != nil { + sh.changes[changeIdx].Body = *req.Body + } if len(req.Labels) > 0 { labels := sh.changes[changeIdx].Labels for _, label := range req.Labels { @@ -115,6 +123,8 @@ func (r *forgeRepository) EditChange(ctx context.Context, fid forge.ChangeID, op if opts.Draft != nil { req.Draft = opts.Draft } + req.Subject = opts.Subject + req.Body = opts.Body req.Labels = opts.AddLabels req.Reviewers = opts.AddReviewers req.Assignees = opts.AddAssignees diff --git a/internal/forge/shamhub/find.go b/internal/forge/shamhub/find.go index 01dccb157..0b67dbd42 100644 --- a/internal/forge/shamhub/find.go +++ b/internal/forge/shamhub/find.go @@ -155,6 +155,7 @@ func (r *forgeRepository) toFindChangeItem(c *Change) *forge.FindChangeItem { ID: ChangeID(c.Number), URL: c.URL, Subject: c.Subject, + Body: c.Body, HeadHash: git.Hash(c.Head.Hash), BaseName: c.Base.Name, Draft: c.Draft, diff --git a/internal/forge/shamhub/testdata/TestIntegration/ChangeComments/UpdateComment/updated-comment b/internal/forge/shamhub/testdata/TestIntegration/ChangeComments/UpdateComment/updated-comment index 85760ee02..ecd61162b 100644 --- a/internal/forge/shamhub/testdata/TestIntegration/ChangeComments/UpdateComment/updated-comment +++ b/internal/forge/shamhub/testdata/TestIntegration/ChangeComments/UpdateComment/updated-comment @@ -1 +1 @@ -"uXAhcpF8V9XZWbQom2aI0nM6Q9fbiqpd" \ No newline at end of file +"G7bkHTnTfmvCMz6JyfufKQF8PR7a9oqD" \ No newline at end of file diff --git a/internal/forge/shamhub/testdata/TestIntegration/ChangeComments/branch b/internal/forge/shamhub/testdata/TestIntegration/ChangeComments/branch index 3d68dade2..06de2cdef 100644 --- a/internal/forge/shamhub/testdata/TestIntegration/ChangeComments/branch +++ b/internal/forge/shamhub/testdata/TestIntegration/ChangeComments/branch @@ -1 +1 @@ -"uO3v3Jiu" \ No newline at end of file +"jez5m7cQ" \ No newline at end of file diff --git a/internal/forge/shamhub/testdata/TestIntegration/ChangeComments/comments b/internal/forge/shamhub/testdata/TestIntegration/ChangeComments/comments index e57864939..e13833f00 100644 --- a/internal/forge/shamhub/testdata/TestIntegration/ChangeComments/comments +++ b/internal/forge/shamhub/testdata/TestIntegration/ChangeComments/comments @@ -1,12 +1,12 @@ [ - "M9TCBnUn2veSjGnStFRLruw4FhpFbpPr", - "ooErWPQY4wHcWm8bJDNOeA2G2BHnMcl1", - "DU3TnJBDljtJOjrPNPgfJRo44fzPxWxZ", - "WeEXYW6yjMMf0jmnnze12omw5CmTHrDt", - "S4IQsdn1dgnUfOJEFb5JEm7kVxLd8oil", - "JNpsluBOeFN8cwri2EMfI8BrYjbArxPf", - "FgUJanBcocO1ablzVyYVjDh6fUZbZXyI", - "qp1FOZUVrehYPmU311YMEQDrHlJ2BJ40", - "sODVHSvcIOhqxyrkgurNH9HMl2b2LSg6", - "k7NLLLvg5wMj1tasfkFfqdbhqfa8Ah0E" + "iivoJ7MBVzBSX5ZSjXUsADZerx7ZEa37", + "8mMtmaLEp2wgKlB5JrgAJoeo6Ui6fgl9", + "6cJi4STnarDSDGWnUBVEQpIQhFUqc2kz", + "EFYN40zzvmin2oAU4FPXiHTOmSHUERjl", + "7372hge5yTtHUySmYNV4PICC1vPFPrXc", + "B55eq0pC1RVynm8sYTbagqGiOjUkNVXF", + "gnJPLIYBAkZAlb12cOLiEQHOjOBqdiRB", + "sAuv6hr5p7kb3qIgWI1NtNo6SUhc7OEl", + "uf3v7hCghPBI2gmgBYhuZdqIEAtcwFhO", + "jLo35606q1DKggWAlZoeWB0Y7ozVjpwB" ] \ No newline at end of file diff --git a/internal/forge/shamhub/testdata/TestIntegration/ChangesStates/closedBranch b/internal/forge/shamhub/testdata/TestIntegration/ChangesStates/closedBranch index d616a2169..24df9967c 100644 --- a/internal/forge/shamhub/testdata/TestIntegration/ChangesStates/closedBranch +++ b/internal/forge/shamhub/testdata/TestIntegration/ChangesStates/closedBranch @@ -1 +1 @@ -"IEtiDhFs" \ No newline at end of file +"zUMZc5wS" \ No newline at end of file diff --git a/internal/forge/shamhub/testdata/TestIntegration/ChangesStates/mergedBranch b/internal/forge/shamhub/testdata/TestIntegration/ChangesStates/mergedBranch index 2142ea6ab..2f2802e20 100644 --- a/internal/forge/shamhub/testdata/TestIntegration/ChangesStates/mergedBranch +++ b/internal/forge/shamhub/testdata/TestIntegration/ChangesStates/mergedBranch @@ -1 +1 @@ -"C5hzQ5Ik" \ No newline at end of file +"0xd3VrO2" \ No newline at end of file diff --git a/internal/forge/shamhub/testdata/TestIntegration/ChangesStates/openBranch b/internal/forge/shamhub/testdata/TestIntegration/ChangesStates/openBranch index 7c13c61bf..f75764ec2 100644 --- a/internal/forge/shamhub/testdata/TestIntegration/ChangesStates/openBranch +++ b/internal/forge/shamhub/testdata/TestIntegration/ChangesStates/openBranch @@ -1 +1 @@ -"jMfwXkYK" \ No newline at end of file +"phdnd9Ow" \ No newline at end of file diff --git a/internal/forge/shamhub/testdata/TestIntegration/CommentCountsByChange/branch b/internal/forge/shamhub/testdata/TestIntegration/CommentCountsByChange/branch index 778cc9b7f..039a14925 100644 --- a/internal/forge/shamhub/testdata/TestIntegration/CommentCountsByChange/branch +++ b/internal/forge/shamhub/testdata/TestIntegration/CommentCountsByChange/branch @@ -1 +1 @@ -"HQWHaq9z" \ No newline at end of file +"5WfSEUpY" \ No newline at end of file diff --git a/internal/forge/shamhub/testdata/TestIntegration/ListChangeTemplates/TemplatesPresent/empty-template b/internal/forge/shamhub/testdata/TestIntegration/ListChangeTemplates/TemplatesPresent/empty-template index 3da52d175..b655a8e62 100644 --- a/internal/forge/shamhub/testdata/TestIntegration/ListChangeTemplates/TemplatesPresent/empty-template +++ b/internal/forge/shamhub/testdata/TestIntegration/ListChangeTemplates/TemplatesPresent/empty-template @@ -1 +1 @@ -"1HQqVNZV.md" \ No newline at end of file +"pcCwLplM.md" \ No newline at end of file diff --git a/internal/forge/shamhub/testdata/TestIntegration/ListChangeTemplates/TemplatesPresent/non-empty-template b/internal/forge/shamhub/testdata/TestIntegration/ListChangeTemplates/TemplatesPresent/non-empty-template index 0c924f438..05d175143 100644 --- a/internal/forge/shamhub/testdata/TestIntegration/ListChangeTemplates/TemplatesPresent/non-empty-template +++ b/internal/forge/shamhub/testdata/TestIntegration/ListChangeTemplates/TemplatesPresent/non-empty-template @@ -1 +1 @@ -"yE3Lj2v5.md" \ No newline at end of file +"lxoHV53Y.md" \ No newline at end of file diff --git a/internal/forge/shamhub/testdata/TestIntegration/SubmitBaseDoesNotExist/base-branch b/internal/forge/shamhub/testdata/TestIntegration/SubmitBaseDoesNotExist/base-branch index b8e719155..915612226 100644 --- a/internal/forge/shamhub/testdata/TestIntegration/SubmitBaseDoesNotExist/base-branch +++ b/internal/forge/shamhub/testdata/TestIntegration/SubmitBaseDoesNotExist/base-branch @@ -1 +1 @@ -"9s9oMX6C" \ No newline at end of file +"gVax4kxU" \ No newline at end of file diff --git a/internal/forge/shamhub/testdata/TestIntegration/SubmitBaseDoesNotExist/branch b/internal/forge/shamhub/testdata/TestIntegration/SubmitBaseDoesNotExist/branch index 02926e09f..a033ea76a 100644 --- a/internal/forge/shamhub/testdata/TestIntegration/SubmitBaseDoesNotExist/branch +++ b/internal/forge/shamhub/testdata/TestIntegration/SubmitBaseDoesNotExist/branch @@ -1 +1 @@ -"vY4xsORW" \ No newline at end of file +"rmcYQqjw" \ No newline at end of file diff --git a/internal/forge/shamhub/testdata/TestIntegration/SubmitEditAssignees/AddAssignee/branch-no-assignee b/internal/forge/shamhub/testdata/TestIntegration/SubmitEditAssignees/AddAssignee/branch-no-assignee index b92100789..5696e5def 100644 --- a/internal/forge/shamhub/testdata/TestIntegration/SubmitEditAssignees/AddAssignee/branch-no-assignee +++ b/internal/forge/shamhub/testdata/TestIntegration/SubmitEditAssignees/AddAssignee/branch-no-assignee @@ -1 +1 @@ -"66MtCOhk" \ No newline at end of file +"3MZZ40Kb" \ No newline at end of file diff --git a/internal/forge/shamhub/testdata/TestIntegration/SubmitEditAssignees/AddAssigneesOneByOne/branch-no-assignee-one-by-one b/internal/forge/shamhub/testdata/TestIntegration/SubmitEditAssignees/AddAssigneesOneByOne/branch-no-assignee-one-by-one index e678e3903..97e0b6e59 100644 --- a/internal/forge/shamhub/testdata/TestIntegration/SubmitEditAssignees/AddAssigneesOneByOne/branch-no-assignee-one-by-one +++ b/internal/forge/shamhub/testdata/TestIntegration/SubmitEditAssignees/AddAssigneesOneByOne/branch-no-assignee-one-by-one @@ -1 +1 @@ -"Op9WQIRi" \ No newline at end of file +"igUdjqag" \ No newline at end of file diff --git a/internal/forge/shamhub/testdata/TestIntegration/SubmitEditAssignees/SubmitWithAssignee/branch-with-assignee b/internal/forge/shamhub/testdata/TestIntegration/SubmitEditAssignees/SubmitWithAssignee/branch-with-assignee index d3f1200a7..cd279fef7 100644 --- a/internal/forge/shamhub/testdata/TestIntegration/SubmitEditAssignees/SubmitWithAssignee/branch-with-assignee +++ b/internal/forge/shamhub/testdata/TestIntegration/SubmitEditAssignees/SubmitWithAssignee/branch-with-assignee @@ -1 +1 @@ -"lE3mefp0" \ No newline at end of file +"ShZbkKGz" \ No newline at end of file diff --git a/internal/forge/shamhub/testdata/TestIntegration/SubmitEditBase/base b/internal/forge/shamhub/testdata/TestIntegration/SubmitEditBase/base index 5a0613317..8fdfe4a23 100644 --- a/internal/forge/shamhub/testdata/TestIntegration/SubmitEditBase/base +++ b/internal/forge/shamhub/testdata/TestIntegration/SubmitEditBase/base @@ -1 +1 @@ -"t8XzNN0X" \ No newline at end of file +"k2EK1wis" \ No newline at end of file diff --git a/internal/forge/shamhub/testdata/TestIntegration/SubmitEditBase/branch b/internal/forge/shamhub/testdata/TestIntegration/SubmitEditBase/branch index 133b93253..5a811bf63 100644 --- a/internal/forge/shamhub/testdata/TestIntegration/SubmitEditBase/branch +++ b/internal/forge/shamhub/testdata/TestIntegration/SubmitEditBase/branch @@ -1 +1 @@ -"9YbzXae4" \ No newline at end of file +"m7yF4ync" \ No newline at end of file diff --git a/internal/forge/shamhub/testdata/TestIntegration/SubmitEditChange/branch b/internal/forge/shamhub/testdata/TestIntegration/SubmitEditChange/branch index 879ccaf2e..e0420ac1c 100644 --- a/internal/forge/shamhub/testdata/TestIntegration/SubmitEditChange/branch +++ b/internal/forge/shamhub/testdata/TestIntegration/SubmitEditChange/branch @@ -1 +1 @@ -"RowsHzO8" \ No newline at end of file +"gz0Insmn" \ No newline at end of file diff --git a/internal/forge/shamhub/testdata/TestIntegration/SubmitEditChange/firstCommitHash b/internal/forge/shamhub/testdata/TestIntegration/SubmitEditChange/firstCommitHash index 68000fd15..bfaa3e7bf 100644 --- a/internal/forge/shamhub/testdata/TestIntegration/SubmitEditChange/firstCommitHash +++ b/internal/forge/shamhub/testdata/TestIntegration/SubmitEditChange/firstCommitHash @@ -1 +1 @@ -"1ee3894a24c031b5d053a0b8bb25a9182fd77604" \ No newline at end of file +"bc8c96b8904897bd058dc097ce3a93137c9fc55a" \ No newline at end of file diff --git a/internal/forge/shamhub/testdata/TestIntegration/SubmitEditDraft/branch b/internal/forge/shamhub/testdata/TestIntegration/SubmitEditDraft/branch index 5bfde7014..3d866e0cc 100644 --- a/internal/forge/shamhub/testdata/TestIntegration/SubmitEditDraft/branch +++ b/internal/forge/shamhub/testdata/TestIntegration/SubmitEditDraft/branch @@ -1 +1 @@ -"pCyU7Tpe" \ No newline at end of file +"MxSsq1Kd" \ No newline at end of file diff --git a/internal/forge/shamhub/testdata/TestIntegration/SubmitEditLabels/branch b/internal/forge/shamhub/testdata/TestIntegration/SubmitEditLabels/branch index 82678979f..f89a7d67b 100644 --- a/internal/forge/shamhub/testdata/TestIntegration/SubmitEditLabels/branch +++ b/internal/forge/shamhub/testdata/TestIntegration/SubmitEditLabels/branch @@ -1 +1 @@ -"jbBnJuHT" \ No newline at end of file +"zoK34kdM" \ No newline at end of file diff --git a/internal/forge/shamhub/testdata/TestIntegration/SubmitEditLabels/label1 b/internal/forge/shamhub/testdata/TestIntegration/SubmitEditLabels/label1 index de5114824..fe59b26ea 100644 --- a/internal/forge/shamhub/testdata/TestIntegration/SubmitEditLabels/label1 +++ b/internal/forge/shamhub/testdata/TestIntegration/SubmitEditLabels/label1 @@ -1 +1 @@ -"QcHb0icn" \ No newline at end of file +"HLZfQoCE" \ No newline at end of file diff --git a/internal/forge/shamhub/testdata/TestIntegration/SubmitEditLabels/label2 b/internal/forge/shamhub/testdata/TestIntegration/SubmitEditLabels/label2 index 7b3d9d81e..6a9e5a9dd 100644 --- a/internal/forge/shamhub/testdata/TestIntegration/SubmitEditLabels/label2 +++ b/internal/forge/shamhub/testdata/TestIntegration/SubmitEditLabels/label2 @@ -1 +1 @@ -"820svnw8" \ No newline at end of file +"JdJJispW" \ No newline at end of file diff --git a/internal/forge/shamhub/testdata/TestIntegration/SubmitEditLabels/label3 b/internal/forge/shamhub/testdata/TestIntegration/SubmitEditLabels/label3 index c09704b58..206841dba 100644 --- a/internal/forge/shamhub/testdata/TestIntegration/SubmitEditLabels/label3 +++ b/internal/forge/shamhub/testdata/TestIntegration/SubmitEditLabels/label3 @@ -1 +1 @@ -"bUnh1ONJ" \ No newline at end of file +"fgvJffiW" \ No newline at end of file diff --git a/internal/forge/shamhub/testdata/TestIntegration/SubmitEditReviewers/AddReviewer/branch-no-reviewer b/internal/forge/shamhub/testdata/TestIntegration/SubmitEditReviewers/AddReviewer/branch-no-reviewer index 876aafd30..878f8860b 100644 --- a/internal/forge/shamhub/testdata/TestIntegration/SubmitEditReviewers/AddReviewer/branch-no-reviewer +++ b/internal/forge/shamhub/testdata/TestIntegration/SubmitEditReviewers/AddReviewer/branch-no-reviewer @@ -1 +1 @@ -"qS0oWVxR" \ No newline at end of file +"hE7bVCmZ" \ No newline at end of file diff --git a/internal/forge/shamhub/testdata/TestIntegration/SubmitEditReviewers/AddReviewersOneByOne/branch-no-reviewer-one-by-one b/internal/forge/shamhub/testdata/TestIntegration/SubmitEditReviewers/AddReviewersOneByOne/branch-no-reviewer-one-by-one index df22e5ade..5d0037b17 100644 --- a/internal/forge/shamhub/testdata/TestIntegration/SubmitEditReviewers/AddReviewersOneByOne/branch-no-reviewer-one-by-one +++ b/internal/forge/shamhub/testdata/TestIntegration/SubmitEditReviewers/AddReviewersOneByOne/branch-no-reviewer-one-by-one @@ -1 +1 @@ -"sN0uOM0J" \ No newline at end of file +"ypPdbssG" \ No newline at end of file diff --git a/internal/forge/shamhub/testdata/TestIntegration/SubmitEditReviewers/SubmitWithReviewer/branch-with-reviewer b/internal/forge/shamhub/testdata/TestIntegration/SubmitEditReviewers/SubmitWithReviewer/branch-with-reviewer index 9bf39d178..f5cf6df16 100644 --- a/internal/forge/shamhub/testdata/TestIntegration/SubmitEditReviewers/SubmitWithReviewer/branch-with-reviewer +++ b/internal/forge/shamhub/testdata/TestIntegration/SubmitEditReviewers/SubmitWithReviewer/branch-with-reviewer @@ -1 +1 @@ -"4oj7KI1p" \ No newline at end of file +"jPM09bmi" \ No newline at end of file diff --git a/internal/forge/shamhub/testdata/TestIntegration/apiURL b/internal/forge/shamhub/testdata/TestIntegration/apiURL index 38ca6faef..090558703 100644 --- a/internal/forge/shamhub/testdata/TestIntegration/apiURL +++ b/internal/forge/shamhub/testdata/TestIntegration/apiURL @@ -1 +1 @@ -"http://127.0.0.1:56373" \ No newline at end of file +"http://127.0.0.1:57035" \ No newline at end of file diff --git a/internal/forge/shamhub/testdata/TestIntegration/gitURL b/internal/forge/shamhub/testdata/TestIntegration/gitURL index 0d906a389..9ff1b3a3c 100644 --- a/internal/forge/shamhub/testdata/TestIntegration/gitURL +++ b/internal/forge/shamhub/testdata/TestIntegration/gitURL @@ -1 +1 @@ -"http://127.0.0.1:56374" \ No newline at end of file +"http://127.0.0.1:57036" \ No newline at end of file diff --git a/internal/forge/shamhub/testdata/TestIntegration/repoURL b/internal/forge/shamhub/testdata/TestIntegration/repoURL index 4551e0131..d392bdd49 100644 --- a/internal/forge/shamhub/testdata/TestIntegration/repoURL +++ b/internal/forge/shamhub/testdata/TestIntegration/repoURL @@ -1 +1 @@ -"http://127.0.0.1:56374/abhinav/test-repo.git" \ No newline at end of file +"http://127.0.0.1:57036/abhinav/test-repo.git" \ No newline at end of file diff --git a/internal/forge/shamhub/testdata/TestIntegration/token b/internal/forge/shamhub/testdata/TestIntegration/token index a5ee830ce..d2214f30d 100644 --- a/internal/forge/shamhub/testdata/TestIntegration/token +++ b/internal/forge/shamhub/testdata/TestIntegration/token @@ -1 +1 @@ -"444a9baa5f8f8904" \ No newline at end of file +"c5bc48fafa1f2844" \ No newline at end of file diff --git a/internal/forge/shamhub/testdata/fixtures/TestIntegration/ChangeComments.yaml b/internal/forge/shamhub/testdata/fixtures/TestIntegration/ChangeComments.yaml index 889179595..3ca4d5053 100644 --- a/internal/forge/shamhub/testdata/fixtures/TestIntegration/ChangeComments.yaml +++ b/internal/forge/shamhub/testdata/fixtures/TestIntegration/ChangeComments.yaml @@ -7,9 +7,9 @@ interactions: proto_major: 1 proto_minor: 1 content_length: 92 - host: 127.0.0.1:56373 - body: '{"subject":"Testing uO3v3Jiu","body":"Test PR for comments","base":"main","head":"uO3v3Jiu"}' - url: http://127.0.0.1:56373/abhinav/test-repo/changes + host: 127.0.0.1:57035 + body: '{"subject":"Testing jez5m7cQ","body":"Test PR for comments","base":"main","head":"jez5m7cQ"}' + url: http://127.0.0.1:57035/abhinav/test-repo/changes method: POST response: proto: HTTP/1.1 @@ -18,8 +18,8 @@ interactions: content_length: 80 body: | { - "number": 4, - "url": "http://127.0.0.1:56374/abhinav/test-repo/change/4" + "number": 2, + "url": "http://127.0.0.1:57036/abhinav/test-repo/change/2" } headers: Content-Length: @@ -28,16 +28,16 @@ interactions: - application/json status: 200 OK code: 200 - duration: 20.3975ms + duration: 39.729167ms - id: 1 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 content_length: 60 - host: 127.0.0.1:56373 - body: '{"changeNumber":4,"body":"M9TCBnUn2veSjGnStFRLruw4FhpFbpPr"}' - url: http://127.0.0.1:56373/abhinav/test-repo/comments + host: 127.0.0.1:57035 + body: '{"changeNumber":2,"body":"iivoJ7MBVzBSX5ZSjXUsADZerx7ZEa37"}' + url: http://127.0.0.1:57035/abhinav/test-repo/comments method: POST response: proto: HTTP/1.1 @@ -55,16 +55,16 @@ interactions: - application/json status: 200 OK code: 200 - duration: 123.292µs + duration: 365.084µs - id: 2 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 content_length: 60 - host: 127.0.0.1:56373 - body: '{"changeNumber":4,"body":"ooErWPQY4wHcWm8bJDNOeA2G2BHnMcl1"}' - url: http://127.0.0.1:56373/abhinav/test-repo/comments + host: 127.0.0.1:57035 + body: '{"changeNumber":2,"body":"8mMtmaLEp2wgKlB5JrgAJoeo6Ui6fgl9"}' + url: http://127.0.0.1:57035/abhinav/test-repo/comments method: POST response: proto: HTTP/1.1 @@ -82,16 +82,16 @@ interactions: - application/json status: 200 OK code: 200 - duration: 1.531375ms + duration: 491.583µs - id: 3 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 content_length: 60 - host: 127.0.0.1:56373 - body: '{"changeNumber":4,"body":"DU3TnJBDljtJOjrPNPgfJRo44fzPxWxZ"}' - url: http://127.0.0.1:56373/abhinav/test-repo/comments + host: 127.0.0.1:57035 + body: '{"changeNumber":2,"body":"6cJi4STnarDSDGWnUBVEQpIQhFUqc2kz"}' + url: http://127.0.0.1:57035/abhinav/test-repo/comments method: POST response: proto: HTTP/1.1 @@ -109,16 +109,16 @@ interactions: - application/json status: 200 OK code: 200 - duration: 84.25µs + duration: 273.625µs - id: 4 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 content_length: 60 - host: 127.0.0.1:56373 - body: '{"changeNumber":4,"body":"WeEXYW6yjMMf0jmnnze12omw5CmTHrDt"}' - url: http://127.0.0.1:56373/abhinav/test-repo/comments + host: 127.0.0.1:57035 + body: '{"changeNumber":2,"body":"EFYN40zzvmin2oAU4FPXiHTOmSHUERjl"}' + url: http://127.0.0.1:57035/abhinav/test-repo/comments method: POST response: proto: HTTP/1.1 @@ -136,16 +136,16 @@ interactions: - application/json status: 200 OK code: 200 - duration: 482.875µs + duration: 195.583µs - id: 5 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 content_length: 60 - host: 127.0.0.1:56373 - body: '{"changeNumber":4,"body":"S4IQsdn1dgnUfOJEFb5JEm7kVxLd8oil"}' - url: http://127.0.0.1:56373/abhinav/test-repo/comments + host: 127.0.0.1:57035 + body: '{"changeNumber":2,"body":"7372hge5yTtHUySmYNV4PICC1vPFPrXc"}' + url: http://127.0.0.1:57035/abhinav/test-repo/comments method: POST response: proto: HTTP/1.1 @@ -163,16 +163,16 @@ interactions: - application/json status: 200 OK code: 200 - duration: 224.083µs + duration: 752.084µs - id: 6 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 content_length: 60 - host: 127.0.0.1:56373 - body: '{"changeNumber":4,"body":"JNpsluBOeFN8cwri2EMfI8BrYjbArxPf"}' - url: http://127.0.0.1:56373/abhinav/test-repo/comments + host: 127.0.0.1:57035 + body: '{"changeNumber":2,"body":"B55eq0pC1RVynm8sYTbagqGiOjUkNVXF"}' + url: http://127.0.0.1:57035/abhinav/test-repo/comments method: POST response: proto: HTTP/1.1 @@ -190,16 +190,16 @@ interactions: - application/json status: 200 OK code: 200 - duration: 103.5µs + duration: 337.125µs - id: 7 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 content_length: 60 - host: 127.0.0.1:56373 - body: '{"changeNumber":4,"body":"FgUJanBcocO1ablzVyYVjDh6fUZbZXyI"}' - url: http://127.0.0.1:56373/abhinav/test-repo/comments + host: 127.0.0.1:57035 + body: '{"changeNumber":2,"body":"gnJPLIYBAkZAlb12cOLiEQHOjOBqdiRB"}' + url: http://127.0.0.1:57035/abhinav/test-repo/comments method: POST response: proto: HTTP/1.1 @@ -217,16 +217,16 @@ interactions: - application/json status: 200 OK code: 200 - duration: 257.333µs + duration: 501.792µs - id: 8 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 content_length: 60 - host: 127.0.0.1:56373 - body: '{"changeNumber":4,"body":"qp1FOZUVrehYPmU311YMEQDrHlJ2BJ40"}' - url: http://127.0.0.1:56373/abhinav/test-repo/comments + host: 127.0.0.1:57035 + body: '{"changeNumber":2,"body":"sAuv6hr5p7kb3qIgWI1NtNo6SUhc7OEl"}' + url: http://127.0.0.1:57035/abhinav/test-repo/comments method: POST response: proto: HTTP/1.1 @@ -244,16 +244,16 @@ interactions: - application/json status: 200 OK code: 200 - duration: 140.333µs + duration: 245.833µs - id: 9 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 content_length: 60 - host: 127.0.0.1:56373 - body: '{"changeNumber":4,"body":"sODVHSvcIOhqxyrkgurNH9HMl2b2LSg6"}' - url: http://127.0.0.1:56373/abhinav/test-repo/comments + host: 127.0.0.1:57035 + body: '{"changeNumber":2,"body":"uf3v7hCghPBI2gmgBYhuZdqIEAtcwFhO"}' + url: http://127.0.0.1:57035/abhinav/test-repo/comments method: POST response: proto: HTTP/1.1 @@ -271,16 +271,16 @@ interactions: - application/json status: 200 OK code: 200 - duration: 121.5µs + duration: 256.667µs - id: 10 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 content_length: 60 - host: 127.0.0.1:56373 - body: '{"changeNumber":4,"body":"k7NLLLvg5wMj1tasfkFfqdbhqfa8Ah0E"}' - url: http://127.0.0.1:56373/abhinav/test-repo/comments + host: 127.0.0.1:57035 + body: '{"changeNumber":2,"body":"jLo35606q1DKggWAlZoeWB0Y7ozVjpwB"}' + url: http://127.0.0.1:57035/abhinav/test-repo/comments method: POST response: proto: HTTP/1.1 @@ -298,16 +298,16 @@ interactions: - application/json status: 200 OK code: 200 - duration: 115.833µs + duration: 340.125µs - id: 11 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 content_length: 43 - host: 127.0.0.1:56373 - body: '{"body":"uXAhcpF8V9XZWbQom2aI0nM6Q9fbiqpd"}' - url: http://127.0.0.1:56373/abhinav/test-repo/comments/1 + host: 127.0.0.1:57035 + body: '{"body":"G7bkHTnTfmvCMz6JyfufKQF8PR7a9oqD"}' + url: http://127.0.0.1:57035/abhinav/test-repo/comments/1 method: PATCH response: proto: HTTP/1.1 @@ -325,15 +325,15 @@ interactions: - application/json status: 200 OK code: 200 - duration: 1.85ms + duration: 1.106625ms - id: 12 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 content_length: 0 - host: 127.0.0.1:56373 - url: http://127.0.0.1:56373/abhinav/test-repo/comments/2 + host: 127.0.0.1:57035 + url: http://127.0.0.1:57035/abhinav/test-repo/comments/2 method: DELETE response: proto: HTTP/1.1 @@ -349,16 +349,16 @@ interactions: - application/json status: 200 OK code: 200 - duration: 450µs + duration: 454.708µs - id: 13 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 content_length: 22 - host: 127.0.0.1:56373 + host: 127.0.0.1:57035 body: '{"body":"should fail"}' - url: http://127.0.0.1:56373/abhinav/test-repo/comments/2 + url: http://127.0.0.1:57035/abhinav/test-repo/comments/2 method: PATCH response: proto: HTTP/1.1 @@ -374,22 +374,22 @@ interactions: - text/plain; charset=utf-8 status: 404 Not Found code: 404 - duration: 314.5µs + duration: 1.387291ms - id: 14 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 content_length: 0 - host: 127.0.0.1:56373 + host: 127.0.0.1:57035 form: change: - - "4" + - "2" limit: - "3" offset: - "0" - url: http://127.0.0.1:56373/abhinav/test-repo/comments?change=4&limit=3&offset=0 + url: http://127.0.0.1:57035/abhinav/test-repo/comments?change=2&limit=3&offset=0 method: GET response: proto: HTTP/1.1 @@ -401,15 +401,15 @@ interactions: "items": [ { "id": 1, - "body": "uXAhcpF8V9XZWbQom2aI0nM6Q9fbiqpd" + "body": "G7bkHTnTfmvCMz6JyfufKQF8PR7a9oqD" }, { "id": 3, - "body": "DU3TnJBDljtJOjrPNPgfJRo44fzPxWxZ" + "body": "6cJi4STnarDSDGWnUBVEQpIQhFUqc2kz" }, { "id": 4, - "body": "WeEXYW6yjMMf0jmnnze12omw5CmTHrDt" + "body": "EFYN40zzvmin2oAU4FPXiHTOmSHUERjl" } ], "offset": 3, @@ -422,22 +422,22 @@ interactions: - application/json status: 200 OK code: 200 - duration: 387.292µs + duration: 1.851541ms - id: 15 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 content_length: 0 - host: 127.0.0.1:56373 + host: 127.0.0.1:57035 form: change: - - "4" + - "2" limit: - "3" offset: - "3" - url: http://127.0.0.1:56373/abhinav/test-repo/comments?change=4&limit=3&offset=3 + url: http://127.0.0.1:57035/abhinav/test-repo/comments?change=2&limit=3&offset=3 method: GET response: proto: HTTP/1.1 @@ -449,15 +449,15 @@ interactions: "items": [ { "id": 5, - "body": "S4IQsdn1dgnUfOJEFb5JEm7kVxLd8oil" + "body": "7372hge5yTtHUySmYNV4PICC1vPFPrXc" }, { "id": 6, - "body": "JNpsluBOeFN8cwri2EMfI8BrYjbArxPf" + "body": "B55eq0pC1RVynm8sYTbagqGiOjUkNVXF" }, { "id": 7, - "body": "FgUJanBcocO1ablzVyYVjDh6fUZbZXyI" + "body": "gnJPLIYBAkZAlb12cOLiEQHOjOBqdiRB" } ], "offset": 6, @@ -470,22 +470,22 @@ interactions: - application/json status: 200 OK code: 200 - duration: 1.042458ms + duration: 1.132917ms - id: 16 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 content_length: 0 - host: 127.0.0.1:56373 + host: 127.0.0.1:57035 form: change: - - "4" + - "2" limit: - "3" offset: - "6" - url: http://127.0.0.1:56373/abhinav/test-repo/comments?change=4&limit=3&offset=6 + url: http://127.0.0.1:57035/abhinav/test-repo/comments?change=2&limit=3&offset=6 method: GET response: proto: HTTP/1.1 @@ -497,15 +497,15 @@ interactions: "items": [ { "id": 8, - "body": "qp1FOZUVrehYPmU311YMEQDrHlJ2BJ40" + "body": "sAuv6hr5p7kb3qIgWI1NtNo6SUhc7OEl" }, { "id": 9, - "body": "sODVHSvcIOhqxyrkgurNH9HMl2b2LSg6" + "body": "uf3v7hCghPBI2gmgBYhuZdqIEAtcwFhO" }, { "id": 10, - "body": "k7NLLLvg5wMj1tasfkFfqdbhqfa8Ah0E" + "body": "jLo35606q1DKggWAlZoeWB0Y7ozVjpwB" } ], "offset": 9 @@ -517,22 +517,22 @@ interactions: - application/json status: 200 OK code: 200 - duration: 1.038417ms + duration: 352.584µs - id: 17 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 content_length: 0 - host: 127.0.0.1:56373 + host: 127.0.0.1:57035 form: change: - - "4" + - "2" limit: - "10" offset: - "0" - url: http://127.0.0.1:56373/abhinav/test-repo/comments?change=4&limit=10&offset=0 + url: http://127.0.0.1:57035/abhinav/test-repo/comments?change=2&limit=10&offset=0 method: GET response: proto: HTTP/1.1 @@ -544,39 +544,39 @@ interactions: "items": [ { "id": 1, - "body": "uXAhcpF8V9XZWbQom2aI0nM6Q9fbiqpd" + "body": "G7bkHTnTfmvCMz6JyfufKQF8PR7a9oqD" }, { "id": 3, - "body": "DU3TnJBDljtJOjrPNPgfJRo44fzPxWxZ" + "body": "6cJi4STnarDSDGWnUBVEQpIQhFUqc2kz" }, { "id": 4, - "body": "WeEXYW6yjMMf0jmnnze12omw5CmTHrDt" + "body": "EFYN40zzvmin2oAU4FPXiHTOmSHUERjl" }, { "id": 5, - "body": "S4IQsdn1dgnUfOJEFb5JEm7kVxLd8oil" + "body": "7372hge5yTtHUySmYNV4PICC1vPFPrXc" }, { "id": 6, - "body": "JNpsluBOeFN8cwri2EMfI8BrYjbArxPf" + "body": "B55eq0pC1RVynm8sYTbagqGiOjUkNVXF" }, { "id": 7, - "body": "FgUJanBcocO1ablzVyYVjDh6fUZbZXyI" + "body": "gnJPLIYBAkZAlb12cOLiEQHOjOBqdiRB" }, { "id": 8, - "body": "qp1FOZUVrehYPmU311YMEQDrHlJ2BJ40" + "body": "sAuv6hr5p7kb3qIgWI1NtNo6SUhc7OEl" }, { "id": 9, - "body": "sODVHSvcIOhqxyrkgurNH9HMl2b2LSg6" + "body": "uf3v7hCghPBI2gmgBYhuZdqIEAtcwFhO" }, { "id": 10, - "body": "k7NLLLvg5wMj1tasfkFfqdbhqfa8Ah0E" + "body": "jLo35606q1DKggWAlZoeWB0Y7ozVjpwB" } ], "offset": 9 @@ -588,4 +588,4 @@ interactions: - application/json status: 200 OK code: 200 - duration: 177.583µs + duration: 3.422792ms diff --git a/internal/forge/shamhub/testdata/fixtures/TestIntegration/ChangesStates.yaml b/internal/forge/shamhub/testdata/fixtures/TestIntegration/ChangesStates.yaml index 32e610d37..0f9f559dc 100644 --- a/internal/forge/shamhub/testdata/fixtures/TestIntegration/ChangesStates.yaml +++ b/internal/forge/shamhub/testdata/fixtures/TestIntegration/ChangesStates.yaml @@ -7,37 +7,37 @@ interactions: proto_major: 1 proto_minor: 1 content_length: 80 - host: 127.0.0.1:56373 - body: '{"subject":"Open jMfwXkYK","body":"Open change","base":"main","head":"jMfwXkYK"}' - url: http://127.0.0.1:56373/abhinav/test-repo/changes + host: 127.0.0.1:57035 + body: '{"subject":"Open phdnd9Ow","body":"Open change","base":"main","head":"phdnd9Ow"}' + url: http://127.0.0.1:57035/abhinav/test-repo/changes method: POST response: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 - content_length: 82 + content_length: 80 body: | { - "number": 15, - "url": "http://127.0.0.1:56374/abhinav/test-repo/change/15" + "number": 9, + "url": "http://127.0.0.1:57036/abhinav/test-repo/change/9" } headers: Content-Length: - - "82" + - "80" Content-Type: - application/json status: 200 OK code: 200 - duration: 13.188042ms + duration: 26.617334ms - id: 1 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 content_length: 84 - host: 127.0.0.1:56373 - body: '{"subject":"Merged C5hzQ5Ik","body":"Merged change","base":"main","head":"C5hzQ5Ik"}' - url: http://127.0.0.1:56373/abhinav/test-repo/changes + host: 127.0.0.1:57035 + body: '{"subject":"Merged 0xd3VrO2","body":"Merged change","base":"main","head":"0xd3VrO2"}' + url: http://127.0.0.1:57035/abhinav/test-repo/changes method: POST response: proto: HTTP/1.1 @@ -46,8 +46,8 @@ interactions: content_length: 82 body: | { - "number": 16, - "url": "http://127.0.0.1:56374/abhinav/test-repo/change/16" + "number": 11, + "url": "http://127.0.0.1:57036/abhinav/test-repo/change/11" } headers: Content-Length: @@ -56,16 +56,16 @@ interactions: - application/json status: 200 OK code: 200 - duration: 13.844667ms + duration: 27.594208ms - id: 2 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 content_length: 84 - host: 127.0.0.1:56373 - body: '{"subject":"Closed IEtiDhFs","body":"Closed change","base":"main","head":"IEtiDhFs"}' - url: http://127.0.0.1:56373/abhinav/test-repo/changes + host: 127.0.0.1:57035 + body: '{"subject":"Closed zUMZc5wS","body":"Closed change","base":"main","head":"zUMZc5wS"}' + url: http://127.0.0.1:57035/abhinav/test-repo/changes method: POST response: proto: HTTP/1.1 @@ -74,8 +74,8 @@ interactions: content_length: 82 body: | { - "number": 18, - "url": "http://127.0.0.1:56374/abhinav/test-repo/change/18" + "number": 13, + "url": "http://127.0.0.1:57036/abhinav/test-repo/change/13" } headers: Content-Length: @@ -84,16 +84,16 @@ interactions: - application/json status: 200 OK code: 200 - duration: 14.069959ms + duration: 26.995792ms - id: 3 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 - content_length: 18 - host: 127.0.0.1:56373 - body: '{"ids":[15,16,18]}' - url: http://127.0.0.1:56373/abhinav/test-repo/change/states + content_length: 17 + host: 127.0.0.1:57035 + body: '{"ids":[9,11,13]}' + url: http://127.0.0.1:57035/abhinav/test-repo/change/states method: POST response: proto: HTTP/1.1 @@ -105,15 +105,15 @@ interactions: "statuses": [ { "state": "open", - "headHash": "84a9e994290ae89ccc93f7d2a03d009b39d103ea" + "headHash": "9af26a9162e8c30d408dcd0e95989dab42b32f54" }, { "state": "merged", - "headHash": "25b03948515094aec6d2cf82537f16d56a1486dc" + "headHash": "e961cf7b9e516673068b87649d0dfaa14bfd8524" }, { "state": "closed", - "headHash": "0c32e505344f156f8aa70189cfd851a1a40765cd" + "headHash": "448f1f47eac33aadb0f4688f42a49ebe88523a4a" } ] } @@ -124,4 +124,4 @@ interactions: - application/json status: 200 OK code: 200 - duration: 10.51575ms + duration: 27.257875ms diff --git a/internal/forge/shamhub/testdata/fixtures/TestIntegration/CommentCountsByChange.yaml b/internal/forge/shamhub/testdata/fixtures/TestIntegration/CommentCountsByChange.yaml index a6c9cab53..041676f62 100644 --- a/internal/forge/shamhub/testdata/fixtures/TestIntegration/CommentCountsByChange.yaml +++ b/internal/forge/shamhub/testdata/fixtures/TestIntegration/CommentCountsByChange.yaml @@ -7,37 +7,37 @@ interactions: proto_major: 1 proto_minor: 1 content_length: 98 - host: 127.0.0.1:56373 - body: '{"subject":"Testing HQWHaq9z","body":"Test PR for comment counts","base":"main","head":"HQWHaq9z"}' - url: http://127.0.0.1:56373/abhinav/test-repo/changes + host: 127.0.0.1:57035 + body: '{"subject":"Testing 5WfSEUpY","body":"Test PR for comment counts","base":"main","head":"5WfSEUpY"}' + url: http://127.0.0.1:57035/abhinav/test-repo/changes method: POST response: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 - content_length: 82 + content_length: 80 body: | { - "number": 11, - "url": "http://127.0.0.1:56374/abhinav/test-repo/change/11" + "number": 7, + "url": "http://127.0.0.1:57036/abhinav/test-repo/change/7" } headers: Content-Length: - - "82" + - "80" Content-Type: - application/json status: 200 OK code: 200 - duration: 28.731083ms + duration: 44.498792ms - id: 1 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 - content_length: 12 - host: 127.0.0.1:56373 - body: '{"ids":[11]}' - url: http://127.0.0.1:56373/abhinav/test-repo/change/comment-counts + content_length: 11 + host: 127.0.0.1:57035 + body: '{"ids":[7]}' + url: http://127.0.0.1:57035/abhinav/test-repo/change/comment-counts method: POST response: proto: HTTP/1.1 @@ -61,4 +61,4 @@ interactions: - application/json status: 200 OK code: 200 - duration: 1.628833ms + duration: 1.488709ms diff --git a/internal/forge/shamhub/testdata/fixtures/TestIntegration/FindChangesByBranchDoesNotExist.yaml b/internal/forge/shamhub/testdata/fixtures/TestIntegration/FindChangesByBranchDoesNotExist.yaml index 4673e14a0..ade3576e1 100644 --- a/internal/forge/shamhub/testdata/fixtures/TestIntegration/FindChangesByBranchDoesNotExist.yaml +++ b/internal/forge/shamhub/testdata/fixtures/TestIntegration/FindChangesByBranchDoesNotExist.yaml @@ -7,13 +7,13 @@ interactions: proto_major: 1 proto_minor: 1 content_length: 0 - host: 127.0.0.1:56373 + host: 127.0.0.1:57035 form: limit: - "10" state: - all - url: http://127.0.0.1:56373/abhinav/test-repo/changes/by-branch/does-not-exist?limit=10&state=all + url: http://127.0.0.1:57035/abhinav/test-repo/changes/by-branch/does-not-exist?limit=10&state=all method: GET response: proto: HTTP/1.1 @@ -29,4 +29,4 @@ interactions: - application/json status: 200 OK code: 200 - duration: 752.916µs + duration: 1.126333ms diff --git a/internal/forge/shamhub/testdata/fixtures/TestIntegration/ListChangeTemplates/NoTemplates.yaml b/internal/forge/shamhub/testdata/fixtures/TestIntegration/ListChangeTemplates/NoTemplates.yaml index 4e2249722..e07556a40 100644 --- a/internal/forge/shamhub/testdata/fixtures/TestIntegration/ListChangeTemplates/NoTemplates.yaml +++ b/internal/forge/shamhub/testdata/fixtures/TestIntegration/ListChangeTemplates/NoTemplates.yaml @@ -7,8 +7,8 @@ interactions: proto_major: 1 proto_minor: 1 content_length: 0 - host: 127.0.0.1:56373 - url: http://127.0.0.1:56373/abhinav/test-repo/change-template + host: 127.0.0.1:57035 + url: http://127.0.0.1:57035/abhinav/test-repo/change-template method: GET response: proto: HTTP/1.1 @@ -24,4 +24,4 @@ interactions: - application/json status: 200 OK code: 200 - duration: 138.274667ms + duration: 353.852042ms diff --git a/internal/forge/shamhub/testdata/fixtures/TestIntegration/ListChangeTemplates/TemplatesPresent.yaml b/internal/forge/shamhub/testdata/fixtures/TestIntegration/ListChangeTemplates/TemplatesPresent.yaml index 2736a773b..0cee6f41c 100644 --- a/internal/forge/shamhub/testdata/fixtures/TestIntegration/ListChangeTemplates/TemplatesPresent.yaml +++ b/internal/forge/shamhub/testdata/fixtures/TestIntegration/ListChangeTemplates/TemplatesPresent.yaml @@ -7,8 +7,8 @@ interactions: proto_major: 1 proto_minor: 1 content_length: 0 - host: 127.0.0.1:56373 - url: http://127.0.0.1:56373/abhinav/test-repo/change-template + host: 127.0.0.1:57035 + url: http://127.0.0.1:57035/abhinav/test-repo/change-template method: GET response: proto: HTTP/1.1 @@ -18,12 +18,12 @@ interactions: body: | [ { - "filename": "1HQqVNZV.md", - "body": "\n" + "filename": "lxoHV53Y.md", + "body": "This is a test template\n" }, { - "filename": "yE3Lj2v5.md", - "body": "This is a test template\n" + "filename": "pcCwLplM.md", + "body": "\n" } ] headers: @@ -33,4 +33,4 @@ interactions: - application/json status: 200 OK code: 200 - duration: 149.63575ms + duration: 294.718584ms diff --git a/internal/forge/shamhub/testdata/fixtures/TestIntegration/SubmitBaseDoesNotExist.yaml b/internal/forge/shamhub/testdata/fixtures/TestIntegration/SubmitBaseDoesNotExist.yaml index 4c536dd39..4d3686cab 100644 --- a/internal/forge/shamhub/testdata/fixtures/TestIntegration/SubmitBaseDoesNotExist.yaml +++ b/internal/forge/shamhub/testdata/fixtures/TestIntegration/SubmitBaseDoesNotExist.yaml @@ -7,9 +7,9 @@ interactions: proto_major: 1 proto_minor: 1 content_length: 106 - host: 127.0.0.1:56373 - body: '{"subject":"Testing vY4xsORW","body":"Test PR with non-existent base","base":"9s9oMX6C","head":"vY4xsORW"}' - url: http://127.0.0.1:56373/abhinav/test-repo/changes + host: 127.0.0.1:57035 + body: '{"subject":"Testing rmcYQqjw","body":"Test PR with non-existent base","base":"gVax4kxU","head":"rmcYQqjw"}' + url: http://127.0.0.1:57035/abhinav/test-repo/changes method: POST response: proto: HTTP/1.1 @@ -25,16 +25,16 @@ interactions: - text/plain; charset=utf-8 status: 400 Bad Request code: 400 - duration: 9.87325ms + duration: 19.742666ms - id: 1 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 content_length: 29 - host: 127.0.0.1:56373 - body: '{"ref":"refs/heads/9s9oMX6C"}' - url: http://127.0.0.1:56373/abhinav/test-repo/ref/exists + host: 127.0.0.1:57035 + body: '{"ref":"refs/heads/gVax4kxU"}' + url: http://127.0.0.1:57035/abhinav/test-repo/ref/exists method: POST response: proto: HTTP/1.1 @@ -52,4 +52,4 @@ interactions: - application/json status: 200 OK code: 200 - duration: 10.2145ms + duration: 22.791416ms diff --git a/internal/forge/shamhub/testdata/fixtures/TestIntegration/SubmitEditAssignees/AddAssignee.yaml b/internal/forge/shamhub/testdata/fixtures/TestIntegration/SubmitEditAssignees/AddAssignee.yaml index aeb06a334..ca6172394 100644 --- a/internal/forge/shamhub/testdata/fixtures/TestIntegration/SubmitEditAssignees/AddAssignee.yaml +++ b/internal/forge/shamhub/testdata/fixtures/TestIntegration/SubmitEditAssignees/AddAssignee.yaml @@ -7,9 +7,9 @@ interactions: proto_major: 1 proto_minor: 1 content_length: 97 - host: 127.0.0.1:56373 - body: '{"subject":"Testing 66MtCOhk","body":"Test PR without assignees","base":"main","head":"66MtCOhk"}' - url: http://127.0.0.1:56373/abhinav/test-repo/changes + host: 127.0.0.1:57035 + body: '{"subject":"Testing 3MZZ40Kb","body":"Test PR without assignees","base":"main","head":"3MZZ40Kb"}' + url: http://127.0.0.1:57035/abhinav/test-repo/changes method: POST response: proto: HTTP/1.1 @@ -18,8 +18,8 @@ interactions: content_length: 82 body: | { - "number": 10, - "url": "http://127.0.0.1:56374/abhinav/test-repo/change/10" + "number": 14, + "url": "http://127.0.0.1:57036/abhinav/test-repo/change/14" } headers: Content-Length: @@ -28,15 +28,15 @@ interactions: - application/json status: 200 OK code: 200 - duration: 25.159916ms + duration: 63.186792ms - id: 1 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 content_length: 0 - host: 127.0.0.1:56373 - url: http://127.0.0.1:56373/abhinav/test-repo/change/10 + host: 127.0.0.1:57035 + url: http://127.0.0.1:57035/abhinav/test-repo/change/14 method: GET response: proto: HTTP/1.1 @@ -45,10 +45,10 @@ interactions: content_length: 518 body: | { - "number": 10, - "html_url": "http://127.0.0.1:56374/abhinav/test-repo/change/10", + "number": 14, + "html_url": "http://127.0.0.1:57036/abhinav/test-repo/change/14", "state": "open", - "title": "Testing 66MtCOhk", + "title": "Testing 3MZZ40Kb", "body": "Test PR without assignees", "base": { "repository": { @@ -56,15 +56,15 @@ interactions: "name": "test-repo" }, "ref": "main", - "sha": "71012226be854d2a77b193ca779abba5cc84cca0" + "sha": "4991ccbcd167930fcee158c37fe0441c8566d8c0" }, "head": { "repository": { "owner": "abhinav", "name": "test-repo" }, - "ref": "66MtCOhk", - "sha": "66a0c50cac60c34e761b18838932a3aab48deac9" + "ref": "3MZZ40Kb", + "sha": "62b50909e6a5b454a2aae35147156f90fc457afd" } } headers: @@ -74,16 +74,16 @@ interactions: - application/json status: 200 OK code: 200 - duration: 22.786459ms + duration: 27.476125ms - id: 2 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 content_length: 39 - host: 127.0.0.1:56373 + host: 127.0.0.1:57035 body: '{"assignees":["assignee1","assignee2"]}' - url: http://127.0.0.1:56373/abhinav/test-repo/change/10 + url: http://127.0.0.1:57035/abhinav/test-repo/change/14 method: PATCH response: proto: HTTP/1.1 @@ -99,15 +99,15 @@ interactions: - application/json status: 200 OK code: 200 - duration: 696.167µs + duration: 166.167µs - id: 3 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 content_length: 0 - host: 127.0.0.1:56373 - url: http://127.0.0.1:56373/abhinav/test-repo/change/10 + host: 127.0.0.1:57035 + url: http://127.0.0.1:57035/abhinav/test-repo/change/14 method: GET response: proto: HTTP/1.1 @@ -116,10 +116,10 @@ interactions: content_length: 573 body: | { - "number": 10, - "html_url": "http://127.0.0.1:56374/abhinav/test-repo/change/10", + "number": 14, + "html_url": "http://127.0.0.1:57036/abhinav/test-repo/change/14", "state": "open", - "title": "Testing 66MtCOhk", + "title": "Testing 3MZZ40Kb", "body": "Test PR without assignees", "base": { "repository": { @@ -127,15 +127,15 @@ interactions: "name": "test-repo" }, "ref": "main", - "sha": "71012226be854d2a77b193ca779abba5cc84cca0" + "sha": "4991ccbcd167930fcee158c37fe0441c8566d8c0" }, "head": { "repository": { "owner": "abhinav", "name": "test-repo" }, - "ref": "66MtCOhk", - "sha": "66a0c50cac60c34e761b18838932a3aab48deac9" + "ref": "3MZZ40Kb", + "sha": "62b50909e6a5b454a2aae35147156f90fc457afd" }, "assignees": [ "assignee1", @@ -149,4 +149,4 @@ interactions: - application/json status: 200 OK code: 200 - duration: 17.645625ms + duration: 25.375709ms diff --git a/internal/forge/shamhub/testdata/fixtures/TestIntegration/SubmitEditAssignees/AddAssigneesOneByOne.yaml b/internal/forge/shamhub/testdata/fixtures/TestIntegration/SubmitEditAssignees/AddAssigneesOneByOne.yaml index 0f7dfd8b2..cfd211e50 100644 --- a/internal/forge/shamhub/testdata/fixtures/TestIntegration/SubmitEditAssignees/AddAssigneesOneByOne.yaml +++ b/internal/forge/shamhub/testdata/fixtures/TestIntegration/SubmitEditAssignees/AddAssigneesOneByOne.yaml @@ -7,9 +7,9 @@ interactions: proto_major: 1 proto_minor: 1 content_length: 97 - host: 127.0.0.1:56373 - body: '{"subject":"Testing Op9WQIRi","body":"Test PR without assignees","base":"main","head":"Op9WQIRi"}' - url: http://127.0.0.1:56373/abhinav/test-repo/changes + host: 127.0.0.1:57035 + body: '{"subject":"Testing igUdjqag","body":"Test PR without assignees","base":"main","head":"igUdjqag"}' + url: http://127.0.0.1:57035/abhinav/test-repo/changes method: POST response: proto: HTTP/1.1 @@ -18,8 +18,8 @@ interactions: content_length: 80 body: | { - "number": 5, - "url": "http://127.0.0.1:56374/abhinav/test-repo/change/5" + "number": 3, + "url": "http://127.0.0.1:57036/abhinav/test-repo/change/3" } headers: Content-Length: @@ -28,16 +28,16 @@ interactions: - application/json status: 200 OK code: 200 - duration: 21.201041ms + duration: 38.723583ms - id: 1 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 content_length: 27 - host: 127.0.0.1:56373 + host: 127.0.0.1:57035 body: '{"assignees":["assignee1"]}' - url: http://127.0.0.1:56373/abhinav/test-repo/change/5 + url: http://127.0.0.1:57035/abhinav/test-repo/change/3 method: PATCH response: proto: HTTP/1.1 @@ -53,16 +53,16 @@ interactions: - application/json status: 200 OK code: 200 - duration: 263.792µs + duration: 1.056125ms - id: 2 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 content_length: 27 - host: 127.0.0.1:56373 + host: 127.0.0.1:57035 body: '{"assignees":["assignee2"]}' - url: http://127.0.0.1:56373/abhinav/test-repo/change/5 + url: http://127.0.0.1:57035/abhinav/test-repo/change/3 method: PATCH response: proto: HTTP/1.1 @@ -78,15 +78,15 @@ interactions: - application/json status: 200 OK code: 200 - duration: 2.75425ms + duration: 597.333µs - id: 3 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 content_length: 0 - host: 127.0.0.1:56373 - url: http://127.0.0.1:56373/abhinav/test-repo/change/5 + host: 127.0.0.1:57035 + url: http://127.0.0.1:57035/abhinav/test-repo/change/3 method: GET response: proto: HTTP/1.1 @@ -95,10 +95,10 @@ interactions: content_length: 571 body: | { - "number": 5, - "html_url": "http://127.0.0.1:56374/abhinav/test-repo/change/5", + "number": 3, + "html_url": "http://127.0.0.1:57036/abhinav/test-repo/change/3", "state": "open", - "title": "Testing Op9WQIRi", + "title": "Testing igUdjqag", "body": "Test PR without assignees", "base": { "repository": { @@ -106,15 +106,15 @@ interactions: "name": "test-repo" }, "ref": "main", - "sha": "71012226be854d2a77b193ca779abba5cc84cca0" + "sha": "df106cd50b11f5b0d7948f26900d32667d644df4" }, "head": { "repository": { "owner": "abhinav", "name": "test-repo" }, - "ref": "Op9WQIRi", - "sha": "34d6de08ed0a392a6ec261c288d5516e65dc2614" + "ref": "igUdjqag", + "sha": "21bead9a53c34ac5cd8ad54b39ef81cbd6fb1985" }, "assignees": [ "assignee1", @@ -128,4 +128,4 @@ interactions: - application/json status: 200 OK code: 200 - duration: 21.133625ms + duration: 35.525ms diff --git a/internal/forge/shamhub/testdata/fixtures/TestIntegration/SubmitEditAssignees/SubmitWithAssignee.yaml b/internal/forge/shamhub/testdata/fixtures/TestIntegration/SubmitEditAssignees/SubmitWithAssignee.yaml index 1bd09cc14..7487bff4f 100644 --- a/internal/forge/shamhub/testdata/fixtures/TestIntegration/SubmitEditAssignees/SubmitWithAssignee.yaml +++ b/internal/forge/shamhub/testdata/fixtures/TestIntegration/SubmitEditAssignees/SubmitWithAssignee.yaml @@ -7,9 +7,9 @@ interactions: proto_major: 1 proto_minor: 1 content_length: 131 - host: 127.0.0.1:56373 - body: '{"subject":"Testing lE3mefp0","body":"Test PR with assignee","base":"main","head":"lE3mefp0","assignees":["assignee1","assignee2"]}' - url: http://127.0.0.1:56373/abhinav/test-repo/changes + host: 127.0.0.1:57035 + body: '{"subject":"Testing ShZbkKGz","body":"Test PR with assignee","base":"main","head":"ShZbkKGz","assignees":["assignee1","assignee2"]}' + url: http://127.0.0.1:57035/abhinav/test-repo/changes method: POST response: proto: HTTP/1.1 @@ -18,8 +18,8 @@ interactions: content_length: 80 body: | { - "number": 7, - "url": "http://127.0.0.1:56374/abhinav/test-repo/change/7" + "number": 6, + "url": "http://127.0.0.1:57036/abhinav/test-repo/change/6" } headers: Content-Length: @@ -28,15 +28,15 @@ interactions: - application/json status: 200 OK code: 200 - duration: 21.594125ms + duration: 39.038709ms - id: 1 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 content_length: 0 - host: 127.0.0.1:56373 - url: http://127.0.0.1:56373/abhinav/test-repo/change/7 + host: 127.0.0.1:57035 + url: http://127.0.0.1:57035/abhinav/test-repo/change/6 method: GET response: proto: HTTP/1.1 @@ -45,10 +45,10 @@ interactions: content_length: 567 body: | { - "number": 7, - "html_url": "http://127.0.0.1:56374/abhinav/test-repo/change/7", + "number": 6, + "html_url": "http://127.0.0.1:57036/abhinav/test-repo/change/6", "state": "open", - "title": "Testing lE3mefp0", + "title": "Testing ShZbkKGz", "body": "Test PR with assignee", "base": { "repository": { @@ -56,15 +56,15 @@ interactions: "name": "test-repo" }, "ref": "main", - "sha": "71012226be854d2a77b193ca779abba5cc84cca0" + "sha": "df106cd50b11f5b0d7948f26900d32667d644df4" }, "head": { "repository": { "owner": "abhinav", "name": "test-repo" }, - "ref": "lE3mefp0", - "sha": "1294690f93a2b746dbb81d60a23b512988633d14" + "ref": "ShZbkKGz", + "sha": "d405649d45daacb7657dd53c7c1b2d6d43fcf185" }, "assignees": [ "assignee1", @@ -78,20 +78,20 @@ interactions: - application/json status: 200 OK code: 200 - duration: 17.238667ms + duration: 34.833583ms - id: 2 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 content_length: 0 - host: 127.0.0.1:56373 + host: 127.0.0.1:57035 form: limit: - "10" state: - all - url: http://127.0.0.1:56373/abhinav/test-repo/changes/by-branch/lE3mefp0?limit=10&state=all + url: http://127.0.0.1:57035/abhinav/test-repo/changes/by-branch/ShZbkKGz?limit=10&state=all method: GET response: proto: HTTP/1.1 @@ -101,10 +101,10 @@ interactions: body: | [ { - "number": 7, - "html_url": "http://127.0.0.1:56374/abhinav/test-repo/change/7", + "number": 6, + "html_url": "http://127.0.0.1:57036/abhinav/test-repo/change/6", "state": "open", - "title": "Testing lE3mefp0", + "title": "Testing ShZbkKGz", "body": "Test PR with assignee", "base": { "repository": { @@ -112,15 +112,15 @@ interactions: "name": "test-repo" }, "ref": "main", - "sha": "71012226be854d2a77b193ca779abba5cc84cca0" + "sha": "df106cd50b11f5b0d7948f26900d32667d644df4" }, "head": { "repository": { "owner": "abhinav", "name": "test-repo" }, - "ref": "lE3mefp0", - "sha": "1294690f93a2b746dbb81d60a23b512988633d14" + "ref": "ShZbkKGz", + "sha": "d405649d45daacb7657dd53c7c1b2d6d43fcf185" }, "assignees": [ "assignee1", @@ -135,4 +135,4 @@ interactions: - application/json status: 200 OK code: 200 - duration: 20.395ms + duration: 38.77125ms diff --git a/internal/forge/shamhub/testdata/fixtures/TestIntegration/SubmitEditBase.yaml b/internal/forge/shamhub/testdata/fixtures/TestIntegration/SubmitEditBase.yaml index ed56e8e18..6c78b8b22 100644 --- a/internal/forge/shamhub/testdata/fixtures/TestIntegration/SubmitEditBase.yaml +++ b/internal/forge/shamhub/testdata/fixtures/TestIntegration/SubmitEditBase.yaml @@ -7,83 +7,83 @@ interactions: proto_major: 1 proto_minor: 1 content_length: 100 - host: 127.0.0.1:56373 - body: '{"subject":"Testing 9YbzXae4","body":"Test PR with custom base","base":"t8XzNN0X","head":"9YbzXae4"}' - url: http://127.0.0.1:56373/abhinav/test-repo/changes + host: 127.0.0.1:57035 + body: '{"subject":"Testing m7yF4ync","body":"Test PR with custom base","base":"k2EK1wis","head":"m7yF4ync"}' + url: http://127.0.0.1:57035/abhinav/test-repo/changes method: POST response: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 - content_length: 80 + content_length: 82 body: | { - "number": 8, - "url": "http://127.0.0.1:56374/abhinav/test-repo/change/8" + "number": 15, + "url": "http://127.0.0.1:57036/abhinav/test-repo/change/15" } headers: Content-Length: - - "80" + - "82" Content-Type: - application/json status: 200 OK code: 200 - duration: 23.763167ms + duration: 25.747833ms - id: 1 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 content_length: 0 - host: 127.0.0.1:56373 - url: http://127.0.0.1:56373/abhinav/test-repo/change/8 + host: 127.0.0.1:57035 + url: http://127.0.0.1:57035/abhinav/test-repo/change/15 method: GET response: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 - content_length: 519 + content_length: 521 body: | { - "number": 8, - "html_url": "http://127.0.0.1:56374/abhinav/test-repo/change/8", + "number": 15, + "html_url": "http://127.0.0.1:57036/abhinav/test-repo/change/15", "state": "open", - "title": "Testing 9YbzXae4", + "title": "Testing m7yF4ync", "body": "Test PR with custom base", "base": { "repository": { "owner": "abhinav", "name": "test-repo" }, - "ref": "t8XzNN0X", - "sha": "71012226be854d2a77b193ca779abba5cc84cca0" + "ref": "k2EK1wis", + "sha": "df106cd50b11f5b0d7948f26900d32667d644df4" }, "head": { "repository": { "owner": "abhinav", "name": "test-repo" }, - "ref": "9YbzXae4", - "sha": "a3fc1801625662da2cc43a337ee7ba729a73d732" + "ref": "m7yF4ync", + "sha": "7f6653dbd8690b191e169c865a74e56d0d834f6f" } } headers: Content-Length: - - "519" + - "521" Content-Type: - application/json status: 200 OK code: 200 - duration: 19.21925ms + duration: 24.243167ms - id: 2 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 content_length: 15 - host: 127.0.0.1:56373 + host: 127.0.0.1:57035 body: '{"base":"main"}' - url: http://127.0.0.1:56373/abhinav/test-repo/change/8 + url: http://127.0.0.1:57035/abhinav/test-repo/change/15 method: PATCH response: proto: HTTP/1.1 @@ -99,27 +99,27 @@ interactions: - application/json status: 200 OK code: 200 - duration: 485.75µs + duration: 200.25µs - id: 3 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 content_length: 0 - host: 127.0.0.1:56373 - url: http://127.0.0.1:56373/abhinav/test-repo/change/8 + host: 127.0.0.1:57035 + url: http://127.0.0.1:57035/abhinav/test-repo/change/15 method: GET response: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 - content_length: 515 + content_length: 517 body: | { - "number": 8, - "html_url": "http://127.0.0.1:56374/abhinav/test-repo/change/8", + "number": 15, + "html_url": "http://127.0.0.1:57036/abhinav/test-repo/change/15", "state": "open", - "title": "Testing 9YbzXae4", + "title": "Testing m7yF4ync", "body": "Test PR with custom base", "base": { "repository": { @@ -127,22 +127,22 @@ interactions: "name": "test-repo" }, "ref": "main", - "sha": "71012226be854d2a77b193ca779abba5cc84cca0" + "sha": "4991ccbcd167930fcee158c37fe0441c8566d8c0" }, "head": { "repository": { "owner": "abhinav", "name": "test-repo" }, - "ref": "9YbzXae4", - "sha": "a3fc1801625662da2cc43a337ee7ba729a73d732" + "ref": "m7yF4ync", + "sha": "7f6653dbd8690b191e169c865a74e56d0d834f6f" } } headers: Content-Length: - - "515" + - "517" Content-Type: - application/json status: 200 OK code: 200 - duration: 17.355333ms + duration: 23.167083ms diff --git a/internal/forge/shamhub/testdata/fixtures/TestIntegration/SubmitEditChange.yaml b/internal/forge/shamhub/testdata/fixtures/TestIntegration/SubmitEditChange.yaml index e0876df1f..3faa19113 100644 --- a/internal/forge/shamhub/testdata/fixtures/TestIntegration/SubmitEditChange.yaml +++ b/internal/forge/shamhub/testdata/fixtures/TestIntegration/SubmitEditChange.yaml @@ -7,9 +7,9 @@ interactions: proto_major: 1 proto_minor: 1 content_length: 79 - host: 127.0.0.1:56373 - body: '{"subject":"Testing RowsHzO8","body":"Test PR","base":"main","head":"RowsHzO8"}' - url: http://127.0.0.1:56373/abhinav/test-repo/changes + host: 127.0.0.1:57035 + body: '{"subject":"Testing gz0Insmn","body":"Test PR","base":"main","head":"gz0Insmn"}' + url: http://127.0.0.1:57035/abhinav/test-repo/changes method: POST response: proto: HTTP/1.1 @@ -19,7 +19,7 @@ interactions: body: | { "number": 1, - "url": "http://127.0.0.1:56374/abhinav/test-repo/change/1" + "url": "http://127.0.0.1:57036/abhinav/test-repo/change/1" } headers: Content-Length: @@ -28,15 +28,15 @@ interactions: - application/json status: 200 OK code: 200 - duration: 22.12625ms + duration: 41.156208ms - id: 1 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 content_length: 0 - host: 127.0.0.1:56373 - url: http://127.0.0.1:56373/abhinav/test-repo/change/1 + host: 127.0.0.1:57035 + url: http://127.0.0.1:57035/abhinav/test-repo/change/1 method: GET response: proto: HTTP/1.1 @@ -46,9 +46,9 @@ interactions: body: | { "number": 1, - "html_url": "http://127.0.0.1:56374/abhinav/test-repo/change/1", + "html_url": "http://127.0.0.1:57036/abhinav/test-repo/change/1", "state": "open", - "title": "Testing RowsHzO8", + "title": "Testing gz0Insmn", "body": "Test PR", "base": { "repository": { @@ -56,15 +56,15 @@ interactions: "name": "test-repo" }, "ref": "main", - "sha": "71012226be854d2a77b193ca779abba5cc84cca0" + "sha": "df106cd50b11f5b0d7948f26900d32667d644df4" }, "head": { "repository": { "owner": "abhinav", "name": "test-repo" }, - "ref": "RowsHzO8", - "sha": "1ee3894a24c031b5d053a0b8bb25a9182fd77604" + "ref": "gz0Insmn", + "sha": "bc8c96b8904897bd058dc097ce3a93137c9fc55a" } } headers: @@ -74,20 +74,20 @@ interactions: - application/json status: 200 OK code: 200 - duration: 18.941208ms + duration: 36.409667ms - id: 2 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 content_length: 0 - host: 127.0.0.1:56373 + host: 127.0.0.1:57035 form: limit: - "10" state: - all - url: http://127.0.0.1:56373/abhinav/test-repo/changes/by-branch/RowsHzO8?limit=10&state=all + url: http://127.0.0.1:57035/abhinav/test-repo/changes/by-branch/gz0Insmn?limit=10&state=all method: GET response: proto: HTTP/1.1 @@ -98,9 +98,9 @@ interactions: [ { "number": 1, - "html_url": "http://127.0.0.1:56374/abhinav/test-repo/change/1", + "html_url": "http://127.0.0.1:57036/abhinav/test-repo/change/1", "state": "open", - "title": "Testing RowsHzO8", + "title": "Testing gz0Insmn", "body": "Test PR", "base": { "repository": { @@ -108,15 +108,15 @@ interactions: "name": "test-repo" }, "ref": "main", - "sha": "71012226be854d2a77b193ca779abba5cc84cca0" + "sha": "df106cd50b11f5b0d7948f26900d32667d644df4" }, "head": { "repository": { "owner": "abhinav", "name": "test-repo" }, - "ref": "RowsHzO8", - "sha": "1ee3894a24c031b5d053a0b8bb25a9182fd77604" + "ref": "gz0Insmn", + "sha": "bc8c96b8904897bd058dc097ce3a93137c9fc55a" } } ] @@ -127,4 +127,4 @@ interactions: - application/json status: 200 OK code: 200 - duration: 16.2305ms + duration: 37.373625ms diff --git a/internal/forge/shamhub/testdata/fixtures/TestIntegration/SubmitEditDraft.yaml b/internal/forge/shamhub/testdata/fixtures/TestIntegration/SubmitEditDraft.yaml index 5114cb40a..46142f166 100644 --- a/internal/forge/shamhub/testdata/fixtures/TestIntegration/SubmitEditDraft.yaml +++ b/internal/forge/shamhub/testdata/fixtures/TestIntegration/SubmitEditDraft.yaml @@ -7,49 +7,49 @@ interactions: proto_major: 1 proto_minor: 1 content_length: 98 - host: 127.0.0.1:56373 - body: '{"subject":"Testing pCyU7Tpe","body":"Test draft PR","base":"main","head":"pCyU7Tpe","draft":true}' - url: http://127.0.0.1:56373/abhinav/test-repo/changes + host: 127.0.0.1:57035 + body: '{"subject":"Testing MxSsq1Kd","body":"Test draft PR","base":"main","head":"MxSsq1Kd","draft":true}' + url: http://127.0.0.1:57035/abhinav/test-repo/changes method: POST response: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 - content_length: 80 + content_length: 82 body: | { - "number": 2, - "url": "http://127.0.0.1:56374/abhinav/test-repo/change/2" + "number": 12, + "url": "http://127.0.0.1:57036/abhinav/test-repo/change/12" } headers: Content-Length: - - "80" + - "82" Content-Type: - application/json status: 200 OK code: 200 - duration: 22.713917ms + duration: 27.033542ms - id: 1 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 content_length: 0 - host: 127.0.0.1:56373 - url: http://127.0.0.1:56373/abhinav/test-repo/change/2 + host: 127.0.0.1:57035 + url: http://127.0.0.1:57035/abhinav/test-repo/change/12 method: GET response: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 - content_length: 521 + content_length: 523 body: | { - "number": 2, - "html_url": "http://127.0.0.1:56374/abhinav/test-repo/change/2", + "number": 12, + "html_url": "http://127.0.0.1:57036/abhinav/test-repo/change/12", "draft": true, "state": "open", - "title": "Testing pCyU7Tpe", + "title": "Testing MxSsq1Kd", "body": "Test draft PR", "base": { "repository": { @@ -57,34 +57,34 @@ interactions: "name": "test-repo" }, "ref": "main", - "sha": "71012226be854d2a77b193ca779abba5cc84cca0" + "sha": "df106cd50b11f5b0d7948f26900d32667d644df4" }, "head": { "repository": { "owner": "abhinav", "name": "test-repo" }, - "ref": "pCyU7Tpe", - "sha": "7bd9a65f890645f1b36eb13dd6a622b6c4b32b13" + "ref": "MxSsq1Kd", + "sha": "8cac016047ff1af09f6ff8b2f728f316c2cd9a69" } } headers: Content-Length: - - "521" + - "523" Content-Type: - application/json status: 200 OK code: 200 - duration: 20.71025ms + duration: 24.692083ms - id: 2 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 content_length: 15 - host: 127.0.0.1:56373 + host: 127.0.0.1:57035 body: '{"draft":false}' - url: http://127.0.0.1:56373/abhinav/test-repo/change/2 + url: http://127.0.0.1:57035/abhinav/test-repo/change/12 method: PATCH response: proto: HTTP/1.1 @@ -100,27 +100,27 @@ interactions: - application/json status: 200 OK code: 200 - duration: 134.583µs + duration: 29.24575ms - id: 3 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 content_length: 0 - host: 127.0.0.1:56373 - url: http://127.0.0.1:56373/abhinav/test-repo/change/2 + host: 127.0.0.1:57035 + url: http://127.0.0.1:57035/abhinav/test-repo/change/12 method: GET response: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 - content_length: 504 + content_length: 506 body: | { - "number": 2, - "html_url": "http://127.0.0.1:56374/abhinav/test-repo/change/2", + "number": 12, + "html_url": "http://127.0.0.1:57036/abhinav/test-repo/change/12", "state": "open", - "title": "Testing pCyU7Tpe", + "title": "Testing MxSsq1Kd", "body": "Test draft PR", "base": { "repository": { @@ -128,34 +128,34 @@ interactions: "name": "test-repo" }, "ref": "main", - "sha": "71012226be854d2a77b193ca779abba5cc84cca0" + "sha": "4991ccbcd167930fcee158c37fe0441c8566d8c0" }, "head": { "repository": { "owner": "abhinav", "name": "test-repo" }, - "ref": "pCyU7Tpe", - "sha": "7bd9a65f890645f1b36eb13dd6a622b6c4b32b13" + "ref": "MxSsq1Kd", + "sha": "8cac016047ff1af09f6ff8b2f728f316c2cd9a69" } } headers: Content-Length: - - "504" + - "506" Content-Type: - application/json status: 200 OK code: 200 - duration: 17.1405ms + duration: 27.589334ms - id: 4 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 content_length: 14 - host: 127.0.0.1:56373 + host: 127.0.0.1:57035 body: '{"draft":true}' - url: http://127.0.0.1:56373/abhinav/test-repo/change/2 + url: http://127.0.0.1:57035/abhinav/test-repo/change/12 method: PATCH response: proto: HTTP/1.1 @@ -171,28 +171,28 @@ interactions: - application/json status: 200 OK code: 200 - duration: 1.807125ms + duration: 205.583µs - id: 5 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 content_length: 0 - host: 127.0.0.1:56373 - url: http://127.0.0.1:56373/abhinav/test-repo/change/2 + host: 127.0.0.1:57035 + url: http://127.0.0.1:57035/abhinav/test-repo/change/12 method: GET response: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 - content_length: 521 + content_length: 523 body: | { - "number": 2, - "html_url": "http://127.0.0.1:56374/abhinav/test-repo/change/2", + "number": 12, + "html_url": "http://127.0.0.1:57036/abhinav/test-repo/change/12", "draft": true, "state": "open", - "title": "Testing pCyU7Tpe", + "title": "Testing MxSsq1Kd", "body": "Test draft PR", "base": { "repository": { @@ -200,22 +200,22 @@ interactions: "name": "test-repo" }, "ref": "main", - "sha": "71012226be854d2a77b193ca779abba5cc84cca0" + "sha": "4991ccbcd167930fcee158c37fe0441c8566d8c0" }, "head": { "repository": { "owner": "abhinav", "name": "test-repo" }, - "ref": "pCyU7Tpe", - "sha": "7bd9a65f890645f1b36eb13dd6a622b6c4b32b13" + "ref": "MxSsq1Kd", + "sha": "8cac016047ff1af09f6ff8b2f728f316c2cd9a69" } } headers: Content-Length: - - "521" + - "523" Content-Type: - application/json status: 200 OK code: 200 - duration: 20.676166ms + duration: 26.078375ms diff --git a/internal/forge/shamhub/testdata/fixtures/TestIntegration/SubmitEditLabels.yaml b/internal/forge/shamhub/testdata/fixtures/TestIntegration/SubmitEditLabels.yaml index 7b515d983..7fd0d143a 100644 --- a/internal/forge/shamhub/testdata/fixtures/TestIntegration/SubmitEditLabels.yaml +++ b/internal/forge/shamhub/testdata/fixtures/TestIntegration/SubmitEditLabels.yaml @@ -7,9 +7,9 @@ interactions: proto_major: 1 proto_minor: 1 content_length: 113 - host: 127.0.0.1:56373 - body: '{"subject":"Testing jbBnJuHT","body":"Test PR with labels","base":"main","head":"jbBnJuHT","labels":["QcHb0icn"]}' - url: http://127.0.0.1:56373/abhinav/test-repo/changes + host: 127.0.0.1:57035 + body: '{"subject":"Testing zoK34kdM","body":"Test PR with labels","base":"main","head":"zoK34kdM","labels":["HLZfQoCE"]}' + url: http://127.0.0.1:57035/abhinav/test-repo/changes method: POST response: proto: HTTP/1.1 @@ -18,8 +18,8 @@ interactions: content_length: 80 body: | { - "number": 6, - "url": "http://127.0.0.1:56374/abhinav/test-repo/change/6" + "number": 4, + "url": "http://127.0.0.1:57036/abhinav/test-repo/change/4" } headers: Content-Length: @@ -28,15 +28,15 @@ interactions: - application/json status: 200 OK code: 200 - duration: 21.992708ms + duration: 40.03625ms - id: 1 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 content_length: 0 - host: 127.0.0.1:56373 - url: http://127.0.0.1:56373/abhinav/test-repo/change/6 + host: 127.0.0.1:57035 + url: http://127.0.0.1:57035/abhinav/test-repo/change/4 method: GET response: proto: HTTP/1.1 @@ -45,10 +45,10 @@ interactions: content_length: 544 body: | { - "number": 6, - "html_url": "http://127.0.0.1:56374/abhinav/test-repo/change/6", + "number": 4, + "html_url": "http://127.0.0.1:57036/abhinav/test-repo/change/4", "state": "open", - "title": "Testing jbBnJuHT", + "title": "Testing zoK34kdM", "body": "Test PR with labels", "base": { "repository": { @@ -56,18 +56,18 @@ interactions: "name": "test-repo" }, "ref": "main", - "sha": "71012226be854d2a77b193ca779abba5cc84cca0" + "sha": "df106cd50b11f5b0d7948f26900d32667d644df4" }, "head": { "repository": { "owner": "abhinav", "name": "test-repo" }, - "ref": "jbBnJuHT", - "sha": "c34dbee79699111d2299f1fd5737e5535ae1f643" + "ref": "zoK34kdM", + "sha": "17075efd3563a350d5679d77009663e4a7b675f9" }, "labels": [ - "QcHb0icn" + "HLZfQoCE" ] } headers: @@ -77,16 +77,16 @@ interactions: - application/json status: 200 OK code: 200 - duration: 15.358041ms + duration: 38.122542ms - id: 2 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 content_length: 23 - host: 127.0.0.1:56373 - body: '{"labels":["820svnw8"]}' - url: http://127.0.0.1:56373/abhinav/test-repo/change/6 + host: 127.0.0.1:57035 + body: '{"labels":["JdJJispW"]}' + url: http://127.0.0.1:57035/abhinav/test-repo/change/4 method: PATCH response: proto: HTTP/1.1 @@ -102,16 +102,16 @@ interactions: - application/json status: 200 OK code: 200 - duration: 1.308292ms + duration: 625.125µs - id: 3 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 content_length: 34 - host: 127.0.0.1:56373 - body: '{"labels":["820svnw8","bUnh1ONJ"]}' - url: http://127.0.0.1:56373/abhinav/test-repo/change/6 + host: 127.0.0.1:57035 + body: '{"labels":["JdJJispW","fgvJffiW"]}' + url: http://127.0.0.1:57035/abhinav/test-repo/change/4 method: PATCH response: proto: HTTP/1.1 @@ -127,20 +127,20 @@ interactions: - application/json status: 200 OK code: 200 - duration: 242.25µs + duration: 592.958µs - id: 4 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 content_length: 0 - host: 127.0.0.1:56373 + host: 127.0.0.1:57035 form: limit: - "10" state: - all - url: http://127.0.0.1:56373/abhinav/test-repo/changes/by-branch/jbBnJuHT?limit=10&state=all + url: http://127.0.0.1:57035/abhinav/test-repo/changes/by-branch/zoK34kdM?limit=10&state=all method: GET response: proto: HTTP/1.1 @@ -150,10 +150,10 @@ interactions: body: | [ { - "number": 6, - "html_url": "http://127.0.0.1:56374/abhinav/test-repo/change/6", + "number": 4, + "html_url": "http://127.0.0.1:57036/abhinav/test-repo/change/4", "state": "open", - "title": "Testing jbBnJuHT", + "title": "Testing zoK34kdM", "body": "Test PR with labels", "base": { "repository": { @@ -161,20 +161,20 @@ interactions: "name": "test-repo" }, "ref": "main", - "sha": "71012226be854d2a77b193ca779abba5cc84cca0" + "sha": "df106cd50b11f5b0d7948f26900d32667d644df4" }, "head": { "repository": { "owner": "abhinav", "name": "test-repo" }, - "ref": "jbBnJuHT", - "sha": "c34dbee79699111d2299f1fd5737e5535ae1f643" + "ref": "zoK34kdM", + "sha": "17075efd3563a350d5679d77009663e4a7b675f9" }, "labels": [ - "QcHb0icn", - "820svnw8", - "bUnh1ONJ" + "HLZfQoCE", + "JdJJispW", + "fgvJffiW" ] } ] @@ -185,4 +185,4 @@ interactions: - application/json status: 200 OK code: 200 - duration: 20.795292ms + duration: 34.247833ms diff --git a/internal/forge/shamhub/testdata/fixtures/TestIntegration/SubmitEditReviewers/AddReviewer.yaml b/internal/forge/shamhub/testdata/fixtures/TestIntegration/SubmitEditReviewers/AddReviewer.yaml index a9ce1ed31..e5511ece0 100644 --- a/internal/forge/shamhub/testdata/fixtures/TestIntegration/SubmitEditReviewers/AddReviewer.yaml +++ b/internal/forge/shamhub/testdata/fixtures/TestIntegration/SubmitEditReviewers/AddReviewer.yaml @@ -7,9 +7,9 @@ interactions: proto_major: 1 proto_minor: 1 content_length: 97 - host: 127.0.0.1:56373 - body: '{"subject":"Testing qS0oWVxR","body":"Test PR without reviewers","base":"main","head":"qS0oWVxR"}' - url: http://127.0.0.1:56373/abhinav/test-repo/changes + host: 127.0.0.1:57035 + body: '{"subject":"Testing hE7bVCmZ","body":"Test PR without reviewers","base":"main","head":"hE7bVCmZ"}' + url: http://127.0.0.1:57035/abhinav/test-repo/changes method: POST response: proto: HTTP/1.1 @@ -18,8 +18,8 @@ interactions: content_length: 82 body: | { - "number": 17, - "url": "http://127.0.0.1:56374/abhinav/test-repo/change/17" + "number": 10, + "url": "http://127.0.0.1:57036/abhinav/test-repo/change/10" } headers: Content-Length: @@ -28,15 +28,15 @@ interactions: - application/json status: 200 OK code: 200 - duration: 13.741459ms + duration: 26.87825ms - id: 1 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 content_length: 0 - host: 127.0.0.1:56373 - url: http://127.0.0.1:56373/abhinav/test-repo/change/17 + host: 127.0.0.1:57035 + url: http://127.0.0.1:57035/abhinav/test-repo/change/10 method: GET response: proto: HTTP/1.1 @@ -45,10 +45,10 @@ interactions: content_length: 518 body: | { - "number": 17, - "html_url": "http://127.0.0.1:56374/abhinav/test-repo/change/17", + "number": 10, + "html_url": "http://127.0.0.1:57036/abhinav/test-repo/change/10", "state": "open", - "title": "Testing qS0oWVxR", + "title": "Testing hE7bVCmZ", "body": "Test PR without reviewers", "base": { "repository": { @@ -56,15 +56,15 @@ interactions: "name": "test-repo" }, "ref": "main", - "sha": "71012226be854d2a77b193ca779abba5cc84cca0" + "sha": "df106cd50b11f5b0d7948f26900d32667d644df4" }, "head": { "repository": { "owner": "abhinav", "name": "test-repo" }, - "ref": "qS0oWVxR", - "sha": "d10f53257e22f018a3d5d54780611749d959d3ed" + "ref": "hE7bVCmZ", + "sha": "4803ddbf5166b633c59944d886b86488a0dfaca0" } } headers: @@ -74,16 +74,16 @@ interactions: - application/json status: 200 OK code: 200 - duration: 13.343458ms + duration: 26.924667ms - id: 2 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 content_length: 39 - host: 127.0.0.1:56373 + host: 127.0.0.1:57035 body: '{"reviewers":["reviewer1","reviewer2"]}' - url: http://127.0.0.1:56373/abhinav/test-repo/change/17 + url: http://127.0.0.1:57035/abhinav/test-repo/change/10 method: PATCH response: proto: HTTP/1.1 @@ -99,15 +99,15 @@ interactions: - application/json status: 200 OK code: 200 - duration: 20.163792ms + duration: 372µs - id: 3 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 content_length: 0 - host: 127.0.0.1:56373 - url: http://127.0.0.1:56373/abhinav/test-repo/change/17 + host: 127.0.0.1:57035 + url: http://127.0.0.1:57035/abhinav/test-repo/change/10 method: GET response: proto: HTTP/1.1 @@ -116,10 +116,10 @@ interactions: content_length: 583 body: | { - "number": 17, - "html_url": "http://127.0.0.1:56374/abhinav/test-repo/change/17", + "number": 10, + "html_url": "http://127.0.0.1:57036/abhinav/test-repo/change/10", "state": "open", - "title": "Testing qS0oWVxR", + "title": "Testing hE7bVCmZ", "body": "Test PR without reviewers", "base": { "repository": { @@ -127,15 +127,15 @@ interactions: "name": "test-repo" }, "ref": "main", - "sha": "78e7fffc2e2f2b050db2efb7f3de43be063e31f3" + "sha": "df106cd50b11f5b0d7948f26900d32667d644df4" }, "head": { "repository": { "owner": "abhinav", "name": "test-repo" }, - "ref": "qS0oWVxR", - "sha": "d10f53257e22f018a3d5d54780611749d959d3ed" + "ref": "hE7bVCmZ", + "sha": "4803ddbf5166b633c59944d886b86488a0dfaca0" }, "requested_reviewers": [ "reviewer1", @@ -149,4 +149,4 @@ interactions: - application/json status: 200 OK code: 200 - duration: 21.720042ms + duration: 25.963667ms diff --git a/internal/forge/shamhub/testdata/fixtures/TestIntegration/SubmitEditReviewers/AddReviewersOneByOne.yaml b/internal/forge/shamhub/testdata/fixtures/TestIntegration/SubmitEditReviewers/AddReviewersOneByOne.yaml index e2a72c93e..43ac4336f 100644 --- a/internal/forge/shamhub/testdata/fixtures/TestIntegration/SubmitEditReviewers/AddReviewersOneByOne.yaml +++ b/internal/forge/shamhub/testdata/fixtures/TestIntegration/SubmitEditReviewers/AddReviewersOneByOne.yaml @@ -7,48 +7,48 @@ interactions: proto_major: 1 proto_minor: 1 content_length: 97 - host: 127.0.0.1:56373 - body: '{"subject":"Testing sN0uOM0J","body":"Test PR without reviewers","base":"main","head":"sN0uOM0J"}' - url: http://127.0.0.1:56373/abhinav/test-repo/changes + host: 127.0.0.1:57035 + body: '{"subject":"Testing ypPdbssG","body":"Test PR without reviewers","base":"main","head":"ypPdbssG"}' + url: http://127.0.0.1:57035/abhinav/test-repo/changes method: POST response: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 - content_length: 82 + content_length: 80 body: | { - "number": 14, - "url": "http://127.0.0.1:56374/abhinav/test-repo/change/14" + "number": 8, + "url": "http://127.0.0.1:57036/abhinav/test-repo/change/8" } headers: Content-Length: - - "82" + - "80" Content-Type: - application/json status: 200 OK code: 200 - duration: 14.613166ms + duration: 46.742041ms - id: 1 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 content_length: 0 - host: 127.0.0.1:56373 - url: http://127.0.0.1:56373/abhinav/test-repo/change/14 + host: 127.0.0.1:57035 + url: http://127.0.0.1:57035/abhinav/test-repo/change/8 method: GET response: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 - content_length: 518 + content_length: 516 body: | { - "number": 14, - "html_url": "http://127.0.0.1:56374/abhinav/test-repo/change/14", + "number": 8, + "html_url": "http://127.0.0.1:57036/abhinav/test-repo/change/8", "state": "open", - "title": "Testing sN0uOM0J", + "title": "Testing ypPdbssG", "body": "Test PR without reviewers", "base": { "repository": { @@ -56,34 +56,34 @@ interactions: "name": "test-repo" }, "ref": "main", - "sha": "71012226be854d2a77b193ca779abba5cc84cca0" + "sha": "df106cd50b11f5b0d7948f26900d32667d644df4" }, "head": { "repository": { "owner": "abhinav", "name": "test-repo" }, - "ref": "sN0uOM0J", - "sha": "fe1856b3db7f006918e699a1c316e92ad3342d93" + "ref": "ypPdbssG", + "sha": "6e27e6dde6045330307119fc608f11a3192bb742" } } headers: Content-Length: - - "518" + - "516" Content-Type: - application/json status: 200 OK code: 200 - duration: 11.315875ms + duration: 37.956792ms - id: 2 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 content_length: 27 - host: 127.0.0.1:56373 + host: 127.0.0.1:57035 body: '{"reviewers":["reviewer1"]}' - url: http://127.0.0.1:56373/abhinav/test-repo/change/14 + url: http://127.0.0.1:57035/abhinav/test-repo/change/8 method: PATCH response: proto: HTTP/1.1 @@ -99,16 +99,16 @@ interactions: - application/json status: 200 OK code: 200 - duration: 415.5µs + duration: 928.584µs - id: 3 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 content_length: 27 - host: 127.0.0.1:56373 + host: 127.0.0.1:57035 body: '{"reviewers":["reviewer2"]}' - url: http://127.0.0.1:56373/abhinav/test-repo/change/14 + url: http://127.0.0.1:57035/abhinav/test-repo/change/8 method: PATCH response: proto: HTTP/1.1 @@ -124,27 +124,27 @@ interactions: - application/json status: 200 OK code: 200 - duration: 102.334µs + duration: 1.520459ms - id: 4 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 content_length: 0 - host: 127.0.0.1:56373 - url: http://127.0.0.1:56373/abhinav/test-repo/change/14 + host: 127.0.0.1:57035 + url: http://127.0.0.1:57035/abhinav/test-repo/change/8 method: GET response: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 - content_length: 583 + content_length: 581 body: | { - "number": 14, - "html_url": "http://127.0.0.1:56374/abhinav/test-repo/change/14", + "number": 8, + "html_url": "http://127.0.0.1:57036/abhinav/test-repo/change/8", "state": "open", - "title": "Testing sN0uOM0J", + "title": "Testing ypPdbssG", "body": "Test PR without reviewers", "base": { "repository": { @@ -152,15 +152,15 @@ interactions: "name": "test-repo" }, "ref": "main", - "sha": "71012226be854d2a77b193ca779abba5cc84cca0" + "sha": "df106cd50b11f5b0d7948f26900d32667d644df4" }, "head": { "repository": { "owner": "abhinav", "name": "test-repo" }, - "ref": "sN0uOM0J", - "sha": "fe1856b3db7f006918e699a1c316e92ad3342d93" + "ref": "ypPdbssG", + "sha": "6e27e6dde6045330307119fc608f11a3192bb742" }, "requested_reviewers": [ "reviewer1", @@ -169,9 +169,9 @@ interactions: } headers: Content-Length: - - "583" + - "581" Content-Type: - application/json status: 200 OK code: 200 - duration: 11.028083ms + duration: 38.124833ms diff --git a/internal/forge/shamhub/testdata/fixtures/TestIntegration/SubmitEditReviewers/SubmitWithReviewer.yaml b/internal/forge/shamhub/testdata/fixtures/TestIntegration/SubmitEditReviewers/SubmitWithReviewer.yaml index 0c837343b..a8df4a6f2 100644 --- a/internal/forge/shamhub/testdata/fixtures/TestIntegration/SubmitEditReviewers/SubmitWithReviewer.yaml +++ b/internal/forge/shamhub/testdata/fixtures/TestIntegration/SubmitEditReviewers/SubmitWithReviewer.yaml @@ -7,54 +7,54 @@ interactions: proto_major: 1 proto_minor: 1 content_length: 131 - host: 127.0.0.1:56373 - body: '{"subject":"Testing 4oj7KI1p","body":"Test PR with reviewer","base":"main","head":"4oj7KI1p","reviewers":["reviewer1","reviewer2"]}' - url: http://127.0.0.1:56373/abhinav/test-repo/changes + host: 127.0.0.1:57035 + body: '{"subject":"Testing jPM09bmi","body":"Test PR with reviewer","base":"main","head":"jPM09bmi","reviewers":["reviewer1","reviewer2"]}' + url: http://127.0.0.1:57035/abhinav/test-repo/changes method: POST response: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 - content_length: 82 + content_length: 80 body: | { - "number": 13, - "url": "http://127.0.0.1:56374/abhinav/test-repo/change/13" + "number": 5, + "url": "http://127.0.0.1:57036/abhinav/test-repo/change/5" } headers: Content-Length: - - "82" + - "80" Content-Type: - application/json status: 200 OK code: 200 - duration: 23.097875ms + duration: 42.211167ms - id: 1 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 content_length: 0 - host: 127.0.0.1:56373 + host: 127.0.0.1:57035 form: limit: - "10" state: - all - url: http://127.0.0.1:56373/abhinav/test-repo/changes/by-branch/4oj7KI1p?limit=10&state=all + url: http://127.0.0.1:57035/abhinav/test-repo/changes/by-branch/jPM09bmi?limit=10&state=all method: GET response: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 - content_length: 637 + content_length: 635 body: | [ { - "number": 13, - "html_url": "http://127.0.0.1:56374/abhinav/test-repo/change/13", + "number": 5, + "html_url": "http://127.0.0.1:57036/abhinav/test-repo/change/5", "state": "open", - "title": "Testing 4oj7KI1p", + "title": "Testing jPM09bmi", "body": "Test PR with reviewer", "base": { "repository": { @@ -62,15 +62,15 @@ interactions: "name": "test-repo" }, "ref": "main", - "sha": "71012226be854d2a77b193ca779abba5cc84cca0" + "sha": "df106cd50b11f5b0d7948f26900d32667d644df4" }, "head": { "repository": { "owner": "abhinav", "name": "test-repo" }, - "ref": "4oj7KI1p", - "sha": "d42a7e9d935c9911190197ad4e04542af2500250" + "ref": "jPM09bmi", + "sha": "ff895ea6c9653846b7725ea8cf32839f6c6cb62b" }, "requested_reviewers": [ "reviewer1", @@ -80,9 +80,9 @@ interactions: ] headers: Content-Length: - - "637" + - "635" Content-Type: - application/json status: 200 OK code: 200 - duration: 23.390833ms + duration: 41.007958ms diff --git a/internal/gateway/gitlab/api.go b/internal/gateway/gitlab/api.go index 6609e1464..946962a68 100644 --- a/internal/gateway/gitlab/api.go +++ b/internal/gateway/gitlab/api.go @@ -516,6 +516,7 @@ type BasicMergeRequest struct { SourceBranch string `json:"source_branch"` TargetBranch string `json:"target_branch"` Title string `json:"title"` + Description string `json:"description"` State string `json:"state"` Assignees []*BasicUser `json:"assignees"` Reviewers []*BasicUser `json:"reviewers"` @@ -695,6 +696,7 @@ type CreateMergeRequestOptions struct { // UpdateMergeRequestOptions configures merge-request updates. type UpdateMergeRequestOptions struct { Title *string `json:"title,omitempty"` + Description *string `json:"description,omitempty"` TargetBranch *string `json:"target_branch,omitempty"` AssigneeIDs *[]int64 `json:"assignee_ids,omitempty"` ReviewerIDs *[]int64 `json:"reviewer_ids,omitempty"` diff --git a/internal/git/commit.go b/internal/git/commit.go index e1861986c..99c83786f 100644 --- a/internal/git/commit.go +++ b/internal/git/commit.go @@ -245,6 +245,21 @@ func (r *Repository) CommitSubject(ctx context.Context, commitish string) (strin return out, nil } +// CommitMessageFull returns the full message of a commit +// (subject and body combined). +func (r *Repository) CommitMessageFull( + ctx context.Context, + commitish string, +) (string, error) { + out, err := r.gitCmd(ctx, + "show", "--no-patch", "--format=%B", commitish, + ).OutputChomp() + if err != nil { + return "", fmt.Errorf("git log: %w", err) + } + return out, nil +} + // CommitMessage is the subject and body of a commit. type CommitMessage struct { // Subject for the commit. diff --git a/internal/handler/squash/handler.go b/internal/handler/squash/handler.go index 1d2c13bbb..7500a5e67 100644 --- a/internal/handler/squash/handler.go +++ b/internal/handler/squash/handler.go @@ -7,10 +7,13 @@ import ( "errors" "fmt" "slices" + "strconv" "strings" "go.abhg.dev/gs/internal/git" "go.abhg.dev/gs/internal/handler/restack" + "go.abhg.dev/gs/internal/msggen" + "go.abhg.dev/gs/internal/scriptrun" "go.abhg.dev/gs/internal/silog" "go.abhg.dev/gs/internal/spice" "go.abhg.dev/gs/internal/spice/state" @@ -65,11 +68,15 @@ type Handler struct { Store Store // required Service Service // required Restack RestackHandler // required + Config *spice.Config // optional + RepoRoot string // optional; repo root dir + Args []string // optional; invoking process args } // Options defines options for the SquashBranch method. -// These are exposed as flags in the CLI +// These are exposed as flags in the CLI. type Options struct { + Fill bool `short:"c" help:"Fill the commit message using the configured message generator."` NoVerify bool `help:"Bypass pre-commit and commit-msg hooks."` // git.commentString is the prefix for comments in commit messages. @@ -115,18 +122,52 @@ func (h *Handler) SquashBranch(ctx context.Context, branchName string, opts *Opt msg := commitMessageTemplate( commitMessages, opts.CommentPrefix, - !opts.NoEdit, // generate comments only if the message will be edited + !opts.NoEdit, // comments only if editing ) - if opts.NoEdit { - // If --no-edit is specified, use the combined commit messages - // as the commit message without opening an editor. - opts.Message = msg - } else { - // Otherwise, use the combined commit messages as a template - // for the commit message, which will be opened in an editor. - commitTemplate = msg + + // If --fill and a message generator is configured, + // run it to produce the squash commit message. + if opts.Fill { + var script string + if h.Config != nil { + script = h.Config.MessageGenerator() + } + if script == "" { + return msggen.ErrNoGenerator + } + + env := scriptrun.EnvFor( + scriptrun.OpBranchSquash, branchName, branch.Base, + ) + env = append(env, + "GS_MESSAGE_KIND=commit", + "GS_MESSAGE_UPDATE="+strconv.FormatBool(true), + "GS_MESSAGE="+msg, + ) + result, err := (&msggen.Runner{ + Log: h.Log, + Args: h.Args, + }).Run( + ctx, script, h.RepoRoot, env, + ) + if err != nil { + h.Log.Warn( + "Message generator failed,"+ + " falling back to editor", + "error", err, + ) + } else { + opts.Message = result.Message() + } } + if opts.Message == "" { + if opts.NoEdit { + opts.Message = msg + } else { + commitTemplate = msg + } + } } // Detach the HEAD so that we don't mess with the current branch diff --git a/internal/handler/squash/handler_test.go b/internal/handler/squash/handler_test.go index eb61c252f..817c69a6e 100644 --- a/internal/handler/squash/handler_test.go +++ b/internal/handler/squash/handler_test.go @@ -7,6 +7,7 @@ import ( "github.com/stretchr/testify/assert" "go.abhg.dev/gs/internal/git" + "go.abhg.dev/gs/internal/msggen" "go.abhg.dev/gs/internal/silog" "go.abhg.dev/gs/internal/spice" "go.uber.org/mock/gomock" @@ -304,6 +305,54 @@ func TestHandler_SquashBranch(t *testing.T) { assert.NoError(t, err) }) + // When --fill is set without a message generator, + // an error should be returned telling the user + // to configure a generator. + t.Run("FillWithoutGenerator", func(t *testing.T) { + ctrl := gomock.NewController(t) + + branchName := "feature" + baseHash := git.Hash("abc123") + headHash := git.Hash("def456") + + mockService := NewMockService(ctrl) + mockService.EXPECT(). + VerifyRestacked(t.Context(), branchName). + Return(nil) + mockService.EXPECT(). + LookupBranch(t.Context(), branchName). + Return(&spice.LookupBranchResponse{ + Head: headHash, + BaseHash: baseHash, + Base: "main", + }, nil) + + mockRepo := NewMockGitRepository(ctrl) + mockRepo.EXPECT(). + CommitMessageRange( + t.Context(), + headHash.String(), + baseHash.String(), + ). + Return([]git.CommitMessage{ + {Subject: "Add feature", Body: "Implementation"}, + }, nil) + + handler := &Handler{ + Log: silog.Nop(), + Repository: mockRepo, + Worktree: NewMockGitWorktree(ctrl), + Store: mockStore, + Service: mockService, + Restack: NewMockRestackHandler(ctrl), + } + + err := handler.SquashBranch( + t.Context(), branchName, &Options{Fill: true}, + ) + assert.ErrorIs(t, err, msggen.ErrNoGenerator) + }) + t.Run("NoMessage", func(t *testing.T) { ctrl := gomock.NewController(t) diff --git a/internal/handler/submit/handler.go b/internal/handler/submit/handler.go index f1587929e..826c73a73 100644 --- a/internal/handler/submit/handler.go +++ b/internal/handler/submit/handler.go @@ -21,7 +21,9 @@ import ( "go.abhg.dev/gs/internal/forge" "go.abhg.dev/gs/internal/git" "go.abhg.dev/gs/internal/iterutil" + "go.abhg.dev/gs/internal/msggen" "go.abhg.dev/gs/internal/must" + "go.abhg.dev/gs/internal/scriptrun" "go.abhg.dev/gs/internal/silog" "go.abhg.dev/gs/internal/spice" "go.abhg.dev/gs/internal/spice/state" @@ -85,6 +87,9 @@ type Handler struct { Store Store // required Service Service // required Browser browser.Launcher // required + Config *spice.Config // optional + RepoRoot string // optional; repo root dir + Args []string // optional; invoking process args // TODO: these should not be a func reference // this whole memoize thing is a bit of a hack @@ -200,11 +205,13 @@ func (v *memoizedValue[T]) Get(get func() (T, error)) (T, error) { // so care must be taken when adding things here. type Options struct { DryRun bool `short:"n" help:"Don't actually submit the stack"` - Fill bool `short:"c" help:"Fill in the change title and body from the commit messages"` + Fill bool `short:"c" negatable:"" config:"message.autoFill" help:"Fill in the title and body of new change requests via the configured message generator. Defaults to spice.message.autoFill. Use --regenerate-message to also update existing change requests."` // TODO: Default to Fill if --no-prompt? - Draft *bool `negatable:"" help:"Whether to mark change requests as drafts"` - Publish bool `name:"publish" negatable:"" default:"true" config:"submit.publish" help:"Whether to create CRs for pushed branches. Defaults to true."` - Web OpenWeb `short:"w" config:"submit.web" help:"Open submitted changes in a web browser. Accepts an optional argument: 'true', 'false', 'created'."` + + RegenerateMessage bool `name:"regenerate-message" help:"Regenerate the title and body of existing change requests via the configured message generator. Unlike --fill, this is never implied by configuration: overwriting an existing description is always explicit."` + Draft *bool `negatable:"" help:"Whether to mark change requests as drafts"` + Publish bool `name:"publish" negatable:"" default:"true" config:"submit.publish" help:"Whether to create CRs for pushed branches. Defaults to true."` + Web OpenWeb `short:"w" config:"submit.web" help:"Open submitted changes in a web browser. Accepts an optional argument: 'true', 'false', 'created'."` NavComment NavCommentWhen `name:"nav-comment" config:"submit.navigationComment" enum:"true,false,multiple" default:"true" help:"Whether to add a navigation comment to the change request. Must be one of: true, false, multiple."` NavCommentSync NavCommentSync `name:"nav-comment-sync" config:"submit.navigationCommentSync" enum:"branch,downstack" default:"branch" hidden:"" help:"Which navigation comment to sync. Must be one of: branch, downstack."` @@ -1147,6 +1154,48 @@ func (h *Handler) submitBranch( } } + // If --regenerate-message and a message generator is + // configured, run it to regenerate the title and body. + // + // Unlike the create path, this is gated on the explicit + // --regenerate-message flag rather than --fill/autoFill: + // overwriting an existing CR's description should be a + // deliberate action, not a side effect of every submit. + var ( + updatedSubject string + updatedBody *string + ) + if opts.RegenerateMessage && h.Config != nil { + if script := h.Config.MessageGenerator(); script != "" { + env := scriptrun.EnvFor( + scriptrun.OpBranchSubmit, branchToSubmit, branch.Base, + ) + env = append(env, + "GS_MESSAGE_KIND=branch", + "GS_MESSAGE_UPDATE=true", + "GS_TITLE="+pull.Subject, + "GS_BODY="+pull.Body, + ) + result, err := (&msggen.Runner{ + Log: log, + Args: h.Args, + }).Run( + ctx, script, h.RepoRoot, env, + ) + if err != nil { + log.Warn( + "Message generator failed", + "error", err, + ) + } else { + updatedSubject = result.Title + updatedBody = &result.Body + updates = append(updates, + "update title/body") + } + } + } + if len(updates) == 0 { log.Infof("CR %v is up-to-date: %s", pull.ID, pull.URL) return status, nil @@ -1188,6 +1237,8 @@ func (h *Handler) submitBranch( editOpts := forge.EditChangeOptions{ Base: upstreamBase, Draft: opts.Draft, + Subject: updatedSubject, + Body: updatedBody, AddLabels: labels, AddReviewers: reviewers, AddAssignees: opts.Assignees, @@ -1337,6 +1388,37 @@ func (h *Handler) prepareBranch( } } + // If --fill and a message generator is configured, + // run it to produce the title and body. + if opts.Fill && opts.Title == "" && opts.Body == "" && + h.Config != nil { + if script := h.Config.MessageGenerator(); script != "" { + env := scriptrun.EnvFor( + scriptrun.OpBranchSubmit, branchToSubmit, baseBranch, + ) + env = append(env, + "GS_MESSAGE_KIND=branch", + "GS_MESSAGE_UPDATE=false", + ) + result, err := (&msggen.Runner{ + Log: h.Log, + Args: h.Args, + }).Run( + ctx, script, h.RepoRoot, env, + ) + if err != nil { + h.Log.Warn( + "Message generator failed,"+ + " falling back to default", + "error", err, + ) + } else { + opts.Title = result.Title + opts.Body = result.Body + } + } + } + var fields []ui.Field form := newBranchSubmitForm(ctx, h.Service, h.Worktree, remoteRepo, h.Log, opts.Options) if opts.Title == "" { diff --git a/internal/msggen/msggen.go b/internal/msggen/msggen.go new file mode 100644 index 000000000..3360cdb31 --- /dev/null +++ b/internal/msggen/msggen.go @@ -0,0 +1,160 @@ +// Package msggen runs the user-configured message generator script +// and parses its JSON output into a [Result]. +// +// Scripts are configured via spice.message.generator. Execution is +// delegated to [scriptrun.Runner] -- the same runner the auto-resolve +// features use -- so the message generator speaks the same JSON +// protocol as the resolvers (see doc/src/guide/scripts.md). +// +// The result fields msggen cares about are Title and Body. The +// shared protocol's Assumptions and Questions are surfaced as logged +// info messages and (when a prompter is wired) an interactive Q&A +// loop driven by the caller. +package msggen + +import ( + "context" + "errors" + "fmt" + + "go.abhg.dev/gs/internal/scriptrun" + "go.abhg.dev/gs/internal/silog" +) + +// Result holds the parsed output of a message generator script. +// +// Title and Body are the user-facing message fields. Assumptions are +// short notes the script wants surfaced (logged at info level by the +// caller). Questions, when non-empty, drives a clarification loop the +// caller may run before treating the result as final. +type Result struct { + // Title is the first-line commit subject or PR title. + Title string + + // Body is the multi-line message body. + Body string + + // Assumptions are informational notes the script made; logged at + // info level by the caller. + Assumptions []string + + // Questions, when non-empty, asks the user for clarification + // before the result is treated as final. + Questions []string +} + +// Message returns the full message by combining Title and Body in the +// conventional format: title, blank line, body. If Body is empty, +// only the Title is returned. +func (r *Result) Message() string { + if r.Body == "" { + return r.Title + } + return r.Title + "\n\n" + r.Body +} + +// ErrNoGenerator is returned when --fill is requested but no message +// generator script is configured. +var ErrNoGenerator = errors.New( + "--fill requires a message generator script; " + + "configure one with: " + + "git config spice.message.generator '