May 20th, 2025
2 reactions

One Pipeline to Rule Them All: Ensuring CodeQL Scanning Results and Dependency Scanning Results Go to the Intended Repository

Michael Omokoh
Product Manager

“One Ring to rule them all, One Ring to find them, One Ring to bring them all, and in the darkness bind them.”
– J.R.R. Tolkien, The Lord of the Rings

In the world of code scanning and dependency scanning, your pipeline is the One Ring—a single definition that can orchestrate scans across multiple repositories. However, much like the One Ring, if misused, it can lead to chaos: publishing results to the unintended repository.

Fear not, brave developer! This guide will show you how to wield your pipeline wisely so that CodeQL scanning results and Dependency Scanning results are always published to the intended repository.


The Problem: Results NOT Going to the Intended Repository

Imagine this: your Azure DevOps pipeline resides in one repository (let’s call it the PipelineRepo, where the pipeline definition lives), while the source code you want to scan lives in another repository (let’s call it the SourceRepo, which contains the code to analyze).

Without proper configuration, your scan results might end up being published to the PipelineRepo instead of the SourceRepo. This behavior occurs because the AdvancedSecurity-Dependency-Scanning, AdvancedSecurity-Codeql-Analyze, and AdvancedSecurity-Publish (collectively referred to as Advanced Security Build Tasks hereafter) publish the SARIF file with scan results to the repository that triggered the pipeline run (which can be the repository containing the pipeline definition).

To ensure your results always go to the intended repository, let’s dive into how to configure your pipeline properly.


The Solution: Use Inferred Publishing (Preferred Method)

The recommended way to ensure that CodeQL scanning and dependency scanning results are published to the intended repository is to use inferred publishing. By setting the advancedsecurity.publish.repository.infer pipeline variable to true, the Advanced Security Build Tasks will automatically detect the repository based on the current working directory during the pipeline run.

Example of Inferred Publishing

Here’s how to configure your pipeline for inferred publishing:

trigger:
  - main

resources:
  repositories:
    # PipelineRepo: The repository containing the pipeline definition.
    # This is optional and only needed if you plan to reference files or scripts from this repo.
    - repository: PipelineRepo
      type: git
      name: DevOpsPipelineRepo
      ref: refs/heads/main
      trigger:
        - main
    # SourceRepo: The repository where scanning and publishing will occur.
    - repository: SourceRepo
      type: git
      name: code-to-analyze-repo
      ref: refs/heads/main
      trigger:
        - main

jobs:
  - job: "CodeQLScan"
    displayName: "CodeQL Scanning with Inferred Publishing"
    variables:
      # Enable repository inference
      advancedsecurity.publish.repository.infer: true
    steps:
      # Checkout the SourceRepo
      - checkout: SourceRepo

      # Initialize CodeQL
      - task: AdvancedSecurity-Codeql-Init@1
        displayName: "Initialize CodeQL"
        inputs:
          languages: "python,javascript" # Adjust based on repository languages

      # Perform CodeQL analysis
      - task: AdvancedSecurity-Codeql-Analyze@1
        displayName: "Analyze Code with CodeQL"

Handling Errors with Inferred Publishing

In some cases, inferred publishing might throw an error if the pipeline cannot determine a valid Git repository in the current working directory. This typically happens in multi-repo scenarios, where multiple repositories are checked out.

Here’s how to handle it:

Error Message

You might encounter an error like:

No valid Git repository found in the working directory.”

This error occurs because the Advanced Security Build Tasks cannot determine which repository to associate the results with.

Solution: Use workspaceRepo: true

By default, CodeQL uses the current working directory to determine the repository for publishing results. However, in scenarios where multiple repositories are checked out, this can lead to ambiguity. Setting workspaceRepo: true explicitly identifies the repository you want to analyze and publish results for.

Example: Multi-Repo Checkout with workspaceRepo: true

trigger:
  - main

