主頁 > 軟體工程 > windows下jenkins通過pipeline來部署和回滾maven、npm、小程式專案

windows下jenkins通過pipeline來部署和回滾maven、npm、小程式專案

2022-07-13 17:32:27 軟體工程

目的

  • 實作后臺java的maven部署
  • 實作前端npm的部署

準備

  • 兩臺服務器,我這邊都是windows的:

    • 服務器A,用于安裝jenkins等服務
    • 服務器B,待部署機器
  • Jenkins,除了默認插件外,額外需要手動安裝插件:

    • Blue Ocean,更方便的展示進度等
    • Publish Over SSH,用于通過ssh來部署遠程服務器
    • DingTalk,釘釘機器人通知插件
  • OpenSSH

  • Git

  • 其他的javamavennpm等工具

安裝軟體

  • 服務器A中安裝jenkins,由于我這邊還是舊的windows server 2012,對docker支持不好,所以直接安裝的msi檔案,具體安裝步驟參考官方檔案,安裝完成后再安裝上述的幾個插件,
  • 服務器A安裝Git,方便從github等代碼工具中遠程拉取代碼,具體安裝步驟可以自行網上搜索,由于我們后期會用到sshtar等工具,所以需要將安裝目錄\Git\usr\bin此路徑加入到windows環境變數中,這樣就可以用里面的各種工具了,如果是npm專案,需要在服務器B中也要安裝,主要是為了用tar打包命令,如果用其他打包方式也可以不安裝,
  • 服務器A安裝javamavennpm,最好與開發服務上版本保持一致,并將其加入到windows環境變數中,這樣的話jenkins就可以直接使用,
  • 服務器B安裝openssh,安裝流程查看官方檔案:Install Win32 OpenSSH,同樣需要將此路徑加入環境變數,且需要按照檔案開啟埠、開機自啟動等

ssh密鑰聯通

  • 整體的流程就是服務器B相當于服務端,服務器A相當于客戶端,我們需要用客戶端通過ssh鏈接到服務端,然后傳輸部署的檔案過去,所以需要在客戶端中生成私鑰和公鑰,公鑰會給到服務端中,私鑰則還是留在客戶端,這樣ssh鏈接時通過私鑰和公鑰驗證通過鏈接到一起就可以傳輸檔案了,

  • 服務器A生成密鑰,需要注意的是jenkinsPublish Over SSH不支持最新的密鑰格式,只支持舊的pem格式的,所以需要加一些引數才行,在剛安裝的git命令工具中輸入ssh-keygen -m PEM -t rsa -b 4096,按照提示一步步執行,生成的會放在~/.ssh檔案下:

    xxx_rsa     #私鑰
    xxx_rsa.pub #公鑰
    
  • 服務器B可以先啟動一下openssh服務然后關閉,此時會自動生成C:\Program Data\ssh目錄,然后我們配置此目錄下的sshd_config檔案,改動如下:

    PubkeyAcceptedKeyTypes=+ssh-rsa #由于上方說了用的舊的格式密鑰,新版本默認已不支持了,所以這里需要額外配置增加支持
    PubkeyAuthentication yes #原先是注釋來著,打開并設定為yes,表示開啟密鑰驗證
    PasswordAuthentication no #原先注釋來著,打開并設定為no, 關閉密碼驗證,否則不安全
    
  • 服務器A生產的公鑰放到服務B中,這里需要注意,服務器B的用戶是管理員用戶,則需要放到C:\ProgramData\ssh\administrators_authorized_keys檔案中,如果是普通用戶,則需要放到C:\Users\用戶名\.ssh\authorized_keys檔案中,通過這里我們也可以發現密鑰實際上是和用戶名沒有關系的,放到哪個用戶名下,是根據位置來的,如果這個用戶有權限訪問到這個密鑰實際上就是可以用這個用戶名來登陸的,

  • 測驗聯通性,可以在服務器A~/.ssh/config中配置:

    Host b_name #服務器B隨便起個名字
      HostName 192.168.0.31 #服務器B的IP地址
      IdentityFile ~/.ssh/xxx_rsa #自身生成的私鑰
      User administrator #服務器B的登陸用戶名
      Port 22 #沒改埠的話默認22
      ServerAliveInterval 60
    

    然后可以ssh b_name來測驗是否可以聯通

  • jenkinsPublish Over SSH插件配置中并測驗聯通性,位置Manage Jenkins->Configure System->SSH Servers中:

    點擊測驗,看是否聯通成功,如果出現類似Fail Auth等錯誤,可以參考此解決方法來解決:Jenkins Publish over ssh authentification failed with private key

