[Bitbucket Pipelines] c++(g++) をビルドする

Bitbucket Pipelines を使って c++(g++) をビルドする手順について記載します。

 

 

 

1. 事前準備

1-1. リポジトリを作成

リポジトリを作成します。詳細割愛。

 

1-2. リポジトリをクローン

リポジトリをローカルPCへクローンします。

git clone

 

1-3. サンプルソース(c++)を作成

ソースコードを作成します。下記は例です。

sample source

 

プログラム例(”hello.cpp”)

#include <iostream>

int main()
{
    std::cout << "Hello world." << std::endl;
    return EXIT_SUCCESS;
}

 

1-4. コミット&プッシュ

作成したソースコードをコミット&プッシュします。

コミット&プッシュ

 

コミット&プッシュ

 

クラウド側に登録を完了

コミット&プッシュ

 

1-5. Pipelines を有効化

以下の手順で Pipelines を有効化します。

NOTE

リポジトリの管理者権限を持つ人のみが以下を実施可能です。

 

(1) ”Repository settings” をクリックします。

Repository settings

 

(2) “PIPELINES“ の中の "Settings“ をクリックします。

Settings

 

(3) “Enable Pipelines“ をチェック状態にします。

Enable Pipelines

 

これで Pipelines が有効になりました。

 

(4) ”bitbucket-pipelines.yml” の雛形を準備します。ここでは下記手順で雛形を準備してみました。

「パイプライン」⇨「Build C++ Application」

Build C++ Application

 

内容を確認後[Commit file]ボタンをクリックします。

Commit file

 

すると・・・初めての Pipelines が実行されました。

 

Start Pipelines

 

当然ながら Failed となりました。

 

こんなメールが私へ届きました。これは良いですね。

複数メンバーがいるときなど、このメールは誰に対して送信されるのかが気になりましたが、ここでは一旦忘れて進めます。

mail 受信

 

”パイプライン” メニューをクリックすると Status が ”Failed” のものがあります。

Failed on pipeline menu

 

クリックして内容を確認してみると・・・ make に check の記載がされていない ・・・ということらしいです。そもそも makefile を準備していないので、エラーになって当然の状況です。

Cause of error

 

「ソース」を確認すると、とりあえず ”bitbucket-pipelines.yml” ファイルが追加されています。

bitbucket-pipelines.yml

 

現時点の yml ファイル内容を以下に記載します。今後このファイルを編集していくことで Pipelines を実際に動くようにしていきます。

["bitbucket-pipelines.yml"]

# Template C++ Application

# This template allows you to validate your C++ application.
# The workflow allows running tests and code linting on the default branch.


image: gcc:10.2


pipelines:
  default:
    - parallel:
        - step:
            name: Test
            script:
              - make check
        - step:
            name: Lint
            script:
              # apt update && apt -y install cppcheck && cppcheck .
              - make lint
        - step:
            name: Build and Run
            script:
              - make compile
              # Execute your C++ application after compilation to check success
              - make distcheck

 

以上で 事前準備 を完了とします。

 


 

2. ビルドする

“bitbucket-pipelines.yml” を編集することで、基本的なビルド&デプロイを実装していきます。

 

2-1. image を ubuntu:18.04 に設定

ここでは例として実行環境(Docker Image)を ubuntu:18.04 に設定します。

(新)image: ubuntu:18.04

(旧)image: gcc:10.2

ちゃんと “Ubuntu 18.04” になったか確認のため、"cat /etc/lsb-release" の一文も追加します。

 

2-2. 開発環境(gcc/g++ など - “build-essential”)をインストール

下記2行を追加します。

- apt-get update
- apt-get -y install build-essential

 

2-3. ソースコードをビルドする

下記1行を追加します。

- g++ hello.cpp -o hello

 

2-4. “parallel” 処理をやめて同時実行を1つのみに修正

Pipelines の実施をシンプルにすることを目的に、”Test” の step のみを残して他の step を削除して簡略化します。詳細説明を割愛。修正後の内容は後述の ”bitbucket-pipelines.yml” を参照。

(parallel は高速な実行を実現できるとても魅力的な機能ですが、この機能を使用するのは Pipelines をある程度使用できるようになってから検討しましょう。)

 

2-5. 以上の修正を実施後の "bitbucket-pipelines.yml"

以上の修正を行った結果の ”bitbucket-pipelines.yml” を以下に示します。

["bitbucket-pipelines.yml"]

image: ubuntu:18.04

pipelines:
  default:
    - step:
        name: Build
        script:
          - cat /etc/lsb-release
          - apt-get update
          - apt-get -y install build-essential
          - g++ hello.cpp -o hello

 

上記修正で Pipelines 実行を正常に完了できるようになりました。OS も “Ubuntu 18.04.6 LTS“ を意図通りにロードできていることを確認できました。

Pipelines 実行 Success

 

本書記載時点、正常終了した Pipelines に対するメールは届きませんでした。

 機能拡張「Jira and Bitbucket (Atlassian Labs)」をインストールした “VS code” から正常終了した Pipelines を下図のように確認することができました。

VS code の様子

 

以上で正常動作する “bitbucket-pipelines.yml” を構築できました。

 この後は少しずつ機能を加えていく感じで修正を行っていきたいと思います。

 


 

3. アーティファクトを登録する

