AppVeyorでMavenプロジェクトのCI

以下の記事で作ってきたMaven+Javaのプロジェクトを、CIで回そうと思って調査したので覚書です。
https://qiita.com/kasa_le/items/db0d84e3e868ff14bc2b

# AppVeyor

こちらから登録できます。
https://www.appveyor.com/

## 特徴

基本的には、Windows上というか、VisualStudioでビルドすることが主目的のようです。

GithubやGitLab, Bitbucket以外のGitにも繋ぐことができます。
(※ただし、ちょっとした制約が発生します。後述)
また、SSHにGitで繋ぐ必要があったのですが、これもAppVeyorなら対応しています。

キャッシュにも対応しています。

OSイメージにはmacOS(Catalina, Majave)やUbuntuもありますが、Mavenビルド用のテンプレートとかそういったものがなく、いろいろと苦労しました。

## 料金

オープンソースなら無料。
それ以外は、基本的に月額課金です。
稼働が高そうで、でも期限が切られているプロジェクトならば、コスト見積もりがしやすいので良いかもしれません。チームメンバー数については特に言及がないので、制限はないかと思います。
https://www.appveyor.com/docs/team-setup/

## 実績
Windowsで使い勝手の良いテキストエディタといえばサクラエディタが有名ですが、AppVeyorを使われているようです。(Azure Pipelinesと併用のようです)

# 設定

基本的にには、プロジェクトのルート直下に`appveyor.yml`というファイルを置くことでCIジョブを定義していきます。

## 1.MSビルド設定を変更する

まず最初にやることは、ビルドがMSビルド(VisualStudio向け)になっているので、ブラウザ上からその設定を解除する必要があります。

- プロジェクトページを開き、[Settings]タブの[Build]を選ぶ

|<img width="580" alt="appveyor_msbuild_off.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103886/d3c1f498-8428-c48d-af9a-36d9e9542f5d.png">|
|:--|

- [MSBuild]の隣の、[Script]を選ぶ

|<img width="876" alt="appveyor_script_select.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103886/a3011964-f3ee-9948-29a3-dcea4b4a9390.png">|
|:--|

- [Save]をクリック

これで準備が終了です。

## 2.`appveyor.yml`を作成する
とりあえず、最終的にビルドとテストがうまく行った`appveyor.yml`はこちらです。

```appveyor.yml
# Branches
branches:
  only:
  - feature/for_ci_test
image: ubuntu

install: 
- sh: sudo add-apt-repository --yes ppa:rpardini/adoptopenjdk
- sh: sudo apt-get update
- sh: sudo apt-get install -y adoptopenjdk-11-jdk-hotspot-installer
- sh: sudo apt install adoptopenjdk-11-jdk-hotspot-set-default
#/usr/lib/jvm/adoptopenjdk-11-jdk-hotspot
- sh: export JAVA_HOME=/usr/lib/jvm/adoptopenjdk-11-jdk-hotspot
- sh: echo $JAVA_HOME
- sh: export PATH=${PATH}

before_build:
- mvn -v

build_script:
- mvn clean package -DskipTests

test_script:
- mvn install verify

on_finish:
  - sh: |
      find "$APPVEYOR_BUILD_FOLDER" -type f -name 'TEST*.xml' -print0 | xargs -0 -I '{}' curl -F 'file=@{}' "https://ci.appveyor.com/api/testresults/junit/$APPVEYOR_JOB_ID"
      
artifacts:
  - path: "**/target/*.?ar"

version: "1.1.{build}"
```

以下のような内容になっています、

- `branches`セクション
  - `feature/for_ci_test`ブランチでのみ実行
- OS
  - ubuntu
- `install`セクション
  - adoptopenjdk-11をインストールし、パスを設定
    - `stack: jdk 11`としてもJDK11を設定できるが、乗っているJDKのバージョンが古くバグが解消されていないため、別途インストールが必要でした
    - パスを無理やり設定しているのは、他のバージョンを切り替える方法がうまく行かなかったからです。
- `before_build`セクション
  - Mavenのバージョンを確認
- `build_script`セクション
  - mvn ビルド(JUnitテストをスキップ)
- `test_script`セクション
  - mvn コマンド(テストあり)
- `on_finish`セクション
  - JUnitのテストレポートをレポートページにアップロード
- `artifacts`セクション
  - `*.jar`と`*.war`をアーティファクトとして保存
- `version`セクション
  - ビルドバージョンの設定 

これを、プロジェクトのルート直下において、コミット、pushすると、CIが走り始めます。

キャッシュができるので、Javaのフォルダを対象にしておいてもいいかもしれませんね。
その場合、キャッシュの有無でjdkをインストールするかどうかを決めるようにshコマンド部分を書き換える必要があります。

# Gitリポジトリサービス以外のGitに繋ぐ場合の注意

Githubリポジトリでは、上記の`appveyor.yml`を置いたらそれを使ってビルドしてくれたのですが、GithubやGitLab,Bitbucketなどのリポジトリサービス**以外**のGitに繋ぐ場合(例えば、自社で立てているGitサーバーなど)は、プロジェクトに置いてある`appveyor.yml`
は全く見てくれないようでした。

一応、同じような設定を、ブラウザ上から設定できるのですが、ページがまたがってあちこちで設定しなければならなかったり、かゆいところには手が届かなく、かなり手間でしたので、使用を検討する場合は注意が必要です。

# 感想

もとがVisualStudioでのビルド向けということで、やはりC#などのプロジェクト向けで、それ以外にはあまり注力されていない印象でした。
素直に、それらのテンプレートが豊富なCIサービスを検討したほうが良いと思いました。

それと、自分のサンプルプロジェクト(JerseySample)はビルド、テストともに通ったのですが、同じ環境で動く別のプロジェクトは、以下のような状態で、結局通すことができませんでした。

|OSイメージ|現象|
|:--|:--|
|Windows上|Mavenビルド中にクラッシュするのか`Exit 1`してしまう|
|macOS上|Mavenビルド中に応答しなくなるのかビルドが永遠に終わらない状態になってしまう|
|Ubuntu上|テストの途中でクラッシュするのか`Exit 1`してしまう(※手元のUbuntu上ではビルドもテストも正常終了する|