Skip to main content

CIシステムでのCodeQL CLIの設定

継続的インテグレーションシステムをCodeQL CLIを実行するように設定し、CodeQL分析を行い、code scanningアラートとして表示させるために結果をGitHub Enterprise Serverにアップロードできます。

Code scanning は、GitHub Enterprise Server の Organization 所有のリポジトリで利用できます。 この機能には、GitHub Advanced Security のライセンスが必要です。 詳細については、「GitHub Advanced Security について」を参照してください。

注: この機能を使うには、サイト管理者が your GitHub Enterprise Server instance の code scanning を有効にする必要があります。 詳細については、「アプライアンスでの code scanning の構成」を参照してください。

注: この記事では、GitHub Enterprise Server のリリース時に使用可能なバージョンの CodeQL CLIに存在する機能について説明します。 Enterprise でより新しいバージョンの CodeQL CLI を使用している場合は、代わりに GitHub Enterprise Cloud のドキュメントを参照してください。

CodeQL CLIでのCode scanningの結果の生成について

CIシステム内のサーバーでCodeQL CLIを利用できるようにして、確実にGitHub Enterprise Serverで認証できるようにしたなら、データを生成する準備ができています。

結果を生成してGitHub Enterprise Serverにアップロードするには、3つの異なるコマンドを使います。

  1. database create では、リポジトリのサポートされている各プログラミング言語の階層構造を表すために CodeQL データベースを作成します。
  2. database analyze では、クエリを実行して各 CodeQL データベースを分析し、結果を SARIF ファイルにまとめます。
  3. github upload-results では、結果の SARIF ファイルを GitHub Enterprise Server にアップロードします。そこで結果はブランチまたは pull request と照合され、code scanning アラートとして表示されます。

--help オプションを使用して、任意のコマンドのコマンドライン ヘルプを表示できます。

注: GitHub Enterprise Server の結果の code scanning として表示する SARIF データをアップロードすることは、GitHub Advanced Security が有効にされた組織が所有するリポジトリ。 詳細については、「リポジトリのセキュリティと分析の設定を管理する」を参照してください。

分析するCodeQLデータベースの作成

  1. 分析するコードをチェックアウトします。

    • ブランチの場合は、分析するブランチのヘッドをチェックアウトします。
    • pull request の場合は、pull request のヘッド コミットをチェックアウトするか、GitHub で生成された pull request のマージ コミットをチェックアウトします。
  2. コードベースの環境を設定し、依存関係が使用可能であることを確認します。 詳細については、CodeQL CLI のドキュメントの「コンパイルされていない言語のデータベースの作成」および 「コンパイル済み言語のデータベースの作成」を参照してください。

  3. コードベースのビルド コマンドを見つけます (ある場合)。 通常、これは CI システムの構成ファイルで使用できます。

  4. リポジトリのチェックアウト ルートから codeql database create を実行し、コードベースをビルドします。

    # Single supported language - create one CodeQL database
    codeql database create <database> --command<build> --language=<language-identifier>
    
    # Multiple supported languages - create one CodeQL database per language
    codeql database create <database> --command<build> \
          --db-cluster --language=<language-identifier>,<language-identifier>

    注: コンテナー化されたビルドを使用する場合は、ビルド タスクが行われるコンテナーで CodeQL CLI を実行する必要があります。

オプション必須使用法
<database>CodeQLデータベースを作成するディレクトリの名前と場所を指定します。 既存のディレクトリを上書きしようとすると、コマンドは失敗します。 また --db-cluster を指定した場合は、これが親ディレクトリであり、分析される言語ごとにサブディレクトリが作成されます。
--languageデータベースを作成する言語の識別子 (cpp`、`csharp`、`go`、`java`、`javascript`、`python`、および `ruby のいずれか) を指定します (TypeScript コードを分析するには javascript を使用します)。 --db-cluster と一緒に使用する場合は、オプションでコンマ区切りリストが受け入れられるか、複数指定できます。
--command推奨。 コードベースのビルド プロセスを呼び出すビルド コマンドまたはスクリプトを指定するために使用します。 コマンドは現在のフォルダーから、または定義されている場合は --source-root から実行されます。 Python および JavaScript または TypeScript の分析には不要です。
--db-cluster省略可能。 --language によって指定された言語ごとに 1 つのデータベースを生成するには、複数言語コードベースを使用します。
--no-run-unnecessary-builds推奨。 CodeQL CLIがビルドをモニターする必要がない場合に、言語のビルドコマンドを抑制するために使います(たとえばPythonやJavaScript/TypeScript)。
--source-root省略可能。 リポジトリのチェックアウト ルートの外部で CLI を実行する場合に使用します。 既定では、database create コマンドで現在のディレクトリがソース ファイルのルート ディレクトリであると見なされます。別の場所を指定するためにこのオプションを使用します。
--codescanning-config省略可能 (詳細) CodeQL データベースの作成方法と、後の手順で実行するクエリを指定する構成ファイルがある場合に使用します。 詳細については、「code scanning のカスタマイズ」と「database create」を参照してください。

