diff --git a/artifactory/utils/vcs.go b/artifactory/utils/vcs.go index ddf9f0f..0e7b0d2 100644 --- a/artifactory/utils/vcs.go +++ b/artifactory/utils/vcs.go @@ -2,6 +2,7 @@ package utils import ( "errors" + "fmt" buildinfo "github.com/jfrog/build-info-go/entities" gofrogcmd "github.com/jfrog/gofrog/io" utils2 "github.com/jfrog/jfrog-cli-artifactory/evidence/utils" @@ -163,6 +164,7 @@ func getMatchingRevisionFromBuild(buildInfo *buildinfo.BuildInfo, vcsUrl string) break } } + log.Info(fmt.Sprintf("base commit: %s for build name: %s and build number: %s", lastVcsRevision, buildInfo.Name, buildInfo.Number)) return lastVcsRevision } diff --git a/evidence/cli/command_cli.go b/evidence/cli/command_cli.go index 0506b72..92b59d2 100644 --- a/evidence/cli/command_cli.go +++ b/evidence/cli/command_cli.go @@ -161,6 +161,10 @@ func validateFoundSubjects(ctx *components.Context, foundSubjects []string) erro return nil } + if slices.Contains(foundSubjects, typeFlag) && slices.Contains(foundSubjects, releaseBundle) { + return nil + } + if slices.Contains(foundSubjects, typeFlag) && attemptSetBuildNameAndNumber(ctx) { return nil } @@ -192,6 +196,7 @@ func platformToEvidenceUrls(rtDetails *coreConfig.ServerDetails) { rtDetails.ArtifactoryUrl = utils.AddTrailingSlashIfNeeded(rtDetails.Url) + "artifactory/" rtDetails.EvidenceUrl = utils.AddTrailingSlashIfNeeded(rtDetails.Url) + "evidence/" rtDetails.MetadataUrl = utils.AddTrailingSlashIfNeeded(rtDetails.Url) + "metadata/" + rtDetails.LifecycleUrl = utils.AddTrailingSlashIfNeeded(rtDetails.Url) + "lifecycle/" } func assertValueProvided(c *components.Context, fieldName string) error { diff --git a/evidence/cli/command_github.go b/evidence/cli/command_github.go index 01a8c47..7c2c287 100644 --- a/evidence/cli/command_github.go +++ b/evidence/cli/command_github.go @@ -35,13 +35,23 @@ func (ebc *evidenceGitHubCommand) CreateEvidence(ctx *components.Context, server ebc.ctx.GetStringFlagValue(project), ebc.ctx.GetStringFlagValue(buildName), ebc.ctx.GetStringFlagValue(buildNumber), - ebc.ctx.GetStringFlagValue(typeFlag)) + ebc.ctx.GetStringFlagValue(typeFlag), + ebc.ctx.GetStringFlagValue(releaseBundle), + ebc.ctx.GetStringFlagValue(releaseBundleVersion)) return ebc.execute(createCmd) } func (ebc *evidenceGitHubCommand) validateEvidenceBuildContext(ctx *components.Context) error { - if !ctx.IsFlagSet(buildNumber) || assertValueProvided(ctx, buildNumber) != nil { - return errorutils.CheckErrorf("--%s is a mandatory field for creating a Release Bundle evidence", buildNumber) + if !ctx.IsFlagSet(typeFlag) { + return errorutils.CheckErrorf("--%s is a mandatory field for creating a GitHub evidence", typeFlag) } - return nil + if ctx.IsFlagSet(buildName) && assertValueProvided(ctx, buildName) == nil { + return nil + } + if ctx.IsFlagSet(releaseBundle) && assertValueProvided(ctx, releaseBundle) == nil && + ctx.IsFlagSet(releaseBundleVersion) && assertValueProvided(ctx, releaseBundleVersion) == nil { + return nil + } + return errorutils.CheckErrorf("Either --build-name or --release-bundle and --release-bundle-version " + + "are mandatory fields for creating a GitHub evidence") } diff --git a/evidence/create_github.go b/evidence/create_github.go index 7bc3bbc..f1901f6 100644 --- a/evidence/create_github.go +++ b/evidence/create_github.go @@ -14,7 +14,11 @@ import ( "github.com/jfrog/jfrog-cli-core/v2/common/build" coreConfig "github.com/jfrog/jfrog-cli-core/v2/utils/config" "github.com/jfrog/jfrog-client-go/artifactory" + "github.com/jfrog/jfrog-client-go/http/httpclient" + rtutils "github.com/jfrog/jfrog-client-go/utils" + "github.com/jfrog/jfrog-client-go/utils/errorutils" "github.com/jfrog/jfrog-client-go/utils/log" + "net/http" "os" "regexp" "strings" @@ -26,19 +30,24 @@ const ( FlagTypeCommitterReviewer FlagType = "gh-commiter" FlagTypeOther FlagType = "other" ) +const releaseBundleInternalApi = "api/v2/release_bundle/internal/graph/" +const releaseBundleApi = "api/v2/release_bundle/records/" -const ghDefaultPredicateType = "https://jfrog.com/evidence/gh-commiter/v1" +const ghDefaultPredicateType = "https://jfrog.com/evidence/git-committer-reviewer/v1" const gitFormat = `format:'{"commit":"%H","abbreviated_commit":"%h","tree":"%T","abbreviated_tree":"%t","parent":"%P","abbreviated_parent":"%p","subject":"%s","sanitized_subject_line":"%f","author":{"name":"%aN","email":"%aE","date":"%aD"},"commiter":{"name":"%cN","email":"%cE","date":"%cD"}}'` type createGitHubEvidence struct { createEvidenceBase - project string - buildName string - buildNumber string + project string + buildName string + buildNumber string + releaseBundle string + releaseBundleVersion string } -func NewCreateGithub(serverDetails *coreConfig.ServerDetails, predicateFilePath, predicateType, markdownFilePath, key, keyId, project, buildName, buildNumber, typeFlag string) Command { +func NewCreateGithub(serverDetails *coreConfig.ServerDetails, + predicateFilePath, predicateType, markdownFilePath, key, keyId, project, buildName, buildNumber, typeFlag, rbName, rbVersion string) Command { flagType := getFlagType(typeFlag) return &createGitHubEvidence{ createEvidenceBase: createEvidenceBase{ @@ -50,20 +59,23 @@ func NewCreateGithub(serverDetails *coreConfig.ServerDetails, predicateFilePath, keyId: keyId, flagType: flagType, }, - project: project, - buildName: buildName, - buildNumber: buildNumber, + project: project, + buildName: buildName, + buildNumber: buildNumber, + releaseBundle: rbName, + releaseBundleVersion: rbVersion, } } func getFlagType(typeFlag string) FlagType { - var flagType FlagType - if typeFlag == "gh-commiter" { - flagType = FlagTypeCommitterReviewer - } else { - flagType = FlagTypeOther + flagTypes := map[string]FlagType{ + "gh-commiter": FlagTypeCommitterReviewer, + } + + if flag, exists := flagTypes[typeFlag]; exists { + return flag } - return flagType + return FlagTypeOther } func (c *createGitHubEvidence) CommandName() string { @@ -78,6 +90,17 @@ func (c *createGitHubEvidence) Run() error { if !isRunningUnderGitHubAction() { return errors.New("this command is intended to be run under GitHub Actions") } + if c.buildName == "" && c.releaseBundle == "" { + return errors.New("build name or release bundle name is required") + } + + if c.releaseBundle != "" { + err := c.getBuildFromReleaseBundle() + if err != nil { + return err + } + } + evidencePredicate, err := c.committerReviewerEvidence() if err != nil { return err @@ -88,9 +111,18 @@ func (c *createGitHubEvidence) Run() error { log.Error("failed to create Artifactory client", err) return err } - subject, sha256, err := c.buildBuildInfoSubjectPath(artifactoryClient) - if err != nil { - return err + + var subject, sha256 string + if c.releaseBundle != "" && c.releaseBundleVersion != "" { + subject, sha256, err = c.buildReleaseBundleSubjectPath(artifactoryClient) + if err != nil { + return err + } + } else { + subject, sha256, err = c.buildBuildInfoSubjectPath(artifactoryClient) + if err != nil { + return err + } } envelope, err := c.createEnvelopeWithPredicateAndPredicateType(subject, sha256, ghDefaultPredicateType, evidencePredicate) @@ -125,6 +157,18 @@ func (c *createGitHubEvidence) buildBuildInfoSubjectPath(artifactoryClient artif return buildInfoPath, buildInfoChecksum, nil } +func (c *createGitHubEvidence) buildReleaseBundleSubjectPath(artifactoryClient artifactory.ArtifactoryServicesManager) (string, string, error) { + repoKey := buildRepoKey(c.project) + manifestPath := buildManifestPath(repoKey, c.releaseBundle, c.releaseBundleVersion) + + manifestChecksum, err := c.getFileChecksum(manifestPath, artifactoryClient) + if err != nil { + return "", "", err + } + + return manifestPath, manifestChecksum, nil +} + func isRunningUnderGitHubAction() bool { return os.Getenv("GITHUB_ACTIONS") == "true" } @@ -177,7 +221,7 @@ func marshalEvidenceToGitLogEntryView(evidence []byte) (*model.GitLogEntryView, func (c *createGitHubEvidence) committerReviewerEvidence() ([]byte, error) { if c.createEvidenceBase.flagType != FlagTypeCommitterReviewer { - return nil, errors.New("flag type must be gh-commiter") + return nil, errors.New("flag type is not supported") } createBuildConfiguration := c.createBuildConfiguration() @@ -195,8 +239,108 @@ func (c *createGitHubEvidence) createBuildConfiguration() *build.BuildConfigurat return buildConfiguration } +func (c *createGitHubEvidence) getBuildFromReleaseBundle() error { + releaseBundleResponse, err := c.getPreviousReleaseBundle() + if err != nil { + return err + } + if len(releaseBundleResponse.ReleaseBundles) == 0 { + return errors.New("no release bundles found") + } + if len(releaseBundleResponse.ReleaseBundles) > 1 { + // Get the previous release bundle + c.releaseBundleVersion = releaseBundleResponse.ReleaseBundles[1].ReleaseBundleVersion + } else { + c.releaseBundleVersion = releaseBundleResponse.ReleaseBundles[0].ReleaseBundleVersion + } + + rbv2Graph, err := c.getReleaseBundleGraph() + if err != nil { + return err + } + for _, node := range rbv2Graph.Root.Nodes { + if node.Type == "buildinfo" { + c.buildName = node.Name + c.buildNumber = node.Version + break + } + } + // Get the current release bundle to put the evidence on + c.releaseBundleVersion = releaseBundleResponse.ReleaseBundles[0].ReleaseBundleVersion + return nil +} + +func (c *createGitHubEvidence) getReleaseBundleGraph() (*model.GraphResponse, error) { + authConfig, err := c.serverDetails.CreateArtAuthConfig() + if err != nil { + return nil, err + } + + artifactoryApiUrl, err := rtutils.BuildUrl(c.serverDetails.GetLifecycleUrl(), releaseBundleInternalApi+c.releaseBundle+"/"+c.releaseBundleVersion, make(map[string]string)) + if err != nil { + return nil, err + } + + artHttpDetails := authConfig.CreateHttpClientDetails() + client, err := httpclient.ClientBuilder().Build() + if err != nil { + return nil, err + } + resp, body, _, err := client.SendGet(artifactoryApiUrl, true, artHttpDetails, "") + if err != nil { + return nil, err + } + if err = errorutils.CheckResponseStatusWithBody(resp, body, http.StatusOK); err != nil { + return nil, err + } + graphResponse := &model.GraphResponse{} + if err = json.Unmarshal(body, &graphResponse); err != nil { + return nil, errorutils.CheckError(err) + } + return graphResponse, nil +} + +func (c *createGitHubEvidence) getPreviousReleaseBundle() (*model.ReleaseBundlesResponse, error) { + authConfig, err := c.serverDetails.CreateArtAuthConfig() + if err != nil { + return nil, err + } + + queryParams := map[string]string{ + "project": c.project, + } + artifactoryApiUrl, err := rtutils.BuildUrl(c.serverDetails.GetLifecycleUrl(), releaseBundleApi+c.releaseBundle, queryParams) + if err != nil { + return nil, err + } + + artHttpDetails := authConfig.CreateHttpClientDetails() + client, err := httpclient.ClientBuilder().Build() + if err != nil { + return nil, err + } + resp, body, _, err := client.SendGet(artifactoryApiUrl, true, artHttpDetails, "") + if err != nil { + return nil, err + } + if err = errorutils.CheckResponseStatusWithBody(resp, body, http.StatusOK); err != nil { + return nil, err + } + + response := &model.ReleaseBundlesResponse{} + if err := json.Unmarshal(body, response); err != nil { + return nil, errorutils.CheckError(err) + } + return response, nil +} + +type PackageVersionResponseContent struct { + Version string `json:"Version,omitempty"` +} + func getGitCommitInfo(serverDetails *coreConfig.ServerDetails, createBuildConfiguration *build.BuildConfiguration, gitDetails artifactoryUtils.GitLogDetails) ([]byte, error) { owner, repository, err := gitHubRepositoryDetails() + log.Info(fmt.Sprintf("owner: %s repository: %s", owner, repository)) if err != nil { return nil, err } diff --git a/evidence/create_github_test.go b/evidence/create_github_test.go index d6c1112..ea251e1 100644 --- a/evidence/create_github_test.go +++ b/evidence/create_github_test.go @@ -34,7 +34,7 @@ func (m *MockBuildAndVcsDetails) GetLastBuildLink(serverDetails *coreConfig.Serv func TestNewCreateGithub(t *testing.T) { serverDetails := &coreConfig.ServerDetails{} - command := NewCreateGithub(serverDetails, "path/to/predicate.json", "predicateType", "path/to/markdown.md", "key", "keyId", "myProject", "myBuild", "123", "gh-commiter") + command := NewCreateGithub(serverDetails, "path/to/predicate.json", "predicateType", "path/to/markdown.md", "key", "keyId", "myProject", "myBuild", "123", "gh-commiter", "", "") assert.NotNil(t, command) diff --git a/evidence/model/release_bundle_graph.go b/evidence/model/release_bundle_graph.go new file mode 100644 index 0000000..f68517f --- /dev/null +++ b/evidence/model/release_bundle_graph.go @@ -0,0 +1,49 @@ +package model + +import "time" + +type GraphResponse struct { + Root Root `json:"root,omitempty"` +} + +// Root corresponds to the "root" key. +// All fields are pointers to allow for null values. +type Root struct { + Type string `json:"type,omitempty"` + Name string `json:"name,omitempty"` + Version string `json:"version,omitempty"` + Repository string `json:"repository,omitempty"` + CreatedMillis int64 `json:"created_millis,omitempty"` + Nodes []Node `json:"nodes,omitempty"` + Evidence []any `json:"evidence,omitempty"` +} + +// Node represents items in the "nodes" array (recursively). +// Again, all fields are pointers to allow them to be nil. +type Node struct { + Type string `json:"type,omitempty"` + Name string `json:"name,omitempty"` + Version string `json:"version,omitempty"` + Repository string `json:"repository,omitempty"` + CreatedMillis int64 `json:"created_millis,omitempty"` + Nodes []Node `json:"nodes,omitempty"` + Evidence []any `json:"evidence,omitempty"` + PackageID string `json:"package_id,omitempty"` +} + +type ReleaseBundle struct { + Status string `json:"status"` + RepositoryKey string `json:"repository_key"` + ReleaseBundleName string `json:"release_bundle_name"` + ReleaseBundleVersion string `json:"release_bundle_version"` + ServiceID string `json:"service_id"` + CreatedBy string `json:"created_by"` + Created time.Time `json:"created"` +} + +type ReleaseBundlesResponse struct { + ReleaseBundles []ReleaseBundle `json:"release_bundles"` + Total int `json:"total"` + Limit int `json:"limit"` + Offset int `json:"offset"` +} diff --git a/go.mod b/go.mod index 580ebab..da66de5 100644 --- a/go.mod +++ b/go.mod @@ -2,13 +2,11 @@ module github.com/jfrog/jfrog-cli-artifactory go 1.23.4 -toolchain go1.23.5 - require ( github.com/c-bata/go-prompt v0.2.5 github.com/forPelevin/gomoji v1.2.0 github.com/jfrog/build-info-go v1.10.9 - github.com/jfrog/froggit-go v1.16.2 + github.com/jfrog/froggit-go v0.0.0-00010101000000-000000000000 github.com/jfrog/gofrog v1.7.6 github.com/jfrog/jfrog-cli-core/v2 v2.58.0 github.com/jfrog/jfrog-client-go v1.50.0 @@ -119,7 +117,6 @@ require ( golang.org/x/term v0.29.0 // indirect golang.org/x/text v0.21.0 // indirect golang.org/x/time v0.7.0 // indirect - golang.org/x/tools v0.29.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect @@ -135,11 +132,14 @@ require ( sigs.k8s.io/yaml v1.4.0 // indirect ) -//replace github.com/jfrog/jfrog-cli-core/v2 => github.com/jfrog/jfrog-cli-core/v2 v2.31.1-0.20250130104846-27e495de291e -replace github.com/jfrog/jfrog-cli-core/v2 => github.com/EyalDelarea/jfrog-cli-core/v2 v2.0.0-20250206084646-819832cab1e1 - //replace github.com/jfrog/jfrog-cli-core/v2 => github.com/jfrog/jfrog-cli-core/v2 v2.31.1-0.20250212021126-e5223ab616af +replace github.com/jfrog/jfrog-cli-core/v2 => github.com/EyalDelarea/jfrog-cli-core/v2 v2.0.0-20250212163056-052cba06bfea + +// replace github.com/jfrog/jfrog-client-go => github.com/jfrog/jfrog-client-go v1.28.1-0.20250126110945-81abbdde452f + +//replace github.com/jfrog/jfrog-cli-core/v2 => github.com/jfrog/jfrog-cli-core/v2 v2.31.1-0.20240811150357-12a9330a2d67 +//replace github.com/jfrog/jfrog-client-go => github.com/jfrog/jfrog-client-go v1.28.1-0.20240811142930-ab9715567376 replace github.com/jfrog/froggit-go => github.com/EyalDelarea/froggit-go v1.6.1-0.20250204105801-761f8d527d7f -replace github.com/jfrog/build-info-go => github.com/jfrog/build-info-go v1.8.9-0.20250203111011-4ff16d3d42be +replace github.com/jfrog/jfrog-client-go => github.com/lesnerd/jfrog-client-go v0.0.0-20250216170623-d841f33debec diff --git a/go.sum b/go.sum index f04b617..b6ac996 100644 --- a/go.sum +++ b/go.sum @@ -6,8 +6,10 @@ github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0 github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/CycloneDX/cyclonedx-go v0.9.2 h1:688QHn2X/5nRezKe2ueIVCt+NRqf7fl3AVQk+vaFcIo= github.com/CycloneDX/cyclonedx-go v0.9.2/go.mod h1:vcK6pKgO1WanCdd61qx4bFnSsDJQ6SbM2ZuMIgq86Jg= +github.com/EyalDelarea/froggit-go v1.6.1-0.20250204105801-761f8d527d7f h1:XOJgHjE+zocmRlBacDFD0wiX9OsZZTd0qRR65/L8myE= github.com/EyalDelarea/froggit-go v1.6.1-0.20250204105801-761f8d527d7f/go.mod h1:HvDkfFfJwIdsXFdqaB+utvD2cLDRmaC3kF8otYb6Chw= -github.com/EyalDelarea/jfrog-cli-core/v2 v2.0.0-20250206084646-819832cab1e1/go.mod h1:Hx2houXADsNv0eRh4w5XCS2uSsPNPn1OmiSDdwGFB7g= +github.com/EyalDelarea/jfrog-cli-core/v2 v2.0.0-20250212163056-052cba06bfea h1:4atnytJRW+AAEt1szegncoMlrUZnCNqoG888mcJDrdI= +github.com/EyalDelarea/jfrog-cli-core/v2 v2.0.0-20250212163056-052cba06bfea/go.mod h1:Hx2houXADsNv0eRh4w5XCS2uSsPNPn1OmiSDdwGFB7g= github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= @@ -59,12 +61,15 @@ github.com/elazarl/goproxy v1.4.0 h1:4GyuSbFa+s26+3rmYNSuUVsx+HgPrV1bk1jXI0l9wjM github.com/elazarl/goproxy v1.4.0/go.mod h1:X/5W/t+gzDyLfHW4DrMdpjqYjpXsURlBt9lpBDxZZZQ= github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= +github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= +github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= github.com/forPelevin/gomoji v1.2.0 h1:9k4WVSSkE1ARO/BWywxgEUBvR/jMnao6EZzrql5nxJ8= github.com/forPelevin/gomoji v1.2.0/go.mod h1:8+Z3KNGkdslmeGZBC3tCrwMrcPy5GRzAD+gL9NAwMXg= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/gfleury/go-bitbucket-v1 v0.0.0-20230825095122-9bc1711434ab h1:+7KwW/yy/ThnRXW9khailFFncxJiiFpxyk5BI9GK9pI= github.com/gfleury/go-bitbucket-v1 v0.0.0-20230825095122-9bc1711434ab/go.mod h1:IqOZzks2wlWCIai0esXnZPdPwxF2yOz0HcCYw5I4pCg= github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c= github.com/gliderlabs/ssh v0.3.8/go.mod h1:xYoytBv1sV0aL3CavoDuJIQNURXkkfPA/wxQ1pL1fAU= @@ -97,7 +102,9 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-github/v56 v56.0.0 h1:TysL7dMa/r7wsQi44BjqlwaHvwlFlqkK8CtBWCX3gb4= github.com/google/go-github/v56 v56.0.0/go.mod h1:D8cdcX98YWJvi7TLo7zM4/h8ZTx6u6fwGEkCdisopo0= +github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= @@ -109,8 +116,13 @@ 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/gookit/color v1.5.4 h1:FZmqs7XOyGgCAxmWyPslpiok1k05wmY3SJTytgvYFs0= github.com/gookit/color v1.5.4/go.mod h1:pZJOeOS8DM43rXbp4AZo1n9zCU2qjpcRko0b6/QJi9w= +github.com/grokify/mogo v0.64.12 h1:BNrZ1qBFuX4qu5722CW6qtqu/mrrsZ3bhKu/w1KowKg= github.com/grokify/mogo v0.64.12/go.mod h1:lDhfYIiOhJo7C2U3aL00PlUU9gLvmTONi4MdIWoGmGM= +github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= +github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= +github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= +github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISHxT2Q8+VepXU= github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= @@ -122,15 +134,10 @@ github.com/jedib0t/go-pretty/v6 v6.6.5 h1:9PgMJOVBedpgYLI56jQRJYqngxYAAzfEUua+3N github.com/jedib0t/go-pretty/v6 v6.6.5/go.mod h1:Uq/HrbhuFty5WSVNfjpQQe47x16RwVGXIveNGEyGtHs= github.com/jfrog/archiver/v3 v3.6.1 h1:LOxnkw9pOn45DzCbZNFV6K0+6dCsQ0L8mR3ZcujO5eI= github.com/jfrog/archiver/v3 v3.6.1/go.mod h1:VgR+3WZS4N+i9FaDwLZbq+jeU4B4zctXL+gL4EMzfLw= -github.com/jfrog/build-info-go v1.8.9-0.20250203111011-4ff16d3d42be/go.mod h1:JcISnovFXKx3wWf3p1fcMmlPdt6adxScXvoJN4WXqIE= github.com/jfrog/build-info-go v1.10.9 h1:mdJ+wlLw2ReFsqC7rifJVlRYLEqYk38uXDYAOZASuGE= github.com/jfrog/build-info-go v1.10.9/go.mod h1:JcISnovFXKx3wWf3p1fcMmlPdt6adxScXvoJN4WXqIE= github.com/jfrog/gofrog v1.7.6 h1:QmfAiRzVyaI7JYGsB7cxfAJePAZTzFz0gRWZSE27c6s= github.com/jfrog/gofrog v1.7.6/go.mod h1:ntr1txqNOZtHplmaNd7rS4f8jpA5Apx8em70oYEe7+4= -github.com/jfrog/jfrog-cli-core/v2 v2.31.1-0.20250212021126-e5223ab616af h1:XnyhhyARP1YCzYGdhk8ovpyZV+hSchiTGVTuejrZXsI= -github.com/jfrog/jfrog-cli-core/v2 v2.31.1-0.20250212021126-e5223ab616af/go.mod h1:Hx2houXADsNv0eRh4w5XCS2uSsPNPn1OmiSDdwGFB7g= -github.com/jfrog/jfrog-client-go v1.50.0 h1:t7v/zpLkPomHR6ZjVbPQ1WPQJd9IFKESK9Tt6phZz3k= -github.com/jfrog/jfrog-client-go v1.50.0/go.mod h1:xHxwKBjPSUBd/FyCWgusfHmSWKUZTkfOZkTmntC2F5Y= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= @@ -156,7 +163,10 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/ktrysmt/go-bitbucket v0.9.80 h1:S+vZTXKx/VG5yCaX4I3Bmwo8lxWr4ifvuHdTboHTMMc= github.com/ktrysmt/go-bitbucket v0.9.80/go.mod h1:b8ogWEGxQMWoeFnT1ZE4aHIPGindI+9z/zAW/OVFjk0= +github.com/lesnerd/jfrog-client-go v0.0.0-20250216170623-d841f33debec h1:Yv4QZ3k5gEGZOeGaxK4l+DtIjwUJb9Do+GZjAyMGLdg= +github.com/lesnerd/jfrog-client-go v0.0.0-20250216170623-d841f33debec/go.mod h1:xHxwKBjPSUBd/FyCWgusfHmSWKUZTkfOZkTmntC2F5Y= github.com/magiconair/properties v1.8.9 h1:nWcCbLq1N2v/cpNsy5WvQ37Fb+YElfq20WJ/a8RkpQM= github.com/magiconair/properties v1.8.9/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA= @@ -178,6 +188,7 @@ github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6T github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-tty v0.0.3 h1:5OfyWorkyO7xP52Mq7tB36ajHDG5OHrmBGIS/DtakQI= github.com/mattn/go-tty v0.0.3/go.mod h1:ihxohKRERHTVzN+aSVRwACLCeqIoZAWpoICkkvrWyR0= +github.com/microsoft/azure-devops-go-api/azuredevops/v7 v7.1.0 h1:mmJCWLe63QvybxhW1iBmQWEaCKdc4SKgALfTNZ+OphU= github.com/microsoft/azure-devops-go-api/azuredevops/v7 v7.1.0/go.mod h1:mDunUZ1IUJdJIRHvFb+LPBUtxe3AYB5MI6BMXNg8194= github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM= github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= @@ -246,6 +257,7 @@ github.com/stoewer/go-strcase v1.3.0/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8w github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= @@ -268,6 +280,7 @@ github.com/urfave/cli v1.22.16 h1:MH0k6uJxdwdeWQTwhSO42Pwr4YLrNLwBtg1MRgTqPdQ= github.com/urfave/cli v1.22.16/go.mod h1:EeJR6BKodywf4zciqrdw6hpCPk68JO9z5LazXZMn5Po= github.com/vbauerster/mpb/v8 v8.9.1 h1:LH5R3lXPfE2e3lIGxN7WNWv3Hl5nWO6LRi2B0L0ERHw= github.com/vbauerster/mpb/v8 v8.9.1/go.mod h1:4XMvznPh8nfe2NpnDo1QTPvW9MVkUhbG90mPWvmOzcQ= +github.com/xanzy/go-gitlab v0.110.0 h1:hsFIFp01v/0D0sdUXoZfRk6CROzZbHQplk6NzKSFKhc= github.com/xanzy/go-gitlab v0.110.0/go.mod h1:wKNKh3GkYDMOsGmnfuX+ITCmDuSDWFO0G+C4AygL9RY= github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= @@ -329,6 +342,7 @@ golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs= golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -384,6 +398,7 @@ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ= golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=