Jenkins による リリース & Git操作 & build 入門
Jenkins による リリース & Git操作 & build 入門:
Jenkins の Job でよく利用する シェルコマンド を紹介
文字列や変数の内容を表示する
以下の動作の違いを確認しましょう
変数の働きを確認しましょう
テストサーバーや本番サーバーへのファイルアップロードにはおもに
以下の動作の違いを確認しましょう
新しいディレクトリを作成する
以下の動作を確認しましょう
指定したディレクトリ以下の全ディレクトリツリーを削除する
以下の動作を確認しましょう
条件分岐する
for文を定義する
真偽を判定する
ファイル、ディレクトリの情報取得
検索して出力する
以下の動作の違いを確認しましょう
前の処理を受けて処理を実行する
Jenkins の Job でよく利用する gitコマンド を紹介
既存リポジトリのコピーを取得
ブランチやファイルを取得してその後の処理の準備をする
インデックスに追加する
commit する
push する
merge する
tag を作成する
01. シェルコマンドで学んだコマンドで実際の動作を確認しましょう
02. gitコマンドで学んだコマンドで実際の動作を確認しましょう
Jenkins による リリース & Git操作 & build 入門
00. Jenkinsについて
Jenkinsとは
準備された仕事を指定されたタイミングで実行する箱
- 継続的インテグレーション(continuous integration)ツール
- アジャイル型開発での利用を前提に設計された
- on-premises(自社運用)型のため企業において一括管理しやすい
- 日本製で、作者は川口耕介氏
- "ジョブ"と呼ばれる用途単位の機能を順次実行していくことでGit操作やファイル転送を実行する
- 1つのジョブは、対象Gitブランチ設定やGitコマンド、シェルコマンドなどを設定することで1つの機能を担う構造になっている
- ジョブを一度作成すると実行時に機能の詳細内容を意識することなく反復利用できる
- 初期状態では、ジョブが何も与えられてない"からっぽのハコ"のようなもの
川口耕介氏
なぜCIツール
- 機械が得意なことを機械に任せる
- 差分抽出
- 反復作業
- 転送設定
- 高速リリース
- テスト
- ローカルルールの撲滅
- 本来創意工夫の必要のない作業
- 属人的な要素の排除
その他のCIサービス
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
コマンド解説
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コマンド
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
コマンド解説
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. 設定
基本設定
ジョブ名(プロジェクト名)
- 半角英数文字列により命名する
- その文字列ままジョブのURLとして利用される
- インスタンス内でユニークである必要がある
- スペースは原則として使わない(%20になる)
説明
- html要素がレンダリングできる
- [プレビュー]押下で作業中のレイアウトが確認できる
古いビルドの破棄
- Jenkinsインスタンスの容量節約のため設定する
- 基本的には「ビルドの保存最大数 : 10」を設定しておけば問題ない
Slack Notifications
- チームでジョブ実行監視を行いたい場合などに有効
- 特に本番用ビルドが走る場合など、失敗ログにすばやく気付けて便利
手順
- 「Notify Success」をチェック
- [高度な設定...]を押下
- 「Team Domain : [Slackのチームドメイン]」
- 「Integration Token : [インテグレーショントークン値]」
- 「Project Channel : [通知したいチャンネル名]」
Git ブランチ選択
Git Parameter
手順
- 引数名になる「Name : BRANCH_NAME」を入力
- このジョブのブランチルールの説明などを「Description」に記載
- 通常のブランチ操作を行うジョブの場合、「Parameter Type : Branch」を選択
- 扱う頻度の高いブランチやデフォルトブランチを設定する developの場合は「Default Value : origin/develop」
DRYRUN フラグ
真偽値
手順
- 引数名になる「名前 : DRYRUN」を入力
- 失敗を許容されないジョブの場合は「デフォルト値」をチェックする テストサーバーではチェックは不要
- このジョブのDRYRUNの使い方などを「説明」に記載
Git Clone
ソースコード管理 - Git
手順
- 「ソースコード管理」で「Git」ラジオボタンをチェックする
- 「Repository URL」にリポジトリのSSHパスを設定
- Ex.) git@github.com:◯◯◯/□□□.git
- 「Branches to build」に、Git Parameterで設定した引数「$BRANCH_NAME」を入力
「シェルの実行」の設定
シェルコマンド
01. シェルコマンドで学んだコマンドで実際の動作を確認しましょう
gitコマンド
02. gitコマンドで学んだコマンドで実際の動作を確認しましょう
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
コメント
コメントを投稿