git 密鑰聯通

  • 同上在服務器A中同上創建私鑰和公鑰,但是github只支持最新版本的,可以不用加那些引數了,具體參考官方檔案:新增 SSH 密鑰到 GitHub 帳戶 - GitHub Docs
  • 以github為例,在個人主頁的Setting->SSH AND GPG keys ->SSH keys中新增,將生成的公鑰粘貼到github中的欄位中就可以了
  • 和上方一樣來測驗下聯通是否OK,其他gitee等原理基本一樣

maven專案部署

  • 如果不熟悉jinkinspipeline相關的話,請先按照官方檔案demo操作一遍:Build a Java app with Maven

  • 官方檔案demo中都是用的docker,我這邊沒有,所以不太一樣,而且官方檔案沒有回滾等操作,所以這邊給出參考的Jenkinsfile:

    pipeline {
        agent any //沒有用docker
        parameters {//這個是引數化構建
            choice choices: ['deploy', 'rollback'], description: '', name: 'action'
            string description: 'rollback ID (only number)', name: 'version'
        }
        stages {
            stage('Build') {
                when {//如果是部署
                    expression { params.action == 'deploy' }
                }
                steps {//maven打包
                    bat 'mvn -B -DskipTests clean package'//linux下是用sh,windows下則bat
                }
            }
            stage('Archive') {
                when {//如果是部署
                    expression { params.action == 'deploy' }
                }
                steps {//將打包出來的jar包歸檔,方便回滾時用到
                    archiveArtifacts artifacts: '自身相關路徑/target/*.jar', followSymlinks: false, onlyIfSuccessful: true
                }
            }
            stage('Rollback') {
                when {//如果是回滾
                    expression { params.action == 'rollback' }
                }
                steps {//回滾就不需要打包了,直接將原先版本的歸檔復制到打包出來的路徑
                    bat 'xcopy /s /f /y "%JENKINS_HOME%\\jobs\\%JOB_NAME%\\builds\\%version%\\archive\\自身相關路徑\\target" 自身相關路徑\\target'
                }
            }
            stage('Publish') {
                steps {//publish over ssh插件相關引數,verbose為true,則jenkins_deploy.bat腳本的執行資訊會回傳
                    sshPublisher(publishers: [sshPublisherDesc(configName: '剛才設定的ssh的名稱', sshRetry: [retries: 3, retryDelay: 5000], transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: 'cmd /c E:\\服務器B相關部署路徑\jenkins_deploy.bat $BUILD_NUMBER', execTimeout: 240000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '服務器B相關路徑', remoteDirectorySDF: false, removePrefix: '自身相關路徑/target', sourceFiles: '自身相關路徑/target/*.jar')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: true)])
                }
            }
        }
    }
    
  • 上方代碼一些注解:

    • 上方的引數化構建歸檔publish over ssh語法都是可以由可視化界面生成的,隨便點開一個job后在左側有流水線語法這個選項,點開后頁面在左側 Declarative Directive Generator中選擇parameters:Parameters可以生成引數化構建片段;而左側片段生成器archiveArtifacts archive the artifacts用來生成歸檔片段,sshPublishers: Send build artifacts over SSH則用來生成發布的片段,這些具體的使用,可以參考官方檔案也可以自行搜索更詳細的用法文章,

    • 引數化構建如果在pipeline中寫了后,不需要在界面中再配置,只需要運行一次后會自動從pipeline中獲取,下次再構建就發現有引數需要填寫了,要想回滾則選擇rollback然后輸入回滾的構建數字運行則會回滾:

    • 一些全域變數,可以參考官方檔案:Using a Jenkinsfile,需要注意的是在linux中可以$JENKINS_HOME,但是在windows中就必須%JENKINS_HOME%這樣了,需要注意的是publish over sshjenkins_deploy.bat傳遞引數的 $BUILD_NUMBER則還是用$才行,用%%不起作用,且執行windows腳本時需要用cmd /c開頭,

  • 服務器B端的結構及腳本:

    • 專案結構:

      abc:
      ├─backup
      │    └─test_2022_06_27_203000_3.jar #在服務端也備份一份,格式:名稱+日期+構建號+jar
      └─prod
      │    └─test.jar #生產檔案
      └─jenkins_deploy.bat
      
    • jenkins_deploy.bat腳本:

      @echo off
      ::設定utf8編碼運行
      chcp 65001
      ::移動到當前目錄
      cd /d E:\abc
      ::設定時間變數,需要注意的是utf編碼和ansi編碼所取時間的位數不一樣
      set "Ymd=%date:~3,4%_%date:~8,2%_%date:~11,2%_%time:~0,2%%time:~3,2%%time:~6,2%"
      ::將時間的空格用0補齊;將引數可能攜帶的引號去掉
      set "param=%1"
      ::%Ymd: =0%是將空格轉為0,%param:"=%是將"去掉
      set backup_name=%Ymd: =0%_%param:"=%
      ::將現有的移到backup中
      copy prod\test.jar backup\test_%backup_name%.jar
      echo 'prod中的備份到backup中'
      ::關閉服務
      net stop test
      ::將最新的移動到生產目錄中
      move /y test.jar prod\test.jar
      echo '最新的移動到prod中'
      ::開啟服務
      net start test
      @echo on
      
  • 上方腳本一些注釋:

    • jenkins編碼沒有做設定,所以要用utf8編碼來執行bat腳本,否則在jenkins中的資訊是亂碼,
    • 時間引數在utf8ansi中取值是不一樣的,需要注意.
    • 1%是bat語法中第一個引數,就是上方的$BUILD_NUMBER構建號,但傳遞過來可能后面帶引號,例如2",所以要把"也去掉
    • %Ymd: =0%意思是將其中的空格轉為0,%param:"=%意思是將其中的"去掉
    • 需要先將test.jar改成用服務的方式運行,最好也要有優雅關閉,可以參考:spring boot不同版本的優雅關閉(graceful shutdown)和在windows下winsw服務方式運行的配置

