<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic CI/CD - Databricks Asset Bundles - Deploy/destroy only bundles with changes after Merge Request in Data Engineering</title>
    <link>https://community.databricks.com/t5/data-engineering/ci-cd-databricks-asset-bundles-deploy-destroy-only-bundles-with/m-p/81453#M36311</link>
    <description>&lt;P&gt;Hello everyone,&lt;/P&gt;&lt;P&gt;&lt;SPAN&gt;We're in the process of migrating to Databricks and are encountering challenges implementing CI/CD using Databricks Asset Bundles.&lt;/SPAN&gt;&lt;SPAN&gt; Our monorepo houses multiple independent bundles within a "dabs" directory,&lt;/SPAN&gt;&lt;SPAN&gt; with only one team member working on a specific bundle at a time.&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN&gt;We've adopted a single-branch strategy with an "environment-per-folder" approach.&lt;/SPAN&gt;&lt;SPAN&gt; Each bundle has a "databricks.&lt;/SPAN&gt;&lt;SPAN&gt;yml" at its root and one or more environment folders (e.&lt;/SPAN&gt;&lt;SPAN&gt;g.,&lt;/SPAN&gt;&lt;SPAN&gt; "uat/",&lt;/SPAN&gt;&lt;SPAN&gt; "prd/").&lt;/SPAN&gt;&lt;SPAN&gt; The targets in "databricks.&lt;/SPAN&gt;&lt;SPAN&gt;yml" targets the appropriate environment folder.&lt;/SPAN&gt;&lt;SPAN&gt; This setup enables easy feature testing in isolation and granular environment control.&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN&gt;Our goal is to efficiently determine which bundles require deployment/destruction after a Merge Request is merged into the "main" branch.&lt;/SPAN&gt;&lt;SPAN&gt; We aim to trigger child pipelines only for bundles with actual changes in the Merge Request.&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN&gt;We've successfully identified changed bundles during Merge Request pipelines (i.e.&amp;nbsp;when a Merge Request is opened) using &lt;/SPAN&gt;&lt;FONT color="#FF0000"&gt;&lt;EM&gt;git diff&lt;/EM&gt;&lt;/FONT&gt;&lt;SPAN&gt; to compare the &lt;/SPAN&gt;&lt;SPAN&gt;target and source branches:&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="markup"&gt;- git fetch 
