À propos de la préparation du code pour l’analyse
Note
Cet article décrit les fonctionnalités disponibles avec l’offre groupée CodeQL CLI 2.16.5 incluse dans la mise en production initiale de GitHub Enterprise Server 3.13.
Si votre administrateur de site a mis à jour votre versionCodeQL CLI vers une version plus récente, consultez la version GitHub Enterprise Cloud de cet article pour obtenir plus d’informations sur les dernières fonctionnalités.
Avant d’analyser votre code avec CodeQL, vous devez créer une base de données CodeQL contenant toutes les données nécessaires pour exécuter des requêtes sur votre code. Vous pouvez créer vous-même des bases de données CodeQL en utilisant CodeQL CLI.
L’analyse CodeQL repose sur l’extraction de données relationnelles de votre code et sur leur utilisation pour créer une base de données CodeQL. Les bases de données CodeQL contiennent toutes les informations importantes relatives à un codebase, qui peuvent être analysées en exécutant des requêtes CodeQL dessus.
Avant de générer une base de données CodeQL, vous devez :
- Installer et configurer CodeQL CLI Pour plus d’informations, consultez « Configuration de CodeQL CLI ».
- Extrayez le code à analyser :
- Pour une branche, extrayez la tête (début) de la branche à analyser.
- Pour une demande de tirage, extrayez son commit de tête ou un commit de fusion généré par GitHub.
- Configurez l’environnement pour le codebase, en vérifiant que toutes les dépendances sont disponibles.
- Pour obtenir les meilleurs résultats avec des langages compilés, recherchez la commande de génération, le cas échéant, pour la codebase. En général, celle-ci est disponible dans un fichier de configuration dans le système CI.
Une fois le codebase prêt, vous pouvez exécuter codeql database create
pour créer la base de données. Pour plus d’informations, consultez Création de bases de données pour les langages non compilés et Création de bases de données pour les langages compilés.
En cours d’exécution codeql database create
Les bases de données CodeQL sont créées en exécutant la commande suivante à partir de la racine d’extraction de votre projet :
codeql database create <database> --language=<language-identifier>
Vous devez spécifier :
-
<database>
: chemin de la nouvelle base de données à créer. Ce répertoire est créé lorsque vous exécutez la commande. Vous ne pouvez pas spécifier de répertoire existant. -
--language
: identificateur du langage pour lequel créer une base de données. Utilisée avec--db-cluster
, l’option accepte une liste séparée par des virgules ou peut être spécifiée plusieurs fois. CodeQL prend en charge la création de bases de données pour les langages suivants :Langue Identificateur Identificateurs alternatifs facultatifs (le cas échéant) C/C++ c-cpp
c
oucpp
C# csharp
Go go
Java/Kotlin java-kotlin
java
oukotlin
JavaScript/TypeScript javascript-typescript
javascript
outypescript
Python python
Ruby ruby
Swift swift
Note
Si vous spécifiez l'un des identificateurs alternatifs, cela équivaut à l'utilisation de l'identificateur de langue standard. Par exemple, la spécification
javascript
au lieu dejavascript-typescript
n’exclut pas l’analyse du code TypeScript. Vous pouvez le faire dans un flux de travail d’installation avancé avec l’option--paths-ignore
. Pour plus d’informations, consultez « Personnalisation de votre configuration avancée pour l’analyse de code ».
Si votre codebase dispose d'une commande ou d'un script de construction qui invoque le processus de construction, nous vous recommandons de le spécifier également :
codeql database create <database> --command <build> \
--language=<language-identifier>
Options de création de bases de données
Vous pouvez spécifier des options supplémentaires en fonction de l’emplacement de votre fichier source, si le code doit être compilé et si vous voulez créer des bases de données CodeQL pour plusieurs langages.
Option | Obligatoire | Usage |
---|---|---|
<database> | Spécifiez le nom et l’emplacement d’un répertoire à créer pour la base de données CodeQL. La commande échoue si vous essayez de remplacer un répertoire existant. Si vous spécifiez aussi --db-cluster , il s’agit du répertoire parent et un sous-répertoire est créé pour chaque langage analysé. | |
--language | Spécifiez l’identificateur de la langue pour laquelle vous souhaitez créer une base de données, l’une des suivantes : c-cpp , csharp , go , java-kotlin , javascript-typescript , python , ruby , and swift . Utilisée avec --db-cluster , l’option accepte une liste séparée par des virgules ou peut être spécifiée plusieurs fois. | |
--command | Recommandé. Utilisez cette option pour spécifier la commande de génération ou le script qui appelle le processus de génération pour le codebase. Les commandes sont exécutées à partir du dossier actuel ou de --source-root si ce dernier est défini. Non nécessaire pour une analyse Python et JavaScript/TypeScript. | |
--db-cluster | Utilisez cette option dans les codebases en plusieurs langages pour générer une seule base de données pour chaque langage spécifié par --language . | |
--no-run-unnecessary-builds | Recommandé. Utilisez cette option pour supprimer la commande de génération pour les langages où l’CodeQL CLI n’a pas besoin de superviser la génération (par exemple, Python et JavaScript/TypeScript). | |
--source-root | Utilisez cette option si vous exécutez l’interface CLI en dehors de la racine d’extraction du dépôt. Par défaut, la commande database create suppose que le répertoire actuel est le répertoire racine des fichiers sources. Utilisez cette option pour spécifier un autre emplacement. | |
--codescanning-config | Avancé. À utiliser si vous avez un fichier de configuration qui spécifie comment créer les bases de données CodeQL et quelles requêtes exécuter dans des étapes ultérieures. Pour plus d’informations, consultez « Personnalisation de votre configuration avancée pour l’analyse de code » et « database create ». |
Vous pouvez spécifier des options d’extracteur pour personnaliser le comportement des extracteurs qui créent les bases de données CodeQL. Pour plus d’informations, consultez « Options d’extracteur ».
Pour des détails complets sur toutes les options que vous pouvez utiliser lors de la création de bases de données, consultez database create.
Exemple avec un langage unique
Cet exemple crée une base de données CodeQL unique pour le référentiel extrait à l'emplacement /checkouts/example-repo
. Il utilise l’extracteur JavaScript pour créer une représentation hiérarchique du code JavaScript et TypeScript dans le dépôt. La base de données obtenue est stockée dans /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.
Exemple avec plusieurs langages
Cet exemple crée deux bases de données CodeQL pour le dépôt extrait à l’emplacement /checkouts/example-repo-multi
. Il utilise :
--db-cluster
pour demander l’analyse de plusieurs langages.--language
pour spécifier les langages pour lesquels créer des bases de données.--command
pour indiquer à l’outil la commande de génération pour le codebase, icimake
.--no-run-unnecessary-builds
pour indiquer à l’outil d’ignorer la commande de génération pour les langages où elle n’est pas nécessaire (comme Python).
Les bases de données obtenues sont stockées dans les sous-répertoires python
et cpp
de /codeql-dbs/example-repo-multi
.
$ 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.
$
Progression et résultats
Des erreurs sont signalées en cas de problèmes avec les options que vous avez spécifiées. Pour les langages interprétés et lorsque vous spécifiez --build-mode none
pour Java, la progression de l’extraction s’affiche dans la console. Pour chaque fichier source, la console indique si l’extraction a réussi ou si elle a échoué. Lors de la génération d’un langage compilé, la console affiche le produit du système de génération.
Une fois la base de données créée, vous trouverez un nouveau répertoire dans le chemin spécifié dans la commande. Si vous avez utilisé l’option --db-cluster
pour créer plusieurs bases de données, un sous-répertoire est créé pour chaque langage. Chaque répertoire de base de données CodeQL contient un certain nombre de sous-répertoires, notamment les données relationnelles (requises pour l’analyse) et une archive source (une copie des fichiers sources créée au moment de la création de la base de données) qui est utilisée pour afficher les résultats de l’analyse.
Création de bases de données pour les langages non compilés
CodeQL CLI comprend des extracteurs pour créer des bases de données pour les langages non compilés, en particulier JavaScript (et TypeScript), Python et Ruby. Ces extracteurs sont appelés automatiquement lorsque vous spécifiez JavaScript, Python ou Ruby comme option --language
lors de l’exécution de database create
. Lorsque vous créez des bases de données pour ces langages, vous devez vous assurer que toutes les dépendances supplémentaires sont disponibles.
Note
Lorsque vous exécutez database create
pour JavaScript, TypeScript, Python et Ruby, vous ne devez pas spécifier d’option--command
. Sinon, cela remplace l’appel de l’extracteur normal, ce qui crée une base de données vide. Si vous créez des bases de données pour plusieurs langages et que l’un d’eux est un langage compilé, utilisez l’option --no-run-unnecessary-builds
pour ignorer la commande pour les langages qui n’ont pas besoin d’être compilés.
JavaScript et TypeScript
La création de bases de données pour JavaScript ne nécessite aucune dépendance supplémentaire. Toutefois, si le projet inclut des fichiers TypeScript, Node.js 14 ou une version plus récente doit être installé et disponible sur le serveur PATH
comme node
. Dans la ligne de commande, vous pouvez spécifier --language=javascript-typescript
pour extraire les fichiers JavaScript et TypeScript :
codeql database create --language=javascript-typescript --source-root <folder-to-extract> <output-folder>/javascript-database
Ici, nous avons spécifié un chemin --source-root
, qui est l’emplacement où la création de la base de données est exécutée, mais qui n’est pas nécessairement la racine d’extraction du codebase.
Par défaut, les fichiers dans les répertoires node_modules
et bower_components
ne sont pas extraits.
Python
Lorsque vous créez des bases de données pour Python, vous devez vous assurer que :
- Python 3 est installé et disponible pour l’extracteur CodeQL.
- La version de Python utilisée par votre code est installée.
Dans la ligne de commande, vous devez spécifier --language=python
. Par exemple :
codeql database create --language=python <output-folder>/python-database
Cette opération exécute la sous-commande database create
à partir de la racine d’extraction du code, générant une nouvelle base de données Python dans <output-folder>/python-database
.
Ruby
La création de bases de données pour Ruby ne demande aucune dépendance supplémentaire. Dans la ligne de commande, vous devez spécifier --language=ruby
. Par exemple :
codeql database create --language=ruby --source-root <folder-to-extract> <output-folder>/ruby-database
Ici, nous avons spécifié un chemin --source-root
, qui est l’emplacement où la création de la base de données est exécutée, mais qui n’est pas nécessairement la racine d’extraction du codebase.
Création de bases de données pour les langages compilés
Pour des langages compilés, CodeQL doit invoquer le système de génération requis pour générer une base de données. Par conséquent, la méthode de génération doit être disponible pour l’interface CLI. Cette approche crée des bases de données qui incluent du code généré. CodeQL dispose de deux méthodes pour générer des codebases :
Détection automatique du système de génération
L’CodeQL CLI comprend des générateurs automatiques pour le code C/C++, C#, Go, Java, Kotlin et Swift. Les générateurs automatiques CodeQL vous permettent de générer des projets pour les langages compilés sans spécifier de commandes de build. Quand un générateur automatique est appelé, CodeQL examine la source pour confirmer la présence d’un système de build et tente d’exécuter le jeu optimal de commandes requises pour extraire une base de données. Pour plus d’informations, consultez « Analyse du code CodeQL pour les langages compilés ».
Un générateur automatique est invoqué automatiquement lorsque vous exécutez codeql database create
pour un langage compilé si vous n’incluez pas d’option --command
. Par exemple, pour une codebase C/C++, vous pouvez simplement exécuter :
codeql database create --language=cpp <output-folder>/cpp-database
Si un codebase utilise un système de build standard, s’appuyer sur un générateur automatique est souvent le moyen le plus simple de créer une base de données. Pour les sources qui demandent des étapes de génération non standard, vous devrez peut-être définir explicitement chaque étape dans la ligne de commande.
Note
- Si vous créez une base de données Go, installez la chaîne d’outils Go (version 1.11 ou ultérieure) et, s’il existe des dépendances, le gestionnaire de dépendances approprié (par exemple dep).
- Le générateur automatique Go tente de détecter automatiquement le code écrit en Go dans un dépôt et exécute uniquement les scripts de build dans une tentative de récupération des dépendances. Pour forcer CodeQL à limiter l’extraction aux fichiers compilés par votre script de build, définissez la variable d’environnement
CODEQL_EXTRACTOR_GO_BUILD_TRACING=on
ou utilisez l’option--command
pour spécifier une commande de build.
Spécification des commandes de build
Les exemples suivants sont conçus pour vous donner une idée de quelques commandes de build que vous pouvez spécifier pour les langages compilés.
Note
L’option --command
accepte un seul argument. Si vous devez utiliser plusieurs commandes, spécifiez --command
plusieurs fois. Si vous devez passer des sous-commandes et des options, l’argument entier doit être entre guillemets pour être interprété correctement.
-
Projet C/C++ généré avec
make
:codeql database create cpp-database --language=c-cpp --command=make
-
Projet C# généré avec
dotnet build
:Il est judicieux d’ajouter
/t:rebuild
pour vous assurer que tout le code sera généré ou d’effectuer undotnet clean
avant (le code qui n’est pas généré ne sera pas inclus dans la base de données CodeQL) :codeql database create csharp-database --language=csharp --command='dotnet build /t:rebuild'
-
Projet Go généré avec la variable d’environnement
CODEQL_EXTRACTOR_GO_BUILD_TRACING=on
:CODEQL_EXTRACTOR_GO_BUILD_TRACING=on codeql database create go-database --language=go
-
Projet Go généré avec un script de build personnalisé :
codeql database create go-database --language=go --command='./scripts/build.sh'
-
Projet Java généré avec Gradle :
# 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'
-
Projet Java généré avec Maven :
codeql database create java-database --language=java-kotlin --command='mvn clean install'
-
Projet Java généré avec Ant :
codeql database create java-database --language=java-kotlin --command='ant -f build.xml'
-
Projet Swift créé à partir d’un projet ou d’un espace de travail Xcode. Par défaut, la plus grande cible Swift est générée :
Il est conseillé de s'assurer que le projet est dans un état propre et qu'il n'y a pas d'artefacts de construction disponibles.
xcodebuild clean -all codeql database create -l swift swift-database
-
Projet Swift généré avec
swift build
:codeql database create -l swift -c "swift build" swift-database
-
Projet Swift généré avec
xcodebuild
:codeql database create -l swift -c "xcodebuild build -target your-target" swift-database
Vous pouvez passer les options
archive
ettest
àxcodebuild
. Toutefois, la commande standardxcodebuild
est recommandée, car elle doit être la plus rapide et doit être tout ce que CodeQL nécessite pour une analyse réussie. -
Projet Swift généré avec un script de build personnalisé :
codeql database create -l swift -c "./scripts/build.sh" swift-database
-
Projet généré avec 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
-
Projet généré avec un script de build personnalisé :
codeql database create new-database --language=<language> --command='./scripts/build.sh'
Cette commande exécute un script personnalisé qui contient toutes les commandes requises pour générer le projet.
Utilisation du traçage de build indirect
Si les générateurs automatiques CodeQL CLI pour les langages compilés ne fonctionnent pas avec votre workflow CI et que vous ne pouvez pas wrapper les appels de commandes de build avec codeql database trace-command
, vous pouvez utiliser le traçage de build indirect pour créer une base de données CodeQL. Pour utiliser le traçage de build indirect, votre système CI doit être en mesure de définir des variables d’environnement personnalisées pour chaque action de génération.
Pour créer une base de données CodeQL avec le traçage de build indirect, exécutez la commande suivante à partir de la racine d’extraction de votre projet :
codeql database init ... --begin-tracing <database>
Vous devez spécifier :
<database>
: chemin de la nouvelle base de données à créer. Ce répertoire est créé lorsque vous exécutez la commande. Vous ne pouvez pas spécifier de répertoire existant.--begin-tracing
: crée des scripts qui peuvent être utilisés pour configurer un environnement dans lequel les commandes de build seront tracées.
Vous pouvez spécifier d’autres options pour la commande codeql database init
comme d’habitude.
Note
Si la compilation s'effectue sous Windows, vous devez définir l'option --trace-process-level <number>
ou --trace-process-name <parent process name>
de manière à ce qu'elle pointe vers un processus CI parent qui observera toutes les étapes de la compilation pour le code analysé.
La commande codeql database init
génère un message :
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: ...
La commande codeql database init
crée <database>/temp/tracingEnvironment
avec des fichiers qui contiennent des variables d’environnement et des valeurs qui permettent à CodeQL de tracer une séquence d’étapes de génération. Ces fichiers sont appelés start-tracing.{json,sh,bat,ps1}
. Utilisez l’un de ces fichiers avec le mécanisme de votre système CI afin de définir les variables d’environnement pour les étapes futures. Vous pouvez :
- Lisez le fichier JSON, traitez-le et affichez les variables d’environnement au format attendu par votre système CI. Par exemple, Azure DevOps attend
echo "##vso[task.setvariable variable=NAME]VALUE"
. - Ou, si votre système CI conserve l’environnement, sourcez le script
start-tracing
approprié pour définir les variables CodeQL dans l’environnement shell du système CI.
Générez votre code, et annulez si vous voulez les variables d’environnement à l’aide d’un script end-tracing.{json,sh,bat,ps1}
du répertoire où les scripts start-tracing
sont stockés, puis exécutez la commande codeql database finalize <database>
.
Une fois que vous avez créé une base de données CodeQL à l’aide du traçage de build indirect, vous pouvez l’utiliser comme n’importe quelle autre base de données CodeQL. Par exemple, analysez la base de données et chargez les résultats dans GitHub si vous utilisez l’analyse du code.
Exemple de création d’une base de données CodeQL à l’aide du traçage de build indirect
Note
Si vous utilisez des pipelines Azure DevOps, le moyen le plus simple de créer une base de données CodeQL consiste à utiliser GitHub Advanced Security for Azure DevOps. Pour obtenir de la documentation, consultez Configurer GitHub Advanced Security for Azure DevOps dans Microsoft Learn.
L’exemple suivant montre comment vous pourriez utiliser le traçage de build indirect dans un pipeline Azure DevOps pour créer une base de données 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` ...
Étapes suivantes
- Pour savoir comment utiliser les données CodeQL CLI pour analyser la base de données que vous avez créée à partir de votre code, consultez Analyse de votre code avec des requêtes CodeQL.