diff --git a/.github/RELEASE_LINK_TEMPLATE.md b/.github/RELEASE_LINK_TEMPLATE.md
new file mode 100644
index 000000000..bcd83c827
--- /dev/null
+++ b/.github/RELEASE_LINK_TEMPLATE.md
@@ -0,0 +1,23 @@
+
+ Downloads JFrog CLI
+
+### Linux
+
+[386](https://releases.jfrog.io/artifactory/jfrog-cli/v2-jf/{version}/jfrog-cli-linux-386/jf)
+[AMD-64](https://releases.jfrog.io/artifactory/jfrog-cli/v2-jf/{version}/jfrog-cli-linux-amd64/jf)
+[ARM-32](https://releases.jfrog.io/artifactory/jfrog-cli/v2-jf/{version}/jfrog-cli-linux-arm/jf)
+[ARM-64](https://releases.jfrog.io/artifactory/jfrog-cli/v2-jf/{version}/jfrog-cli-linux-arm64/jf)
+[PPC-64](https://releases.jfrog.io/artifactory/jfrog-cli/v2-jf/{version}/jfrog-cli-linux-ppc64/jf)
+[PPC-64-LE](https://releases.jfrog.io/artifactory/jfrog-cli/v2-jf/{version}/jfrog-cli-linux-ppc64le/jf)
+[S390X](https://releases.jfrog.io/artifactory/jfrog-cli/v2-jf/{version}/jfrog-cli-linux-s390x/jf)
+
+### MacOS
+
+[AMD-64](https://releases.jfrog.io/artifactory/jfrog-cli/v2-jf/{version}/jfrog-cli-mac-386/jf)
+[ARM-64](https://releases.jfrog.io/artifactory/jfrog-cli/v2-jf/{version}/jfrog-cli-mac-arm64/jf)
+
+### Windows
+
+[AMD-64](https://releases.jfrog.io/artifactory/jfrog-cli/v2-jf/{version}/jfrog-cli-windows-amd64/jf.exe)
+
+
diff --git a/.github/workflows/addReleaseLinks.yml b/.github/workflows/addReleaseLinks.yml
new file mode 100644
index 000000000..75622164b
--- /dev/null
+++ b/.github/workflows/addReleaseLinks.yml
@@ -0,0 +1,27 @@
+name: Add links on release
+on:
+ release:
+ types: [created]
+
+jobs:
+ add-links-on-release:
+ name: Add links on release
+ runs-on: ubuntu-latest
+ steps:
+ - name: Check out repository
+ uses: actions/checkout@v2
+
+ - name: Create markdown download links
+ run: |
+ # Remove the prefix 'v' from version.
+ RELEASE_VERSION=$(echo "${{ github.event.release.tag_name }}" | sed 's/^v//')
+
+ # Replace the place-holders '{version}' with the actual release version.
+ sed "s/{version}/$RELEASE_VERSION/g" ./.github/RELEASE_LINK_TEMPLATE.md > ./temp_releaseLinkTemplate.md
+
+ - name: Add links to release notes
+ uses: softprops/action-gh-release@v1
+ with:
+ token: ${{ secrets.GITHUB_TOKEN }}
+ body_path: "temp_releaseLinkTemplate.md"
+ append_body: true
diff --git a/.github/workflows/analysis.yml b/.github/workflows/analysis.yml
index e78785890..ccc237c65 100644
--- a/.github/workflows/analysis.yml
+++ b/.github/workflows/analysis.yml
@@ -31,7 +31,7 @@ jobs:
with:
path: ~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
- restore-keys: ${{ runner.os }}-go
+ restore-keys: ${{ runner.os }}-go-
- name: Run Go vet
run: go vet -v ./...
@@ -65,3 +65,15 @@ jobs:
uses: securego/gosec@master
with:
args: -exclude G204,G301,G302,G304,G306 -tests -exclude-dir \.*test\.* ./...
+
+ ShellCheck:
+ name: Shellcheck
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout Source
+ uses: actions/checkout@v3
+
+ - name: Run ShellCheck
+ uses: ludeeus/action-shellcheck@master
+ with:
+ ignore_paths: '*test*'
diff --git a/.github/workflows/dockerTests.yml b/.github/workflows/dockerTests.yml
index 0c8c02535..1a30ece44 100644
--- a/.github/workflows/dockerTests.yml
+++ b/.github/workflows/dockerTests.yml
@@ -21,8 +21,7 @@ jobs:
- name: Install Go
uses: actions/setup-go@v3
with:
- # We are temporarily downgrading to Go 1.20.5 due to a bug in version 1.20.6 that causes Docker tests to fail.
- go-version: 1.20.5
+ go-version: 1.20.x
- name: Checkout code
uses: actions/checkout@v3
with:
diff --git a/.github/workflows/frogbot-scan-pull-request.yml b/.github/workflows/frogbot-scan-pull-request.yml
index 998c8c91f..740419027 100644
--- a/.github/workflows/frogbot-scan-pull-request.yml
+++ b/.github/workflows/frogbot-scan-pull-request.yml
@@ -15,6 +15,7 @@ jobs:
- uses: jfrog/frogbot@v2
env:
JFROG_CLI_LOG_LEVEL: "DEBUG"
+
# [Mandatory]
# JFrog platform URL (This functionality requires version 3.29.0 or above of Xray)
JF_URL: ${{ secrets.FROGBOT_URL }}
@@ -116,4 +117,5 @@ jobs:
# [Optional]
# Set the minimum severity for vulnerabilities that should be fixed and commented on in pull requests
# The following values are accepted: Low, Medium, High or Critical
- # JF_MIN_SEVERITY: ""
\ No newline at end of file
+ # JF_MIN_SEVERITY: ""
+
diff --git a/.github/workflows/frogbot-scan-repository.yml b/.github/workflows/frogbot-scan-repository.yml
index 01b568f67..12e117be8 100644
--- a/.github/workflows/frogbot-scan-repository.yml
+++ b/.github/workflows/frogbot-scan-repository.yml
@@ -10,6 +10,7 @@ permissions:
security-events: write
jobs:
scan-repository:
+ name: Scan Repository (${{ matrix.branch }} branch)
runs-on: ubuntu-latest
strategy:
matrix:
@@ -19,6 +20,7 @@ jobs:
- uses: jfrog/frogbot@v2
env:
JFROG_CLI_LOG_LEVEL: "DEBUG"
+
# [Mandatory]
# JFrog platform URL (This functionality requires version 3.29.0 or above of Xray)
JF_URL: ${{ secrets.FROGBOT_URL }}
diff --git a/.github/workflows/mavenTests.yml b/.github/workflows/mavenTests.yml
index 25d0f1f10..a7f55587c 100644
--- a/.github/workflows/mavenTests.yml
+++ b/.github/workflows/mavenTests.yml
@@ -35,7 +35,7 @@ jobs:
with:
path: ~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
- restore-keys: ${{ runner.os }}-go
+ restore-keys: ${{ runner.os }}-go-
- name: Setup Maven v3.8.8 for macOS
uses: stCarolas/setup-maven@v4.5
with:
diff --git a/.github/workflows/nugetTests.yml b/.github/workflows/nugetTests.yml
index c17fadd48..262dabb50 100644
--- a/.github/workflows/nugetTests.yml
+++ b/.github/workflows/nugetTests.yml
@@ -43,7 +43,7 @@ jobs:
with:
path: ~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
- restore-keys: ${{ runner.os }}-go
+ restore-keys: ${{ runner.os }}-go-
- name: Setup Artifactory
run: |
go install github.com/jfrog/jfrog-testing-infra/local-rt-setup@latest
diff --git a/.github/workflows/pythonTests.yml b/.github/workflows/pythonTests.yml
index d9e7dd0a7..fd937028b 100644
--- a/.github/workflows/pythonTests.yml
+++ b/.github/workflows/pythonTests.yml
@@ -27,10 +27,11 @@ jobs:
uses: actions/setup-go@v3
with:
go-version: 1.20.x
+ # Due to a bug in Python 3.12.0 we temporary use version 3.11.5
- name: Setup Python3
uses: actions/setup-python@v4
with:
- python-version: "3.x"
+ python-version: "3.11.5"
- name: Setup Pipenv
if: ${{ matrix.suite == 'pipenv' }}
run: python -m pip install pipenv
diff --git a/.github/workflows/scriptTests.yml b/.github/workflows/scriptTests.yml
index 7201edeeb..27ce99e5e 100644
--- a/.github/workflows/scriptTests.yml
+++ b/.github/workflows/scriptTests.yml
@@ -12,25 +12,86 @@ concurrency:
cancel-in-progress: true
jobs:
Scripts-tests:
- name: Script tests (${{ matrix.os }})
+ name: Script tests (${{ matrix.suite.os }})
defaults:
run:
shell: bash
strategy:
fail-fast: false
matrix:
- os: [ ubuntu, windows, macos ]
- runs-on: ${{ matrix.os }}-latest
+ suite:
+ - os: "ubuntu"
+
+ - os: "macos"
+
+ - os: "windows"
+ osSuffix: ".exe"
+ runs-on: ${{ matrix.suite.os }}-latest
steps:
- 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: Test install CLI - jf
- run: sh build/installcli/jf.sh && jf --version
+ run: |
+ sh build/installcli/jf.sh
+ jf --version
+
- name: Test install CLI - jfrog
- run: sh build/installcli/jfrog.sh && jfrog --version
+ run: |
+ sh build/installcli/jfrog.sh
+ jfrog --version
+
- name: Test get CLI - jf
- run: sh build/getcli/jf.sh && ./jf --version
+ run: |
+ sh build/getcli/jf.sh
+ ./jf --version
+
- name: Test get CLI - jfrog
- run: sh build/getcli/jfrog.sh && ./jfrog --version
+ run: |
+ sh build/getcli/jfrog.sh
+ ./jfrog --version
+
+ - name: Test Build CLI - sh
+ run: |
+ sh build/build.sh
+ ./jf${{ matrix.suite.osSuffix }} --version
+ if: ${{ matrix.suite.os != 'windows' }}
+
+ - name: Test Build CLI - bat
+ run: |
+ build/build.bat
+ ./jf${{ matrix.suite.osSuffix }} --version
+ if: ${{ matrix.suite.os == 'windows' }}
+
+ # Prior to the release, we set the new version in the package.json files, introducing the prereleased version.
+ # This adjustment may result in an attempt to download a version that hasn't been published to releases.jfrog.io yet.
+ # To handle it, we fetch the most recent JFrog CLI release and store it in the LATEST_RELEASE step output.
+ - name: "Get latest release"
+ id: latest-release
+ run: |
+ export LATEST_RELEASE=`curl https://api.github.com/repos/jfrog/jfrog-cli/releases/latest -s | jq .name -r | cut -c 2-`
+ echo "LATEST_RELEASE=$LATEST_RELEASE" >> "$GITHUB_OUTPUT"
+ shell: bash
+
+ - name: Test install npm - v2
+ working-directory: build/npm/v2
+ run: |
+ npm version ${{ steps.latest-release.outputs.LATEST_RELEASE }} --allow-same-version
+ npm install
+ ./bin/jfrog${{ matrix.suite.osSuffix }} --version
+
+ - name: Test install npm - v2-jf
+ working-directory: build/npm/v2-jf
+ run: |
+ npm version ${{ steps.latest-release.outputs.LATEST_RELEASE }} --allow-same-version
+ npm install
+ ./bin/jf${{ matrix.suite.osSuffix }} --version
diff --git a/.github/workflows/xrayTests.yml b/.github/workflows/xrayTests.yml
index 83d8a6f64..afb659a97 100644
--- a/.github/workflows/xrayTests.yml
+++ b/.github/workflows/xrayTests.yml
@@ -61,9 +61,11 @@ jobs:
uses: actions/checkout@v3
with:
ref: ${{ github.event.pull_request.head.sha }}
- - name: Run Xray tests
+
+ - name: Run Xray tests (without Docker Scan)
run: go test -v github.com/jfrog/jfrog-cli --timeout 0 --test.xray --jfrog.url=${{ secrets.PLATFORM_URL }} --jfrog.adminToken=${{ secrets.PLATFORM_ADMIN_TOKEN }} --jfrog.user=${{ secrets.PLATFORM_USER }} --test.containerRegistry=${{ secrets.CONTAINER_REGISTRY }}
if: ${{ matrix.os != 'ubuntu' }}
- - name: Run Docker scan and Xray tests
+
+ - name: Run Xray tests (with Docker Scan, only on Ubuntu)
run: go test -v github.com/jfrog/jfrog-cli --timeout 0 --test.xray --test.dockerScan --jfrog.url=${{ secrets.PLATFORM_URL }} --jfrog.adminToken=${{ secrets.PLATFORM_ADMIN_TOKEN }} --test.containerRegistry=${{ secrets.CONTAINER_REGISTRY }}
if: ${{ matrix.os == 'ubuntu' }}
diff --git a/Jenkinsfile b/Jenkinsfile
index 88627412b..aed8e48b1 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -25,7 +25,7 @@ node("docker") {
repo = 'jfrog-cli'
sh 'rm -rf temp'
sh 'mkdir temp'
- def goRoot = tool 'go-1.20.5'
+ def goRoot = tool 'go-1.20.10'
env.GOROOT="$goRoot"
env.PATH+=":${goRoot}/bin"
env.GO111MODULE="on"
@@ -395,18 +395,22 @@ def distributeToReleases(stage, version, rbcSpecName) {
}
def publishNpmPackage(jfrogCliRepoDir) {
+ dir('/tmp') {
+ sh '''#!/bin/bash
+ apt update
+ apt install wget -y
+ echo "Downloading npm..."
+ wget https://nodejs.org/dist/v8.17.0/node-v8.17.0-linux-x64.tar.xz
+ tar -xvf node-v8.17.0-linux-x64.tar.xz
+ '''
+ }
dir(jfrogCliRepoDir+"build/npm/$identifier") {
withCredentials([string(credentialsId: 'npm-authorization', variable: 'NPM_AUTH_TOKEN')]) {
sh '''#!/bin/bash
- apt update
- apt install wget -y
- echo "Downloading npm..."
- wget https://nodejs.org/dist/v8.11.1/node-v8.11.1-linux-x64.tar.xz
- tar -xvf node-v8.11.1-linux-x64.tar.xz
- export PATH=$PATH:$PWD/node-v8.11.1-linux-x64/bin/
+ export PATH=/tmp/node-v8.17.0-linux-x64/bin:$PATH
echo "//registry.npmjs.org/:_authToken=$NPM_AUTH_TOKEN" > .npmrc
echo "registry=https://registry.npmjs.org" >> .npmrc
- ./node-v8.11.1-linux-x64/bin/npm publish
+ npm publish
'''
}
}
diff --git a/README.md b/README.md
index b16f33d2a..022e4f894 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,7 @@
[![Scanned by Frogbot](https://raw.github.com/jfrog/frogbot/master/images/frogbot-badge.svg)](https://github.com/jfrog/frogbot#readme)
[![Go Report Card](https://goreportcard.com/badge/github.com/jfrog/jfrog-cli)](https://goreportcard.com/report/github.com/jfrog/jfrog-cli)
-[![license](https://img.shields.io/badge/License-Apache_2.0-blue.svg?style=flat)](https://raw.githubusercontent.com/jfrog/jfrog-cli/v2/LICENSE) [![](https://img.shields.io/badge/Docs-%F0%9F%93%96-blue)](https://www.jfrog.com/confluence/display/CLI/JFrog+CLI)
+[![license](https://img.shields.io/badge/License-Apache_2.0-blue.svg?style=flat)](https://raw.githubusercontent.com/jfrog/jfrog-cli/v2/LICENSE) [![](https://img.shields.io/badge/Docs-%F0%9F%93%96-blue)](https://docs.jfrog-applications.jfrog.io/jfrog-applications/jfrog-cli)
[![Go version](https://img.shields.io/github/go-mod/go-version/jfrog/jfrog-cli)](https://tip.golang.org/doc/go1.20)
diff --git a/access_test.go b/access_test.go
index 919eba11c..ba092b1d1 100644
--- a/access_test.go
+++ b/access_test.go
@@ -3,33 +3,86 @@ package main
import (
"encoding/base64"
"encoding/json"
+ "fmt"
"github.com/jfrog/jfrog-cli-core/v2/common/commands"
- coreenvsetup "github.com/jfrog/jfrog-cli-core/v2/general/envsetup"
+ coreEnvSetup "github.com/jfrog/jfrog-cli-core/v2/general/envsetup"
"github.com/jfrog/jfrog-cli-core/v2/utils/config"
"github.com/jfrog/jfrog-cli-core/v2/utils/coreutils"
- coretests "github.com/jfrog/jfrog-cli-core/v2/utils/tests"
+ coreTests "github.com/jfrog/jfrog-cli-core/v2/utils/tests"
"github.com/jfrog/jfrog-cli/utils/tests"
"github.com/jfrog/jfrog-client-go/auth"
+ "github.com/jfrog/jfrog-client-go/http/httpclient"
+ clientUtils "github.com/jfrog/jfrog-client-go/utils"
+ "github.com/jfrog/jfrog-client-go/utils/errorutils"
+ "github.com/jfrog/jfrog-client-go/utils/io/httputils"
clientTestUtils "github.com/jfrog/jfrog-client-go/utils/tests"
"github.com/stretchr/testify/assert"
+ "net/http"
"testing"
)
+var (
+ accessDetails *config.ServerDetails
+ accessCli *tests.JfrogCli
+ accessHttpDetails httputils.HttpClientDetails
+)
+
func initAccessTest(t *testing.T) {
if !*tests.TestAccess {
t.Skip("Skipping Access test. To run Access test add the '-test.access=true' option.")
}
}
+func initAccessCli() {
+ if accessCli != nil {
+ return
+ }
+ accessCli = tests.NewJfrogCli(execMain, "jfrog", authenticateAccess())
+}
+
+func InitAccessTests() {
+ initArtifactoryCli()
+ initAccessCli()
+ cleanUpOldBuilds()
+ cleanUpOldRepositories()
+ cleanUpOldUsers()
+ tests.AddTimestampToGlobalVars()
+ createRequiredRepos()
+ cleanArtifactoryTest()
+}
+
+func authenticateAccess() string {
+ *tests.JfrogUrl = clientUtils.AddTrailingSlashIfNeeded(*tests.JfrogUrl)
+ accessDetails = &config.ServerDetails{
+ AccessUrl: *tests.JfrogUrl + tests.AccessEndpoint}
+
+ cred := fmt.Sprintf("--url=%s", *tests.JfrogUrl)
+ if *tests.JfrogAccessToken != "" {
+ accessDetails.AccessToken = *tests.JfrogAccessToken
+ cred += fmt.Sprintf(" --access-token=%s", accessDetails.AccessToken)
+ } else {
+ accessDetails.User = *tests.JfrogUser
+ accessDetails.Password = *tests.JfrogPassword
+ cred += fmt.Sprintf(" --user=%s --password=%s", accessDetails.User, accessDetails.Password)
+ }
+
+ accessAuth, err := accessDetails.CreateAccessAuthConfig()
+ if err != nil {
+ coreutils.ExitOnErr(err)
+ }
+ accessHttpDetails = accessAuth.CreateHttpClientDetails()
+ return cred
+}
+
func TestSetupInvitedUser(t *testing.T) {
initAccessTest(t)
- tempDirPath, createTempDirCallback := coretests.CreateTempDirWithCallbackAndAssert(t)
+ tempDirPath, createTempDirCallback := coreTests.CreateTempDirWithCallbackAndAssert(t)
defer createTempDirCallback()
setEnvCallBack := clientTestUtils.SetEnvWithCallbackAndAssert(t, coreutils.HomeDir, tempDirPath)
defer setEnvCallBack()
- serverDetails := &config.ServerDetails{Url: *tests.JfrogUrl, AccessToken: *tests.JfrogAccessToken}
- encodedCred := encodeConnectionDetails(serverDetails, t)
- setupCmd := coreenvsetup.NewEnvSetupCommand().SetEncodedConnectionDetails(encodedCred)
+ setupServerDetails := &config.ServerDetails{Url: *tests.JfrogUrl, AccessToken: *tests.JfrogAccessToken}
+ encodedCred := encodeConnectionDetails(setupServerDetails, t)
+ setupCmd := coreEnvSetup.NewEnvSetupCommand().SetEncodedConnectionDetails(encodedCred)
suffix := setupCmd.SetupAndConfigServer()
assert.Empty(t, suffix)
configs, err := config.GetAllServersConfigs()
@@ -54,7 +107,7 @@ func TestRefreshableAccessTokens(t *testing.T) {
initAccessTest(t)
server := &config.ServerDetails{Url: *tests.JfrogUrl, AccessToken: *tests.JfrogAccessToken}
- err := coreenvsetup.GenerateNewLongTermRefreshableAccessToken(server)
+ err := coreEnvSetup.GenerateNewLongTermRefreshableAccessToken(server)
assert.NoError(t, err)
assert.NotEmpty(t, server.RefreshToken)
configCmd := commands.NewConfigCommand(commands.AddOrEdit, tests.ServerId).SetDetails(server).SetInteractive(false)
@@ -76,7 +129,7 @@ func TestRefreshableAccessTokens(t *testing.T) {
assert.NotEmpty(t, curRefreshToken)
// Make the token always refresh.
- auth.InviteRefreshBeforeExpiryMinutes = 365 * 24 * 60
+ auth.RefreshPlatformTokenBeforeExpiryMinutes = 365 * 24 * 60
// Upload a file and assert tokens were refreshed.
uploadedFiles++
@@ -90,7 +143,7 @@ func TestRefreshableAccessTokens(t *testing.T) {
}
// Make the token not refresh. Verify Tokens did not refresh.
- auth.InviteRefreshBeforeExpiryMinutes = 0
+ auth.RefreshPlatformTokenBeforeExpiryMinutes = 0
uploadedFiles++
err = uploadWithSpecificServerAndVerify(t, artifactoryCommandExecutor, "testdata/a/b/b2.in", uploadedFiles)
if !assert.NoError(t, err) {
@@ -115,3 +168,121 @@ func getAccessTokensFromConfig(t *testing.T, serverId string) (accessToken, refr
}
return details.AccessToken, details.RefreshToken, nil
}
+
+const (
+ userScope = "applied-permissions/user"
+ defaultExpiry = 31536000
+)
+
+var atcTestCases = []struct {
+ name string
+ args []string
+ shouldExpire bool
+ // The expected expiry or -1 if we use the default expiry value
+ expectedExpiry int
+ expectedScope string
+ expectedRefreshable bool
+ expectedReference bool
+}{
+ {
+ name: "default",
+ args: []string{"atc"},
+ shouldExpire: true,
+ expectedExpiry: -1,
+ expectedScope: userScope,
+ expectedRefreshable: false,
+ expectedReference: false,
+ },
+ {
+ name: "explicit user, no expiry",
+ args: []string{"atc", auth.ExtractUsernameFromAccessToken(*tests.JfrogAccessToken), "--expiry=0"},
+ shouldExpire: false,
+ expectedExpiry: 0,
+ expectedScope: userScope,
+ expectedRefreshable: false,
+ expectedReference: false,
+ },
+ {
+ name: "refreshable, admin",
+ args: []string{"atc", "--refreshable", "--grant-admin"},
+ shouldExpire: true,
+ expectedExpiry: -1,
+ expectedScope: "applied-permissions/admin",
+ expectedRefreshable: true,
+ expectedReference: false,
+ },
+ {
+ name: "reference, custom scope, custom expiry",
+ args: []string{"atc", "--reference", "--scope=system:metrics:r", "--expiry=123456"},
+ shouldExpire: true,
+ expectedExpiry: 123456,
+ expectedScope: "system:metrics:r",
+ expectedRefreshable: false,
+ expectedReference: true,
+ },
+ {
+ name: "groups, description",
+ args: []string{"atc", "--groups=group1,group2", "--description=description"},
+ shouldExpire: true,
+ expectedExpiry: -1,
+ expectedScope: "applied-permissions/groups:group1,group2",
+ expectedRefreshable: false,
+ expectedReference: false,
+ },
+}
+
+func TestAccessTokenCreate(t *testing.T) {
+ initAccessTest(t)
+ if *tests.JfrogAccessToken == "" {
+ t.Skip("access token create command only supports authorization with access token, but a token is not provided. Skipping...")
+ }
+
+ for _, test := range atcTestCases {
+ t.Run(test.name, func(t *testing.T) {
+ var token auth.CreateTokenResponseData
+ output := accessCli.RunCliCmdWithOutput(t, test.args...)
+ assert.NoError(t, json.Unmarshal([]byte(output), &token))
+ defer revokeToken(t, token.TokenId)
+
+ if test.shouldExpire {
+ if test.expectedExpiry == -1 {
+ // If expectedExpiry is -1, expect the default expiry
+ assert.Positive(t, *token.ExpiresIn)
+ } else {
+ assert.EqualValues(t, test.expectedExpiry, *token.ExpiresIn)
+ }
+ } else {
+ assert.Nil(t, token.ExpiresIn)
+ }
+ assert.NotEmpty(t, token.AccessToken)
+ assert.Equal(t, test.expectedScope, token.Scope)
+ assertNotEmptyIfExpected(t, test.expectedRefreshable, token.RefreshToken)
+ assertNotEmptyIfExpected(t, test.expectedReference, token.ReferenceToken)
+
+ // Try pinging Artifactory with the new token.
+ assert.NoError(t, tests.NewJfrogCli(execMain, "jfrog rt",
+ "--url="+*tests.JfrogUrl+tests.ArtifactoryEndpoint+" --access-token="+token.AccessToken).Exec("ping"))
+ })
+ }
+}
+
+func assertNotEmptyIfExpected(t *testing.T, expected bool, output string) {
+ if expected {
+ assert.NotEmpty(t, output)
+ } else {
+ assert.Empty(t, output)
+ }
+}
+
+func revokeToken(t *testing.T, tokenId string) {
+ if tokenId == "" {
+ return
+ }
+
+ client, err := httpclient.ClientBuilder().Build()
+ assert.NoError(t, err)
+
+ resp, _, err := client.SendDelete(*tests.JfrogUrl+"access/api/v1/tokens/"+tokenId, nil, accessHttpDetails, "")
+ assert.NoError(t, err)
+ assert.NoError(t, errorutils.CheckResponseStatus(resp, http.StatusOK))
+}
diff --git a/artifactory/cli.go b/artifactory/cli.go
index 1e02ab521..12a639464 100644
--- a/artifactory/cli.go
+++ b/artifactory/cli.go
@@ -3,6 +3,7 @@ package artifactory
import (
"errors"
"fmt"
+ "github.com/jfrog/jfrog-cli/utils/accesstoken"
"os"
"strconv"
"strings"
@@ -860,13 +861,13 @@ func GetCommands() []cli.Command {
{
Name: "access-token-create",
Aliases: []string{"atc"},
- Flags: cliutils.GetCommandFlags(cliutils.AccessTokenCreate),
+ Flags: cliutils.GetCommandFlags(cliutils.ArtifactoryAccessTokenCreate),
Usage: accesstokencreate.GetDescription(),
HelpName: corecommon.CreateUsage("rt atc", accesstokencreate.GetDescription(), accesstokencreate.Usage),
UsageText: accesstokencreate.GetArguments(),
ArgsUsage: common.CreateEnvVars(),
BashComplete: corecommon.CreateBashCompletionFunc(),
- Action: accessTokenCreateCmd,
+ Action: artifactoryAccessTokenCreateCmd,
},
{
Name: "transfer-settings",
@@ -2199,7 +2200,7 @@ func groupDeleteCmd(c *cli.Context) error {
return commands.Exec(groupDeleteCmd)
}
-func accessTokenCreateCmd(c *cli.Context) error {
+func artifactoryAccessTokenCreateCmd(c *cli.Context) error {
if c.NArg() > 1 {
return cliutils.WrongNumberOfArgumentsHandler(c)
}
@@ -2208,20 +2209,16 @@ func accessTokenCreateCmd(c *cli.Context) error {
if err != nil {
return err
}
- // If the username is provided as an argument, then it is used when creating the token.
- // If not, then the configured username (or the value of the --user option) is used.
- var userName string
- if c.NArg() > 0 {
- userName = c.Args().Get(0)
- } else {
- userName = serverDetails.GetUser()
- }
- expiry, err := cliutils.GetIntFlagValue(c, "expiry", cliutils.TokenExpiry)
+
+ username := accesstoken.GetSubjectUsername(c, serverDetails)
+ expiry, err := cliutils.GetIntFlagValue(c, cliutils.Expiry, cliutils.ArtifactoryTokenExpiry)
if err != nil {
return err
}
accessTokenCreateCmd := generic.NewAccessTokenCreateCommand()
- accessTokenCreateCmd.SetUserName(userName).SetServerDetails(serverDetails).SetRefreshable(c.Bool("refreshable")).SetExpiry(expiry).SetGroups(c.String("groups")).SetAudience(c.String("audience")).SetGrantAdmin(c.Bool("grant-admin"))
+ accessTokenCreateCmd.SetUserName(username).SetServerDetails(serverDetails).
+ SetRefreshable(c.Bool(cliutils.Refreshable)).SetExpiry(expiry).SetGroups(c.String(cliutils.Groups)).
+ SetAudience(c.String(cliutils.Audience)).SetGrantAdmin(c.Bool(cliutils.GrantAdmin))
err = commands.Exec(accessTokenCreateCmd)
if err != nil {
return err
diff --git a/artifactory_test.go b/artifactory_test.go
index 390961e66..4330130a7 100644
--- a/artifactory_test.go
+++ b/artifactory_test.go
@@ -1,6 +1,7 @@
package main
import (
+ "archive/zip"
"bytes"
"crypto/tls"
"encoding/csv"
@@ -4166,6 +4167,38 @@ func TestUploadDeploymentViewWithArchive(t *testing.T) {
cleanArtifactoryTest()
}
+func TestUploadZipAndCheckDeploymentViewWithArchive(t *testing.T) {
+ initArtifactoryTest(t, "")
+
+ // Create tmp dir
+ assert.NoError(t, os.Mkdir(tests.Out, 0755))
+ wd, err := os.Getwd()
+ assert.NoError(t, err)
+ defer cleanArtifactoryTest()
+ chdirCallback := clientTestUtils.ChangeDirWithCallback(t, wd, tests.Out)
+ defer chdirCallback()
+
+ // Create file and a zip
+ fileName := "dummy_file.txt"
+ zipName := "test.zip"
+ assert.NoError(t, os.WriteFile(fileName, nil, 0644))
+
+ // Upload & download zip file
+ assert.NoError(t, artifactoryCli.Exec("upload", fileName, path.Join(tests.RtRepo1, zipName), "--archive", "zip"))
+ assert.NoError(t, artifactoryCli.Exec("download", path.Join(tests.RtRepo1, zipName)))
+
+ // Check for time-zone offset for each file in the zip
+ r, err := zip.OpenReader(zipName)
+ assert.NoError(t, err)
+ defer func() { assert.NoError(t, r.Close()) }()
+ _, sysTimezoneOffset := time.Now().Zone()
+ for _, file := range r.File {
+ _, fileTimezoneOffset := file.Modified.Zone()
+ assert.Equal(t, sysTimezoneOffset, fileTimezoneOffset)
+ }
+
+}
+
func TestUploadDetailedSummary(t *testing.T) {
initArtifactoryTest(t, "")
uploadCmd := generic.NewUploadCommand()
@@ -5190,7 +5223,7 @@ func TestArtifactoryReplicationCreate(t *testing.T) {
cleanArtifactoryTest()
}
-func TestAccessTokenCreate(t *testing.T) {
+func TestArtifactoryAccessTokenCreate(t *testing.T) {
initArtifactoryTest(t, "")
buffer, _, previousLog := coretests.RedirectLogOutputToBuffer()
@@ -5268,7 +5301,7 @@ func TestRefreshableArtifactoryTokens(t *testing.T) {
assert.NotEmpty(t, curRefreshToken)
// Make the token always refresh.
- auth.RefreshBeforeExpiryMinutes = 60
+ auth.RefreshArtifactoryTokenBeforeExpiryMinutes = 60
// Upload a file and assert tokens were refreshed.
uploadedFiles++
@@ -5312,7 +5345,7 @@ func TestRefreshableArtifactoryTokens(t *testing.T) {
}
// Make the token not refresh. Verify Tokens did not refresh.
- auth.RefreshBeforeExpiryMinutes = 0
+ auth.RefreshArtifactoryTokenBeforeExpiryMinutes = 0
uploadedFiles++
err = uploadWithSpecificServerAndVerify(t, artifactoryCommandExecutor, "testdata/a/b/b2.in", uploadedFiles)
if err != nil {
@@ -5601,7 +5634,7 @@ func testProjectInit(t *testing.T, projectExampleName string, technology coreuti
// Copy a simple project in a temp work dir
tmpWorkDir, deleteWorkDir := coretests.CreateTempDirWithCallbackAndAssert(t)
defer deleteWorkDir()
- testdataSrc := filepath.Join(filepath.FromSlash(tests.GetTestResourcesPath()), technology.ToString(), projectExampleName)
+ testdataSrc := filepath.Join(filepath.FromSlash(tests.GetTestResourcesPath()), technology.String(), projectExampleName)
err = biutils.CopyDir(testdataSrc, tmpWorkDir, true, nil)
assert.NoError(t, err)
if technology == coreutils.Go {
@@ -5619,7 +5652,7 @@ func testProjectInit(t *testing.T, projectExampleName string, technology coreuti
err = platformCli.WithoutCredentials().Exec("project", "init", "--path", tmpWorkDir, "--server-id="+tests.ServerId)
assert.NoError(t, err)
// Validate correctness of .jfrog/projects/$technology.yml
- validateProjectYamlFile(t, tmpWorkDir, technology.ToString())
+ validateProjectYamlFile(t, tmpWorkDir, technology.String())
// Validate correctness of .jfrog/projects/build.yml
validateBuildYamlFile(t, tmpWorkDir)
}
diff --git a/build/build.sh b/build/build.sh
index ea46362c1..0cc3e14eb 100755
--- a/build/build.sh
+++ b/build/build.sh
@@ -8,5 +8,5 @@ if [ $# -eq 0 ]
exe_name="$1"
fi
-CGO_ENABLED=0 go build -o $exe_name -ldflags '-w -extldflags "-static"' main.go
+CGO_ENABLED=0 go build -o "$exe_name" -ldflags '-w -extldflags "-static"' main.go
echo "The $exe_name executable was successfully created."
diff --git a/build/chocolatey/v2-jf/README.md b/build/chocolatey/v2-jf/README.md
index c85de6a4c..bc20431eb 100644
--- a/build/chocolatey/v2-jf/README.md
+++ b/build/chocolatey/v2-jf/README.md
@@ -24,13 +24,13 @@ choco pack version=
```
This will create the file _build/chocolatey/jfrog-cli.\.nupkg which can be
-installed with Chcolatey
+installed with Chocolatey
```powershell
choco install jfrog-cli..nupkg
```
-See Chocolatey's official documenattion [here](https://chocolatey.org/docs/create-packages)
+See Chocolatey's official documentation [here](https://chocolatey.org/docs/create-packages)
[choco-dockerfile-pr]: https://github.com/chocolatey/choco/pull/1153
[choco-dockerfile]: https://github.com/chocolatey/choco/tree/master/docker
diff --git a/build/chocolatey/v2-jf/jfrog-cli-v2-jf.nuspec b/build/chocolatey/v2-jf/jfrog-cli-v2-jf.nuspec
index 4810c3614..9fc7ad50e 100644
--- a/build/chocolatey/v2-jf/jfrog-cli-v2-jf.nuspec
+++ b/build/chocolatey/v2-jf/jfrog-cli-v2-jf.nuspec
@@ -8,7 +8,7 @@
JFrog CLI V2-jfJFrog LtdJFrog Ltd
- https://www.jfrog.com/confluence/display/CLI/JFrog+CLI
+ https://docs.jfrog-applications.jfrog.io/jfrog-applications/jfrog-clihttps://github.com/jfrog/jfrog-cli/blob/v2/LICENSEfalsehttps://github.com/jfrog/jfrog-cli/issues
diff --git a/build/chocolatey/v2/README.md b/build/chocolatey/v2/README.md
index c85de6a4c..bc20431eb 100644
--- a/build/chocolatey/v2/README.md
+++ b/build/chocolatey/v2/README.md
@@ -24,13 +24,13 @@ choco pack version=
```
This will create the file _build/chocolatey/jfrog-cli.\.nupkg which can be
-installed with Chcolatey
+installed with Chocolatey
```powershell
choco install jfrog-cli..nupkg
```
-See Chocolatey's official documenattion [here](https://chocolatey.org/docs/create-packages)
+See Chocolatey's official documentation [here](https://chocolatey.org/docs/create-packages)
[choco-dockerfile-pr]: https://github.com/chocolatey/choco/pull/1153
[choco-dockerfile]: https://github.com/chocolatey/choco/tree/master/docker
diff --git a/build/chocolatey/v2/jfrog-cli.nuspec b/build/chocolatey/v2/jfrog-cli.nuspec
index 022f60c36..d65e32bb4 100644
--- a/build/chocolatey/v2/jfrog-cli.nuspec
+++ b/build/chocolatey/v2/jfrog-cli.nuspec
@@ -8,7 +8,7 @@
JFrog CLI V2JFrog LtdJFrog Ltd
- https://www.jfrog.com/confluence/display/CLI/JFrog+CLI
+ https://docs.jfrog-applications.jfrog.io/jfrog-applications/jfrog-clihttps://github.com/jfrog/jfrog-cli/blob/v2/LICENSEfalsehttps://github.com/jfrog/jfrog-cli/issues
diff --git a/build/deb_rpm/v2-jf/build-scripts/deb-install.sh b/build/deb_rpm/v2-jf/build-scripts/deb-install.sh
index 6e4651be5..d3e1cd727 100644
--- a/build/deb_rpm/v2-jf/build-scripts/deb-install.sh
+++ b/build/deb_rpm/v2-jf/build-scripts/deb-install.sh
@@ -1,3 +1,5 @@
+#!/bin/bash
+
wget -qO - https://releases.jfrog.io/artifactory/api/gpg/key/public | apt-key add -;
echo "deb https://releases.jfrog.io/artifactory/jfrog-debs xenial contrib" | sudo tee -a /etc/apt/sources.list;
apt update;
diff --git a/build/deb_rpm/v2-jf/build-scripts/pack.sh b/build/deb_rpm/v2-jf/build-scripts/pack.sh
index 6d258a119..7a02590aa 100755
--- a/build/deb_rpm/v2-jf/build-scripts/pack.sh
+++ b/build/deb_rpm/v2-jf/build-scripts/pack.sh
@@ -46,12 +46,11 @@ errorExit() {
}
checkDockerAccess() {
- log "Checking docker" "DEBUG"
- docker -v > /dev/null 2>&1 && docker ps > /dev/null 2>&1
- if [ $? -ne 0 ]; then
- errorExit "Must run as user that can execute docker commands"
+ if docker -v > /dev/null 2>&1 && docker ps > /dev/null 2>&1; then
+ log "Docker is available" "DEBUG"
+ else
+ errorExit "Must run as a user that can execute docker commands"
fi
- log "Docker is avaiable" "DEBUG"
}
exitWithUsage(){
@@ -64,7 +63,7 @@ createDEBPackage(){
local flavour="deb"
# cleanup old files and containers
- rm -f ${JFROG_CLI_PKG}/${JFROG_CLI_PREFIX}*${VERSION_FORMATTED}*.${flavour}
+ rm -f "${JFROG_CLI_PKG}/${JFROG_CLI_PREFIX}*${VERSION_FORMATTED}*.${flavour}"
docker rm -f "${RPM_BUILDER_NAME}" 2>/dev/null
log "Building ${JFROG_CLI_PREFIX} ${flavour} ${JFROG_CLI_VERSION} on ${DEB_BUILD_IMAGE} image"
@@ -72,7 +71,7 @@ createDEBPackage(){
docker run -t --rm -v "${JFROG_CLI_HOME}/${flavour}":${DEB_IMAGE_ROOT_DIR}/src \
-v "${JFROG_CLI_PKG}":${DEB_IMAGE_ROOT_DIR}/pkg \
--name ${DEB_BUILDER_NAME} \
- ${DEB_BUILD_IMAGE} bash -c "\
+ "${DEB_BUILD_IMAGE}" bash -c "\
\
echo '' && echo '' && \
apt-get update && \
@@ -107,7 +106,7 @@ createRPMPackage(){
local flavour="rpm"
# cleanup old files and containers
- rm -f ${JFROG_CLI_PKG}/${JFROG_CLI_PREFIX}*${VERSION_FORMATTED}*.${flavour}
+ rm -f "${JFROG_CLI_PKG}/${JFROG_CLI_PREFIX}*${VERSION_FORMATTED}*.${flavour}"
docker rm -f "${RPM_BUILDER_NAME}" 2>/dev/null
log "Building ${JFROG_CLI_PREFIX} ${flavour} ${JFROG_CLI_VERSION} on ${RPM_BUILD_IMAGE} image"
@@ -115,7 +114,7 @@ createRPMPackage(){
docker run -t --rm -v "${JFROG_CLI_HOME}/${flavour}":${RPM_IMAGE_ROOT_DIR}/src \
-v "${JFROG_CLI_PKG}":${RPM_IMAGE_ROOT_DIR}/pkg \
--name ${RPM_BUILDER_NAME} \
- ${RPM_BUILD_IMAGE} bash -c "\
+ "${RPM_BUILD_IMAGE}" bash -c "\
echo '' && echo '' && \
yum install -y ${RPM_DEPS} && \
echo '' && echo '' && \
@@ -159,10 +158,10 @@ rpmSign()(
if [[ -f "${filePath}" && -f "${gpgFileInHost}" ]]; then
log ""; log "";
log "Initiating rpm sign on ${filePath}..."
- docker run --rm --name cli-rpm-sign -v "${filePath}":${filePathInImage} \
+ docker run --rm --name cli-rpm-sign -v "${filePath}:${filePathInImage}" \
-v "${gpgFileInHost}":"${gpgFileInImage}" \
-v "${JFROG_CLI_HOME}/build-scripts":${RPM_IMAGE_ROOT_DIR}/src \
- ${RPM_SIGN_IMAGE} \
+ "${RPM_SIGN_IMAGE}" \
bash -c "yum install -y expect rpm-sign pinentry && \
${RPM_IMAGE_ROOT_DIR}/src/${rpmSignScript} \"${gpgFileInImage}\" \"${keYID}\" \"${passphrase}\" \"${filePathInImage}\" \
&& exit 0 || exit 1" \
@@ -178,7 +177,7 @@ rpmSign()(
runTests()(
local flavour=$1
- [ ! -z "${flavour}" ] || { echo "Flavour is mandatory to run tests"; exit 1; }
+ [ -n "${flavour}" ] || { echo "Flavour is mandatory to run tests"; exit 1; }
local fileName="${JFROG_CLI_PREFIX}-${VERSION_FORMATTED}.${flavour}"
local filePath="${JFROG_CLI_PKG}"/${fileName}
@@ -199,7 +198,7 @@ runTests()(
if [ -f "${filePath}" ]; then
log ""; log "";
log "Testing ${filePath} on ${testImage}..."
- docker run --rm --name cli-test -v "${filePath}":${filePathInImage} ${testImage} \
+ docker run --rm --name cli-test -v "${filePath}:${filePathInImage}" "${testImage}" \
bash -c "${installCommand} && jf -version | grep ${JFROG_CLI_VERSION} && \
${signatureTestCommand} && exit 0 || exit 1" \
|| { echo "ERROR: ############### Test failed! ###################"; exit 1; }
@@ -214,28 +213,28 @@ runTests()(
getArch(){
local image=$1
- [ ! -z "$image" ] || return 0;
+ [ -n "$image" ] || return 0;
- docker run --rm ${image} bash -c "uname -m 2>/dev/null" 2>/dev/null
+ docker run --rm "${image}" bash -c "uname -m 2>/dev/null" 2>/dev/null
}
createPackage(){
local flavour=$1
- [ ! -z "${flavour}" ] || errorExit "Flavour is not passed to createPackage method"
+ [ -n "${flavour}" ] || errorExit "Flavour is not passed to createPackage method"
- cp -f "${JFROG_CLI_BINARY}" "${JFROG_CLI_HOME}"/${flavour}/jf \
+ cp -f "${JFROG_CLI_BINARY}" "${JFROG_CLI_HOME}"/"${flavour}"/jf \
|| errorExit "Failed to copy ${JFROG_CLI_BINARY} to ${JFROG_CLI_HOME}/${flavour}/jf"
case "$flavour" in
rpm)
- [ ! -z "${JFROG_CLI_RPM_ARCH}" ] || JFROG_CLI_RPM_ARCH=$(getArch "${RPM_BUILD_IMAGE}")
+ [ -n "${JFROG_CLI_RPM_ARCH}" ] || JFROG_CLI_RPM_ARCH=$(getArch "${RPM_BUILD_IMAGE}")
VERSION_FORMATTED="${JFROG_CLI_VERSION}.${JFROG_CLI_RPM_ARCH}"
createRPMPackage
;;
deb)
- [ ! -z "${JFROG_CLI_DEB_ARCH}" ] || JFROG_CLI_DEB_ARCH=$(getArch "${DEB_BUILD_IMAGE}")
+ [ -n "${JFROG_CLI_DEB_ARCH}" ] || JFROG_CLI_DEB_ARCH=$(getArch "${DEB_BUILD_IMAGE}")
VERSION_FORMATTED="${JFROG_CLI_VERSION}.${JFROG_CLI_DEB_ARCH}"
createDEBPackage
;;
@@ -248,7 +247,7 @@ createPackage(){
setBuildImage(){
local arch="$1"
- [ ! -z "${arch}" ] || errorExit "Architecture is not passed to setBuildImage method"
+ [ -n "${arch}" ] || errorExit "Architecture is not passed to setBuildImage method"
case "$1" in
x86_64)
@@ -262,7 +261,7 @@ setBuildImage(){
}
main(){
- while [[ $# > 0 ]]; do
+ while [[ $# -gt 0 ]]; do
case "$1" in
-f | --flavour)
flavours="$2"
@@ -323,21 +322,21 @@ main(){
esac
done
- : ${flavours:="rpm deb"}
- : ${JFROG_CLI_RUN_TEST:="false"}
- : ${RPM_BUILD_IMAGE:="centos:8"}
- : ${RPM_SIGN_IMAGE:="centos:7"}
- : ${DEB_BUILD_IMAGE:="ubuntu:16.04"}
- : ${DEB_TEST_IMAGE:="${DEB_BUILD_IMAGE}"}
- : ${RPM_TEST_IMAGE:="${RPM_BUILD_IMAGE}"}
- : ${JFROG_CLI_RELEASE_VERSION:="1"}
- : ${RPM_SIGN_PASSPHRASE:="$(cat $RPM_SIGN_PASSPHRASE_FILE)"}
- : ${RPM_SIGN_KEY_ID:="JFrog Inc."}
- : ${RPM_SIGN_KEY_NAME:="RPM-GPG-KEY-jfrog-cli"}
-
- [ ! -z "${JFROG_CLI_BINARY}" ] || exitWithUsage "jfrog cli binary is not passed"
+ : "${flavours:="rpm deb"}"
+ : "${JFROG_CLI_RUN_TEST:="false"}"
+ : "${RPM_BUILD_IMAGE:="centos:8"}"
+ : "${RPM_SIGN_IMAGE:="centos:7"}"
+ : "${DEB_BUILD_IMAGE:="ubuntu:16.04"}"
+ : "${DEB_TEST_IMAGE:="${DEB_BUILD_IMAGE}"}"
+ : "${RPM_TEST_IMAGE:="${RPM_BUILD_IMAGE}"}"
+ : "${JFROG_CLI_RELEASE_VERSION:="1"}"
+ : "${RPM_SIGN_PASSPHRASE:=$(cat "$RPM_SIGN_PASSPHRASE_FILE")}"
+ : "${RPM_SIGN_KEY_ID:="JFrog Inc."}"
+ : "${RPM_SIGN_KEY_NAME:="RPM-GPG-KEY-jfrog-cli"}"
+
+ [ -n "${JFROG_CLI_BINARY}" ] || exitWithUsage "jfrog cli binary is not passed"
[ -f "$JFROG_CLI_BINARY" ] || exitWithUsage "jfrog cli binary is not available at $JFROG_CLI_BINARY"
- [ ! -z "${JFROG_CLI_VERSION}" ] || exitWithUsage "version is not passed, pass the version to be built"
+ [ -n "${JFROG_CLI_VERSION}" ] || exitWithUsage "version is not passed, pass the version to be built"
if [[ "$flavours" == *"rpm"* ]] && [[ -z "${RPM_SIGN_PASSPHRASE}" || "${RPM_SIGN_PASSPHRASE}" == "" ]]; then
echo "ERROR: RPM_SIGN_PASSPHRASE environment variable is not set"
@@ -351,8 +350,13 @@ main(){
for flavour in $flavours; do
createPackage "$flavour"
- [[ "${flavour}" == "rpm" ]] && rpmSign || true
- [[ "${JFROG_CLI_RUN_TEST}" == "true" ]] && runTests "${flavour}" || true
+ if [[ "${flavour}" == "rpm" ]]; then
+ rpmSign
+ fi
+
+ if [[ "${JFROG_CLI_RUN_TEST}" == "true" ]]; then
+ runTests "${flavour}"
+ fi
done
log "...and Done!"
diff --git a/build/deb_rpm/v2-jf/build-scripts/rpm-install.sh b/build/deb_rpm/v2-jf/build-scripts/rpm-install.sh
index 4b42e5864..6eaceadb5 100644
--- a/build/deb_rpm/v2-jf/build-scripts/rpm-install.sh
+++ b/build/deb_rpm/v2-jf/build-scripts/rpm-install.sh
@@ -1,7 +1,8 @@
-echo "[jfrog-cli]" > jfrog-cli.repo;
-echo "name=jfrog-cli" >> jfrog-cli.repo;
-echo "baseurl=https://releases.jfrog.io/artifactory/jfrog-rpms" >> jfrog-cli.repo;
-echo "enabled=1" >> jfrog-cli.repo;
-echo "gpgcheck=0" >> jfrog-cli.repo;
-sudo mv jfrog-cli.repo /etc/yum.repos.d/;
+#!/bin/bash
+
+echo -e "[jfrog-cli]
+name=jfrog-cli
+baseurl=https://releases.jfrog.io/artifactory/jfrog-rpms
+enabled=1
+gpgcheck=0" | sudo tee /etc/yum.repos.d/jfrog-cli.repo >/dev/null
yum install -y jfrog-cli-v2-jf;
diff --git a/build/deb_rpm/v2-jf/build-scripts/rpm-sign.sh b/build/deb_rpm/v2-jf/build-scripts/rpm-sign.sh
index 5a94ce9fe..f76d1d0c7 100755
--- a/build/deb_rpm/v2-jf/build-scripts/rpm-sign.sh
+++ b/build/deb_rpm/v2-jf/build-scripts/rpm-sign.sh
@@ -23,11 +23,14 @@ rpmInitSigning(){
log "Initializing rpm sign..."
- gpg --allow-secret-key-import --import ${gpgKeyFile} && \
+ gpg --allow-secret-key-import --import "${gpgKeyFile}" && \
gpg --export -a "${keyID}" > /tmp/tmpFile && \
- rpm --import /tmp/tmpFile && \
- rpm -q gpg-pubkey --qf '%{name}-%{version}-%{release} --> %{summary}\n' | grep "${keyID}" || \
- { echo "ERROR: RPM signature initialization failed!" >&2; exit 1; }
+ if rpm --import /tmp/tmpFile && rpm -q gpg-pubkey --qf '%{name}-%{version}-%{release} --> %{summary}\n' | grep "${keyID}"; then
+ echo "RPM signature initialization succeeded."
+ else
+ echo "ERROR: RPM signature initialization failed!" >&2
+ exit 1
+ fi
rpmEditRpmMacro "${keyID}" || \
{ echo "ERROR: Configuring rpm macro failed!" >&2; exit 1; }
diff --git a/build/deb_rpm/v2-jf/deb/debian/control b/build/deb_rpm/v2-jf/deb/debian/control
index 06b29a49f..8e2d15591 100644
--- a/build/deb_rpm/v2-jf/deb/debian/control
+++ b/build/deb_rpm/v2-jf/deb/debian/control
@@ -4,7 +4,7 @@ Priority: optional
Maintainer: Jfrog
Build-Depends: debhelper (>=8~)
Standards-Version: 3.9.7
-Homepage: https://www.jfrog.com/confluence/display/CLI/JFrog+CLI
+Homepage: https://docs.jfrog-applications.jfrog.io/jfrog-applications/jfrog-cli
Package: jfrog-cli-v2-jf
Architecture: any
diff --git a/build/deb_rpm/v2/build-scripts/deb-install.sh b/build/deb_rpm/v2/build-scripts/deb-install.sh
index 3540fc6ca..20253e4ff 100644
--- a/build/deb_rpm/v2/build-scripts/deb-install.sh
+++ b/build/deb_rpm/v2/build-scripts/deb-install.sh
@@ -1,3 +1,5 @@
+#!/bin/bash
+
wget -qO - https://releases.jfrog.io/artifactory/api/gpg/key/public | apt-key add -;
echo "deb https://releases.jfrog.io/artifactory/jfrog-debs xenial contrib" | sudo tee -a /etc/apt/sources.list;
apt update;
diff --git a/build/deb_rpm/v2/build-scripts/pack.sh b/build/deb_rpm/v2/build-scripts/pack.sh
index b47269c7a..90e904962 100755
--- a/build/deb_rpm/v2/build-scripts/pack.sh
+++ b/build/deb_rpm/v2/build-scripts/pack.sh
@@ -46,12 +46,11 @@ errorExit() {
}
checkDockerAccess() {
- log "Checking docker" "DEBUG"
- docker -v > /dev/null 2>&1 && docker ps > /dev/null 2>&1
- if [ $? -ne 0 ]; then
- errorExit "Must run as user that can execute docker commands"
- fi
- log "Docker is avaiable" "DEBUG"
+if docker -v > /dev/null 2>&1 && docker ps > /dev/null 2>&1; then
+ log "Docker is available" "DEBUG"
+else
+ errorExit "Must run as a user that can execute docker commands"
+fi
}
exitWithUsage(){
@@ -64,7 +63,7 @@ createDEBPackage(){
local flavour="deb"
# cleanup old files and containers
- rm -f ${JFROG_CLI_PKG}/${JFROG_CLI_PREFIX}*${VERSION_FORMATTED}*.${flavour}
+ rm -f "${JFROG_CLI_PKG}/${JFROG_CLI_PREFIX}*${VERSION_FORMATTED}*.${flavour}"
docker rm -f "${RPM_BUILDER_NAME}" 2>/dev/null
log "Building ${JFROG_CLI_PREFIX} ${flavour} ${JFROG_CLI_VERSION} on ${DEB_BUILD_IMAGE} image"
@@ -72,7 +71,7 @@ createDEBPackage(){
docker run -t --rm -v "${JFROG_CLI_HOME}/${flavour}":${DEB_IMAGE_ROOT_DIR}/src \
-v "${JFROG_CLI_PKG}":${DEB_IMAGE_ROOT_DIR}/pkg \
--name ${DEB_BUILDER_NAME} \
- ${DEB_BUILD_IMAGE} bash -c "\
+ "${DEB_BUILD_IMAGE}" bash -c "\
\
echo '' && echo '' && \
apt-get update && \
@@ -107,7 +106,7 @@ createRPMPackage(){
local flavour="rpm"
# cleanup old files and containers
- rm -f ${JFROG_CLI_PKG}/${JFROG_CLI_PREFIX}*${VERSION_FORMATTED}*.${flavour}
+ rm -f "${JFROG_CLI_PKG}/${JFROG_CLI_PREFIX}*${VERSION_FORMATTED}*.${flavour}"
docker rm -f "${RPM_BUILDER_NAME}" 2>/dev/null
log "Building ${JFROG_CLI_PREFIX} ${flavour} ${JFROG_CLI_VERSION} on ${RPM_BUILD_IMAGE} image"
@@ -115,7 +114,7 @@ createRPMPackage(){
docker run -t --rm -v "${JFROG_CLI_HOME}/${flavour}":${RPM_IMAGE_ROOT_DIR}/src \
-v "${JFROG_CLI_PKG}":${RPM_IMAGE_ROOT_DIR}/pkg \
--name ${RPM_BUILDER_NAME} \
- ${RPM_BUILD_IMAGE} bash -c "\
+ "${RPM_BUILD_IMAGE}" bash -c "\
echo '' && echo '' && \
yum install -y ${RPM_DEPS} && \
echo '' && echo '' && \
@@ -159,10 +158,10 @@ rpmSign()(
if [[ -f "${filePath}" && -f "${gpgFileInHost}" ]]; then
log ""; log "";
log "Initiating rpm sign on ${filePath}..."
- docker run --rm --name cli-rpm-sign -v "${filePath}":${filePathInImage} \
+ docker run --rm --name cli-rpm-sign -v "${filePath}:${filePathInImage}" \
-v "${gpgFileInHost}":"${gpgFileInImage}" \
-v "${JFROG_CLI_HOME}/build-scripts":${RPM_IMAGE_ROOT_DIR}/src \
- ${RPM_SIGN_IMAGE} \
+ "${RPM_SIGN_IMAGE}" \
bash -c "yum install -y expect rpm-sign pinentry && \
${RPM_IMAGE_ROOT_DIR}/src/${rpmSignScript} \"${gpgFileInImage}\" \"${keYID}\" \"${passphrase}\" \"${filePathInImage}\" \
&& exit 0 || exit 1" \
@@ -178,7 +177,7 @@ rpmSign()(
runTests()(
local flavour=$1
- [ ! -z "${flavour}" ] || { echo "Flavour is mandatory to run tests"; exit 1; }
+ [ -n "${flavour}" ] || { echo "Flavour is mandatory to run tests"; exit 1; }
local fileName="${JFROG_CLI_PREFIX}-${VERSION_FORMATTED}.${flavour}"
local filePath="${JFROG_CLI_PKG}"/${fileName}
@@ -199,7 +198,7 @@ runTests()(
if [ -f "${filePath}" ]; then
log ""; log "";
log "Testing ${filePath} on ${testImage}..."
- docker run --rm --name cli-test -v "${filePath}":${filePathInImage} ${testImage} \
+ docker run --rm --name cli-test -v "${filePath}:${filePathInImage}" "${testImage}" \
bash -c "${installCommand} && jfrog -version | grep ${JFROG_CLI_VERSION} && \
${signatureTestCommand} && exit 0 || exit 1" \
|| { echo "ERROR: ############### Test failed! ###################"; exit 1; }
@@ -214,28 +213,28 @@ runTests()(
getArch(){
local image=$1
- [ ! -z "$image" ] || return 0;
+ [ -n "$image" ] || return 0;
- docker run --rm ${image} bash -c "uname -m 2>/dev/null" 2>/dev/null
+ docker run --rm "${image}" bash -c "uname -m 2>/dev/null" 2>/dev/null
}
createPackage(){
local flavour=$1
- [ ! -z "${flavour}" ] || errorExit "Flavour is not passed to createPackage method"
+ [ -n "${flavour}" ] || errorExit "Flavour is not passed to createPackage method"
- cp -f "${JFROG_CLI_BINARY}" "${JFROG_CLI_HOME}"/${flavour}/jfrog \
+ cp -f "${JFROG_CLI_BINARY}" "${JFROG_CLI_HOME}"/"${flavour}"/jfrog \
|| errorExit "Failed to copy ${JFROG_CLI_BINARY} to ${JFROG_CLI_HOME}/${flavour}/jfrog"
case "$flavour" in
rpm)
- [ ! -z "${JFROG_CLI_RPM_ARCH}" ] || JFROG_CLI_RPM_ARCH=$(getArch "${RPM_BUILD_IMAGE}")
+ [ -n "${JFROG_CLI_RPM_ARCH}" ] || JFROG_CLI_RPM_ARCH=$(getArch "${RPM_BUILD_IMAGE}")
VERSION_FORMATTED="${JFROG_CLI_VERSION}.${JFROG_CLI_RPM_ARCH}"
createRPMPackage
;;
deb)
- [ ! -z "${JFROG_CLI_DEB_ARCH}" ] || JFROG_CLI_DEB_ARCH=$(getArch "${DEB_BUILD_IMAGE}")
+ [ -n "${JFROG_CLI_DEB_ARCH}" ] || JFROG_CLI_DEB_ARCH=$(getArch "${DEB_BUILD_IMAGE}")
VERSION_FORMATTED="${JFROG_CLI_VERSION}.${JFROG_CLI_DEB_ARCH}"
createDEBPackage
;;
@@ -248,7 +247,7 @@ createPackage(){
setBuildImage(){
local arch="$1"
- [ ! -z "${arch}" ] || errorExit "Architecture is not passed to setBuildImage method"
+ [ -n "${arch}" ] || errorExit "Architecture is not passed to setBuildImage method"
case "$1" in
x86_64)
@@ -262,7 +261,7 @@ setBuildImage(){
}
main(){
- while [[ $# > 0 ]]; do
+ while [[ $# -gt 0 ]]; do
case "$1" in
-f | --flavour)
flavours="$2"
@@ -323,21 +322,21 @@ main(){
esac
done
- : ${flavours:="rpm deb"}
- : ${JFROG_CLI_RUN_TEST:="false"}
- : ${RPM_BUILD_IMAGE:="centos:8"}
- : ${RPM_SIGN_IMAGE:="centos:7"}
- : ${DEB_BUILD_IMAGE:="ubuntu:16.04"}
- : ${DEB_TEST_IMAGE:="${DEB_BUILD_IMAGE}"}
- : ${RPM_TEST_IMAGE:="${RPM_BUILD_IMAGE}"}
- : ${JFROG_CLI_RELEASE_VERSION:="1"}
- : ${RPM_SIGN_PASSPHRASE:="$(cat $RPM_SIGN_PASSPHRASE_FILE)"}
- : ${RPM_SIGN_KEY_ID:="JFrog Inc."}
- : ${RPM_SIGN_KEY_NAME:="RPM-GPG-KEY-jfrog-cli"}
-
- [ ! -z "${JFROG_CLI_BINARY}" ] || exitWithUsage "jfrog cli binary is not passed"
+ : "${flavours:="rpm deb"}"
+ : "${JFROG_CLI_RUN_TEST:="false"}"
+ : "${RPM_BUILD_IMAGE:="centos:8"}"
+ : "${RPM_SIGN_IMAGE:="centos:7"}"
+ : "${DEB_BUILD_IMAGE:="ubuntu:16.04"}"
+ : "${DEB_TEST_IMAGE:="${DEB_BUILD_IMAGE}"}"
+ : "${RPM_TEST_IMAGE:="${RPM_BUILD_IMAGE}"}"
+ : "${JFROG_CLI_RELEASE_VERSION:="1"}"
+ : "${RPM_SIGN_PASSPHRASE:=$(cat "$RPM_SIGN_PASSPHRASE_FILE")}"
+ : "${RPM_SIGN_KEY_ID:="JFrog Inc."}"
+ : "${RPM_SIGN_KEY_NAME:="RPM-GPG-KEY-jfrog-cli"}"
+
+ [ -n "${JFROG_CLI_BINARY}" ] || exitWithUsage "jfrog cli binary is not passed"
[ -f "$JFROG_CLI_BINARY" ] || exitWithUsage "jfrog cli binary is not available at $JFROG_CLI_BINARY"
- [ ! -z "${JFROG_CLI_VERSION}" ] || exitWithUsage "version is not passed, pass the version to be built"
+ [ -n "${JFROG_CLI_VERSION}" ] || exitWithUsage "version is not passed, pass the version to be built"
if [[ "$flavours" == *"rpm"* ]] && [[ -z "${RPM_SIGN_PASSPHRASE}" || "${RPM_SIGN_PASSPHRASE}" == "" ]]; then
echo "ERROR: RPM_SIGN_PASSPHRASE environment variable is not set"
@@ -351,8 +350,13 @@ main(){
for flavour in $flavours; do
createPackage "$flavour"
- [[ "${flavour}" == "rpm" ]] && rpmSign || true
- [[ "${JFROG_CLI_RUN_TEST}" == "true" ]] && runTests "${flavour}" || true
+ if [[ "${flavour}" == "rpm" ]]; then
+ rpmSign
+ fi
+
+ if [[ "${JFROG_CLI_RUN_TEST}" == "true" ]]; then
+ runTests "${flavour}"
+ fi
done
log "...and Done!"
diff --git a/build/deb_rpm/v2/build-scripts/rpm-install.sh b/build/deb_rpm/v2/build-scripts/rpm-install.sh
index 98849e879..5ac712e88 100644
--- a/build/deb_rpm/v2/build-scripts/rpm-install.sh
+++ b/build/deb_rpm/v2/build-scripts/rpm-install.sh
@@ -1,8 +1,9 @@
-echo "[jfrog-cli]" > jfrog-cli.repo;
-echo "name=jfrog-cli" >> jfrog-cli.repo;
-echo "baseurl=https://releases.jfrog.io/artifactory/jfrog-rpms" >> jfrog-cli.repo;
-echo "enabled=1" >> jfrog-cli.repo;
-echo "gpgcheck=0" >> jfrog-cli.repo;
-sudo mv jfrog-cli.repo /etc/yum.repos.d/;
+#!/bin/bash
+
+echo -e "[jfrog-cli]
+name=jfrog-cli
+baseurl=https://releases.jfrog.io/artifactory/jfrog-rpms
+enabled=1
+gpgcheck=0" | sudo tee /etc/yum.repos.d/jfrog-cli.repo >/dev/null
yum install -y jfrog-cli-v2;
jf intro;
diff --git a/build/deb_rpm/v2/build-scripts/rpm-sign.sh b/build/deb_rpm/v2/build-scripts/rpm-sign.sh
index 5a94ce9fe..f76d1d0c7 100755
--- a/build/deb_rpm/v2/build-scripts/rpm-sign.sh
+++ b/build/deb_rpm/v2/build-scripts/rpm-sign.sh
@@ -23,11 +23,14 @@ rpmInitSigning(){
log "Initializing rpm sign..."
- gpg --allow-secret-key-import --import ${gpgKeyFile} && \
+ gpg --allow-secret-key-import --import "${gpgKeyFile}" && \
gpg --export -a "${keyID}" > /tmp/tmpFile && \
- rpm --import /tmp/tmpFile && \
- rpm -q gpg-pubkey --qf '%{name}-%{version}-%{release} --> %{summary}\n' | grep "${keyID}" || \
- { echo "ERROR: RPM signature initialization failed!" >&2; exit 1; }
+ if rpm --import /tmp/tmpFile && rpm -q gpg-pubkey --qf '%{name}-%{version}-%{release} --> %{summary}\n' | grep "${keyID}"; then
+ echo "RPM signature initialization succeeded."
+ else
+ echo "ERROR: RPM signature initialization failed!" >&2
+ exit 1
+ fi
rpmEditRpmMacro "${keyID}" || \
{ echo "ERROR: Configuring rpm macro failed!" >&2; exit 1; }
diff --git a/build/deb_rpm/v2/deb/debian/control b/build/deb_rpm/v2/deb/debian/control
index d93140e44..4c9f43f08 100644
--- a/build/deb_rpm/v2/deb/debian/control
+++ b/build/deb_rpm/v2/deb/debian/control
@@ -4,7 +4,7 @@ Priority: optional
Maintainer: Jfrog
Build-Depends: debhelper (>=8~)
Standards-Version: 3.9.7
-Homepage: https://www.jfrog.com/confluence/display/CLI/JFrog+CLI
+Homepage: https://docs.jfrog-applications.jfrog.io/jfrog-applications/jfrog-cli
Package: jfrog-cli-v2
Architecture: any
diff --git a/build/docker/slim/Dockerfile b/build/docker/slim/Dockerfile
index ae69bd4c7..43e2ae71b 100644
--- a/build/docker/slim/Dockerfile
+++ b/build/docker/slim/Dockerfile
@@ -11,6 +11,6 @@ FROM ${repo_name_21}/jfrog-docker/alpine:3
ARG image_name=jfrog-cli
ARG cli_executable_name
ENV CI true
-RUN apk add --no-cache bash tzdata ca-certificates curl
+RUN apk add --no-cache bash tzdata ca-certificates curl jq
COPY --from=builder /${image_name}/${cli_executable_name} /usr/local/bin/${cli_executable_name}
RUN chmod +x /usr/local/bin/${cli_executable_name}
diff --git a/build/getcli/jf.sh b/build/getcli/jf.sh
index 177e476c8..7b1f5eeff 100644
--- a/build/getcli/jf.sh
+++ b/build/getcli/jf.sh
@@ -1,7 +1,6 @@
#!/bin/bash
CLI_OS="na"
-CLI_UNAME="na"
CLI_MAJOR_VER="v2-jf"
VERSION="[RELEASE]"
@@ -13,11 +12,11 @@ else
echo "Downloading the latest version of JFrog CLI..."
fi
-if $(echo "${OSTYPE}" | grep -q msys); then
+if echo "${OSTYPE}" | grep -q msys; then
CLI_OS="windows"
URL="https://releases.jfrog.io/artifactory/jfrog-cli/${CLI_MAJOR_VER}/${VERSION}/jfrog-cli-windows-amd64/jf.exe"
FILE_NAME="jf.exe"
-elif $(echo "${OSTYPE}" | grep -q darwin); then
+elif echo "${OSTYPE}" | grep -q darwin; then
CLI_OS="mac"
if [[ $(uname -m) == 'arm64' ]]; then
URL="https://releases.jfrog.io/artifactory/jfrog-cli/${CLI_MAJOR_VER}/${VERSION}/jfrog-cli-mac-arm64/jf"
@@ -52,7 +51,7 @@ else
;;
*)
echo "Unknown machine type: $MACHINE_TYPE"
- exit -1
+ exit 1
;;
esac
URL="https://releases.jfrog.io/artifactory/jfrog-cli/${CLI_MAJOR_VER}/${VERSION}/jfrog-cli-${CLI_OS}-${ARCH}/jf"
diff --git a/build/getcli/jfrog.sh b/build/getcli/jfrog.sh
index 6f09e17a7..1debb922e 100644
--- a/build/getcli/jfrog.sh
+++ b/build/getcli/jfrog.sh
@@ -1,7 +1,6 @@
#!/bin/bash
CLI_OS="na"
-CLI_UNAME="na"
CLI_MAJOR_VER="v2"
VERSION="[RELEASE]"
@@ -13,11 +12,11 @@ else
echo "Downloading the latest version of JFrog CLI..."
fi
-if $(echo "${OSTYPE}" | grep -q msys); then
+if echo "${OSTYPE}" | grep -q msys; then
CLI_OS="windows"
URL="https://releases.jfrog.io/artifactory/jfrog-cli/${CLI_MAJOR_VER}/${VERSION}/jfrog-cli-windows-amd64/jfrog.exe"
FILE_NAME="jfrog.exe"
-elif $(echo "${OSTYPE}" | grep -q darwin); then
+elif echo "${OSTYPE}" | grep -q darwin; then
CLI_OS="mac"
if [[ $(uname -m) == 'arm64' ]]; then
URL="https://releases.jfrog.io/artifactory/jfrog-cli/${CLI_MAJOR_VER}/${VERSION}/jfrog-cli-mac-arm64/jfrog"
@@ -52,7 +51,7 @@ else
;;
*)
echo "Unknown machine type: $MACHINE_TYPE"
- exit -1
+ exit 1
;;
esac
URL="https://releases.jfrog.io/artifactory/jfrog-cli/${CLI_MAJOR_VER}/${VERSION}/jfrog-cli-${CLI_OS}-${ARCH}/jfrog"
diff --git a/build/gitlab/v2/.setup-jfrog-unix.yml b/build/gitlab/v2/.setup-jfrog-unix.yml
index cbef2bb81..4f8f78cfa 100644
--- a/build/gitlab/v2/.setup-jfrog-unix.yml
+++ b/build/gitlab/v2/.setup-jfrog-unix.yml
@@ -39,7 +39,7 @@
# Build the URL to the executable matching the OS.
- |
- if $(echo "${OSTYPE}" | grep -q darwin); then
+ if echo "${OSTYPE}" | grep -q darwin; then
CLI_OS="mac"
if [[ $(uname -m) == 'arm64' ]]; then
URL="${BASE_URL}/jfrog-cli/v2-jf/${VERSION}/jfrog-cli-mac-arm64/jf"
diff --git a/build/installcli/jf.sh b/build/installcli/jf.sh
index 134359c9b..4619708d4 100755
--- a/build/installcli/jf.sh
+++ b/build/installcli/jf.sh
@@ -1,11 +1,8 @@
#!/bin/bash
CLI_OS="na"
-CLI_UNAME="na"
CLI_MAJOR_VER="v2-jf"
VERSION="[RELEASE]"
-# Order is by destination priority.
-DESTINATION_PATHS="/usr/local/bin /usr/bin /opt/bin"
if [ $# -eq 1 ]
then
@@ -16,11 +13,11 @@ else
fi
echo ""
-if $(echo "${OSTYPE}" | grep -q msys); then
+if echo "${OSTYPE}" | grep -q msys; then
CLI_OS="windows"
URL="https://releases.jfrog.io/artifactory/jfrog-cli/${CLI_MAJOR_VER}/${VERSION}/jfrog-cli-windows-amd64/jf.exe"
FILE_NAME="jf.exe"
-elif $(echo "${OSTYPE}" | grep -q darwin); then
+elif echo "${OSTYPE}" | grep -q darwin; then
CLI_OS="mac"
if [[ $(uname -m) == 'arm64' ]]; then
URL="https://releases.jfrog.io/artifactory/jfrog-cli/${CLI_MAJOR_VER}/${VERSION}/jfrog-cli-mac-arm64/jf"
@@ -55,7 +52,7 @@ else
;;
*)
echo "Unknown machine type: $MACHINE_TYPE"
- exit -1
+ exit 1
;;
esac
URL="https://releases.jfrog.io/artifactory/jfrog-cli/${CLI_MAJOR_VER}/${VERSION}/jfrog-cli-${CLI_OS}-${ARCH}/jf"
@@ -66,13 +63,12 @@ curl -XGET "$URL" -L -k -g > $FILE_NAME
chmod u+x $FILE_NAME
# Move executable to a destination in path.
-set -- $DESTINATION_PATHS
+# Order is by destination priority.
+set -- "/usr/local/bin" "/usr/bin" "/opt/bin"
while [ -n "$1" ]; do
# Check if destination is in path.
- if echo $PATH|grep "$1" -> /dev/null ; then
- mv $FILE_NAME $1
- if [ "$?" -eq "0" ]
- then
+ if echo "$PATH"|grep "$1" -> /dev/null ; then
+ if mv $FILE_NAME "$1" ; then
echo ""
echo "The $FILE_NAME executable was installed in $1"
jf intro
@@ -80,9 +76,7 @@ while [ -n "$1" ]; do
else
echo ""
echo "We'd like to install the JFrog CLI executable in $1. Please approve this installation by entering your password."
- sudo mv $FILE_NAME $1
- if [ "$?" -eq "0" ]
- then
+ if sudo mv $FILE_NAME "$1" ; then
echo ""
echo "The $FILE_NAME executable was installed in $1"
jf intro
diff --git a/build/installcli/jfrog.sh b/build/installcli/jfrog.sh
index a8359af1e..80ec7c3f3 100755
--- a/build/installcli/jfrog.sh
+++ b/build/installcli/jfrog.sh
@@ -1,11 +1,8 @@
#!/bin/bash
CLI_OS="na"
-CLI_UNAME="na"
CLI_MAJOR_VER="v2"
VERSION="[RELEASE]"
-# Order is by destination priority.
-DESTINATION_PATHS="/usr/local/bin /usr/bin /opt/bin"
if [ $# -eq 1 ]
then
@@ -16,11 +13,11 @@ else
fi
echo ""
-if $(echo "${OSTYPE}" | grep -q msys); then
+if echo "${OSTYPE}" | grep -q msys; then
CLI_OS="windows"
URL="https://releases.jfrog.io/artifactory/jfrog-cli/${CLI_MAJOR_VER}/${VERSION}/jfrog-cli-windows-amd64/jfrog.exe"
FILE_NAME="jfrog.exe"
-elif $(echo "${OSTYPE}" | grep -q darwin); then
+elif echo "${OSTYPE}" | grep -q darwin; then
CLI_OS="mac"
if [[ $(uname -m) == 'arm64' ]]; then
URL="https://releases.jfrog.io/artifactory/jfrog-cli/${CLI_MAJOR_VER}/${VERSION}/jfrog-cli-mac-arm64/jfrog"
@@ -55,7 +52,7 @@ else
;;
*)
echo "Unknown machine type: $MACHINE_TYPE"
- exit -1
+ exit 1
;;
esac
URL="https://releases.jfrog.io/artifactory/jfrog-cli/${CLI_MAJOR_VER}/${VERSION}/jfrog-cli-${CLI_OS}-${ARCH}/jfrog"
@@ -66,22 +63,19 @@ curl -XGET "$URL" -L -k -g > $FILE_NAME
chmod u+x $FILE_NAME
# Move executable to a destination in path.
-set -- $DESTINATION_PATHS
+# Order is by destination priority.
+set -- "/usr/local/bin" "/usr/bin" "/opt/bin"
while [ -n "$1" ]; do
# Check if destination is in path.
- if echo $PATH|grep "$1" -> /dev/null ; then
- mv $FILE_NAME $1
- if [ "$?" -eq "0" ]
- then
+ if echo "$PATH"|grep "$1" -> /dev/null ; then
+ if mv $FILE_NAME "$1" ; then
echo ""
echo "The $FILE_NAME executable was installed in $1"
exit 0
else
echo ""
echo "We'd like to install the JFrog CLI executable in $1. Please approve this installation by entering your password."
- sudo mv $FILE_NAME $1
- if [ "$?" -eq "0" ]
- then
+ if sudo mv $FILE_NAME "$1" ; then
echo ""
echo "The $FILE_NAME executable was installed in $1"
exit 0
diff --git a/build/npm/v2-jf/README.md b/build/npm/v2-jf/README.md
index a53432f1d..4b3ca76d9 100644
--- a/build/npm/v2-jf/README.md
+++ b/build/npm/v2-jf/README.md
@@ -6,7 +6,7 @@
# JFrog CLI
-[Website](http://www.jfrog.com) • [Docs](https://www.jfrog.com/confluence/display/CLI/JFrog+CLI) • [Issues](https://github.com/jfrog/jfrog-cli-go/issues) • [Blog](https://jfrog.com/blog/) • [We're Hiring](https://join.jfrog.com/) • [Artifactory Free Trial](https://jfrog.com/artifactory/free-trial/)
+[Website](http://www.jfrog.com) • [Docs](https://docs.jfrog-applications.jfrog.io/jfrog-applications/jfrog-cli) • [Issues](https://github.com/jfrog/jfrog-cli/issues) • [Blog](https://jfrog.com/blog/) • [We're Hiring](https://join.jfrog.com/) • [Artifactory Free Trial](https://jfrog.com/artifactory/free-trial/)
## Overview
diff --git a/build/npm/v2-jf/init.js b/build/npm/v2-jf/init.js
index e3d82ebd6..8b5499b1e 100644
--- a/build/npm/v2-jf/init.js
+++ b/build/npm/v2-jf/init.js
@@ -1,65 +1,90 @@
validateNpmVersion();
-var https = require('https');
-var http = require('http');
-var url = require('url');
-var fs = require('fs');
-var packageJson = require('./package.json');
-var fileName = getFileName();
-var filePath = "bin/" + fileName;
-var version = packageJson.version;
-var pkgName = "jfrog-cli-" + getArchitecture();
+const {get} = require("https");
+const {request} = require("http");
+const {URL} = require("url");
+const {createWriteStream, chmodSync} = require("fs");
+const packageJson = require("./package.json");
+const fileName = getFileName();
+const filePath = "bin/" + fileName;
+const version = packageJson.version;
+const pkgName = "jfrog-cli-" + getArchitecture();
downloadCli();
function validateNpmVersion() {
if (!isValidNpmVersion()) {
- throw new Error("JFrog CLI can be installed using npm version 5.0.0 or above.");
+ throw new Error(
+ "JFrog CLI can be installed using npm version 5.0.0 or above."
+ );
}
}
function downloadWithProxy(myUrl) {
- var proxyparts = url.parse(process.env.https_proxy);
- var myUrlParts = url.parse(myUrl);
+ const proxyParts = new URL(process.env.https_proxy);
+ const myUrlParts = new URL(myUrl);
- http.request({
- host: proxyparts.hostname,
- port: proxyparts.port,
- method: 'CONNECT',
- path: myUrlParts.hostname + ':443'
- }).on('connect', function(res, socket, head) {
- https.get({
- host: myUrlParts.hostname,
- socket: socket,
- path: myUrlParts.path,
- agent: false
- }, function(res) {
- if (res.statusCode == 301 || res.statusCode == 302) {
- downloadWithProxy(res.headers.location);
- } else if (res.statusCode == 200) {
- writeToFile(res);
- } else {
- console.log('Unexpected status code ' + res.statusCode + ' during JFrog CLI download');
- }
- }).on('error', function (err) {console.error(err);});
- }).end();
+ request({
+ host: proxyParts.hostname,
+ port: proxyParts.port,
+ method: "CONNECT",
+ path: myUrlParts.hostname + ":443",
+ })
+ .on("connect", function (res, socket, _) {
+ get(
+ {
+ host: myUrlParts.hostname,
+ socket: socket,
+ path: myUrlParts.path,
+ agent: false,
+ },
+ function (res) {
+ if (res.statusCode === 301 || res.statusCode === 302) {
+ downloadWithProxy(res.headers.location);
+ } else if (res.statusCode === 200) {
+ writeToFile(res);
+ } else {
+ console.log(
+ "Unexpected status code " +
+ res.statusCode +
+ " during JFrog CLI download"
+ );
+ }
+ }
+ ).on("error", function (err) {
+ console.error(err);
+ });
+ })
+ .end();
}
function download(url) {
- https.get(url, function(res) {
- if (res.statusCode == 301 || res.statusCode == 302) {
+ get(url, function (res) {
+ if (res.statusCode === 301 || res.statusCode === 302) {
download(res.headers.location);
- } else if (res.statusCode == 200) {
+ } else if (res.statusCode === 200) {
writeToFile(res);
} else {
- console.log('Unexpected status code ' + res.statusCode + ' during JFrog CLI download');
+ console.log(
+ "Unexpected status code " +
+ res.statusCode +
+ " during JFrog CLI download"
+ );
}
- }).on('error', function (err) {console.error(err);});
+ }).on("error", function (err) {
+ console.error(err);
+ });
}
function downloadCli() {
- console.log("Downloading JFrog CLI " + version );
- var startUrl = 'https://releases.jfrog.io/artifactory/jfrog-cli/v2-jf/' + version + '/' + pkgName + '/' + fileName;
+ console.log("Downloading JFrog CLI " + version);
+ const startUrl =
+ "https://releases.jfrog.io/artifactory/jfrog-cli/v2-jf/" +
+ version +
+ "/" +
+ pkgName +
+ "/" +
+ fileName;
// We detect outbound proxy by looking at the environment variable
if (process.env.https_proxy && process.env.https_proxy.length > 0) {
downloadWithProxy(startUrl);
@@ -69,58 +94,61 @@ function downloadCli() {
}
function isValidNpmVersion() {
- var child_process = require('child_process');
- var npmVersionCmdOut = child_process.execSync("npm version -json");
- var npmVersion = JSON.parse(npmVersionCmdOut).npm;
- // Supported since version 5.0.0
- return parseInt(npmVersion.charAt(0)) > 4;
+ const child_process = require("child_process");
+ const npmVersionCmdOut = child_process.execSync("npm version -json");
+ const npmVersion = JSON.parse(npmVersionCmdOut).npm;
+ // Supported since version 5.0.0 (also support npm v10+)
+ return parseInt(npmVersion.split('.')[0]) > 4;
}
function writeToFile(response) {
- var file = fs.createWriteStream(filePath);
- response.on('data', function (chunk) {
- file.write(chunk);
- }).on('end', function () {
- file.end();
- if (!process.platform.startsWith("win")) {
- fs.chmodSync(filePath, 0555);
- }
- }).on('error', function (err) {
- console.error(err);
- });
+ const file = createWriteStream(filePath);
+ response
+ .on("data", function (chunk) {
+ file.write(chunk);
+ })
+ .on("end", function () {
+ file.end();
+ if (!process.platform.startsWith("win")) {
+ chmodSync(filePath, '755');
+ }
+ })
+ .on("error", function (err) {
+ console.error(err);
+ });
}
function getArchitecture() {
const platform = process.platform;
- if (platform.startsWith('win')) {
+ if (platform.startsWith("win")) {
// Windows architecture:
- return 'windows-amd64';
+ return "windows-amd64";
}
const arch = process.arch;
- if (platform.includes('darwin')) {
+ if (platform.includes("darwin")) {
// macOS architecture:
- return arch === 'arm64' ? 'mac-arm64' : 'mac-386';
+ return arch === "arm64" ? "mac-arm64" : "mac-386";
}
// linux architecture:
switch (arch) {
- case 'x64':
- return 'linux-amd64';
- case 'arm64':
- return 'linux-arm64';
- case 'arm':
- return 'linux-arm';
- case 's390x':
- return 'linux-s390x';
- case 'ppc64':
- return 'linux-ppc64';
+ case "x64":
+ return "linux-amd64";
+ case "arm64":
+ return "linux-arm64";
+ case "arm":
+ return "linux-arm";
+ case "s390x":
+ return "linux-s390x";
+ case "ppc64":
+ return "linux-ppc64";
default:
- return 'linux-386';
+ return "linux-386";
}
}
function getFileName() {
- var executable = "jf";
+ let executable = "jf";
if (process.platform.startsWith("win")) {
executable += ".exe";
}
diff --git a/build/npm/v2-jf/package-lock.json b/build/npm/v2-jf/package-lock.json
index 4657dffc3..cbbd69036 100644
--- a/build/npm/v2-jf/package-lock.json
+++ b/build/npm/v2-jf/package-lock.json
@@ -1,5 +1,5 @@
{
"name": "jfrog-cli-v2-jf",
- "version": "2.46.2",
+ "version": "2.50.4",
"lockfileVersion": 1
}
diff --git a/build/npm/v2-jf/package.json b/build/npm/v2-jf/package.json
index 8285fd5af..fcb104097 100644
--- a/build/npm/v2-jf/package.json
+++ b/build/npm/v2-jf/package.json
@@ -1,6 +1,6 @@
{
"name": "jfrog-cli-v2-jf",
- "version": "2.46.2",
+ "version": "2.50.4",
"description": "🐸 Command-line interface for JFrog Artifactory, Xray, Distribution, Pipelines and Mission Control 🐸",
"homepage": "https://github.com/jfrog/jfrog-cli",
"preferGlobal": true,
diff --git a/build/npm/v2/README.md b/build/npm/v2/README.md
index 621441235..ebae7d87d 100644
--- a/build/npm/v2/README.md
+++ b/build/npm/v2/README.md
@@ -6,7 +6,7 @@
# JFrog CLI
-[Website](http://www.jfrog.com) • [Docs](https://www.jfrog.com/confluence/display/CLI/JFrog+CLI) • [Issues](https://github.com/jfrog/jfrog-cli-go/issues) • [Blog](https://jfrog.com/blog/) • [We're Hiring](https://join.jfrog.com/) • [Artifactory Free Trial](https://jfrog.com/artifactory/free-trial/)
+[Website](http://www.jfrog.com) • [Docs](https://docs.jfrog-applications.jfrog.io/jfrog-applications/jfrog-cli) • [Issues](https://github.com/jfrog/jfrog-cli/issues) • [Blog](https://jfrog.com/blog/) • [We're Hiring](https://join.jfrog.com/) • [Artifactory Free Trial](https://jfrog.com/artifactory/free-trial/)
## Overview
diff --git a/build/npm/v2/init.js b/build/npm/v2/init.js
index 87ba9989b..e37011c6b 100644
--- a/build/npm/v2/init.js
+++ b/build/npm/v2/init.js
@@ -1,66 +1,91 @@
validateNpmVersion();
-var https = require('https');
-var http = require('http');
-var url = require('url');
-var fs = require('fs');
-var packageJson = require('./package.json');
-var fileName = getFileName();
-var filePath = "bin/" + fileName;
-var version = packageJson.version;
-var pkgName = "jfrog-cli-" + getArchitecture();
+const {get} = require("https");
+const {request} = require("http");
+const {URL} = require("url");
+const {createWriteStream, chmodSync} = require("fs");
+const packageJson = require("./package.json");
+const fileName = getFileName();
+const filePath = "bin/" + fileName;
+const version = packageJson.version;
+const pkgName = "jfrog-cli-" + getArchitecture();
downloadCli();
function validateNpmVersion() {
if (!isValidNpmVersion()) {
- throw new Error("JFrog CLI can be installed using npm version 5.0.0 or above.");
+ throw new Error(
+ "JFrog CLI can be installed using npm version 5.0.0 or above."
+ );
}
}
function downloadWithProxy(myUrl) {
- var proxyparts = url.parse(process.env.https_proxy);
- var myUrlParts = url.parse(myUrl);
+ const proxyParts = new URL(process.env.https_proxy);
+ const myUrlParts = new URL(myUrl);
- http.request({
- host: proxyparts.hostname,
- port: proxyparts.port,
- method: 'CONNECT',
- path: myUrlParts.hostname + ':443'
- }).on('connect', function(res, socket, head) {
- https.get({
- host: myUrlParts.hostname,
- socket: socket,
- path: myUrlParts.path,
- agent: false
- }, function(res) {
- if (res.statusCode == 301 || res.statusCode == 302) {
- downloadWithProxy(res.headers.location);
- } else if (res.statusCode == 200) {
- writeToFile(res);
- } else {
- console.log('Unexpected status code ' + res.statusCode + ' during JFrog CLI download');
- }
- }).on('error', function (err) {console.error(err);});
- }).end();
+ request({
+ host: proxyParts.hostname,
+ port: proxyParts.port,
+ method: "CONNECT",
+ path: myUrlParts.hostname + ":443",
+ })
+ .on("connect", function (res, socket, _) {
+ get(
+ {
+ host: myUrlParts.hostname,
+ socket: socket,
+ path: myUrlParts.path,
+ agent: false,
+ },
+ function (res) {
+ if (res.statusCode === 301 || res.statusCode === 302) {
+ downloadWithProxy(res.headers.location);
+ } else if (res.statusCode === 200) {
+ writeToFile(res);
+ } else {
+ console.log(
+ "Unexpected status code " +
+ res.statusCode +
+ " during JFrog CLI download"
+ );
+ }
+ }
+ ).on("error", function (err) {
+ console.error(err);
+ });
+ })
+ .end();
}
function download(url) {
- https.get(url, function(res) {
- if (res.statusCode == 301 || res.statusCode == 302) {
+ get(url, function (res) {
+ if (res.statusCode === 301 || res.statusCode === 302) {
download(res.headers.location);
- } else if (res.statusCode == 200) {
+ } else if (res.statusCode === 200) {
writeToFile(res);
} else {
- console.log('Unexpected status code ' + res.statusCode + ' during JFrog CLI download');
+ console.log(
+ "Unexpected status code " +
+ res.statusCode +
+ " during JFrog CLI download"
+ );
}
- }).on('error', function (err) {console.error(err);});
+ }).on("error", function (err) {
+ console.error(err);
+ });
}
function downloadCli() {
- console.log("Downloading JFrog CLI " + version );
- var startUrl = 'https://releases.jfrog.io/artifactory/jfrog-cli/v2/' + version + '/' + pkgName + '/' + fileName;
- // We detect outbount proxy by looking at the environment variable
+ console.log("Downloading JFrog CLI " + version);
+ const startUrl =
+ "https://releases.jfrog.io/artifactory/jfrog-cli/v2/" +
+ version +
+ "/" +
+ pkgName +
+ "/" +
+ fileName;
+ // We detect outbound proxy by looking at the environment variable
if (process.env.https_proxy && process.env.https_proxy.length > 0) {
downloadWithProxy(startUrl);
} else {
@@ -69,58 +94,61 @@ function downloadCli() {
}
function isValidNpmVersion() {
- var child_process = require('child_process');
- var npmVersionCmdOut = child_process.execSync("npm version -json");
- var npmVersion = JSON.parse(npmVersionCmdOut).npm;
- // Supported since version 5.0.0
- return parseInt(npmVersion.charAt(0)) > 4;
+ const child_process = require("child_process");
+ const npmVersionCmdOut = child_process.execSync("npm version -json");
+ const npmVersion = JSON.parse(npmVersionCmdOut).npm;
+ // Supported since version 5.0.0 (also support npm v10+)
+ return parseInt(npmVersion.split('.')[0]) > 4;
}
function writeToFile(response) {
- var file = fs.createWriteStream(filePath);
- response.on('data', function (chunk) {
- file.write(chunk);
- }).on('end', function () {
- file.end();
- if (!process.platform.startsWith("win")) {
- fs.chmodSync(filePath, 0555);
- }
- }).on('error', function (err) {
- console.error(err);
- });
+ const file = createWriteStream(filePath);
+ response
+ .on("data", function (chunk) {
+ file.write(chunk);
+ })
+ .on("end", function () {
+ file.end();
+ if (!process.platform.startsWith("win")) {
+ chmodSync(filePath, '755');
+ }
+ })
+ .on("error", function (err) {
+ console.error(err);
+ });
}
function getArchitecture() {
const platform = process.platform;
- if (platform.startsWith('win')) {
+ if (platform.startsWith("win")) {
// Windows architecture:
- return 'windows-amd64';
+ return "windows-amd64";
}
const arch = process.arch;
- if (platform.includes('darwin')) {
+ if (platform.includes("darwin")) {
// macOS architecture:
- return arch === 'arm64' ? 'mac-arm64' : 'mac-386';
+ return arch === "arm64" ? "mac-arm64" : "mac-386";
}
// linux architecture:
switch (arch) {
- case 'x64':
- return 'linux-amd64';
- case 'arm64':
- return 'linux-arm64';
- case 'arm':
- return 'linux-arm';
- case 's390x':
- return 'linux-s390x';
- case 'ppc64':
- return 'linux-ppc64';
+ case "x64":
+ return "linux-amd64";
+ case "arm64":
+ return "linux-arm64";
+ case "arm":
+ return "linux-arm";
+ case "s390x":
+ return "linux-s390x";
+ case "ppc64":
+ return "linux-ppc64";
default:
- return 'linux-386';
+ return "linux-386";
}
}
function getFileName() {
- var executable = "jfrog";
+ let executable = "jfrog";
if (process.platform.startsWith("win")) {
executable += ".exe";
}
diff --git a/build/npm/v2/package-lock.json b/build/npm/v2/package-lock.json
index 894036f90..83fc68b50 100644
--- a/build/npm/v2/package-lock.json
+++ b/build/npm/v2/package-lock.json
@@ -1,5 +1,5 @@
{
"name": "jfrog-cli-v2",
- "version": "2.46.2",
- "lockfileVersion": 1
+ "version": "2.50.4",
+ "lockfileVersion": 2
}
diff --git a/build/npm/v2/package.json b/build/npm/v2/package.json
index 84ad3f5d9..8d8d82559 100644
--- a/build/npm/v2/package.json
+++ b/build/npm/v2/package.json
@@ -1,6 +1,6 @@
{
"name": "jfrog-cli-v2",
- "version": "2.46.2",
+ "version": "2.50.4",
"description": "🐸 Command-line interface for JFrog Artifactory, Xray, Distribution, Pipelines and Mission Control 🐸",
"homepage": "https://github.com/jfrog/jfrog-cli",
"preferGlobal": true,
diff --git a/build/setupcli/jf.sh b/build/setupcli/jf.sh
index d8a7493a4..ecf68f0cc 100755
--- a/build/setupcli/jf.sh
+++ b/build/setupcli/jf.sh
@@ -1,11 +1,8 @@
#!/bin/bash
CLI_OS="na"
-CLI_UNAME="na"
CLI_MAJOR_VER="v2-jf"
VERSION="[RELEASE]"
-# Order is by destination priority.
-DESTINATION_PATHS="/usr/local/bin /usr/bin /opt/bin"
SETUP_COMMAND="jf setup"
GREEN_COLOR='\033[0;32m'
REMOVE_COLOR='\033[0m'
@@ -20,11 +17,11 @@ then
fi
echo "Downloading the latest version of JFrog CLI..."
-if $(echo "${OSTYPE}" | grep -q msys); then
+if echo "${OSTYPE}" | grep -q msys; then
CLI_OS="windows"
URL="https://releases.jfrog.io/artifactory/jfrog-cli/${CLI_MAJOR_VER}/${VERSION}/jfrog-cli-windows-amd64/jf.exe"
FILE_NAME="jf.exe"
-elif $(echo "${OSTYPE}" | grep -q darwin); then
+elif echo "${OSTYPE}" | grep -q darwin; then
CLI_OS="mac"
if [[ $(uname -m) == 'arm64' ]]; then
URL="https://releases.jfrog.io/artifactory/jfrog-cli/${CLI_MAJOR_VER}/${VERSION}/jfrog-cli-mac-arm64/jf"
@@ -59,7 +56,7 @@ else
;;
*)
echo "Unknown machine type: $MACHINE_TYPE"
- exit -1
+ exit 1
;;
esac
URL="https://releases.jfrog.io/artifactory/jfrog-cli/${CLI_MAJOR_VER}/${VERSION}/jfrog-cli-${CLI_OS}-${ARCH}/jf"
@@ -70,28 +67,25 @@ curl -XGET "$URL" -L -k -g > $FILE_NAME
chmod u+x $FILE_NAME
# Move executable to a destination in path.
-set -- $DESTINATION_PATHS
+# Order is by destination priority.
+set -- "/usr/local/bin" "/usr/bin" "/opt/bin"
while [ -n "$1" ]; do
# Check if destination is in path.
- if echo $PATH|grep "$1" -> /dev/null ; then
- mv $FILE_NAME $1
- if [ "$?" -eq "0" ]
- then
+ if echo "$PATH"|grep "$1" -> /dev/null ; then
+ if mv $FILE_NAME "$1" ; then
echo ""
echo "The $FILE_NAME executable was installed in $1"
print_installation_greeting
- $SETUP_COMMAND $BASE64_CRED
+ $SETUP_COMMAND "$BASE64_CRED"
exit 0
else
echo ""
echo "We'd like to install the JFrog CLI executable in $1. Please approve this installation by entering your password."
- sudo mv $FILE_NAME $1
- if [ "$?" -eq "0" ]
- then
+ if sudo mv $FILE_NAME "$1" ; then
echo ""
echo "The $FILE_NAME executable was installed in $1"
print_installation_greeting
- $SETUP_COMMAND $BASE64_CRED
+ $SETUP_COMMAND "$BASE64_CRED"
exit 0
fi
fi
diff --git a/docs/artifactory/accesstokencreate/help.go b/docs/artifactory/accesstokencreate/help.go
index 22f57c693..f51c8e6f0 100644
--- a/docs/artifactory/accesstokencreate/help.go
+++ b/docs/artifactory/accesstokencreate/help.go
@@ -1,12 +1,12 @@
package accesstokencreate
-var Usage = []string{"rt atc", "rt atc "}
+var Usage = []string{"rt atc", "rt atc "}
func GetDescription() string {
- return "Creates an access token. By default an user-scoped token will be created, unless the --groups and/or --grant-admin options are specified."
+ return "Creates an Artifactory access token. By default an user-scoped token will be created, unless the --groups and/or --grant-admin options are specified."
}
func GetArguments() string {
- return ` user name
- The user name for which this token is created. If not specified, the token will be created for the current user.`
+ return ` username
+ The username for which this token is created. If not specified, the token will be created for the current user.`
}
diff --git a/docs/general/token/help.go b/docs/general/token/help.go
new file mode 100644
index 000000000..601a1665d
--- /dev/null
+++ b/docs/general/token/help.go
@@ -0,0 +1,14 @@
+package token
+
+var Usage = []string{"atc", "atc "}
+
+func GetDescription() string {
+ return `Creates an access token.
+ By default, an user-scoped token will be created.
+ Administrator may provide the scope explicitly with '--scope', or implicitly with '--groups', '--grant-admin'.`
+}
+
+func GetArguments() string {
+ return ` username
+ The username for which this token is created. If not specified, the token will be created for the current user.`
+}
diff --git a/documentation/CLI-for-JFrog-Artifactory.md b/documentation/CLI-for-JFrog-Artifactory.md
index 375d47eaf..41b473330 100644
--- a/documentation/CLI-for-JFrog-Artifactory.md
+++ b/documentation/CLI-for-JFrog-Artifactory.md
@@ -227,6 +227,7 @@ This command is used to upload files to Artifactory.
| --symlinks | \[Default: false\]
If true, the command will preserve the soft links structure in Artifactory. The `symlink` file representation will contain the symbolic link and checksum properties. |
| --explode | \[Default: false\]
If true, the command will extract an archive containing multiple artifacts after it is deployed to Artifactory, while maintaining the archive's file structure. |
| --include-dirs | \[Default: false\]
If true, the source path applies to bottom-chain directories and not only to files. Bottom-chain directories are either empty or do not include other directories that match the source path. |
+| --bypass-archive-inspection | \[Default: false\]
Set to true to bypass the archive security inspection before it is unarchived. Used with the 'explode' option.|
| --exclusions | \[Optional\]
A list of Semicolon-separated exclude patterns. Allows using wildcards, regular expressions or ANT patterns, according to the value of the **--regexp** and **--ant** options. Please read the **--regexp** and **--ant** options description for more information. |
| --sync-deletes | \[Optional\]
Specific path in Artifactory, under which to sync artifacts after the upload. After the upload, this path will include only the artifacts uploaded during this upload operation. The other files under this path will be deleted. |
| --quiet | \[Default: false\]
If true, the delete confirmation message is skipped. |
diff --git a/documentation/CLI-for-JFrog-Lifecycle.md b/documentation/CLI-for-JFrog-Lifecycle.md
index 6a998e4c3..eaccb5bd6 100644
--- a/documentation/CLI-for-JFrog-Lifecycle.md
+++ b/documentation/CLI-for-JFrog-Lifecycle.md
@@ -17,7 +17,7 @@ The following sections describe the commands available in JFrog CLI when perform
### Creating a Release Bundle v2 from builds or from existing Release Bundles
-This command creates a Release Bundle v2 from a published build-info or from an existing Release Bundle.
+This command creates a Release Bundle v2 from published build-infos or from existing Release Bundles.
1. To create a Release Bundle from published build-infos, provide the `--builds` option, which accepts a path to a file using the following JSON format:
```json
{
@@ -48,20 +48,20 @@ This command creates a Release Bundle v2 from a published build-info or from an
```
`project` is optional (if left empty, the default project will be used)
-| | |
-|------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| Command-name | release-bundle-create |
-| Abbreviation | rbc |
-| Command options | |
-| --builds | \[Optional\]
Path to a JSON file containing information about the source builds from which to create a Release Bundle. |
-| --project | \[Optional\]
JFrog Project key associated with the Release Bundle version. |
-| --release-bundles | \[Optional\]
Path to a JSON file containing information about the source Release Bundles from which to create a Release Bundle. |
-| --server-id | \[Optional\]
Platform server ID configured using the `jf c add` command. |
-| --signing-key | \[Mandatory\]
The GPG/RSA key-pair name given in Artifactory. |
-| --sync | \[Default: false\]
Set to true to run synchronously. |
-| Command arguments | |
-| release bundle name | Name of the newly created Release Bundle. |
-| release bundle version | Version of the newly created Release Bundle. |
+| | |
+|------------------------|----------------------------------------------------------------------------------------------------------------------------------------|
+| Command-name | release-bundle-create |
+| Abbreviation | rbc |
+| Command options | |
+| --builds | \[Optional\]
Path to a JSON file containing information about the source builds from which to create a Release Bundle. |
+| --project | \[Optional\]
JFrog Project key associated with the Release Bundle version. |
+| --release-bundles | \[Optional\]
Path to a JSON file containing information about the source Release Bundles from which to create a Release Bundle. |
+| --server-id | \[Optional\]
Platform server ID configured using the `jf c add` command. |
+| --signing-key | \[Mandatory\]
The GPG/RSA key-pair name given in Artifactory. |
+| --sync | \[Default: false\]
Set to true to run synchronously. |
+| Command arguments | |
+| release bundle name | Name of the newly created Release Bundle. |
+| release bundle version | Version of the newly created Release Bundle. |
#### Examples
@@ -77,33 +77,33 @@ jf rbc --builds=/path/to/builds-spec.json --signing-key=myKeyPair myApp 1.0.0
Create a Release Bundle v2 with the name "myApp" and version "1.0.0", with signing key pair "myKeyPair".
The Release Bundle will include the artifacts of the Release Bundles that were provided in the Release Bundles spec.
```
-jf rbc --spec=/path/to/release-bundles-spec.json --signing-key=myKeyPair myApp 1.0.0
+jf rbc --release-bundles=/path/to/release-bundles-spec.json --signing-key=myKeyPair myApp 1.0.0
```
##### Example 3
Create a Release Bundle v2 synchronously with the name "myApp" and version "1.0.0", in project "project0", with signing key pair "myKeyPair".
The Release Bundle will include the artifacts of the Release Bundles that were provided in the Release Bundles spec.
```
-jf rbc --spec=/path/to/release-bundles-spec.json --signing-key=myKeyPair --sync=true --project=project0 myApp 1.0.0
+jf rbc --release-bundles=/path/to/release-bundles-spec.json --signing-key=myKeyPair --sync=true --project=project0 myApp 1.0.0
```
### Promoting a Release Bundle v2
This command promotes a Release Bundle v2 to a target environment.
-| | |
-|------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| Command-name | release-bundle-promote |
-| Abbreviation | rbp |
-| Command options | |
-| --overwrite | \[Default: false\]
Set to true to replace artifacts with the same name but a different checksum, if such already exist at the promotion targets. By default, the promotion is stopped when a conflict occurs.|
-| --project | \[Optional\]
Project key associated with the Release Bundle version. |
-| --server-id | \[Optional\]
Platform server ID configured using the config command. |
-| --signing-key | \[Mandatory\]
The GPG/RSA key-pair name given in Artifactory. |
-| --sync | \[Default: false\]
Set to true to run synchronously. |
-| Command arguments | |
-| release bundle name | Name of the Release Bundle to promote. |
-| release bundle version | Version of the Release Bundle to promote. |
-| environment | Name of the target environment for the promotion. |
+| | |
+|------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| Command-name | release-bundle-promote |
+| Abbreviation | rbp |
+| Command options | |
+| --overwrite | \[Default: false\]
Set to true to replace artifacts with the same name but a different checksum, if such already exist at the promotion targets. By default, the promotion is stopped when a conflict occurs. |
+| --project | \[Optional\]
Project key associated with the Release Bundle version. |
+| --server-id | \[Optional\]
Platform server ID configured using the config command. |
+| --signing-key | \[Mandatory\]
The GPG/RSA key-pair name given in Artifactory. |
+| --sync | \[Default: false\]
Set to true to run synchronously. |
+| Command arguments | |
+| release bundle name | Name of the Release Bundle to promote. |
+| release bundle version | Version of the Release Bundle to promote. |
+| environment | Name of the target environment for the promotion. |
#### Examples
##### Example 1
@@ -121,3 +121,69 @@ Use signing key pair "myKeyPair" and overwrite in case of conflicts.
```
jf rbp --signing-key=myKeyPair --project=project0 --overwrite=true --sync=true myApp 1.0.0 PROD
```
+
+### Distributing a release bundle
+
+This command distributes a Release Bundle v2 to an edge node.
+
+| | |
+|------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| Command-name | release-bundle-distribute |
+| Abbreviation | rbd |
+| Command options | |
+| --create-repo | \[Default: false\]
Set to true to create the repository on the edge if it does not exist. |
+| --dry-run | \[Default: false\]
Set to true to disable communication with JFrog Distribution. |
+| --dist-rules | \[Optional\]
Path to a file, which includes the Distribution Rules in a JSON format. See [structure](#distribution-rules-structure) bellow. |
+| --site | \[Default: *\]
Wildcard filter for site name. |
+| --city | \[Default: *\]
Wildcard filter for site city name. |
+| --country-codes | \[Default: *\]
Semicolon-separated list of wildcard filters for site country codes. |
+| --insecure-tls | \[Default: false\]
Set to true to skip TLS certificates verification. |
+| --mapping-pattern | \[Optional\]
Specify along with 'mapping-target' to distribute artifacts to a different path on the edge node. You can use wildcards to specify multiple artifacts. |
+| --mapping-target | \[Optional\]