詳細については、CodeQL CLI のドキュメントの「CodeQL データベースの作成」を参照してください。

単一言語の例

この例では、/checkouts/example-repo でチェックアウトされたリポジトリの CodeQL データベースを作成します。 JavaScript 抽出機能を使用して、リポジトリに JavaScript および TypeScript コードの階層表現を作成します。 結果のデータベースは /codeql-dbs/example-repo に格納されます。

$ codeql database create /codeql-dbs/example-repo --language=javascript \
    --source-root /checkouts/example-repo

> Initializing database at /codeql-dbs/example-repo.
> Running command [/codeql-home/codeql/javascript/tools/autobuild.cmd]
    in /checkouts/example-repo.
> [build-stdout] Single-threaded extraction.
> [build-stdout] Extracting
...
> Finalizing database at /codeql-dbs/example-repo.
> Successfully created database at /codeql-dbs/example-repo.

複数言語の例

この例では、/checkouts/example-repo-multi でチェックアウトされたリポジトリの CodeQL データベースを 2 つ作成します。 イベント プロセッサで使用されるものは次のとおりです。

  • --db-cluster: 複数の言語の分析を要求します。
  • --language: データベースを作成する言語を指定します。
  • --command: コードベースのビルド コマンド (ここでは make) をツールに伝えます。
  • --no-run-unnecessary-builds: 必要のない言語 (Python など) のビルド コマンドをスキップするようにツールに伝えます。

結果のデータベースは、/codeql-dbs/example-repo-multipython および cpp サブディレクトリに格納されます。

$ codeql database create /codeql-dbs/example-repo-multi \
    --db-cluster --language python,cpp \
    --command make --no-run-unnecessary-builds \
    --source-root /checkouts/example-repo-multi
Initializing databases at /codeql-dbs/example-repo-multi.
Running build command: [make]
[build-stdout] Calling python3 /codeql-bundle/codeql/python/tools/get_venv_lib.py
[build-stdout] Calling python3 -S /codeql-bundle/codeql/python/tools/python_tracer.py -v -z all -c /codeql-dbs/example-repo-multi/python/working/trap_cache -p ERROR: 'pip' not installed.
[build-stdout] /usr/local/lib/python3.6/dist-packages -R /checkouts/example-repo-multi
[build-stdout] [INFO] Python version 3.6.9
[build-stdout] [INFO] Python extractor version 5.16
[build-stdout] [INFO] [2] Extracted file /checkouts/example-repo-multi/hello.py in 5ms
[build-stdout] [INFO] Processed 1 modules in 0.15s
[build-stdout] <output from calling 'make' to build the C/C++ code>
Finalizing databases at /codeql-dbs/example-repo-multi.
Successfully created databases at /codeql-dbs/example-repo-multi.
$

CodeQLデータベースの分析

  1. CodeQLデータベースを作成してください(上記参照)。
  2. データベースに対して codeql database analyze を実行し、使用するクエリを指定します。
    codeql database analyze <database> --format=<format> \
        --output=<output>  <queries>

注: 1 つのコミットに対して複数の CodeQL データベースを分析する場合、このコマンドによって生成されるそれぞれの結果セットに対して SARIF カテゴリを指定する必要があります。 結果をGitHub Enterprise Serverにアップロードする際には、code scanningはこのカテゴリを使ってそれぞれの言語に対する結果を別々に保存します。 この操作を忘れた場合は、各アップロードで前の結果が上書きされます。

codeql database analyze <database> --format=<format> \
    --sarif-category=<language-specifier> --output=<output> \
    <queries>
