【初心者向け】bitbucket-pipelinesのキーワードとTips

Ola!!
SET（Software Engineer in Test）Gの@mochioです。
みなさんはCI/CDやってますか！？

CIツールといえば「CircleCI」や「Jenkins」が有名だと思いますが、
ここではAtlassian謹製の「**bitbucket-pipelines**」を紹介したいと思います。

[fukabori.fmのCI/CDの回](https://fukabori.fm/episode/7)でも話されていたとおり、
開発フローの**序盤で導入する**のが一番効果的だと思ってます。

導入に関しては[こちらの記事](https://qiita.com/bbq-all-stars/items/10776d36f72e7d497c2e)を参考にしていただければと思います。

# キーワードとは
CIの設定はbitbucket-pipelines.ymlにyaml形式で書いていくのですが、
キーワードはそのパイプライン（操作の流れ）において**何を行うか**を記述するものになります。
yaml上ではkeyにあたる部分です。
よく使うものをリストアップして使用例とともに紹介します。

## image
CI・CDを回すコンテナイメージを指定します。
Docker Hubで公開されているイメージを使用したり、
プライベートイメージも使ったりできます。
すべてのstepで同一のイメージを使う場合は一番上に記述すれば良いです。
step以下に記述することもでき、使用するimageを分けることもできます。

#### 使用例

```yaml:Docker&nbsp;Hub
image: python:3.6

pipelines:
  default:
    - step:
```

```yaml:Docker&nbsp;Hub(Private)
image: python:3.6
  name: account-name/watashino-openjdk:8
  username: $DOCKER_HUB_USERNAME
  password: $DOCKER_HUB_PASSWORD
  email: $DOCKER_HUB_EMAIL

pipelines:
  default:
    - step:
```
```yaml:Amazon&nbsp;Container&nbsp;Registory
image: python:3.6
  name: <aws_account_id>.dkr.ecr.<region>.amazonaws.com/openjdk:8
  aws:
    access-key: $AWS_ACCESS_KEY
    secret-key: $AWS_SECRET_KEY

pipelines:
  default:
    - step:
```
```yaml:step毎にimageを分けたい
pipelines:
  default:
    - step:
        image: python:3.6
    - step:
        image: ruby:2.5
```
$変数名はbitbucket側で環境変数として設定することができる変数になります。
センシティブな情報は全部そちらで管理しましょう。
管理方法は[こちら](https://qiita.com/masakuni-ito/items/009a264c772006729e76#%E7%92%B0%E5%A2%83%E5%A4%89%E6%95%B0%E3%81%AE%E8%A8%AD%E5%AE%9A)を参照してください。

## pipelines
パイプラインを定義します。
pipelines以下にstepを宣言して、実行の詳細を記述していきます。

## step
stepを宣言してから操作を記述していきます。

#### 使用例

```yaml
image: ruby:2.5

pipelines:
  default:
    - step:
        script: echo "unittestします"
    - step:
        script: echo "rubocopかけます"
```

## default
defaultを宣言すると、すべてのブランチがCIの実行対象となります。
実行されるタイミングはブランチのpush時です。

#### 使用例

```yaml
image: python:3.6
 
pipelines:
  default:
    - step:
        script: echo "全部のブランチ対象だよー"
```

## branches
特定のブランチをCIの実行対象とすることができます。
アスタリスクを使うこともできます。

#### 使用例

```yaml:developブランチを指定するとき
image: python:3.6
 
pipelines:
  branches:
    develop:
      - step:
          script: echo "developだけですよ"
```
```yaml:featureブランチを指定するとき
image: python:3.6
 
pipelines:
  branches:
    feature/*:
      - step:
          script: echo "featureがつくブランチが対象です"
```
## tags
特定のgitタグに紐づくブランチを指定できます。

#### 使用例

```yaml
image: python:3.6
 
pipelines:
  tags:
    enhancement:
      - step:
          script: echo "enhancementタグがついているブランチのみです"
```

## parallel
並列でJobを実行したいときに使います。

#### 使用例
```yaml
image: ruby:2.5

pipelines:
  default:
    - parallel:      # 以下のスクリプトは並列実行されます！
        - step:
            name: Integration 1
            script:
              - ./integration-tests.sh --batch 1
        - step:
            name: Integration 2
            script:
              - ./integration-tests.sh --batch 2
```

## name
stepに名前をつけることができます。
テスト実行、静的解析実行、デプロイ実行など場合によって分けたいですね。

#### 使用例
```yaml
image: ruby:2.5
 
pipelines:
  branches:
    develop:
      - step:
          name: Execution unit testing
```

## trigger
上の方でpush時に実行されると言いましたが、
triggerを使えばマニュアル実行に変更することもできます。
デプロイタスクなどはこちらにしたほうが良いかもしれません。
triggerを使用しない場合はauto（pushがトリガー）になるので注意。

#### 使用例
```yaml
image: ruby:2.5
 
pipelines:
  branches:
    develop:
      - step:
          trigger: manual
          name: deploy
          script: sh deploy_shimasu.sh
```
## deployment
デプロイステップには使うようにしましょう。
deploymentsダッシュボードで扱えるようになります。
deploymentsの詳細に関してはまた別記事に書こうかなーと思ってます。
#### 使用例
```yaml
image: ruby:2.5
 
pipelines:
  branches:
    develop:
      - step:
          deployment: test
          script: echo "start test deploy"
```

## size
使用するコンテナのサイズを変更できます。
1xもしくは2xが使えるようです。
2xにした場合**ビルド時間も二倍でカウントされる**ので注意
（bitbucketはCircleCIと課金体系がちょっと違い、ビルド時間に対して料金が変動します。）
#### 使用例
```yaml
image: ruby:2.5
 
pipelines:
  branches:
    develop:
      - step:
          size: 2x
          script: echo "start many tests"
```
## script
コンテナ内で実行したいコマンドを記述します。

#### 使用例
```yaml
image: rails:5.0.1
 
pipelines:
  branches:
    develop:
      - step:
          script: rspec spec/
```
## artifacts
stepでの成果物を後のstepで使用するために使います。

#### 使用例
```yaml
image: python:3.6
 
pipelines:
  branches:
    develop:
      - step:
          script: rspec spec/ –format html:test_result.html
          artifacts: test_result.html
      - step:
          name: report test result
```

## options
パイプラインすべてに適用できるオプションを設定します。
現状max-timeしかないようです。

## max-time
max-timeは一つのstepの最大時間を設定できます。
単位は分なので注意

#### 使用例
```yaml
options:
  max-time: 60
pipelines:
  default:
    - step:
        name: Sleeping step
        script:
          - sleep 120m
    - step:
        name: quick step
        max-time: 5
        script:
          - sleep 120m #this step will timeout after 5 minutes
```
上の例のようにstep内に記述することでoptionに記述したものの掛け算をして使うことができます。

## clone
コンテナにクローンするときの設定を記述します。

## depth
depthはどこまでのコミットを含めてクローンしてくるかを設定できます。
デフォルトは50です。

#### 使用例
```yaml
clone:
  depth: 5       # include the last five commits
  
pipelines:
  default:
    - step:
        name: Cloning
        script:
          - echo "Clone all the things!"
```

## definitions
複数コンテナを連動させたいときや、キャッシュをとっておきたいときはdefinitionsで定義します

## services
複数コンテナを連動させて使いたいときはservicesで名前を定義してパイプラインで使うことができます。

#### 使用例
```yaml
pipelines:
  branches:
    master:
      - step:
          image: redis
          script:
            - redis-cli -h localhost ping
          services:
            - redis
            - mysql
definitions:
  services:
    redis:
      image: redis:3.2
    mysql:
      image: mysql:5.7
      environment:
        MYSQL_DATABASE: my-db
        MYSQL_ROOT_PASSWORD: $password
```

## caches
ビルドの度に依存関係を毎回インストールするのは、時間もかかりますし料金もかかります。
cachesを使うことでキャッシュをとっておくことができます。

#### 使用例
```yaml
image: ruby:2.4.0
pipelines:
  default:
    - step:
        caches:
          - bundler #cache is defined below in the definitions section
        script:
          - bundle install --path vendor/bundle

definitions:
  caches:
    bundler: vendor/bundle
```

# Tips
## ビルドコンテナ内からサーバにssh接続をしたいとき
CI自体はbitbucketが管理するクラウド上のコンテナで動きます。
そのため、デプロイ先のサーバ内でなにかしらのスクリプトを動かしたいときは、
そのコンテナから接続できるようにする必要があります。

1. 「設定」→「PIPELINES」→「SSH keys」
<img width="485" alt="スクリーンショット 2018-12-18 13.49.56.png" src="https://qiita-image-store.s3.amazonaws.com/0/156024/44aa90b3-2175-ff43-7240-e6d4277d7120.png">
2. Generate Keys
<img width="817" alt="スクリーンショット 2018-12-18 13.51.38.png" src="https://qiita-image-store.s3.amazonaws.com/0/156024/289b2e42-a4c7-759c-ae33-492559ec8688.png">
3. 公開鍵が発行されるので、デプロイ先のサーバ内で公開鍵認証設定をする。
https://qiita.com/nnahito/items/dbe6fbfe347cd66ae7e6
4. 接続！

ちなみにsshのオプションでよくやる「-i .ssh/kagidayo.pub」みたいな指定は要りません。
bitbucketがうまくやってくれます。

## デプロイ先サーバにIP制限をかけたい
CircleCIだとIPが公開されていないので、
cliを使ってごにょごにょやる必要があり少し手間ですよね。
bitbucket-pipelinesだと[こちら](https://confluence.atlassian.com/bitbucket/what-are-the-bitbucket-cloud-ip-addresses-i-should-use-to-configure-my-corporate-firewall-343343385.html)にbitbucket cloudのIPが公開されていますので、
接続許可設定をしてあげればよいです。

# まとめ
自分で作ったパイプラインが動いてグリーンになるのは面白いし気持ち良いので
CIをどんどん導入していきましょう！
次回は実践編を書きたいと思います！

明日は***食を愛し食に喰われた男***@suzu-4が何か伝えます。

Salud!!🌵 

# 参考/引用
https://ja.confluence.atlassian.com/bitbucket/configure-bitbucket-pipelines-yml-792298910.html