npm專案部署

  • 整體流程和maven一樣,同樣官方也有參考demo,Build a Node.js and React app with npm,這里只給出參考的檔案:

  • Jenkinsfile:

    pipeline {
        agent any
        parameters {
            choice choices: ['deploy', 'rollback'], description: '', name: 'action'
            string description: 'rollback ID (only number)', name: 'version'
        }
        stages {
            stage('Install') {
                when {
                    expression { params.action == 'deploy' }
                }
                steps {//install
                    bat 'npm ci --registry https://registry.npm.taobao.org'
                }
            }
            stage("Build"){
                when {
                    expression { params.action == 'deploy' }
                }
                steps {//build
                    bat 'npm run build'
                }
            }
            stage("Archive"){
                when {
                    expression { params.action == 'deploy' }
                }
                steps {//先打包成壓縮檔案,再歸檔,同時也方便傳輸
                    bat 'tar -zcvf dist.tar.gz -C dist .'
                    archiveArtifacts artifacts: '*.tar.gz', followSymlinks: false, onlyIfSuccessful: true
                }
            }
            stage('rollback') {
                when {
                    expression { params.action == 'rollback' }
                }
                steps {//將壓縮檔案拷貝到正常打包后的位置
                    bat 'copy /y "%JENKINS_HOME%\\jobs\\%JOB_NAME%\\builds\\%version%\\archive\\dist.tar.gz" dist.tar.gz'
                }
            }
            stage("Publish"){
                steps {
                    sshPublisher(publishers: [sshPublisherDesc(configName: '剛才設定的ssh的名稱', sshRetry: [retries: 3, retryDelay: 5000], transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: 'cmd /c E:\\服務器B相關部署路徑\\jenkins_deploy.bat $BUILD_NUMBER', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '服務器B相關部署路徑', remoteDirectorySDF: false, removePrefix: '', sourceFiles: 'dist.tar.gz')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: true)])
                }
            }
        }
    }
    
  • 服務器B的jenkins_deploy.bat腳本,結構和maven專案差不多,

    • 專案結構:

      abc:
      ├─backup
      │    └─test_2022_06_27_203000_3.tar.gz #在服務端也備份一份,格式:名稱+日期+構建號+tar.gz
      └─prod
      │    ├─static
      │    └─index.html
      └─jenkins_deploy.bat
      
    • jenkins_deploy.bat腳本:

      @echo off
      ::設定utf8編碼運行
      chcp 65001
      ::移動到當前目錄
      cd /d E:\abc
      ::設定時間變數,需要注意的是utf編碼和ansi編碼所取時間的位數不一樣
      set "Ymd=%date:~3,4%_%date:~8,2%_%date:~11,2%_%time:~0,2%%time:~3,2%%time:~6,2%"
      ::獲取第一個引數
      set "param=%1"
      ::將時間的空格用0補齊;將引數可能攜帶的引號去掉
      set backup_name=%Ymd: =0%_%param:"=%
      ::將現有的打包后移到backup中
      tar -zcvf test_%backup_name%.tar.gz -C prod .
      move test_%backup_name%.tar.gz backup\test_%backup_name%.tar.gz
      echo 'prod中內容打包到backup中'
      ::清空prod檔案夾,然后將傳遞過來的解壓到prod中
      del /q prod\*
      for /d %%x in (prod\*) do @rd /s /q "%%x"
      tar -zxvf dist.tar.gz -C prod
      echo '最新的解壓到prod中'
      ::洗掉傳遞過來的
      del dist.tar.gz
      echo '洗掉傳遞過來的檔案'
      @echo on
      

構建通知

  • 目前插件可以通過釘釘和企業微信機器人通知,目前只測驗了釘釘的,感徑訓可以,目前我這邊沒有在pipeline中自定義,只是用了通用功能,更多功能可查看官方檔案或自行搜索相關文章,

