diff --git a/cmd/commit/commit.go b/cmd/commit/commit.go index be0caad..7de1515 100644 --- a/cmd/commit/commit.go +++ b/cmd/commit/commit.go @@ -20,7 +20,7 @@ type Commit struct { Message string `json:"message" mapstructure:"message"` Summary *common.RenderedText `json:"summary,omitempty" mapstructure:"summary"` Rendered *RenderedMessage `json:"rendered,omitempty" mapstructure:"rendered"` - Parents []CommitReference `json:"parents" mapstructure:"parents"` + Parents []CommitReference `json:"parents,omitempty" mapstructure:"parents"` Date time.Time `json:"date" mapstructure:"date"` Repository repository.Repository `json:"repository" mapstructure:"repository"` Links common.Links `json:"links" mapstructure:"links"` diff --git a/cmd/common/selector.go b/cmd/common/selector.go new file mode 100644 index 0000000..45db868 --- /dev/null +++ b/cmd/common/selector.go @@ -0,0 +1,7 @@ +package common + +// Selector represents a selector for references (pipelines, branches, tags, etc.) +type Selector struct { + Type string `json:"type" mapstructure:"type"` + Pattern string `json:"pattern,omitempty" mapstructure:"pattern"` +} diff --git a/cmd/pipeline/pipeline.go b/cmd/pipeline/pipeline.go index 5145459..a7ea885 100644 --- a/cmd/pipeline/pipeline.go +++ b/cmd/pipeline/pipeline.go @@ -53,12 +53,6 @@ type ConfigurationSource struct { URI string `json:"uri" mapstructure:"uri"` } -// TriggerBody represents the body for triggering a pipeline -type TriggerBody struct { - Target Target `json:"target"` - Variables []Variable `json:"variables,omitempty"` -} - // Command represents this folder's command var Command = &cobra.Command{ Use: "pipeline", @@ -84,18 +78,7 @@ var columns = common.Columns[Pipeline]{ return strings.Compare(strings.ToLower(a.State.Name), strings.ToLower(b.State.Name)) == -1 }}, {Name: "branch", DefaultSorter: false, Compare: func(a, b Pipeline) bool { - return strings.Compare(strings.ToLower(a.Target.RefName), strings.ToLower(b.Target.RefName)) == -1 - }}, - {Name: "commit", DefaultSorter: false, Compare: func(a, b Pipeline) bool { - aHash := "" - bHash := "" - if a.Target.Commit != nil { - aHash = a.Target.Commit.Hash - } - if b.Target.Commit != nil { - bHash = b.Target.Commit.Hash - } - return strings.Compare(strings.ToLower(aHash), strings.ToLower(bHash)) == -1 + return strings.Compare(strings.ToLower(a.Target.GetDestination()), strings.ToLower(b.Target.GetDestination())) == -1 }}, {Name: "creator", DefaultSorter: false, Compare: func(a, b Pipeline) bool { return strings.Compare(strings.ToLower(a.Creator.Name), strings.ToLower(b.Creator.Name)) == -1 @@ -161,17 +144,7 @@ func (pipeline Pipeline) GetRow(headers []string) []string { case "state": row = append(row, pipeline.State.String()) case "branch": - row = append(row, pipeline.Target.RefName) - case "commit": - if pipeline.Target.Commit != nil { - hash := pipeline.Target.Commit.Hash - if len(hash) > 7 { - hash = hash[:7] - } - row = append(row, hash) - } else { - row = append(row, " ") - } + row = append(row, pipeline.Target.GetDestination()) case "creator": row = append(row, pipeline.Creator.Name) case "duration": @@ -233,16 +206,17 @@ func (pipeline Pipeline) MarshalJSON() (data []byte, err error) { // UnmarshalJSON implements the json.Unmarshaler interface. // // implements json.Unmarshaler -func (pipeline *Pipeline) UnmarshalJSON(data []byte) error { +func (pipeline *Pipeline) UnmarshalJSON(data []byte) (err error) { type surrogate Pipeline var inner struct { Type string `json:"type"` surrogate - CreatedOn core.Time `json:"created_on"` - CompletedOn core.Time `json:"completed_on,omitempty"` - DurationInSeconds uint64 `json:"duration_in_seconds"` + Target json.RawMessage `json:"target"` + CreatedOn core.Time `json:"created_on"` + CompletedOn core.Time `json:"completed_on,omitempty"` + DurationInSeconds uint64 `json:"duration_in_seconds"` } - if err := json.Unmarshal(data, &inner); err != nil { + if err = json.Unmarshal(data, &inner); err != nil { return errors.JSONUnmarshalError.WrapIfNotMe(err) } if inner.Type != pipeline.GetType() { @@ -252,5 +226,8 @@ func (pipeline *Pipeline) UnmarshalJSON(data []byte) error { pipeline.CreatedOn = time.Time(inner.CreatedOn) pipeline.CompletedOn = time.Time(inner.CompletedOn) pipeline.Duration = time.Duration(inner.DurationInSeconds) * time.Second + if pipeline.Target, err = UnmarshalTarget(inner.Target); err != nil { + return errors.JSONUnmarshalError.WrapIfNotMe(err) + } return errors.JSONUnmarshalError.Wrap(pipeline.Validate()) } diff --git a/cmd/pipeline/pipeline_test.go b/cmd/pipeline/pipeline_test.go index a80c4a4..aeb7fb7 100644 --- a/cmd/pipeline/pipeline_test.go +++ b/cmd/pipeline/pipeline_test.go @@ -87,21 +87,62 @@ func (suite *PipelineSuite) UnmarshalData(filename string, v any) error { // ***************************************************************************** func (suite *PipelineSuite) TestCanUnmarshal() { - var pipeline pipeline.Pipeline - err := suite.UnmarshalData("pipeline.json", &pipeline) + var pl pipeline.Pipeline + err := suite.UnmarshalData("pipeline.json", &pl) suite.Require().NoError(err) - suite.Require().NotNil(pipeline) - suite.Assert().Equal("{a1b2c3d4-e5f6-7890-abcd-ef1234567890}", pipeline.ID.String()) - suite.Assert().Equal(uint64(42), pipeline.BuildNumber) - suite.Assert().Equal("COMPLETED", pipeline.State.Name) - suite.Assert().NotNil(pipeline.State.Result) - suite.Assert().Equal("SUCCESSFUL", pipeline.State.Result.Name) - suite.Assert().Equal("branch", pipeline.Target.RefType) - suite.Assert().Equal("main", pipeline.Target.RefName) - suite.Assert().Equal("abc123def456", pipeline.Target.Commit.Hash) - suite.Assert().Equal(330*time.Second, pipeline.Duration) - suite.Assert().Equal("John Developer", pipeline.Creator.Name) - suite.Assert().Equal("myworkspace/my-repo", pipeline.Repository.FullName) + suite.Assert().Equal("{a1b2c3d4-e5f6-7890-abcd-ef1234567890}", pl.ID.String()) + suite.Assert().Equal(uint64(42), pl.BuildNumber) + suite.Assert().Equal("COMPLETED", pl.State.Name) + suite.Require().NotNil(pl.State.Result) + suite.Assert().Equal("SUCCESSFUL", pl.State.Result.Name) + suite.Assert().Equal(330*time.Second, pl.Duration) + suite.Assert().Equal(uuid.MustParse("12345678-1234-1234-1234-123456789012"), uuid.UUID(pl.Creator.ID)) + suite.Assert().Equal("557058:12345678-abcd-efgh-ijkl-123456789012", pl.Creator.AccountID) + suite.Assert().Equal("John Developer", pl.Creator.Name) + suite.Assert().Equal("johnd", pl.Creator.Nickname) + suite.Assert().Equal("myworkspace/my-repo", pl.Repository.FullName) + + suite.Require().NotNil(pl.Target) + suite.Assert().Equal("main", pl.Target.GetDestination()) + suite.Assert().Equal("abc123def456", pl.Target.GetCommit().Hash) + + target, ok := pl.Target.(*pipeline.ReferenceTarget) + suite.Require().True(ok) + suite.Assert().Equal("branch", target.ReferenceType) + suite.Assert().Equal("main", target.ReferenceName) + suite.Assert().Equal("abc123def456", target.Commit.Hash) +} + +func (suite *PipelineSuite) TestCanUnmarshalWithPullRequest() { + var pl pipeline.Pipeline + err := suite.UnmarshalData("pipeline-pullrequest.json", &pl) + suite.Require().NoError(err) + suite.Assert().Equal("{a1b2c3d4-e5f6-7890-abcd-ef1234567890}", pl.ID.String()) + suite.Assert().Equal(uint64(42), pl.BuildNumber) + suite.Assert().Equal("COMPLETED", pl.State.Name) + suite.Require().NotNil(pl.State.Result) + suite.Assert().Equal("FAILED", pl.State.Result.Name) + suite.Assert().Equal(330*time.Second, pl.Duration) + suite.Assert().Equal(uuid.MustParse("12345678-1234-1234-1234-123456789012"), uuid.UUID(pl.Creator.ID)) + suite.Assert().Equal("557058:12345678-abcd-efgh-ijkl-123456789012", pl.Creator.AccountID) + suite.Assert().Equal("John Developer", pl.Creator.Name) + suite.Assert().Equal("johnd", pl.Creator.Nickname) + suite.Assert().Equal("myworkspace/my-repo", pl.Repository.FullName) + + suite.Require().NotNil(pl.Target) + suite.Assert().Equal("main", pl.Target.GetDestination()) + suite.Assert().Equal("3c80cde6b371", pl.Target.GetCommit().Hash) + + target, ok := pl.Target.(*pipeline.PullRequestReferenceTarget) + suite.Require().True(ok) + suite.Assert().Equal("main", target.Destination) + suite.Assert().Equal("abc123def456", target.DestinationCommit.Hash) + suite.Assert().Equal("custom", target.Selector.Type) + suite.Assert().Equal("run-tests", target.Selector.Pattern) + suite.Assert().Equal("3c80cde6b371", target.Commit.Hash) + suite.Assert().Equal(uint64(62), target.PullRequest.ID) + suite.Assert().Equal("feat: add API key authentication", target.PullRequest.Title) + suite.Assert().False(target.PullRequest.IsDraft) } func (suite *PipelineSuite) TestCanMarshal() { @@ -117,16 +158,12 @@ func (suite *PipelineSuite) TestCanMarshal() { Name: "SUCCESSFUL", }, }, - Target: pipeline.Target{ - Type: "pipeline_ref_target", - RefType: "branch", - RefName: "main", - Commit: &commit.Commit{ - Hash: "abc123def456", - }, - Selector: &pipeline.Selector{ - Type: "default", - }, + Target: pipeline.ReferenceTarget{ + Type: "pipeline_ref_target", + ReferenceType: "branch", + ReferenceName: "main", + Commit: commit.CommitReference{Hash: "abc123def456"}, + Selector: &common.Selector{Type: "default"}, }, CreatedOn: time.Date(2024, 1, 15, 10, 30, 0, 0, time.UTC), CompletedOn: time.Date(2024, 1, 15, 10, 35, 30, 0, time.UTC), @@ -145,13 +182,13 @@ func (suite *PipelineSuite) TestCanMarshal() { }, Repository: pipeline.Repository{ Type: "repository", - UUID: "{repo-uuid-1234-5678-abcd}", + UUID: "{12854e6a-e6f8-44ac-b006-1521931d4c0d}", Name: "my-repo", FullName: "myworkspace/my-repo", Links: common.Links{ Self: &common.Link{HREF: url.URL{Scheme: "https", Host: "api.bitbucket.org", Path: "/2.0/repositories/myworkspace/my-repo"}}, HTML: &common.Link{HREF: url.URL{Scheme: "https", Host: "bitbucket.org", Path: "/myworkspace/my-repo"}}, - Avatar: &common.Link{HREF: url.URL{Scheme: "https", Host: "bytebucket.org", Path: "/ravatar/{repo-uuid}"}}, + Avatar: &common.Link{HREF: url.URL{Scheme: "https", Host: "bytebucket.org", Path: "/ravatar/{12854e6a-e6f8-44ac-b006-1521931d4c0d}"}}, }, }, Links: common.Links{ diff --git a/cmd/pipeline/target.go b/cmd/pipeline/target.go index 9225579..7829540 100644 --- a/cmd/pipeline/target.go +++ b/cmd/pipeline/target.go @@ -1,76 +1,37 @@ package pipeline import ( - "encoding/json" + "strings" "bitbucket.org/gildas_cherruel/bb/cmd/commit" + "github.com/gildas/go-core" "github.com/gildas/go-errors" ) // Target represents the target of a pipeline (branch, tag, etc.) -type Target struct { - Type string `json:"type" mapstructure:"type"` - RefType string `json:"ref_type,omitempty" mapstructure:"ref_type"` - RefName string `json:"ref_name,omitempty" mapstructure:"ref_name"` - Selector *Selector `json:"selector,omitempty" mapstructure:"selector"` - Commit *commit.Commit `json:"commit,omitempty" mapstructure:"commit"` +type Target interface { + core.TypeCarrier + GetDestination() string + GetCommit() commit.CommitReference } -// Selector represents a pipeline selector for custom pipelines -type Selector struct { - Type string `json:"type" mapstructure:"type"` - Pattern string `json:"pattern,omitempty" mapstructure:"pattern"` -} - -// GetType returns the target type -func (target Target) GetType() string { - return "pipeline_ref_target" -} - -// MarshalJSON custom JSON marshalling for Target -// -// implements json.Marshaler -func (target Target) MarshalJSON() ([]byte, error) { - type surrogate Target - var commitRef *commit.CommitReference - - if target.Commit != nil { - commitRef = target.Commit.GetReference() - } - - data, err := json.Marshal(struct { - Type string `json:"type"` - surrogate - CommitRef *commit.CommitReference `json:"commit,omitempty"` - }{ - Type: target.GetType(), - surrogate: surrogate(target), - CommitRef: commitRef, - }) - return data, errors.JSONMarshalError.Wrap(err) -} - -// UnmarshalJSON custom JSON unmarshalling for Target -// -// implements json.Unmarshaler -func (target *Target) UnmarshalJSON(data []byte) error { - type surrogate Target - var inner struct { - Type string `json:"type"` - surrogate - CommitReference *commit.CommitReference `json:"commit,omitempty"` - } - - if err := json.Unmarshal(data, &inner); err != nil { - return errors.JSONUnmarshalError.WrapIfNotMe(err) +var targetRegistry = core.TypeRegistry{} + +// UnmarshalTarget unmarshals a Target from JSON data +func UnmarshalTarget(payload []byte) (Target, error) { + target, err := targetRegistry.UnmarshalJSON(payload) + if err != nil { + if strings.HasPrefix(err.Error(), "Missing JSON Property") { + return nil, errors.JSONUnmarshalError.Wrap(errors.ArgumentMissing.With("type")) + } + if strings.HasPrefix(err.Error(), "Unsupported Type") { + keys := make([]string, 0, len(targetRegistry)) + for key := range targetRegistry { + keys = append(keys, key) + } + return nil, errors.JSONUnmarshalError.Wrap(errors.InvalidType.With(strings.TrimSuffix(strings.TrimPrefix(err.Error(), `Unsupported Type "`), `"`), strings.Join(keys, ", "))) + } + return nil, err } - if inner.Type != target.GetType() { - return errors.JSONUnmarshalError.Wrap(errors.InvalidType.With(inner.Type, target.GetType())) - } - *target = Target(inner.surrogate) - if inner.CommitReference != nil { - target.Commit = inner.CommitReference.AsCommit() - } - - return nil + return target.(Target), nil } diff --git a/cmd/pipeline/target_pullrequest_reference.go b/cmd/pipeline/target_pullrequest_reference.go new file mode 100644 index 0000000..7f27cad --- /dev/null +++ b/cmd/pipeline/target_pullrequest_reference.go @@ -0,0 +1,42 @@ +package pipeline + +import ( + "bitbucket.org/gildas_cherruel/bb/cmd/commit" + "bitbucket.org/gildas_cherruel/bb/cmd/common" + "bitbucket.org/gildas_cherruel/bb/cmd/pullrequest" +) + +// PullRequestReferenceTarget represents a target for a pipeline that is a pull request reference. +type PullRequestReferenceTarget struct { + Source string `json:"source" mapstructure:"source"` + Destination string `json:"destination" mapstructure:"destination"` + DestinationCommit commit.CommitReference `json:"destination_commit" mapstructure:"destination_commit"` + Commit commit.CommitReference `json:"commit" mapstructure:"commit"` + Selector *common.Selector `json:"selector,omitempty" mapstructure:"selector"` + PullRequest pullrequest.PullRequestReference `json:"pullrequest" mapstructure:"pullrequest"` +} + +func init() { + targetRegistry.Add(PullRequestReferenceTarget{}) +} + +// GetType returns the type of the PullRequestReferenceTarget. +// +// implements core.TypeCarrier +func (target PullRequestReferenceTarget) GetType() string { + return "pipeline_pullrequest_target" +} + +// GetDestination returns the destination of the PullRequestReferenceTarget. +// +// implements Target +func (target PullRequestReferenceTarget) GetDestination() string { + return target.Destination +} + +// GetCommit returns the commit of the PullRequestReferenceTarget. +// +// implements Target +func (target PullRequestReferenceTarget) GetCommit() commit.CommitReference { + return target.Commit +} diff --git a/cmd/pipeline/target_reference.go b/cmd/pipeline/target_reference.go new file mode 100644 index 0000000..9e6336a --- /dev/null +++ b/cmd/pipeline/target_reference.go @@ -0,0 +1,76 @@ +package pipeline + +import ( + "encoding/json" + + "bitbucket.org/gildas_cherruel/bb/cmd/commit" + "bitbucket.org/gildas_cherruel/bb/cmd/common" + "github.com/gildas/go-errors" +) + +// ReferenceTarget represents the target of a pipeline (branch, tag, etc.) +type ReferenceTarget struct { + Type string `json:"type" mapstructure:"type"` + ReferenceType string `json:"ref_type,omitempty" mapstructure:"ref_type"` + ReferenceName string `json:"ref_name,omitempty" mapstructure:"ref_name"` + Selector *common.Selector `json:"selector,omitempty" mapstructure:"selector"` + Commit commit.CommitReference `json:"commit" mapstructure:"commit"` +} + +func init() { + targetRegistry.Add(ReferenceTarget{}) +} + +// GetType returns the target type +func (target ReferenceTarget) GetType() string { + return "pipeline_ref_target" +} + +// GetDestination returns the target's destination +// +// implements Target +func (target ReferenceTarget) GetDestination() string { + return target.ReferenceName +} + +// GetCommit return the target's commit reference +func (target ReferenceTarget) GetCommit() commit.CommitReference { + return target.Commit +} + +// MarshalJSON custom JSON marshalling for Target +// +// implements json.Marshaler +func (target ReferenceTarget) MarshalJSON() ([]byte, error) { + type surrogate ReferenceTarget + + data, err := json.Marshal(struct { + Type string `json:"type"` + surrogate + }{ + Type: target.GetType(), + surrogate: surrogate(target), + }) + return data, errors.JSONMarshalError.Wrap(err) +} + +// UnmarshalJSON custom JSON unmarshalling for Target +// +// implements json.Unmarshaler +func (target *ReferenceTarget) UnmarshalJSON(data []byte) error { + type surrogate ReferenceTarget + var inner struct { + Type string `json:"type"` + surrogate + } + + if err := json.Unmarshal(data, &inner); err != nil { + return errors.JSONUnmarshalError.WrapIfNotMe(err) + } + if inner.Type != target.GetType() { + return errors.JSONUnmarshalError.Wrap(errors.InvalidType.With(inner.Type, target.GetType())) + } + *target = ReferenceTarget(inner.surrogate) + + return nil +} diff --git a/cmd/pipeline/trigger.go b/cmd/pipeline/trigger.go index 141d353..2204a00 100644 --- a/cmd/pipeline/trigger.go +++ b/cmd/pipeline/trigger.go @@ -12,6 +12,12 @@ import ( "github.com/spf13/cobra" ) +// TriggerBody represents the body for triggering a pipeline +type TriggerBody struct { + Target Target `json:"target"` + Variables []Variable `json:"variables,omitempty"` +} + var triggerCmd = &cobra.Command{ Use: "trigger", Aliases: []string{"run", "start", "create"}, @@ -49,16 +55,16 @@ func triggerProcess(cmd *cobra.Command, args []string) (err error) { } // Build the target - target := Target{ + target := ReferenceTarget{ Type: "pipeline_ref_target", } if len(triggerOptions.Tag) > 0 { - target.RefType = "tag" - target.RefName = triggerOptions.Tag + target.ReferenceType = "tag" + target.ReferenceName = triggerOptions.Tag } else if len(triggerOptions.Branch) > 0 { - target.RefType = "branch" - target.RefName = triggerOptions.Branch + target.ReferenceType = "branch" + target.ReferenceName = triggerOptions.Branch } else { // Try to detect the current git branch currentBranch, err := branch.GetCurrentBranch() @@ -66,17 +72,17 @@ func triggerProcess(cmd *cobra.Command, args []string) (err error) { log.Errorf("Failed to retrieve the current branch", err) return errors.ArgumentMissing.With("branch or tag", "use --branch or --tag to specify the target") } - target.RefType = currentBranch.GetType() - target.RefName = currentBranch.Name + target.ReferenceType = currentBranch.GetType() + target.ReferenceName = currentBranch.Name log.Infof("Using current branch: %s", currentBranch.Name) } if len(triggerOptions.Commit) > 0 { - target.Commit = &commit.Commit{Hash: triggerOptions.Commit} + target.Commit = commit.CommitReference{Hash: triggerOptions.Commit} } if len(triggerOptions.Pattern) > 0 { - target.Selector = &Selector{ + target.Selector = &common.Selector{ Type: "custom", Pattern: triggerOptions.Pattern, } diff --git a/cmd/pullrequest/create.go b/cmd/pullrequest/create.go index 1a58f67..b8e22aa 100644 --- a/cmd/pullrequest/create.go +++ b/cmd/pullrequest/create.go @@ -124,6 +124,14 @@ func createProcess(cmd *cobra.Command, args []string) (err error) { } else { var reviewers []reviewer.Reviewer + // Find me + log.Debugf("Finding current user") + me, err := user.GetMe(cmd.Context(), cmd) + if err != nil { + return errors.Join(errors.New("failed to get current user"), err) + } + log.Infof("Current user: %s (%s)", me.Username, me.ID) + // Find the default reviewers from the repo or project settings log.Debugf("No reviewers in the repository, trying to get effective default reviewers from the repository") reviewers, err = pullrequestRepository.GetEffectiveDefaultReviewers(cmd.Context(), cmd) @@ -132,6 +140,10 @@ func createProcess(cmd *cobra.Command, args []string) (err error) { return err } log.Debugf("Found %d default reviewers", len(reviewers)) + + // Removing myself from the reviewers since I cannot be a reviewer of my own pullrequest + reviewers = core.Filter(reviewers, func(reviewer reviewer.Reviewer) bool { return reviewer.User.ID != me.ID }) + log.Debugf("Filtered reviewers to remove current user: %d reviewers remaining", len(reviewers)) payload.Reviewers = core.Map(reviewers, func(reviewer reviewer.Reviewer) user.User { return reviewer.User }) } diff --git a/cmd/pullrequest/pullrequest_reference.go b/cmd/pullrequest/pullrequest_reference.go new file mode 100644 index 0000000..57399d9 --- /dev/null +++ b/cmd/pullrequest/pullrequest_reference.go @@ -0,0 +1,14 @@ +package pullrequest + +import ( + "bitbucket.org/gildas_cherruel/bb/cmd/common" +) + +// PullRequestReference describes a reference to a PullRequest +type PullRequestReference struct { + Type string `json:"type" mapstructure:"type"` + ID uint64 `json:"id" mapstructure:"id"` + Title string `json:"title" mapstructure:"title"` + IsDraft bool `json:"draft" mapstructure:"draft"` + Links common.Links `json:"links" mapstructure:"links"` +} diff --git a/cmd/pullrequest/update.go b/cmd/pullrequest/update.go index 62e3976..54afbbb 100644 --- a/cmd/pullrequest/update.go +++ b/cmd/pullrequest/update.go @@ -13,6 +13,7 @@ import ( "bitbucket.org/gildas_cherruel/bb/cmd/user" "bitbucket.org/gildas_cherruel/bb/cmd/workspace" "github.com/gildas/go-core" + "github.com/gildas/go-errors" "github.com/gildas/go-flags" "github.com/gildas/go-logger" "github.com/spf13/cobra" @@ -156,6 +157,14 @@ func updateProcess(cmd *cobra.Command, args []string) error { if len(updateOptions.AddReviewers.Values) > 0 { if updateOptions.AddReviewers.Values[0] == "default" { + // Find me + log.Debugf("Finding current user") + me, err := user.GetMe(cmd.Context(), cmd) + if err != nil { + return errors.Join(errors.New("failed to get current user"), err) + } + log.Infof("Current user: %s (%s)", me.Username, me.ID) + // Find the default reviewers from the repo or project settings var reviewers []reviewer.Reviewer @@ -166,6 +175,11 @@ func updateProcess(cmd *cobra.Command, args []string) error { return err } log.Debugf("Found %d default reviewers", len(reviewers)) + + // Removing myself from the reviewers since I cannot be a reviewer of my own pullrequest + reviewers = core.Filter(reviewers, func(reviewer reviewer.Reviewer) bool { return reviewer.User.ID != me.ID }) + log.Debugf("Filtered reviewers to remove current user: %d reviewers remaining", len(reviewers)) + // Replace the first reviewer with the list of default reviewers and appends the rest updateOptions.AddReviewers.Values = append( core.Map(reviewers, func(reviewer reviewer.Reviewer) string { return reviewer.User.ID.String() }), diff --git a/cmd/repository/repository.go b/cmd/repository/repository.go index ad99d91..e5e75bb 100644 --- a/cmd/repository/repository.go +++ b/cmd/repository/repository.go @@ -39,7 +39,7 @@ type Repository struct { MainBranch string `json:"-" mapstructure:"-"` DefaultMergeStrategy string `json:"-" mapstructure:"-"` BranchingModel string `json:"-" mapstructure:"-"` - Parent *Repository `json:"parent" mapstructure:"parent"` + Parent *Repository `json:"parent,omitempty" mapstructure:"parent"` Links common.Links `json:"links" mapstructure:"links"` CreatedOn time.Time `json:"created_on" mapstructure:"created_on"` UpdatedOn time.Time `json:"updated_on" mapstructure:"updated_on"` diff --git a/cmd/user/user.go b/cmd/user/user.go index 916eb57..e2011ef 100644 --- a/cmd/user/user.go +++ b/cmd/user/user.go @@ -164,14 +164,15 @@ func (user User) MarshalJSON() (data []byte, err error) { // GetMe gets the current user func GetMe(context context.Context, cmd *cobra.Command) (user *User, err error) { log := logger.Must(logger.FromContext(context)).Child("user", "me") - if user, err = UserCache.Get("me"); err == nil { - log.Debugf("User found in cache") - return - } + profile, err := profile.GetProfileFromCommand(cmd.Context(), cmd) if err != nil { return nil, err } + if user, err = UserCache.Get(profile.Name + ":me"); err == nil { + log.Debugf("User found in cache") + return + } err = profile.Get( context, cmd, @@ -179,7 +180,7 @@ func GetMe(context context.Context, cmd *cobra.Command) (user *User, err error) &user, ) if err == nil { - _ = UserCache.Set(*user, "me") + _ = UserCache.Set(*user, profile.Name+":me") } return } @@ -199,7 +200,7 @@ func GetUser(context context.Context, cmd *cobra.Command, userid string) (user * } userUUID, err := common.ParseUUID(userid) if err == nil { - if user, err = UserCache.Get(userUUID.String()); err != nil { + if user, err = UserCache.Get(profile.Name + ":" + userUUID.String()); err != nil { err = profile.Get( context, cmd, @@ -207,7 +208,7 @@ func GetUser(context context.Context, cmd *cobra.Command, userid string) (user * &user, ) if err == nil { - _ = UserCache.Set(*user) + _ = UserCache.Set(*user, profile.Name+":"+userUUID.String()) } } } diff --git a/go.mod b/go.mod index b799749..4e8e1e8 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/gildas/go-core v0.6.4 github.com/gildas/go-errors v0.4.0 github.com/gildas/go-flags v0.4.1 - github.com/gildas/go-logger v1.8.2 + github.com/gildas/go-logger v1.9.0 github.com/gildas/go-request v0.9.17 github.com/go-git/go-git/v5 v5.16.4 github.com/google/uuid v1.6.0 @@ -30,14 +30,13 @@ require ( cloud.google.com/go/auth v0.18.1 // indirect cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect cloud.google.com/go/compute/metadata v0.9.0 // indirect - cloud.google.com/go/logging v1.13.1 // indirect + cloud.google.com/go/logging v1.13.2 // indirect cloud.google.com/go/longrunning v0.8.0 // indirect dario.cat/mergo v1.0.2 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/ProtonMail/go-crypto v1.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/clipperhouse/stringish v0.1.1 // indirect - github.com/clipperhouse/uax29/v2 v2.5.0 // indirect + github.com/clipperhouse/uax29/v2 v2.6.0 // indirect github.com/cloudflare/circl v1.6.3 // indirect github.com/cyphar/filepath-securejoin v0.6.1 // indirect github.com/danieljoos/wincred v1.2.3 // indirect @@ -55,7 +54,7 @@ require ( github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect github.com/google/s2a-go v0.1.9 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.11 // indirect - github.com/googleapis/gax-go/v2 v2.16.0 // indirect + github.com/googleapis/gax-go/v2 v2.17.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/kevinburke/ssh_config v1.4.0 // indirect @@ -85,16 +84,16 @@ require ( golang.org/x/crypto v0.47.0 // indirect golang.org/x/exp v0.0.0-20260112195511-716be5621a96 // indirect golang.org/x/net v0.49.0 // indirect - golang.org/x/oauth2 v0.34.0 // indirect + golang.org/x/oauth2 v0.35.0 // indirect golang.org/x/sync v0.19.0 // indirect - golang.org/x/sys v0.40.0 // indirect + golang.org/x/sys v0.41.0 // indirect golang.org/x/term v0.39.0 // indirect golang.org/x/text v0.33.0 // indirect golang.org/x/time v0.14.0 // indirect - google.golang.org/api v0.264.0 // indirect - google.golang.org/genproto v0.0.0-20260202165425-ce8ad4cf556b // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20260202165425-ce8ad4cf556b // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260202165425-ce8ad4cf556b // indirect + google.golang.org/api v0.265.0 // indirect + google.golang.org/genproto v0.0.0-20260203192932-546029d2fa20 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20260203192932-546029d2fa20 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260203192932-546029d2fa20 // indirect google.golang.org/grpc v1.78.0 // indirect google.golang.org/protobuf v1.36.11 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect diff --git a/go.sum b/go.sum index e484500..f15c4ae 100644 --- a/go.sum +++ b/go.sum @@ -10,8 +10,8 @@ cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdB cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10= cloud.google.com/go/iam v1.5.3 h1:+vMINPiDF2ognBJ97ABAYYwRgsaqxPbQDlMnbHMjolc= cloud.google.com/go/iam v1.5.3/go.mod h1:MR3v9oLkZCTlaqljW6Eb2d3HGDGK5/bDv93jhfISFvU= -cloud.google.com/go/logging v1.13.1 h1:O7LvmO0kGLaHY/gq8cV7T0dyp6zJhYAOtZPX4TF3QtY= -cloud.google.com/go/logging v1.13.1/go.mod h1:XAQkfkMBxQRjQek96WLPNze7vsOmay9H5PqfsNYDqvw= +cloud.google.com/go/logging v1.13.2 h1:qqlHCBvieJT9Cdq4QqYx1KPadCQ2noD4FK02eNqHAjA= +cloud.google.com/go/logging v1.13.2/go.mod h1:zaybliM3yun1J8mU2dVQ1/qDzjbOqEijZCn6hSBtKak= cloud.google.com/go/longrunning v0.8.0 h1:LiKK77J3bx5gDLi4SMViHixjD2ohlkwBi+mKA7EhfW8= cloud.google.com/go/longrunning v0.8.0/go.mod h1:UmErU2Onzi+fKDg2gR7dusz11Pe26aknR4kHmJJqIfk= dario.cat/mergo v1.0.2 h1:85+piFYR1tMbRrLcDwR18y4UKJ3aH1Tbzi24VRW1TK8= @@ -31,10 +31,8 @@ github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UF github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chengxilo/virtualterm v1.0.4 h1:Z6IpERbRVlfB8WkOmtbHiDbBANU7cimRIof7mk9/PwM= github.com/chengxilo/virtualterm v1.0.4/go.mod h1:DyxxBZz/x1iqJjFxTFcr6/x+jSpqN0iwWCOK1q10rlY= -github.com/clipperhouse/stringish v0.1.1 h1:+NSqMOr3GR6k1FdRhhnXrLfztGzuG+VuFDfatpWHKCs= -github.com/clipperhouse/stringish v0.1.1/go.mod h1:v/WhFtE1q0ovMta2+m+UbpZ+2/HEXNWYXQgCt4hdOzA= -github.com/clipperhouse/uax29/v2 v2.5.0 h1:x7T0T4eTHDONxFJsL94uKNKPHrclyFI0lm7+w94cO8U= -github.com/clipperhouse/uax29/v2 v2.5.0/go.mod h1:Wn1g7MK6OoeDT0vL+Q0SQLDz/KpfsVRgg6W7ihQeh4g= +github.com/clipperhouse/uax29/v2 v2.6.0 h1:z0cDbUV+aPASdFb2/ndFnS9ts/WNXgTNNGFoKXuhpos= +github.com/clipperhouse/uax29/v2 v2.6.0/go.mod h1:Wn1g7MK6OoeDT0vL+Q0SQLDz/KpfsVRgg6W7ihQeh4g= github.com/cloudflare/circl v1.6.3 h1:9GPOhQGF9MCYUeXyMYlqTR6a5gTrgR/fBLXvUgtVcg8= github.com/cloudflare/circl v1.6.3/go.mod h1:2eXP6Qfat4O/Yhh8BznvKnJ+uzEoTQ6jVKJRn81BiS4= github.com/cncf/xds/go v0.0.0-20251022180443-0feb69152e9f h1:Y8xYupdHxryycyPlc9Y+bSQAYZnetRJ70VMVKm5CKI0= @@ -73,8 +71,8 @@ github.com/gildas/go-errors v0.4.0 h1:pJ5km8sKrOm5MQd/0g+y4pSKI38YBwPs5NkwSsU8bk github.com/gildas/go-errors v0.4.0/go.mod h1:a05AfO2MLgb8OTPj5l/HZRrBhfjxnwWyEKXgyeoKjtg= github.com/gildas/go-flags v0.4.1 h1:I8k751mMdxnNsay41cTKoHAsiFVoUpW8nQ22acipSDg= github.com/gildas/go-flags v0.4.1/go.mod h1:NAthqN8eTSoUppTwNiq9/+4gx8GDjyt51IZVDVjcMtk= -github.com/gildas/go-logger v1.8.2 h1:s2SX2Umj0Xxto9Av1nLm67FRVj2hyC6KLk4u/Uq13EQ= -github.com/gildas/go-logger v1.8.2/go.mod h1:RQI07N8rEa3pRA2A/VSq75txocFoyM15c/j5vyW4+jQ= +github.com/gildas/go-logger v1.9.0 h1:okqKXsKi0aLhAuvKdK13p9LVjB8hK4SaiGEuafuJ9ms= +github.com/gildas/go-logger v1.9.0/go.mod h1:fvLS4gSO/DvsNMBDuoZJFwHD4kgBeerhflUv04fY9kU= github.com/gildas/go-request v0.9.17 h1:LC+SzjoNOn8uNPkQqSlsbImsZt5MLlwk6g5tPMm4iws= github.com/gildas/go-request v0.9.17/go.mod h1:zKNR/Uviq7h1Pa2p/CWdW0aGtYm8m4+R8jQ/FLD/wv8= github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c= @@ -110,8 +108,8 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/enterprise-certificate-proxy v0.3.11 h1:vAe81Msw+8tKUxi2Dqh/NZMz7475yUvmRIkXr4oN2ao= github.com/googleapis/enterprise-certificate-proxy v0.3.11/go.mod h1:RFV7MUdlb7AgEq2v7FmMCfeSMCllAzWxFgRdusoGks8= -github.com/googleapis/gax-go/v2 v2.16.0 h1:iHbQmKLLZrexmb0OSsNGTeSTS0HO4YvFOG8g5E4Zd0Y= -github.com/googleapis/gax-go/v2 v2.16.0/go.mod h1:o1vfQjjNZn4+dPnRdl/4ZD7S9414Y4xA+a/6Icj6l14= +github.com/googleapis/gax-go/v2 v2.17.0 h1:RksgfBpxqff0EZkDWYuz9q/uWsTVz+kf43LsZ1J6SMc= +github.com/googleapis/gax-go/v2 v2.17.0/go.mod h1:mzaqghpQp4JDh3HvADwrat+6M3MOIDp5YKHhb9PAgDY= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= @@ -223,8 +221,8 @@ golang.org/x/exp v0.0.0-20260112195511-716be5621a96/go.mod h1:nzimsREAkjBCIEFtHi golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o= golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8= -golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw= -golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= +golang.org/x/oauth2 v0.35.0 h1:Mv2mzuHuZuY2+bkyWXIHMfhNdJAdwW3FuWeCPYN5GVQ= +golang.org/x/oauth2 v0.35.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -234,8 +232,8 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= -golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.39.0 h1:RclSuaJf32jOqZz74CkPA9qFuVTX7vhLlpfj/IGWlqY= golang.org/x/term v0.39.0/go.mod h1:yxzUCTP/U+FzoxfdKmLaA0RV1WgE0VY7hXBwKtY/4ww= @@ -247,14 +245,14 @@ golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/api v0.264.0 h1:+Fo3DQXBK8gLdf8rFZ3uLu39JpOnhvzJrLMQSoSYZJM= -google.golang.org/api v0.264.0/go.mod h1:fAU1xtNNisHgOF5JooAs8rRaTkl2rT3uaoNGo9NS3R8= -google.golang.org/genproto v0.0.0-20260202165425-ce8ad4cf556b h1:mJ7ODqDXbGE8alZwxCKWc9OTvpFQkXB6KRHvjnb9W8Q= -google.golang.org/genproto v0.0.0-20260202165425-ce8ad4cf556b/go.mod h1:Tt+08/KdKEt3l8x3Pby3HLQxMB3uk/MzaQ4ZIv0ORTs= -google.golang.org/genproto/googleapis/api v0.0.0-20260202165425-ce8ad4cf556b h1:SGYyueaEovpqmWmtTvwtVgo638V/QFE2zlTCnRrR3jg= -google.golang.org/genproto/googleapis/api v0.0.0-20260202165425-ce8ad4cf556b/go.mod h1:ZdbssH/1SOVnjnDlXzxDHK2MCidiqXtbYccJNzNYPEE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260202165425-ce8ad4cf556b h1:GZxXGdFaHX27ZSMHudWc4FokdD+xl8BC2UJm1OVIEzs= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260202165425-ce8ad4cf556b/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= +google.golang.org/api v0.265.0 h1:FZvfUdI8nfmuNrE34aOWFPmLC+qRBEiNm3JdivTvAAU= +google.golang.org/api v0.265.0/go.mod h1:uAvfEl3SLUj/7n6k+lJutcswVojHPp2Sp08jWCu8hLY= +google.golang.org/genproto v0.0.0-20260203192932-546029d2fa20 h1:/CU1zrxTpGylJJbe3Ru94yy6sZRbzALq2/oxl3pGB3U= +google.golang.org/genproto v0.0.0-20260203192932-546029d2fa20/go.mod h1:Tt+08/KdKEt3l8x3Pby3HLQxMB3uk/MzaQ4ZIv0ORTs= +google.golang.org/genproto/googleapis/api v0.0.0-20260203192932-546029d2fa20 h1:7ei4lp52gK1uSejlA8AZl5AJjeLUOHBQscRQZUgAcu0= +google.golang.org/genproto/googleapis/api v0.0.0-20260203192932-546029d2fa20/go.mod h1:ZdbssH/1SOVnjnDlXzxDHK2MCidiqXtbYccJNzNYPEE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260203192932-546029d2fa20 h1:Jr5R2J6F6qWyzINc+4AM8t5pfUz6beZpHp678GNrMbE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260203192932-546029d2fa20/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= google.golang.org/grpc v1.78.0 h1:K1XZG/yGDJnzMdd/uZHAkVqJE+xIDOcmdSFZkBUicNc= google.golang.org/grpc v1.78.0/go.mod h1:I47qjTo4OKbMkjA/aOOwxDIiPSBofUtQUI5EfpWvW7U= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= diff --git a/packaging/chocolatey/bitbucket-cli.nuspec b/packaging/chocolatey/bitbucket-cli.nuspec index de6a07c..a5942f6 100644 --- a/packaging/chocolatey/bitbucket-cli.nuspec +++ b/packaging/chocolatey/bitbucket-cli.nuspec @@ -3,7 +3,7 @@ bitbucket-cli - 0.17.3 + 0.17.4 Gildas Cherruel bitbucket-cli (Install) Gildas Cherruel @@ -18,7 +18,7 @@ Command line interface for Bitbucket The Bitbucket Command Line Interface brings the power of the Bitbucket platform to your command line. Creating and merging Pull Requests, cloning repositories, and more are now just a few keystrokes away. -- Use the Effective Default Reviewers of the repository when creating/updating Pull Requests. +- Obfuscation Support diff --git a/packaging/chocolatey/tools/chocolateyinstall.ps1 b/packaging/chocolatey/tools/chocolateyinstall.ps1 index 7791916..01deecd 100644 --- a/packaging/chocolatey/tools/chocolateyinstall.ps1 +++ b/packaging/chocolatey/tools/chocolateyinstall.ps1 @@ -5,9 +5,9 @@ $packageArgs = @{ packageName = $env:ChocolateyPackageName unzipLocation = $toolsDir fileType = 'exe' - file64 = "$toolsDir\bitbucket-cli-0.17.3-windows-amd64.7z" + file64 = "$toolsDir\bitbucket-cli-0.17.4-windows-amd64.7z" softwareName = 'bitbucket-cli*' - checksum64 = '8e6ed3dc943f5f3923333b870729ef6fcb7d8215afd98bb6566faa6cf3afb863' + checksum64 = '' checksumType64= 'sha256' } diff --git a/packaging/package-description.xml b/packaging/package-description.xml index 2a28f9a..d9cccf3 100644 --- a/packaging/package-description.xml +++ b/packaging/package-description.xml @@ -11,6 +11,7 @@ Note: This snapcraft is not affiliated with Atlassian. + diff --git a/packaging/snap/snapcraft.yaml b/packaging/snap/snapcraft.yaml index 85c522f..bbc6498 100644 --- a/packaging/snap/snapcraft.yaml +++ b/packaging/snap/snapcraft.yaml @@ -13,7 +13,7 @@ issues: https://github.com/gildas/bitbucket-cli/issues contact: - https://github.com/gildas/bitbucket-cli license: MIT -version: 0.17.3 +version: 0.17.4 base: core24 grade: stable confinement: strict diff --git a/testdata/pipeline-pullrequest.json b/testdata/pipeline-pullrequest.json new file mode 100644 index 0000000..01a5bec --- /dev/null +++ b/testdata/pipeline-pullrequest.json @@ -0,0 +1,90 @@ +{ + "type": "pipeline", + "uuid": "{a1b2c3d4-e5f6-7890-abcd-ef1234567890}", + "build_number": 42, + "state": { + "type": "pipeline_state_completed", + "name": "COMPLETED", + "result": { + "type": "pipeline_state_completed_failed", + "name": "FAILED" + } + }, + "target": { + "type": "pipeline_pullrequest_target", + "source": "frontend-develop-non-delete-key", + "destination": "main", + "destination_commit": { + "type": "commit", + "hash": "abc123def456" + }, + "commit": { + "type": "commit", + "hash": "3c80cde6b371" + }, + "selector": { + "type": "custom", + "pattern": "run-tests" + }, + "pullrequest": { + "type": "pullrequest", + "id": 62, + "title": "feat: add API key authentication", + "draft": false, + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/repositories/myworkspace/my-repo/pullrequests/62" + }, + "html": { + "href": "https://bitbucket.org/myworkspace/my-repo/pull-requests/62" + } + } + } + }, + "created_on": "2024-01-15T10:30:00+00:00", + "completed_on": "2024-01-15T10:35:30+00:00", + "duration_in_seconds": 330, + "creator": { + "type": "user", + "uuid": "{12345678-1234-1234-1234-123456789012}", + "account_id": "557058:12345678-abcd-efgh-ijkl-123456789012", + "display_name": "John Developer", + "nickname": "johnd", + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/users/%7B12345678-1234-1234-1234-123456789012%7D" + }, + "avatar": { + "href": "https://secure.gravatar.com/avatar/abc123" + }, + "html": { + "href": "https://bitbucket.org/%7B12345678-1234-1234-1234-123456789012%7D/" + } + } + }, + "repository": { + "type": "repository", + "uuid": "{12854e6a-e6f8-44ac-b006-1521931d4c0d}", + "name": "my-repo", + "full_name": "myworkspace/my-repo", + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/repositories/myworkspace/my-repo" + }, + "html": { + "href": "https://bitbucket.org/myworkspace/my-repo" + }, + "avatar": { + "href": "https://bytebucket.org/ravatar/%7B12854e6a-e6f8-44ac-b006-1521931d4c0d%7D" + } + } + }, + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/repositories/myworkspace/my-repo/pipelines/%7Bb2c3d4e5-f6a7-8901-bcde-f12345678901%7D" + }, + "steps": { + "href": "https://api.bitbucket.org/2.0/repositories/myworkspace/my-repo/pipelines/%7Bb2c3d4e5-f6a7-8901-bcde-f12345678901%7D/steps/" + } + } +} \ No newline at end of file diff --git a/testdata/pipeline.json b/testdata/pipeline.json index 703869b..dc38b02 100644 --- a/testdata/pipeline.json +++ b/testdata/pipeline.json @@ -45,7 +45,7 @@ }, "repository": { "type": "repository", - "uuid": "{repo-uuid-1234-5678-abcd}", + "uuid": "{12854e6a-e6f8-44ac-b006-1521931d4c0d}", "name": "my-repo", "full_name": "myworkspace/my-repo", "links": { @@ -56,7 +56,7 @@ "href": "https://bitbucket.org/myworkspace/my-repo" }, "avatar": { - "href": "https://bytebucket.org/ravatar/%7Brepo-uuid%7D" + "href": "https://bytebucket.org/ravatar/%7B12854e6a-e6f8-44ac-b006-1521931d4c0d%7D" } } }, diff --git a/version.go b/version.go index edd6491..0bae1c4 100644 --- a/version.go +++ b/version.go @@ -12,7 +12,7 @@ var branch string var stamp string // VERSION is the version of this application -var VERSION = "0.17.3" +var VERSION = "0.17.4" // APP is the name of the application const APP = "bb"