オプション必須使用法
<database>分析するCodeQLデータベースを含むディレクトリのパスを指定します。
<packs,queries>実行する CodeQL パックまたはクエリを指定します。 code scanning に使用される標準クエリを実行するには、このパラメーターを省略します。 CodeQL CLI バンドルに含まれている他のクエリ スイートを確認する場合は、/<extraction-root>/qlpacks/codeql/<language>-queries/codeql-suites を参照してください。 独自のクエリ スイートの作成については、CodeQL CLI のドキュメントの「CodeQL クエリ スイートの作成」を参照してください。
--formatコマンドによって生成される結果ファイルの形式を指定します。 GitHub へのアップロードの場合、これは sarifv2.1.0 である必要があります。 詳細については、「code scanning の SARIF サポート」を参照してください。
--outputSARIF 結果ファイルを保存する場所を指定します。
--sarif-category単一データベースの分析の場合は省略可能です。 リポジトリ内の単一コミットに対して複数のデータベースを分析する場合に言語を定義するために必要です。 この分析の SARIF 結果ファイルに含めるカテゴリを指定します。 カテゴリは、同じツールとコミットに対する複数の分析を区別するために使用されますが、異なる言語またはコードの異なる部分で実行されます。
--sarif-add-query-help省略可能。 分析で使用されるカスタム クエリに対して使用可能なマークダウン レンダリング クエリ ヘルプを含める場合に使用します。 関連するクエリによってアラートが生成された場合は、SARIF 出力に含まれるカスタム クエリのクエリ ヘルプがすべてコード スキャン UI に表示されます。 詳細については、CodeQL CLI のドキュメントの「CodeQL CLI でのデータベースの分析」を参照してください。
--threads任意。 複数のスレッドを使用してクエリを実行する場合に使用します。 既定値は 1 です。 クエリの実行を高速化するために、より多くのスレッドを指定できます。 スレッドの数を論理プロセッサの数に設定するには、0 を指定します。
--verbose省略可能。 データベース作成プロセスから分析プロセスと診断データに関する詳細情報を取得するために使用します。

詳細については、CodeQL CLI のドキュメントの「CodeQL CLI でのデータベースの分析」を参照してください。

基本的な例

この例では、/codeql-dbs/example-repo で格納されている CodeQL データベースを分析し、結果を SARIF ファイル (/temp/example-repo-js.sarif) として保存します。 --sarif-category を使用して、結果を JavaScript として識別する追加の情報を SARIF ファイルに含めます。 これは、リポジトリ中の単一のコミットに対して分析するCodeQLデータベースが複数ある場合に不可欠です。

$ codeql database analyze /codeql-dbs/example-repo  \
    javascript-code-scanning.qls --sarif-category=javascript \
    --format=sarifv2.1.0 --output=/temp/example-repo-js.sarif

> Running queries.
> Compiling query plan for /codeql-home/codeql/qlpacks/codeql-javascript/AngularJS/DisablingSce.ql.
...
> Shutting down query evaluator.
> Interpreting results.

GitHub Enterprise Serverへの結果のアップロード

注:

  • SARIF アップロードでは、アップロードごとに最大 5,000 件の結果がサポートされます。 この制限を超える結果はすべて無視されます。 ツールで生成される結果が多すぎる場合は、最も重要なルールまたはクエリの結果に焦点を当てるように構成を更新する必要があります。

  • SARIF アップロードでサポートされる gzip 圧縮の SARIF ファイルの最大サイズは、アップロードごとに 10 MB となります。 この制限を超えるアップロードはすべて拒否されます。 含まれる結果が多すぎるために SARIF ファイルが大きくなりすぎた場合は、最も重要なルールまたはクエリの結果に焦点を当てるように構成を更新する必要があります。

結果を GitHub Enterprise Server にアップロードする前に、以前に作成した GitHub Appまたは personal access token を CodeQL CLI に渡す最善の方法を決める必要があります (「CI システムでの CodeQL CLI のインストール」を参照)。 シークレット ストアの安全な使用に関する CI システムのガイダンスを確認することをお勧めします。 CodeQL CLIは以下をサポートします。

  • --github-auth-stdin オプションを使用し、標準入力を介して CLI にトークンを渡す (推奨)。
  • 環境変数 GITHUB_TOKEN にシークレットを保存し、--github-auth-stdin オプションを含めずに CLI を実行する。

CI サーバーの最も安全で信頼性の高い方法を決定した場合は、各 SARIF 結果ファイルで codeql github upload-results を実行し、トークンが環境変数 GITHUB_TOKEN で使用可能でない限り、--github-auth-stdin を含めます。

echo "$UPLOAD_TOKEN" | codeql github upload-results --repository=<repository-name> \
      --ref=<ref> --commit=<commit> --sarif=<file> \
      --github-url=<URL> --github-auth-stdin
オプション必須使用法
--repositoryデータのアップロード先となるリポジトリの OWNER/NAME を指定します。 オーナーは GitHub Advanced Security のライセンスを持つ Enterprise 内の Organization でなければならず、GitHub Advanced Security はリポジトリで有効化されていなければなりません。 詳細については、「リポジトリのセキュリティと分析の設定を管理する」を参照してください。
--refチェックアウトして分析した ref の名前を指定して、結果を正しいコードと照合できるようにします。 ブランチで refs/heads/BRANCH-NAME を使用するか、pull request のヘッド コミットで refs/pull/NUMBER/head を使用するか、pull request の GitHub で生成されたマージ コミットで refs/pull/NUMBER/merge を使用します。
--commit分析したコミットの完全な SHA を指定します。
--sarif読み込む SARIF ファイルを指定します。
--github-urlGitHub Enterprise ServerのURLを指定してください。
--github-auth-stdin任意。 GitHub の REST API での認証用に作成された GitHub App または personal access token を標準入力で CLI に渡すために使います。 このトークンを使用して設定された GITHUB_TOKEN 環境変数にコマンドがアクセスできる場合、これは必要ありません。

