Qiita初投稿です!よろしくお願いします
TL;DR
この記事を読むと、あるレポジトリで出力されるアウトプットを、別リポジトリ向けに反映するPull Requestを自動で作成できるようになります。
リポジトリ間で依存関係があったりすると使い道が見出せるかもしれません。
1. やったこと
-
課題
Aレポジトリで修正して、Pull Requestがmasterブランチにマージされた後にwebpackして、Bレポジトリに反映するPull Requestを都度手動で実施するのが結構手間。時々、Bレポジトリに反映するのを忘れて、あれ...みたいな事態に陥りがち。 -
解決策
CircleCIがmasterブランチにマージされる度にうまいことやってくれるようにする。
2. hubコマンドをCircleCIで使って解決する
hubコマンドとは?
hubコマンドは、GitHubが提供しているコマンドラインツールです。gitコマンドを拡張して、GitHubの様々な機能が使えるようになります。
今回は、hubコマンド(v2.13.0)を使って、CLIでPull Requestを作成します。
3. 実行手順
Pull Requestを作成するためのシェルスクリプトを作成する
create-pull-request.sh
#!/bin/bash
set -ex
LOCAL_REPO=path/to/some_repo
REMOTE_REPO=organization/some_repo
COPY_FROM=path/to/copy_from
COPY_TO=path/to/copy_to
NEW_BRANCH=some_branch_name
COMMIT_HASH="$(echo $CIRCLE_SHA1 | cut -c -7)"
PR_TEMPLATE=$HOME/target/.github/CIRCLECI_PULL_REQUEST_TEMPLATE.md
# install hub command
wget https://github.com/github/hub/releases/download/v$HUB_VER/hub-linux-amd64-2.13.0.tgz
tar zvxvf hub-linux-amd64-2.13.0.tgz
sudo ./hub-linux-amd64-2.13.0/install
rm -rf hub-linux-amd64-2.13.0
# git clone
mkdir -p $REPO_DIR
hub clone $REPO_LOCATION $REPO_DIR
# 反映したい内容をコピー
cp -fp $COPY_FROM $COPY_TO
# git configの設定
git config --global user.email "circleci@example.com"
git config --global user.name "circleci"
# 反映したい内容をCommit
cd $REPO_DIR
git checkout -b $NEW_BRANCH
git add . && git commit -m "update for $COMMIT_HASH"
# Pull Request Templateを編集
## 作成するPull RequestのタイトルにCommit Hashを付ける
sed -ie "s/hoge$/hoge($COMMIT_HASH)/" $PR_TEMPLATE
## 作成するPull Requestの内容に作成元のPull Requestを紐付ける
echo -e "$CIRCLE_PULL_REQUEST" >> $PR_TEMPLATE
# Pull Requestを作成
hub pull-request -F $PR_TEMPLATE -b develop -p
シェルスクリプトには、実行権限を付けることをお忘れなく。
CIRCLECI_PULL_REQUEST_TEMPLATE.md
update: for hoge
## Reference pull request
hoge
は、シェルスクリプトにてhoge(commit_hash)
に置き換えられ、テンプレートの行末にCircleCI実行対象のPull RequestのURLを追記するようにしています。
CircleCIにシェルスクリプトを組み込む
config.yml (CircleCI)
本稿の対象となるconfig.ymlの一部を抜粋して以下に記載します。
version: 2
references:
## branch filters
filter_only_master: &filter_only_master
branches:
only:
- /^master/
jobs:
create_pull_request:
docker:
- image: some-docker-image
steps:
- checkout
- run:
name: create pull request
command: ./.circleci/create-pull-request.sh
workflows:
version: 2
build_and_deploy:
jobs:
- create_pull_request:
filters: *filter_only_master
4. ちょっと苦労したところ
hub pull-requestコマンドは、初回実行時に username と password を以下のように聞かれてしまう。
$ hub pull-request -F PULL_REQUEST_TEMPLATE.md
github.com username:
github.com password for user (never stored):
two-factor authentication code:
これを解決するために以下を行うことで解決できました。
- CircleCIのEnvironment Variablesに
GITHUB_USER
とOAUTH_TOKEN
を追加する - シェルスクリプトに以下を追記する
cat << EOF > ~/.config/hub
github.com:
- user: $GITHUB_USER
oauth_token: $OAUTH_TOKEN
protocol: https
EOF
chmod 600 ~/.config/hub
これは、hub pull-request
コマンドを初回に実行した際に生成されるものを手動で作成したものですが、シェルスクリプトに書くのはちょっとダサい。。。と思ったので、もう少し調べてみると以下のような記述を見つけました。
$ man hub
:(snip)
CONFIGURATION
GitHub OAuth authentication
Hub will prompt for GitHub username password the first time it needs to access the API and exchange it for an OAuth token, which it saves in ~/.config/hub.
To avoid being prompted, use GITHUB_USER and GITHUB_PASSWORD environment variables.
Alternatively, you may provide GITHUB_TOKEN, an access token with repo permissions. This will not be written to ~/.config/hub.
:(snip)
なるほど。。。そこで、最終的には、以下を行うことで解決しました。
- CircleCIのEnvironment Variablesに
GITHUB_TOKEN
を追加する
これで、初回実行時でも username と password を聞かれることなく、hub pull-request
を実行することができました。
5. 工夫したところ
Pull Request間の対応関係を分かりやすくするために以下を行いました。
- Templateのタイトルにハッシュ値を付けて、Pull Requestを識別できるようにした
- Templateの内容に元のPull RequestのURLを追記して、Referenceできるようにした
6. 今後やりたいこと
- Hotfix等の対応の場合に、ベースブランチを変えられるようにしたい!
- Commitした内容を判定して、反映する内容を変えられるようにしたい!
7. まとめ
今回は、CircleCIとhubコマンドの一部を使ってみましたが、使い方によっては色々柔軟にできそうだなという感じでした。他にも使い場面がありそうなので使っていこうと思います。
以上!