JenkinsのMultibranch-pipelineをSubversionで使う

はじめに
------

Multibranch-pipelineをSubversionで使おうとしたらうまくいかなくて苦労したので解決策を書く。
こういう風にしか解決できなかったが、絶対間違っていると思うので正しい書き方を知っている人がいたら教えてほしい。

何をしたかったか
------

こういうプロジェクトがあったとして、すべてのブランチでmvnコマンドを実行したい。

### ブランチ

```
SomeProject
  +- trunk
  +- branches
     +- branch1
     +- branch2
```

### プロジェクト概要

- javaのコマンドラインプログラム
- mavenビルド
  - jarファイル生成
- profileは3つ
  - dev
  - test
  - prod


解決した書き方
------

```
pipeline {
  agent any
  tools {
    maven "maven3_current"
    jdk "jdk8_current"
  }
  stages {
    stage('チェックアウト') {
      steps {
        checkout([
            $class: 'SubversionSCM',
            additionalCredentials: [],
            excludedCommitMessages: '',
            excludedRegions: '',
            excludedRevprop: '',
            excludedUsers: '',
            filterChangelog: false,
            ignoreDirPropChanges: false,
            includedRegions: '',
            locations: [
                [
                    cancelProcessOnExternalsFail: true,
                    credentialsId: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx',
                    depthOption: 'infinity',
                    ignoreExternalsOption: true,
                    local: '.',
                    remote: 'http://subversion.server.host.com/svn/SomeProject'
                ]
            ],
            quietOperation: true,
            workspaceUpdater: [
                $class: 'UpdateWithCleanUpdater'
            ]
        ])
      }
    }
    stage('Mavenビルド') {
      steps {
        sh script: '''
            for pom in `find . -name "pom.xml"`; do
                mvn clean -f ${pom}
                mvn package -f ${pom} -Pdev
                mvn package -f ${pom} -Ptest
                mvn package -f ${pom} -Pprod
            done
        '''
      }
    }
    stage('成果物の保存') {
      steps {
        archiveArtifacts artifacts: '**/target/SomeProject*.jar', fingerprint: true, onlyIfSuccessful: true
      }
    }
  }
}
```

どこで詰まったのか
------

当初の書き方はこう。

```
    stage('Mavenビルド') {
      steps {
        sh "mvn clean package -Pdev,test,prod"
      }
    }
    stage('成果物の保存') {
      steps {
        archiveArtifacts artifacts: 'target/SomeProject*.jar', fingerprint: true, onlyIfSuccessful: true
      }
    }
```

何が悪かったか。

### 1. pom.xmlが見つからない

checkoutするのはSomeProjectだが、pom.xmlがあるのはSomeProject/trunkの下。
当初の書き方だとpom.xmlが見つからない、と怒られる。
=> pom.xmlがあるディレクトリにcdするか、"-f pom.xml"で指定する必要がある。"-f pom.xml"で指定する方法を採用。


### 2. stepsに繰り返し処理を書く構文が分からない

1.をtrunk,branches/branch1,branches/branch2で実行するには、pom.xmlを見つけ、それぞれmvnコマンドを実行する、という繰り返し処理を書く必要がある。
ところがその構文が見つからない。
=> シェルのforを使うことに。

正しい構文を教えてください...


### 3. stepsのshにシェルの構文を書けない

2.でシェルの繰り返し構文を使うことにしたので、stepsにfor文を書く必要がある。
で、以下の書き方はエラーになる。

```sh
sh "for pom in `find . -name "pom.xml"`; do mvn clean -f ${pom}; mvn (略); done"
```
=> シェルの構文をそのまま使うには sh script: "シェル" と書かなければいけない。


### 4. プロファイルをまとめて指定できない

以下の書き方は正しいはずだが、1つのプロファイルの成果物しか生成されない。

```
mvn clean package -Pdev,test,prod
```
=> 1コマンドずつ分解した

jenkinsを使わないで手で打つと意図したとおりに成果物が生成される。
原因は分かっていない。
これも誰か教えてください...


### 5. 成果物が見つからない

これは簡単だった。
targetディレクトリがあるのはSomeProject/trunkの下だから見つからないに決まっている。
=> ワイルドカードで階層ディレクトリを指定。trunkとbranches/branch1では階層が異なるので"*/target"はダメで"**/target"としなければいけない。


結論
------

SubversionをやめてGitを使おう。
(ぇー)