詳細については、CodeQL CLI のドキュメントの「github upload-results」を参照してください。

基本的な例

この例では、SARIF ファイル temp/example-repo-js.sarif からリポジトリ my-org/example-repo に結果をアップロードします。 結果が main ブランチのコミット deb275d2d5fe9a522a0b7bd8b6b6a1c939552718 に対するものであることを code scanning API に伝えます。

$ echo $UPLOAD_TOKEN | codeql github upload-results --repository=my-org/example-repo \
    --ref=refs/heads/main --commit=deb275d2d5fe9a522a0b7bd8b6b6a1c939552718 \
    --sarif=/temp/example-repo-js.sarif --github-url=https://github.example.com \
    --github-auth-stdin

アップロードが失敗しなければ、このコマンドからの出力はありません。 コマンドプロンプトは、アップロードが完了してデータ処理が開始された時点で戻ってきます。 小さなコードベースでは、すぐ後にGitHub Enterprise Server中のcode scanningアラートを調べることができるでしょう。 チェックアウトしたコードに応じて、アラートを直接 pull request に、またはブランチの [セキュリティ] タブで表示できます。詳細については、「pull request でのcode scanning アラートのトリアージ」および「リポジトリのcode scanning アラートを管理する」を参照してください。

CodeQL分析のためのCIの設定例

これは、2つのサポートされている言語を持つコードベースを分析し、結果をGitHub Enterprise Serverにアップロードするために使うことができる一連のコマンドの例です。

# Create CodeQL databases for Java and Python in the 'codeql-dbs' directory
# Call the normal build script for the codebase: 'myBuildScript'

codeql database create codeql-dbs --source-root=src \
    --db-cluster --language=java,python --command=./myBuildScript

# Analyze the CodeQL database for Java, 'codeql-dbs/java'
# Tag the data as 'java' results and store in: 'java-results.sarif'

codeql database analyze codeql-dbs/java java-code-scanning.qls \
    --format=sarif-latest --sarif-category=java --output=java-results.sarif

# Analyze the CodeQL database for Python, 'codeql-dbs/python'
# Tag the data as 'python' results and store in: 'python-results.sarif'

codeql database analyze codeql-dbs/python python-code-scanning.qls \
    --format=sarif-latest --sarif-category=python --output=python-results.sarif

# Upload the SARIF file with the Java results: 'java-results.sarif'

echo $UPLOAD_TOKEN | codeql github upload-results --repository=my-org/example-repo \
    --ref=refs/heads/main --commit=deb275d2d5fe9a522a0b7bd8b6b6a1c939552718 \
    --sarif=java-results.sarif --github-auth-stdin

# Upload the SARIF file with the Python results: 'python-results.sarif'

echo $UPLOAD_TOKEN | codeql github upload-results --repository=my-org/example-repo \
    --ref=refs/heads/main --commit=deb275d2d5fe9a522a0b7bd8b6b6a1c939552718 \
    --sarif=python-results.sarif --github-auth-stdin

CIシステムでのCodeQL CLIのトラブルシューティング

ログと診断情報を見る

code scanningクエリスイートを使ってCodeQLデータベースを分析する際には、アラートに関する詳細情報を生成するのに加えて、CLIはデータベース生成ステップからの診断情報とサマリメトリクスを報告します。 アラートが少ないリポジトリでは、実際にコード中の問題が少ないのか、あるいはCodeQLデータベースの生成時にエラーがあったのかを判断するのにこの情報が役立つかもしれません。 codeql database analyze からさらに詳しい出力を得るには、--verbose オプションを使用します。

使用可能な診断情報の種類について詳しくは、「code scanning ログの表示」を参照してください。

Code scanningは、分析された言語の1つからの分析結果だけを表示します。

デフォルトでは、code scanningはリポジトリの分析ごとに1つのSARIF結果ファイルを期待します。 したがって、コミットから2つめのSARIF結果ファイルをアップロードすると、それはデータのオリジナルのセットの置き換えとして扱われます。

リポジトリ中の1つのコミットについての結果をcode scanning APIに複数アップロードしたい場合は、それぞれの結果をユニークなセットとして特定しなければなりません。 コミットごとに分析する CodeQL データセットを複数作成するリポジトリでは、--sarif-category オプションを使用して、そのリポジトリで生成するそれぞれの SARIF ファイルに言語または他の一意のカテゴリを指定します。

参考資料