Skip to content

Commit dddae8b

Browse files
authored
Merge pull request #311 from finos/fix/release-post-steps-ui-conflict
fix(release): repair the release pipeline and sign released artifacts
2 parents 001b964 + a587e8a commit dddae8b

12 files changed

Lines changed: 452 additions & 32 deletions

File tree

.github/workflows/dev-containers.yml

Lines changed: 49 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,10 @@ jobs:
103103
contents: read
104104
packages: write
105105
security-events: write
106+
# Required for keyless cosign signing (ambient OIDC token) and
107+
# actions/attest-build-provenance on pushed images.
108+
id-token: write
109+
attestations: write
106110

107111
steps:
108112
- name: Checkout code
@@ -126,14 +130,23 @@ jobs:
126130
cache-key: ${{ needs.setup-cache.outputs.cache-key }}
127131
fail-on-cache-miss: false
128132

133+
- name: Setup Bun (for UI static bundle)
134+
# Bun is required to compile the Reflex SPA bundle during `make build`.
135+
# Without it the wheel ships no _static/ directory and the container starts
136+
# in embedded mode with a missing SPA — a non-bootable signed image (H2).
137+
# This mirrors the prod-release.yml build-wheel pattern for prod/dev parity.
138+
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2
139+
with:
140+
bun-version: "1.2.15" # pinned; update intentionally to avoid surprise breakage
141+
129142
- name: Build package wheel
130-
# This job builds a wheel to scan in a container image and has no bun/uv
131-
# to compile the SPA (it never shipped one). Skip the UI build.
132-
env:
133-
ORB_SKIP_UI_BUILD: "1"
143+
# SPA bundle is compiled by the setuptools build hook during `make build`
144+
# now that Bun is on PATH. ORB_SKIP_UI_BUILD is NOT set so the wheel
145+
# ships the _static/ directory — identical to the prod-release.yml wheel.
134146
run: make build
135147

136148
- name: Build and scan container image
149+
id: build
137150
shell: bash
138151
env:
139152
REGISTRY: ${{ needs.config.outputs.container-registry }}
@@ -169,12 +182,23 @@ jobs:
169182
--build-arg "VCS_REF=$(git rev-parse --short HEAD)" \
170183
--build-arg "PYTHON_VERSION=$PYTHON_VERSION" \
171184
--build-arg "PACKAGE_NAME_SHORT=$PACKAGE_NAME_SHORT" \
185+
--provenance=true \
186+
--sbom=true \
187+
--metadata-file metadata.json \
172188
--cache-from type=gha \
173189
--cache-to type=gha,mode=max \
174190
--push \
175191
-t "$REGISTRY/$IMAGE_NAME:$VERSION-python$PYTHON_VERSION" \
176192
.
177193
194+
# Extract the immutable digest for the signing steps below.
195+
DIGEST=$(jq -r '."containerimage.digest"' metadata.json)
196+
{
197+
echo "digest=${DIGEST}"
198+
echo "image=${REGISTRY}/${IMAGE_NAME}"
199+
echo "pushed=true"
200+
} >> "$GITHUB_OUTPUT"
201+
178202
# Pull back a single-arch image for local Trivy scanning.
179203
# Multi-arch manifests cannot be loaded/scanned; we use the first
180204
# entry of build-platforms (SCAN_PLATFORM) rather than hardcoding amd64.
@@ -195,8 +219,29 @@ jobs:
195219
--load \
196220
-t "$REGISTRY/$IMAGE_NAME:$VERSION-python$PYTHON_VERSION" \
197221
.
222+
echo "pushed=false" >> "$GITHUB_OUTPUT"
198223
fi
199224
225+
- name: Install cosign
226+
# Only needed when an image was pushed; skip on PR / local-only builds.
227+
if: steps.build.outputs.pushed == 'true'
228+
uses: sigstore/cosign-installer@6f9f17788090df1f26f669e9d70d6ae9567deba6 # v4.1.2
229+
230+
- name: Sign container image (keyless / OIDC)
231+
if: steps.build.outputs.pushed == 'true'
232+
env:
233+
DIGEST: ${{ steps.build.outputs.digest }}
234+
IMAGE: ${{ steps.build.outputs.image }}
235+
run: cosign sign --yes "$IMAGE@$DIGEST"
236+
237+
- name: Attach SLSA provenance attestation
238+
if: steps.build.outputs.pushed == 'true'
239+
uses: actions/attest-build-provenance@0f67c3f4856b2e3261c31976d6725780e5e4c373 # v4.1.1
240+
with:
241+
subject-name: ${{ steps.build.outputs.image }}
242+
subject-digest: ${{ steps.build.outputs.digest }}
243+
push-to-registry: true
244+
200245
- name: Run Trivy security scan
201246
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0
202247
with:

.github/workflows/dev-pypi.yml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,12 +80,12 @@ jobs:
8080
echo "VERSION=${{ needs.config.outputs.package-version }}"
8181
echo "TARGET=testpypi"
8282
} >> "$GITHUB_ENV"
83-
echo "Publishing to: TestPyPI with version: $VERSION"
83+
echo "Publishing to: TestPyPI with version: ${{ needs.config.outputs.package-version }}"
8484
8585
- name: Setup Python and UV
8686
uses: ./.github/actions/setup-uv-cached
8787
with:
88-
cache-key: deps-${{ needs.config.outputs.default-python-version }}-${{ hashFiles('.project.yml', 'pyproject.toml', 'requirements*.txt') }}
88+
cache-key: deps-${{ needs.config.outputs.default-python-version }}-${{ hashFiles('.project.yml', 'pyproject.toml', 'uv.lock') }}
8989
fail-on-cache-miss: false
9090

9191
- name: Setup Bun (for UI static bundle)
@@ -143,7 +143,7 @@ jobs:
143143
- name: Setup Python and UV
144144
uses: ./.github/actions/setup-uv-cached
145145
with:
146-
cache-key: deps-${{ needs.config.outputs.default-python-version }}-${{ hashFiles('.project.yml', 'pyproject.toml', 'requirements*.txt') }}
146+
cache-key: deps-${{ needs.config.outputs.default-python-version }}-${{ hashFiles('.project.yml', 'pyproject.toml', 'uv.lock') }}
147147
fail-on-cache-miss: false
148148

149149
- name: Generate SBOM files
@@ -156,6 +156,7 @@ jobs:
156156
name: reports-sbom-${{ needs.config.outputs.package-version }}
157157
path: |
158158
python-sbom-cyclonedx.json
159+
python-sbom.json
159160
python-sbom-spdx.json
160161
retention-days: 180
161162

0 commit comments

Comments
 (0)