つばくろぐ @takamii228

知は力なり

GitLab CEでMerge Request時のCIを事前にマージしてから実行する

最近のお仕事ではCIにGitLab CIを使っています。

Merge Request時にGitLab CIを実行して、CI上で静的解析やビルド・テストを実行してコードをクリーンに保つようにしています。

しかしMerge Requestがしばらく放置されてしまい、当時はCIのPipelineが成功していたとしても、ターゲットブランチが先に進んでしまってからマージした場合、マージ後のCIが失敗してしまうケースがあります。

これを防ぐためにはコンフリクトを直すときのように常にローカルでfetch / rebaseしたり最新のターゲットブランチをマージして再Pushして解決することができますが、なかなか面倒です。

githubやgitbucketにはこれを防ぐ機能として、マージ先のブランチが先に進んでしまっていた場合にマージ先のoriginの情報をマージ対象のブランチにマージする Update branch 機能があり、PRのレビュー画面で実行することができます。

github.blog

GitLabにも似たような機能がないかと探していたら、こんな機能を見つけました。

https://docs.gitlab.com/ce/ci/merge_request_pipelines/pipelines_for_merged_results/index.html

It’s possible for your source and target branches to diverge, which can result in the scenario that source branch’s pipeline was green, the target’s pipeline was green, but the combined output fails.

By having your merge request pipeline automatically create a new ref that contains the merge result of the source and target branch (then running a pipeline on that ref), we can better test that the combined result is also valid.

GitLab can run pipelines for merge requests on this merged result. That is, where the source and target branches are combined into a new ref and a pipeline for this ref validates the result prior to merging.

マージ対象のブランチにマージしてからPipelineを実行してくれるらしい。

これこれ、と思ってReposirtoyの設定を見てみたら、設定が見当たらない。

おかしいなと思ってよく見てみると・・・

f:id:takamii228:20190727155021p:plain

あー課金ユーザ向けだった。。。

仕方ないので似たようなことができるように自作しました。

まずgitlab-ci.ymlの中でMerge Request実行時には最初にupdate-branch.shを実行するように設定します。

// Merge Request時はこっちを実行する
mergeRequestBuild:
  stage: build
  tags:
    - ci-runner
  script:
    - ./update-branch.sh
    - ./lint.sh
    - ./build.sh
  only:
    - merge_requests

// ブランチPush時はこっちを実行する
branchBuild:
  stage: build
  tags:
    - ci-runner
  script:
    - ./lint.sh
    - ./build.sh

update-branch.shでは最新のターゲットブランチとマージ対象のブランチを作成して、マージ対象のブランチにターゲットブランチをマージします。

#!/bin/sh

set -x
set -e

TARGET_BRANCH=$CI_MERGE_REQUEST_TARGET_BRANCH_NAME
SOURCE_BRANCH=$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME

if [ -n "$SOURCE_BRANCH" ]; then
    # CIの実行ごとにブランチを再利用しないようにコミットごとにテンポラリのブランチ名を作成する
    TMP_SOURCE_BRANCH=$SOURCE_BRANCH-`git rev-parse --short HEAD`-`date "+%Y%m%d%H%M%S"`
    TMP_TARGET_BRANCH=$TARGET_BRANCH-`git rev-parse --short HEAD`-`date "+%Y%m%d%H%M%S"`

    # Merge対象のブランチをテンポラリのブランチ名でチェックアウトする
    git checkout -f -b $TMP_SOURCE_BRANCH HEAD

    # Merge元のブランチをテンポラリのブランチ名でチェックアウトする
    git checkout -f -b $TMP_TARGET_BRANCH origin/$TARGET_BRANCH

    # Merge対象のブランチにMerge元のブランチをマージする
    git merge $TMP_SOURCE_BRANCH -m "merge $CI_COMMIT_REF_NAME into develop"
fi

Merge Request対象のブランチ名はCI_COMMIT_REF_NAMEから取得することができました。

https://docs.gitlab.com/ee/ci/variables/predefined_variables.html

