{"meta":{"title":"Creating CodeQL query suites","intro":"You can create query suites for queries you frequently use in your CodeQL analyses.","product":"Security and code quality","breadcrumbs":[{"href":"/en/code-security","title":"Security and code quality"},{"href":"/en/code-security/tutorials","title":"Tutorials"},{"href":"/en/code-security/tutorials/customize-code-scanning","title":"Customize code scanning"},{"href":"/en/code-security/tutorials/customize-code-scanning/creating-codeql-query-suites","title":"Creating CodeQL query suites"}],"documentType":"article"},"body":"# Creating CodeQL query suites\n\nYou can create query suites for queries you frequently use in your CodeQL analyses.\n\nYou can create query suites for the queries that you want to frequently use in your CodeQL analyses. For more information, see [CodeQL query suites](/en/code-security/concepts/code-scanning/codeql/codeql-query-suites).\n\n> \\[!NOTE]\n> Any custom queries that you want to add to a query suite must be in a [CodeQL pack](/en/code-security/codeql-cli/getting-started-with-the-codeql-cli/customizing-analysis-with-codeql-packs) and contain the correct query metadata. For more information, see [Writing custom queries for the CodeQL CLI](/en/code-security/how-tos/scan-code-for-vulnerabilities/scan-from-the-command-line/writing-and-sharing-custom-queries-for-the-codeql-cli).\n\n## Locating queries to add to a query suite\n\nWhen creating a query suite, you first need to specify the locations of the\nqueries that you want to select. You can define the location of one or more\nqueries using:\n\n* A `query` instruction: Tells CodeQL to look for one or more specified `.ql`\n  files:\n\n  ```yaml\n  - query: <path-to-query>\n  ```\n\n  The argument must be one or more file paths, relative to the CodeQL pack containing\n  the suite definition.\n\n* A `queries` instruction: Tells CodeQL to recursively scan a directory\n  for `.ql` files:\n\n  ```yaml\n  - queries: <path-to-subdirectory>\n  ```\n\n  The path of the directory must be relative to the root of the CodeQL pack that\n  contains the suite definition file. To find the queries relative to a\n  different CodeQL pack, add a `from` field:\n\n  ```yaml\n  - queries: <path-to-subdirectory>\n    from: <ql-pack-name>\n    version: ^x.y.z\n  ```\n\n  The `version` field is optional and specifies a range of compatible versions of this CodeQL pack.\n  If you don’t specify a version, then the most recent version of the pack is used.\n\n* A `qlpack` instruction: Tells CodeQL to resolve queries in the default suite of the\n  named CodeQL pack:\n\n  ```yaml\n  - qlpack: <qlpack-name>\n    version: ^x.y.z\n  ```\n\n  The default suite of a query pack includes a recommended set of queries\n  inside of that query pack. Not all query packs have a default suite. If the given query pack does not define a default suite, the qlpack instruction will resolve to all of the queries within the pack.\n\n  The `version` field is optional and specifies a range of compatible versions of this CodeQL pack.\n  If you don’t specify a version, then the most recent version of the pack is used.\n\n> \\[!NOTE]\n> When pathnames appear in query suite definitions, they must always be given with a forward slash, `/`, as a directory separator. This ensures that query suite definitions work on all operating systems.\n\nYou must add at least one `query`, `queries`, or `qlpack` instruction to\nyour suite definition, otherwise no queries will be selected. If the suite\ncontains no further instructions, all the queries found from the list of files,\nin the given directory, or in the named CodeQL pack are selected. If there are further\nfiltering instructions, only queries that match the constraints imposed by those\ninstructions will be selected.\n\n## Filtering the queries in a query suite\n\nAfter you have defined the initial set of queries to add to your suite by\nspecifying `query`, `queries`, or `qlpack` instructions, you can add\n`include` and `exclude` instructions. These instructions define selection\ncriteria based on specific properties:\n\n* When you execute an `include` instruction on a set of queries, any\n  queries that match your conditions are retained in the selection, and queries\n  that don’t match are removed.\n* When you execute an `exclude` instructions on a set of queries,\n  any queries that match your conditions are removed from the selection, and queries\n  that don’t match are retained.\n\nThe order of your filter instructions is important. The first filter instruction\nthat appears after the locating instructions determines whether the queries are\nincluded or excluded by default. If the first filter is an `include`, the\ninitially located queries will only be part of the suite if they match an\nexplicit `include` filter. If the first filter is an `exclude`, the initially\nlocated queries are part of the suite unless they are explicitly excluded.\n\nSubsequent instructions are executed in order and the instructions that appear\nlater in the file take precedence over the earlier instructions. So, `include`\ninstructions can be overridden by a later `exclude` instructions that match\nthe same query. Similarly, `exclude`s can be overridden by a later\n`include`.\n\nFor both instructions, the argument is a constraint block—that is, a YAML map\nrepresenting the constraints. Each constraint is a map entry, where the key is\ntypically a query metadata property. The value can be:\n\n* A single string.\n* A `/`-enclosed [regular expression](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/regex/Pattern.html).\n* A list containing strings, regular expressions, or both.\n\nTo match a constraint, a metadata value must match one of the strings or\nregular expressions. When there is more than one metadata key, each key must be matched.\nThe standard metadata keys available to match on are: `description`, `id`, `kind`,\n`name`, `tags`, `precision`, and `problem.severity`.\nFor more information about query metadata properties, see\n[Metadata for CodeQL queries](https://codeql.github.com/docs/writing-codeql-queries/metadata-for-codeql-queries/#metadata-for-codeql-queries).\n\nIn addition to metadata tags, the keys in the constraint block can also be:\n\n* `query filename`: Matches on the last path component of the query file name.\n* `query path`: Matches on the path to the query file relative to its\n  enclosing CodeQL pack.\n* `tags contain`: One of the given match strings must match\n  one of the space-separated components of the value of the `@tags` metadata property.\n* `tags contain all`: Each of the given match strings must match one of the\n  components of the `@tags` metadata property.\n\n### Examples of filtering which queries are run\n\nA common use case is to create a query suite that runs all queries in a CodeQL pack,\nexcept for a few specific queries that the user does not want to run. In general, we\nrecommend filtering on the query `id`, which is a unique and stable identifier for\neach query. The following three query suite definitions are semantically identical and\nfilter by the query `id`:\n\nThis filter matches all the queries in the default suite of `codeql/cpp-queries`, except for the two queries with the excluded identifiers:\n\n```yaml\n- qlpack: codeql/cpp-queries\n- exclude:\n    id:\n      - cpp/cleartext-transmission\n      - cpp/cleartext-storage-file\n```\n\nIn this example, a separate `exclude` instruction is used for each query:\n\n```yaml\n- qlpack: codeql/cpp-queries\n- exclude:\n    id: cpp/cleartext-transmission\n- exclude:\n    id: cpp/cleartext-storage-file\n```\n\nIn this example, a regular expression excludes the same two queries. It would also exclude any future queries added to the suite with identifiers that begin: `cpp/cleartext-`:\n\n```yaml\n- qlpack: codeql/cpp-queries\n- exclude:\n    id:\n      - /^cpp\\/cleartext-.*/\n```\n\nTo define a suite that selects all queries in the default suite of the\n`codeql/cpp-queries` CodeQL pack, and then refines them to only include\nsecurity queries, use:\n\n```yaml\n- qlpack: codeql/cpp-queries\n- include:\n    tags contain: security\n```\n\nTo define a suite that selects all queries with `@kind problem`\nand `@precision high` from the `my-custom-queries` directory, use:\n\n```yaml\n- queries: my-custom-queries\n- include:\n    kind: problem\n    precision: very-high\n```\n\nNote that the following query suite definition behaves differently from the definition above. This definition selects queries that are `@kind problem` *or*\nare `@precision very-high`:\n\n```yaml\n- queries: my-custom-queries\n- include:\n    kind: problem\n- include:\n    precision: very-high\n```\n\nTo create a suite that selects all queries with `@kind problem` from the\n`my-custom-queries` directory except those with `@problem.severity\nrecommendation`, use:\n\n```yaml\n- queries: my-custom-queries\n- include:\n    kind: problem\n- exclude:\n    problem.severity: recommendation\n```\n\nTo create a suite that selects all queries with `@tag security` and\n`@precision high` or `very-high` from the `codeql/cpp-queries` CodeQL pack,\nuse:\n\n```yaml\n- queries: .\n  from: codeql/cpp-queries\n- include:\n    tags contain: security\n    precision:\n    - high\n    - very-high\n```\n\n> \\[!NOTE]\n> You can use the `codeql resolve queries /path/to/suite.qls` command to see which queries are selected by a query suite definition. For more information, see [resolve queries](/en/code-security/codeql-cli/codeql-cli-manual/resolve-queries).\n\n## Reusing existing query suite definitions\n\nExisting query suite definitions can be reused by specifying:\n\n* An `import` instruction: Adds the queries selected by a\n  previously defined `.qls` file to the current suite:\n\n  ```yaml\n  - import: <path-to-query-suite>\n  ```\n\n  The path to the imported suite must be relative to the CodeQL pack containing the\n  current suite definition. If the imported query suite is in a different QL\n  pack you can use:\n\n  ```yaml\n  - import: <path-to-query-suite>\n    from: <ql-pack>\n    version: ^x.y.z\n  ```\n\n  The `version` field is optional and specifies a range of compatible versions of this CodeQL pack.\n  If you don’t specify a version, then the most recent version of the pack is used.\n\n  Queries added using an `import` instruction can be filtered using subsequent\n  `exclude` instructions.\n\n* An `apply` instruction: Adds all of the instructions from a\n  previously defined `.qls` file to the current suite. The instructions in the\n  applied `.qls` file are executed as if they appear in place of `apply`.\n  Any `include` and `exclude` instructions from the applied suite also act on\n  queries added by any earlier instructions:\n\n  ```yaml\n  - apply: <path-to-query-suite>\n  ```\n\n  The `apply` instruction can also be used to apply a set of reusable\n  conditions, saved in a `.yml` file, to multiple query definitions. For more\n  information, see the [examples](#reusability-examples) below.\n\n### Reusability Examples\n\nTo use the same conditions in multiple query suite definitions, create a\nseparate `.yml` file containing your instructions. For example, save the\nfollowing in a file called `reusable-instructions.yml`:\n\n```yaml\n- include:\n    kind:\n    - problem\n    - path-problem\n    tags contain: security\n    precision:\n    - high\n    - very-high\n```\n\nAdd `reusable-instructions.yml` to the same CodeQL pack as your current query\nsuite. Then, in one or more query suites, use the `apply` instruction to apply\nthe reusable instructions to the current suite. For example:\n\n```yaml\n- queries: queries/cpp/custom\n- apply: reusable-instructions.yml\n```\n\nThis will filter the queries in `queries/cpp/custom` to only include those that match the reusable conditions.\n\nYou can also create a suite definition using `reusable-instructions.yml` on\nqueries in a different CodeQL pack. If the `.qls` file is in the same CodeQL pack as\nthe queries, you can add a `from` field immediately after the `apply`\ninstruction:\n\n```yaml\n# load queries from the default suite of my-org/my-other-custom-queries\n- qlpack: my-org/my-other-custom-queries\n\n# apply the reusable instructions from the my-org/my-custom-instructions CodeQL pack\n- apply: reusable-instructions.yml\n  from: my-org/my-custom-instructions\n  version: ^1.2.3 # optional\n```\n\nA common use case for an `import` instruction is to apply a further filter to queries from another\nquery suite. For example, this suite will further filter the `cpp-security-and-quality` suite\nand exclude `low` and `medium` precision queries:\n\n```yaml\n- import: codeql-suites/cpp-security-and-quality.qls\n  from: codeql/cpp-queries\n- exclude:\n    precision:\n      - low\n      - medium\n```\n\nIf you want to `include` queries imported from another suite, the syntax is a little different:\n\n```yaml\n- import: codeql-suites/cpp-security-and-quality.qls\n  from: codeql/cpp-queries\n- exclude: {}\n- include:\n    precision:\n      - very-high\n      - high\n```\n\nNotice the empty `exclude` instruction. This is required to ensure that the subsequent `include`\ninstruction is able to filter queries from the imported suite.\n\n## Naming a query suite\n\nYou can provide a name for your query suite by specifying a `description`\ninstruction:\n\n```yaml\n- description: <name-of-query-suite>\n```\n\n## Saving a query suite\n\nSave your query suite in a file with a `.qls` extension and add it to a CodeQL\npack. For more information, see [Customizing analysis with CodeQL packs](/en/code-security/codeql-cli/getting-started-with-the-codeql-cli/customizing-analysis-with-codeql-packs#custom-codeql-packs).\n\n## Using query suites with CodeQL\n\nYou can specify query suites on the command line for any command that accepts\n`.qls` files. For example, you can compile the queries selected by a suite\ndefinition using `query compile`, or use the queries in an analysis using\n`database analyze`. For more information about analyzing CodeQL databases, see\n[Analyzing your code with CodeQL queries](/en/code-security/codeql-cli/getting-started-with-the-codeql-cli/analyzing-your-code-with-codeql-queries).\n\n## Further reading\n\n* [CodeQL queries](https://codeql.github.com/docs/writing-codeql-queries/codeql-queries/#codeql-queries)"}