- changes=$(git diff --name-status origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME origin/$CI_COMMIT_REF_NAME -- dabs/&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;SPAN&gt;This first pipeline allows to ensure the changed bundles are valid using &lt;FONT color="#FF0000"&gt;&lt;EM&gt;databricks bundle validate&lt;/EM&gt;&lt;/FONT&gt;.&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN&gt;However,&lt;/SPAN&gt;&lt;SPAN&gt; replicating this logic for the pipeline triggered after the Merge Request is merged (which is a branch pipeline) is proving difficult.&lt;/SPAN&gt;&lt;SPAN&gt; We need to accurately identify the same changed bundles for deployment/destruction (i.e. &lt;FONT color="#FF0000"&gt;&lt;EM&gt;databricks bundle deploy -t {env}&lt;/EM&gt;&lt;/FONT&gt;/&lt;FONT color="#FF0000"&gt;&lt;EM&gt;databricks bundle destroy -t {env}&lt;/EM&gt;&lt;/FONT&gt;).&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN&gt;We've thought about two potential solutions:&lt;/SPAN&gt;&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;&lt;STRONG&gt;Comparing commits:&lt;/STRONG&gt;&lt;SPAN&gt; Determining relevant commits from the Merge Request and comparing them to the "main" branch.&lt;/SPAN&gt;&lt;SPAN&gt; This seems complex due to potential squashing and concurrent Merge Requests.&lt;/SPAN&gt;&lt;/LI&gt;&lt;LI&gt;&lt;STRONG&gt;Using artifacts:&lt;/STRONG&gt;&lt;SPAN&gt; Storing changed bundles as an artifact during the Merge Request pipeline and retrieving/using this artifact in the subsequent pipeline.&lt;/SPAN&gt;&lt;SPAN&gt; This approach might be complex due to potential naming conflicts.&lt;/SPAN&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;&lt;SPAN&gt;Is there a more efficient way to identify changed bundles after a Merge Request is merged? We could simply re-deploy all the bundles but what about destruction of bundles? We have the need for bundle destruction in certain environments (e.&lt;/SPAN&gt;&lt;SPAN&gt;g.,&lt;/SPAN&gt;&lt;SPAN&gt; uat) to manage costs and UI cleanliness as we'll have lots of jobs.&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN&gt;We'd appreciate any advice or alternative approaches to tackle this challenge.&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN&gt;Thanks in advance for your help!&lt;/SPAN&gt;&lt;/P&gt;</description>
    <pubDate>Thu, 01 Aug 2024 08:31:00 GMT</pubDate>
    <dc:creator>achntrl</dc:creator>
    <dc:date>2024-08-01T08:31:00Z</dc:date>
    <item>
      <title>CI/CD - Databricks Asset Bundles - Deploy/destroy only bundles with changes after Merge Request</title>
      <link>https://community.databricks.com/t5/data-engineering/ci-cd-databricks-asset-bundles-deploy-destroy-only-bundles-with/m-p/81453#M36311</link>
      <description>&lt;P&gt;Hello everyone,&lt;/P&gt;&lt;P&gt;&lt;SPAN&gt;We're in the process of migrating to Databricks and are encountering challenges implementing CI/CD using Databricks Asset Bundles.&lt;/SPAN&gt;&lt;SPAN&gt; Our monorepo houses multiple independent bundles within a "dabs" directory,&lt;/SPAN&gt;&lt;SPAN&gt; with only one team member working on a specific bundle at a time.&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN&gt;We've adopted a single-branch strategy with an "environment-per-folder" approach.&lt;/SPAN&gt;&lt;SPAN&gt; Each bundle has a "databricks.&lt;/SPAN&gt;&lt;SPAN&gt;yml" at its root and one or more environment folders (e.&lt;/SPAN&gt;&lt;SPAN&gt;g.,&lt;/SPAN&gt;&lt;SPAN&gt; "uat/",&lt;/SPAN&gt;&lt;SPAN&gt; "prd/").&lt;/SPAN&gt;&lt;SPAN&gt; The targets in "databricks.&lt;/SPAN&gt;&lt;SPAN&gt;yml" targets the appropriate environment folder.&lt;/SPAN&gt;&lt;SPAN&gt; This setup enables easy feature testing in isolation and granular environment control.&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN&gt;Our goal is to efficiently determine which bundles require deployment/destruction after a Merge Request is merged into the "main" branch.&lt;/SPAN&gt;&lt;SPAN&gt; We aim to trigger child pipelines only for bundles with actual changes in the Merge Request.&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN&gt;We've successfully identified changed bundles during Merge Request pipelines (i.e.&amp;nbsp;when a Merge Request is opened) using &lt;/SPAN&gt;&lt;FONT color="#FF0000"&gt;&lt;EM&gt;git diff&lt;/EM&gt;&lt;/FONT&gt;&lt;SPAN&gt; to compare the &lt;/SPAN&gt;&lt;SPAN&gt;target and source branches:&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="markup"&gt;- git fetch 
- changes=$(git diff --name-status origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME origin/$CI_COMMIT_REF_NAME -- dabs/&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;SPAN&gt;This first pipeline allows to ensure the changed bundles are valid using &lt;FONT color="#FF0000"&gt;&lt;EM&gt;databricks bundle validate&lt;/EM&gt;&lt;/FONT&gt;.&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN&gt;However,&lt;/SPAN&gt;&lt;SPAN&gt; replicating this logic for the pipeline triggered after the Merge Request is merged (which is a branch pipeline) is proving difficult.&lt;/SPAN&gt;&lt;SPAN&gt; We need to accurately identify the same changed bundles for deployment/destruction (i.e. &lt;FONT color="#FF0000"&gt;&lt;EM&gt;databricks bundle deploy -t {env}&lt;/EM&gt;&lt;/FONT&gt;/&lt;FONT color="#FF0000"&gt;&lt;EM&gt;databricks bundle destroy -t {env}&lt;/EM&gt;&lt;/FONT&gt;).&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN&gt;We've thought about two potential solutions:&lt;/SPAN&gt;&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;&lt;STRONG&gt;Comparing commits:&lt;/STRONG&gt;&lt;SPAN&gt; Determining relevant commits from the Merge Request and comparing them to the "main" branch.&lt;/SPAN&gt;&lt;SPAN&gt; This seems complex due to potential squashing and concurrent Merge Requests.&lt;/SPAN&gt;&lt;/LI&gt;&lt;LI&gt;&lt;STRONG&gt;Using artifacts:&lt;/STRONG&gt;&lt;SPAN&gt; Storing changed bundles as an artifact during the Merge Request pipeline and retrieving/using this artifact in the subsequent pipeline.&lt;/SPAN&gt;&lt;SPAN&gt; This approach might be complex due to potential naming conflicts.&lt;/SPAN&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;&lt;SPAN&gt;Is there a more efficient way to identify changed bundles after a Merge Request is merged? We could simply re-deploy all the bundles but what about destruction of bundles? We have the need for bundle destruction in certain environments (e.&lt;/SPAN&gt;&lt;SPAN&gt;g.,&lt;/SPAN&gt;&lt;SPAN&gt; uat) to manage costs and UI cleanliness as we'll have lots of jobs.&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN&gt;We'd appreciate any advice or alternative approaches to tackle this challenge.&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN&gt;Thanks in advance for your help!&lt;/SPAN&gt;&lt;/P&gt;</description>
      <pubDate>Thu, 01 Aug 2024 08:31:00 GMT</pubDate>
      <guid>https://community.databricks.com/t5/data-engineering/ci-cd-databricks-asset-bundles-deploy-destroy-only-bundles-with/m-p/81453#M36311</guid>
      <dc:creator>achntrl</dc:creator>
      <dc:date>2024-08-01T08:31:00Z</dc:date>
    </item>
    <item>
      <title>Re: CI/CD - Databricks Asset Bundles - Deploy/destroy only bundles with changes after Merge Request</title>
      <link>https://community.databricks.com/t5/data-engineering/ci-cd-databricks-asset-bundles-deploy-destroy-only-bundles-with/m-p/139320#M51156</link>
      <description>&lt;P class="my-2 [&amp;amp;+p]:mt-4 [&amp;amp;_strong:has(+br)]:inline-block [&amp;amp;_strong:has(+br)]:pb-2"&gt;Your challenge—reliably determining the subset of changed Databricks Asset Bundles after a Merge Request (MR) is merged into main for focused deploy/destroy CI/CD actions—is common in complex monorepo, multi-environment setups. Let’s break down the problem and present practical solutions tailored to Databricks Bundle and monorepo-specific workflows.&lt;/P&gt;
&lt;H2 class="mb-2 mt-4 font-display font-semimedium text-base first:mt-0"&gt;Key Challenges&lt;/H2&gt;
&lt;UL class="marker:text-quiet list-disc"&gt;
&lt;LI class="py-0 my-0 prose-p:pt-0 prose-p:mb-2 prose-p:my-0 [&amp;amp;&amp;gt;p]:pt-0 [&amp;amp;&amp;gt;p]:mb-2 [&amp;amp;&amp;gt;p]:my-0"&gt;
&lt;P class="my-2 [&amp;amp;+p]:mt-4 [&amp;amp;_strong:has(+br)]:inline-block [&amp;amp;_strong:has(+br)]:pb-2"&gt;&lt;STRONG&gt;Branch pipeline context loss&lt;/STRONG&gt;: After a MR merges, the direct comparison context (source↔target) is unavailable. Only the "main" branch is present, making it hard to know which bundles changed, especially with squashed or rebased merges.&lt;/P&gt;
&lt;/LI&gt;
&lt;LI class="py-0 my-0 prose-p:pt-0 prose-p:mb-2 prose-p:my-0 [&amp;amp;&amp;gt;p]:pt-0 [&amp;amp;&amp;gt;p]:mb-2 [&amp;amp;&amp;gt;p]:my-0"&gt;
&lt;P class="my-2 [&amp;amp;+p]:mt-4 [&amp;amp;_strong:has(+br)]:inline-block [&amp;amp;_strong:has(+br)]:pb-2"&gt;&lt;STRONG&gt;Efficiency&lt;/STRONG&gt;: Deploying/destroying all bundles is wasteful—targeted actions are needed.&lt;/P&gt;
&lt;/LI&gt;
&lt;LI class="py-0 my-0 prose-p:pt-0 prose-p:mb-2 prose-p:my-0 [&amp;amp;&amp;gt;p]:pt-0 [&amp;amp;&amp;gt;p]:mb-2 [&amp;amp;&amp;gt;p]:my-0"&gt;
&lt;P class="my-2 [&amp;amp;+p]:mt-4 [&amp;amp;_strong:has(+br)]:inline-block [&amp;amp;_strong:has(+br)]:pb-2"&gt;&lt;STRONG&gt;Clean-up (destruction)&lt;/STRONG&gt;: To avoid resource waste in dynamic environments, you must reliably detect which bundles should be destroyed after a MR merge.&lt;/P&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;HR /&gt;
&lt;H2 class="mb-2 mt-4 font-display font-semimedium text-base first:mt-0"&gt;Practical Strategies&lt;/H2&gt;
&lt;H2 class="mb-2 mt-4 font-display font-semimedium text-base first:mt-0"&gt;1.&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;Artifact and Bundle Tracking (Recommended)&lt;/STRONG&gt;&lt;/H2&gt;
&lt;P class="my-2 [&amp;amp;+p]:mt-4 [&amp;amp;_strong:has(+br)]:inline-block [&amp;amp;_strong:has(+br)]:pb-2"&gt;Store a manifest of changed bundles as a pipeline artifact during the MR pipeline, and then consume this manifest in the main branch (post-merge) pipeline.&lt;/P&gt;
&lt;UL class="marker:text-quiet list-disc"&gt;
&lt;LI class="py-0 my-0 prose-p:pt-0 prose-p:mb-2 prose-p:my-0 [&amp;amp;&amp;gt;p]:pt-0 [&amp;amp;&amp;gt;p]:mb-2 [&amp;amp;&amp;gt;p]:my-0"&gt;
&lt;P class="my-2 [&amp;amp;+p]:mt-4 [&amp;amp;_strong:has(+br)]:inline-block [&amp;amp;_strong:has(+br)]:pb-2"&gt;&lt;STRONG&gt;How it works:&lt;/STRONG&gt;&lt;/P&gt;
&lt;UL class="marker:text-quiet list-disc"&gt;
&lt;LI class="py-0 my-0 prose-p:pt-0 prose-p:mb-2 prose-p:my-0 [&amp;amp;&amp;gt;p]:pt-0 [&amp;amp;&amp;gt;p]:mb-2 [&amp;amp;&amp;gt;p]:my-0"&gt;
&lt;P class="my-2 [&amp;amp;+p]:mt-4 [&amp;amp;_strong:has(+br)]:inline-block [&amp;amp;_strong:has(+br)]:pb-2"&gt;&lt;STRONG&gt;During MR pipeline:&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;Use&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;git diff&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;to determine changed bundle folders, save to a manifest file (e.g.,&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;changed_bundles.txt&lt;/CODE&gt;), and upload as an MR pipeline artifact.&lt;/P&gt;
&lt;/LI&gt;
&lt;LI class="py-0 my-0 prose-p:pt-0 prose-p:mb-2 prose-p:my-0 [&amp;amp;&amp;gt;p]:pt-0 [&amp;amp;&amp;gt;p]:mb-2 [&amp;amp;&amp;gt;p]:my-0"&gt;
&lt;P class="my-2 [&amp;amp;+p]:mt-4 [&amp;amp;_strong:has(+br)]:inline-block [&amp;amp;_strong:has(+br)]:pb-2"&gt;&lt;STRONG&gt;Main branch pipeline:&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;Download the artifact from the most recent MR pipeline(s) associated with that commit (using your CI system’s API or environment variables). Use this manifest to restrict deployment/destruction actions.&lt;/P&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;LI class="py-0 my-0 prose-p:pt-0 prose-p:mb-2 prose-p:my-0 [&amp;amp;&amp;gt;p]:pt-0 [&amp;amp;&amp;gt;p]:mb-2 [&amp;amp;&amp;gt;p]:my-0"&gt;
&lt;P class="my-2 [&amp;amp;+p]:mt-4 [&amp;amp;_strong:has(+br)]:inline-block [&amp;amp;_strong:has(+br)]:pb-2"&gt;&lt;STRONG&gt;Advantages:&lt;/STRONG&gt;&lt;/P&gt;
&lt;UL class="marker:text-quiet list-disc"&gt;
&lt;LI class="py-0 my-0 prose-p:pt-0 prose-p:mb-2 prose-p:my-0 [&amp;amp;&amp;gt;p]:pt-0 [&amp;amp;&amp;gt;p]:mb-2 [&amp;amp;&amp;gt;p]:my-0"&gt;
&lt;P class="my-2 [&amp;amp;+p]:mt-4 [&amp;amp;_strong:has(+br)]:inline-block [&amp;amp;_strong:has(+br)]:pb-2"&gt;Precise, works through squash/rebase merges.&lt;/P&gt;
&lt;/LI&gt;
&lt;LI class="py-0 my-0 prose-p:pt-0 prose-p:mb-2 prose-p:my-0 [&amp;amp;&amp;gt;p]:pt-0 [&amp;amp;&amp;gt;p]:mb-2 [&amp;amp;&amp;gt;p]:my-0"&gt;
&lt;P class="my-2 [&amp;amp;+p]:mt-4 [&amp;amp;_strong:has(+br)]:inline-block [&amp;amp;_strong:has(+br)]:pb-2"&gt;Minimizes unnecessary deploy/destroy actions.&lt;/P&gt;
&lt;/LI&gt;
&lt;LI class="py-0 my-0 prose-p:pt-0 prose-p:mb-2 prose-p:my-0 [&amp;amp;&amp;gt;p]:pt-0 [&amp;amp;&amp;gt;p]:mb-2 [&amp;amp;&amp;gt;p]:my-0"&gt;
&lt;P class="my-2 [&amp;amp;+p]:mt-4 [&amp;amp;_strong:has(+br)]:inline-block [&amp;amp;_strong:has(+br)]:pb-2"&gt;Scales to multiple contributors and concurrent MRs.&lt;/P&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;LI class="py-0 my-0 prose-p:pt-0 prose-p:mb-2 prose-p:my-0 [&amp;amp;&amp;gt;p]:pt-0 [&amp;amp;&amp;gt;p]:mb-2 [&amp;amp;&amp;gt;p]:my-0"&gt;
&lt;P class="my-2 [&amp;amp;+p]:mt-4 [&amp;amp;_strong:has(+br)]:inline-block [&amp;amp;_strong:has(+br)]:pb-2"&gt;&lt;STRONG&gt;Potential caveats:&lt;/STRONG&gt;&lt;/P&gt;
&lt;UL class="marker:text-quiet list-disc"&gt;
&lt;LI class="py-0 my-0 prose-p:pt-0 prose-p:mb-2 prose-p:my-0 [&amp;amp;&amp;gt;p]:pt-0 [&amp;amp;&amp;gt;p]:mb-2 [&amp;amp;&amp;gt;p]:my-0"&gt;
&lt;P class="my-2 [&amp;amp;+p]:mt-4 [&amp;amp;_strong:has(+br)]:inline-block [&amp;amp;_strong:has(+br)]:pb-2"&gt;Artifact retrieval scripts must handle edge cases with multiple concurrent pipelines and merges.&lt;/P&gt;
&lt;/LI&gt;
&lt;LI class="py-0 my-0 prose-p:pt-0 prose-p:mb-2 prose-p:my-0 [&amp;amp;&amp;gt;p]:pt-0 [&amp;amp;&amp;gt;p]:mb-2 [&amp;amp;&amp;gt;p]:my-0"&gt;
&lt;P class="my-2 [&amp;amp;+p]:mt-4 [&amp;amp;_strong:has(+br)]:inline-block [&amp;amp;_strong:has(+br)]:pb-2"&gt;Some CI/CD systems (like GitLab and GitHub Actions) support "pass artifacts" or "pipeline attachments," but you must map pipelines to commits.&lt;/P&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2 class="mb-2 mt-4 font-display font-semimedium text-base first:mt-0"&gt;2.&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;Commit Message and Metadata Parsing&lt;/STRONG&gt;&lt;/H2&gt;
&lt;P class="my-2 [&amp;amp;+p]:mt-4 [&amp;amp;_strong:has(+br)]:inline-block [&amp;amp;_strong:has(+br)]:pb-2"&gt;Require the MR pipeline to attach metadata to the merge commit on main (e.g., via commit message, tag, or secret file update) listing the changed bundles. Your main branch pipeline can parse this metadata.&lt;/P&gt;
&lt;UL class="marker:text-quiet list-disc"&gt;
&lt;LI class="py-0 my-0 prose-p:pt-0 prose-p:mb-2 prose-p:my-0 [&amp;amp;&amp;gt;p]:pt-0 [&amp;amp;&amp;gt;p]:mb-2 [&amp;amp;&amp;gt;p]:my-0"&gt;
&lt;P class="my-2 [&amp;amp;+p]:mt-4 [&amp;amp;_strong:has(+br)]:inline-block [&amp;amp;_strong:has(+br)]:pb-2"&gt;&lt;STRONG&gt;How it works:&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;For example, append something like&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;BUNDLES_CHANGED: dabs/foo, dabs/bar&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;to the merge commit. Use CI scripting to parse the commit message for bundle names.&lt;/P&gt;
&lt;/LI&gt;
&lt;LI class="py-0 my-0 prose-p:pt-0 prose-p:mb-2 prose-p:my-0 [&amp;amp;&amp;gt;p]:pt-0 [&amp;amp;&amp;gt;p]:mb-2 [&amp;amp;&amp;gt;p]:my-0"&gt;
&lt;P class="my-2 [&amp;amp;+p]:mt-4 [&amp;amp;_strong:has(+br)]:inline-block [&amp;amp;_strong:has(+br)]:pb-2"&gt;&lt;STRONG&gt;Caveats:&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;Less robust if contributors bypass conventions or push directly.&lt;/P&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2 class="mb-2 mt-4 font-display font-semimedium text-base first:mt-0"&gt;3.&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;Re-Query the Git History (with Limits)&lt;/STRONG&gt;&lt;/H2&gt;
&lt;P class="my-2 [&amp;amp;+p]:mt-4 [&amp;amp;_strong:has(+br)]:inline-block [&amp;amp;_strong:has(+br)]:pb-2"&gt;In the main branch pipeline, use&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;git log&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;+&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;git diff&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;to compare the last merge commit(s) or the last N commits on main. This is imperfect with large/parallel changes, but works if merges are sequential.&lt;/P&gt;
&lt;UL class="marker:text-quiet list-disc"&gt;
&lt;LI class="py-0 my-0 prose-p:pt-0 prose-p:mb-2 prose-p:my-0 [&amp;amp;&amp;gt;p]:pt-0 [&amp;amp;&amp;gt;p]:mb-2 [&amp;amp;&amp;gt;p]:my-0"&gt;
&lt;P class="my-2 [&amp;amp;+p]:mt-4 [&amp;amp;_strong:has(+br)]:inline-block [&amp;amp;_strong:has(+br)]:pb-2"&gt;&lt;STRONG&gt;Example:&lt;/STRONG&gt;&lt;/P&gt;
&lt;DIV class="w-full md:max-w-[90vw]"&gt;
&lt;DIV class="codeWrapper text-light selection:text-super selection:bg-super/10 my-md relative flex flex-col rounded-lg font-mono text-sm font-normal bg-subtler"&gt;
&lt;DIV class="translate-y-xs -translate-x-xs bottom-xl mb-xl flex h-0 items-start justify-end md:sticky md:top-[calc(var(--header-height)+var(--size-xs))]"&gt;
&lt;DIV class="overflow-hidden rounded-full border-subtlest ring-subtlest divide-subtlest bg-base"&gt;
&lt;DIV class="border-subtlest ring-subtlest divide-subtlest bg-subtler"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="-mt-xl"&gt;
&lt;DIV&gt;
&lt;DIV class="text-quiet bg-subtle py-xs px-sm inline-block rounded-br rounded-tl-lg text-xs font-thin" data-testid="code-language-indicator"&gt;text&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV&gt;&lt;SPAN&gt;&lt;CODE&gt;git fetch origin
git diff --name-status HEAD~1 HEAD -- dabs/
&lt;/CODE&gt;&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;P class="my-2 [&amp;amp;+p]:mt-4 [&amp;amp;_strong:has(+br)]:inline-block [&amp;amp;_strong:has(+br)]:pb-2"&gt;(Replace&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;HEAD~1&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;with the correct ancestor commit based on your CI/CD provider’s merge mechanism.)&lt;/P&gt;
&lt;/LI&gt;
&lt;LI class="py-0 my-0 prose-p:pt-0 prose-p:mb-2 prose-p:my-0 [&amp;amp;&amp;gt;p]:pt-0 [&amp;amp;&amp;gt;p]:mb-2 [&amp;amp;&amp;gt;p]:my-0"&gt;
&lt;P class="my-2 [&amp;amp;+p]:mt-4 [&amp;amp;_strong:has(+br)]:inline-block [&amp;amp;_strong:has(+br)]:pb-2"&gt;&lt;STRONG&gt;Limitations:&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;Won’t account for overlapping changes from multiple merged MRs if using squash/rebase.&lt;/P&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;HR /&gt;
&lt;H2 class="mb-2 mt-4 font-display font-semimedium text-base first:mt-0"&gt;Handling Destruction of Bundles&lt;/H2&gt;
&lt;P class="my-2 [&amp;amp;+p]:mt-4 [&amp;amp;_strong:has(+br)]:inline-block [&amp;amp;_strong:has(+br)]:pb-2"&gt;Destruction is harder: it requires knowledge of both changed and deleted bundles (e.g., folders removed in the MR).&lt;/P&gt;
&lt;UL class="marker:text-quiet list-disc"&gt;
&lt;LI class="py-0 my-0 prose-p:pt-0 prose-p:mb-2 prose-p:my-0 [&amp;amp;&amp;gt;p]:pt-0 [&amp;amp;&amp;gt;p]:mb-2 [&amp;amp;&amp;gt;p]:my-0"&gt;
&lt;P class="my-2 [&amp;amp;+p]:mt-4 [&amp;amp;_strong:has(+br)]:inline-block [&amp;amp;_strong:has(+br)]:pb-2"&gt;Store full bundle folder inventory as a file on the main branch (e.g.,&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;all_bundles.txt&lt;/CODE&gt;), regenerate it in each pipeline, and track deletions via diff.&lt;/P&gt;
&lt;/LI&gt;
&lt;LI class="py-0 my-0 prose-p:pt-0 prose-p:mb-2 prose-p:my-0 [&amp;amp;&amp;gt;p]:pt-0 [&amp;amp;&amp;gt;p]:mb-2 [&amp;amp;&amp;gt;p]:my-0"&gt;
&lt;P class="my-2 [&amp;amp;+p]:mt-4 [&amp;amp;_strong:has(+br)]:inline-block [&amp;amp;_strong:has(+br)]:pb-2"&gt;Deploy logic: If a bundle was present in the previous&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;main&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;pipeline but no longer exists, trigger destruction for that environment.&lt;/P&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;HR /&gt;
&lt;H2 class="mb-2 mt-4 font-display font-semimedium text-base first:mt-0"&gt;Recommendations&lt;/H2&gt;
&lt;UL class="marker:text-quiet list-disc"&gt;
&lt;LI class="py-0 my-0 prose-p:pt-0 prose-p:mb-2 prose-p:my-0 [&amp;amp;&amp;gt;p]:pt-0 [&amp;amp;&amp;gt;p]:mb-2 [&amp;amp;&amp;gt;p]:my-0"&gt;
&lt;P class="my-2 [&amp;amp;+p]:mt-4 [&amp;amp;_strong:has(+br)]:inline-block [&amp;amp;_strong:has(+br)]:pb-2"&gt;&lt;STRONG&gt;Use artifact-based detection&lt;/STRONG&gt;: This is standard in larger monorepo CI/CD and is robust to squash merges and rebases. Artifacts can be passed with careful management and CI API scripting.&lt;/P&gt;
&lt;/LI&gt;
&lt;LI class="py-0 my-0 prose-p:pt-0 prose-p:mb-2 prose-p:my-0 [&amp;amp;&amp;gt;p]:pt-0 [&amp;amp;&amp;gt;p]:mb-2 [&amp;amp;&amp;gt;p]:my-0"&gt;
&lt;P class="my-2 [&amp;amp;+p]:mt-4 [&amp;amp;_strong:has(+br)]:inline-block [&amp;amp;_strong:has(+br)]:pb-2"&gt;&lt;STRONG&gt;Implement a “bundle index”&lt;/STRONG&gt;: Keep a simple manifest (&lt;CODE&gt;all_bundles.txt&lt;/CODE&gt;) and compare it between runs to detect removals.&lt;/P&gt;
&lt;/LI&gt;
&lt;LI class="py-0 my-0 prose-p:pt-0 prose-p:mb-2 prose-p:my-0 [&amp;amp;&amp;gt;p]:pt-0 [&amp;amp;&amp;gt;p]:mb-2 [&amp;amp;&amp;gt;p]:my-0"&gt;
&lt;P class="my-2 [&amp;amp;+p]:mt-4 [&amp;amp;_strong:has(+br)]:inline-block [&amp;amp;_strong:has(+br)]:pb-2"&gt;&lt;STRONG&gt;Consider automating bundle meta-tracking&lt;/STRONG&gt;: If your CI allows storing variables per pipeline or commit, you can automate bundle change tracking and clean-ups.&lt;/P&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;HR /&gt;
&lt;H2 class="mb-2 mt-4 font-display font-semimedium text-base first:mt-0"&gt;Example: Artifact-Based Approach (GitLab, Pseudocode)&lt;/H2&gt;
&lt;P class="my-2 [&amp;amp;+p]:mt-4 [&amp;amp;_strong:has(+br)]:inline-block [&amp;amp;_strong:has(+br)]:pb-2"&gt;&lt;STRONG&gt;MR Pipeline:&lt;/STRONG&gt;&lt;/P&gt;
&lt;DIV class="w-full md:max-w-[90vw]"&gt;
&lt;DIV class="codeWrapper text-light selection:text-super selection:bg-super/10 my-md relative flex flex-col rounded-lg font-mono text-sm font-normal bg-subtler"&gt;
&lt;DIV class="translate-y-xs -translate-x-xs bottom-xl mb-xl flex h-0 items-start justify-end md:sticky md:top-[calc(var(--header-height)+var(--size-xs))]"&gt;
&lt;DIV class="overflow-hidden rounded-full border-subtlest ring-subtlest divide-subtlest bg-base"&gt;
&lt;DIV class="border-subtlest ring-subtlest divide-subtlest bg-subtler"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="-mt-xl"&gt;
&lt;DIV&gt;
&lt;DIV class="text-quiet bg-subtle py-xs px-sm inline-block rounded-br rounded-tl-lg text-xs font-thin" data-testid="code-language-indicator"&gt;bash&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV&gt;&lt;SPAN&gt;&lt;CODE&gt;&lt;SPAN class="token token"&gt;git&lt;/SPAN&gt; &lt;SPAN class="token token"&gt;diff&lt;/SPAN&gt; --name-status origin/&lt;SPAN class="token token"&gt;$CI_MERGE_REQUEST_TARGET_BRANCH_NAME&lt;/SPAN&gt; origin/&lt;SPAN class="token token"&gt;$CI_COMMIT_REF_NAME&lt;/SPAN&gt; -- dabs/ &lt;SPAN class="token token operator"&gt;|&lt;/SPAN&gt; &lt;SPAN class="token token punctuation"&gt;\&lt;/SPAN&gt;
&lt;SPAN class="token token"&gt;awk&lt;/SPAN&gt; &lt;SPAN class="token token"&gt;'{print $2}'&lt;/SPAN&gt; &lt;SPAN class="token token operator"&gt;|&lt;/SPAN&gt; &lt;SPAN class="token token"&gt;awk&lt;/SPAN&gt; -F/ &lt;SPAN class="token token"&gt;'{print $2}'&lt;/SPAN&gt; &lt;SPAN class="token token operator"&gt;|&lt;/SPAN&gt; &lt;SPAN class="token token"&gt;sort&lt;/SPAN&gt; -u &lt;SPAN class="token token operator"&gt;&amp;gt;&lt;/SPAN&gt; changed_bundles.txt
&lt;SPAN class="token token"&gt;# Save as artifact&lt;/SPAN&gt;
&lt;/CODE&gt;&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;P class="my-2 [&amp;amp;+p]:mt-4 [&amp;amp;_strong:has(+br)]:inline-block [&amp;amp;_strong:has(+br)]:pb-2"&gt;&lt;STRONG&gt;Main Pipeline:&lt;/STRONG&gt;&lt;/P&gt;
&lt;UL class="marker:text-quiet list-disc"&gt;
&lt;LI class="py-0 my-0 prose-p:pt-0 prose-p:mb-2 prose-p:my-0 [&amp;amp;&amp;gt;p]:pt-0 [&amp;amp;&amp;gt;p]:mb-2 [&amp;amp;&amp;gt;p]:my-0"&gt;
&lt;P class="my-2 [&amp;amp;+p]:mt-4 [&amp;amp;_strong:has(+br)]:inline-block [&amp;amp;_strong:has(+br)]:pb-2"&gt;Use the CI system’s API (e.g., GitLab’s&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;CI_PIPELINE_SOURCE&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;and/or its REST API) to find the latest pipeline for each merged MR commit and retrieve&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;changed_bundles.txt&lt;/CODE&gt;.&lt;/P&gt;
&lt;/LI&gt;
&lt;LI class="py-0 my-0 prose-p:pt-0 prose-p:mb-2 prose-p:my-0 [&amp;amp;&amp;gt;p]:pt-0 [&amp;amp;&amp;gt;p]:mb-2 [&amp;amp;&amp;gt;p]:my-0"&gt;
&lt;P class="my-2 [&amp;amp;+p]:mt-4 [&amp;amp;_strong:has(+br)]:inline-block [&amp;amp;_strong:has(+br)]:pb-2"&gt;Use this list to trigger deployments/destructions.&lt;/P&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;HR /&gt;
&lt;H2 class="mb-2 mt-4 font-display font-semimedium text-base first:mt-0"&gt;Avoiding Deploy-All&lt;/H2&gt;
&lt;UL class="marker:text-quiet list-disc"&gt;
&lt;LI class="py-0 my-0 prose-p:pt-0 prose-p:mb-2 prose-p:my-0 [&amp;amp;&amp;gt;p]:pt-0 [&amp;amp;&amp;gt;p]:mb-2 [&amp;amp;&amp;gt;p]:my-0"&gt;
&lt;P class="my-2 [&amp;amp;+p]:mt-4 [&amp;amp;_strong:has(+br)]:inline-block [&amp;amp;_strong:has(+br)]:pb-2"&gt;&lt;STRONG&gt;Never deploy/destroy all unless necessary.&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;This is inefficient and risks unintended side effects.&lt;/P&gt;
&lt;/LI&gt;
&lt;LI class="py-0 my-0 prose-p:pt-0 prose-p:mb-2 prose-p:my-0 [&amp;amp;&amp;gt;p]:pt-0 [&amp;amp;&amp;gt;p]:mb-2 [&amp;amp;&amp;gt;p]:my-0"&gt;
&lt;P class="my-2 [&amp;amp;+p]:mt-4 [&amp;amp;_strong:has(+br)]:inline-block [&amp;amp;_strong:has(+br)]:pb-2"&gt;&lt;STRONG&gt;For deleted bundles&lt;/STRONG&gt;: Compare the previous and current list of bundles and destroy only those removed from the repo.&lt;/P&gt;
&lt;/LI&gt;
&lt;/UL&gt;</description>
      <pubDate>Mon, 17 Nov 2025 11:55:47 GMT</pubDate>
      <guid>https://community.databricks.com/t5/data-engineering/ci-cd-databricks-asset-bundles-deploy-destroy-only-bundles-with/m-p/139320#M51156</guid>
      <dc:creator>mark_ott</dc:creator>
      <dc:date>2025-11-17T11:55:47Z</dc:date>
    </item>
  </channel>
</rss>

