Skip to content

Commit

Permalink
Support Lifecycle Release Bundle Distribute (#2068)
Browse files Browse the repository at this point in the history
  • Loading branch information
RobiNino authored Aug 30, 2023
1 parent d71026b commit c72d7d8
Show file tree
Hide file tree
Showing 12 changed files with 297 additions and 103 deletions.
44 changes: 44 additions & 0 deletions .github/workflows/lifecycleTests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: Lifecycle Tests
on:
push:
branches:
- '**'
tags-ignore:
- '**'
# Triggers the workflow on labeled PRs only.
pull_request_target:
types: [labeled]
# Ensures that only the latest commit is running for each PR at a time.
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}-${{ github.ref }}
cancel-in-progress: true
jobs:
Lifecycle-Tests:
if: contains(github.event.pull_request.labels.*.name, 'safe to test') || github.event_name == 'push'
name: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- name: Install Go
uses: actions/setup-go@v3
with:
go-version: 1.20.x
- name: Checkout code
uses: actions/checkout@v3
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Go Cache
uses: actions/cache@v3
with:
path: ~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: ${{ runner.os }}-go-
- name: Checkout code
uses: actions/checkout@v3
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Run Lifecycle tests
run: go test -v github.com/jfrog/jfrog-cli --timeout 0 --test.lifecycle --jfrog.url=${{ secrets.PLATFORM_URL }} --jfrog.adminToken=${{ secrets.PLATFORM_ADMIN_TOKEN }} --jfrog.user=${{ secrets.PLATFORM_USER }} --ci.runId=${{ runner.os }}-lifecycle
76 changes: 25 additions & 51 deletions distribution/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@ package distribution

