分析のためのコードの準備について
注: この記事では、GitHub Enterprise Server 3.14 の初期リリースに含まれている CodeQL CLI 2.17.6 バンドルで使用できる機能について説明します。
サイト管理者が CodeQL CLI のバージョンをより新しいリリースに更新している場合は、この記事の GitHub Enterprise Cloud バージョンで最新の機能に関する情報を参照してください。
CodeQL を使用してコードを分析する前に、コードに対してクエリを実行するために必要なすべてのデータが含まれた CodeQL データベースを作成する必要があります。 CodeQL CLI を使い、CodeQL データベースを自分で作成できます。
CodeQL の分析は、コードからリレーショナル データを抽出し、それを使用して CodeQL データベースを構築することに依存しています。 CodeQL データベースには、コードベースに関するすべての重要な情報が含まれており、CodeQL クエリを実行することでそれを分析できます。
CodeQL データベースを生成する前に、次のことを行う必要があります。
- CodeQL CLI をインストールして設定する。 詳しくは、「CodeQL CLI の設定」を参照してください。
- 分析するコードをチェックアウトします。
- ブランチの場合は、分析するブランチのヘッドをチェックアウトします。
- pull request の場合は、pull request のヘッド コミットをチェックアウトするか、GitHub で生成された pull request のマージ コミットをチェックアウトします。
- コードベースの環境を設定し、依存関係が使用可能であることを確認します。
- コンパイル型言語で最適な結果を得るには、コードベースのビルド コマンドを見つけます (存在する場合)。 通常、これは CI システムの構成ファイルで使用できます。
コードベースの準備ができたら、codeql database create
を実行してデータベースを作成できます。 詳しくは、「コンパイルされていない言語のデータベースの作成」および「コンパイル済み言語のデータベースの作成」を参照してください。
実行中 codeql database create
プロジェクトのチェックアウト ルートから次のコマンドを実行すると、CodeQL データベースが作成されます。
codeql database create <database> --language=<language-identifier>
ユーザーは次のものを指定する必要があります。
-
<database>
: 作成する新しいデータベースへのパス。 このコマンドを実行すると、このディレクトリが作成されます。既存のディレクトリを指定することはできません。 -
--language
: どの言語のデータベースを作成するかを表す識別子。--db-cluster
と一緒に使用する場合は、オプションでコンマ区切りリストが受け入れられるか、複数指定できます。 CodeQL では、次の言語のデータベースの作成がサポートされています。言語 識別子 オプションの代替識別子 (存在する場合) C/C++ c-cpp
c
またはcpp
C# csharp
Go go
Java/Kotlin java-kotlin
java
またはkotlin
JavaScript/TypeScript javascript-typescript
javascript
またはtypescript
Python python
Ruby ruby
Swift swift
注: 代替識別子の 1 つを指定した場合、これは標準の言語識別子の使用と同じです。 たとえば、
javascript-typescript
の代わりにjavascript
を指定した場合、TypeScript コードの分析は除外されません。 これは、--paths-ignore
オプションを使用して高度なセットアップ ワークフローで行うことができます。 詳しくは、「コード スキャン用の高度なセットアップのカスタマイズ」を参照してください。
コードベースにビルド プロセスを呼び出すビルド コマンドまたはスクリプトがある場合は、次のように指定することをお勧めします。
codeql database create <database> --command <build> \
--language=<language-identifier>
データベースを作成するためのオプション
ソース ファイルの場所、コードをコンパイルする必要があるかどうか、複数の言語の CodeQL データベースを作成するかどうかに応じて、追加のオプションを指定できます。
オプション | 必須 | 使用法 |
---|---|---|
<database> | CodeQLデータベースを作成するディレクトリの名前と場所を指定します。 既存のディレクトリを上書きしようとすると、コマンドは失敗します。 また --db-cluster を指定した場合は、これが親ディレクトリであり、分析される言語ごとにサブディレクトリが作成されます。 | |
--language | c-cpp 、csharp 、go 、java-kotlin 、javascript-typescript 、python 、ruby 、swift のいずれかに、データベースを作成する言語の識別子を指定します。 --db-cluster と一緒に使用する場合は、オプションでコンマ区切りリストが受け入れられるか、複数指定できます。 | |
--command | 推奨。 コードベースのビルド プロセスを呼び出すビルド コマンドまたはスクリプトを指定するために使用します。 コマンドは、現在のフォルダーまたは、定義されている場合は、--source-root から実行されます。 Python および JavaScript または TypeScript の分析には不要です。 | |
--build-mode | 推奨。 --command を指定しない場合は、Java を使用して、ビルド (none ) なしで CodeQL データベースを作成するか、ビルド コマンド (autobuild ) の自動検出を試行するかどうかを指定します。 既定では、自動ビルド検出が指定されています。 ビルド モードの比較については、「CodeQL ビルド モード」をご覧ください。 | |
--db-cluster | --language によって指定された言語ごとに 1 つのデータベースを生成するには、複数言語コードベースを使用します。 | |
--no-run-unnecessary-builds | 推奨。 CodeQL CLIがビルドをモニターする必要がない場合に、言語のビルドコマンドを抑制するために使います(たとえばPythonやJavaScript/TypeScript)。 | |
--source-root | リポジトリのチェックアウト ルートの外部で CLI を実行する場合に使用します。 既定では、database create コマンドで現在のディレクトリがソース ファイルのルート ディレクトリであると見なされます。別の場所を指定するためにこのオプションを使用します。 | |
--codescanning-config | [詳細設定]。 CodeQL データベースの作成方法と、後の手順で実行するクエリを指定する構成ファイルがある場合に使用します。 詳細については、「コード スキャン用の高度なセットアップのカスタマイズ」および「database create」を参照してください。 |
エクストラクターのオプションを指定して、CodeQL データベースを作成するエクストラクターの動作をカスタマイズできます。 詳しくは、「エクストラクターのオプション」を参照してください。
データベースを作成するときに使うことができるすべてのオプションについて詳しくは、「database create」をご覧ください。
単一言語の例
この例では、/checkouts/example-repo
でチェックアウトされたリポジトリに対して単一の CodeQL データベースを作成します。 JavaScript 抽出機能を使用して、リポジトリに JavaScript および TypeScript コードの階層表現を作成します。 結果のデータベースは /codeql-dbs/example-repo
に格納されます。
$ codeql database create /codeql-dbs/example-repo --language=javascript-typescript \
--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-multi
の python
および cpp
サブディレクトリに格納されます。
$ codeql database create /codeql-dbs/example-repo-multi \
--db-cluster --language python,c-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.
$
進行状況と結果
指定したオプションに問題がある場合は、エラーが報告されます。 インタープリター言語の場合、Java に --build-mode none
を指定すると、抽出の進行状況がコンソールに表示されます。 ソース ファイルごとに、抽出の成功または失敗がコンソールに表示されます。 コンパイル型言語がビルドされると、コンソールにビルド システムの出力が表示されます。
データベースが正常に作成されると、コマンドで指定したパスに新しいディレクトリが見つかります。 --db-cluster
オプションを使用して複数のデータベースを作成した場合は、言語ごとにサブディレクトリが作成されます。 各 CodeQL データベース ディレクトリには、リレーショナル データ (分析に必要) やソース アーカイブ (データベースの作成時に作られたソース ファイルのコピー) などの複数のサブディレクトリが含まれており、分析結果の表示に使用されます。
非コンパイル型言語のデータベースの作成
CodeQL CLI には、非コンパイル型言語 (具体的には JavaScript (および TypeScript)、Python、Ruby) のデータベースを作成するためのエクストラクターが含まれています。 こうしたエクストラクターは、database create
を実行するときに --language
オプションとして JavaScript、Python、または Ruby を指定すると、自動的に呼び出されます。 これらの言語のデータベースを作成するときは、追加の依存関係がすべて使用可能であることを確認する必要があります。
Note
JavaScript、TypeScript、Python、Ruby 用に database create
を実行する場合は、--command
オプションを指定しないでください。 そうでないと、通常のエクストラクター呼び出しがオーバーライドされ、空のデータベースが作成されます。 複数の言語のデータベースを作成し、そのうちの 1 つがコンパイル型言語である場合は、--no-run-unnecessary-builds
オプションを使用して、コンパイルする必要のない言語のコマンドをスキップします。
JavaScript および TypeScript
JavaScript のデータベースを作成するために追加の依存関係は必要ありませんが、プロジェクトに TypeScript ファイルが含まれている場合は、Node.js 14 以降をインストールして、PATH
で node
として利用できるようにする必要があります。 コマンド ラインで --language=javascript-typescript
を指定して、JavaScript と TypeScript の両方のファイルを抽出できます。
codeql database create --language=javascript-typescript --source-root <folder-to-extract> <output-folder>/javascript-database
ここでは、--source-root
パスを指定しています。これはデータベースの作成が実行される場所ですが、必ずしもコードベースのチェックアウト ルートではありません。
既定では、node_modules
および bower_components
ディレクトリ内のファイルは抽出されません。
Python
Python のデータベースを作成する場合は、次のことを確認する必要があります。
- Python 3 がインストールされていて、CodeQL エクストラクターで使用できること。
- コードで使用している Python のバージョンがインストールされていること。
コマンド ラインで --language=python
を指定する必要があります。 次に例を示します。
codeql database create --language=python <output-folder>/python-database
これにより、コードのチェックアウト ルートから database create
サブコマンドが実行され、<output-folder>/python-database
に新しい Python データベースが生成されます。
Ruby
Ruby のデータベースを作成するには、追加の依存関係は必要ありません。 コマンド ラインで --language=ruby
を指定する必要があります。 次に例を示します。
codeql database create --language=ruby --source-root <folder-to-extract> <output-folder>/ruby-database
ここでは、--source-root
パスを指定しています。これはデータベースの作成が実行される場所ですが、必ずしもコードベースのチェックアウト ルートではありません。
コンパイル型言語のデータベースの作成
ほとんどの コンパイル型言語では、CodeQL からデータベースを生成するために必要なビルド システムを呼び出す必要があるため、CLI でビルド メソッドを使用できる必要があります。 この方法では、生成されたコードを含むデータベースが作成されます。 CodeQL には、コードベースを構築するには以下の 2 つの方法があります。
さらに、Java には、コードをビルドしなくてもデータベースを生成できるオプションがあります。 これは、多数のリポジトリに対して code scanning を有効にする場合に特に便利です。 詳細については、「CodeQL ビルド モード」をご覧ください。
ビルド システムの自動検出
CodeQL CLI には、C/C++、C#、Go、Java、Kotlin、および Swift コード用の自動ビルダーが含まれています。 CodeQL の自動ビルダーを使用すると、ビルド コマンドを指定せずにコンパイル型言語のプロジェクトをビルドできます。 自動ビルダーが呼び出されると、CodeQL はソースでビルド システムの証拠を調べ、データベースの抽出に必要な最適なコマンドのセットを実行しようとします。 詳しくは、「コンパイル済み言語の CodeQL コード スキャン」を参照してください。
--command
オプションを含めない場合、--build-mode none
を設定しない場合、コンパイル型言語に対して codeql database create
を実行すると、自動ビルダーが自動的に呼び出されます。 たとえば、C/C++ コードベースの場合は、次を実行するだけです。
codeql database create --language=cpp <output-folder>/cpp-database
コードベースで標準のビルド システムを使用するのであれば、多くの場合、自動ビルダーを利用することがデータベースを作成する最も簡単な方法です。 標準以外のビルド ステップを必要とするソースについては、コマンド ラインで各ステップを明示的に定義することが必要な場合があります。
Note
- Go データベースを構築する場合は、Go ツールチェーン (バージョン 1.11 以降) をインストールし、依存関係がある場合は、適切な依存関係マネージャー (dep など) をインストールします。
- Go の自動ビルダーはリポジトリ内で、Go で記述されたコードの自動検出を試み、依存関係のフェッチを試みる際にのみビルド スクリプトを実行します。 CodeQL で強制的に、抽出をビルド スクリプトによってコンパイルされたファイルに制限するには、環境変数
CODEQL_EXTRACTOR_GO_BUILD_TRACING=on
を設定するか、--command
オプションを使用してビルド コマンドを指定します。
ビルド コマンドの指定
次の例は、コンパイル型言語について指定できるビルド コマンドの一部を示すために設計されています。
Note
--command
オプションで指定できる引数は 1 つです。複数のコマンドを使用する必要がある場合は、--command
を複数回指定します。 サブコマンドとオプションを渡す必要がある場合は、正しく解釈されるように引数全体を引用符で囲む必要があります。
-
make
を使用してビルドされた C/C++ プロジェクト:codeql database create cpp-database --language=c-cpp --command=make
-
dotnet build
を使用してビルドされた C# プロジェクト:すべてのコードが確実にビルドされるように
/t:rebuild
を追加するか、事前にdotnet clean
を実行することをお勧めします (ビルドされていないコードは CodeQL データベースに含まれません)。codeql database create csharp-database --language=csharp --command='dotnet build /t:rebuild'
-
CODEQL_EXTRACTOR_GO_BUILD_TRACING=on
環境変数を使用してビルドされた Go プロジェクト:CODEQL_EXTRACTOR_GO_BUILD_TRACING=on codeql database create go-database --language=go
-
カスタム ビルド スクリプトを使用してビルドされた Go プロジェクト:
codeql database create go-database --language=go --command='./scripts/build.sh'
-
Gradle を使用してビルドされた Java プロジェクト:
# Use `--no-daemon` because a build delegated to an existing daemon cannot be detected by CodeQL. # To ensure isolated builds without caching, add `--no-build-cache` on persistent machines. codeql database create java-database --language=java-kotlin --command='gradle --no-daemon clean test'
-
Maven を使用してビルドされた Java プロジェクト:
codeql database create java-database --language=java-kotlin --command='mvn clean install'
-
Ant を使用してビルドされた Java プロジェクト:
codeql database create java-database --language=java-kotlin --command='ant -f build.xml'
-
Xcode プロジェクトまたはワークスペースからビルドされた Swift プロジェクト。 既定では、最大の Swift ターゲットがビルドされます。
プロジェクトがクリーン状態であり、使用可能なビルドアーティファクトがないことを確認するのは良い考えです。
xcodebuild clean -all codeql database create -l swift swift-database
-
swift build
を使用してビルドされた Swift プロジェクト:codeql database create -l swift -c "swift build" swift-database
-
xcodebuild
を使用してビルドされた Swift プロジェクト:codeql database create -l swift -c "xcodebuild build -target your-target" swift-database
archive
とtest
オプションをxcodebuild
に渡すことができます。 ただし、標準のxcodebuild
コマンドが推奨されます。これは最も速く、CodeQL のスキャンが成功するために必要なものがすべて揃っているはずです。 -
カスタム ビルド スクリプトを使用してビルドされた Swift プロジェクト:
codeql database create -l swift -c "./scripts/build.sh" swift-database
-
Bazel を使用してビルドされたプロジェクト:
# Navigate to the Bazel workspace. # Before building, remove cached objects # and stop all running Bazel server processes. bazel clean --expunge # Build using the following Bazel flags, to help CodeQL detect the build: # `--spawn_strategy=local`: build locally, instead of using a distributed build # `--nouse_action_cache`: turn off build caching, which might prevent recompilation of source code # `--noremote_accept_cached`, `--noremote_upload_local_results`: avoid using a remote cache # `--disk_cache=`: avoid using a disk cache. Note that a disk cache is no longer considered a remote cache as of Bazel 6. codeql database create new-database --language=<language> \ --command='bazel build --spawn_strategy=local --nouse_action_cache --noremote_accept_cached --noremote_upload_local_results --disk_cache= //path/to/package:target' # After building, stop all running Bazel server processes. # This ensures future build commands start in a clean Bazel server process # without CodeQL attached. bazel shutdown
-
カスタム ビルド スクリプトを使用してビルドされたプロジェクト:
codeql database create new-database --language=<language> --command='./scripts/build.sh'
このコマンドにより、プロジェクトのビルドに必要なすべてのコマンドを含むカスタム スクリプトを実行します。
間接ビルド トレースの使用
コンパイル型言語の CodeQL CLI 自動ビルダーが CI ワークフローで動作せず、codeql database trace-command
でビルド コマンドの呼び出しをラップできない場合は、間接ビルド トレースを使用して CodeQL データベースを作成できます。 間接ビルド トレースを使用するには、CI システムで各ビルド アクションのカスタム環境変数を設定できる必要があります。
間接ビルド トレースを使用して CodeQL データベースを作成するには、プロジェクトのチェックアウト ルートから次のコマンドを実行します。
codeql database init ... --begin-tracing <database>
ユーザーは次のものを指定する必要があります。
<database>
: 作成する新しいデータベースへのパス。 このコマンドを実行すると、このディレクトリが作成されます。既存のディレクトリを指定することはできません。--begin-tracing
: ビルド コマンドがトレースされる環境を設定するために使用できるスクリプトを作成します。
codeql database init
コマンドの他のオプションを通常どおり指定できます。
Note
Windows でビルドを実行する場合は、--trace-process-level <number>
または --trace-process-name <parent process name>
を設定して、分析対象コードのすべてのビルド ステップを監視する親 CI プロセスをオプションで参照する必要があります。
codeql database init
コマンドによりメッセージが出力されます。
Created skeleton <database>. This in-progress database is ready to be populated by an extractor. In order to initialise tracing, some environment variables need to be set in the shell your build will run in. A number of scripts to do this have been created in <database>/temp/tracingEnvironment. Please run one of these scripts before invoking your build command.
Based on your operating system, we recommend you run: ...
codeql database init
コマンドを使用すると、CodeQL で一連のビルド ステップをトレースできるようにするための環境変数と値が含まれたファイルと共に、<database>/temp/tracingEnvironment
が作成されます。 これらのファイルには start-tracing.{json,sh,bat,ps1}
のように名前が付けられます。 これらのファイルの 1 つを CI システムのメカニズムと共に使用して、今後の手順のための環境変数を設定します。 次のようにすることができます。
- JSON ファイルを読み取り、処理し、CI システムによって想定されている形式で環境変数を出力します。 たとえば、Azure DevOps では
echo "##vso[task.setvariable variable=NAME]VALUE"
が想定されています。 - または、CI システムで環境を永続化する場合は、適切な
start-tracing
スクリプトをソースとして、CI システムのシェル環境に CodeQL 変数を設定します。
コードをビルドします。必要に応じて、start-tracing
スクリプトが保存されているディレクトリにある end-tracing.{json,sh,bat,ps1}
スクリプトを使用して環境変数の設定を解除してから、codeql database finalize <database>
コマンドを実行します。
間接ビルド トレースを使用して CodeQL データベースを作成したら、それを他の CodeQL データベースと同様に操作できます。 たとえば、データベースを分析し、コード スキャンを使用する場合は GitHub に結果をアップロードします。
間接ビルド トレースを使用して CodeQL データベースを作成する例
Note
Azure DevOps パイプラインを使用する場合、CodeQL データベースを作成する最も簡単な方法は、GitHub Advanced Security for Azure DevOps を使用することです。 ドキュメントについては、Microsoft Learn で「GitHub Advanced Security for Azure DevOps を構成する」を参照してください。
次の例は、Azure DevOps パイプラインでの間接ビルド トレースを使用して CodeQL データベースを作成する方法を示しています。
steps:
# Download the CodeQL CLI and query packs...
# Check out the repository ...
# Run any pre-build tasks, for example, restore NuGet dependencies...
# Initialize the CodeQL database.
# In this example, the CodeQL CLI has been downloaded and placed on the PATH.
- task: CmdLine@1
displayName: Initialize CodeQL database
inputs:
# Assumes the source code is checked out to the current working directory.
# Creates a database at `<current working directory>/db`.
# Running on Windows, so specifies a trace process level.
script: "codeql database init --language csharp --trace-process-name Agent.Worker.exe --source-root . --begin-tracing db"
# Read the generated environment variables and values,
# and set them so they are available for subsequent commands
# in the build pipeline. This is done in PowerShell in this example.
- task: PowerShell@1
displayName: Set CodeQL environment variables
inputs:
targetType: inline
script: >
$json = Get-Content $(System.DefaultWorkingDirectory)/db/temp/tracingEnvironment/start-tracing.json | ConvertFrom-Json
$json.PSObject.Properties | ForEach-Object {
$template = "##vso[task.setvariable variable="
$template += $_.Name
$template += "]"
$template += $_.Value
echo "$template"
}
# Execute the pre-defined build step. Note the `msbuildArgs` variable.
- task: VSBuild@1
inputs:
solution: '**/*.sln'
msbuildArgs: /p:OutDir=$(Build.ArtifactStagingDirectory)
platform: Any CPU
configuration: Release
# Execute a clean build, in order to remove any existing build artifacts prior to the build.
clean: True
displayName: Visual Studio Build
# Read and set the generated environment variables to end build tracing. This is done in PowerShell in this example.
- task: PowerShell@1
displayName: Clear CodeQL environment variables
inputs:
targetType: inline
script: >
$json = Get-Content $(System.DefaultWorkingDirectory)/db/temp/tracingEnvironment/end-tracing.json | ConvertFrom-Json
$json.PSObject.Properties | ForEach-Object {
$template = "##vso[task.setvariable variable="
$template += $_.Name
$template += "]"
$template += $_.Value
echo "$template"
}
- task: CmdLine@2
displayName: Finalize CodeQL database
inputs:
script: 'codeql database finalize db'
# Other tasks go here, for example:
# `codeql database analyze`
# then `codeql github upload-results` ...
次のステップ
- CodeQL CLI を使用して、コードから作成したデータベースを分析する方法については、「CodeQL クエリによるコード分析」を参照してください。