Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Lifecycle Release Bundle Distribute #2068

Merged
merged 6 commits into from
Aug 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading