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  }