gitalb ciでは毎回git checkout HEADでローカル環境のチェックアウトをしているため、CI上でブランチのマージを実行する場合は明示的にブランチを切ってcheckoutする必要がありました。

また今回はGitLab CI Runnerはshellで実行しているため、ビルド実行後のブランチ情報は毎回残ってしまいます。そのため毎回の実行でブランチ名が一位になるようにコミットハッシュ+実行日時をいれるようにしました。

コンフリクトが発生する場合は失敗mergeReuqestBuildは失敗するのでConflictが発生していることがCIの実行時に気づけるようになりました。

自分の情報収集のやり方を整理してみた

後輩とかに「どうやって情報収集してるんですか?」と聞かれることが多々あったので、整理してみました。

GitPitch Presents: github/takami228/mypresentation/how-to-get-informtaion

Modern Slide Decks for Developers on Linux, OSX, Windows 10. Present offline. Share online. Export to PPTX and PDF.

インプットとアウトプットの比率はバランスが大事ですね。

ある程度インプットの貯金がないとアウトプットも出ないですし、逆にインプットしすぎでもただの頭でっかちになってしまいます。

あとアウトプットに含まれるかもですが、「経験から学ぶ」という観点も大事ですよね。

個人的にはインプットの習慣は付きつつあるので、アウトプットの比率を高めないとなーと思うこの頃です。

約6年ぶりにAtCoderを再開した話

AtCoderを再開した

2018年の年末あたりからTwitterのTLでAtCoderの文字をよく見るようになったので、懐かしくなってAtCoderを再開しました。

実はわたくし、AtCoderがサービス開始したころに登録した古参ユーザなのです。

私の競プロ歴

学生時代は私の指導教員がICPCの運営委員だったので、ICPCには研究室配属後に学部4年と修士1年の時に研究室メンバで予選会だけ参加しました。

当時は蟻本をチームで輪講したり、PKUを解いたりして対策してました。

模擬予選では3問解けましたが、本番の予選では2問しか解けなくてもっと早くから対策を始めてれば・・・と悔しい思いをしたのを覚えています。 (どっちにせよ学内に世界大会出るようなチームがいたので予選突破は厳しかったのですが笑)

2012年には代々木オリンピックセンターで行われたアジア予選のスタッフもやりました。

試合ではUniversity of Agitsuneが全完してたのを覚えてます。また懇親会で生iwiwi先生や生chokudaiさんと話して写真を撮ったのも覚えてます。懐かしいですね。

takamii.hatenablog.com

ちょうど修士1年の2012年あたりにAtCoderがサービス開始したんじゃないかな、と記憶してます。

当時はコンテストの参加者は1000人前後だったと思うのですが、今や1万人規模なので、競プロ人口が増えているなーと感じています。

社会人になってからの競プロ

社会人1年目あたりまでは暇つぶしに出てたような記憶があります。

ただ途中から仕事が本格化したり、休日が他の予定で埋まるようになっていつの間にか出なくなってしまいました。

自習の興味関心も競プロで扱うようなアルゴリズムから実際の業務で使うアーキテクチャフレームワーククラウドサービスや開発プロセスの方に移ってしまったのも要因かなと思います。

ただ最近はITエンジニアの能力を客観的にアピールする指標としてAtCoderのレートが定着してきているように感じるので、CS出身の自分の力をちゃんと客観的に示すべく、レートを磨きたいなと思い再開しました。

とりあえず水色を目指してみよう

年末年始から再開して今のレートは茶色です。

f:id:takamii228:20190531174021p:plain

f:id:takamii228:20190531174031p:plain

学生時代はDPとかDFS、BFS、ダイクストラ、二部マッチングとかなんとなく書けてたんですが、すっぽり抜け落ちてしまったので絶賛復習中です。

現状ABCで2問-3問解けるくらいの実力なので、まずは3問をノーミスですぱっと解けるようにして水色を目指したいなーという感じです。

私はゆるふわエンジョイ勢ですが、毎回コンテストを無償で開催してくれるAtCoder社には感謝しかありません。今度とも応援しております!