完工

  • 以上就是整體流程,只是記錄了下一些關鍵點,

另外補充下小程式的部署和用powershell腳本的寫法

  • 小程式

    • 主要是利用官方的miniprogram-ci來完成,此類別庫可以實作預覽和上傳(上傳后還是需要登陸小程式平臺來設定體驗版或者是提交正式版本),這個類別庫是nodejs寫的,所以需要大體了解下nodejs腳本的寫法,可以參考Node.js 入門教程

    • 小程式用miniprogram-ci上傳前需要先到小程式平臺“開發管理”->"開發設定"->"小程式代碼上傳"中生成小程式代碼上傳密鑰,實際上就和ssh的密鑰類似,在撰寫腳本時會用到此密鑰,此密鑰不要放到和代碼一起的版本控制中,否則太不安全了,有兩種方式,一種是直接放到jenkins所在服務器的某個路徑,然后在腳本時直接引;一種是放到jenkins的密鑰管理中,類似github的密鑰一樣,然后在pipeline通過withCredentials可以獲取到,這里采用的是后一種方法,

    • jenkins所在服務器安裝nodejs(最好與開發的版本一致),同時在 jenkins插件管理中安裝nodejs插件并在全域配置中設定nodejs版本(安裝插件后會多出此選項);需要在專案中引入miniprogram-ci 庫:npm install miniprogram-ci --save,專案結構如下所示,腳本放到ci\upload.js

      xxx:
      ├─ci
      │    └─upload.js #腳本路徑
      └─dist
      │    └─...
      └─public
      │    └─...
      └─src
      │    └─...
      └─JenkinsFile
      
    • upload.js

      const ci = require('miniprogram-ci');//小程式類別庫
      const path = require('path');
      const fs = require("fs");
      const argv = require('minimist')(process.argv.slice(2));//此類別庫主要用戶決議引數,實作--version 12,則argv.version就為12,如果系統沒有自帶,則npm安裝下
      const manifest = require('../src/manifest.json');//用的uniapp,直接從這里取appid,需要確保manifest.json不要有注釋,或者自己新建個json檔案也行
      const appDirectory = fs.realpathSync(process.cwd());//當前命令列路徑,主要用于獲取絕對路徑
      let projectPath = path.resolve(appDirectory, './dist/build/mp-weixin');//組裝專案路徑
      let qrCodeImg = path.resolve(appDirectory, './qrcode.jpg');//組裝二維碼路徑
      let type = argv.type;//引數預覽還是上傳
      let privateKeyPath = argv.key;//傳遞upload的私鑰路徑
      let version = argv.version ? argv.version : argv.number;//版本號,如果有傳遞則用,沒傳遞則用構建號
      let desc = argv.desc ? argv.desc : '暫無描述';//描述
      //配置
      const project = new ci.Project({
        appid: manifest["mp-weixin"].appid,
        type: 'miniProgram',
        projectPath: projectPath,
        privateKeyPath: privateKeyPath,
        ignores: ['node_modules/**/*'],
      });
      if (type === 'preview') {
        //預覽
        (async () => {
          await ci.preview({
            project,
            desc: desc,
            setting: {
              es6: true,
            },
            qrcodeFormat: 'image',
            qrcodeOutputDest: qrCodeImg,
            onProgressUpdate: console.log,
          });
        })();
      } else if (type === 'upload') {
        //上傳
        (async () => {
          await ci.upload({
            project,
            version: version,
            desc: desc,
            setting: {
              es6: true,
            },
            onProgressUpdate: console.log,
          });
        })();
      }
      
    • JenkinsFile(cmd版本),小程式自帶回退上一版本的功能,所以這里就沒有做回退選項,如果想做可參考上方的實作,是同一個邏輯

      pipeline {
          agent any
          parameters {
              string description: 'version (example: 1.0.0)', name: 'version'
              string description: 'description', name: 'desc'
          }
          stages {
              stage('Install') {
                  steps {
                      bat 'npm ci --registry https://registry.npm.taobao.org'
                  }
              }
              stage("Build"){
                  steps {
                      bat 'npm run build:mp-weixin'//用的uniapp
                  }
              }
              stage("Preview"){
                  steps {//先掉用預覽來生成二維碼圖片,用于歸檔后在jinkins中查看,這一步也可以不用
                      withCredentials([sshUserPrivateKey(credentialsId: '小程式密鑰在jenkins保存后的id', keyFileVariable: 'identity')]) {
                          bat 'node ci\\upload.js --type=preview --desc="%desc%" --key="%identity%"'
                      }
                  }
              }
              stage("Archive"){
                  steps {//同時將二維碼也歸檔,方便在jenkins中查看,如果是jenkins外網可以訪問,還可以將歸檔后的預覽二維碼發送到釘釘等通知工具中,或者內網也可以用oss自帶的cli工具上傳到oss中供外網訪問,此二維碼有效時間是25分鐘
                      bat 'tar -zcvf dist.tar.gz -C dist\\build\\mp-weixin .'
                      archiveArtifacts artifacts: '*.tar.gz,qrcode.jpg', followSymlinks: false, onlyIfSuccessful: true
                  }
              }
              stage("Publish"){
                  steps {//上傳,這里將version和BUILD_NUMBER都傳遞過去,如果version沒有填寫,則用構建號作為小程式版本號
                      withCredentials([sshUserPrivateKey(credentialsId: '小程式密鑰在jenkins保存后的id', keyFileVariable: 'identity')]) {
                          bat 'node ci\\upload.js --type=upload --version="%version%" --number="%BUILD_NUMBER%" --desc="%desc%" --key="%identity%"'
                      }
                  }
              }
          }
      }
      
    • jenkinsFile(powershell版本)

      pipeline {
          agent any
          parameters {
              string description: 'version (example: 1.0.0)', name: 'version'
              string description: 'description', name: 'desc'
          }
          stages {
              stage('Install') {
                  steps {
                      powershell 'npm ci --registry https://registry.npm.taobao.org'
                  }
              }
              stage("Build"){
                  steps {
                      powershell 'npm run build:mp-weixin'
                  }
              }
              stage("Preview"){
                  steps {
                      withCredentials([sshUserPrivateKey(credentialsId: '小程式密鑰在jenkins保存后的id', keyFileVariable: 'identity')]) {
                          //這個引數中如果有空格會決議引數不完整,所以必須加引號
                          powershell "node ci\\upload.js --type=preview --desc='$desc' --key='$identity'"
                      }
                  }
              }
              stage("Archive"){
                  steps {
                      powershell 'tar -zcvf dist.tar.gz -C dist\\build\\mp-weixin .'
                      archiveArtifacts artifacts: '*.tar.gz,qrcode.jpg', followSymlinks: false, onlyIfSuccessful: true
                  }
              }
              stage("Publish"){
                  steps {
                      withCredentials([sshUserPrivateKey(credentialsId: '小程式密鑰在jenkins保存后的id', keyFileVariable: 'identity')]) {
                          powershell "node ci\\upload.js --type=upload --version='$version' --number='$BUILD_NUMBER' --desc='$desc' --key='$identity'"
                      }
                  }
              }
          }
      }
      
  • maven的powershell寫法

    • jenkinsfiles

      pipeline {
          agent any //沒有用docker
          parameters {//這個是引數化構建
              choice choices: ['deploy', 'rollback'], description: '', name: 'action'
              string description: 'rollback ID (only number)', name: 'version'
          }
          stages {
              stage('Build') {
                  when {//如果是部署
                      expression { params.action == 'deploy' }
                  }
                  steps {//maven打包
                      powershell 'mvn -B -DskipTests clean package'
                  }
              }
              stage('Archive') {
                  when {//如果是部署
                      expression { params.action == 'deploy' }
                  }
                  steps {//將打包出來的jar包歸檔,方便回滾時用到
                      archiveArtifacts artifacts: '自身相關路徑/target/*.jar', followSymlinks: false, onlyIfSuccessful: true
                  }
              }
              stage('Rollback') {
                  when {//如果是回滾
                      expression { params.action == 'rollback' }
                  }
                  steps {//回滾就不需要打包了,直接將原先版本的歸檔復制到打包出來的路徑
                      powershell 'copy-item -path "$JENKINS_HOME\\jobs\\$JOB_NAME\\builds\\$version\\archive\\自身相關路徑\\target\\*" -destination 自身相關路徑\\target\\ -recurse -force'
                  }
              }
              stage('Publish') {
                  steps {//publish over ssh插件相關引數,verbose為true,則jenkins_deploy腳本的執行資訊會回傳
                      sshPublisher(publishers: [sshPublisherDesc(configName: '剛才設定的ssh的名稱', sshRetry: [retries: 3, retryDelay: 5000], transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: 'powershell E:\\服務器B相關部署路徑\jenkins_deploy.sp1 -number $BUILD_NUMBER', execTimeout: 240000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '服務器B相關路徑', remoteDirectorySDF: false, removePrefix: '自身相關路徑/target', sourceFiles: '自身相關路徑/target/*.jar')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: true)])
                  }
              }
          }
      }
      
    • jenkins_deploy.ps1

      #獲取引數
      param (
      	[string]$number
      )
      #移動到當前目錄
      Set-Location E:\abc
      #設定時間變數
      $date=(get-date).ToString('yyyy_MM_dd_HHmmss')
      #備份檔案名
      $backup_name = 'test_'+$date+'_'+$number+'.jar'
      #將現有的移到backup中
      Move-Item -path prod\test.jar -destination backup\$backup_name -force
      Write-Output 'backup end'
      #關閉服務
      net stop test
      #將最新的移動到生產目錄中
      Move-Item -path test.jar -destination prod\test.jar -force
      Write-Output 'move new to prod'
      #開啟服務
      net start test
      Write-Output 'finished'
      
  • npm的powershell寫法

    • jenkinsfiles

      pipeline {
          agent any
          parameters {
              choice choices: ['deploy', 'rollback'], description: '', name: 'action'
              string description: 'rollback ID (only number)', name: 'version'
          }
          stages {
              stage('Install') {
                  when {
                      expression { params.action == 'deploy' }
                  }
                  steps {//install
                      powershell 'npm ci --registry https://registry.npm.taobao.org'
                  }
              }
              stage("Build"){
                  when {
                      expression { params.action == 'deploy' }
                  }
                  steps {//build
                      powershell 'npm run build'
                  }
              }
              stage("Archive"){
                  when {
                      expression { params.action == 'deploy' }
                  }
                  steps {//先打包成壓縮檔案,再歸檔,同時也方便傳輸
                      powershell 'tar -zcvf dist.tar.gz -C dist .'
                      archiveArtifacts artifacts: '*.tar.gz', followSymlinks: false, onlyIfSuccessful: true
                  }
              }
              stage('rollback') {
                  when {
                      expression { params.action == 'rollback' }
                  }
                  steps {//將壓縮檔案拷貝到正常打包后的位置
                      powershell 'copy-item -path  "$JENKINS_HOME\\jobs\\$JOB_NAME\\builds\\$version\\archive\\dist.tar.gz" -destination dist.tar.gz -force'
                  }
              }
              stage("Publish"){
                  steps {
                      sshPublisher(publishers: [sshPublisherDesc(configName: '剛才設定的ssh的名稱', sshRetry: [retries: 3, retryDelay: 5000], transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: 'powershell E:\\服務器B相關部署路徑\\jenkins_deploy.ps1 -number $BUILD_NUMBER', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '服務器B相關部署路徑', remoteDirectorySDF: false, removePrefix: '', sourceFiles: 'dist.tar.gz')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: true)])
                  }
              }
          }
      }
      
    • jenkins_deploy.ps1

      #獲取引數
      param (
      	[string]$number
      )
      #移動到當前目錄
      Set-Location E:\abc
      #設定時間變數
      $date=(get-date).ToString('yyyy_MM_dd_HHmmss')
      #備份檔案名
      $backup_name = 'test_'+$date+'_'+$number+'.tar.gz'
      #將現有的打包
      tar -zcvf $backup_name -C prod .
      #將打包后的移動到backup中
      Move-Item -path $backup_name -destination backup\$backup_name -force
      Write-Output 'backup end'
      #清空prod檔案夾
      Remove-Item -path prod\* -recurse -force
      #將最新的解壓到prod中
      tar -zxvf dist.tar.gz -C prod
      Write-Output 'extra to prod'
      #洗掉傳遞過來的
      Remove-item -path dist.tar.gz -force
      Write-Output 'finished'
      
  • powershell各種方法的呼叫會更簡單一些,需要大體了解下相關語法,參考PowerShell教程 ,例如如果tar沒有加入環境變數,需要這樣寫才行& "c:\Program Files\git\usr\bin\tar.exe" -zcvf xxxx才行,

  • windows下jenkinscmdpowershell的編碼也是費勁,目前powershell腳本檔案不管是設定成ansi,utf8-bom,utf8在jinkins中都是中文亂碼,但是在本地ansi,utf8-bom不是亂碼,但是utf8是亂碼,貌似windows powershell 5.1如果用utf8則必須用帶bom的,但最新的powershell 7則改成不帶bomutf8,jenkins也是,改了編碼配置命令列展示正常了,但另一個地方又出現亂碼,壓根是沖突的,所以目前能寫英文的都寫英文的,就這樣系統報錯的話還是亂碼,真是一堆的坑,目前針對powershell 5還算正常的方式是將所有的ps1檔案設定為utf8-bom編碼,然后將jenkins的啟動項中增加-Dfile.encoding=UTF-8來修改為utf8編碼,

轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/498965.html

標籤:其他

上一篇:這個簡單的小功能,半年為我們產研團隊省下213個小時

下一篇:軟體專案管理 9.2.軟體專案配置管理程序

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • Git本地庫既關聯GitHub又關聯Gitee

    創建代碼倉庫 使用gitee舉例(github和gitee差不多) 1.在gitee右上角點擊+,選擇新建倉庫 ? 2.選擇填寫倉庫資訊,然后進行創建 ? 3.服務端已經準備好了,本地開始作準備 (1)Git 全域設定 git config --global user.name "成鈺" git c ......

    uj5u.com 2020-09-10 05:04:14 more
  • CODING DevOps 代碼質量實戰系列第二課,相約周三

    隨著 ToB(企業服務)的興起和 ToC(消費互聯網)產品進入成熟期,線上故障帶來的損失越來越大,代碼質量越來越重要,而「質量內建」正是 DevOps 核心理念之一。**《DevOps 代碼質量實戰(PHP 版)》**為 CODING DevOps 代碼質量實戰系列的第二課,同時也是本系列的 PHP ......

    uj5u.com 2020-09-10 05:07:43 more
  • 推薦Scrum書籍

    推薦Scrum書籍 直接上干貨,推薦書籍清單如下(推薦有順序的哦) Scrum指南 Scrum精髓 Scrum敏捷軟體開發 Scrum捷徑 硝煙中的Scrum和XP : 我們如何實施Scrum 敏捷軟體開發:Scrum實戰指南 Scrum要素 大規模Scrum:大規模敏捷組織的設計 用戶故事地圖 用 ......

    uj5u.com 2020-09-10 05:07:45 more
  • CODING DevOps 代碼質量實戰系列最后一課,周四發車

    隨著 ToB(企業服務)的興起和 ToC(消費互聯網)產品進入成熟期,線上故障帶來的損失越來越大,代碼質量越來越重要,而「質量內建」正是 DevOps 核心理念之一。 **《DevOps 代碼質量實戰(Java 版)》**為 CODING DevOps 代碼質量實戰系列的最后一課,同時也是本系列的 ......

    uj5u.com 2020-09-10 05:07:52 more
  • 敏捷軟體工程實踐書籍

    Scrum轉型想要做好,第一步先了解并真正落實Scrum,那么我推薦的Scrum書籍是要看懂并實踐的。第二步是團隊的工程實踐要做扎實。 下面推薦工程實踐書單: 重構:改善既有代碼的設計 決議極限編程 : 擁抱變化 代碼整潔代碼 程式員的職業素養 修改代碼的藝術 撰寫可讀代碼的藝術 測驗驅動開發 : ......

    uj5u.com 2020-09-10 05:07:55 more
  • Jenkins+svn+nginx實作windows環境自動部署vue前端專案

    前面文章介紹了Jenkins+svn+tomcat實作自動化部署,現在終于有空抽時間出來寫下Jenkins+svn+nginx實作自動部署vue前端專案。 jenkins的安裝和配置已經在前面文章進行介紹,下面介紹實作vue前端專案需要進行的哪些額外的步驟。 注意:在安裝jenkins和nginx的 ......

    uj5u.com 2020-09-10 05:08:49 more
  • CODING DevOps 微服務專案實戰系列第一課,明天等你

    CODING DevOps 微服務專案實戰系列第一課**《DevOps 微服務專案實戰:DevOps 初體驗》**將由 CODING DevOps 開發工程師 王寬老師 向大家介紹 DevOps 的基本理念,并探討為什么現代開發活動需要 DevOps,同時將以 eShopOnContainers 項 ......

    uj5u.com 2020-09-10 05:09:14 more
  • CODING DevOps 微服務專案實戰系列第二課來啦!

    近年來,工程專案的結構越來越復雜,需要接入合適的持續集成流水線形式,才能滿足更多變的需求,那么如何優雅地使用 CI 能力提升生產效率呢?CODING DevOps 微服務專案實戰系列第二課 《DevOps 微服務專案實戰:CI 進階用法》 將由 CODING DevOps 全堆疊工程師 何晨哲老師 向 ......

    uj5u.com 2020-09-10 05:09:33 more
  • CODING DevOps 微服務專案實戰系列最后一課,周四開講!

    隨著軟體工程越來越復雜化,如何在 Kubernetes 集群進行灰度發布成為了生產部署的”必修課“,而如何實作安全可控、自動化的灰度發布也成為了持續部署重點關注的問題。CODING DevOps 微服務專案實戰系列最后一課:**《DevOps 微服務專案實戰:基于 Nginx-ingress 的自動 ......

    uj5u.com 2020-09-10 05:10:00 more
  • CODING 儀表盤功能正式推出,實作作業資料可視化!

    CODING 儀表盤功能現已正式推出!該功能旨在用一張張統計卡片的形式,統計并展示使用 CODING 中所產生的資料。這意味著無需額外的設定,就可以收集歸納寶貴的作業資料并予之量化分析。這些海量的資料皆會以圖表或串列的方式躍然紙上,方便團隊成員隨時查看各專案的進度、狀態和指標,云端協作迎來真正意義上 ......

    uj5u.com 2020-09-10 05:11:01 more
