Azure Devops (Pipelines) でテスト、ビルド、イメージプッシュをする

# はじめに

記載情報は CI/CD に関連します。  
実務上関わった環境・機能を身近な情報としてお届けしたく、投稿をはじめました。  
各学習上、お金のかからない方法を選択していきます。

以下の手順を実施することで、パイプラインからのテスト、ビルド、イメージプッシュをできるようにします。

## 対象者と関連環境・機能

この記事は下記のような人を対象にしています。

- CI/CD 初学者
- プログラミング初学者
- 駆け出しエンジニア

記載している環境・機能は以下です。

- Azure Devops
- Azure Pipelines
- Java
- Gradle
- Docker

## 本記事の趣旨

必要処理をべた書きしているのみにつき、あくまでも動かす過程の参考程度の情報です。  
本記事では「こんなこといちいち手順みながらサーバ上でシェル叩くのか？」といったあたりについての解消の一助になれば、といった意図でのご紹介とさせていただきます。  
最終的に「Azure-Pipelines がベストな方法か？」といえば、必ずしもそうではないです。  
利用までのハードルが低めで助かる印象もありますが、Azure-Pipelines 固有のタスク挙動に振り回された挙句、別ツールでの自動化案も出るような場合、結局各タスクはシェルスクリプトとして別に切り出しておいた方が汎用性はあります。（ログ出力とかも自前で工夫する形と思いますが、そこ含めて何が自環境にあっているか、の判断になると思います。）  
自動化の方法が複数ある中で、一番楽できそうな（コストが下がりそうな）方法抽出判断の参考になっていたら幸いです。

| 対象               | 判断                                                                                                   |
| ------------------ | ------------------------------------------------------------------------------------------------------ |
| 横展開、量産の有無 | 対応の必要があり次第、対応のしやすさがコストに直結                                                     |
| 作業者の手間       | 開発者には開発に注力してもらう必要があるので、即座に、繰り返し実行しやすいことが重要                   |
| 運用側の手間       | 開発側に作業環境連携して手順送って、使い方について問い合わせもまあまあ来る、という事態を避けられそうか |

## 準備

今回は github 上のパイプラインを Azure Pipelines から実行します。  
下記が準備となりますが、振り返りが不要な場合にはお読み飛ばしください。