アーティファクトは、ステップによって作成されるファイルです。パイプライン設定で定義したら、以降のステップで共有したり、エクスポートしてステップの完了後にアーティファクトを保持したりすることができます。たとえば、ビルド ステップで生成された JAR ファイルまたはレポートを、後のデプロイメント ステップで使用できます。ステップで生成されたアーティファクトをダウンロードしたり、外部ストレージにアップロードすることもできます。

次の点に留意する必要があります。

 

ここまで作成した “bitbucket-pipelines.yml“ にアーティファクト指定を加えてみます。

["bitbucket-pipelines.yml"] ファイルをアーティファクトへ登録した例

image: ubuntu:18.04

pipelines:
  default:
    - step:
        name: Build
        script:
          - cat /etc/lsb-release
          - apt-get update
          - apt-get -y install build-essential
          - g++ hello.cpp -o hello
        artifacts:
          - hello

 

["bitbucket-pipelines.yml"] フォルダーをアーティファクトへ登録した例

image: ubuntu:18.04

pipelines:
  default:
    - step:
        name: Build
        script:
          - cat /etc/lsb-release
          - apt-get update
          - apt-get -y install build-essential zip
          - mkdir out
          - g++ hello.cpp -o out/hello
        artifacts:
          - out/**

 

パイプラインを実行後の画面です。”Artifacs” の画面から “hello“ をダウンロードすることができます。

Artifact

 

参考:

 

 


 

4. デプロイする

アーティファクトは保存期間14日以内という制約がありました。
アーティファクトを14日以上保存する必要がある場合は他の場所へデプロイする必要があります。

AWS へ保存する、ftp で保存する、など様々な方法を Bitbucket は提供していますが、ここでは「ダウンロード」メニューからビルド結果を取得できるようにする方法を紹介します。
言い換えると、Pipelines にダウンロードサイトへ デプロイ する処理を追加します。

 

4-1. ステップ1: リポジトリ所有者向けにアプリパスワードを作成する

アプリパスワードを作成します。

 

(1) Bitbucket にログイン後、①設定アイコン 、②[Personal Bitbucket settings]を順にクリックします。

Personal Bitbucket settings

 

(2) メニューから [アクセス管理] のグループ中にある[アプリパスワード]を選択します。

アプリパスワード

 

(3) [アプリパスワードの作成] ボタンをクリックします。

 

(4) 下図中の ①、② を記入後、③をクリックします。

①の Label はユーザーの識別用に使用されるため「Pipelines」などの任意の名前を設定できます。

ここでは評価に使用しているリポジトリ名をそのまま使用します。

アプリパスワード

 

(5) 「新しいアプリ パスワード」を表示するので記録します。

新しいアプリパスワード

 

 

4-2. ステップ2: 認証トークンを使用して Pipelines 変数を作成する

Bitbucket Downloads にファイルをアップロードするには、以下の変数を設定する必要があります。

 

パラメータ名
BITBUCKET_USERNAME リポジトリを所有、かつアーティファクトをアップロードするユーザーの Bitbucket ユーザー名
BITBUCKET_APP_PASSWORD Bitbucket が生成したアプリパスワード

 

(1) リポジトリの設定で、特定のデプロイメント環境に対してこれらの変数を定義します。

 [Repository settings] > “PIPELINES“ の[Repository variables] をクリックします。

Repository variables

 

(2) 下記内容を "Repository variables" へ登録します。

Name Value
BITBUCKET_USERNAME リポジトリを所有、かつアーティファクトをアップロードするユーザーの Bitbucket ユーザー名
BITBUCKET_APP_PASSWORD Bitbucket が生成したアプリパスワード

 

重要

BITBUCKET_USERNAME として設定するのは、下図赤枠に表示の "ユーザー名" です。その上の "名前" ではありません。

 

BITBUCKET_USERNAME

 

設定後の様子(例)です。

Repository variables

 

 

4-3. ステップ3a: Bitbucket-upload-file パイプを使用したアーティファクトのデプロイ

アーティファクトを Bitbucket Downloads にアップロードするには、bitbucket-upload-file パイプを使用します。必要な作業は、アップロードするファイルをビルドのアウトプットから参照するだけです。

ここまでに作成した “bitbucket-pipelines.yml“ へ “bitbucket-upload-file“ パイプの処理を追加します。ここでは “step” を加える形で追加してみます。 “name: Deploy“ としました。

 下記例で FILENAME をフルパス表記で記載していますが、説明資料を見る限り ${BITBUCKET_CLONE_DIR} からの相対パスの表記で大丈夫そうです。ただし私は未確認ですのでご自身で試してみてください。

 

["bitbucket-pipelines.yml"]

image: ubuntu:18.04

pipelines:
  default:
    - step:
        name: Build
        script:
          - cat /etc/lsb-release
          - apt-get update
          - apt-get -y install build-essential
          - g++ hello.cpp -o hello
        artifacts:
          - hello
    - step:
        name: Deploy
        script:
          - echo $BITBUCKET_CLONE_DIR
          - pipe: atlassian/bitbucket-upload-file:0.3.3
            variables:
              BITBUCKET_USERNAME: $BITBUCKET_USERNAME
              BITBUCKET_APP_PASSWORD: $BITBUCKET_APP_PASSWORD
              FILENAME: "${BITBUCKET_CLONE_DIR}/hello"

 

NOTE

“BITBUCKET_CLONE_DIR“ はカレントパスを示す変数です。これを使用することでフルパス表記で FILENAME を記載しています。詳細は資料 “Variables in pipelines | Bitbucket Cloud | Atlassian Documentation” を参照してください。パイプラインで使用できる他の変数も確認することができます。

 

注意

2022/10/14 時点、スクリプト最新バージョンは 0.3.3 です。時々バージョンアップを行うようなので、注意しつつ原則最新版の使用をご検討ください。

- pipe: atlassian/bitbucket-upload-file:0.3.3

 

この “bitbucket-pipelines.yml“ によりパイプラインを実行した結果を以下に記載します。

こちらは パイプライン実行を成功 (Successful) した例です。

パイプライン実行を成功 (Successful) した例 

 

pipelines

 

[ダウンロード]をクリックすると、”hello” をダウンロードできるようになっていることを確認できます。

ダウンロード

 

NOTE

複数のファイルを登録する場合、事前に zip コマンドで圧縮したファイルを登録することを推奨します。

 

 

4-4. ステップ3b: curl および Bitbucket REST API を使用したアーティファクトのデプロイ

前述「ステップ3a」の pipe 処理部分を curl コマンドにより実行する方法を紹介します。

詳細は こちら 資料の「ステップ3b」を参照ください。

 

["bitbucket-pipelines.yml"]

image: ubuntu:18.04

pipelines:
  default:
    - step:
        name: Build
        script:
          - cat /etc/lsb-release
          - apt-get update
          - apt-get -y install build-essential
          - g++ hello.cpp -o hello
        artifacts:
          - hello
    - step:
        name: Deploy
        script:
          - echo $BITBUCKET_CLONE_DIR
          - curl -X POST "https://${BITBUCKET_USERNAME}:${BITBUCKET_APP_PASSWORD}@api.bitbucket.org/2.0/repositories/${BITBUCKET_REPO_OWNER}/${BITBUCKET_REPO_SLUG}/downloads" --form files=@"hello"

 

NOTE

Atlassian ドキュメント中に変数 BITBUCKET_REPO_OWNER の説明を見つけられませんでしたが、上記 YAML コードでちゃんと動作することを確認できました。

 

NOTE

REST API 詳細については The Bitbucket Cloud REST API (atlassian.com) を参照ください。

 

 

4-5. (参考) curl コマンドでダウンロードへ登録したファイルを取得する

ダウンロードへ登録したファイルを下記 curl コマンドによりダウンロードすることができます。任意の端末からダウンロードする、各種自動化などで活用する、Pipelines 実行時にビルド済み最新ライブラリを別リポジトリからダウンロードしてくる、など活用の可能性がいろいろありそうです。

 

■一般書式1

curl --user $USER_ID:$APP_PASSWORD -s -L https://api.bitbucket.org/2.0/repositories/{workspace}/{repo_slug}/downloads/{filename} -o {filename}

■一般書式2

curl --user $USER_ID:$APP_PASSWORD -s -L https://api.bitbucket.org/2.0/repositories/{workspace}/{repo_slug}/downloads/{filename} > {filename}

 

■具体例

項目 説明
$USER_ID ログインユーザのIDを記載します。ここでは私のID Hidetoshi_Kinoshita を例示します。
$APP_PASSWORD $USER_ID で取得済みのアプリパスワードです。例示では **** としていますが実際に使用時は取得したパスワードを入力します。
アプリパスワードの権限はリポジトリへ "書き込み" でテストしましたが、ファイル取得だけなら "読み取り" 権限だけでも良いかもしれません。
basic 認証では正常に動作しませんでした。アプリパスワードを使う必要があります。
{workspace} ワークスペース名を記載します。下記例では "Hidetoshi_Kinoshita" を指定しています。
{repo_slug} リポジトリ名を記載します。下記例では "test_repository" を指定しています。
{filename} 取得するファイル名です。 下記では "hello" を指定しています。

 

curl --user Hidetoshi_Kinoshita:************************************ -s -L https://api.bitbucket.org/2.0/repositories/Hidetoshi_Kinoshita/test_repository/downloads/hello -o hello

 

※ 上記コマンドによる動作確認は、Ubuntu 22.04 にて行いました。

 

参考:

 

 


 

5. パイプライントリガー

Pipelines のビルド構成は bitbucket-pipelines.yml ファイルで定義できます。Pipelines を初めて利用される場合は、Bitbucket Pipelines を使い始める のドキュメントをご確認ください。

パイプライントリガー

 

5-1. 手動でパイプラインを実行する

ブラウザ画面で Bitbucket のリポジトリを表示して、この画面から希望するブランチやコミットを対象にパイプライン実行することができます。

 

5-1-1. 手動実行のみ可能なパイプラインを設定する

パイプラインを手動でのみ実行したい場合、カスタム パイプラインを使用します。カスタム パイプラインは、ブランチへのコミットでは自動的に実行されません。カスタム パイプラインを定義するには、bitbucket-pipelines.yml ファイルの custom セクションにパイプライン構成を追加します。カスタム パイプラインとして定義されていないパイプラインは、ブランチへのプッシュが発生したときに自動的に実行されます。

カスタム パイプラインのもう 1 つのメリットは、変数の値を一時的に追加または更新できる点です。バージョン番号を追加したり、1 回のみ使用する値を提供したりするために使用できます。詳細は パイプライン トリガー | Bitbucket Cloud | アトラシアン サポート (atlassian.com) を参照してください。

パイプラインを手動で実行し、Bitbucket Cloud UI からトリガーするには、リポジトリへの書き込み権限が必要です。

 

["bitbucket-pipelines.yml" 例]

image: ubuntu:18.04

pipelines:
  custom: # Pipelines that can only be triggered manually
    - step:
        name: Build
        script:
          - echo "This script can only be triggerd manually (custom)."
          - cat /etc/lsb-release
          - apt-get update
          - apt-get -y install build-essential
          - g++ hello.cpp -o hello
        artifacts:
          - hello

 

 

5-1-2. ブランチとパイプランを選んで手動でパイプラインを実行する

ブラウザ画面から、ブランチとパイプランを選んで手動でパイプラインを実行する、手順を記載します。

下記のような bitbucket-pipelines.yml ファイルを登録している場合を例に説明します。

 

["bitbucket-pipelines.yml" 例]

image: ubuntu:18.04

pipelines:
  default:
    - step:
        name: Build
        script:
          - cat /etc/lsb-release
          - apt-get update
          - apt-get -y install build-essential zip
          - g++ hello.cpp -o hello
        artifacts:
          - hello
    - step:
        name: Deploy
        script:
          - pwd && ls -al
          - echo $BITBUCKET_CLONE_DIR
          - pipe: atlassian/bitbucket-upload-file:0.3.2
            variables:
              BITBUCKET_USERNAME: $BITBUCKET_USERNAME
              BITBUCKET_APP_PASSWORD: $BITBUCKET_APP_PASSWORD
              FILENAME: "${BITBUCKET_CLONE_DIR}/hello"

  custom: # Pipelines that can only be triggered manually
    custom-build:
      - step:
          script:
            - echo "This script can only be triggerd manually (custom)."
            - cat /etc/lsb-release
            - apt-get update
            - apt-get -y install build-essential
            - g++ hello.cpp -o hello
          artifacts:
            - hello

 

方法1

(1) [パイプライン]メニューを選択します。

(2) [Run pipeline] をクリックします。

custom-build

 

(3) ”Branch” と ”Pipeline” を選択後、[Run]ボタンをクリックします。

custom-build

 

以上の操作により、選択したブランチのコミット HEAD に対してパイプラインを実行します。

 

 

方法2

(1) [ブランチ]メニューを選択します。

 (2) パイプランを実行するブランチの [・・・] > [Run pipelines for a branch] をクリックします。

custom-build

 

(3) ”Pipeline” を選択後、[Run]ボタンをクリックします。

custom-build

 

以上の操作により、選択したブランチのコミット HEAD に対してパイプラインを実行します。

 

 

5-1-3. 特定コミットをパイプライン実行する

以下の手順で行います。

(1) [コミット]メニューを選択します。

(2) パイプラインを実行するコミットを選択します。

custom-build

 

(3) 「Run pipeline」をクリックします。

custom-build

 

(4) "Pipeline" を選択後、[Run]ボタンをクリックします。

custom-build

 

以上の操作により、コミットに対してパイプラインを実行します。

 

NOTE

当然のことですが、コミット時点の bitbucket-pipelines.yml ファイルに設定されている Pipelines 構成からのみ選択可能です。

 

 

5-2. 特定ブランチへのコミットをトリガーにパイプラインを実行する

プッシュ先のブランチに応じてパイプラインの動作を変えることができます。これを行うには、bitbucket-pipelines.yml ファイル内にブランチ固有の設定を含める必要があります。

bitbucket-pipelines.yml を設定する」も参照してください。

 

["bitbucket-pipelines.yml" 例]

image: ubuntu:18.04

pipelines:
  default:
    - step:
        script:
          - echo "This script runs on all branches that don't have any specific pipeline assigned in 'branches'."
  branches:
    main:
      - step:
          name: Build
          script:
            - echo "This script runs only on commit to the main branch."
            - cat /etc/lsb-release
            - apt-get update
            - apt-get -y install build-essential
            - g++ hello.cpp -o hello
          artifacts:
            - hello
    feature/*:
      - step:
          script:
            - echo "This script runs only on commit to branches with names that match the feature/* pattern."

 

 

以上の設定により、条件を満たすブランチへのコミットに対してパイプラインを実行します。

 

NOTE

プルリクエストからのマージもコミットとして使われます。

具体例として、例えば feature/add_function1 ブランチを develop ブランチへマージした場合は devekop ブランチへのコミットとして扱われて該当するパイプラインがあれば実行されます。

 

NOTE

複数のブランチ条件で同一の steps を実行する方法について下記で紹介されていました。

git - Bitbucket Pipelines - multiple branches with same steps - Stack Overflow

こんな感じで複数条件を記載すれば良いようです。

注意事項として '{rev,staging}' 内にスペースを加えてはいけないと記載されていました。

pipelines:
  branches:
    '{release/**,hotfix/**}':
      - step:
        script:
          - echo 'step'

 

 

5-3. "Pull Request" をトリガーにパイプラインを実行する

"Pull Request" をトリガーにパイプラインを実行する例について記載します。

 

["bitbucket-pipelines.yml" 例]

image: ubuntu:18.04

pipelines:
  pull-requests:
    '**':
      - step:
          script:
            - echo "This script runs on pull-requests to any branch not elsewhere defined."
    feature/*:
      - step:
          name: Build
          script:
            - echo "This script runs only on pull-requests to the main branch."
            - cat /etc/lsb-release
            - apt-get update
            - apt-get -y install build-essential
            - g++ hello.cpp -o hello
          artifacts:
            - hello

 

以上の操作により、条件を満足するブランチのプルリクエストおよびプルリクエスト中のコミットに対してパイプラインを実行します。

 

 

 

5-4. スケジュールでパイプラインを実行する

スケジュールされたパイプラインを使用すると、パイプラインを時間、日、または週単位で実行できます。パイプラインを例えば毎晩0時に実行する、というスケジュールによるパイプライン実行はよく使用されるパイプライン運用方法の一つです。

 

パイプラインのスケジュールを作成する

以下の手順でパイプラインのスケジュールを作成します。

 (1) Bitbucket のリポジトリに移動します。

(2) [パイプライン] > [Schedules] (右上) をクリックします。

pipelines - schedules

 

(3) [New schedule] をクリックします。

pipelines - schedules

 

(4) スケジュールを登録したいブランチとパイプラインを選択します。

pipelines - schedules

 

(5) スケジュールを設定します。

pipelines - schedules

 

pipelines - schedules

 

 

スケジュールの削除

[パイプライン] > [スケジュール] (画面右上の) に移動して、リポジトリのすべてのスケジュールを確認します。

 

参考:

 

 


 

6. パイプラインで git clone する


6-1. public リポジトリを git clone する

public リポジトリを “git clone“ する例として “google test“ のリポジトリを対象に git clone してみます。

下記にサンプルを記載します。

 

["bitbucket-pipelines.yml" 例]

image: ubuntu:18.04

pipelines:
  default:
    - step:
        name: git clone
        script:
          - apt-get update && apt-get -y install tzdata
          - export TZ="Asia/Tokyo" && date
          - apt-get -y install git
          - git clone https://github.com/google/googletest.git
          - ls
          - cd googletest
          - ls

 

説明をかなり割愛しますが、public リポジトリはこんな感じで簡単に git clone できます。

下図の通り、このパイプラインを全て正常に実行することができました。

Pipelines 中で git clone

 

重要

上記例では、下記2行を入れることが正しく動作させるためのコツです。

これら無しだと git インストール中に入力待ちとなって無限に Pipelines を終わらなくなるので注意してください。

またこの状態になってしまったら 手動で中止 する必要があることも注意してください。

- apt-get update && apt-get -y install tzdata

- export TZ="Asia/Tokyo" && date

 

 

6-2. 他の Bitbucket private リポジトリを git clone する

パイプラインの中で他の Bitbucket private リポジトリを git clone する手順について説明します。

下記のようなことをすることを想定します。Hidetoshi_Kinoshita/pipelines_test1.git はこの評価のために私が準備した実験用の private リポジトリです。

 

["bitbucket-pipelines.yml" 例]

image: ubuntu:18.04

pipelines:
  default:
    - step:
        name: git clone
        script:
          - apt-get update && apt-get -y install tzdata
          - export TZ="Asia/Tokyo" && date
          - apt-get -y install git
          - git clone git@bitbucket.org:Hidetoshi_Kinoshita/pipelines_test1.git
          - ls
          - cd pp_pipelines_test1
          - ls

 

まずはこのままパイプラインを実行して結果を確認してみます。

 

実行結果

 

実行結果

 

予想通りですが、「Permission denied (publickey) .」となって "git clone" を失敗しました。パイプラインに対して SSH 鍵を登録してリポジトリへアクセスできるようにする必要がある、ということです。

以下、パイプラインに対して SSH 鍵を登録する手順の説明です。

 

(1) パイプラインを実行する側のリポジトリ設定から「SSH keys」メニューをクリックします。

 

(2) [Generate keys] または [Use my own keys] ボタンをクリックします。

ここでは [Generate keys] ボタンをクリックして進みます。

Generate keys

 

(3) "Private key" と "Public key" を生成して下図のような画面へ表示します。

SSH keys

 

(4) [Copy public key] ボタンをクリックして ”public key” をコピーします。

SSH keys

 

(5) ターゲットリポジトリへ “public key“ を登録します。リポジトリ("pipelines_test1")へ移動して、[Repository settings] > [一般] > [アクセスキー] をクリックします。

SSH keys

 

(6) [Add key] ボタンをクリックします。

SSH keys

 

(7) 下図のような画面を表示するので、必要事項を記入後に [Add SSH key] ボタンをクリックします。

SSH keys

 

ここでは下図のように入力してみました。[Add SSH key] ボタンをクリックします。

SSH keys

 

するとこんな感じの画面表示となりました。

SSH keys

 

以上で SSH 鍵の設定を完了です。

 

(8) 先程失敗(Failed)となったパイプラインを再度実行してみます。

[Run pipelines] ボタンをクリックします。

Run pipeline

 

下図画面を表示するので[Run]ボタンをクリックします。

Run pipeline

 

Run pipeline

 

パイプライン実行を成功です。

以上の手順により、他の Bitbucket private リポジトリから git clone できることを確認できました。

 

参考:

 


 

7. アーティファクトのファイル名にビルド番号を付ける

変数 BITBUCKET_BUILD_NUMBER によりパイプライン中でビルド番号を使うことができます。これを使うことでパイプラインを実行する度にファイル名やフォルダ名を変えることが可能になります。

 

["bitbucket-pipelines.yml" 例]

image: ubuntu:18.04

pipelines:
  default:
    - step:
        name: Build
        script:
          - cat /etc/lsb-release
          - apt-get update
          - apt-get -y install build-essential
          - mkdir out
          - g++ hello.cpp -o out/hello_$BITBUCKET_BUILD_NUMBER
          - ls out
        artifacts:
          - out/**

 

これを実行することで hello_6 というファイルを出力することができました。6 という値はビルド番号 #6 からくるものです。

BITBUCKET_BUILD_NUMBER 使用方法

 

NOTE

'artifacts' で $BITBUCKET_BUILD_NUMBER を使うことはできないように見えます。

下記のようなサンプルで実験しましたが、 out_$BITBUCKET_BUILD_NUMBER/** を artifacts へ登録できませんでした。'script' を全て正常に動作できていることから、 artifacts 固有の問題と推測しています。

 

["bitbucket-pipelines.yml" 例]

image: ubuntu:18.04

pipelines:
  default:
    - step:
        name: Build
        script:
          - cat /etc/lsb-release
          - apt-get update
          - apt-get -y install build-essential zip
          - mkdir out
          - mkdir out_$BITBUCKET_BUILD_NUMBER
          - g++ hello.cpp -o out/hello_$BITBUCKET_BUILD_NUMBER
          - cp out/hello_$BITBUCKET_BUILD_NUMBER out_$BITBUCKET_BUILD_NUMBER/hello_$BITBUCKET_BUILD_NUMBER
          - ls out
          - ls out_$BITBUCKET_BUILD_NUMBER
        artifacts:
          - out/**
          - out_$BITBUCKET_BUILD_NUMBER/**

 

参考:

 


 

8. ユニットテストを行う

Pipelines 上でユニットテストを実施します。

cmake でユニットテストを構成済みであることを前提として以下を記載します。

 

 

["bitbucket-pipelines.yml" 例]

image: ubuntu:22.04

pipelines:
  default:
    - parallel:
      - step:
          name: build and unit-test
          script:
            - apt-get update && apt-get -y install tzdata
            - export TZ="Asia/Tokyo" && date
            - apt-get -y install build-essential cmake
            - gcc --version && cmake --version && lcov --version && cppcheck --version
            # build and install googletest.
            - tar zxvf release-1.12.0.tar.gz    # googletest
            - cd googletest-release-1.12.0
            - mkdir build
            - cd build
            - cmake ..
            - make
            - make install
            - cd ..
            - cd ..
            # build and tests.
            - mkdir build
            - cd build
            - cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DBUILD_TESTING=ON ..
            - make
            # do unit-tests.
            - ctest --output-on-failure

 

以下、CMakeLists.txt の部分の身参考記載します。

[(参考) "CMakeLists.txt" 例]

# このバージョン以上のCMAKEを使うよう宣言
cmake_minimum_required(VERSION 3.10)

# プロジェクト名.c/c++言語であることを宣言
#project(sample CXX)
project(sample C)

# バージョン番号
set(serial "1.0.0")

# c++17 が必要
set(CMAKE_CXX_STANDARD 17)

# デバッグ出力
message(STATUS "PROJECT_SOURCE_DIR = ${PROJECT_SOURCE_DIR}")
message(STATUS "PROJECT_BINARY_DIR = ${PROJECT_BINARY_DIR}")
message(STATUS "CMAKE_CXX_STANDARD = ${CMAKE_CXX_STANDARD}")

# 共通オプション
set(CMAKE_CXX_FLAGS "--coverage")
set(CMAKE_C_FLAGS "--coverage")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --coverage")

# ビルドの種類によってオプションを変える
set(CMAKE_CXX_FLAGS_DEBUG "-Wall -O0 -g")
set(CMAKE_CXX_FLAGS_RELEASE "-Wall -O3 -DNDEBUG")
set(CMAKE_CXX_FLAGS_MINSIZEREL "-Wall -Os -DNDEBUG")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-Wall -O2 -g -DNDEBUG")
set(CMAKE_C_FLAGS_DEBUG "-Wall -O0 -g")
set(CMAKE_C_FLAGS_RELEASE "-Wall -O3 -DNDEBUG")
set(CMAKE_C_FLAGS_MINSIZEREL "-Wall -Os -DNDEBUG")
set(CMAKE_C_FLAGS_RELWITHDEBINFO "-Wall -O2 -g -DNDEBUG")

include_directories(include)

add_subdirectory(PfLogPrintf)

# ライブラリの作成を指示.SHARED で共有ライブラリ
# sample.c を元に、libsample.so という名前で作成
add_library(sample SHARED sample.c)

# sample.so をビルドする際に PfLogPrintf をリンクする
target_link_libraries(sample PfLogPrintf)

if(BUILD_TESTING)
  # ctest を valgrind ありで実行するために下記が必要
  include(CTest)

  # テストを有効化
  enable_testing()
  # サブディレクトリを指定.指定したディレクトリ内のCMakeLists.txt が実行される
  add_subdirectory(test)
endif()

# capability ライブラリのインクルードディレクトリを教えてあげる
# PROJECT_SOURCE_DIRはこのプロジェクトのルートディレクトリの絶対パス
target_include_directories( sample
  PUBLIC ${PROJECT_SOURCE_DIR}/include
  )

 

[(参考) test フォルダ内の "CMakeLists.txt" 例]

# このバージョン以上のCMAKEを使うよう宣言
cmake_minimum_required(VERSION 3.10)

# プロジェクト名.c/c++言語であることを宣言
project(test_sample CXX)
#project(test_sample C)

# To use the googletest
find_package(GTest REQUIRED)

# デバッグ出力
message(STATUS "PROJECT_SOURCE_DIR = ${PROJECT_SOURCE_DIR}")
message(STATUS "PROJECT_BINARY_DIR = ${PROJECT_BINARY_DIR}")
message(STATUS "CMAKE_CXX_STANDARD = ${CMAKE_CXX_STANDARD}")

# 共通オプション
set(CMAKE_CXX_FLAGS "--coverage")
set(CMAKE_C_FLAGS "--coverage")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --coverage")

# ビルドの種類によってオプションを変える
set(CMAKE_CXX_FLAGS_DEBUG "-Wall -O0 -g")
set(CMAKE_CXX_FLAGS_RELEASE "-Wall -O3 -DNDEBUG")
set(CMAKE_CXX_FLAGS_MINSIZEREL "-Wall -Os -DNDEBUG")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-Wall -O2 -g -DNDEBUG")

# リンクディレクトリの指定
#link_directories(PfLogPrintf)

# 今回作成する実行ファイル test_sample, ソースファイル3つ
add_executable(
    test_sample
    function1_test.cpp
    function2_test.cpp
    function3_test.cpp
    )
 
# gtest, pthread をリンクします
target_link_libraries(
    test_sample 
    ${GTEST_BOTH_LIBRARIES} 
    pthread
    sample)

#target_link_libraries(test_sample GTest::GTest GTest::Main)
target_include_directories(test_sample PUBLIC ${GTEST_INCLUDE_DIRS})

include(GoogleTest)
gtest_add_tests(TARGET test_sample)

 

 

 


 

9. ユニットテストへ動的解析を加える (Valgrind)

Valgrind(ヴァルグリンド)は、メモリデバッグや、メモリリークの検出、スレッドエラーの検出、プロファイリングなどを行うための仮想機械を利用したソフトウェア開発ツールです。

ユニットテストと Valgrind を併用するのはとても有益で良い方法の1つです。

Valgrind で最もよく利用されている標準のツールは Memcheck です。 Memcheck はほぼすべての命令に特別な計測用のコードを挿入し、「正当性」があり、「アドレス可能」であるかという情報が、それぞれVビットおよびAビットに格納されているかを追跡します。データは移動したり加工されたりするが、計測用のコードは1ビットレベルで正確であるようにA、Vビットを追跡します。

さらに、Memcheck は標準のCメモリアロケータを独自の実装に置き換え、割り当て済みブロックの前後にメモリガードを挿入します。この機能により、Memcheck はプログラムが割り当てられたブロックよりわずかに外側の領域を読み書きする off-by-one エラーを検出できます。

Memcheck が検出や警告可能な問題には、下記のものがあります。

こうした機能への代償として処理性能が低下します。Memcheckの元で動作するプログラムはValgrindなしで動作する場合と比べて5倍から20倍遅く、また多くのメモリを使用します。(メモリ確保ごとにかなりのメモリを追加で消費します)。したがって、ほとんどの開発者は常にMemcheck(あるいは他のValgrindツール)の元でコードを走らせることはしません。特定のバグを解析したり、(Memcheckが検出可能な種類の)潜在的なバグがないことを検証するために使用するのが最も典型的な方法です。

 

ユニットテストの実行を Valgrind で実施する手順を以下に記載します。ここでは ctest のオプション指定を変更することで実施する例を示します。(ctest は標準で Valgrind をサポートしています。)

 

  1. apt-get install で Valgrind を追加します。
    apt-get install -y valgrind
  2. 前述のユニットテストを下記の通り変更します。
    (新) ctest --output-on-failure -T MemCheck --overwrite MemoryCheckCommandOptions="--leak-check=full --error-exitcode=1"
    (旧) ctest --output-on-failure

 

["bitbucket-pipelines.yml" 例]

image: ubuntu:22.04

pipelines:
  default:
    - parallel:
      - step:
          name: build and unit-test, coverage
          script:
            - apt-get update && apt-get -y install tzdata
            - export TZ="Asia/Tokyo" && date
            - apt-get -y install build-essential cmake valgrind lcov cppcheck zip
            - gcc --version && cmake --version && lcov --version && cppcheck --version
            # build and install googletest.
            - tar zxvf release-1.12.0.tar.gz    # googletest
            - cd googletest-release-1.12.0
            - mkdir build
            - cd build
            - cmake ..
            - make
            - make install
            - cd ..
            - cd ..
            # build IoGeneral and tests.
            - mkdir build
            - cd build
            - cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DBUILD_TESTING=ON ..
            - make
            # do unit-tests.
            - ctest --output-on-failure -T MemCheck --overwrite MemoryCheckCommandOptions="--leak-check=full --error-exitcode=1"

 

 

 


 

10. ユニットテストへソースコードカバレッジを加える

ソースコードカバレッジ処理を追加する例を以下に記載します。

 

["bitbucket-pipelines.yml" 例]

image: ubuntu:22.04

pipelines:
  default:
    - parallel:
      - step:
          name: build and unit-test, coverage
          script:
            - apt-get update && apt-get -y install tzdata
            - export TZ="Asia/Tokyo" && date
            - apt-get -y install build-essential cmake valgrind lcov cppcheck zip
            - gcc --version && cmake --version && lcov --version && cppcheck --version
            # build and install googletest.
            - tar zxvf release-1.12.0.tar.gz    # googletest
            - cd googletest-release-1.12.0
            - mkdir build
            - cd build
            - cmake ..
            - make
            - make install
            - cd ..
            - cd ..
            # build sample and tests.
            - mkdir build
            - cd build
            - cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DBUILD_TESTING=ON ..
            - make
            # do unit-tests.
            - ctest --output-on-failure
          after-script:
            # source code coverage <-
            - pwd && ls
            - pushd build/CMakeFiles/sample.dir
            - lcov -d . -c -o sample.info --rc lcov_branch_coverage=1
            - lcov -r sample.info */googletest/* test/* */c++/* -o sampleFiltered.info --rc lcov_branch_coverage=1
            - genhtml -o lcovHtml --num-spaces 4 -s --legend sampleFiltered.info --branch-coverage
            - popd
            # ->
            # deploy results of source code coverage.
            - echo $BITBUCKET_CLONE_DIR
            - zip -r lcovHtml_IoGeneral.zip build/CMakeFiles/sample.dir/lcovHtml
            - pipe: atlassian/bitbucket-upload-file:0.3.2
              variables:
                BITBUCKET_USERNAME: $BITBUCKET_USERNAME
                BITBUCKET_APP_PASSWORD: $BITBUCKET_APP_PASSWORD
                FILENAME: "${BITBUCKET_CLONE_DIR}/lcovHtml_sample.zip"
            # ->

          artifacts:
            - build/CMakeFiles/sample.dir/lcovHtml/**

 

ソースコードカバレッジ測定の主たる実行部分は下記3行です。

            - lcov -d . -c -o sample.info --rc lcov_branch_coverage=1
            - lcov -r sample.info */googletest/* test/* */c++/* -o sampleFiltered.info --rc lcov_branch_coverage=1
            - genhtml -o lcovHtml --num-spaces 4 -s --legend sampleFiltered.info --branch-coverage

 

 

以上の処理により下図のような結果を取得することができます。

カバレッジ結果

 

カバレッジ結果

 

 


 

11. 静的解析を行う (cppcheck)

オープンソースの静的解析ツール(cppcheck)を pipelines 中で適用する例を紹介します。

 

["bitbucket-pipelines.yml" 例]

image: ubuntu:22.04

pipelines:
  default:
    - parallel:           
      - step:
          name: cppcheck
          script:
            - apt-get update && apt-get -y install tzdata
            - export TZ="Asia/Tokyo" && date
            - apt-get -y install build-essential cmake valgrind lcov cppcheck
            - cppcheck --version
            # build and install googletest.
            - tar zxvf release-1.12.0.tar.gz    # googletest
            - cd googletest-release-1.12.0
            - mkdir build
            - cd build
            - cmake ..
            - make
            - make install
            - cd ..
            - cd ..
            # build sample
            - mkdir build
            - cd build
            - cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DBUILD_TESTING=ON ..
            # cppcheck
            - cppcheck --project=compile_commands.json --enable=all --error-exitcode=1 --inline-suppr --force --suppressions-list=../suppressions_list.txt -i$BITBUCKET_CLONE_DIR/test/

 

 


 

Appendix

 

A.1. Pipelines の step における失敗によるスクリプト停止を避ける方法

Pipelines は Linux 上でbash / shellコマンドを実行しているだけです。スクリプトランナーは、各コマンドの戻り状況コードを探して成功したか失敗したかを確認します。したがって、さまざまな手法を使用してこのステータスコードを制御できます。

 

方法1

あなたのコマンドの末尾に " || true" を加える、という方法があります。

(例) ./gradlew -DBASE_URL=qa2 clean BSchrome_win || true

 

方法2

必ず実行したいステップを after-script へ記載すると、前のステップの成功/失敗ステータスに関係なく常に実行することができます。

- step:
    name: Hoge
    script:
      - 何か処理する
      - 何か処理する
    after-script:
      - cd config/geb # You may need this, if the current working directory is reset. Check with 'pwd'
      - cd build/reports
      - zip -r testresult.zip BSchrome_winTest 

 

 

 

A.2. Pipelines 最長実行時間を変更する方法

Pipelines は step 1つに対して最長 120分 を実行することができます。max-time を設定することでこの値を変更することができ、(1-120) の範囲でこの値を変更可能です。

 

options:  
   max-time: 60

 

 


 

 

 

ライセンス

本ページの情報は、特記無い限り下記 MIT ライセンスで提供されます。

The MIT License (MIT)

  Copyright 2021 Kinoshita Hidetoshi

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

 

 

参考

 


 

変更履歴

2021-04-10 - 新規作成

 

Programming Items トップページ

プライバシーポリシー