Skip to content

Commit 667c810

Browse files
authored
Enable lifecycle release bundle distribute (#2185)
1 parent 2821ca8 commit 667c810

File tree

7 files changed

+134
-21
lines changed

7 files changed

+134
-21
lines changed

Diff for: documentation/CLI-for-JFrog-Lifecycle.md

+66
Original file line numberDiff line numberDiff line change
@@ -121,3 +121,69 @@ Use signing key pair "myKeyPair" and overwrite in case of conflicts.
121121
```
122122
jf rbp --signing-key=myKeyPair --project=project0 --overwrite=true --sync=true myApp 1.0.0 PROD
123123
```
124+
125+
### Distributing a release bundle
126+
127+
This command distributes a Release Bundle v2 to an edge node.
128+
129+
| | |
130+
|------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
131+
| Command-name | release-bundle-distribute |
132+
| Abbreviation | rbd |
133+
| Command options | |
134+
| --create-repo | \[Default: false\]<br><br>Set to true to create the repository on the edge if it does not exist. |
135+
| --dry-run | \[Default: false\]<br><br>Set to true to disable communication with JFrog Distribution. |
136+
| --dist-rules | \[Optional\]<br><br>Path to a file, which includes the Distribution Rules in a JSON format. See [structure](#distribution-rules-structure) bellow. |
137+
| --site | \[Default: *\]<br><br>Wildcard filter for site name. |
138+
| --city | \[Default: *\]<br><br>Wildcard filter for site city name. |
139+
| --country-codes | \[Default: *\]<br><br>Semicolon-separated list of wildcard filters for site country codes. |
140+
| --insecure-tls | \[Default: false\]<br><br>Set to true to skip TLS certificates verification. |
141+
| --mapping-pattern | \[Optional\]<br><br>Specify along with 'mapping-target' to distribute artifacts to a different path on the edge node. You can use wildcards to specify multiple artifacts. |
142+
| --mapping-target | \[Optional\]<br><br>The target path for distributed artifacts on the edge node. If not specified, the artifacts will have the same path and name on the edge node, as on the source Artifactory server. For flexibility in specifying the distribution path, you can include [placeholders](https://www.jfrog.com/confluence/display/CLI/CLI+for+JFrog+Artifactory#CLIforJFrogArtifactory-UsingPlaceholders) in the form of {1}, {2} which are replaced by corresponding tokens in the pattern path that are enclosed in parenthesis. |
143+
| Command arguments | |
144+
| release bundle name | Name of the Release Bundle to distribute. |
145+
| release bundle version | Version of the Release Bundle to distribute. |
146+
147+
#### Distribution Rules Structure:
148+
```json
149+
{
150+
"distribution_rules": [
151+
{
152+
"site_name": "DC-1",
153+
"city_name": "New-York",
154+
"country_codes": ["1"]
155+
},
156+
{
157+
"site_name": "DC-2",
158+
"city_name": "Tel-Aviv",
159+
"country_codes": ["972"]
160+
}
161+
]
162+
}
163+
```
164+
The Distribution Rules format also supports wildcards. For example:
165+
```json
166+
{
167+
"distribution_rules": [
168+
{
169+
"site_name": "",
170+
"city_name": "",
171+
"country_codes": ["*"]
172+
}
173+
]
174+
}
175+
```
176+
177+
#### Examples
178+
179+
#### Example 1
180+
Distribute the Release Bundle v2 named myApp with version 1.0.0. Use the distribution rules defined in the specified file.
181+
182+
jf rbd --dist-rules=/path/to/dist-rules.json myApp 1.0.0
183+
184+
#### Example 2
185+
186+
Distribute the Release Bundle v2 named myApp with version 1.0.0 using the default distribution rules.
187+
Map files under the 'source' directory to be placed under the 'target' directory.
188+
189+
jf rbd --dist-rules=/path/to/dist-rules.json --mapping-pattern="(*)/source/(*)" --mapping-target="{1}/target/{2}" myApp 1.0.0

Diff for: go.mod

+10
Original file line numberDiff line numberDiff line change
@@ -123,3 +123,13 @@ require (
123123
gopkg.in/warnings.v0 v0.1.2 // indirect
124124
gopkg.in/yaml.v3 v3.0.1 // indirect
125125
)
126+
127+
// replace github.com/jfrog/build-info-go => github.com/jfrog/build-info-go v1.8.9-0.20230828134416-f0db33dd9344
128+
129+
// replace github.com/jfrog/jfrog-cli-core/v2 => github.com/jfrog/jfrog-cli-core/v2 v2.31.1-0.20230904170814-03a7938bae94
130+
131+
// replace github.com/jfrog/gofrog => github.com/jfrog/gofrog v1.2.6-0.20230418122323-2bf299dd6d27
132+
133+
replace github.com/jfrog/jfrog-client-go => github.com/jfrog/jfrog-client-go v1.28.1-0.20230913164821-c396cb9a4e06
134+
135+
// replace github.com/jfrog/build-info-go => github.com/jfrog/build-info-go v1.8.9-0.20230831151231-e5e7bd035ddc

Diff for: go.sum

+2-2
Original file line numberDiff line numberDiff line change
@@ -241,8 +241,8 @@ github.com/jfrog/gofrog v1.3.0 h1:o4zgsBZE4QyDbz2M7D4K6fXPTBJht+8lE87mS9bw7Gk=
241241
github.com/jfrog/gofrog v1.3.0/go.mod h1:IFMc+V/yf7rA5WZ74CSbXe+Lgf0iApEQLxRZVzKRUR0=
242242
github.com/jfrog/jfrog-cli-core/v2 v2.43.0 h1:euo1CjZcpMdWkFUQ3zffRPfCR1zXhLD6TE/lfexV99o=
243243
github.com/jfrog/jfrog-cli-core/v2 v2.43.0/go.mod h1:NWqT0ZnAvEdjaXGp64POvRV35TJ2R/c0W45UmrXQonk=
244-
github.com/jfrog/jfrog-client-go v1.32.2 h1:t0ceWCtFri+xsa0D2ESqD/itcovlxBXCky1A1MJ4P2I=
245-
github.com/jfrog/jfrog-client-go v1.32.2/go.mod h1:UewnwkIf/77HzBgwCPzOHZCK6V/Nw5/JwdzN/tRb4aU=
244+
github.com/jfrog/jfrog-client-go v1.28.1-0.20230913164821-c396cb9a4e06 h1:QcREjpuUJmLsy7aSXTcMomAIVFgOsdUHGi7lcqVfg8M=
245+
github.com/jfrog/jfrog-client-go v1.28.1-0.20230913164821-c396cb9a4e06/go.mod h1:UewnwkIf/77HzBgwCPzOHZCK6V/Nw5/JwdzN/tRb4aU=
246246
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
247247
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
248248
github.com/jszwec/csvutil v1.8.0 h1:G7vS2LGdpZZDH1HmHeNbxOaJ/ZnJlpwGFvOkTkJzzNk=

Diff for: lifecycle/cli.go

+1-2
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ func GetCommands() []cli.Command {
5555
ArgsUsage: common.CreateEnvVars(),
5656
BashComplete: coreCommon.CreateBashCompletionFunc(),
5757
Category: lcCategory,
58-
Hidden: true,
5958
Action: distribute,
6059
},
6160
})
@@ -170,7 +169,7 @@ func assertSigningKeyProvided(c *cli.Context) error {
170169
}
171170

172171
func createLifecycleDetailsByFlags(c *cli.Context) (*coreConfig.ServerDetails, error) {
173-
lcDetails, err := cliutils.CreateServerDetailsWithConfigOffer(c, false, cliutils.Platform)
172+
lcDetails, err := cliutils.CreateServerDetailsWithConfigOffer(c, true, cliutils.Platform)
174173
if err != nil {
175174
return nil, err
176175
}

Diff for: lifecycle_test.go

+27-6
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,14 @@ import (
1414
"github.com/jfrog/jfrog-client-go/lifecycle"
1515
"github.com/jfrog/jfrog-client-go/lifecycle/services"
1616
clientUtils "github.com/jfrog/jfrog-client-go/utils"
17+
"github.com/jfrog/jfrog-client-go/utils/distribution"
1718
"github.com/jfrog/jfrog-client-go/utils/errorutils"
1819
"github.com/stretchr/testify/assert"
1920
"net/http"
2021
"os"
2122
"path/filepath"
2223
"testing"
24+
"time"
2325
)
2426

2527
const (
@@ -64,14 +66,17 @@ func TestLifecycle(t *testing.T) {
6466
promoteRb(t, lcManager, number3)
6567

6668
// Verify the artifacts of both the initial release bundles made it to the prod repo.
67-
searchSpec, err := tests.CreateSpec(tests.SearchAllProdRepo)
69+
searchProdSpec, err := tests.CreateSpec(tests.SearchAllProdRepo)
6870
assert.NoError(t, err)
69-
inttestutils.VerifyExistInArtifactory(tests.GetExpectedLifecycleArtifacts(), searchSpec, serverDetails, t)
71+
inttestutils.VerifyExistInArtifactory(tests.GetExpectedLifecycleArtifacts(), searchProdSpec, serverDetails, t)
7072

7173
distributeRb(t)
74+
defer remoteDeleteReleaseBundle(t, lcManager, tests.LcRbName3, number3)
75+
7276
// Verify the artifacts were distributed correctly by the provided path mappings.
73-
expected := append(tests.GetExpectedLifecycleArtifacts(), tests.GetExpectedLifecycleMappingArtifacts()...)
74-
inttestutils.VerifyExistInArtifactory(expected, searchSpec, serverDetails, t)
77+
searchDevSpec, err := tests.CreateSpec(tests.SearchAllDevRepo)
78+
assert.NoError(t, err)
79+
inttestutils.VerifyExistInArtifactory(tests.GetExpectedLifecycleDistributedArtifacts(), searchDevSpec, serverDetails, t)
7580
}
7681

7782
func uploadBuilds(t *testing.T) func() {
@@ -107,9 +112,11 @@ func distributeRb(t *testing.T) {
107112
assert.NoError(t, lcCli.Exec(
108113
"rbd", tests.LcRbName3, number3,
109114
getOption(cliutils.DistRules, distributionRulesPath),
110-
getOption(cliutils.PathMappingPattern, tests.RtProdRepo+"/(*)"),
111-
getOption(cliutils.PathMappingTarget, tests.RtProdRepo+"/target/{1}"),
115+
getOption(cliutils.PathMappingPattern, "(*)/(*)"),
116+
getOption(cliutils.PathMappingTarget, "{1}/target/{2}"),
112117
))
118+
// Wait after distribution before asserting. Can be removed once distribute supports sync.
119+
time.Sleep(5 * time.Second)
113120
}
114121

115122
func getOption(option, value string) string {
@@ -187,6 +194,20 @@ func deleteReleaseBundle(t *testing.T, lcManager *lifecycle.LifecycleServicesMan
187194
assert.NoError(t, lcManager.DeleteReleaseBundle(rbDetails, services.ReleaseBundleQueryParams{Async: false}))
188195
}
189196

197+
func remoteDeleteReleaseBundle(t *testing.T, lcManager *lifecycle.LifecycleServicesManager, rbName, rbVersion string) {
198+
params := distribution.NewDistributeReleaseBundleParams(rbName, rbVersion)
199+
rules := &distribution.DistributionCommonParams{
200+
SiteName: "*",
201+
CityName: "*",
202+
CountryCodes: []string{"*"},
203+
}
204+
params.DistributionRules = append(params.DistributionRules, rules)
205+
206+
assert.NoError(t, lcManager.RemoteDeleteReleaseBundle(params, false))
207+
// Wait after remote deleting. Can be removed once remote deleting supports sync.
208+
time.Sleep(5 * time.Second)
209+
}
210+
190211
func uploadBuild(t *testing.T, specFileName, buildName, buildNumber string) {
191212
specFile, err := tests.CreateSpec(specFileName)
192213
assert.NoError(t, err)

Diff for: testdata/filespecs/search_all_dev_repo.json

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"files": [
3+
{
4+
"pattern": "${DEV_REPO}/*"
5+
}
6+
]
7+
}

Diff for: utils/tests/consts.go

+21-11
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ const (
9191
SearchAllMaven = "search_all_maven.json"
9292
SearchAllNpm = "search_all_npm.json"
9393
SearchAllRepo1 = "search_all_repo1.json"
94+
SearchAllDevRepo = "search_all_dev_repo.json"
9495
SearchAllProdRepo = "search_all_prod_repo.json"
9596
SearchDistRepoByInSuffix = "search_dist_repo_by_in_suffix.json"
9697
SearchRepo1ByInSuffix = "search_repo1_by_in_suffix.json"
@@ -2099,17 +2100,26 @@ func GetExpectedLifecycleArtifacts() []string {
20992100
}
21002101
}
21012102

2102-
func GetExpectedLifecycleMappingArtifacts() []string {
2103-
return []string{
2104-
RtProdRepo + "/target/a1.in",
2105-
RtProdRepo + "/target/a2.in",
2106-
RtProdRepo + "/target/a3.in",
2107-
RtProdRepo + "/target/b1.in",
2108-
RtProdRepo + "/target/b2.in",
2109-
RtProdRepo + "/target/b3.in",
2110-
RtProdRepo + "/target/c1.in",
2111-
RtProdRepo + "/target/c2.in",
2112-
RtProdRepo + "/target/c3.in",
2103+
func GetExpectedLifecycleDistributedArtifacts() []string {
2104+
return []string{
2105+
RtDevRepo + "/a1.in",
2106+
RtDevRepo + "/a2.in",
2107+
RtDevRepo + "/a3.in",
2108+
RtDevRepo + "/b1.in",
2109+
RtDevRepo + "/b2.in",
2110+
RtDevRepo + "/b3.in",
2111+
RtDevRepo + "/c1.in",
2112+
RtDevRepo + "/c2.in",
2113+
RtDevRepo + "/c3.in",
2114+
RtDevRepo + "/target/a1.in",
2115+
RtDevRepo + "/target/a2.in",
2116+
RtDevRepo + "/target/a3.in",
2117+
RtDevRepo + "/target/b1.in",
2118+
RtDevRepo + "/target/b2.in",
2119+
RtDevRepo + "/target/b3.in",
2120+
RtDevRepo + "/target/c1.in",
2121+
RtDevRepo + "/target/c2.in",
2122+
RtDevRepo + "/target/c3.in",
21132123
}
21142124
}
21152125

0 commit comments

Comments
 (0)