- [Azure Devops (Artifacts) を無償、無料で使う](https://qiita.com/wf-kenji-ikeda/items/9c21859d8b5b6a63246e)
- [Spring Tool Suite 4 インストール、Spring Initializr 、gradlew の利用](https://qiita.com/wf-kenji-ikeda/items/d00766da8a4076ec43ed)
- [Spring Boot Web アプリケーションを作る](https://qiita.com/wf-kenji-ikeda/items/1e64e44094ce8a1d997f)
- [Jar の Library を作り、Azure Artifacts を利用して成果物を配布する](https://qiita.com/wf-kenji-ikeda/items/696bda335a8933abfcb3)
- [ライブラリ開発者より指定されたバージョンを利用してアプリを作る](https://qiita.com/wf-kenji-ikeda/items/5bf06ce19c52e73a5463)
- [アプリを Docker 、Docker Compose でコンテナを動かしてみる](https://qiita.com/wf-kenji-ikeda/items/e6604ea6ae257f3925a7)
- [Azure Devops (PileLines) を無償、無料で使う](https://qiita.com/wf-kenji-ikeda/items/451838da3b4ac45a8d65)

### ソース

本作業で利用するパイプラインとなります。  
[azure-Pipelines](https://github.com/oad3/application-springboot/blob/main/pipelines/20_application-springboot/20_application-springboot-build.yml)

20_application-springboot-build.yml

```Azure Pipelines
trigger:　※パイプラインを起動するトリガーの設定。本サンプルでは手動での実行のみを想定。
  - none

parameters:
  - name: BuildTag
    displayName: BuildTag (ex x.x.x)  ※現場ではBuildTagが自動でカウントアップされる仕組みにより、どういう結果であれ履歴保持されます。ここでは一旦最短でパラメータ渡し。
    type: string
    default: ""

pool:
  vmImage: "ubuntu-latest"　※MS提供のVMでパイプライン実行を行う。

resources:
  repositories:
  - repository: 'application-springboot'　※githubからとってくる対象リポジトリ
    type: github　※githubからとってくる
    ref: main　※githubからとってくるブランチ
    endpoint: '20220501'　※作成したサービスコネクション名
    name: 'oad3/application-springboot'　　※githubからとってくる対象リポジトリ

stages:
  - stage: BuildStage
    jobs:
      - job: BuildJob
        displayName: "Gradle Build And Docker Build Push"
        continueOnError: false
        workspace:
          clean: outputs
        steps:
          - checkout: self　※パイプラインを置いているリポジトリ。必要に応じてチェックアウト
          - checkout: application-springboot　※ビルド対象リポジトリ。
          - bash: |
              echo $JAVA_HOME_11_X64　※MS提供のubuntuイメージ上におけるJAVA11のパス
          - task: Gradle@2
            displayName: Gradle Build and Test
            inputs:
              gradleWrapperFile: "./application-springboot/gradlew"　※ビルド対象リポジトリ配置したgradlewを利用してビルド。gradleバージョンを自分でコントロール可
              workingDirectory: "./application-springboot"　※作業ディレクトリ
              tasks: "build test"　※gradleに「buildとtestタスクを実行せよ」との指示
              publishJUnitResults: true　※JUnitで試験した結果をパブリッシュ
              testResultsFiles: "**/TEST-*.xml"　※JUnitで試験した結果をパブリッシュ
              javaHomeOption: "path"　※利用するJAVAはパスを指定するから、それでビルド
              jdkDirectory: "$(JAVA_HOME_11_X64)"　※「javaHomeOption == Path」のときに指定必須。ここのでビルド
              sonarQubeRunAnalysis: false　※現場ではsonarQubeもつかっているけれどここでは省略。静的解析
              spotBugsAnalysis: false　※現場ではspotBugsもつかっているけれどここでは省略。静的解析
            env:
              SYSTEM_ACCESSTOKEN: "$(System.AccessToken)"　※今回は省いてしまっているがビルド成果物をパブリッシュするときには利用
          - bash: |
              ls -la ./application-springboot/build/libs/
          - task: Docker@2　※Docker login
            displayName: Login to Docker Hub
            inputs:
              command: login
              containerRegistry: "DockerRegistryServiceConnection"
          - task: Docker@2　※Docker Build and Push
            displayName: Docker Build and Push
            inputs:
              Dockerfile: "./application-springboot/Dockerfile"
              command: buildAndPush
              repository: "oad3jp999/application-springboot"
              tags: "${{ parameters.BuildTag }}"
          - task: Docker@2　※Docker logout
            displayName: Logout of Docker Hub
            inputs:
              command: logout
              containerRegistry: "DockerRegistryServiceConnection"

```

### github 上のパイプラインを実行出来るようにサービスコネクション(Service connections)を作成する

- github への接続認証のため、事前に[個人アクセストークン](https://docs.github.com/ja/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token)を取得します。
- github の個人アクセストークン取得後、サービスコネクションを作成作成します。
![ServiceConnections_001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2738816/f6f95aeb-4c0f-45a1-266e-3cc52999e0d6.png)
![ServiceConnections_002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2738816/ba24e7a8-b812-a906-03f6-c7ea67f1e752.png)
![ServiceConnections_003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2738816/e3376963-8535-d762-7f68-f5740f4b2c90.png)

### Docker Hub にイメージプッシュ出来るようにサービスコネクション(Service connections)を作成する

- 前提作業  
  [Docker Hub アカウントの登録](https://docs.docker.jp/docker-hub/accounts.html#registration-for-a-docker-hub-account)  
  [Docker Hub にログイン](https://docs.docker.jp/docker-hub/accounts.html#login)
![ServiceConnectionsDockerHub_001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2738816/afbc2e23-6333-3cf4-11e4-81dafb768482.png)
![ServiceConnectionsDockerHub_002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2738816/d32db7f4-205e-84f8-915b-74ee86bc64f4.png)
![ServiceConnectionsDockerHub_003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2738816/f7ebe1e8-546e-b43f-1a7b-798791877c78.png)

### 作成したサービスコネクション(Service connections)を利用して、パイプラインを実行する

★★★ 要注意 ★★★  
MS Hosted VM の利用申請が通っていないとパイプライン実行まで一日では終わらない可能性がありますが、少々腰を据えて準備ください。  
※ご参考 　
[Azure Devops (PileLines) を無償、無料で使う](https://qiita.com/wf-kenji-ikeda/items/451838da3b4ac45a8d65)

## 実行結果

- Gradle での Build と Test に成功
![CreateBuildPipeline_001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2738816/e044f6d5-eadc-ba71-a62c-17f4bf3c658b.png)

- Docker イメージの Build と Push に成功
![CreateBuildPipeline_002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2738816/e6e0b22f-0cbb-7035-56a3-24599488902f.png)

- Junit の結果がパブリッシュされている
![CreateBuildPipeline_003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2738816/6d9bf30c-e000-c6f6-b21f-5dfb92bc8fd8.png)

- Docker イメージ登録状況
![CreateBuildPipeline_004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2738816/af6aa396-a02a-4d2c-26f1-83b9c50a7eb2.png)

## 関連記事

- [CI/CD とは?](https://qiita.com/wf-kenji-ikeda/items/bfb6d5e21b33d0cca83b)
- [Azure Devops (Artifacts) を無償、無料で使う](https://qiita.com/wf-kenji-ikeda/items/9c21859d8b5b6a63246e)
- [Spring Tool Suite 4 インストール、Spring Initializr 、gradlew の利用](https://qiita.com/wf-kenji-ikeda/items/d00766da8a4076ec43ed)
- [Spring Boot Web アプリケーションを作る](https://qiita.com/wf-kenji-ikeda/items/1e64e44094ce8a1d997f)
- [Jar の Library を作り、Azure Artifacts を利用して成果物を配布する](https://qiita.com/wf-kenji-ikeda/items/696bda335a8933abfcb3)
- [ライブラリ開発者より指定されたバージョンを利用してアプリを作る](https://qiita.com/wf-kenji-ikeda/items/5bf06ce19c52e73a5463)
- [アプリを Docker 、Docker Compose でコンテナを動かしてみる](https://qiita.com/wf-kenji-ikeda/items/e6604ea6ae257f3925a7)
- [Azure Devops (PileLines) を無償、無料で使う](https://qiita.com/wf-kenji-ikeda/items/451838da3b4ac45a8d65)
- [Azure Devops (PileLines) でテスト、ビルド、イメージプッシュをする](https://qiita.com/wf-kenji-ikeda/items/5ddf6158bb98c4174db9)
- [minikube(kubernetes) でコンテナを動かしてみる](https://qiita.com/wf-kenji-ikeda/items/95604d83850a17b91c46)
- [nginx のコンテナを Docker や minikube(kubernetes) で動かし、静的コンテンツ公開工程を模倣](https://qiita.com/wf-kenji-ikeda/items/bf6cb1b7a047f562d309)

## 参考記事

[Azure Pipelines を無料枠で使おうとして躓いた話](https://qiita.com/Hachiyou-Renge/items/2083f2ce9e8b38558805)  
[Azure Pipelines エージェント](https://docs.microsoft.com/ja-jp/azure/devops/pipelines/agents/agents?view=azure-devops&tabs=browser)