<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Jenkins SCM實現Git倉庫定期編譯

      本文解決的問題:

      1. 利用Jenkins SCM定期觸發GitSCM構建。
      2. 如何配置Jenkins SCM機制。
      3. 如何寫一個jenkinsfile,學習基本的Groovy DSL語法。
      4. GitSCM插件,通過GIT_BRANCH變量得到分支名。
      5. 將本地分支切換到觸發構建的分支,將所有子模塊切換到同名的分支并git pull最新代碼。

      Jenkins是一款自動化任務的軟件。軟件開發經常需要編譯版本發布。于是我們可以利用Jenkins定期獲得代碼進行編譯。

      一、Jenkins運行原理

      1. Jenkins官方文檔: https://www.jenkins.io/doc/book/pipeline/getting-started/
      2. Jenkins文檔: https://rtyler.github.io/jenkins.io/doc/book/pipeline/getting-started/#defining-a-pipeline-in-scm

      參考:jenkins原理圖

      組網圖

      日常工作場景為開發者將代碼提交到代碼服務器如:Github。如果要實現自動化編譯。基本步驟如下:

      1. 首先安裝Jenkins后,Jenkins Agent有完整的編譯環境,與開發者代碼編譯環境完全一樣。
      2. 在Jenkins Controller上創建流水線(pipline)任務。例如:SCM任務可以定期去代碼服務器上拉取代碼。

      二、Jenkins SCM

      本章內容解決每周自動觸發編譯的問題,在滿足以下條件時執行編譯:

      1. 代碼倉庫在本周有新的代碼提交。
      2. 代碼倉庫如果有多個不同分支有新提交,則采用不同編譯時段錯開。

      創建Jenkins任務步驟:

      1. Jenkins上創建任務(Job)名為:build_pipline
      2. 進入任務設置界面:Dashboard >> build_pipline
      3. 在Jenkins配置界面 “構建觸發器” 中選擇任務觸發條件:定時構建,輪詢SCM,觸發遠程構建等。這些條件之間是或的關系,也就是任何一個條件滿足都會運行任務(Job)。
      4. 在Jenkins配置界面 “流水線” 中設置任務執行的具體內容。

      Jenkins的任務執行規則為首先根據構建觸發器里的條件滿足后觸發Jenkins任務啟動,任務查找流水線里定義的執行內容。流水線由Groovy腳本編寫,里面定義了不同的stage階段。Jenkins是由第一個stage執行到最后一個stage,執行完畢后返回執行結果。

      Jenkins配置界面如下:

      2.1 配置構建觸發器:輪詢SCM

      勾選輪詢SCM后需要配置“日程表”設置周期。點圖標“?”號可以獲取幫助提示。
      輸入格式為:

      MINUTE HOUR DOM MONTH DOW
      

      說明:
      MINUTE: Minutes within the hour (0–59)
      HOUR: The hour of the day (0–23)
      DOM: The day of the month (1–31)
      MONTH: The month (1–12)
      DOW: The day of the week (0–7) where 0 and 7 are Sunday.

      2.2 配置流水線:GitSCM

      環境要求:Jenkins安裝GitSCM插件。

      參考:

      1. https://zhuanlan.zhihu.com/p/432225597

      [!NOTE] SCM配置
      https://dev.to/logesh-sakthivel/jenkins-pipeline-script-from-scm-2k3k
      Prerequisite

      Jenkinsfile must be located in the SCM(Github,Bitbucket,…)

      配置步驟:

      1. 定義選擇:Pipline Script from SCM。
      2. SCM中,因為我用的是Git就選Git。
      3. Repositories:填上倉庫URL,也就是git clone的地址。如:ssh://myuser@mygitserver/git/myrepo。注意網絡一定是能通這個倉庫地址的。
      4. Credentials:設置倉庫的賬號密碼。建議設置好免密登錄。
      5. 指定分支:選擇你需要定期編譯的分支名。如:*/master
      6. 腳本路徑:jenkinsfile目錄。所以代碼倉庫myrepo需要準備好jeninsfile。jenkinsfile里面的內容是定義流水線的執行階段。下一章具體講到jenkinsfile的語法規則。

      配置界面如下:

      2.2.1 Repositories:倉庫地址

      填寫的倉庫地址一定是Jenkins服務器能連接的。如果倉庫是一個私有Gitlab的倉庫。可以在Gitlab服務器上配置好jenkins的ssh key認證后就可以免密登錄。雖然可以在Credentials設置好賬號密碼但對于測試不是很方便。
      在調試階段需要設置一個方便測試的倉庫地址,一般不是Gitlab這樣的團隊公共地址。如果倉庫地址是自己的一臺主機的git倉庫,可以通過下面方法設置好免密。使用jenkins運行任務的賬號,登錄jenkins服務器:

      // 設置免密登錄git倉庫服務器
      ssh-copy-id myuser@172.2.0.3
      

      因為git倉庫地址也是ssh的,所以只要jenkins服務器能ssh到git倉庫的服務器就可以。

      2.2.2 jenkinsfile目錄

      我的倉庫名為myrepo,則jenkinsfile路徑為:

      myrepo/mydir/jenkinsfile
      

      2.3 定時構建和輪詢(SCM)的區別

      • 定時構建:即使沒有代碼變更也計劃執行。
      • 輪詢SCM:定期檢查SCM(如:Git倉庫),檢測到有新提交時才觸發構建。

      三、jenkinsfile

      解決的問題:

      1. 定義clone了倉庫后如何編譯。

      參考:

      1. jenkins流水線

      [!NOTE]

      1. web界面創建
      2. Pipeline script from SCM(How to create Jenkins File)
        Create a text file and name it Jenkinsfile.txt. Place your pipeline code in this text file. Add this text file to the root folder of your project in the code repository.

      We can add post-build actions in the Jenkins file. These actions will be executed every time after work is finished.

      jenkinsfile由Groovy DSL語法定義了流水線的工作流(work flow)。

      3.1 Groovy語法

      參考:

      1. [Jenkins構建腳本 - 簡書 (jianshu.com)](https://www.jianshu.com/p/1a4f35f9678d
      2. 【Jenkinsfile語法示例:parameters參數化構建】

      3.1.1 注釋

      舉例:

      /* stage('mystage') {
      	steps {
      		script {
      		    // 打印。 Groovy單行注釋
      			echo "branch: ${env.TARGET_BRANCH}"
      		}
      
      		sh '''
      			  # 更新子模塊的遠程分支信息  <<< shell里注釋采用shell注釋語法
      			  git submodule sync --recursive
      		"""
      	}
      } */   <<< Groovy多行注釋
      

      3.2 設置子模塊默認分支

      解決的問題:

      1. 子模塊如何有默認的本地分支。
      2. 如何關聯到倉庫.git/modules/config目錄下配置的注分支。

      默認情況下git clone下來的代碼子模塊是不會自動拉取的。

      build_pipline$ git submodule
      -1df5654c75 mysubmodule_1
      

      并且本地分支未創建,子模塊也沒有submodule upate --init。這種情況我們要利用Jenkins的GitSCM配置extensions。

      extensions: [
          // 強制創建myrepo倉庫的本地分支
          [$class: 'LocalBranch', localBranch:  env.TARGET_BRANCH],
      
          // 實現子模塊遞歸檢出記住的commit id
          //[$class: 'SubmoduleOption', recursiveSubmodules: true],
      ],
      

      在git倉庫中會設置默認的分支

      $ cat myrepo/.git/modules/mysubmodule_1/config
      [core]
              repositoryformatversion = 0
              filemode = true
              bare = false
              logallrefupdates = true
              worktree = ../../../mysubmodule_1
      [remote "origin"]
              url = ssh://mygitserver/mysubmodule_1
              fetch = +refs/heads/*:refs/remotes/origin/*
      [branch "master"]
              remote = origin
              merge = refs/heads/master
      

      這樣子模塊默認有本地master分支且追蹤了遠端遠端master分支。

      mysubmodule_1$ git checkout master
      Switched to branch 'master'
      Your branch is up to date with 'origin/master'.
      
      /workspace/build_pipline/mysubmodule_1$ git pull
      Already up to date.
      

      3.3 子模塊切分支

      遍歷所有子模塊并切到與GIT_BRANCH同名的本地分支。采用的是調用shell腳本利用git命令實現。

      // 更新子模塊并追蹤遠端分支
      script {
      	sh '''
      		git checkout -B "${TARGET_BRANCH}" --track "${GIT_BRANCH}"
      		git submodule update --init --recursive
      		git submodule foreach --recursive "
      			if ! git rev-parse --verify "${TARGET_BRANCH}" >/dev/null 2>&1; then
      				# 分支不存在時,創建并跟蹤遠程分支
      				git checkout -b "${TARGET_BRANCH}" --track "${GIT_BRANCH}"
      			else
      				# 分支存在時,切換到該分支并拉取更新
      				git checkout "${TARGET_BRANCH}" && git pull
      			fi
      		"
         '''
      }
      

      3.4 設置環境變量將代碼clone到指定目錄

      在 Jenkins 的 Git SCM 配置中,默認會將代碼克隆到工作空間(Workspace)的根目錄。若需將代碼克隆到?指定子目錄,可通過 extensions 中的 CheckoutToSubdirectory 擴展實現。

      extensions: [ 
      	// 關鍵配置:指定克隆目錄為工作空間下的 `myrepo` 子目錄 
      	[$class: 'CheckoutToSubdirectory', parentDir: 'myrepo'] //目標目錄路徑(相對工作空間) 
      ]
      

      高級場景:動態目錄生成。若目錄名需基于環境變量動態生成:

      script {
          def envDir = "build-${env.BUILD_ID}"  // 動態目錄名(如 build-123)
          checkout([
              $class: 'GitSCM',
              extensions: [
      	        [$class: 'CleanBeforeCheckout'], // 清理目標目錄
                  [$class: 'CheckoutToSubdirectory', parentDir: envDir]
              ]
          ])
      }
      

      3.5 jenkinsfile實現示例

      實現了SCM編譯,拉取git倉庫并切出本地分支。jenkinsfile示例如下:

      pipeline {
          agent any
      
          environment {
              APP_NAME = "MYAPP"
          }
          stages {
              stage('GitSCMEnv') {
                  steps {
                      script {
                          env.TARGET_BRANCH = env.GIT_BRANCH.split('/').last()
                          echo "branch: ${env.TARGET_BRANCH}"
      
                          checkout([
                              // 作用是聲明使用Git作為源代碼管理工具,并配置與之相關的核心參數
                              $class: 'GitSCM',
                              // 指定待檢出的分支
                              branches: [[name: env.GIT_BRANCH]],
                              // 配置遠程倉庫地址和認證信息
                              userRemoteConfigs: scm.userRemoteConfigs,
                              extensions: [
                                  // 強制創建myrepo本地分支,不包括子模塊
                                  //[$class: 'LocalBranch', localBranch:  env.TARGET_BRANCH],
                                  [$class: 'LocalBranch', 
                                      localBranch: env.TARGET_BRANCH,// 動態指定本地分支名
                                      trackingBranch: env.GIT_BRANCH // 綁定遠程分支
                                  ],
                                  // 子模塊遞歸檢出的是記住的commit id,子模塊默認的本地分支
                                  [$class: 'SubmoduleOption',
                                      recursiveSubmodules: true,     // 遞歸更新嵌套子模塊
                                      parentCredentials: true,       // 統一使用父倉庫憑證
                                      shallow: false,                // 禁用淺克隆確保可pull
                                      trackingSubmodules: true       // 跟蹤子模塊遠程分支
                                  ],
                                  [$class: 'CleanBeforeCheckout'],    // 清理之前的同名目錄
                              ]
                          ])
                      }
      
                      sh """
                          echo "Application Name: \${APP_NAME}"
                          pwd
                          ls -la
                          env | sort
                      """
      
                  }
              }
      
              // 更新子模塊并追蹤遠端分支
              stage('Submodules'){
                  steps {
                      script {
                          sh '''
                              git checkout -B "${TARGET_BRANCH}" --track "origin/${TARGET_BRANCH}"
                              git submodule update --init --recursive
                              git submodule foreach --recursive "
                                  if ! git rev-parse --verify "${TARGET_BRANCH}" >/dev/null 2>&1; then
      	                            # 分支不存在時,創建并跟蹤遠程分支
                                      git checkout -b "${TARGET_BRANCH}" --track "origin/${TARGET_BRANCH}"
                                  else
      	                            # 分支存在時,切換到該分支并拉取更新
                                      git checkout "${TARGET_BRANCH}" && git pull
                                  fi
                              "
                         '''
                      }
                  }
              }
              /* stage('build') {
                  steps {
                      sh './build.sh' // 執行編譯腳本
                  }
              } */
          }
      }
      
      

      四、調試方法

      4.1 直接登錄到Jenkins服務器上查看

      可以到Jenkins的工作目錄查看實際clone的代碼,切的分支。

      // 登錄Jenkins用戶
      su jenkins
      /var/lib/jenkins/workspace/build_pipline/
      

      4.2 查看日志:Console Output

      Dashboard >> build_pipline >> {job} >> Console Output
      查看jenkins各個stage的日志打印

      4.2.1 打印出環境變量日志

      + env
      + sort
      APP_NAME=SIMPLE_APP
      BUILD_DISPLAY_NAME=#17
      BUILD_ID=17
      BUILD_NUMBER=17
      BUILD_TAG=jenkins-build_pipline-17
      BUILD_URL=[http://myjenkins:8080/job/build_pipline/17/](http://myjenkins:8080/job/build_pipline/17/)
      CI=true
      EXECUTOR_NUMBER=1
      GIT_BRANCH=origin/master
      GIT_COMMIT=131d6ae6e
      GIT_PREVIOUS_COMMIT=131d6ae6e
      GIT_PREVIOUS_SUCCESSFUL_COMMIT=131d6ae6e
      GIT_URL=ssh://jenkins@mygitserver/mybuild
      HOME=/var/lib/jenkins
      HUDSON_COOKIE=463b-f94f-4f72-aea4-0400
      HUDSON_HOME=/var/lib/jenkins
      HUDSON_SERVER_COOKIE=1de5db4ef9069b3e
      HUDSON_URL=[http://myjenkins:8080/](http://myjenkins:8080/)
      INVOCATION_ID=6420
      JENKINS_HOME=/var/lib/jenkins
      JENKINS_NODE_COOKIE=4f2d-d9ff-4921-866d-ac9f
      JENKINS_SERVER_COOKIE=durable-5059
      JENKINS_URL=[http://myjenkins:8080/](http://myjenkins:8080/)
      JOB_BASE_NAME=build_pipline
      JOB_DISPLAY_URL=[http://myjenkins:8080/job/build_pipline/display/redirect](http://myjenkins:8080/job/build_pipline/display/redirect)
      JOB_NAME=build_pipline
      JOB_URL=[http://myjenkins:8080/job/build_pipline/](http://myjenkins:8080/job/build_pipline/)
      JOURNAL_STREAM=8:74272520
      LANG=en_US.UTF-8
      LC_ADDRESS=zh_CN.UTF-8
      LC_IDENTIFICATION=zh_CN.UTF-8
      LC_MEASUREMENT=zh_CN.UTF-8
      LC_MONETARY=zh_CN.UTF-8
      LC_NAME=zh_CN.UTF-8
      LC_NUMERIC=zh_CN.UTF-8
      LC_PAPER=zh_CN.UTF-8
      LC_TELEPHONE=zh_CN.UTF-8
      LC_TIME=zh_CN.UTF-8
      LOGNAME=jenkins
      NODE_LABELS=built-in
      NODE_NAME=built-in
      NOTIFY_SOCKET=/run/systemd/notify
      PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin
      PWD=/var/lib/jenkins/workspace/build_pipline
      RUN_ARTIFACTS_DISPLAY_URL=[http://myjenkins:8080/job/build_pipline/17/display/redirect?page=artifacts](http://myjenkins:8080/job/build_pipline/17/display/redirect?page=artifacts)
      RUN_CHANGES_DISPLAY_URL=[http://myjenkins:8080/job/build_pipline/17/display/redirect?page=changes](http://myjenkins:8080/job/build_pipline/17/display/redirect?page=changes)
      RUN_DISPLAY_URL=[http://myjenkins:8080/job/build_pipline/17/display/redirect](http://myjenkins:8080/job/build_pipline/17/display/redirect)
      RUN_TESTS_DISPLAY_URL=[http://myjenkins:8080/job/build_pipline/17/display/redirect?page=tests](http://myjenkins:8080/job/build_pipline/17/display/redirect?page=tests)
      SHELL=/bin/bash
      STAGE_NAME=Stage 2
      USER=jenkins
      WORKSPACE_TMP=/var/lib/jenkins/workspace/build_pipline@tmp
      WORKSPACE=/var/lib/jenkins/workspace/build_pipline
      

      4.3 Git 輪詢日志

      Dashboard >> build_pipline >> Git 輪詢日志

      [poll] Latest remote head revision on refs/heads/master is: 131d6ae6e - already built by 16
      Done. Took 0.29 sec
      No changes   <<< 提示git倉庫沒有新提交所以沒有觸發編譯。
      

      五、遇到的問題

      5.1 如何設置免密git clone : Permission denied (publickey,password).

      解決:見:2.2.1 Repositories:倉庫地址

      5.2 報錯:Bad substitution

      現象:

       [Shell Script -- git submodule update --init --recursive git submodule foreach --recursive " if ! git rev-parse --verify "${env.targetBranch}" >/dev/null 2>&1; then git checkout -b ${env.targetBranch} --track "origin/${env.targetBranch}" else echo "${targetBranch}" fi "]
       
       (http://myjenkins:8080/job/build_pipline/48/execution/node/45/log) (self time 533ms)
      + git submodule update --init --recursive
      /var/lib/jenkins/workspace/build_pipline@tmp/durable-5a39671e/script.sh: 3: Bad substitution
      

      解決:
      語法錯誤。變量不需要加env,將${env.targetBranch}替換為${targetBranch}

      5.3 submoduleCfg配置報錯:git.SubmoduleConfig.branches

      現象:

      // 語句
      checkout([
      	$class: 'GitSCM',
      	submoduleCfg: [  
      		[path: 'modules/mysubmodule_1', branches: env.TARGET_BRANCH],  
      	]
      ])  
      

      報錯

      java.lang.ClassCastException: hudson.plugins.git.SubmoduleConfig.branches expects java.util.Collection<java.lang.String> but received class java.lang.String
      

      解決:變量加上中括號。

      // 子模塊分支綁定,(不過測試由于Jenkins版本不支持并為生效)
      submoduleCfg: [
      	[path: 'modules/mysubmodule_1', branches: [env.TARGET_BRANCH]]
      ]           
      
      posted @ 2025-04-05 14:21  liqinglucky  閱讀(81)  評論(0)    收藏  舉報
      主站蜘蛛池模板: av午夜福利一片免费看久久| 最近中文字幕完整版| 116美女极品a级毛片| 成在人线av无码免费看网站直播| 野花韩国高清电影| 久久大香萑太香蕉av黄软件| 国产丰满乱子伦无码专区| 崇左市| 一本无码在线观看| 亚洲精品国产av一区二区| 亚洲性图日本一区二区三区| 亚洲色大成网站WWW永久麻豆| 深夜在线观看免费av| 日韩精品福利视频在线观看| 国产乱子伦无套一区二区三区| 国产高清吹潮免费视频| 精品国产丝袜自在线拍国语| 麻豆一区二区中文字幕| 久久涩综合一区二区三区| 久久婷婷综合色丁香五月| 日本一卡2卡3卡四卡精品网站| 成人福利国产午夜AV免费不卡在线 | 乱女乱妇熟女熟妇综合网| 国产精品美腿一区在线看| 精品国产肉丝袜在线拍国语| 亚洲高请码在线精品av| 亚洲日韩久热中文字幕| 不卡乱辈伦在线看中文字幕| 高清日韩一区二区三区视频 | 国产av一区二区三区| 狠狠躁夜夜躁无码中文字幕 | 国产成人亚洲精品狼色在线| 亚洲欧美日韩愉拍自拍美利坚| 久女女热精品视频在线观看| 国产精品中文字幕视频| 国产日韩av二区三区| 蜜臀av在线一区二区三区| 久久不见久久见免费影院www日本| 人人爽人人爽人人片av东京热| 久久精品国产亚洲AⅤ无码| 高清美女视频一区二区三区|