真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

windows下jenkins通過pipeline來部署和回滾maven、npm、小程序項(xiàng)目

目的

  • 實(shí)現(xiàn)后臺(tái)java的maven部署
  • 實(shí)現(xiàn)前端npm的部署

準(zhǔn)備

  • 兩臺(tái)服務(wù)器,我這邊都是windows的:

    創(chuàng)新互聯(lián)建站是一家以網(wǎng)站建設(shè)公司、網(wǎng)頁設(shè)計(jì)、品牌設(shè)計(jì)、軟件運(yùn)維、成都網(wǎng)站推廣、小程序App開發(fā)等移動(dòng)開發(fā)為一體互聯(lián)網(wǎng)公司。已累計(jì)為VR全景等眾行業(yè)中小客戶提供優(yōu)質(zhì)的互聯(lián)網(wǎng)建站和軟件開發(fā)服務(wù)。

    • 服務(wù)器A,用于安裝jenkins等服務(wù)
    • 服務(wù)器B,待部署機(jī)器
  • Jenkins,除了默認(rèn)插件外,額外需要手動(dòng)安裝插件:

    • Blue Ocean,更方便的展示進(jìn)度等
    • Publish Over SSH,用于通過ssh來部署遠(yuǎn)程服務(wù)器
    • DingTalk,釘釘機(jī)器人通知插件
  • OpenSSH

  • Git

  • 其他的java、mavennpm等工具

安裝軟件

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

ssh密鑰聯(lián)通

  • 整體的流程就是服務(wù)器B相當(dāng)于服務(wù)端,服務(wù)器A相當(dāng)于客戶端,我們需要用客戶端通過ssh鏈接到服務(wù)端,然后傳輸部署的文件過去,所以需要在客戶端中生成私鑰和公鑰,公鑰會(huì)給到服務(wù)端中,私鑰則還是留在客戶端,這樣ssh鏈接時(shí)通過私鑰和公鑰驗(yàn)證通過鏈接到一起就可以傳輸文件了。

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

    xxx_rsa     #私鑰
    xxx_rsa.pub #公鑰
    
  • 服務(wù)器B可以先啟動(dòng)一下openssh服務(wù)然后關(guān)閉,此時(shí)會(huì)自動(dòng)生成C:\Program Data\ssh目錄,然后我們配置此目錄下的sshd_config文件,改動(dòng)如下:

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

  • 測試聯(lián)通性,可以在服務(wù)器A~/.ssh/config中配置:

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

    然后可以ssh b_name來測試是否可以聯(lián)通

  • jenkinsPublish Over SSH插件配置中并測試聯(lián)通性,位置Manage Jenkins->Configure System->SSH Servers中:

    點(diǎn)擊測試,看是否聯(lián)通成功,如果出現(xiàn)類似Fail Auth等錯(cuò)誤,可以參考此解決方法來解決:Jenkins Publish over ssh authentification failed with private key

git 密鑰聯(lián)通

  • 同上在服務(wù)器A中同上創(chuàng)建私鑰和公鑰,但是github只支持最新版本的,可以不用加那些參數(shù)了,具體參考官方文檔:新增 SSH 密鑰到 GitHub 帳戶 - GitHub Docs
  • 以github為例,在個(gè)人主頁的Setting->SSH AND GPG keys ->SSH keys中新增,將生成的公鑰粘貼到github中的字段中就可以了
  • 和上方一樣來測試下聯(lián)通是否OK,其他gitee等原理基本一樣

