Jenkins による リリース & Git操作 & build 入門

##### Jenkins による リリース & Git操作 & build 入門

<img src="https://sekiyaeiji.github.io/image-storage/dist/img/about-jenkins/logo.png" width=30%>

---

# index

- [00. Jenkinsについて](https://qiita.com/sekiyaeiji/items/5a09cd926b88d63b6490#00-jenkins%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6)
- [01. シェルコマンド](https://qiita.com/sekiyaeiji/items/5a09cd926b88d63b6490#01-%E3%82%B7%E3%82%A7%E3%83%AB%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89)
- [02. gitコマンド](https://qiita.com/sekiyaeiji/items/5a09cd926b88d63b6490#02-git%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89)
- [03. 設定](https://qiita.com/sekiyaeiji/items/5a09cd926b88d63b6490#03-%E8%A8%AD%E5%AE%9A)
- [04. 「シェルの実行」のバリエーション](https://qiita.com/sekiyaeiji/items/5a09cd926b88d63b6490#04-%E3%82%B7%E3%82%A7%E3%83%AB%E3%81%AE%E5%AE%9F%E8%A1%8C%E3%81%AE%E3%83%90%E3%83%AA%E3%82%A8%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3)

---

# 00. Jenkinsについて

---

## Jenkinsとは

---

### 準備された仕事を指定されたタイミングで実行する箱

- 継続的インテグレーション（continuous integration）ツール
- アジャイル型開発での利用を前提に設計された
- on-premises（自社運用）型のため企業において一括管理しやすい
- 日本製で、作者は川口耕介氏 
- "ジョブ"と呼ばれる用途単位の機能を順次実行していくことで**Git操作**や**ファイル転送**を実行する
- 1つのジョブは、対象Gitブランチ設定やGitコマンド、シェルコマンドなどを設定することで1つの機能を担う構造になっている
- ジョブを一度作成すると実行時に機能の詳細内容を意識することなく反復利用できる
- 初期状態では、ジョブが何も与えられてない"からっぽのハコ"のようなもの

---

#### 川口耕介氏

<img src="https://sekiyaeiji.github.io/image-storage/dist/img/about-jenkins/kawaguchishi.jpg" width=20%>

---


## なぜCIツール

- 機械が得意なことを機械に任せる
  - 差分抽出
  - 反復作業
  - 転送設定
  - 高速リリース
  - テスト
- ローカルルールの撲滅
  - 本来創意工夫の必要のない作業
  - 属人的な要素の排除

<img src="https://sekiyaeiji.github.io/image-storage/dist/img/about-jenkins/flow.png" width=80%>

---


## その他のCIサービス

- [Circle CI](https://circleci.com/)
- [Travis CI](https://travis-ci.org/)
- 他多数．．．

<img src="https://sekiyaeiji.github.io/image-storage/dist/img/about-jenkins/ci-circleci.png" width=30%>

<img src="https://sekiyaeiji.github.io/image-storage/dist/img/about-jenkins/ci-travisci.png" width=30%>

---


# 01. シェルコマンド

---

Jenkins の Job でよく利用する シェルコマンド を紹介

---

### Jenkins 「シェルの実行」内容の例

```
#!/bin/bash

### 変数定義
# ホスト
HOST_REMOTE=［ホストの名前］

# パス
PATH_DIST=${WORKSPACE}/dist/
PATH_REMOTE=［リモートのパス］

# コマンド
RSYNC="rsync -rlcv --delete"


### ディレクトリ生成 （2回目の実行以降はコメントアウトする）
# echo -e "\n\n*** ディレクトリ生成 開始 ***"
# ssh $HOST_REMOTE mkdir -p $PATH_REMOTE
# echo -e "*** ディレクトリ生成 終了 ***\n"


### ファイル転送
if ${DRYRUN} ; then
  # dryrun
  echo -e "\n\n*** dryrun 開始 ***"
  $RSYNC -n $PATH_DIST $HOST_REMOTE:$PATH_REMOTE
  echo -e "*** dryrun 終了 ***\n\n"
else
  # deploy
  echo -e "\n\n*** deploy 開始 ***"
  $RSYNC $PATH_DIST $HOST_REMOTE:$PATH_REMOTE
  echo -e "*** deploy 終了 ***\n\n"
fi
```

---

### よく使うコマンド

- `echo`
- `rsync`
- `mkdir`
- `rm`
- `if then elif then else exit fi`
- `for do done`
- `test`
- `ls`
- `grep`
- `xargs`
- `#`
- `#!/bin/bash`

次章にてこれらを1つずつ確認する

---


## コマンド解説

---

### echo

---

文字列や変数の内容を表示する

- UNIXコマンドの1つ
- 文字通り「echo」の意味

---

#### よく使うオプション

|option|内容|
|:--|:--|
|`-e`|escapeの頭文字。エスケープ文字を有効にして表示する|

---

#### サンプルコード

```
echo -e "\n\n*** dryrun 開始 ***"
```

---

#### Work

##### 01

以下の動作の違いを確認しましょう

```
echo あいうえお
echo  あ\nい\nう\nえ\nお
echo -e あ\\nい\\nう\\nえ\\nお
echo  "あ\nい\nう\nえ\nお"
echo -e "あ\nい\nう\nえ\nお"
```

---

##### 02

変数の働きを確認しましょう


```
HOGE="あ\nい\nう\nえ\nお"
echo -e $HOGE
```

---

### rsync

---

テストサーバーや本番サーバーへのファイルアップロードにはおもに`rsync`を利用する

- UNIXソフトウェアの1つ
- 「remote sync」の意味
- 転送元パスの「/」の有無が挙動に影響するので**注意**が必要
- 転送元パスの「/hoge」はディレクトリ自身を含み、「/hoge/」はディレクトリの中身だけに作用する

---

#### よく使うオプション

|option|内容|
|:--|:--|
|`-r`, `--recursive`|指定したディレクトリの下層のディレクトリにも再帰的に実行する|
|`-l`, `--links`|ローカルのシステムと同様にリモートのシステムでシンボリック・リンクを再作成する|
|`-c`, `--checksum`|コピー先に同じチェックサムとサイズを持つ同名のファイルをスキップする|
|`-v`, `--verbose`|転送中の情報を詳しく表示する。このオプションは三つまで連記指定可能|
|`-n`, `--dry-run`|実際には実行しないで、実行したと仮定した場合の情報だけを表示する|
|`--delete`|コピー先に存在してコピー元に存在しないファイルを削除する|
|`--ignore-existing`|コピー先に存在するファイルは更新しない|
|`--include`|指定したファイルやディレクトリを対象に含む|
|`--exclude`|指定したファイルやディレクトリを対象に含まない|

---

#### サンプルコード

```
PATH_LOCAL=${WORKSPACE}/dist/
PATH_REMOTE=/hoge/
rsync -rlcv --delete $PATH_LOCAL $PATH_REMOTE
rsync -r -l -c -v --delete $PATH_LOCAL $PATH_REMOTE
```

---

#### Work

以下の動作の違いを確認しましょう

```
cd ［作業するディレクトリ］
```

```
rsync -rlcvn a/ b
rsync -rlcv a/ b
```

```
rsync -rlcvn a c
rsync -rlcv a c
```

```
rsync -rlcv a/ d
rsync -rlcvv a/ e
rsync -rlcvvv a/ f
```

---


### mkdir

---

新しいディレクトリを作成する

- UNIXコマンドの1つ
- 「make directory」の意味

---

#### よく使うオプション

|option|内容|
|:--|:--|
|`-p`, `--parents`|親ディレクトリも同時に作成する|

---

#### サンプルコード

```
PATH_REMOTE=/hoge/
mkdir -p $PATH_REMOTE
```

---

#### Work

以下の動作を確認しましょう

```
PATH_REMOTE=e
mkdir -p $PATH_REMOTE
```

---

### rm

---

指定したディレクトリ以下の全ディレクトリツリーを削除する

- UNIXコマンドの1つ
- 「remove」の意味
- パスの指定を誤るとサーバーが空になるので注意

---

#### よく使うオプション

|option|内容|
|:--|:--|
|`-r`, `-R`, `--recursive`|指定したディレクトリの下層のディレクトリにも再帰的に実行する|
|`-f`, `--force`|警告メッセージを表示せずに実行する|

---

#### サンプルコード

```
PATH_BACKUP=${WORKSPACE}/_backup/
if test -d $PATH_BACKUP ; then
  rm -rf $PATH_BACKUP
fi
```

---

#### Work

以下の動作を確認しましょう

```
PATH_REMOTE=e
rm -rf $PATH_REMOTE
```

---


### if ［条件］; then ［処理］ elif ［条件］; then ［処理］ else ［処理］ fi

---

条件分岐する

- シェル・スクリプト構文
- 条件によって処理を分ける

---

#### サンプルコード & Work

```
HOGE=3
if [ $HOGE -eq 1 ]; then
  echo -e "1です"
elif [ $HOGE -eq 2 ]; then
  echo -e "2です"
else
  echo -e "${HOGE}です"
fi
```

---


### for ［イテレータ変数］ in ［配列］ do ［処理］ done

---

for文を定義する

- シェル・スクリプト構文
- ループ制御文
- Bに配列、Aにイテレータ変数、Cに処理内容を記述する

---

#### サンプルコード & Work

```
CONTENT_ARR=()
CONTENT_ARR+=(a/)
CONTENT_ARR+=(b/)
CONTENT_ARR+=(c/)

for CONTENT in ${CONTENT_ARR[@]}
do
  echo -e "${CONTENT}"
done
```

---


### test

---

真偽を判定する

- UNIXコマンドの1つ
- 条件式を評価し真偽値を返す

---

#### よく使うオプション

|option|内容|
|:--|:--|
|`-d`|directoryの頭文字。指定したファイルが存在し，ディレクトリであれば真を返す|

---

#### サンプルコード

```
### WORKSPACEから dist/ と .git/ 以外を削除
if test -d ${WORKSPACE} ; then
  ls -A | grep -v "dist" | grep -v ".git" | xargs rm -rf | rm -rf .editorconfig | rm -rf .gitignore | rm -rf bin
fi
```

---

#### Work

```
if test -d a/; then
  echo -e "存在します"
else
  echo -e "存在しません"
fi

if test -d z/; then
  echo -e "存在します"
else
  echo -e "存在しません"
fi
```

---



### ls

---

ファイル、ディレクトリの情報取得

- UNIXコマンドの1つ
- 「list」の意味
- ディレクトリやファイルの情報を表示する

#### よく使うオプション

|option|内容|
|:--|:--|
|`-A`|".."や"."を表示しない|

---

#### サンプルコード

```
### WORKSPACEから dist/ と .git/ 以外を削除
if test -d ${WORKSPACE} ; then
  ls -A | grep -v "dist" | grep -v ".git" | xargs rm -rf | rm -rf .editorconfig | rm -rf .gitignore | rm -rf bin
fi
```

---

#### Work

```
ls ./
ls -A ./
```

---



### grep

---

検索して出力する

- UNIXコマンドの1つ

---

#### よく使うオプション

|option|内容|
|:--|:--|
|`-v`, `--invert-match`|マッチしない行を出力する|

---

#### サンプルコード

```
### WORKSPACEから dist/ と .git/ 以外を削除
if test -d ${WORKSPACE} ; then
  ls -A | grep -v "dist" | grep -v ".git" | xargs rm -rf | rm -rf .editorconfig | rm -rf .gitignore | rm -rf bin
fi
```

---

#### Work

以下の動作の違いを確認しましょう

```
grep テキスト ./b/*.txt
grep a ./b/*.txt
grep b ./b/*.txt
```

---

### xargs

---

前の処理を受けて処理を実行する

- UNIXコマンドの1つ
- 「エックスアーグズ」と読む
- 入力を読み込み、それを引数として指定したコマンドを実行する

---

#### サンプルコード & Work

```
rsync -rlcv a/ b
ls | grep b | xargs rm -rf
```

---


### `#`

---

- UNIXシェルスクリプトの一行コメントアウトの記述に利用する

---

### `#!/bin/bash`

---

- UNIXシェルスクリプトの先頭に書くUNIX命令
- この命令のことをシバン、シェバン（shebang）と呼ぶ
- インタプリタを起動する命令
- シェバン以下に書くコマンドの種類を指定している
- `#!/bin/bash`、`#!/bin/sh`、`#!/bin/csh`、`#!/usr/bin/perl`、`#!/usr/bin/ruby`などがある


---

# 02. gitコマンド

---

<img src="https://sekiyaeiji.github.io/image-storage/dist/img/about-git/git.png" width=40%>

---


<img src="https://sekiyaeiji.github.io/image-storage/dist/img/about-git/github-octocat.png" width=20%>


---

#### Octocat Monalisa

> Once upon a time, there was a cat who’s name was Monalisa. Monalisa and her owner went to the beach. When Monalisa got to the beach, her owner Kelly gave her goggles so Monalisa could swim and see what was in the ocean. When Monalisa went in the water she found lots of fish. When Monalisa was swimming she was so exited she opened her mouth and swallowed a coral that made you grow legs like a octopus but keep your normal face. So Monalisa grew legs and became Mrs. Monalisa octocat.


---

Jenkins の Job でよく利用する gitコマンド を紹介


---

### Jenkins 「シェルの実行」内容の例

```
### $BRANCH_NAME を checkout
git checkout $BRANCH_NAME

### $BRANCH_NAME を master に merge
git checkout master
git merge $BRANCH_NAME
git push origin master

### $WORKSPACEを削除
if test -d ${WORKSPACE} ; then
  rm -rf ${WORKSPACE}
fi
```

---

### よく使うコマンド

- `clone`
- `checkout`
- `add`
- `commit`
- `push`
- `merge`
- `tag`

次章にてこれらを1つずつ確認する

---


## コマンド解説

---

### clone

---

既存リポジトリのコピーを取得

- clone コマンドは Jenkins Job内では「ソースコード管理」の「Git」の機能で実行することが多い

---

#### サンプルコード & Work

```
cd ［作業するディレクトリ］
git clone https://github.com/sekiyaeiji/jenkins-demo.git
cd jenkins-demo
```

---

### checkout

---

ブランチやファイルを取得してその後の処理の準備をする

---

#### サンプルコード & Work

```
git checkout master
git checkout develop
git checkout master
```

---

### add

---

インデックスに追加する

---

#### よく使うオプション

|option|内容|
|:--|:--|
|`-A`|「.」と「-u」を合わせた機能。すべての変更を含む内容を追加登録する|

---

#### サンプルコード & Work

```
git add -A
```

---

### commit

---

commit する

---

#### サンプルコード & Work

```
git commit -m "hoge"
```

---

### push

---

push する

---

#### サンプルコード & Work

```
git push origin develop
```

---

### merge

---

merge する

---

#### サンプルコード & Work

```
git checkout master
git merge develop
```

---

### tag

---

tag を作成する

---

#### よく使うオプション

|option|内容|
|:--|:--|
|`-m`|作成する tag にメッセージを付与する|

---

#### サンプルコード & Work

```
git tag fuga -m "piyo"
git tag
git push --tag
```

---

# 03. 設定

---

## 基本設定

<img src="https://sekiyaeiji.github.io/image-storage/dist/img/about-jenkins/cap001.png" width=100%>


---

### ジョブ名（プロジェクト名）

- 半角英数文字列により命名する
- その文字列ままジョブのURLとして利用される
- インスタンス内でユニークである必要がある
- スペースは原則として使わない（%20になる）

---

### 説明

- html要素がレンダリングできる
- ［プレビュー］押下で作業中のレイアウトが確認できる

---

### 古いビルドの破棄

- Jenkinsインスタンスの容量節約のため設定する
- 基本的には「ビルドの保存最大数 ： 10」を設定しておけば問題ない

---

### Slack Notifications

- チームでジョブ実行監視を行いたい場合などに有効
- 特に本番用ビルドが走る場合など、失敗ログにすばやく気付けて便利

---

#### 手順

- 「Notify Success」をチェック
- ［高度な設定...］を押下
- 「Team Domain ： ［Slackのチームドメイン］」
- 「Integration Token ： ［インテグレーショントークン値］」
- 「Project Channel ： ［通知したいチャンネル名］」

---

## Git ブランチ選択

### Git Parameter

<img src="https://sekiyaeiji.github.io/image-storage/dist/img/about-jenkins/cap002.png" width=100%>

---

#### 手順

- 引数名になる「Name ： BRANCH_NAME」を入力
- このジョブのブランチルールの説明などを「Description」に記載
- 通常のブランチ操作を行うジョブの場合、「Parameter Type ： Branch」を選択
- 扱う頻度の高いブランチやデフォルトブランチを設定する developの場合は「Default Value ： origin/develop」

---

## DRYRUN フラグ

### 真偽値

<img src="https://sekiyaeiji.github.io/image-storage/dist/img/about-jenkins/cap003.png" width=100%>

---

#### 手順

- 引数名になる「名前 ： DRYRUN」を入力
- 失敗を許容されないジョブの場合は「デフォルト値」をチェックする  テストサーバーではチェックは不要
- このジョブのDRYRUNの使い方などを「説明」に記載

---

## Git Clone

### ソースコード管理 - Git

<img src="https://sekiyaeiji.github.io/image-storage/dist/img/about-jenkins/cap004.png" width=100%>

---

#### 手順

- 「ソースコード管理」で「Git」ラジオボタンをチェックする
- 「Repository URL」にリポジトリのSSHパスを設定
    - Ex.) git@github.com:◯◯◯/□□□.git
- 「Branches to build」に、Git Parameterで設定した引数「$BRANCH_NAME」を入力

---

## 「シェルの実行」の設定

---

### シェルコマンド

[01. シェルコマンド](https://qiita.com/sekiyaeiji/private/5a09cd926b88d63b6490#01-%E3%82%B7%E3%82%A7%E3%83%AB%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89)で学んだコマンドで実際の動作を確認しましょう

---

### gitコマンド

[02. gitコマンド](https://qiita.com/sekiyaeiji/private/5a09cd926b88d63b6490#02-git%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89)で学んだコマンドで実際の動作を確認しましょう

---

# 04. 「シェルの実行」のバリエーション

---

## dryrun試行 を含む通常の rsync deploy

- WORKSPACE内の「dist」ディレクトリの内容をリモートにリリースするシェルサンプル

---

```
#!/bin/bash

### 変数定義
# ホスト
HOST_REMOTE=［ホストの名前］

# パス
PATH_DIST=${WORKSPACE}/dist/
PATH_REMOTE=［リモートのパス］

# コマンド
RSYNC="rsync -rlcv --delete"


### ディレクトリ生成 （2回目以降の実行時はコメントアウトしてもOK）
# echo -e "\n\n*** ディレクトリ生成 開始 ***"
# ssh $HOST_REMOTE mkdir -p $PATH_REMOTE
# echo -e "*** ディレクトリ生成 終了 ***\n"


### ファイル転送
if ${DRYRUN} ; then
  # dryrun
  echo -e "\n\n*** dryrun 開始 ***"
  $RSYNC -n $PATH_DIST $HOST_REMOTE:$PATH_REMOTE
  echo -e "*** dryrun 終了 ***\n\n"
else
  # deploy
  echo -e "\n\n*** deploy 開始 ***"
  $RSYNC $PATH_DIST $HOST_REMOTE:$PATH_REMOTE
  echo -e "*** deploy 終了 ***\n\n"
fi
```

---

## remote からファイルを取得する

- WORKSPACE内の「_backup」ディレクトリにリモートのファイルを保存するシェルサンプル

---

```
#!/bin/bash

### 変数定義
# ホスト
HOST_REMOTE=［ホストの名前］

# パス
PATH_BACKUP=${WORKSPACE}/_backup/
PATH_REMOTE=［リモートのパス］

# コマンド
RSYNC_BACKUP="rsync -rl"


### バックアップ保存
# WORKSPACE内の過去のバックアップを削除
if test -d $PATH_BACKUP ; then
  rm -rf $PATH_BACKUP
fi

# WORKSPACEにバックアップを保存
echo -e "\n\n*** backup 開始 ***"
$RSYNC_BACKUP $HOST_REMOTE:$PATH_REMOTE $PATH_BACKUP
echo -e "*** backup 終了 ***\n\n"
```

---

## rsync deploy と remote からのバックアップ保存の組み合わせ

- おもに本番リリースジョブに利用する
- 本番 deploy ではこのリリース直前のバックアップを原則として義務づけている
- DRYRUN の際にバックアップが作動しないよう条件を設定する

---

```
#!/bin/bash

### 変数定義
# ホスト
HOST_REMOTE=［ホストの名前］

# パス
PATH_DIST=${WORKSPACE}/dist/
PATH_BACKUP=${WORKSPACE}/_backup/
PATH_REMOTE=［リモートのパス］

# コマンド
RSYNC="rsync -rlcv --delete"
RSYNC_BACKUP="rsync -rl"


### ディレクトリ生成 （2回目以降の実行時はコメントアウトしてもOK）
# echo -e "\n\n*** ディレクトリ生成 開始 ***"
# ssh $HOST_REMOTE mkdir -p $PATH_REMOTE
# echo -e "*** ディレクトリ生成 終了 ***\n"


### バックアップ保存
if [ ${DRYRUN} = false ] ; then
  # WORKSPACE内の過去のバックアップを削除
  if test -d $PATH_BACKUP ; then
    rm -rf $PATH_BACKUP
  fi

  # WORKSPACEにバックアップを保存
  echo -e "\n\n*** backup 開始 ***"
  $RSYNC_BACKUP $HOST_REMOTE:$PATH_REMOTE $PATH_BACKUP
  echo -e "*** backup 終了 ***\n\n"
fi


### ファイル転送
if ${DRYRUN} ; then
  # dryrun
  echo -e "\n\n*** dryrun 開始 ***"
  $RSYNC -n $PATH_DIST $HOST_REMOTE:$PATH_REMOTE
  echo -e "*** dryrun 終了 ***\n\n"
else
 # deploy
  echo -e "\n\n*** deploy 開始 ***"
  $RSYNC $PATH_DIST $HOST_REMOTE:$PATH_REMOTE
  echo -e "*** deploy 終了 ***\n\n"
fi
```

---

### Work

- 「RSYNC_BACKUP」のオプション値「-rl」の理由を考察する

---


## WORKSPACE 内に残留するブランチ情報を削除する

- ジョブの最後に記述する
- WORKSPACE 内のGitブランチリストを削除することによって、次のビルド表示のブランチリストを最新の状態で取得できるようにする

---

```
#!/bin/bash

### WORKSPACE 内に残留するブランチ情報を削除
# パス
PATH_GIT_BRANCHES=${WORKSPACE}/.git/refs/remotes/

# 削除
if test -d $PATH_GIT_BRANCHES ; then
  rm -rf $PATH_GIT_BRANCHES
fi
```

---

## バックアップから deploy する

- 万が一、バックアップからの切り戻しをする場合に利用する
- 通常、誤操作防止のため通常のデプロイジョブとは別に作成するのが一般的
- 別のジョブの WORKSPACE を直接参照するため、 PATH_BACKUP に環境変数の ${WORKSPACE} を利用しないことに注意
- 別の Jenkins インスタンスに設定する場合は PATH_BACKUP のルートパスを変更すること
- 説明欄の `<h2 style="color:red;">【警告】 このジョブは通常運用では決して利用しません 【警告】</h2>` のような警告記載により、操作を防止する工夫が必要

---

```
#!/bin/bash

### 変数定義
# ホスト
HOST_REMOTE=［ホストの名前］

# パス ： PATH_BACKUP は特定のジョブのパスを直接指定しています
PATH_BACKUP=［Jenkins インスタンスのルートパス］/workspace/［リリースジョブのプロジェクト名］/_backup/
PATH_REMOTE=［リモートのパス］

# コマンド
RSYNC="rsync -rlcv"


### ファイル転送
if ${DRYRUN} ; then
  echo -e "\n\n*** failback dryrun 開始 ***"
  $RSYNC -n $PATH_BACKUP $HOST_REMOTE:$PATH_REMOTE
  echo -e "*** failback dryrun 終了 ***\n\n"
else
  # deploy
  echo -e "\n\n*** failback deploy 開始 ***"
  $RSYNC $PATH_BACKUP $HOST_REMOTE:$PATH_REMOTE
  echo -e "*** failback deploy 終了 ***\n\n"
fi
```

---

## TAG を打つ

- リリースTAGを生成する場合などに利用する
- 「$BRANCH_NAME」 は Git Parameter などから取得する

---

```
#!/bin/bash


### checkout develop
# git checkout develop
git checkout $BRANCH_NAME
BRANCH_ID="${BRANCH_NAME//origin\/release\//}"


### Tag生成
DATE=`date +%Y%m%d_%H-%M-%S`
TITLE="release_${DATE}_$BRANCH_ID"
git tag -a ${TITLE} -m "version : ${DATE}"
git push --tag
git tag -d ${TITLE}
```

---

## develop を master にマージする

- develop と master の同期をする場合などに利用する
- 「$BRANCH_NAME」 は Git Parameter などから取得する

---

```
#!/bin/bash

### $BRANCH_NAME を checkout
git checkout $BRANCH_NAME

### $BRANCH_NAME を master に merge
git checkout master
git merge $BRANCH_NAME
git push origin master
```

---

## 納品用ブランチ delivery ブランチにコミットする

- MU納品案件の納品方法の1スタイル
- delivery という名前のブランチに、build 後の dist の内容だけをコミットする
- 納品先に diff を送付することにより変更点を伝達できる
- 「$BRANCH_NAME」 は Git Parameter などから取得する

---

```
#!/bin/bash

### 変数
BRANCH_DELIVERY=delivery
COMMIT_ID="$(git rev-parse HEAD)"

echo -e "\n\n*** $BRANCH_DELIVERY に $COMMIT_ID をデプロイする ***"

### checkout
git checkout $BRANCH_DELIVERY
git checkout origin/$BRANCH_NAME -- dist

### WORKSPACEから dist/ と .git/ 以外を削除
if test -d ${WORKSPACE} ; then
  ls -A | grep -v "dist" | grep -v ".git" | xargs rm -rf | rm -rf .editorconfig | rm -rf .gitignore | rm -rf bin
fi

### distディレクトリをroot展開
cp -r dist/* .
rm -rf dist

### commit
if [ -z "$(git status --porcelain)" ]; then
  echo -e "\n*** commitすべき差分が存在しません ***\n\n"
else
  git add -A
  git commit -m "delivery branch : $COMMIT_ID"
  git push origin $BRANCH_DELIVERY
fi
```


## WORKSPACE 内で build する （シンボリックリンクを利用する場合）

- バージョン管理の理想形は、dist をコミットしない状態
- Jenkins ジョブ内で dist を生成して deploy する
- 現状、ジョブ実行でnpmインストールできる環境は社内にない
- /home/node_package/ に事前にインフラにインストール依頼が必要
- インストールされたパスを SYMBOLIC_LINK に設定する

---

```
#!/bin/bash

### 変数定義
# パス
PATH_SRC=${WORKSPACE}/src/

# シンボリックリンク
SYMBOLIC_LINK=/home/node_package/［プロジェクトディレクトリなど］/node_modules

# コマンド
BUILD="npm run build"


### ビルド
if test -d $PATH_SRC ; then

  # 指定領域のnode_modulesにシンボリックリンクを張る
  if test -d node_modules ; then
    echo -e "*** node_module is exist ***\n\n"
  else
    ln -s $SYMBOLIC_LINK
  fi

  # npm update
  source ~/.nvm/nvm.sh
  nvm use v8.9.1
  node -v
  nvm ls
  BABEL_DISABLE_CACHE=1

  # ビルド
  echo -e "\n\n*** build ***"
  $BUILD
  echo -e "*** build done ***\n\n"
else
  echo -e "\n\n*** content buildが実行できませんでした ***\n\n"
  exit
fi
```