This is an automated email from the ASF dual-hosted git repository.
potiuk pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/main by this push:
new 01ce2deda4e CI: Publish canary SBOMs with main docs (#63310)
01ce2deda4e is described below
commit 01ce2deda4e23d6bd6310f7f4b1b8b9f5e9b6eac
Author: Aaron Chen <[email protected]>
AuthorDate: Fri Mar 13 06:36:51 2026 -0700
CI: Publish canary SBOMs with main docs (#63310)
---
.github/workflows/ci-image-checks.yml | 33 +++++
.../images/output_sbom_update-sbom-information.svg | 72 ++++++-----
.../images/output_sbom_update-sbom-information.txt | 2 +-
.../src/airflow_breeze/commands/sbom_commands.py | 18 ++-
.../commands/sbom_commands_config.py | 1 +
dev/breeze/src/airflow_breeze/utils/cdxgen.py | 4 +-
dev/breeze/tests/test_sbom_commands.py | 133 +++++++++++++++++++++
7 files changed, 228 insertions(+), 35 deletions(-)
diff --git a/.github/workflows/ci-image-checks.yml
b/.github/workflows/ci-image-checks.yml
index 126bf9fd1f7..de3d48ca581 100644
--- a/.github/workflows/ci-image-checks.yml
+++ b/.github/workflows/ci-image-checks.yml
@@ -316,6 +316,39 @@ jobs:
with:
name: airflow-docs
path: './generated/_build'
+ - name: "Make sure SBOM dir exists and has the right permissions"
+ run: |
+ sudo mkdir -vp ./files/sbom
+ sudo chown -R "${USER}" .
+ if: >
+ inputs.canary-run == 'true' &&
+ (github.event_name == 'schedule' || github.event_name ==
'workflow_dispatch')
+ - name: "Determine Airflow version for SBOMs"
+ run: |
+ AIRFLOW_VERSION=$(awk -F'"' '/^__version__ = / {print $2}'
airflow-core/src/airflow/__init__.py)
+ test -n "${AIRFLOW_VERSION}"
+ echo "AIRFLOW_VERSION=${AIRFLOW_VERSION}" >> "${GITHUB_ENV}"
+ if: >
+ inputs.canary-run == 'true' &&
+ (github.event_name == 'schedule' || github.event_name ==
'workflow_dispatch')
+ - name: "Prepare SBOMs"
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ run: >
+ breeze sbom update-sbom-information
+ --airflow-version ${AIRFLOW_VERSION} --remote-name origin --force
+ --all-combinations --run-in-parallel --airflow-root-path
"${GITHUB_WORKSPACE}"
+ --airflow-constraints-reference constraints-main
+ if: >
+ inputs.canary-run == 'true' &&
+ (github.event_name == 'schedule' || github.event_name ==
'workflow_dispatch')
+ - name: "Generated SBOM files"
+ run: |
+ echo "Generated SBOM files:"
+ find ./generated/_build/docs/apache-airflow/stable/sbom/ -type f |
sort
+ if: >
+ inputs.canary-run == 'true' &&
+ (github.event_name == 'schedule' || github.event_name ==
'workflow_dispatch')
- name: Check disk space available
run: df -H
- name: Create /mnt/airflow-site directory
diff --git a/dev/breeze/doc/images/output_sbom_update-sbom-information.svg
b/dev/breeze/doc/images/output_sbom_update-sbom-information.svg
index 152fea8b5fd..7fe1a450eee 100644
--- a/dev/breeze/doc/images/output_sbom_update-sbom-information.svg
+++ b/dev/breeze/doc/images/output_sbom_update-sbom-information.svg
@@ -1,4 +1,4 @@
-<svg class="rich-terminal" viewBox="0 0 1482 1270.0"
xmlns="http://www.w3.org/2000/svg">
+<svg class="rich-terminal" viewBox="0 0 1482 1318.8"
xmlns="http://www.w3.org/2000/svg">
<!-- Generated with Rich https://www.textualize.io -->
<style>
@@ -43,7 +43,7 @@
<defs>
<clipPath id="breeze-sbom-update-sbom-information-clip-terminal">
- <rect x="0" y="0" width="1463.0" height="1219.0" />
+ <rect x="0" y="0" width="1463.0" height="1267.8" />
</clipPath>
<clipPath id="breeze-sbom-update-sbom-information-line-0">
<rect x="0" y="1.5" width="1464" height="24.65"/>
@@ -192,9 +192,15 @@
<clipPath id="breeze-sbom-update-sbom-information-line-48">
<rect x="0" y="1172.7" width="1464" height="24.65"/>
</clipPath>
+<clipPath id="breeze-sbom-update-sbom-information-line-49">
+ <rect x="0" y="1197.1" width="1464" height="24.65"/>
+ </clipPath>
+<clipPath id="breeze-sbom-update-sbom-information-line-50">
+ <rect x="0" y="1221.5" width="1464" height="24.65"/>
+ </clipPath>
</defs>
- <rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1"
x="1" y="1" width="1480" height="1268" rx="8"/><text
class="breeze-sbom-update-sbom-information-title" fill="#c5c8c6"
text-anchor="middle" x="740"
y="27">Command: sbom update-sbom-information</text>
+ <rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1"
x="1" y="1" width="1480" height="1316.8" rx="8"/><text
class="breeze-sbom-update-sbom-information-title" fill="#c5c8c6"
text-anchor="middle" x="740"
y="27">Command: sbom update-sbom-information</text>
<g transform="translate(26,22)">
<circle cx="0" cy="0" r="7" fill="#ff5f57"/>
<circle cx="22" cy="0" r="7" fill="#febc2e"/>
@@ -225,35 +231,37 @@
</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="459.2"
textLength="12.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-18)">│</text><text
class="breeze-sbom-update-sbom-information-r6" x="488" y="459.2"
textLength="85.4"
clip-path="url(#breeze-sbom-update-sbom-information-line-18)">origin)</text><text
class="breeze-sbom-update-sbom-information-r5" x="1451.8" y="459.2"
textLength="12.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-18)">│</text>< [...]
</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="483.6"
textLength="12.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-19)">│</text><text
class="breeze-sbom-update-sbom-information-r4" x="24.4" y="483.6"
textLength="439.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-19)">--airflow-version                   </text><text
class="breeze-sbom-update-sbom- [...]
</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="508"
textLength="12.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-20)">│</text><text
class="breeze-sbom-update-sbom-information-r1" x="488" y="508" textLength="122"
clip-path="url(#breeze-sbom-update-sbom-information-line-20)">versions) </text><text
class="breeze-sbom-update-sbom-information-r6" x="610" y="508"
textLength="73.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-20)">(TEXT)</tex [...]
-</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="532.4"
textLength="12.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-21)">│</text><text
class="breeze-sbom-update-sbom-information-r4" x="24.4" y="532.4"
textLength="439.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-21)">--python-versions                   </text><text
class="breeze-sbom-update-sbom- [...]
-</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="556.8"
textLength="12.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-22)">│</text><text
class="breeze-sbom-update-sbom-information-r1" x="488" y="556.8"
textLength="341.6"
clip-path="url(#breeze-sbom-update-sbom-information-line-22)">historical python versions) </text><text
class="breeze-sbom-update-sbom-information-r6" x="829.6" y="556.8"
textLength="561.2" clip-path="url(#breeze-sbom-update [...]
-</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="581.2"
textLength="12.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-23)">│</text><text
class="breeze-sbom-update-sbom-information-r6" x="488" y="581.2"
textLength="61"
clip-path="url(#breeze-sbom-update-sbom-information-line-23)">3.13)</text><text
class="breeze-sbom-update-sbom-information-r5" x="1451.8" y="581.2"
textLength="12.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-23)">│</text><text
[...]
-</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="605.6"
textLength="12.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-24)">│</text><text
class="breeze-sbom-update-sbom-information-r4" x="24.4" y="605.6"
textLength="439.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-24)">--include-provider-dependencies     </text><text
class="breeze-sbom-update-sbom-information-r1" x="488" y="605.6"
textLength="732" clip-path="url(#bre [...]
-</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="630"
textLength="12.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-25)">│</text><text
class="breeze-sbom-update-sbom-information-r4" x="24.4" y="630"
textLength="195.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-25)">--include-python</text><text
class="breeze-sbom-update-sbom-information-r1" x="219.6" y="630"
textLength="12.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-25)">/</te [...]
-</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="654.4"
textLength="12.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-26)">│</text><text
class="breeze-sbom-update-sbom-information-r4" x="24.4" y="654.4"
textLength="158.6"
clip-path="url(#breeze-sbom-update-sbom-information-line-26)">--include-npm</text><text
class="breeze-sbom-update-sbom-information-r1" x="183" y="654.4"
textLength="12.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-26)">/</t [...]
-</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="678.8"
textLength="12.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-27)">│</text><text
class="breeze-sbom-update-sbom-information-r4" x="24.4" y="678.8"
textLength="439.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-27)">--all-combinations                  </text><text
class="breeze-sbom-update-sbom-infor [...]
-</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="703.2"
textLength="12.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-28)">│</text><text
class="breeze-sbom-update-sbom-information-r4" x="488" y="703.2"
textLength="109.8"
clip-path="url(#breeze-sbom-update-sbom-information-line-28)">--include</text><text
class="breeze-sbom-update-sbom-information-r1" x="597.8" y="703.2"
textLength="841.8"
clip-path="url(#breeze-sbom-update-sbom-information-line-28)">  [...]
-</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="727.6"
textLength="12.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-29)">│</text><text
class="breeze-sbom-update-sbom-information-r4" x="24.4" y="727.6"
textLength="439.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-29)">--package-filter                    </text><text
class="breeze-sbom-update- [...]
-</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="752"
textLength="12.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-30)">│</text><text
class="breeze-sbom-update-sbom-information-r1" x="488" y="752"
textLength="951.6"
clip-path="url(#breeze-sbom-update-sbom-information-line-30)">matching the full package name, for example `apache-airflow-providers-*`.     </text><text
class="breeze-sbom-update-sbo [...]
-</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="776.4"
textLength="12.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-31)">│</text><text
class="breeze-sbom-update-sbom-information-r1" x="488" y="776.4"
textLength="951.6"
clip-path="url(#breeze-sbom-update-sbom-information-line-31)">Useful when you want to selectseveral similarly named packages together.      </text><text
class="bre [...]
-</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="800.8"
textLength="12.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-32)">│</text><text
class="breeze-sbom-update-sbom-information-r6" x="488" y="800.8"
textLength="524.6"
clip-path="url(#breeze-sbom-update-sbom-information-line-32)">(apache-airflow-providers | apache-airflow)</text><text
class="breeze-sbom-update-sbom-information-r5" x="1451.8" y="800.8"
textLength="12.2" clip-path="url(#breeze-s [...]
-</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="825.2"
textLength="12.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-33)">│</text><text
class="breeze-sbom-update-sbom-information-r4" x="24.4" y="825.2"
textLength="439.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-33)">--force                            
[...]
-</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="849.6"
textLength="12.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-34)">│</text><text
class="breeze-sbom-update-sbom-information-r4" x="24.4" y="849.6"
textLength="439.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-34)">--github-token                      </text><text
class="breeze-sb [...]
-</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="874"
textLength="1464"
clip-path="url(#breeze-sbom-update-sbom-information-line-35)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
class="breeze-sbom-update-sbom-information-r1" x="1464" y="874"
textLength="12.2" clip-path="url(#breeze-sbom-update-sbom-information-line-35)">
-</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="898.4"
textLength="24.4"
clip-path="url(#breeze-sbom-update-sbom-information-line-36)">╭─</text><text
class="breeze-sbom-update-sbom-information-r5" x="24.4" y="898.4"
textLength="219.6"
clip-path="url(#breeze-sbom-update-sbom-information-line-36)"> Parallel running </text><text
class="breeze-sbom-update-sbom-information-r5" x="244" y="898.4"
textLength="1195.6" clip-path="url(#breeze-sbom-update-sbom-inf [...]
-</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="922.8"
textLength="12.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-37)">│</text><text
class="breeze-sbom-update-sbom-information-r4" x="24.4" y="922.8"
textLength="305"
clip-path="url(#breeze-sbom-update-sbom-information-line-37)">--run-in-parallel        </text><text
class="breeze-sbom-update-sbom-information-r1" x="353.8" y="922.8"
textLength="854" clip-path="url( [...]
-</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="947.2"
textLength="12.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-38)">│</text><text
class="breeze-sbom-update-sbom-information-r4" x="24.4" y="947.2"
textLength="305"
clip-path="url(#breeze-sbom-update-sbom-information-line-38)">--parallelism            </text><text
class="breeze-sbom-update-sbom-information-r1" x="353.8" y="947.2"
textLength=" [...]
-</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="971.6"
textLength="12.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-39)">│</text><text
class="breeze-sbom-update-sbom-information-r6" x="353.8" y="971.6"
textLength="280.6"
clip-path="url(#breeze-sbom-update-sbom-information-line-39)">(INTEGER RANGE 1<=x<=8)</text><text
class="breeze-sbom-update-sbom-information-r5" x="1451.8" y="971.6"
textLength="12.2" clip-path="url(#breeze-sbom-update-s [...]
-</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="996"
textLength="12.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-40)">│</text><text
class="breeze-sbom-update-sbom-information-r4" x="24.4" y="996"
textLength="305"
clip-path="url(#breeze-sbom-update-sbom-information-line-40)">--skip-cleanup           </text><text
class="breeze-sbom-update-sbom-information-r1" x="353.8" y="996"
textLength="732" clip-p [...]
-</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="1020.4"
textLength="12.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-41)">│</text><text
class="breeze-sbom-update-sbom-information-r4" x="24.4" y="1020.4"
textLength="305"
clip-path="url(#breeze-sbom-update-sbom-information-line-41)">--debug-resources        </text><text
class="breeze-sbom-update-sbom-information-r1" x="353.8" y="1020.4"
textLength="768.6" clip-path= [...]
-</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="1044.8"
textLength="12.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-42)">│</text><text
class="breeze-sbom-update-sbom-information-r4" x="24.4" y="1044.8"
textLength="305"
clip-path="url(#breeze-sbom-update-sbom-information-line-42)">--include-success-outputs</text><text
class="breeze-sbom-update-sbom-information-r1" x="353.8" y="1044.8"
textLength="841.8" clip-path="url(#breeze-sbom-update-sbom-informatio [...]
-</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="1069.2"
textLength="1464"
clip-path="url(#breeze-sbom-update-sbom-information-line-43)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
class="breeze-sbom-update-sbom-information-r1" x="1464" y="1069.2"
textLength="12.2" clip-path="url(#breeze-sbom-update-sbom-information-line-43)">
-</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="1093.6"
textLength="24.4"
clip-path="url(#breeze-sbom-update-sbom-information-line-44)">╭─</text><text
class="breeze-sbom-update-sbom-information-r5" x="24.4" y="1093.6"
textLength="195.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-44)"> Common options </text><text
class="breeze-sbom-update-sbom-information-r5" x="219.6" y="1093.6"
textLength="1220" clip-path="url(#breeze-sbom-update-sbom-in [...]
-</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="1118"
textLength="12.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-45)">│</text><text
class="breeze-sbom-update-sbom-information-r4" x="24.4" y="1118"
textLength="109.8"
clip-path="url(#breeze-sbom-update-sbom-information-line-45)">--verbose</text><text
class="breeze-sbom-update-sbom-information-r7" x="158.6" y="1118"
textLength="24.4"
clip-path="url(#breeze-sbom-update-sbom-information-line-45)">-v</text> [...]
-</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="1142.4"
textLength="12.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-46)">│</text><text
class="breeze-sbom-update-sbom-information-r4" x="24.4" y="1142.4"
textLength="109.8"
clip-path="url(#breeze-sbom-update-sbom-information-line-46)">--dry-run</text><text
class="breeze-sbom-update-sbom-information-r7" x="158.6" y="1142.4"
textLength="24.4"
clip-path="url(#breeze-sbom-update-sbom-information-line-46)">-D< [...]
-</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="1166.8"
textLength="12.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-47)">│</text><text
class="breeze-sbom-update-sbom-information-r4" x="24.4" y="1166.8"
textLength="109.8"
clip-path="url(#breeze-sbom-update-sbom-information-line-47)">--answer </text><text
class="breeze-sbom-update-sbom-information-r7" x="158.6" y="1166.8"
textLength="24.4" clip-path="url(#breeze-sbom-update-sbom-information-line-47)
[...]
-</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="1191.2"
textLength="12.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-48)">│</text><text
class="breeze-sbom-update-sbom-information-r4" x="24.4" y="1191.2"
textLength="109.8"
clip-path="url(#breeze-sbom-update-sbom-information-line-48)">--help   </text><text
class="breeze-sbom-update-sbom-information-r7" x="158.6" y="1191.2"
textLength="24.4" clip-path="url(#breeze-sbom-update-sbom-informatio [...]
-</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="1215.6"
textLength="1464"
clip-path="url(#breeze-sbom-update-sbom-information-line-49)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
class="breeze-sbom-update-sbom-information-r1" x="1464" y="1215.6"
textLength="12.2" clip-path="url(#breeze-sbom-update-sbom-information-line-49)">
+</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="532.4"
textLength="12.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-21)">│</text><text
class="breeze-sbom-update-sbom-information-r4" x="24.4" y="532.4"
textLength="439.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-21)">--airflow-constraints-reference     </text><text
class="breeze-sbom-update-sbom-information-r1" x="488" y="532.4"
textLength="951.6" clip-path="url(#b [...]
+</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="556.8"
textLength="12.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-22)">│</text><text
class="breeze-sbom-update-sbom-information-r1" x="488" y="556.8"
textLength="597.8"
clip-path="url(#breeze-sbom-update-sbom-information-line-22)">generation. Defaults to constraints derived from </text><text
class="breeze-sbom-update-sbom-information-r4" x="1085.8" y="556.8"
textLength="207. [...]
+</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="581.2"
textLength="12.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-23)">│</text><text
class="breeze-sbom-update-sbom-information-r4" x="24.4" y="581.2"
textLength="439.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-23)">--python-versions                   </text><text
class="breeze-sbom-update-sbom- [...]
+</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="605.6"
textLength="12.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-24)">│</text><text
class="breeze-sbom-update-sbom-information-r1" x="488" y="605.6"
textLength="341.6"
clip-path="url(#breeze-sbom-update-sbom-information-line-24)">historical python versions) </text><text
class="breeze-sbom-update-sbom-information-r6" x="829.6" y="605.6"
textLength="561.2" clip-path="url(#breeze-sbom-update [...]
+</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="630"
textLength="12.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-25)">│</text><text
class="breeze-sbom-update-sbom-information-r6" x="488" y="630" textLength="61"
clip-path="url(#breeze-sbom-update-sbom-information-line-25)">3.13)</text><text
class="breeze-sbom-update-sbom-information-r5" x="1451.8" y="630"
textLength="12.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-25)">│</text><text
class [...]
+</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="654.4"
textLength="12.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-26)">│</text><text
class="breeze-sbom-update-sbom-information-r4" x="24.4" y="654.4"
textLength="439.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-26)">--include-provider-dependencies     </text><text
class="breeze-sbom-update-sbom-information-r1" x="488" y="654.4"
textLength="732" clip-path="url(#bre [...]
+</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="678.8"
textLength="12.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-27)">│</text><text
class="breeze-sbom-update-sbom-information-r4" x="24.4" y="678.8"
textLength="195.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-27)">--include-python</text><text
class="breeze-sbom-update-sbom-information-r1" x="219.6" y="678.8"
textLength="12.2" clip-path="url(#breeze-sbom-update-sbom-information-line-27)"
[...]
+</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="703.2"
textLength="12.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-28)">│</text><text
class="breeze-sbom-update-sbom-information-r4" x="24.4" y="703.2"
textLength="158.6"
clip-path="url(#breeze-sbom-update-sbom-information-line-28)">--include-npm</text><text
class="breeze-sbom-update-sbom-information-r1" x="183" y="703.2"
textLength="12.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-28)">/</t [...]
+</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="727.6"
textLength="12.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-29)">│</text><text
class="breeze-sbom-update-sbom-information-r4" x="24.4" y="727.6"
textLength="439.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-29)">--all-combinations                  </text><text
class="breeze-sbom-update-sbom-infor [...]
+</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="752"
textLength="12.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-30)">│</text><text
class="breeze-sbom-update-sbom-information-r4" x="488" y="752"
textLength="109.8"
clip-path="url(#breeze-sbom-update-sbom-information-line-30)">--include</text><text
class="breeze-sbom-update-sbom-information-r1" x="597.8" y="752"
textLength="841.8"
clip-path="url(#breeze-sbom-update-sbom-information-line-30)"> flags& [...]
+</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="776.4"
textLength="12.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-31)">│</text><text
class="breeze-sbom-update-sbom-information-r4" x="24.4" y="776.4"
textLength="439.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-31)">--package-filter                    </text><text
class="breeze-sbom-update- [...]
+</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="800.8"
textLength="12.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-32)">│</text><text
class="breeze-sbom-update-sbom-information-r1" x="488" y="800.8"
textLength="951.6"
clip-path="url(#breeze-sbom-update-sbom-information-line-32)">matching the full package name, for example `apache-airflow-providers-*`.     </text><text
class="breeze-sbom-update [...]
+</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="825.2"
textLength="12.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-33)">│</text><text
class="breeze-sbom-update-sbom-information-r1" x="488" y="825.2"
textLength="951.6"
clip-path="url(#breeze-sbom-update-sbom-information-line-33)">Useful when you want to selectseveral similarly named packages together.      </text><text
class="bre [...]
+</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="849.6"
textLength="12.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-34)">│</text><text
class="breeze-sbom-update-sbom-information-r6" x="488" y="849.6"
textLength="524.6"
clip-path="url(#breeze-sbom-update-sbom-information-line-34)">(apache-airflow-providers | apache-airflow)</text><text
class="breeze-sbom-update-sbom-information-r5" x="1451.8" y="849.6"
textLength="12.2" clip-path="url(#breeze-s [...]
+</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="874"
textLength="12.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-35)">│</text><text
class="breeze-sbom-update-sbom-information-r4" x="24.4" y="874"
textLength="439.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-35)">--force                            
[...]
+</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="898.4"
textLength="12.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-36)">│</text><text
class="breeze-sbom-update-sbom-information-r4" x="24.4" y="898.4"
textLength="439.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-36)">--github-token                      </text><text
class="breeze-sb [...]
+</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="922.8"
textLength="1464"
clip-path="url(#breeze-sbom-update-sbom-information-line-37)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
class="breeze-sbom-update-sbom-information-r1" x="1464" y="922.8"
textLength="12.2" clip-path="url(#breeze-sbom-update-sbom-information-line-37)">
+</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="947.2"
textLength="24.4"
clip-path="url(#breeze-sbom-update-sbom-information-line-38)">╭─</text><text
class="breeze-sbom-update-sbom-information-r5" x="24.4" y="947.2"
textLength="219.6"
clip-path="url(#breeze-sbom-update-sbom-information-line-38)"> Parallel running </text><text
class="breeze-sbom-update-sbom-information-r5" x="244" y="947.2"
textLength="1195.6" clip-path="url(#breeze-sbom-update-sbom-inf [...]
+</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="971.6"
textLength="12.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-39)">│</text><text
class="breeze-sbom-update-sbom-information-r4" x="24.4" y="971.6"
textLength="305"
clip-path="url(#breeze-sbom-update-sbom-information-line-39)">--run-in-parallel        </text><text
class="breeze-sbom-update-sbom-information-r1" x="353.8" y="971.6"
textLength="854" clip-path="url( [...]
+</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="996"
textLength="12.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-40)">│</text><text
class="breeze-sbom-update-sbom-information-r4" x="24.4" y="996"
textLength="305"
clip-path="url(#breeze-sbom-update-sbom-information-line-40)">--parallelism            </text><text
class="breeze-sbom-update-sbom-information-r1" x="353.8" y="996"
textLength="927.2" [...]
+</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="1020.4"
textLength="12.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-41)">│</text><text
class="breeze-sbom-update-sbom-information-r6" x="353.8" y="1020.4"
textLength="280.6"
clip-path="url(#breeze-sbom-update-sbom-information-line-41)">(INTEGER RANGE 1<=x<=8)</text><text
class="breeze-sbom-update-sbom-information-r5" x="1451.8" y="1020.4"
textLength="12.2" clip-path="url(#breeze-sbom-updat [...]
+</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="1044.8"
textLength="12.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-42)">│</text><text
class="breeze-sbom-update-sbom-information-r4" x="24.4" y="1044.8"
textLength="305"
clip-path="url(#breeze-sbom-update-sbom-information-line-42)">--skip-cleanup           </text><text
class="breeze-sbom-update-sbom-information-r1" x="353.8" y="1044.8"
textLength="73 [...]
+</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="1069.2"
textLength="12.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-43)">│</text><text
class="breeze-sbom-update-sbom-information-r4" x="24.4" y="1069.2"
textLength="305"
clip-path="url(#breeze-sbom-update-sbom-information-line-43)">--debug-resources        </text><text
class="breeze-sbom-update-sbom-information-r1" x="353.8" y="1069.2"
textLength="768.6" clip-path= [...]
+</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="1093.6"
textLength="12.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-44)">│</text><text
class="breeze-sbom-update-sbom-information-r4" x="24.4" y="1093.6"
textLength="305"
clip-path="url(#breeze-sbom-update-sbom-information-line-44)">--include-success-outputs</text><text
class="breeze-sbom-update-sbom-information-r1" x="353.8" y="1093.6"
textLength="841.8" clip-path="url(#breeze-sbom-update-sbom-informatio [...]
+</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="1118"
textLength="1464"
clip-path="url(#breeze-sbom-update-sbom-information-line-45)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
class="breeze-sbom-update-sbom-information-r1" x="1464" y="1118"
textLength="12.2" clip-path="url(#breeze-sbom-update-sbom-information-line-45)">
+</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="1142.4"
textLength="24.4"
clip-path="url(#breeze-sbom-update-sbom-information-line-46)">╭─</text><text
class="breeze-sbom-update-sbom-information-r5" x="24.4" y="1142.4"
textLength="195.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-46)"> Common options </text><text
class="breeze-sbom-update-sbom-information-r5" x="219.6" y="1142.4"
textLength="1220" clip-path="url(#breeze-sbom-update-sbom-in [...]
+</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="1166.8"
textLength="12.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-47)">│</text><text
class="breeze-sbom-update-sbom-information-r4" x="24.4" y="1166.8"
textLength="109.8"
clip-path="url(#breeze-sbom-update-sbom-information-line-47)">--verbose</text><text
class="breeze-sbom-update-sbom-information-r7" x="158.6" y="1166.8"
textLength="24.4"
clip-path="url(#breeze-sbom-update-sbom-information-line-47)">-v< [...]
+</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="1191.2"
textLength="12.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-48)">│</text><text
class="breeze-sbom-update-sbom-information-r4" x="24.4" y="1191.2"
textLength="109.8"
clip-path="url(#breeze-sbom-update-sbom-information-line-48)">--dry-run</text><text
class="breeze-sbom-update-sbom-information-r7" x="158.6" y="1191.2"
textLength="24.4"
clip-path="url(#breeze-sbom-update-sbom-information-line-48)">-D< [...]
+</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="1215.6"
textLength="12.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-49)">│</text><text
class="breeze-sbom-update-sbom-information-r4" x="24.4" y="1215.6"
textLength="109.8"
clip-path="url(#breeze-sbom-update-sbom-information-line-49)">--answer </text><text
class="breeze-sbom-update-sbom-information-r7" x="158.6" y="1215.6"
textLength="24.4" clip-path="url(#breeze-sbom-update-sbom-information-line-49)
[...]
+</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="1240"
textLength="12.2"
clip-path="url(#breeze-sbom-update-sbom-information-line-50)">│</text><text
class="breeze-sbom-update-sbom-information-r4" x="24.4" y="1240"
textLength="109.8"
clip-path="url(#breeze-sbom-update-sbom-information-line-50)">--help   </text><text
class="breeze-sbom-update-sbom-information-r7" x="158.6" y="1240"
textLength="24.4" clip-path="url(#breeze-sbom-update-sbom-information-line [...]
+</text><text class="breeze-sbom-update-sbom-information-r5" x="0" y="1264.4"
textLength="1464"
clip-path="url(#breeze-sbom-update-sbom-information-line-51)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
class="breeze-sbom-update-sbom-information-r1" x="1464" y="1264.4"
textLength="12.2" clip-path="url(#breeze-sbom-update-sbom-information-line-51)">
</text>
</g>
</g>
diff --git a/dev/breeze/doc/images/output_sbom_update-sbom-information.txt
b/dev/breeze/doc/images/output_sbom_update-sbom-information.txt
index 709b6ebb3e1..82bf8b08614 100644
--- a/dev/breeze/doc/images/output_sbom_update-sbom-information.txt
+++ b/dev/breeze/doc/images/output_sbom_update-sbom-information.txt
@@ -1 +1 @@
-16159ccbed065c1e19a36d024ef2144c
+1787b9c259a81b9bfb7837050ea87b42
diff --git a/dev/breeze/src/airflow_breeze/commands/sbom_commands.py
b/dev/breeze/src/airflow_breeze/commands/sbom_commands.py
index ef50c1f41a8..0b864e278fa 100644
--- a/dev/breeze/src/airflow_breeze/commands/sbom_commands.py
+++ b/dev/breeze/src/airflow_breeze/commands/sbom_commands.py
@@ -150,6 +150,14 @@ SBOM_INDEX_TEMPLATE = """
envvar="AIRFLOW_VERSION",
help="Version of airflow to update sbom from. (defaulted to all active
airflow versions)",
)
[email protected](
+ "--airflow-constraints-reference",
+ type=str,
+ required=False,
+ envvar="AIRFLOW_CONSTRAINTS_REFERENCE",
+ help="Constraint reference to use when downloading Airflow constraints for
SBOM generation. "
+ "Defaults to constraints derived from --airflow-version.",
+)
@option_historical_python_versions
@click.option(
"--include-provider-dependencies",
@@ -222,6 +230,7 @@ def update_sbom_information(
airflow_root_path: Path | None,
airflow_site_archive_path: Path | None,
airflow_version: str | None,
+ airflow_constraints_reference: str | None,
all_combinations: bool,
debug_resources: bool,
force: bool,
@@ -252,7 +261,10 @@ def update_sbom_information(
all_airflow_versions = airflow_versions.copy()
else:
airflow_versions = [airflow_version]
- all_airflow_versions = get_active_airflow_versions(confirm=False,
remote_name=remote_name)
+ if airflow_site_archive_path and add_stable:
+ all_airflow_versions, _ =
get_active_airflow_versions(confirm=False, remote_name=remote_name)
+ else:
+ all_airflow_versions = airflow_versions.copy()
if python_versions:
python_versions_list = python_versions.split(",")
else:
@@ -308,6 +320,7 @@ def update_sbom_information(
include_provider_dependencies,
include_python,
jobs_to_run,
+
airflow_constraints_reference=airflow_constraints_reference,
python_versions=use_python_versions,
)
else:
@@ -325,6 +338,7 @@ def update_sbom_information(
include_provider_dependencies,
include_python,
jobs_to_run,
+ airflow_constraints_reference=airflow_constraints_reference,
python_versions=use_python_versions,
)
if add_stable and airflow_site_archive_path and
all_airflow_versions[-1] in airflow_versions:
@@ -491,6 +505,7 @@ def core_jobs(
include_provider_dependencies: bool,
include_python: bool,
jobs_to_run: list[SbomApplicationJob],
+ airflow_constraints_reference: str | None,
python_versions: list[str],
):
for airflow_v in airflow_versions:
@@ -550,6 +565,7 @@ def core_jobs(
target_path=target_sbom_path,
include_python=include_python,
include_npm=include_npm,
+ constraints_reference=airflow_constraints_reference,
)
)
diff --git a/dev/breeze/src/airflow_breeze/commands/sbom_commands_config.py
b/dev/breeze/src/airflow_breeze/commands/sbom_commands_config.py
index 1a0ceda2620..0ff0c9c3889 100644
--- a/dev/breeze/src/airflow_breeze/commands/sbom_commands_config.py
+++ b/dev/breeze/src/airflow_breeze/commands/sbom_commands_config.py
@@ -37,6 +37,7 @@ SBOM_PARAMETERS: dict[str, list[dict[str, str | list[str]]]]
= {
"options": [
"--remote-name",
"--airflow-version",
+ "--airflow-constraints-reference",
"--python-versions",
"--include-provider-dependencies",
"--include-python",
diff --git a/dev/breeze/src/airflow_breeze/utils/cdxgen.py
b/dev/breeze/src/airflow_breeze/utils/cdxgen.py
index 43507c2ed85..de28f626633 100644
--- a/dev/breeze/src/airflow_breeze/utils/cdxgen.py
+++ b/dev/breeze/src/airflow_breeze/utils/cdxgen.py
@@ -348,6 +348,7 @@ class SbomCoreJob(SbomApplicationJob):
include_provider_dependencies: bool
include_python: bool
include_npm: bool
+ constraints_reference: str | None = None
def get_job_name(self) -> str:
name = f"{self.airflow_version}"
@@ -393,8 +394,9 @@ class SbomCoreJob(SbomApplicationJob):
else:
source_dir_with_file.unlink(missing_ok=True)
if self.include_python:
+ constraints_reference = self.constraints_reference or
f"constraints-{self.airflow_version}"
if not download_constraints_file(
- constraints_reference=f"constraints-{self.airflow_version}",
+ constraints_reference=constraints_reference,
python_version=self.python_version,
airflow_constraints_mode="constraints"
if self.include_provider_dependencies
diff --git a/dev/breeze/tests/test_sbom_commands.py
b/dev/breeze/tests/test_sbom_commands.py
new file mode 100644
index 00000000000..2370bdccc32
--- /dev/null
+++ b/dev/breeze/tests/test_sbom_commands.py
@@ -0,0 +1,133 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+from __future__ import annotations
+
+from pathlib import Path
+from unittest.mock import patch
+
+import pytest
+
+from airflow_breeze.commands.sbom_commands import update_sbom_information
+from airflow_breeze.utils.cdxgen import SbomCoreJob
+from airflow_breeze.utils.path_utils import FILES_SBOM_PATH
+
+
[email protected](
+ ("constraints_reference", "expected_constraints_reference"),
+ [
+ ("constraints-main", "constraints-main"),
+ (None, "constraints-3.2.0"),
+ ],
+)
+def test_sbom_core_job_resolves_constraints_reference(
+ tmp_path, constraints_reference, expected_constraints_reference
+):
+ job = SbomCoreJob(
+ python_version="3.10",
+ target_path=tmp_path / "output.json",
+ airflow_version="3.2.0",
+ application_root_path=FILES_SBOM_PATH,
+ include_provider_dependencies=False,
+ include_python=True,
+ include_npm=False,
+ constraints_reference=constraints_reference,
+ )
+ with patch(
+ "airflow_breeze.utils.cdxgen.download_constraints_file",
autospec=True, return_value=True
+ ) as mock_dl:
+ job.download_dependency_files(output=None, github_token=None)
+
+ mock_dl.assert_called_once()
+ assert mock_dl.call_args.kwargs["constraints_reference"] ==
expected_constraints_reference
+
+
+def
test_update_sbom_information_with_airflow_root_path_skips_released_versions_lookup(tmp_path):
+ airflow_root_path = Path(tmp_path)
+ airflow_docs_dir = airflow_root_path / "generated" / "_build" / "docs" /
"apache-airflow" / "stable"
+ airflow_docs_dir.mkdir(parents=True)
+
+ with (
+ patch("airflow_breeze.utils.cdxgen.start_cdxgen_servers",
autospec=True),
+ patch(
+ "airflow_breeze.utils.github.get_active_airflow_versions",
+ autospec=True,
+ return_value=(["3.2.0"], {}),
+ ) as mock_get_active_airflow_versions,
+ patch("airflow_breeze.commands.sbom_commands.core_jobs",
autospec=True) as mock_core_jobs,
+ ):
+ update_sbom_information.callback(
+ airflow_root_path=airflow_root_path,
+ airflow_site_archive_path=None,
+ airflow_version="3.2.0",
+ airflow_constraints_reference="constraints-main",
+ all_combinations=False,
+ debug_resources=False,
+ force=False,
+ github_token=None,
+ include_npm=True,
+ include_provider_dependencies=False,
+ include_python=True,
+ include_success_outputs=False,
+ package_filter="apache-airflow",
+ parallelism=1,
+ python_versions="3.10",
+ remote_name="origin",
+ run_in_parallel=False,
+ skip_cleanup=False,
+ add_stable=True,
+ )
+
+ mock_get_active_airflow_versions.assert_not_called()
+ mock_core_jobs.assert_called_once()
+ assert mock_core_jobs.call_args.kwargs["airflow_constraints_reference"] ==
"constraints-main"
+
+
+def
test_update_sbom_information_with_site_archive_path_keeps_stable_lookup(tmp_path):
+ airflow_site_archive_path = Path(tmp_path)
+
+ with (
+ patch("airflow_breeze.utils.cdxgen.start_cdxgen_servers",
autospec=True),
+ patch(
+ "airflow_breeze.utils.github.get_active_airflow_versions",
+ autospec=True,
+ return_value=(["3.1.0"], {}),
+ ) as mock_get_active_airflow_versions,
+ patch("airflow_breeze.commands.sbom_commands.core_jobs",
autospec=True),
+ ):
+ update_sbom_information.callback(
+ airflow_root_path=None,
+ airflow_site_archive_path=airflow_site_archive_path,
+ airflow_version="3.2.0",
+ airflow_constraints_reference=None,
+ all_combinations=False,
+ debug_resources=False,
+ force=False,
+ github_token=None,
+ include_npm=True,
+ include_provider_dependencies=False,
+ include_python=True,
+ include_success_outputs=False,
+ package_filter="apache-airflow",
+ parallelism=1,
+ python_versions="3.10",
+ remote_name="origin",
+ run_in_parallel=False,
+ skip_cleanup=False,
+ add_stable=True,
+ )
+
+ mock_get_active_airflow_versions.assert_called_once_with(confirm=False,
remote_name="origin")