maven項(xiàng)目部署

  • 如果不熟悉jenkinspipeline相關(guān)的話,請先按照官方文檔demo操作一遍:Build a Java app with Maven

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

    pipeline {
        agent any //沒有用docker
        parameters {//這個(gè)是參數(shù)化構(gòu)建
            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包歸檔,方便回滾時(shí)用到
                    archiveArtifacts artifacts: '自身相關(guān)路徑/target/*.jar', followSymlinks: false, onlyIfSuccessful: true
                }
            }
            stage('Rollback') {
                when {//如果是回滾
                    expression { params.action == 'rollback' }
                }
                steps {//回滾就不需要打包了,直接將原先版本的歸檔復(fù)制到打包出來的路徑
                    bat 'xcopy /s /f /y "%JENKINS_HOME%\\jobs\\%JOB_NAME%\\builds\\%version%\\archive\\自身相關(guān)路徑\\target" 自身相關(guān)路徑\\target'
                }
            }
            stage('Publish') {
                steps {//publish over ssh插件相關(guān)參數(shù),verbose為true,則jenkins_deploy.bat腳本的執(zhí)行信息會(huì)返回
                    sshPublisher(publishers: [sshPublisherDesc(configName: '剛才設(shè)置的ssh的名稱', sshRetry: [retries: 3, retryDelay: 5000], transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: 'cmd /c E:\\服務(wù)器B相關(guān)部署路徑\jenkins_deploy.bat $BUILD_NUMBER', execTimeout: , flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '服務(wù)器B相關(guān)路徑', remoteDirectorySDF: false, removePrefix: '自身相關(guān)路徑/target', sourceFiles: '自身相關(guān)路徑/target/*.jar')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: true)])
                }
            }
        }
    }
    
  • 上方代碼一些注解:

    • 上方的參數(shù)化構(gòu)建、歸檔publish over ssh語法都是可以由可視化界面生成的,隨便點(diǎn)開一個(gè)job后在左側(cè)有流水線語法這個(gè)選項(xiàng),點(diǎn)開后頁面在左側(cè) Declarative Directive Generator中選擇parameters:Parameters可以生成參數(shù)化構(gòu)建片段;而左側(cè)片段生成器archiveArtifacts archive the artifacts用來生成歸檔片段,sshPublishers: Send build artifacts over SSH則用來生成發(fā)布的片段,這些具體的使用,可以參考官方文檔也可以自行搜索更詳細(xì)的用法文章。

    • 參數(shù)化構(gòu)建如果在pipeline中寫了后,不需要在界面中再配置,只需要運(yùn)行一次后會(huì)自動(dòng)從pipeline中獲取,下次再構(gòu)建就發(fā)現(xiàn)有參數(shù)需要填寫了,要想回滾則選擇rollback然后輸入回滾的構(gòu)建數(shù)字運(yùn)行則會(huì)回滾:

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

  • 服務(wù)器B端的結(jié)構(gòu)及腳本:

    • 項(xiàng)目結(jié)構(gòu):

      abc:
      ├─backup
      │    └─test_2022_06_27__3.jar #在服務(wù)端也備份一份,格式:名稱+日期+構(gòu)建號+jar
      └─prod
      │    └─test.jar #生產(chǎn)文件
      └─jenkins_deploy.bat
      
    • jenkins_deploy.bat腳本:

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

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

npm項(xiàng)目部署

  • 整體流程和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 {//先打包成壓縮文件,再歸檔,同時(shí)也方便傳輸
                    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: '剛才設(shè)置的ssh的名稱', sshRetry: [retries: 3, retryDelay: 5000], transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: 'cmd /c E:\\服務(wù)器B相關(guān)部署路徑\\jenkins_deploy.bat $BUILD_NUMBER', execTimeout: , flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '服務(wù)器B相關(guān)部署路徑', remoteDirectorySDF: false, removePrefix: '', sourceFiles: 'dist.tar.gz')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: true)])
                }
            }
        }
    }
    
  • 服務(wù)器B的jenkins_deploy.bat腳本,結(jié)構(gòu)和maven項(xiàng)目差不多。

    • 項(xiàng)目結(jié)構(gòu):

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

      @echo off
      ::設(shè)置utf8編碼運(yùn)行
      chcp 
      ::移動(dòng)到當(dāng)前目錄
      cd /d E:\abc
      ::設(shè)置時(shí)間變量,需要注意的是utf編碼和ansi編碼所取時(shí)間的位數(shù)不一樣
      set "Ymd=%date:~3,4%_%date:~8,2%_%date:~11,2%_%time:~0,2%%time:~3,2%%time:~6,2%"
      ::獲取第一個(gè)參數(shù)
      set "param=%1"
      ::將時(shí)間的空格用0補(bǔ)齊;將參數(shù)可能攜帶的引號去掉
      set backup_name=%Ymd: =0%_%param:"=%
      ::將現(xiàn)有的打包后移到backup中
      tar -zcvf test_%backup_name%.tar.gz -C prod .
      move test_%backup_name%.tar.gz backup\test_%backup_name%.tar.gz
      echo 'prod中內(nèi)容打包到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
      

構(gòu)建通知

  • 目前插件可以通過釘釘和企業(yè)微信機(jī)器人通知,目前只測試了釘釘?shù)模杏X還可以,目前我這邊沒有在pipeline中自定義,只是用了通用功能,更多功能可查看官方文檔或自行搜索相關(guān)文章。

完工

  • 以上就是整體流程,只是記錄了下一些關(guān)鍵點(diǎn)。

