{"id":2043,"date":"2025-05-20T23:47:00","date_gmt":"2025-05-20T23:47:00","guid":{"rendered":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/2025\/05\/20\/one-pipeline-to-rule-them-all-ensuring-codeql-scanning-results-and-dependency-scanning-results-go-to-the-intended-repository\/"},"modified":"2025-05-20T23:47:00","modified_gmt":"2025-05-20T23:47:00","slug":"one-pipeline-to-rule-them-all-ensuring-codeql-scanning-results-and-dependency-scanning-results-go-to-the-intended-repository","status":"publish","type":"post","link":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/2025\/05\/20\/one-pipeline-to-rule-them-all-ensuring-codeql-scanning-results-and-dependency-scanning-results-go-to-the-intended-repository\/","title":{"rendered":"One Pipeline to Rule Them All: Ensuring CodeQL Scanning Results and Dependency Scanning Results Go to the Intended Repository"},"content":{"rendered":"<p><em>\u201cOne Ring to rule them all, One Ring to find them, One Ring to bring them all, and in the darkness bind them.\u201d<\/em><br \/>\n  \u2013 J.R.R. Tolkien, <em>The Lord of the Rings<\/em><\/p>\n<p>In the world of code scanning and dependency scanning, your pipeline is the <strong>One Ring<\/strong>\u2014a 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.<\/p>\n<p>Fear not, brave developer! This guide will show you how to <strong>wield your pipeline wisely<\/strong> so that CodeQL scanning results and Dependency Scanning results are always published to the intended repository.<\/p>\n<p><strong>The Problem: Results NOT Going to the Intended Repository<\/strong><\/p>\n<p>Imagine this: your Azure DevOps pipeline resides in one repository (let\u2019s call it the\u00a0<strong>PipelineRepo<\/strong>, where the pipeline definition lives), while the source code you want to scan lives in another repository (let\u2019s call it the\u00a0<strong>SourceRepo<\/strong>, which contains the code to analyze).<\/p>\n<p>Without proper configuration, your scan results might end up being published to the\u00a0<strong>PipelineRepo<\/strong>\u00a0instead of the\u00a0<strong>SourceRepo<\/strong>. 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).<\/p>\n<p>To ensure your results always go to the intended repository, let\u2019s dive into how to configure your pipeline properly.<\/p>\n<h2>The Solution: Use Inferred Publishing (Preferred Method)<\/h2>\n<p>The recommended way to ensure that CodeQL scanning and dependency scanning results are published to the intended repository is to use\u00a0<strong>inferred publishing<\/strong>. By setting the\u00a0advancedsecurity.publish.repository.infer\u00a0pipeline variable to\u00a0true, the Advanced Security Build Tasks will automatically detect the repository based on the current working directory during the pipeline run.<\/p>\n<h3>Example of Inferred Publishing<\/h3>\n<p>Here\u2019s how to configure your pipeline for inferred publishing:<\/p>\n<p>trigger:<br \/>\n  &#8211; main<\/p>\n<p>resources:<br \/>\n  repositories:<br \/>\n    # PipelineRepo: The repository containing the pipeline definition.<br \/>\n    # This is optional and only needed if you plan to reference files or scripts from this repo.<br \/>\n    &#8211; repository: PipelineRepo<br \/>\n      type: git<br \/>\n      name: DevOpsPipelineRepo<br \/>\n      ref: refs\/heads\/main<br \/>\n      trigger:<br \/>\n        &#8211; main<br \/>\n    # SourceRepo: The repository where scanning and publishing will occur.<br \/>\n    &#8211; repository: SourceRepo<br \/>\n      type: git<br \/>\n      name: code-to-analyze-repo<br \/>\n      ref: refs\/heads\/main<br \/>\n      trigger:<br \/>\n        &#8211; main<\/p>\n<p>jobs:<br \/>\n  &#8211; job: &#8220;CodeQLScan&#8221;<br \/>\n    displayName: &#8220;CodeQL Scanning with Inferred Publishing&#8221;<br \/>\n    variables:<br \/>\n      # Enable repository inference<br \/>\n      advancedsecurity.publish.repository.infer: true<br \/>\n    steps:<br \/>\n      # Checkout the SourceRepo<br \/>\n      &#8211; checkout: SourceRepo<\/p>\n<p>      # Initialize CodeQL<br \/>\n      &#8211; task: AdvancedSecurity-Codeql-Init@1<br \/>\n        displayName: &#8220;Initialize CodeQL&#8221;<br \/>\n        inputs:<br \/>\n          languages: &#8220;python,javascript&#8221; # Adjust based on repository languages<\/p>\n<p>      # Perform CodeQL analysis<br \/>\n      &#8211; task: AdvancedSecurity-Codeql-Analyze@1<br \/>\n        displayName: &#8220;Analyze Code with CodeQL&#8221;<\/p>\n<h2>Handling Errors with Inferred Publishing<\/h2>\n<p>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 <strong>multi-repo scenarios<\/strong>, where multiple repositories are checked out.<\/p>\n<p>Here\u2019s how to handle it:<\/p>\n<h3>Error Message<\/h3>\n<p>You might encounter an error like:<\/p>\n<p>\u201c<em>No valid Git repository found in the working directory<\/em>.\u201d<\/p>\n<p>This error occurs because the <em>Advanced Security Build Tasks<\/em> cannot determine which repository to associate the results with.<\/p>\n<h3>Solution: Use\u00a0workspaceRepo: true<\/h3>\n<p>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\u00a0workspaceRepo: true\u00a0explicitly identifies the repository you want to analyze and publish results for.<\/p>\n<h4>Example: Multi-Repo Checkout with workspaceRepo: true<\/h4>\n<p>trigger:<br \/>\n  &#8211; main<\/p>\n<p>resources:<br \/>\n  repositories:<br \/>\n    # PipelineRepo: The repository containing the pipeline definition.<br \/>\n    # This is optional and only needed if you plan to reference files or scripts from this repo.<br \/>\n    &#8211; repository: PipelineRepo<br \/>\n      type: git<br \/>\n      name: DevOpsPipelineRepo<br \/>\n      ref: refs\/heads\/main<\/p>\n<p>    # SourceRepo1: The repository where scanning and publishing will occur.<br \/>\n    &#8211; repository: SourceRepo1<br \/>\n      type: git<br \/>\n      name: code-to-analyze-repo<br \/>\n      ref: refs\/heads\/master<\/p>\n<p>    # SourceRepo2: The repository where scanning and publishing will occur.<br \/>\n    &#8211; repository: SourceRepo2<br \/>\n      type: git<br \/>\n      name: code-to-analyze-repo<br \/>\n      ref: refs\/heads\/master<\/p>\n<p>jobs:<br \/>\n  # Job 1: CodeQL Scanning for SourceRepo1 with workspaceRepo set to true<br \/>\n  &#8211; job: &#8220;CodeQLScanSourceRepo1&#8221;<br \/>\n    displayName: &#8220;CodeQL Scanning for Juice Shop&#8221;<br \/>\n    variables:<br \/>\n      advancedsecurity.publish.repository.infer: true<br \/>\n    steps:<br \/>\n      &#8211; checkout: SourceRepo1<br \/>\n        workspaceRepo: true<br \/>\n      &#8211; task: AdvancedSecurity-Codeql-Init@1<br \/>\n        inputs:<br \/>\n          languages: &#8220;javascript&#8221; # Adjust based on SourceRepo1 languages<br \/>\n          enableAutomaticCodeQLInstall: true<br \/>\n      &#8211; task: AdvancedSecurity-Codeql-Analyze@1<br \/>\n        displayName: &#8220;Analyze Code with CodeQL&#8221;<\/p>\n<p>  # Job 2: CodeQL Scanning for SourceRepo2 with workspaceRepo set to true<br \/>\n  &#8211; job: &#8220;CodeQLScanSourceRepo2&#8221;<br \/>\n    displayName: &#8220;CodeQL Scanning for Benchmark (No Build Mode)&#8221;<br \/>\n    variables:<br \/>\n      advancedsecurity.publish.repository.infer: true<br \/>\n    steps:<br \/>\n      &#8211; checkout: SourceRepo2<br \/>\n        workspaceRepo: true<br \/>\n      &#8211; task: AdvancedSecurity-Codeql-Init@1<br \/>\n        displayName: Initialize CodeQL<br \/>\n        inputs:<br \/>\n          languages: &#8220;java&#8221; # Adjust based on SourceRepo2 languages<br \/>\n          buildtype: &#8220;none&#8221;<br \/>\n      &#8211; task: AdvancedSecurity-Codeql-Analyze@1<br \/>\n        displayName: Perform CodeQL Analysis<\/p>\n<p>This configuration ensures that the repository designated with\u00a0workspace: true\u00a0is analyzed and that results are published to the correct repository. For more details, refer to the <a href=\"https:\/\/learn.microsoft.com\/en-us\/azure\/devops\/pipelines\/repos\/multi-repo-checkout?view=azure-devops\">Azure DevOps multi-repo checkout documentation<\/a> and the <a href=\"https:\/\/learn.microsoft.com\/en-us\/azure\/devops\/pipelines\/yaml-schema\/steps-checkout?view=azure-pipelines\">checkout step documentation<\/a>.<\/p>\n<h2>This Also Applies to Pipeline Dependency Scanning<\/h2>\n<p>While this guide focuses on CodeQL static analysis, you can also use inferred publishing for <strong>Dependency Scanning<\/strong>, which identifies vulnerabilities in your project\u2019s dependencies.<\/p>\n<p>Here\u2019s how to configure your pipeline:<\/p>\n<p>trigger:<br \/>\n  &#8211; main<\/p>\n<p>resources:<br \/>\n  repositories:<br \/>\n    # PipelineRepo: The repository containing the pipeline definition.<br \/>\n    # This is optional and only needed if you plan to reference files or scripts from this repo.<br \/>\n    &#8211; repository: PipelineRepo<br \/>\n      type: git<br \/>\n      name: DevOpsPipelineRepo<br \/>\n      ref: refs\/heads\/main<br \/>\n      trigger:<br \/>\n        &#8211; main<br \/>\n    # SourceRepo: The repository where scanning and publishing will occur.<br \/>\n    &#8211; repository: SourceRepo<br \/>\n      type: git<br \/>\n      name: code-to-analyze-repo<br \/>\n      ref: refs\/heads\/main<br \/>\n      trigger:<br \/>\n        &#8211; main<\/p>\n<p>jobs:<br \/>\n  &#8211; job: &#8220;DependencyScan&#8221;<br \/>\n    displayName: &#8220;Dependency Scanning with Inferred Publishing&#8221;<br \/>\n    variables:<br \/>\n      # Enable repository inference<br \/>\n      advancedsecurity.publish.repository.infer: true<br \/>\n    steps:<br \/>\n      # Checkout the SourceRepo<br \/>\n      &#8211; checkout: SourceRepo<\/p>\n<p>      # Perform Dependency Scanning<br \/>\n      &#8211; task: AdvancedSecurity-Dependency-Scanning@1<br \/>\n        displayName: &#8220;Analyze Dependencies for Vulnerabilities&#8221;<\/p>\n<p>With dependency scanning, If you want to scope your scan to a specific folder, you can set a pipeline variable\u00a0DependencyScanning.SourcePath\u00a0to any directory file path in the build agent that you want to analyze.<\/p>\n<p>For more information, see <a href=\"https:\/\/learn.microsoft.com\/en-us\/azure\/devops\/repos\/security\/github-advanced-security-dependency-scanning-troubleshoot?view=azure-devops#adjusting-your-scanning-directory\">Adjusting your scanning directory with Dependency scanning<\/a>.<\/p>\n<h2>One Pipeline to Rule Them All<\/h2>\n<p>Inferred publishing is the\u00a0<strong>go-to choice<\/strong>, 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.<\/p>\n<h2>Additional Resources<\/h2>\n<p><a href=\"https:\/\/learn.microsoft.com\/en-us\/azure\/devops\/repos\/security\/configure-github-advanced-security-features?view=azure-devops&amp;tabs=yaml\">Configure GitHub Advanced Security for Azure DevOps features \u2013 Azure Repos | Microsoft Learn<\/a><br \/>\n<a href=\"https:\/\/learn.microsoft.com\/en-us\/azure\/devops\/pipelines\/repos\/multi-repo-checkout?view=azure-devops\">Azure DevOps Multi-Repo Checkout Documentation<\/a><br \/>\n<a href=\"https:\/\/learn.microsoft.com\/en-us\/azure\/devops\/pipelines\/yaml-schema\/steps-checkout?view=azure-pipelines\">Azure DevOps Checkout Step Documentation<\/a><br \/>\n<a href=\"https:\/\/learn.microsoft.com\/en-us\/azure\/devops\/pipelines\/\">Azure DevOps Pipelines Documentation<\/a><\/p>\n<p><em>\u201cEven the smallest person can change the course of the future.\u201d<\/em><br \/>\n  Start small by configuring your pipeline correctly, and you\u2019ll see a big impact on your team\u2019s security workflows.<\/p>\n<p>To learn more about other upcoming Azure DevOps investments in security and beyond, see <a href=\"https:\/\/aka.ms\/AzureDevOpsRoadmap\" target=\"_blank\">Azure DevOps Roadmap.<\/a><\/p>\n<p>The post <a href=\"https:\/\/devblogs.microsoft.com\/devops\/one-pipeline-to-rule-them-all-codeql-dependency-scanning\/\">One Pipeline to Rule Them All: Ensuring CodeQL Scanning Results and Dependency Scanning Results Go to the Intended Repository<\/a> appeared first on <a href=\"https:\/\/devblogs.microsoft.com\/devops\">Azure DevOps Blog<\/a>.<\/p>","protected":false},"excerpt":{"rendered":"<p>\u201cOne Ring to rule them all, One Ring to find them, One Ring to bring them all, and in the [&hellip;]<\/p>\n","protected":false},"author":0,"featured_media":94,"comment_status":"","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[3],"tags":[],"class_list":["post-2043","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-azure"],"_links":{"self":[{"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/posts\/2043","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/types\/post"}],"replies":[{"embeddable":true,"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/comments?post=2043"}],"version-history":[{"count":0,"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/posts\/2043\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/media\/94"}],"wp:attachment":[{"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/media?parent=2043"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/categories?post=2043"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/tags?post=2043"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}