GitLab CIでMRSをautorebaseする方法


この記事では、gitlab ciのautorebase mrsの使い方を紹介します.

問題


あなたならば
  • あなたのGit履歴線形を保つようにしてください
  • コードレビュー&CIのマージ要求を使用してください
  • あなたのCIは些細な時に走る
  • あなたが統合されたMRのために1以上のMRを持っているときはいつでも、あなたは他のすべてを再利用しなければならないでしょう.私のチームでは、CIの時間を30分以下に抑えることができます.しかし、3〜4人のMRSが並んでいたので、今までとマージをしています.

    考え


    最良の解決策は、再基地を自動化することです.私たちはgitlabと統合された外部サーバーを持つことができ、何か新しいものがメインブランチにマージされたときにコードを再利用します.または、我々は光を開始し、ベースを使用して再基地を実行します.そうすることができます.
  • メインブランチパイプラインの先頭で実行するCIジョブを持っている
  • ゲットオールオープンMRrest API
  • 呼び出しthe rebase endpoint すべてのミセス
  • コード


    JavaScriptでソリューションを実装します.まず、NPMパッケージを生成し、依存関係をインストールします.
    $ npm run -y
    $ npm install --save-dev node-fetch
    
    では、実行可能ファイルを作成しましょう.
    $ touch rebase.js
    $ chmod +x rebase.js
    
    ファイルの内容は次のとおりです.
    #!/usr/bin/env node
    
    setはファイルを実行するときに実行するコマンドです.
    const fetch = require("node-fetch");
    
    js
    node-fetch , ブラウザからのフェッチAPIのノード実装.
    const projectId = process.argv[2] ? process.argv[2] : process.env.CI_PROJECT_ID,
      apiToken = process.argv[3] ? process.argv[3] : process.env.API_TOKEN,
    
    スクリプトは、必要な値を提供する2つの方法をサポートしています.
    $ export CI_PROJECT_ID="28869171"
    $ export API_TOKEN="secret-key"
    $ ./rebase.js
    
    または
    $ ./rebase.js 28869171 secret-key
    
    最初の方法は、それがGitlab CIエージェントでどう動くかを模倣します;第2の方法は局所的にテストするのが簡単です.
      apiV4Url = process.env.CI_API_V4_URL
        ? process.env.CI_API_V4_URL
        : "https://gitlab.com/api/v4";
    
    自己ホストされたgitlabインスタンスのためのnod他の誰でも、デフォルト値で罰金です.
    function callApi(command, method = "GET") {
      console.log("query", apiV4Url + "/projects/" + projectId + command);
    
      return fetch(apiV4Url + "/projects/" + projectId + command, {
        method,
        headers: { "PRIVATE-TOKEN": apiToken },
      });
    }
    
    我々の短いスクリプトでコード複製を避けるヘルパー方法.
    callApi("/merge_requests?state=opened")
      .then((response) => response.json())
      .then((response) => {
        const iids = response.map((mr) => mr.iid);
    
    すべてのオープンのMRSとは、IID -ローカルIDの配列に戻り値を返しました.
        return Promise.all(
          iids.map((iid) => {
            return callApi(`/merge_requests/${iid}/rebase`, "PUT")
    
    ごとにiid , Rebaseを呼び出します.それは優雅に失敗します、それで、MRが再利用できないならば、質問は衝突しません.
              .then((response) => response.json())
              .then((response) => {
                response.iid = iid;
    
                return response;
              })
    
    応答は簡潔です([{ rebase_in_progress: true }] ), 私はIIDを追加しているので、少なくとも私たちは何のミセスが再利用されている伝えることができます.
              .catch(console.error);
          })
        );
      })
    
    ログエラーとキャッチ失敗.
      .then((resultSummary) => {
        console.log(resultSummary);
      })
      .catch((error) => {
        console.error(error);
      });
    
    画面に結果を表示します.

    コンプリートベース.js


    #!/usr/bin/env node
    
    const fetch = require("node-fetch");
    
    const projectId = process.argv[2] ? process.argv[2] : process.env.CI_PROJECT_ID,
      apiToken = process.argv[3] ? process.argv[3] : process.env.API_TOKEN,
      apiV4Url = process.env.CI_API_V4_URL
        ? process.env.CI_API_V4_URL
        : "https://gitlab.com/api/v4";
    
    function callApi(command, method = "GET") {
      console.log("query", apiV4Url + "/projects/" + projectId + command);
    
      return fetch(apiV4Url + "/projects/" + projectId + command, {
        method,
        headers: { "PRIVATE-TOKEN": apiToken },
      });
    }
    
    callApi("/merge_requests?state=opened")
      .then((response) => response.json())
      .then((response) => {
        const iids = response.map((mr) => mr.iid);
    
        return Promise.all(
          iids.map((iid) => {
            return callApi(`/merge_requests/${iid}/rebase`, "PUT")
              .then((response) => response.json())
              .then((response) => {
                response.iid = iid;
    
                return response;
              })
              .catch(console.error);
          })
        );
      })
      .then((resultSummary) => {
        console.log(resultSummary);
      })
      .catch((error) => {
        console.error(error);
      });
    

    Gitlab CIの設定


    image: node:16
    
    stages:
      - build
      - test
    
    build:
      stage: build
    
      rules:
        - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
          when: always
    
      script:
        - npm ci
        - ./rebase.js
    
    test:
      stage: test
      script:
        - echo 'test run'
    

    コンプリート.Gitlab CI気象研


    image: node:16
    
    stages:
      - build
      - test
    
    build:
      stage: build
      rules:
        - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
          when: always
      script:
        - npm ci
        - ./rebase.js
    
    test:
      stage: test
      script:
        - echo 'test run'
    

    スクリプト出力


    スクリプトの実行例
    query https://gitlab.com/api/v4/projects/28869171/merge_requests?state=opened
    query https://gitlab.com/api/v4/projects/28869171/merge_requests/2/rebase
    [ { rebase_in_progress: true, iid: 2 } ]
    

    構成


    このスクリプトを実行するには、APIトークンを作成しなければなりません.ここではpersonal access token :

    トークンを作成した後、API_TOKEN CI変数に.これは、変数が'マスクされていないので、Ciログに事故で表示されません.

    私のレポの場合、ULRはhttps://gitlab.com/how-to.dev/autorebase-merge-requests/-/settings/ci_cd .
    CIの外部スクリプトを実行するには、プロジェクトIDを設定する必要があります.

    私のレポのためにhttps://gitlab.com/how-to.dev/autorebase-merge-requests/edit .

    リンク

  • GitLab merge request api docs
  • GitLab CI variables
  • Example repo
  • 概要


    この記事では、gitlab ciに簡単なautorebaseを追加する方法を見ました.あなたがGitlabビデオコースに興味があるならば、登録によって私に知らせてくださいhere .