另外補(bǔ)充下小程序的部署和用powershell腳本的寫法

  • 小程序

    • 主要是利用官方的miniprogram-ci來完成,此類庫可以實(shí)現(xiàn)預(yù)覽和上傳(上傳后還是需要登陸小程序平臺(tái)來設(shè)置體驗(yàn)版或者是提交正式版本),這個(gè)類庫是nodejs寫的,所以需要大體了解下nodejs腳本的寫法,可以參考Node.js 入門教程

    • 小程序用miniprogram-ci上傳前需要先到小程序平臺(tái)“開發(fā)管理”->"開發(fā)設(shè)置"->"小程序代碼上傳"中生成小程序代碼上傳密鑰,實(shí)際上就和ssh的密鑰類似,在編寫腳本時(shí)會(huì)用到此密鑰,此密鑰不要放到和代碼一起的版本控制中,否則太不安全了,有兩種方式,一種是直接放到j(luò)enkins所在服務(wù)器的某個(gè)路徑,然后在腳本時(shí)直接引;一種是放到j(luò)enkins的密鑰管理中,類似github的密鑰一樣,然后在pipeline通過withCredentials可以獲取到,這里采用的是后一種方法,在jinkins中新建credentials,選擇SSH Username with private key,其中id則為Jenkinsfile中引用的名稱,用戶名可以隨便填寫,Private Key則從小程序端下載的key文件中直接復(fù)制過來填入即可。

    • jenkins所在服務(wù)器安裝nodejs(最好與開發(fā)的版本一致),同時(shí)在 jenkins插件管理中安裝nodejs插件并在全局配置中設(shè)置nodejs版本(安裝插件后會(huì)多出此選項(xiàng));需要在項(xiàng)目中引入miniprogram-ci 庫:npm install miniprogram-ci --save,項(xiàng)目結(jié)構(gòu)如下所示,腳本放到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));//此類庫主要用于解析參數(shù),實(shí)現(xiàn)--version 12,則argv.version就為12,如果系統(tǒng)沒有自帶,則npm安裝下
      const manifest = require('../src/manifest.json');//用的uniapp,直接從這里取appid,需要確保manifest.json不要有注釋,或者自己新建個(gè)json文件也行
      const appDirectory = fs.realpathSync(process.cwd());//當(dāng)前命令行路徑,主要用于獲取絕對路徑
      let projectPath = path.resolve(appDirectory, './dist/build/mp-weixin');//組裝項(xiàng)目路徑
      let qrCodeImg = path.resolve(appDirectory, './qrcode.jpg');//組裝二維碼路徑
      let type = argv.type;//參數(shù)預(yù)覽還是上傳
      let privateKeyPath = argv.key;//傳遞upload的私鑰路徑
      let version = argv.version ? argv.version : argv.number;//版本號,如果有傳遞則用,沒傳遞則用構(gòu)建號
      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') {
        //預(yù)覽
        (async () => {
          await ci.preview({
            project,
            desc: desc,
            setting: {
              es6: true,
              es7: true
            },
            qrcodeFormat: 'image',
            qrcodeOutputDest: qrCodeImg,
            onProgressUpdate: console.log,
          });
        })();
      } else if (type === 'upload') {
        //上傳
        (async () => {
          await ci.upload({
            project,
            version: version,
            desc: desc,
            setting: {
              es6: true,
              es7: true
            },
            onProgressUpdate: console.log,
          });
        })();
      }
      
    • JenkinsFile(cmd版本),小程序自帶回退上一版本的功能,所以這里就沒有做回退選項(xiàng),如果想做可參考上方的實(shí)現(xiàn),是同一個(gè)邏輯

      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 {//先掉用預(yù)覽來生成二維碼圖片,用于歸檔后在jenkins中查看,這一步也可以不用
                      withCredentials([sshUserPrivateKey(credentialsId: '小程序密鑰在jenkins保存后的id', keyFileVariable: 'identity')]) {
                          bat 'node ci\\upload.js --type=preview --desc="%desc%" --key="%identity%"'
                      }
                  }
              }
              stage("Archive"){
                  steps {//同時(shí)將二維碼也歸檔,方便在jenkins中查看,如果是jenkins外網(wǎng)可以訪問,還可以將歸檔后的預(yù)覽二維碼發(fā)送到釘釘?shù)韧ㄖぞ咧?,或者?nèi)網(wǎng)也可以用oss自帶的cli工具上傳到oss中供外網(wǎng)訪問,此二維碼有效時(shí)間是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沒有填寫,則用構(gòu)建號作為小程序版本號
                      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')]) {
                          //這個(gè)參數(shù)中如果有空格會(huì)解析參數(shù)不完整,所以必須加引號
                          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 {//這個(gè)是參數(shù)化構(gòu)建
              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包歸檔,方便回滾時(shí)用到
                      archiveArtifacts artifacts: '自身相關(guān)路徑/target/*.jar', followSymlinks: false, onlyIfSuccessful: true
                  }
              }
              stage('Rollback') {
                  when {//如果是回滾
                      expression { params.action == 'rollback' }
                  }
                  steps {//回滾就不需要打包了,直接將原先版本的歸檔復(fù)制到打包出來的路徑
                      powershell 'copy-item -path "$JENKINS_HOME\\jobs\\$JOB_NAME\\builds\\$version\\archive\\自身相關(guān)路徑\\target\\*" -destination 自身相關(guān)路徑\\target\\ -recurse -force'
                  }
              }
              stage('Publish') {
                  steps {//publish over ssh插件相關(guān)參數(shù),verbose為true,則jenkins_deploy腳本的執(zhí)行信息會(huì)返回
                      sshPublisher(publishers: [sshPublisherDesc(configName: '剛才設(shè)置的ssh的名稱', sshRetry: [retries: 3, retryDelay: 5000], transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: 'powershell E:\\服務(wù)器B相關(guān)部署路徑\jenkins_deploy.sp1 -number $BUILD_NUMBER', execTimeout: , flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '服務(wù)器B相關(guān)路徑', remoteDirectorySDF: false, removePrefix: '自身相關(guān)路徑/target', sourceFiles: '自身相關(guān)路徑/target/*.jar')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: true)])
                  }
              }
          }
      }
      
    • jenkins_deploy.ps1

      #獲取參數(shù)
      param (
      	[string]$number
      )
      #移動(dòng)到當(dāng)前目錄
      Set-Location E:\abc
      #設(shè)置時(shí)間變量
      $date=(get-date).ToString('yyyy_MM_dd_HHmmss')
      #備份文件名
      $backup_name = 'test_'+$date+'_'+$number+'.jar'
      #將現(xiàn)有的復(fù)制backup中
      Copy-Item -path prod\test.jar -destination backup\$backup_name -force
      Write-Output 'backup end'
      #關(guān)閉服務(wù)
      net stop test
      #將最新的移動(dòng)到生產(chǎn)目錄中
      Move-Item -path test.jar -destination prod\test.jar -force
      Write-Output 'move new to prod'
      #開啟服務(wù)
      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 {//先打包成壓縮文件,再歸檔,同時(shí)也方便傳輸
                      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: '剛才設(shè)置的ssh的名稱', sshRetry: [retries: 3, retryDelay: 5000], transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: 'powershell E:\\服務(wù)器B相關(guān)部署路徑\\jenkins_deploy.ps1 -number $BUILD_NUMBER', execTimeout: , flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '服務(wù)器B相關(guān)部署路徑', remoteDirectorySDF: false, removePrefix: '', sourceFiles: 'dist.tar.gz')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: true)])
                  }
              }
          }
      }
      
    • jenkins_deploy.ps1

      #獲取參數(shù)
      param (
      	[string]$number
      )
      #移動(dòng)到當(dāng)前目錄
      Set-Location E:\abc
      #設(shè)置時(shí)間變量
      $date=(get-date).ToString('yyyy_MM_dd_HHmmss')
      #備份文件名
      $backup_name = 'test_'+$date+'_'+$number+'.tar.gz'
      #將現(xiàn)有的打包
      tar -zcvf $backup_name -C prod .
      #將打包后的移動(dòng)到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各種方法的調(diào)用會(huì)更現(xiàn)代、簡單一些,個(gè)人更推薦,需要大體了解下相關(guān)語法,參考PowerShell 在線教程或者PowerShell教程 。例如如果tar沒有加入環(huán)境變量,需要這樣寫才行& "xxxx\git\usr\bin\tar.exe" -zcvf xxxx才行。

  • windows下jenkinscmdpowershell的編碼也是費(fèi)勁,目前powershell腳本文件不管是設(shè)置成ansi,utf8-bom,utf8在jenkins中都是中文亂碼,但是在本地運(yùn)行ansi,utf8-bom格式不是亂碼,但是utf8格式是亂碼,貌似windows powershell 5.1如果用utf8則必須用帶bom的,但最新的powershell 7則改成不帶bomutf8jenkins也是,改了編碼配置命令行展示正常了,但另一個(gè)地方又出現(xiàn)亂碼,壓根是沖突的,所以目前能寫英文的都寫英文的,就這樣系統(tǒng)報(bào)錯(cuò)的話還是亂碼,真是一堆的坑。

  • 目前針對powershell還算正常的方式是:

    • 設(shè)置ps1腳本文件編碼為utf8-bom,可以用notepad++等軟件來轉(zhuǎn)換下。
    • 設(shè)置powershell軟件本身的編碼為utf8,具體操作是打印$profile可得到配置文件所在位置名稱,在配置文件內(nèi)(沒有則自己新建個(gè)同名的)輸入:$OutputEncoding = [console]::InputEncoding = [console]::OutputEncoding = New-Object System.Text.UTF8Encoding,保存后再次打開powershell默認(rèn)就是utf8展示了。
    • 設(shè)置jenkins的編碼為utf8,在其安裝目錄下的jenkins.xml文件中在java啟動(dòng)項(xiàng)中增加-Dfile.encoding=UTF-8,重啟即可。

新聞名稱:windows下jenkins通過pipeline來部署和回滾maven、npm、小程序項(xiàng)目
文章網(wǎng)址:http://weahome.cn/article/dschgpe.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部