github.com/jfrog/jfrog-cli@v1.54.1/Jenkinsfile (about) 1 node("docker") { 2 cleanWs() 3 // Subtract repo name from the repo url (https://REPO_NAME/ -> REPO_NAME/) 4 withCredentials([string(credentialsId: 'repo21-url', variable: 'REPO21_URL')]) { 5 echo "${REPO21_URL}" 6 def repo21Name = "${REPO21_URL}".substring(8, "${REPO21_URL}".length()) 7 env.REPO_NAME_21="$repo21Name" 8 } 9 def architectures = [ 10 [pkg: 'jfrog-cli-windows-amd64', goos: 'windows', goarch: 'amd64', fileExtension: '.exe'], 11 [pkg: 'jfrog-cli-linux-386', goos: 'linux', goarch: '386', fileExtension: '', debianImage: 'i386/ubuntu:16.04', debianArch: 'i386'], 12 [pkg: 'jfrog-cli-linux-amd64', goos: 'linux', goarch: 'amd64', fileExtension: '', debianImage: 'ubuntu:16.04', debianArch: 'x86_64', rpmImage: 'tgagor/centos:stream8'], 13 [pkg: 'jfrog-cli-linux-arm64', goos: 'linux', goarch: 'arm64', fileExtension: ''], 14 [pkg: 'jfrog-cli-linux-arm', goos: 'linux', goarch: 'arm', fileExtension: ''], 15 [pkg: 'jfrog-cli-mac-386', goos: 'darwin', goarch: 'amd64', fileExtension: ''], 16 [pkg: 'jfrog-cli-mac-arm64', goos: 'darwin', goarch: 'arm64', fileExtension: ''], 17 [pkg: 'jfrog-cli-linux-s390x', goos: 'linux', goarch: 's390x', fileExtension: ''], 18 [pkg: 'jfrog-cli-linux-ppc64', goos: 'linux', goarch: 'ppc64', fileExtension: ''], 19 [pkg: 'jfrog-cli-linux-ppc64le', goos: 'linux', goarch: 'ppc64le', fileExtension: ''] 20 ] 21 22 subject = 'jfrog' 23 identifier = 'v1' 24 repo = 'jfrog-cli' 25 cliExecutableName = 'jfrog' 26 sh 'rm -rf temp' 27 sh 'mkdir temp' 28 def goRoot = tool 'go-1.19.2' 29 env.GOROOT="$goRoot" 30 env.PATH+=":${goRoot}/bin" 31 env.GO111MODULE="on" 32 env.JFROG_CLI_OFFER_CONFIG="false" 33 34 dir('temp') { 35 cliWorkspace = pwd() 36 sh "echo cliWorkspace=$cliWorkspace" 37 stage('Clone JFrog CLI sources') { 38 sh 'git clone https://github.com/jfrog/jfrog-cli.git' 39 dir("$repo") { 40 if (BRANCH?.trim()) { 41 sh "git checkout $BRANCH" 42 } 43 } 44 } 45 46 stage('Build JFrog CLI') { 47 jfrogCliRepoDir = "${cliWorkspace}/${repo}/" 48 dir("$jfrogCliRepoDir") { 49 sh 'build/build.sh' 50 } 51 52 builderPath = "builder/${cliExecutableName}" 53 54 sh 'mkdir builder' 55 sh "mv $jfrogCliRepoDir/jfrog builder/" 56 57 // Extract CLI version 58 version = sh(script: "builder/jfrog -v | tr -d 'jfrog version' | tr -d '\n'", returnStdout: true) 59 print "CLI version: $version" 60 } 61 62 stage('Install CLI v2') { 63 // Install JFrog CLI v2, so that it can be used to create the release bundle. 64 sh 'curl -fL https://install-cli.jfrog.io | sh' 65 } 66 67 configRepo21() 68 69 try { 70 if ("$EXECUTION_MODE".toString().equals("Publish packages")) { 71 stage('Docker login') { 72 dockerLogin() 73 } 74 75 stage('Build and publish rpm and debian') { 76 buildRpmAndDeb(version, architectures) 77 } 78 79 stage('Npm publish') { 80 publishNpmPackage(jfrogCliRepoDir) 81 } 82 83 stage('Build and publish docker images') { 84 buildPublishDockerImages(version, jfrogCliRepoDir) 85 } 86 } else if ("$EXECUTION_MODE".toString().equals("Build CLI")) { 87 downloadToolsCert() 88 print "Uploading version $version to Repo21" 89 uploadCli(architectures) 90 stage("Distribute executables") { 91 distributeToReleases("jfrog-cli", version, "cli-rbc-spec.json") 92 } 93 } 94 } finally { 95 cleanupRepo21() 96 } 97 } 98 } 99 100 def downloadToolsCert() { 101 stage('Download tools cert') { 102 // Download the certificate file and key file, used for signing the JFrog CLI binary. 103 withCredentials([ 104 string(credentialsId: 'download-signing-cert-access-token', variable: 'DOWNLOAD_SIGNING_CERT_ACCESS_TOKEN'), 105 string(credentialsId: 'repo21-url', variable: 'REPO21_URL') 106 ]) { 107 sh """#!/bin/bash 108 $builderPath rt dl installation-files/certificates/jfrog/jfrogltd_signingcer_full.tar.gz --url $REPO21_URL/artifactory --flat --access-token=$DOWNLOAD_SIGNING_CERT_ACCESS_TOKEN 109 """ 110 } 111 sh 'tar -xvzf jfrogltd_signingcer_full.tar.gz' 112 } 113 } 114 115 // Config Repo21 as default server. 116 def configRepo21() { 117 withCredentials([ 118 usernamePassword(credentialsId: 'repo21', usernameVariable: 'REPO21_USER', passwordVariable: 'REPO21_PASSWORD'), 119 string(credentialsId: 'repo21-url', variable: 'REPO21_URL') 120 ]) { 121 sh """#!/bin/bash 122 $builderPath c add repo21 --url=$REPO21_URL --user=$REPO21_USER --password=$REPO21_PASSWORD --interactive=false 123 $builderPath c use repo21 124 """ 125 } 126 } 127 128 def cleanupRepo21() { 129 sh """#!/bin/bash 130 $builderPath c rm repo21 --quiet 131 """ 132 } 133 134 def buildRpmAndDeb(version, architectures) { 135 boolean built = false 136 withCredentials([file(credentialsId: 'rpm-gpg-key2', variable: 'rpmGpgKeyFile'), string(credentialsId: 'rpm-sign-passphrase', variable: 'rpmSignPassphrase')]) { 137 def dirPath = "${pwd()}/jfrog-cli/build/deb_rpm/pkg" 138 def gpgPassphraseFilePath = "$dirPath/RPM-GPG-PASSPHRASE-jfrog-cli" 139 writeFile(file: gpgPassphraseFilePath, text: "$rpmSignPassphrase") 140 141 for (int i = 0; i < architectures.size(); i++) { 142 def currentBuild = architectures[i] 143 if (currentBuild.debianImage) { 144 stage("Build debian ${currentBuild.pkg}") { 145 build(currentBuild.goos, currentBuild.goarch, currentBuild.pkg, 'jfrog') 146 dir("$jfrogCliRepoDir") { 147 sh "build/deb_rpm/build-scripts/pack.sh -b jfrog -v $version -f deb --deb-arch $currentBuild.debianArch --deb-build-image $currentBuild.debianImage -t --deb-test-image $currentBuild.debianImage" 148 built = true 149 } 150 } 151 } 152 if (currentBuild.rpmImage) { 153 stage("Build rpm ${currentBuild.pkg}") { 154 build(currentBuild.goos, currentBuild.goarch, currentBuild.pkg, 'jfrog') 155 dir("$jfrogCliRepoDir") { 156 sh """#!/bin/bash 157 build/deb_rpm/build-scripts/pack.sh -b jfrog -v $version -f rpm --rpm-build-image $currentBuild.rpmImage -t --rpm-test-image $currentBuild.rpmImage --rpm-gpg-key-file /$rpmGpgKeyFile --rpm-gpg-passphrase-file $gpgPassphraseFilePath 158 """ 159 built = true 160 } 161 } 162 } 163 } 164 165 if (built) { 166 stage("Deploy deb and rpm") { 167 def packageName = "jfrog-cli" 168 sh """#!/bin/bash 169 $builderPath rt u $jfrogCliRepoDir/build/deb_rpm/*.i386.deb ecosys-jfrog-debs/pool/$packageName/ --deb=xenial,bionic,eoan,focal/contrib/i386 --flat 170 $builderPath rt u $jfrogCliRepoDir/build/deb_rpm/*.x86_64.deb ecosys-jfrog-debs/pool/$packageName/ --deb=xenial,bionic,eoan,focal/contrib/amd64 --flat 171 $builderPath rt u $jfrogCliRepoDir/build/deb_rpm/*.rpm ecosys-jfrog-rpms/$packageName/ --flat 172 """ 173 } 174 175 stage("Distribute deb-rpm to releases") { 176 distributeToReleases("deb-rpm", version, "deb-rpm-rbc-spec.json") 177 } 178 } 179 } 180 } 181 182 def uploadCli(architectures) { 183 for (int i = 0; i < architectures.size(); i++) { 184 def currentBuild = architectures[i] 185 stage("Build and upload ${currentBuild.pkg}") { 186 buildAndUpload(currentBuild.goos, currentBuild.goarch, currentBuild.pkg, currentBuild.fileExtension) 187 } 188 } 189 } 190 191 def buildPublishDockerImages(version, jfrogCliRepoDir) { 192 def repo21Prefix = "${REPO_NAME_21}/ecosys-docker-local" 193 def images = [ 194 // Pushing the second slim name for backward compatibility. 195 [dockerFile:'build/docker/slim/Dockerfile', names:["jfrog/jfrog-cli", "jfrog/jfrog-cli-go"]], 196 [dockerFile:'build/docker/full/Dockerfile', names:["jfrog/jfrog-cli-full"]] 197 ] 198 for (int i = 0; i < images.size(); i++) { 199 def currentImage = images[i] 200 def primaryName = currentImage.names[0] 201 202 def imageRepo21Name = "$repo21Prefix/$primaryName" 203 buildDockerImage(imageRepo21Name, version, currentImage.dockerFile, jfrogCliRepoDir) 204 pushDockerImageVersion(imageRepo21Name, version) 205 206 // Push alternative tags if needed. 207 for (int n = 1; n < currentImage.names.size(); n++) { 208 def newName = currentImage.names[n] 209 def currentRepo21Name = "$repo21Prefix/$newName" 210 tagDockerImage(imageRepo21Name, version, currentRepo21Name, version, jfrogCliRepoDir) 211 pushDockerImageVersion(currentRepo21Name, version) 212 } 213 } 214 215 stage("Distribute cli-docker-images to releases") { 216 distributeToReleases("cli-docker-images", version, "docker-images-rbc-spec.json") 217 } 218 219 stage("Promote docker images") { 220 for (int i = 0; i < images.size(); i++) { 221 def currentImage = images[i] 222 promoteDockerImage(currentImage.names[0], version, jfrogCliRepoDir) 223 224 // Promote alternative tags if needed. 225 for (int n = 1; n < currentImage.names.size(); n++) { 226 promoteDockerImage(currentImage.names[n], version, jfrogCliRepoDir) 227 } 228 } 229 } 230 } 231 232 def promoteDockerImage(name, version, jfrogCliRepoDir) { 233 print "Promoting docker image: $name" 234 withCredentials([string(credentialsId: 'jfrog-cli-automation', variable: 'JFROG_CLI_AUTOMATION_ACCESS_TOKEN')]) { 235 options = "--url https://releases.jfrog.io/artifactory --access-token=$JFROG_CLI_AUTOMATION_ACCESS_TOKEN" 236 sh """#!/bin/bash 237 $builderPath rt docker-promote $name reg2 reg2 --copy --source-tag=$version --target-tag=latest $options 238 """ 239 } 240 } 241 242 def buildDockerImage(name, version, dockerFile, jfrogCliRepoDir) { 243 dir("$jfrogCliRepoDir") { 244 sh """#!/bin/bash 245 docker build --tag=$name:$version --build-arg repo_name_21=${REPO_NAME_21} -f $dockerFile . 246 """ 247 } 248 } 249 250 def tagDockerImage(name, version, newName, newVersion, jfrogCliRepoDir) { 251 dir("$jfrogCliRepoDir") { 252 sh """#!/bin/bash 253 docker tag $name:$version $newName:$newVersion 254 """ 255 } 256 } 257 258 def pushDockerImageVersion(name, version) { 259 sh """#!/bin/bash 260 $builderPath rt docker-push $name:$version ecosys-docker-local 261 """ 262 } 263 264 def uploadBinaryToJfrogRepo21(pkg, fileName) { 265 sh """#!/bin/bash 266 $builderPath rt u $jfrogCliRepoDir/$fileName ecosys-jfrog-cli/$identifier/$version/$pkg/ --flat 267 """ 268 } 269 270 def build(goos, goarch, pkg, fileName) { 271 dir("${jfrogCliRepoDir}") { 272 env.GOOS="$goos" 273 env.GOARCH="$goarch" 274 sh "build/build.sh $fileName" 275 sh "chmod +x $fileName" 276 // Remove goos and goarch env var to prevent interfering with following builds. 277 env.GOOS="" 278 env.GOARCH="" 279 280 if (goos == 'windows') { 281 dir("${cliWorkspace}/certs-dir") { 282 // Move the jfrog executable into the 'sign' directory, so that it is signed there. 283 sh "mv $jfrogCliRepoDir/$fileName ${jfrogCliRepoDir}build/sign/${fileName}.unsigned" 284 // Copy all the certificate files into the 'sign' directory. 285 sh "cp -r ./ ${jfrogCliRepoDir}build/sign/" 286 // Pull the docker container, which signs the JFrog CLI binary. 287 // In order to build it locally, run the following command: 288 // "docker build -t jfrog-cli-sign-tool ${jfrogCliRepoDir}build/sign/" 289 sh """#!/bin/bash 290 $cliWorkspace/$builderPath rt docker-pull ${REPO_NAME_21}/ecosys-docker-local/jfrog-cli-sign-tool ecosys-docker-local 291 """ 292 // Run the pulled image in order to signs the JFrog CLI binary. 293 def signCmd = "osslsigncode sign -certs workspace/JFrog_Ltd_.crt -key workspace/jfrogltd.key -n JFrog_CLI -i https://www.jfrog.com/confluence/display/CLI/JFrog+CLI -in workspace/${fileName}.unsigned -out workspace/$fileName" 294 sh "docker run -v ${jfrogCliRepoDir}build/sign/:/workspace --rm ${REPO_NAME_21}/ecosys-docker-local/jfrog-cli-sign-tool $signCmd" 295 // Move the JFrog CLI binary from the 'sign' directory, back to its original location. 296 sh "mv ${jfrogCliRepoDir}build/sign/$fileName $jfrogCliRepoDir" 297 } 298 } 299 } 300 } 301 302 def buildAndUpload(goos, goarch, pkg, fileExtension) { 303 def fileName = "jfrog$fileExtension" 304 305 build(goos, goarch, pkg, fileName) 306 uploadBinaryToJfrogRepo21(pkg, fileName) 307 sh "rm $jfrogCliRepoDir/$fileName" 308 } 309 310 def distributeToReleases(stage, version, rbcSpecName) { 311 sh "jf ds rbc $stage-rb-$identifier $version --spec=${jfrogCliRepoDir}build/release_specs/$rbcSpecName --spec-vars=\"VERSION=$version;IDENTIFIER=$identifier\" --sign" 312 sh "$builderPath rt rbd $stage-rb-$identifier $version --site=releases.jfrog.io --sync" 313 } 314 315 def publishNpmPackage(jfrogCliRepoDir) { 316 dir(jfrogCliRepoDir+'build/npm/') { 317 withCredentials([string(credentialsId: 'npm-authorization', variable: 'NPM_AUTH_TOKEN')]) { 318 sh '''#!/bin/bash 319 apt update 320 apt install wget -y 321 echo "Downloading npm..." 322 wget https://nodejs.org/dist/v8.11.1/node-v8.11.1-linux-x64.tar.xz 323 tar -xvf node-v8.11.1-linux-x64.tar.xz 324 export PATH=$PATH:$PWD/node-v8.11.1-linux-x64/bin/ 325 echo "//registry.npmjs.org/:_authToken=$NPM_AUTH_TOKEN" > .npmrc 326 echo "registry=https://registry.npmjs.org" >> .npmrc 327 ./node-v8.11.1-linux-x64/bin/npm publish 328 ''' 329 } 330 } 331 } 332 333 def dockerLogin() { 334 withCredentials([ 335 usernamePassword(credentialsId: 'repo21', usernameVariable: 'REPO21_USER', passwordVariable: 'REPO21_PASSWORD'), 336 string(credentialsId: 'repo21-url', variable: 'REPO21_URL') 337 ]) { 338 sh "echo $REPO21_PASSWORD | docker login $REPO_NAME_21 -u=$REPO21_USER --password-stdin" 339 } 340 }