From a4aa71ad87d7f7ec1583c2d8b47ca1c822b1c964 Mon Sep 17 00:00:00 2001 From: Mohd Kaif <98801504+KaifAhmad1@users.noreply.github.com> Date: Mon, 31 Aug 2026 14:04:28 +0530 Subject: [PATCH] fix(ci): unblock py3.9 install matrix and raise Scorecard pinning/signing (#1329) * fix(ci): unblock py3.9 install matrix and raise Scorecard pinning/signing pip install semantica failed on Python 3.9 across all three OSes because spacy had no upper bound, so pip resolved spacy 3.8.16 whose thinc>=8.3.12 requirement has no cp39 wheels and no working sdist build path. Cap spacy/thinc for python_version < '3.10' to the last wheel-compatible pair. Also addresses the two OpenSSF Scorecard findings that were actually fixable in code: - Pinned-Dependencies: Dockerfile base images (node:26-alpine, python:3.13-slim) were unpinned by digest; pin both, and pin five previously-unversioned pip install calls in CI (build, safety, bandit, semgrep, jq, pip-audit). - Signed-Releases: attest-build-provenance only publishes to the GH attestations API, which Scorecard doesn't inspect. Sign dist/* with Sigstore and attach the .sigstore.json bundles as release assets. * fix(ci): correct Sigstore artifact inputs --------- Co-authored-by: Sameer6305 --- .github/workflows/ci.yml | 2 +- .github/workflows/release.yml | 20 +++++++++++++++++--- .github/workflows/security-scan.yml | 2 +- .github/workflows/security.yml | 2 +- Dockerfile | 4 ++-- pyproject.toml | 9 ++++++++- 6 files changed, 30 insertions(+), 9 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cafe3074..4ccfd3d2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -72,7 +72,7 @@ jobs: diff \ <(grep -E '^[a-zA-Z0-9._-]+==' requirements-ci.txt | sed 's/ \\$//') \ <(grep -E '^[a-zA-Z0-9._-]+==' /tmp/requirements-ci-check.txt) - - run: pip install build + - run: pip install build==1.6.0 # wheel is build-time only (not in requirements-ci.txt) — install the # same pinned version [build-system] declares so --no-isolation works. - run: pip install wheel==0.48.0 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d731d98d..c8071042 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -16,7 +16,7 @@ jobs: cancel-in-progress: false permissions: contents: write # for the GitHub Release - id-token: write # for PyPI Trusted Publishing (OIDC) and attestation signing + id-token: write # for PyPI Trusted Publishing (OIDC), attestation signing, and Sigstore attestations: write # for SLSA build provenance # If you add another job to this workflow, give it its own explicit # `permissions:` block rather than relying on the workflow-level default @@ -40,7 +40,7 @@ jobs: # build runs against the same versions CI tests against. - name: Install pinned build dependencies run: pip install -r requirements-ci.txt - - run: pip install build + - run: pip install build==1.6.0 # wheel is build-time only (not in requirements-ci.txt) — install the # same pinned version [build-system] declares so --no-isolation works. - run: pip install wheel==0.48.0 @@ -71,7 +71,21 @@ jobs: uses: actions/attest-build-provenance@4d101475d8b20a2381f78447822ac1eab6504dd8 # v4 with: subject-path: 'dist/*' + # attest-build-provenance publishes to the GH attestations API only, which + # OpenSSF Scorecard's Signed-Releases check does not inspect - it looks for + # signature files attached as release assets. Sign here too so + # `dist/*.sigstore.json` bundles ship alongside the wheel/sdist on the + # GitHub Release itself. + - name: Sign artifacts with Sigstore + uses: sigstore/gh-action-sigstore-python@790bc6befb9d733738f18d8f895854b453640ec9 # v3.5.0 + with: + inputs: | + dist/*.whl + dist/*.tar.gz - uses: softprops/action-gh-release@efb35369e0ad2afab669f228072c1b0d510eae64 # v3.0.3 with: - files: dist/* + files: | + dist/*.whl + dist/*.tar.gz + dist/*.sigstore.json - uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # release/v1 diff --git a/.github/workflows/security-scan.yml b/.github/workflows/security-scan.yml index 5b4461af..a30ca234 100644 --- a/.github/workflows/security-scan.yml +++ b/.github/workflows/security-scan.yml @@ -52,7 +52,7 @@ jobs: # Tooling AFTER the pinned set: installing safety/bandit/semgrep/jq # first lets the pinned requirements overwrite their transitive deps # (e.g. rich), which breaks the safety CLI at runtime. - pip install safety bandit semgrep jq + pip install safety==3.8.1 bandit==1.9.4 semgrep==1.175.0 jq==1.12.0 - name: Run Safety Check (Package Vulnerabilities) run: | diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml index 412e7eaa..d768fedd 100644 --- a/.github/workflows/security.yml +++ b/.github/workflows/security.yml @@ -37,6 +37,6 @@ jobs: # pyproject.toml changes under review. The schedule/workflow_dispatch # runs stay non-blocking until a full pass over pre-existing findings # across the whole [all] tree has been done. - - run: pip install pip-audit + - run: pip install pip-audit==2.10.1 - run: pip-audit -r requirements-ci.txt continue-on-error: ${{ github.event_name != 'pull_request' }} diff --git a/Dockerfile b/Dockerfile index a462509e..edb3c4da 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # syntax=docker/dockerfile:1 -FROM node:26-alpine AS frontend-builder +FROM node:26-alpine@sha256:2d984a15c9b54fd0aeb608b8e0d0d83529eb34d2966db27a1fb4f1edc3d298a3 AS frontend-builder WORKDIR /app COPY explorer/package*.json ./explorer/ @@ -9,7 +9,7 @@ RUN npm ci COPY explorer/ ./ RUN mkdir -p /app/semantica && npm run build -FROM python:3.13-slim AS runtime +FROM python:3.13-slim@sha256:7ce4b6dfe35e55397b7cda544f8a13f191b7ae28dc5aad71fe664dbc9bc2623f AS runtime ENV PYTHONDONTWRITEBYTECODE=1 \ PYTHONUNBUFFERED=1 \ diff --git a/pyproject.toml b/pyproject.toml index b1850166..bbcaca5d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -49,7 +49,14 @@ dependencies = [ "scipy>=1.13.1", "scikit-learn>=1.7.2", "umap-learn>=0.5.12", - "spacy>=3.4.0", + # thinc (spacy's core dep) dropped Python 3.9 wheels at 8.3.10, and later + # spacy patch releases (3.8.8+) require thinc>=8.3.9-only-on-3.10+ ranges, + # which forces a source build that fails outright on 3.9 (see Install + # Matrix run history). Capping both keeps 3.9 on the last wheel-compatible + # pair; 3.10+ is left unconstrained to always get the latest spacy/thinc. + "spacy>=3.4.0,<3.8.8; python_version < '3.10'", + "spacy>=3.4.0; python_version >= '3.10'", + "thinc<8.3.5; python_version < '3.10'", "transformers>=4.20.0", "torch>=1.13.1", "sentence-transformers>=2.2.0",