web-dev-qa-db-ja.com

Jenkins Pipeline Shared Libraryを同じリポジトリからロードする

TL; DR Jenkinsfileローカルからリポジトリ(loadステップ以外)にコードをインポートする方法はありますか?

どうして?

複雑なビルドの場合、Jenkinsfileがかさばり、メンテナンスが難しくなることを経験しました。
ビルドジョブはコードであるため、他のコードと同じ手段をとることは素晴らしいことです。つまり、それをより小さな(より保守しやすい)ユニットに分割し、nit testそれらにしたいと思います。

私が試したもの

  • 共有ライブラリ :Jenkins Pipelineロジックを別のモジュールで小さなファイルに分割し、さらに単体テストすることもできます。
    ただし、それらは別のリポジトリに存在する必要があり(GitHubにない場合)、Jenkinsに設定する必要があります。
  • load St​​ep :groovyのロードを許可scriptsリポジトリから。
    ただし、ファイルは「完全な」groovyクラスではなくスクリプトである必要があり、相互に依存する複数のファイルまたはクラスを持つことは困難です。たとえば、継承は不可能です。
    さらに、Jenkinsジョブで replay を実行すると、これらのファイルは表示されないため、開発とデバッグが困難になります。

私の質問

  • Jenkinsfileと同じリポジトリに共有ライブラリを作成し、このライブラリをJenkinsfileにインポートする方法(または回避策)はありますか?
  • または、まだ試したことのない別の方法がありますか?

ディレクトリ構造の例

shared libs について説明したディレクトリ構造と同様に、次の単一のリポジトリ内が必要です。

(root)
+- someModule
|   +- ...
+- jenkins           # Classes/Scripts used by Jenkins in a separate module
|   +- src                       # Groovy source files
|      +- org
|          +- foo
|              +- Bar.groovy     # for org.foo.Bar class
|   +- test                      # Groovy test files
|      +- org
|          +- foo
|              +- BarTest.groovy # Test for org.foo.Bar class
|   +- pom.xml or build.groovy   # Build for local library
+- Jenkinsfile     # Build "someModule", uses classes from "jenkins" module
21
schnatterer

回避策:

library identifier: 'shared-library@version', retriever: legacySCM(scm)

PR 37 で現在採用されているアプローチは、ビルドエージェントでは適切に機能せず、とにかく@Libraryアノテーションではなくlibraryステップを使用するスクリプトでのみ機能します。

ちなみに、loadステップからロードされたファイルdoReplayに表示されます。しかし、そのようなファイルで定義されている型をスクリプトが静的に参照できないことは事実です。つまり、ライブラリvars/*.groovyをシミュレートできますが、src/**/*.groovyはシミュレートできません。これは、現在のPR 37と同じ制限です。

6
Jesse Glick

そのための適切な方法は、カスタムSCMRetrieverを実装することだと思います。

ただし、次のハックを使用できます。

jenkins/vars/log.groovyローカルリポジトリの内容:

def info(message) {
    echo "INFO: ${message}"
}

Jenkinsfileは、その共有ライブラリをjenkins/libraryステップを使用したディレクトリ:

node('node1') { // load library
    checkout scm
    // create new git repo inside jenkins subdirectory
    sh('cd jenkins && git init && git add --all . && git commit -m init &> /dev/null') 
    def repoPath = sh(returnStdout: true, script: 'pwd').trim() + "/jenkins"
    library identifier: 'local-lib@master', retriever: modernSCM([$class: 'GitSCMSource', remote: repoPath])
}

node('node2') {
    stage('Build') {
        log.info("called shared lib") // use the loaded library
    }
}
4
Pawel Wiejacha

パイプラインが共有ライブラリであるレポのサブディレクトリの使用を可能にする、私が書いたプラグインを見ることができます: https://github.com/karolgil/SharedLibrary

ビルドしてインストールしたら、次のようにパイプラインに追加するだけです。

@SharedLibrary('dir/in/repo') _

パイプラインの共有ライブラリとしてdir/in/repoの使用を開始するには。

3
Karol Gil

同じことをしたいと思い、これを作成することになりました:

https://github.com/jenkinsci/workflow-cps-global-lib-plugin/pull/37

ここに私がそれを使用する方法があります:

https://github.com/syndesisio/syndesis-pipeline-library/blob/master/Jenkinsfile#L

私の場合、リポジトリに含まれるパイプラインライブラリを実際にtestsするJenkinsfileを作成したかったのです。

ご意見をお聞かせください。また、PRについてもコメントをお気軽にお寄せください。

2
iocanel

SCM(JenkinsジョブUI構成に埋め込まれていない)からパイプラインをチェックアウトしている場合、Pawelのバージョンに問題があることがわかりました。これはそれらの場合の私のバージョンです:

node {
    def jenkinsDir = sh(returnStdout: true, script: 'pwd').trim().replaceAll('(.*)(@[0-9]*$)', '$1') + "@script/jenkins"
    ssh("cd ${jenkinsDir} && ls -l vars/ && if [ -d .git ]; then rm -rf .git; fi; git init && git add --all . && git commit -m init &> /dev/null")
    library identifier: 'local-lib@master', retriever: modernSCM([$class: 'GitSCMSource', remote: jenkinsDir])

    stage('Build') {
        log.info("called shared lib") // use the loaded library
    }
}

これらの場合、パイプライン自体は別のワークスペースでチェックアウトされます(同じディレクトリ名ですが、@scriptは、パイプライン自体が実行される場所(およびコードもチェックアウトされる場所)よりも。

「jenkins」ディレクトリは、パイプラインがチェックアウトされているワークスペースでのみ使用可能です(少なくとも「vars」フォルダーを含む最新バージョンで)。別のブランチ)。

0
lqbweb