@@ -122,6 +122,73 @@ jobs:
122122 print(f'Version {version} is valid for release publishing')
123123 "
124124
125+ - name : Generate requirements file for SBOM
126+ run : |
127+ uv export --locked --format=requirements-txt --output-file=requirements.txt
128+ echo "Generated requirements.txt for SBOM creation from lockfile"
129+
130+ - name : Install SBOM generation tools
131+ run : |
132+ uv tool install cyclonedx-bom
133+ uv tool install pip-audit
134+
135+ - name : Generate SBOM with CycloneDX
136+ run : |
137+ uv tool run cyclonedx-py requirements --format json --output-file sbom-cyclonedx.json requirements.txt
138+ uv tool run cyclonedx-py requirements --format xml --output-file sbom-cyclonedx.xml requirements.txt
139+ echo "Generated CycloneDX SBOM in JSON and XML formats"
140+
141+ - name : Generate vulnerability report with pip-audit
142+ run : |
143+ uv tool run pip-audit --format json --output vulnerability-report.json --requirement requirements.txt || true
144+ echo "Generated vulnerability report (non-blocking)"
145+
146+ - name : Create SBOM summary
147+ run : |
148+ echo "## Software Bill of Materials (SBOM)" > sbom-summary.md
149+ echo "" >> sbom-summary.md
150+ echo "This release includes the following supply chain security artifacts:" >> sbom-summary.md
151+ echo "" >> sbom-summary.md
152+ echo "- **Provenance**: Cryptographic proof of build integrity using GitHub's OIDC tokens" >> sbom-summary.md
153+ echo "- **SBOM**: Complete dependency inventory in CycloneDX format" >> sbom-summary.md
154+ echo "- **Vulnerability Report**: Security scan results for all dependencies" >> sbom-summary.md
155+ echo "" >> sbom-summary.md
156+ echo "### Dependencies Count:" >> sbom-summary.md
157+ echo "- Direct dependencies: $(grep -c '^[^#]' requirements.txt || echo '0')" >> sbom-summary.md
158+ echo "- Total dependencies (including transitive): $(wc -l < requirements.txt)" >> sbom-summary.md
159+ echo "" >> sbom-summary.md
160+ echo "### Verification:" >> sbom-summary.md
161+ echo "You can verify this package's provenance on PyPI using:" >> sbom-summary.md
162+ echo '```bash' >> sbom-summary.md
163+ echo 'pip install sigstore' >> sbom-summary.md
164+ echo 'python -m sigstore verify --bundle <bundle-file> exospherehost==${{ startsWith(github.ref_name, 'v') && substring(github.ref_name, 1) || github.ref_name }}' >> sbom-summary.md
165+ echo '```' >> sbom-summary.md
166+
125167 - run : uv build
126168
127- - run : uv publish
169+ - name : Publish to PyPI with provenance
170+ run : uv publish --provenance
171+
172+ - name : Upload SBOM artifacts
173+ uses : actions/upload-artifact@v4
174+ with :
175+ name : sbom-artifacts-${{ github.ref_name }}
176+ path : |
177+ python-sdk/sbom-cyclonedx.json
178+ python-sdk/sbom-cyclonedx.xml
179+ python-sdk/requirements.txt
180+ python-sdk/vulnerability-report.json
181+ python-sdk/sbom-summary.md
182+ retention-days : 90
183+
184+ - name : Add SBOM to release assets
185+ uses : softprops/action-gh-release@v2
186+ if : startsWith(github.ref, 'refs/tags/')
187+ with :
188+ files : |
189+ python-sdk/sbom-cyclonedx.json
190+ python-sdk/sbom-cyclonedx.xml
191+ python-sdk/sbom-summary.md
192+ python-sdk/vulnerability-report.json
193+ body_path : python-sdk/sbom-summary.md
194+ append_body : true
0 commit comments