import (
"errors"
"os"
"path/filepath"
"strings"

"github.com/jfrog/jfrog-cli-core/v2/common/commands"
"github.com/jfrog/jfrog-cli-core/v2/common/spec"
distributionCommands "github.com/jfrog/jfrog-cli-core/v2/distribution/commands"
Expand All @@ -18,10 +14,14 @@ import (
"github.com/jfrog/jfrog-cli/docs/artifactory/releasebundleupdate"
"github.com/jfrog/jfrog-cli/docs/common"
"github.com/jfrog/jfrog-cli/utils/cliutils"
"github.com/jfrog/jfrog-cli/utils/distribution"
distributionServices "github.com/jfrog/jfrog-client-go/distribution/services"
distributionServicesUtils "github.com/jfrog/jfrog-client-go/distribution/services/utils"
"github.com/jfrog/jfrog-client-go/utils/errorutils"
"github.com/urfave/cli"
"os"
"path/filepath"
"strings"
)

func GetCommands() []cli.Command {
Expand Down Expand Up @@ -111,11 +111,11 @@ func releaseBundleCreateCmd(c *cli.Context) error {
return err
}
releaseBundleCreateCmd := distributionCommands.NewReleaseBundleCreateCommand()
rtDetails, err := createArtifactoryDetailsByFlags(c)
dsDetails, err := createDistributionDetailsByFlags(c)
if err != nil {
return err
}
releaseBundleCreateCmd.SetServerDetails(rtDetails).SetReleaseBundleCreateParams(params).SetSpec(releaseBundleCreateSpec).SetDryRun(c.Bool("dry-run")).SetDetailedSummary(c.Bool("detailed-summary"))
releaseBundleCreateCmd.SetServerDetails(dsDetails).SetReleaseBundleCreateParams(params).SetSpec(releaseBundleCreateSpec).SetDryRun(c.Bool("dry-run")).SetDetailedSummary(c.Bool("detailed-summary"))

err = commands.Exec(releaseBundleCreateCmd)
if releaseBundleCreateCmd.IsDetailedSummary() {
Expand Down Expand Up @@ -153,11 +153,11 @@ func releaseBundleUpdateCmd(c *cli.Context) error {
return err
}
releaseBundleUpdateCmd := distributionCommands.NewReleaseBundleUpdateCommand()
rtDetails, err := createArtifactoryDetailsByFlags(c)
dsDetails, err := createDistributionDetailsByFlags(c)
if err != nil {
return err
}
releaseBundleUpdateCmd.SetServerDetails(rtDetails).SetReleaseBundleUpdateParams(params).SetSpec(releaseBundleUpdateSpec).SetDryRun(c.Bool("dry-run")).SetDetailedSummary(c.Bool("detailed-summary"))
releaseBundleUpdateCmd.SetServerDetails(dsDetails).SetReleaseBundleUpdateParams(params).SetSpec(releaseBundleUpdateSpec).SetDryRun(c.Bool("dry-run")).SetDetailedSummary(c.Bool("detailed-summary"))

err = commands.Exec(releaseBundleUpdateCmd)
if releaseBundleUpdateCmd.IsDetailedSummary() {
Expand All @@ -177,11 +177,11 @@ func releaseBundleSignCmd(c *cli.Context) error {
params.StoringRepository = c.String("repo")
params.GpgPassphrase = c.String("passphrase")
releaseBundleSignCmd := distributionCommands.NewReleaseBundleSignCommand()
rtDetails, err := createArtifactoryDetailsByFlags(c)
dsDetails, err := createDistributionDetailsByFlags(c)
if err != nil {
return err
}
releaseBundleSignCmd.SetServerDetails(rtDetails).SetReleaseBundleSignParams(params).SetDetailedSummary(c.Bool("detailed-summary"))
releaseBundleSignCmd.SetServerDetails(dsDetails).SetReleaseBundleSignParams(params).SetDetailedSummary(c.Bool("detailed-summary"))
err = commands.Exec(releaseBundleSignCmd)
if releaseBundleSignCmd.IsDetailedSummary() {
if summary := releaseBundleSignCmd.GetSummary(); summary != nil {
Expand All @@ -192,45 +192,29 @@ func releaseBundleSignCmd(c *cli.Context) error {
}

func releaseBundleDistributeCmd(c *cli.Context) error {
if c.NArg() != 2 {
return cliutils.WrongNumberOfArgumentsHandler(c)
}
if c.IsSet("max-wait-minutes") && !c.IsSet("sync") {
return cliutils.PrintHelpAndReturnError("The --max-wait-minutes option can't be used without --sync", c)
}
var distributionRules *spec.DistributionRules
if c.IsSet("dist-rules") {
if c.IsSet("site") || c.IsSet("city") || c.IsSet("country-code") {
return cliutils.PrintHelpAndReturnError("The --dist-rules option can't be used with --site, --city or --country-code", c)
}
var err error
distributionRules, err = spec.CreateDistributionRulesFromFile(c.String("dist-rules"))
if err != nil {
return err
}
} else {
distributionRules = createDefaultDistributionRules(c)
if err := distribution.ValidateReleaseBundleDistributeCmd(c); err != nil {
return err
}

params := distributionServices.NewDistributeReleaseBundleParams(c.Args().Get(0), c.Args().Get(1))
releaseBundleDistributeCmd := distributionCommands.NewReleaseBundleDistributeCommand()
rtDetails, err := createArtifactoryDetailsByFlags(c)
dsDetails, err := createDistributionDetailsByFlags(c)
if err != nil {
return err
}
maxWaitMinutes, err := cliutils.GetIntFlagValue(c, "max-wait-minutes", 60)
distributionRules, maxWaitMinutes, params, err := distribution.InitReleaseBundleDistributeCmd(c)
if err != nil {
return err
}
releaseBundleDistributeCmd.SetServerDetails(rtDetails).

distributeCmd := distributionCommands.NewReleaseBundleDistributeV1Command()
distributeCmd.SetServerDetails(dsDetails).
SetDistributeBundleParams(params).
SetDistributionRules(distributionRules).
SetDryRun(c.Bool("dry-run")).
SetSync(c.Bool("sync")).
SetMaxWaitMinutes(maxWaitMinutes).
SetAutoCreateRepo(c.Bool("create-repo"))

return commands.Exec(releaseBundleDistributeCmd)
return commands.Exec(distributeCmd)
}

func releaseBundleDeleteCmd(c *cli.Context) error {
Expand All @@ -248,7 +232,7 @@ func releaseBundleDeleteCmd(c *cli.Context) error {
return err
}
} else {
distributionRules = createDefaultDistributionRules(c)
distributionRules = distribution.CreateDefaultDistributionRules(c)
}

params := distributionServices.NewDeleteReleaseBundleParams(c.Args().Get(0), c.Args().Get(1))
Expand All @@ -260,11 +244,11 @@ func releaseBundleDeleteCmd(c *cli.Context) error {
}
params.MaxWaitMinutes = maxWaitMinutes
distributeBundleCmd := distributionCommands.NewReleaseBundleDeleteParams()
rtDetails, err := createArtifactoryDetailsByFlags(c)
dsDetails, err := createDistributionDetailsByFlags(c)
if err != nil {
return err
}
distributeBundleCmd.SetQuiet(cliutils.GetQuietValue(c)).SetServerDetails(rtDetails).SetDistributeBundleParams(params).SetDistributionRules(distributionRules).SetDryRun(c.Bool("dry-run"))
distributeBundleCmd.SetQuiet(cliutils.GetQuietValue(c)).SetServerDetails(dsDetails).SetDistributeBundleParams(params).SetDistributionRules(distributionRules).SetDryRun(c.Bool("dry-run"))

return commands.Exec(distributeBundleCmd)
}
Expand All @@ -283,16 +267,6 @@ func createDefaultReleaseBundleSpec(c *cli.Context) *spec.SpecFiles {
BuildSpec()
}

func createDefaultDistributionRules(c *cli.Context) *spec.DistributionRules {
return &spec.DistributionRules{
DistributionRules: []spec.DistributionRule{{
SiteName: c.String("site"),
CityName: c.String("city"),
CountryCodes: cliutils.GetStringsArrFlagValue(c, "country-codes"),
}},
}
}

func createReleaseBundleCreateUpdateParams(c *cli.Context, bundleName, bundleVersion string) (distributionServicesUtils.ReleaseBundleParams, error) {
releaseBundleParams := distributionServicesUtils.NewReleaseBundleParams(bundleName, bundleVersion)
releaseBundleParams.SignImmediately = c.Bool("sign")
Expand Down Expand Up @@ -336,13 +310,13 @@ func populateReleaseNotesSyntax(c *cli.Context) (distributionServicesUtils.Relea
return distributionServicesUtils.PlainText, nil
}

func createArtifactoryDetailsByFlags(c *cli.Context) (*coreConfig.ServerDetails, error) {
artDetails, err := cliutils.CreateServerDetailsWithConfigOffer(c, true, cliutils.Ds)
func createDistributionDetailsByFlags(c *cli.Context) (*coreConfig.ServerDetails, error) {
dsDetails, err := cliutils.CreateServerDetailsWithConfigOffer(c, true, cliutils.Ds)
if err != nil {
return nil, err
}
if artDetails.DistributionUrl == "" {
if dsDetails.DistributionUrl == "" {
return nil, errors.New("the --dist-url option is mandatory")
}
return artDetails, nil
return dsDetails, nil
}
3 changes: 2 additions & 1 deletion distribution_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
distributionServices "github.com/jfrog/jfrog-client-go/distribution/services"
clientDistUtils "github.com/jfrog/jfrog-client-go/distribution/services/utils"
clientUtils "github.com/jfrog/jfrog-client-go/utils"
"github.com/jfrog/jfrog-client-go/utils/distribution"
"github.com/jfrog/jfrog-client-go/utils/io/fileutils"
"github.com/jfrog/jfrog-client-go/utils/io/httputils"
"github.com/jfrog/jfrog-client-go/utils/log"
Expand Down Expand Up @@ -566,7 +567,7 @@ func TestDistributeSyncTimeout(t *testing.T) {
testServer, mockServerDetails, _ := coreTestUtils.CreateDsRestsMockServer(t, func(w http.ResponseWriter, r *http.Request) {
if r.RequestURI == "/api/v1/distribution/"+tests.BundleName+"/"+bundleVersion {
w.WriteHeader(http.StatusOK)
content, err := json.Marshal(distributionServices.DistributionResponseBody{TrackerId: json.Number(trackerId)})
content, err := json.Marshal(distribution.DistributionResponseBody{TrackerId: json.Number(trackerId)})
assert.NoError(t, err)
_, err = w.Write(content)
assert.NoError(t, err)
Expand Down
15 changes: 15 additions & 0 deletions docs/lifecycle/distribute/help.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package distribute

var Usage = []string{"rbd [command options] <release bundle name> <release bundle version>"}

func GetDescription() string {
return "Distribute a release bundle."
}

func GetArguments() string {
return ` release bundle name
Name of the Release Bundle to distribute.
release bundle version
Version of the Release Bundle to distribute.`
}
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,8 @@ require (

// replace github.com/jfrog/build-info-go => github.com/jfrog/build-info-go v1.8.9-0.20230828134416-f0db33dd9344

// replace github.com/jfrog/jfrog-cli-core/v2 => github.com/jfrog/jfrog-cli-core/v2 v2.31.1-0.20230828140932-e44caa02288e
replace github.com/jfrog/jfrog-cli-core/v2 => github.com/jfrog/jfrog-cli-core/v2 v2.31.1-0.20230830130857-c5a2b11b52be

// replace github.com/jfrog/gofrog => github.com/jfrog/gofrog v1.2.6-0.20230418122323-2bf299dd6d27

// replace github.com/jfrog/jfrog-client-go => github.com/jfrog/jfrog-client-go v1.28.1-0.20230803140217-0a5f43783ae8
replace github.com/jfrog/jfrog-client-go => github.com/jfrog/jfrog-client-go v1.28.1-0.20230830130057-df2d2a80b555
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -241,10 +241,10 @@ github.com/jfrog/build-info-go v1.9.9 h1:YMA9okHawBNL8SrCWzqULSf5M4W+YnWyUhmkWSj
github.com/jfrog/build-info-go v1.9.9/go.mod h1:t31QRpH5xUJKw8XkQlAA+Aq7aanyS1rrzpcK8xSNVts=
github.com/jfrog/gofrog v1.3.0 h1:o4zgsBZE4QyDbz2M7D4K6fXPTBJht+8lE87mS9bw7Gk=
github.com/jfrog/gofrog v1.3.0/go.mod h1:IFMc+V/yf7rA5WZ74CSbXe+Lgf0iApEQLxRZVzKRUR0=
github.com/jfrog/jfrog-cli-core/v2 v2.41.4 h1:+V35NN+UaKl6ZFSjAyZFZ4VijCgsORnGsHug02DROdE=
github.com/jfrog/jfrog-cli-core/v2 v2.41.4/go.mod h1:Mi3WFUzG2CU6tlLpGsMNRaKkhH/tIMuci4tjnPZ9S3M=
github.com/jfrog/jfrog-client-go v1.31.6 h1:uWuyT4BDm9s5ES6oDTBny9Gl6yf8iKFjcbmHSHQZrDc=
github.com/jfrog/jfrog-client-go v1.31.6/go.mod h1:icb00ZJN/mMMNkQduHDkzpqsXH9Flwi3f3COYexq3Nc=
github.com/jfrog/jfrog-cli-core/v2 v2.31.1-0.20230830130857-c5a2b11b52be h1:MjbSKQy937o0WFBKCXtvkX4EUSPCaA1LIhGISJUjYbU=
github.com/jfrog/jfrog-cli-core/v2 v2.31.1-0.20230830130857-c5a2b11b52be/go.mod h1:kaFzB3X83/jdzMcuGOYOaqnlz5MVTnDYt/asrOsCv18=
github.com/jfrog/jfrog-client-go v1.28.1-0.20230830130057-df2d2a80b555 h1:yaF5J4LNk+ws5+j+BFMJ43NMqpKuCtF7dUfCeGLttl8=
github.com/jfrog/jfrog-client-go v1.28.1-0.20230830130057-df2d2a80b555/go.mod h1:icb00ZJN/mMMNkQduHDkzpqsXH9Flwi3f3COYexq3Nc=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/jszwec/csvutil v1.8.0 h1:G7vS2LGdpZZDH1HmHeNbxOaJ/ZnJlpwGFvOkTkJzzNk=
Expand Down
58 changes: 56 additions & 2 deletions lifecycle/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ import (
coreConfig "github.com/jfrog/jfrog-cli-core/v2/utils/config"
"github.com/jfrog/jfrog-cli/docs/common"
rbCreate "github.com/jfrog/jfrog-cli/docs/lifecycle/create"
rbDistribute "github.com/jfrog/jfrog-cli/docs/lifecycle/distribute"
rbPromote "github.com/jfrog/jfrog-cli/docs/lifecycle/promote"
"github.com/jfrog/jfrog-cli/utils/cliutils"
"github.com/jfrog/jfrog-cli/utils/distribution"
"github.com/jfrog/jfrog-client-go/utils"
"github.com/jfrog/jfrog-client-go/utils/errorutils"
"github.com/urfave/cli"
Expand Down Expand Up @@ -43,6 +45,19 @@ func GetCommands() []cli.Command {
Category: lcCategory,
Action: promote,
},
{
Name: "release-bundle-distribute",
Aliases: []string{"rbd"},
Flags: cliutils.GetCommandFlags(cliutils.ReleaseBundleDistribute),
Usage: rbDistribute.GetDescription(),
HelpName: coreCommon.CreateUsage("rbd", rbDistribute.GetDescription(), rbDistribute.Usage),
UsageText: rbDistribute.GetArguments(),
ArgsUsage: common.CreateEnvVars(),
BashComplete: coreCommon.CreateBashCompletionFunc(),
Category: lcCategory,
Hidden: true,
Action: distribute,
},
})
}

Expand Down Expand Up @@ -77,7 +92,7 @@ func create(c *cli.Context) (err error) {
return
}

createCmd := lifecycle.NewReleaseBundleCreate().SetServerDetails(lcDetails).SetReleaseBundleName(c.Args().Get(0)).
createCmd := lifecycle.NewReleaseBundleCreateCommand().SetServerDetails(lcDetails).SetReleaseBundleName(c.Args().Get(0)).
SetReleaseBundleVersion(c.Args().Get(1)).SetSigningKeyName(c.String(cliutils.SigningKey)).SetSync(c.Bool(cliutils.Sync)).
SetReleaseBundleProject(cliutils.GetProject(c)).SetBuildsSpecPath(c.String(cliutils.Builds)).
SetReleaseBundlesSpecPath(c.String(cliutils.ReleaseBundles))
Expand All @@ -102,12 +117,51 @@ func promote(c *cli.Context) error {
return err
}

createCmd := lifecycle.NewReleaseBundlePromote().SetServerDetails(lcDetails).SetReleaseBundleName(c.Args().Get(0)).
createCmd := lifecycle.NewReleaseBundlePromoteCommand().SetServerDetails(lcDetails).SetReleaseBundleName(c.Args().Get(0)).
SetReleaseBundleVersion(c.Args().Get(1)).SetEnvironment(c.Args().Get(2)).SetSigningKeyName(c.String(cliutils.SigningKey)).
SetSync(c.Bool(cliutils.Sync)).SetReleaseBundleProject(cliutils.GetProject(c)).SetOverwrite(c.Bool(cliutils.Overwrite))
return commands.Exec(createCmd)
}

func distribute(c *cli.Context) error {
if err := validateDistributeCommand(c); err != nil {
return err
}

lcDetails, err := createLifecycleDetailsByFlags(c)
if err != nil {
return err
}
distributionRules, _, params, err := distribution.InitReleaseBundleDistributeCmd(c)
if err != nil {
return err
}

distributeCmd := lifecycle.NewReleaseBundleDistributeCommand()
distributeCmd.SetServerDetails(lcDetails).
SetDistributeBundleParams(params).
SetDistributionRules(distributionRules).
SetDryRun(c.Bool("dry-run")).
SetAutoCreateRepo(c.Bool(cliutils.CreateRepo)).
SetPathMappingPattern(c.String(cliutils.PathMappingPattern)).
SetPathMappingTarget(c.String(cliutils.PathMappingTarget))
return commands.Exec(distributeCmd)
}

func validateDistributeCommand(c *cli.Context) error {
if err := distribution.ValidateReleaseBundleDistributeCmd(c); err != nil {
return err
}

mappingPatternProvided := c.IsSet(cliutils.PathMappingPattern)
mappingTargetProvided := c.IsSet(cliutils.PathMappingTarget)
if (mappingPatternProvided && !mappingTargetProvided) ||
(!mappingPatternProvided && mappingTargetProvided) {
return errorutils.CheckErrorf("the options --%s and --%s must be provided together", cliutils.PathMappingPattern, cliutils.PathMappingTarget)
}
return nil
}

func assertSigningKeyProvided(c *cli.Context) error {
if c.String(cliutils.SigningKey) == "" {
return errorutils.CheckErrorf("the --%s option is mandatory", cliutils.SigningKey)
Expand Down
Loading

0 comments on commit c72d7d8

Please sign in to comment.