resources:
  repositories:
    # PipelineRepo: The repository containing the pipeline definition.
    # This is optional and only needed if you plan to reference files or scripts from this repo.
    - repository: PipelineRepo
      type: git
      name: DevOpsPipelineRepo
      ref: refs/heads/main

    # SourceRepo1: The repository where scanning and publishing will occur.
    - repository: SourceRepo1
      type: git
      name: code-to-analyze-repo
      ref: refs/heads/master

    # SourceRepo2: The repository where scanning and publishing will occur.
    - repository: SourceRepo2
      type: git
      name: code-to-analyze-repo
      ref: refs/heads/master


jobs:
  # Job 1: CodeQL Scanning for SourceRepo1 with workspaceRepo set to true
  - job: "CodeQLScanSourceRepo1"
    displayName: "CodeQL Scanning for Juice Shop"
    variables:
      advancedsecurity.publish.repository.infer: true
    steps:
      - checkout: SourceRepo1
        workspaceRepo: true
      - task: AdvancedSecurity-Codeql-Init@1
        inputs:
          languages: "javascript" # Adjust based on SourceRepo1 languages
          enableAutomaticCodeQLInstall: true
      - task: AdvancedSecurity-Codeql-Analyze@1
        displayName: "Analyze Code with CodeQL"

  # Job 2: CodeQL Scanning for SourceRepo2 with workspaceRepo set to true
  - job: "CodeQLScanSourceRepo2"
    displayName: "CodeQL Scanning for Benchmark (No Build Mode)"
    variables:
      advancedsecurity.publish.repository.infer: true
    steps:
      - checkout: SourceRepo2
        workspaceRepo: true
      - task: AdvancedSecurity-Codeql-Init@1
        displayName: Initialize CodeQL
        inputs:
          languages: "java" # Adjust based on SourceRepo2 languages
          buildtype: "none"
      - task: AdvancedSecurity-Codeql-Analyze@1
        displayName: Perform CodeQL Analysis

This configuration ensures that the repository designated with workspaceRepo: true is analyzed and that results are published to the correct repository. For more details, refer to the Azure DevOps multi-repo checkout documentation and the checkout step documentation.


This Also Applies to Pipeline Dependency Scanning

While this guide focuses on CodeQL static analysis, you can also use inferred publishing for Dependency Scanning, which identifies vulnerabilities in your project’s dependencies.

Here’s how to configure your pipeline:

trigger:
  - main

resources:
  repositories:
    # PipelineRepo: The repository containing the pipeline definition.
    # This is optional and only needed if you plan to reference files or scripts from this repo.
    - repository: PipelineRepo
      type: git
      name: DevOpsPipelineRepo
      ref: refs/heads/main
      trigger:
        - main
    # SourceRepo: The repository where scanning and publishing will occur.
    - repository: SourceRepo
      type: git
      name: code-to-analyze-repo
      ref: refs/heads/main
      trigger:
        - main

jobs:
  - job: "DependencyScan"
    displayName: "Dependency Scanning with Inferred Publishing"
    variables:
      # Enable repository inference
      advancedsecurity.publish.repository.infer: true
    steps:
      # Checkout the SourceRepo
      - checkout: SourceRepo

      # Perform Dependency Scanning
      - task: AdvancedSecurity-Dependency-Scanning@1
        displayName: "Analyze Dependencies for Vulnerabilities"

With dependency scanning, If you want to scope your scan to a specific folder, you can set a pipeline variable DependencyScanning.SourcePath to any directory file path in the build agent that you want to analyze.

For more information, see Adjusting your scanning directory with Dependency scanning.


One Pipeline to Rule Them All

Inferred publishing is the go-to choice, offering a streamlined configuration that minimizes errors and provides clear guidance when challenges arise. By adopting these best practices, you can ensure that CodeQL and Dependency Scanning results are always directed to the intended repository. The ability to seamlessly manage your code scanning workflows is now within your grasp.

Additional Resources

“Even the smallest person can change the course of the future.”
Start small by configuring your pipeline correctly, and you’ll see a big impact on your team’s security workflows.

To learn more about other upcoming Azure DevOps investments in security and beyond, see Azure DevOps Roadmap.

Author

Michael Omokoh
Product Manager

I’m a Product Manager at GitHub Advanced Security for Azure DevOps, where I advocate for users across the software development lifecycle, ensuring secure coding practices are integrated seamlessly into their workflow. My work bridges the gap between developers, security teams, and product leadership to create a more secure development environment.

0 comments