最新发布
  • windows系統git使用ssh方式和gitee/github進行同步

    使用git來clone專案有兩種方式:HTTPS和SSH:
    HTTPS:不管是誰,拿到url隨便clone,但是在push的時候需要驗證用戶名和密碼;
    SSH:clone的專案你必須是擁有者或者管理員,而且需要在clone前添加SSH Key。SSH 在push的時候,是不需要輸入用戶名的,如果配置... ......

    uj5u.com 2023-04-19 08:41:12 more
  • windows系統git使用ssh方式和gitee/github進行同步

    使用git來clone專案有兩種方式:HTTPS和SSH:
    HTTPS:不管是誰,拿到url隨便clone,但是在push的時候需要驗證用戶名和密碼;
    SSH:clone的專案你必須是擁有者或者管理員,而且需要在clone前添加SSH Key。SSH 在push的時候,是不需要輸入用戶名的,如果配置... ......

    uj5u.com 2023-04-19 08:35:34 more
  • 2023年農牧行業6大CRM系統、5大場景盤點

    在物聯網、大資料、云計算、人工智能、自動化技術等現代資訊技術蓬勃發展與逐步成熟的背景下,數字化正成為農牧行業供給側結構性變革與高質量發展的核心驅動因素。因此,改造和提升傳統農牧業、開拓創新現代智慧農牧業,加快推進農牧業的現代化、資訊化、數字化建設已成為農牧業發展的重要方向。 當下,企業數字化轉型已經 ......

    uj5u.com 2023-04-18 08:05:44 more
  • 2023年農牧行業6大CRM系統、5大場景盤點

    在物聯網、大資料、云計算、人工智能、自動化技術等現代資訊技術蓬勃發展與逐步成熟的背景下,數字化正成為農牧行業供給側結構性變革與高質量發展的核心驅動因素。因此,改造和提升傳統農牧業、開拓創新現代智慧農牧業,加快推進農牧業的現代化、資訊化、數字化建設已成為農牧業發展的重要方向。 當下,企業數字化轉型已經 ......

    uj5u.com 2023-04-18 08:00:18 more
  • 計算機組成原理—存盤器

    計算機組成原理—硬體結構 二、存盤器 1.概述 存盤器是計算機系統中的記憶設備,用來存放程式和資料 1.1存盤器的層次結構 快取-主存層次主要解決CPU和主存速度不匹配的問題,速度接近快取 主存-輔存層次主要解決存盤系統的容量問題,容量接近與價位接近于主存 2.主存盤器 2.1概述 主存與CPU的聯 ......

    uj5u.com 2023-04-17 08:20:31 more
  • 談一談我對協同開發的一些認識

    如今各互聯網公司普通都使用敏捷開發,采用小步快跑的形式來進行專案開發。如果是小專案或者小需求,那一個開發可能就搞定了。但對于電商等復雜的系統,其功能多,結構復雜,一個人肯定是搞不定的,所以都是很多人來共同開發維護。以我曾經待過的商城團隊為例,光是后端開發就有七十多人。 為了更好地開發這類大型系統,往 ......

    uj5u.com 2023-04-17 08:18:55 more
  • 專案管理PRINCE2核心知識點整理

    PRINCE2,即 PRoject IN Controlled Environment(受控環境中的專案)是一種結構化的專案管理方法論,由英國政府內閣商務部(OGC)推出,是英國專案管理標準。
    PRINCE2 作為一種開放的方法論,是一套結構化的專案管理流程,描述了如何以一種邏輯性的、有組織的方法,... ......

    uj5u.com 2023-04-17 08:18:51 more
  • 談一談我對協同開發的一些認識

    如今各互聯網公司普通都使用敏捷開發,采用小步快跑的形式來進行專案開發。如果是小專案或者小需求,那一個開發可能就搞定了。但對于電商等復雜的系統,其功能多,結構復雜,一個人肯定是搞不定的,所以都是很多人來共同開發維護。以我曾經待過的商城團隊為例,光是后端開發就有七十多人。 為了更好地開發這類大型系統,往 ......

    uj5u.com 2023-04-17 08:18:00 more
  • 專案管理PRINCE2核心知識點整理

    PRINCE2,即 PRoject IN Controlled Environment(受控環境中的專案)是一種結構化的專案管理方法論,由英國政府內閣商務部(OGC)推出,是英國專案管理標準。
    PRINCE2 作為一種開放的方法論,是一套結構化的專案管理流程,描述了如何以一種邏輯性的、有組織的方法,... ......

    uj5u.com 2023-04-17 08:17:55 more
  • 計算機組成原理—存盤器

    計算機組成原理—硬體結構 二、存盤器 1.概述 存盤器是計算機系統中的記憶設備,用來存放程式和資料 1.1存盤器的層次結構 快取-主存層次主要解決CPU和主存速度不匹配的問題,速度接近快取 主存-輔存層次主要解決存盤系統的容量問題,容量接近與價位接近于主存 2.主存盤器 2.1概述 主存與CPU的聯 ......

    uj5u.com 2023-04-17 08:12:06 more