CircleCI で master ブランチとマージされたブランチでテストする
やりたいこと
CircleCI で普通に checkout
を用いてテストを流して通っても、master にマージ後にエラーになってしまうことがある。それを防ぐためにブランチを master にマージした状態でテストを流したい。
JenkinsやTravisだと選択したらできる程度の機能だが、現状のCircleCIだと頑張らないとできない(という認識)
事前知識
GitHub に pull request (PR) すると github 上では pull/xxx/head
と pull/xxx/merge
というブランチが作られる。
pull/xxx/head
が PR されたブランチの head と同じ状態のもので pull/xxx/merge
がマージ対象のブランチとマージした状態のブランチになる。
なので、基本的には pull/xxx/merge
のほうを CircleCI で checkout してテストを流せば良い。
しかし、CircleCI の checkout
では pull/xxx/merge
のほうを選ぶことができない。
また、pull/xxx/merge
の checkout
だと Conflict したかどうかの判断がしづらい。Pull Request を投げた瞬間は
- Conflict しなかった場合:
pull/xxx/merge
が作られる - Conflict した場合:
pull/xxx/merge
が作られない
一度 pull/xxx/merge
が作られた後に、git commit && push を積むと
- Conflict しなかった場合:
pull/xxx/merge
が更新される - Conflict した場合:
pull/xxx/merge
が更新されない
という挙動をする。pull/xx/merge
の存在確認だけでは Conflict 判定ができない。
やり方
結局こうなった。つまるところ git checkout master
して git merge --no-commit pull/xxx/head
で master に merge してあげている。
制約条件としては Pull Request にしていること。
その制約の代わりに fork されたリポジトリから Pull Request を送った場合でも動くようになっている。
if [[ -n "${CIRCLE_PULL_REQUEST}" ]]; then
# TODO: Any ways to get PR destination branch dynamically?
PR_DEST_BRANCH=master
# CIRCLE_PR_NUMBER is available only if PR is created from a fork (unavailable if created from a branch).
# So, manually construct it from CIRCLE_PULL_REQUEST environment variable.
CIRCLE_PR_NUMBER=$(basename "${CIRCLE_PULL_REQUEST}")
# Update PR refs for testing.
FETCH_REFS="+${PR_DEST_BRANCH}:${PR_DEST_BRANCH}"
FETCH_REFS="${FETCH_REFS} +refs/pull/${CIRCLE_PR_NUMBER}/head:pull/${CIRCLE_PR_NUMBER}/head"
FETCH_REFS="${FETCH_REFS} +refs/pull/${CIRCLE_PR_NUMBER}/merge:pull/${CIRCLE_PR_NUMBER}/merge"
# Retrieve the refs
echo "git fetch -u origin ${FETCH_REFS}"
git fetch -u origin ${FETCH_REFS}
# Checkout PR destination branch and merge PR head ref.
# If conflicts occur, exit with non-zero.
echo "git checkout ${PR_DEST_BRANCH}"
git checkout "${PR_DEST_BRANCH}"
git config user.name 'foo' # Need to configure something to git merge
git config user.email '[email protected]'
echo "git merge --no-commit \"pull/${CIRCLE_PR_NUMBER}/head\""
git merge --no-commit "pull/${CIRCLE_PR_NUMBER}/head"
fi
これを checkout のあとに書く
jobs:
foobar:
steps:
- checkout
- run:
name: 'Checkout merged branch'
command: |
ここにインデントして書く
CircleCI 2.1 以上なら commands にしておくとよいかもしれない
version: 2.1
commands:
checkout_merge:
steps:
- run:
name: 'Checkout merged branch'
command: |
ここにインデントして書く
jobs:
foobar:
steps:
- checkout
- checkout_merge
参考文献
-
https://discuss.circleci.com/t/show-test-results-for-prospective-merge-of-a-github-pr/1662/8
- このままだと「事前知識」に書いたように Conflict 検知がうまくいかなかった。
Author And Source
この問題について(CircleCI で master ブランチとマージされたブランチでテストする), 我々は、より多くの情報をここで見つけました https://qiita.com/sonots/items/1ccf420594c0e6d5b885著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .