From ac92fb03de4ca19be4d07850721e7d4bad1f604f Mon Sep 17 00:00:00 2001 From: Matthew Watkins Date: Tue, 30 Jun 2026 15:39:26 +0100 Subject: [PATCH] CI: Adopt reusable workflows, fix zizmor findings Replace the large inline build/test and release pipelines with thin callers of the reusable multi-arch Python workflows from lfreleng-actions/python-workflows, pinned to the v0.1.1 release commit. The reusable workflows reproduce the canonical pipeline (metadata, build, tests, audit, SBOM and Grype scan, fanned across the x64 + arm64 matrix); native NSS/NSPR prerequisites are supplied through the committed setup script (.github/scripts/setup-nss.sh) consumed via the reusable workflow's setup_script input. PyPI publishing stays in this repository so the existing token credentials remain scoped here. This collapses hundreds of lines of duplicated pipeline YAML and clears the zizmor security findings reported against the repository: * High excessive-permissions: the workflow-level "actions: write" in build-test.yaml is gone with the inline cache-clear logic. * Medium artipacked (credential persistence): the inline checkouts that carried persisted credentials have been removed. The remaining workflows are brought into line with the clean template: * compatibility.yaml: add "persist-credentials: false" to both checkouts. The fedora:44 CI container is intentionally tracked by tag (not a frozen digest) so it keeps receiving Fedora security rebuilds and stays aligned with the downstream Sigul consumer, so the High unpinned-images finding is suppressed inline with a documented rationale rather than pinned to a digest. * advanced-tests.yaml: add "persist-credentials: false" to all six checkout steps. The default-persona zizmor scan (the persona the GitHub code-scanning upload uses) now reports no findings. Co-Authored-By: Claude Signed-off-by: Matthew Watkins --- .github/workflows/advanced-tests.yaml | 12 + .github/workflows/build-test-release.yaml | 985 ++-------------------- .github/workflows/build-test.yaml | 812 +----------------- .github/workflows/compatibility.yaml | 14 +- 4 files changed, 102 insertions(+), 1721 deletions(-) diff --git a/.github/workflows/advanced-tests.yaml b/.github/workflows/advanced-tests.yaml index 9dac397..6ef44e6 100644 --- a/.github/workflows/advanced-tests.yaml +++ b/.github/workflows/advanced-tests.yaml @@ -76,6 +76,8 @@ jobs: # yamllint disable-line rule:line-length - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false - name: Set up Python ${{ matrix.python-version }} # yamllint disable-line rule:line-length @@ -148,6 +150,8 @@ jobs: # yamllint disable-line rule:line-length - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false - name: Set up Python # yamllint disable-line rule:line-length @@ -209,6 +213,8 @@ jobs: # yamllint disable-line rule:line-length - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false - name: Set up Python # yamllint disable-line rule:line-length @@ -266,6 +272,8 @@ jobs: # yamllint disable-line rule:line-length - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false - name: Set up Python # yamllint disable-line rule:line-length @@ -321,6 +329,8 @@ jobs: # yamllint disable-line rule:line-length - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false - name: Set up Python # yamllint disable-line rule:line-length @@ -399,6 +409,8 @@ jobs: # yamllint disable-line rule:line-length - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false - name: Set up Python # yamllint disable-line rule:line-length diff --git a/.github/workflows/build-test-release.yaml b/.github/workflows/build-test-release.yaml index 8be53c5..744ef17 100644 --- a/.github/workflows/build-test-release.yaml +++ b/.github/workflows/build-test-release.yaml @@ -1,8 +1,19 @@ --- # SPDX-License-Identifier: Apache-2.0 -# SPDX-FileCopyrightText: 2025 The Linux Foundation - -# Runs on a new pull request, performs build and runs tests +# SPDX-FileCopyrightText: 2026 The Linux Foundation + +# Runs on a tag push, performs build/test/release. +# +# Thin caller for the reusable multi-arch Python build/test/release +# pipeline in lfreleng-actions/python-workflows. The reusable `release` +# job validates the tag, builds (x64 + arm64), tests, audits, scans, +# attaches artefacts and promotes the draft release. Native NSS/NSPR +# prerequisites are supplied through the committed setup script. +# +# PyPI publishing is performed HERE, not in the reusable workflow: PyPI +# trusted publishing / token credentials are scoped to this repository, +# so the `test-pypi` and `pypi` jobs below download the run-scoped +# 'dist-*' build artefacts the reusable workflow produced and upload them. name: 'Python Build/Test/Release' # yamllint disable-line rule:truthy @@ -12,760 +23,45 @@ on: tags: - '**' -permissions: {} - -jobs: - repository-metadata: - name: "Repository Metadata" - runs-on: ubuntu-latest - permissions: - contents: read - pull-requests: read - timeout-minutes: 5 - steps: - # Load the egress allow-list out-of-band from - # lfreleng-actions/.github and publish it as - # $CONNECTION_ALLOW_LIST for the harden-runner step below - # to consume in 'block' mode. Loading out-of-band means - # the workflow no longer depends on any org-level GitHub - # variable being exposed at runtime (org variables are - # unreachable from workflows triggered by PRs raised from - # forks, which previously forced a fallback to audit mode). - # yamllint disable-line rule:line-length - - uses: lfreleng-actions/harden-runner-block-action@42663a22f7abe31521cbc6120901353a4b2849bc # v0.2.0 - with: - # yamllint disable-line rule:line-length - config: 'lfreleng-actions//.github/harden-runner/lfreleng-actions/allow_list.txt@18d9c4446bea555d0783e850f6d295f844fe8f67' # v0.1.1 - - # Harden the runner with the just-loaded allow-list. - - name: 'Harden runner (block)' - # yamllint disable-line rule:line-length - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 - with: - egress-policy: 'block' - allowed-endpoints: > - ${{ env.CONNECTION_ALLOW_LIST }} - - # yamllint disable-line rule:line-length - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - with: - fetch-depth: 0 - - - name: "Gather repository metadata" - id: repo-metadata - # yamllint disable-line rule:line-length - uses: lfreleng-actions/repository-metadata-action@ceabcd987d13d7bfefd2372e01eebb0ddac45956 # v0.2.0 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - github_summary: 'false' - gerrit_summary: 'false' - artifact_upload: 'true' - artifact_formats: 'json' - - tag-validate: - name: 'Validate Tag Push' - runs-on: 'ubuntu-latest' - permissions: - contents: write # Needed to draft a release - timeout-minutes: 5 - outputs: - tag: "${{ steps.tag-validate.outputs.tag_name }}" - steps: - # Load the egress allow-list out-of-band from - # lfreleng-actions/.github and publish it as - # $CONNECTION_ALLOW_LIST for the harden-runner step below - # to consume in 'block' mode. Loading out-of-band means - # the workflow no longer depends on any org-level GitHub - # variable being exposed at runtime (org variables are - # unreachable from workflows triggered by PRs raised from - # forks, which previously forced a fallback to audit mode). - # yamllint disable-line rule:line-length - - uses: lfreleng-actions/harden-runner-block-action@42663a22f7abe31521cbc6120901353a4b2849bc # v0.2.0 - with: - # yamllint disable-line rule:line-length - config: 'lfreleng-actions//.github/harden-runner/lfreleng-actions/allow_list.txt@18d9c4446bea555d0783e850f6d295f844fe8f67' # v0.1.1 - - # Harden the runner with the just-loaded allow-list. - - name: 'Harden runner (block)' - # yamllint disable-line rule:line-length - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 - with: - egress-policy: 'block' - allowed-endpoints: > - ${{ env.CONNECTION_ALLOW_LIST }} - - - name: 'Checkout repository' - # yamllint disable-line rule:line-length - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - with: - fetch-depth: 0 - fetch-tags: true - - - name: 'Verify pushed tag' - id: 'tag-validate' - # yamllint disable-line rule:line-length - uses: lfreleng-actions/tag-validate-action@461d187a53b5de27b068c2cea5af972c085a4a6a # v1.0.2 - with: - token: "${{ secrets.GITHUB_TOKEN }}" - require_type: 'semver' - reject_development: 'true' - require_github: 'true' - # yamllint disable-line rule:line-length - require_signed: 'ssh,gpg-unverifiable' # Cannot verify GPG without key - - - name: 'Ensure draft release exists' - id: 'ensure-release' - shell: bash - env: - GH_TOKEN: "${{ secrets.GITHUB_TOKEN }}" - TAG_NAME: "${{ steps.tag-validate.outputs.tag_name }}" - run: | - # Ensure draft release exists - TAG="${TAG_NAME}" - # Check if release exists and get its draft status - if RELEASE_INFO=$(gh release view "$TAG" \ - --json isDraft 2>/dev/null); then - IS_DRAFT=$(echo "$RELEASE_INFO" | jq -r '.isDraft') - if [ "$IS_DRAFT" = "true" ]; then - echo "Draft release for tag $TAG already exists" - else - echo "Published release for tag $TAG already exists" - fi - else - echo "Creating draft release for tag $TAG" - gh release create "$TAG" \ - --draft \ - --title "Release $TAG" \ - --notes "Automated release for $TAG" - fi - - python-metadata: - name: 'Extract Project Metadata' - needs: 'tag-validate' - runs-on: ubuntu-latest - outputs: - matrix_json: "${{ steps.metadata.outputs.python_matrix_json }}" - project_name: "${{ steps.metadata.outputs.project_name }}" - permissions: - contents: read - timeout-minutes: 5 - steps: - # Load the egress allow-list out-of-band from - # lfreleng-actions/.github and publish it as - # $CONNECTION_ALLOW_LIST for the harden-runner step below - # to consume in 'block' mode. Loading out-of-band means - # the workflow no longer depends on any org-level GitHub - # variable being exposed at runtime (org variables are - # unreachable from workflows triggered by PRs raised from - # forks, which previously forced a fallback to audit mode). - # yamllint disable-line rule:line-length - - uses: lfreleng-actions/harden-runner-block-action@42663a22f7abe31521cbc6120901353a4b2849bc # v0.2.0 - with: - # yamllint disable-line rule:line-length - config: 'lfreleng-actions//.github/harden-runner/lfreleng-actions/allow_list.txt@18d9c4446bea555d0783e850f6d295f844fe8f67' # v0.1.1 - - # Harden the runner with the just-loaded allow-list. - - name: 'Harden runner (block)' - # yamllint disable-line rule:line-length - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 - with: - egress-policy: 'block' - allowed-endpoints: > - ${{ env.CONNECTION_ALLOW_LIST }} - - # yamllint disable-line rule:line-length - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - - - name: 'Extract Python project metadata' - id: metadata - # yamllint disable-line rule:line-length - uses: lfreleng-actions/build-metadata-action@bc866421c816f63e6ab09f3d42bf95566be50940 # v0.4.0 - with: - path_prefix: '.' - output_format: summary - include_environment: true - use_version_extract: true - verbose: true - - python-build-sdist: - name: 'Build Source Distribution' - runs-on: ubuntu-latest - needs: python-metadata - permissions: - contents: read - id-token: write # Needed for attestations - attestations: write # Needed for attestations - timeout-minutes: 10 - steps: - # Load the egress allow-list out-of-band from - # lfreleng-actions/.github and publish it as - # $CONNECTION_ALLOW_LIST for the harden-runner step below - # to consume in 'block' mode. Loading out-of-band means - # the workflow no longer depends on any org-level GitHub - # variable being exposed at runtime (org variables are - # unreachable from workflows triggered by PRs raised from - # forks, which previously forced a fallback to audit mode). - # yamllint disable-line rule:line-length - - uses: lfreleng-actions/harden-runner-block-action@42663a22f7abe31521cbc6120901353a4b2849bc # v0.2.0 - with: - # yamllint disable-line rule:line-length - config: 'lfreleng-actions//.github/harden-runner/lfreleng-actions/allow_list.txt@18d9c4446bea555d0783e850f6d295f844fe8f67' # v0.1.1 - - # Harden the runner with the just-loaded allow-list. - - name: 'Harden runner (block)' - # yamllint disable-line rule:line-length - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 - with: - egress-policy: 'block' - allowed-endpoints: > - ${{ env.CONNECTION_ALLOW_LIST }} - - # yamllint disable-line rule:line-length - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - - - name: Build NSS/NSPR from source - run: | - chmod +x .github/scripts/install-nss.sh - ./.github/scripts/install-nss.sh - - # Set environment variables for subsequent steps - echo "PKG_CONFIG_PATH=/usr/lib/pkgconfig:$PKG_CONFIG_PATH" \ - >> "$GITHUB_ENV" - echo "LD_LIBRARY_PATH=/usr/lib:$LD_LIBRARY_PATH" >> "$GITHUB_ENV" - - - name: "Build source distribution" - id: python-build-sdist - # yamllint disable-line rule:line-length - uses: lfreleng-actions/python-build-action@5f570d5d17a7315074a824a91c6a705b6fc5c7dd # v1.1.2 - with: - artefact_name: python-nss-ng-sdist - build_formats: sdist - attestations: true - - python-build-x64: - name: "Python Build x64 ${{ matrix.python-version }}" - runs-on: ubuntu-latest - needs: python-metadata - strategy: - fail-fast: false - matrix: "${{ fromJson(needs.python-metadata.outputs.matrix_json) }}" - permissions: - contents: read - id-token: write # Needed for attestations - attestations: write # Needed for attestations - timeout-minutes: 20 - env: - GH_TOKEN: "${{ secrets.GITHUB_TOKEN }}" - steps: - # Load the egress allow-list out-of-band from - # lfreleng-actions/.github and publish it as - # $CONNECTION_ALLOW_LIST for the harden-runner step below - # to consume in 'block' mode. Loading out-of-band means - # the workflow no longer depends on any org-level GitHub - # variable being exposed at runtime (org variables are - # unreachable from workflows triggered by PRs raised from - # forks, which previously forced a fallback to audit mode). - # yamllint disable-line rule:line-length - - uses: lfreleng-actions/harden-runner-block-action@42663a22f7abe31521cbc6120901353a4b2849bc # v0.2.0 - with: - # yamllint disable-line rule:line-length - config: 'lfreleng-actions//.github/harden-runner/lfreleng-actions/allow_list.txt@18d9c4446bea555d0783e850f6d295f844fe8f67' # v0.1.1 - - # Harden the runner with the just-loaded allow-list. - - name: 'Harden runner (block)' - # yamllint disable-line rule:line-length - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 - with: - egress-policy: 'block' - allowed-endpoints: > - ${{ env.CONNECTION_ALLOW_LIST }} - - # yamllint disable-line rule:line-length - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - - - name: "Build Python project ${{ matrix.python-version }}" - id: python-build - # yamllint disable-line rule:line-length - uses: lfreleng-actions/python-build-action@5f570d5d17a7315074a824a91c6a705b6fc5c7dd # v1.1.2 - with: - artefact_name: python-nss-ng-x64-py${{ matrix.python-version }} - python_version: ${{ matrix.python-version }} - make: true - make_args: 'deps-nss env-github-actions' - build_formats: wheel - auditwheel: true - manylinux_version: manylinux_2_38 - sigstore_sign: true - attestations: true - - python-build-arm64: - name: "Python Build ARM64 ${{ matrix.python-version }}" - runs-on: ubuntu-24.04-arm - needs: python-metadata - strategy: - fail-fast: false - matrix: "${{ fromJson(needs.python-metadata.outputs.matrix_json) }}" - permissions: - contents: read - id-token: write # Needed for attestations - attestations: write # Needed for attestations - timeout-minutes: 20 - env: - GH_TOKEN: "${{ secrets.GITHUB_TOKEN }}" - steps: - # Load the egress allow-list out-of-band from - # lfreleng-actions/.github and publish it as - # $CONNECTION_ALLOW_LIST for the harden-runner step below - # to consume in 'block' mode. Loading out-of-band means - # the workflow no longer depends on any org-level GitHub - # variable being exposed at runtime (org variables are - # unreachable from workflows triggered by PRs raised from - # forks, which previously forced a fallback to audit mode). - # yamllint disable-line rule:line-length - - uses: lfreleng-actions/harden-runner-block-action@42663a22f7abe31521cbc6120901353a4b2849bc # v0.2.0 - with: - # yamllint disable-line rule:line-length - config: 'lfreleng-actions//.github/harden-runner/lfreleng-actions/allow_list.txt@18d9c4446bea555d0783e850f6d295f844fe8f67' # v0.1.1 - - # Harden the runner with the just-loaded allow-list. - - name: 'Harden runner (block)' - # yamllint disable-line rule:line-length - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 - with: - egress-policy: 'block' - allowed-endpoints: > - ${{ env.CONNECTION_ALLOW_LIST }} - - # yamllint disable-line rule:line-length - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - - - name: "Build Python project ${{ matrix.python-version }}" - id: python-build - # yamllint disable-line rule:line-length - uses: lfreleng-actions/python-build-action@5f570d5d17a7315074a824a91c6a705b6fc5c7dd # v1.1.2 - with: - artefact_name: python-nss-ng-arm64-py${{ matrix.python-version }} - python_version: ${{ matrix.python-version }} - make: true - make_args: 'deps-nss env-github-actions' - build_formats: wheel - auditwheel: true - manylinux_version: manylinux_2_38 - sigstore_sign: true - attestations: true - - python-tests-x64: - name: "Python Tests x64 ${{ matrix.python-version }}" - runs-on: 'ubuntu-latest' - needs: ['python-metadata', 'python-build-x64'] - strategy: - fail-fast: false - matrix: "${{ fromJson(needs.python-metadata.outputs.matrix_json) }}" - permissions: - contents: read - timeout-minutes: 12 - steps: - # Load the egress allow-list out-of-band from - # lfreleng-actions/.github and publish it as - # $CONNECTION_ALLOW_LIST for the harden-runner step below - # to consume in 'block' mode. Loading out-of-band means - # the workflow no longer depends on any org-level GitHub - # variable being exposed at runtime (org variables are - # unreachable from workflows triggered by PRs raised from - # forks, which previously forced a fallback to audit mode). - # yamllint disable-line rule:line-length - - uses: lfreleng-actions/harden-runner-block-action@42663a22f7abe31521cbc6120901353a4b2849bc # v0.2.0 - with: - # yamllint disable-line rule:line-length - config: 'lfreleng-actions//.github/harden-runner/lfreleng-actions/allow_list.txt@18d9c4446bea555d0783e850f6d295f844fe8f67' # v0.1.1 - - # Harden the runner with the just-loaded allow-list. - - name: 'Harden runner (block)' - # yamllint disable-line rule:line-length - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 - with: - egress-policy: 'block' - allowed-endpoints: > - ${{ env.CONNECTION_ALLOW_LIST }} - - # yamllint disable-line rule:line-length - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - - - name: Build NSS/NSPR and install system dependencies - run: | - # Only install system-level (apt) deps here; pip deps are - # handled later by python-test-action under the correct - # actions/setup-python interpreter. - make deps-nss deps-test-system env-github-actions - sudo ldconfig - - - name: "Python tests [pytest] ${{ matrix.python-version }}" - # yamllint disable-line rule:line-length - uses: lfreleng-actions/python-test-action@aa753462f090101dcb0c4708e9499f55e276e373 # v1.1.2 - with: - python_version: ${{ matrix.python-version }} - # yamllint disable-line rule:line-length - artefact_name: python-nss-ng-x64-py${{ matrix.python-version }}-coverage - report_artefact: 'true' - env: - LD_LIBRARY_PATH: /usr/lib:/usr/lib/x86_64-linux-gnu - - python-tests-arm64: - name: "Python Tests ARM64 ${{ matrix.python-version }}" - runs-on: 'ubuntu-24.04-arm' - needs: ['python-metadata', 'python-build-arm64'] - strategy: - fail-fast: false - matrix: "${{ fromJson(needs.python-metadata.outputs.matrix_json) }}" - permissions: - contents: read - timeout-minutes: 12 - steps: - # Load the egress allow-list out-of-band from - # lfreleng-actions/.github and publish it as - # $CONNECTION_ALLOW_LIST for the harden-runner step below - # to consume in 'block' mode. Loading out-of-band means - # the workflow no longer depends on any org-level GitHub - # variable being exposed at runtime (org variables are - # unreachable from workflows triggered by PRs raised from - # forks, which previously forced a fallback to audit mode). - # yamllint disable-line rule:line-length - - uses: lfreleng-actions/harden-runner-block-action@42663a22f7abe31521cbc6120901353a4b2849bc # v0.2.0 - with: - # yamllint disable-line rule:line-length - config: 'lfreleng-actions//.github/harden-runner/lfreleng-actions/allow_list.txt@18d9c4446bea555d0783e850f6d295f844fe8f67' # v0.1.1 - - # Harden the runner with the just-loaded allow-list. - - name: 'Harden runner (block)' - # yamllint disable-line rule:line-length - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 - with: - egress-policy: 'block' - allowed-endpoints: > - ${{ env.CONNECTION_ALLOW_LIST }} - - # yamllint disable-line rule:line-length - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - - - name: Build NSS/NSPR and install system dependencies - run: | - # Only install system-level (apt) deps here; pip deps are - # handled later by python-test-action under the correct - # actions/setup-python interpreter. - make deps-nss deps-test-system env-github-actions - sudo ldconfig - - - name: "Python tests [pytest] ${{ matrix.python-version }}" - # yamllint disable-line rule:line-length - uses: lfreleng-actions/python-test-action@aa753462f090101dcb0c4708e9499f55e276e373 # v1.1.2 - with: - python_version: ${{ matrix.python-version }} - # yamllint disable-line rule:line-length - artefact_name: python-nss-ng-arm64-py${{ matrix.python-version }}-coverage - report_artefact: 'true' - env: - LD_LIBRARY_PATH: /usr/lib:/usr/lib/aarch64-linux-gnu - - python-audit-x64: - name: "Python Audit x64 ${{ matrix.python-version }}" - runs-on: 'ubuntu-latest' - needs: ['python-metadata', 'python-build-x64'] - strategy: - fail-fast: false - matrix: "${{ fromJson(needs.python-metadata.outputs.matrix_json) }}" - permissions: - contents: read - timeout-minutes: 10 - steps: - # Load the egress allow-list out-of-band from - # lfreleng-actions/.github and publish it as - # $CONNECTION_ALLOW_LIST for the harden-runner step below - # to consume in 'block' mode. Loading out-of-band means - # the workflow no longer depends on any org-level GitHub - # variable being exposed at runtime (org variables are - # unreachable from workflows triggered by PRs raised from - # forks, which previously forced a fallback to audit mode). - # yamllint disable-line rule:line-length - - uses: lfreleng-actions/harden-runner-block-action@42663a22f7abe31521cbc6120901353a4b2849bc # v0.2.0 - with: - # yamllint disable-line rule:line-length - config: 'lfreleng-actions//.github/harden-runner/lfreleng-actions/allow_list.txt@18d9c4446bea555d0783e850f6d295f844fe8f67' # v0.1.1 - - # Harden the runner with the just-loaded allow-list. - - name: 'Harden runner (block)' - # yamllint disable-line rule:line-length - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 - with: - egress-policy: 'block' - allowed-endpoints: > - ${{ env.CONNECTION_ALLOW_LIST }} - - # yamllint disable-line rule:line-length - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - - - name: Build NSS/NSPR and install system dependencies - run: | - make deps-nss deps-test-system env-github-actions - - - name: "Audit dependencies ${{ matrix.python-version }}" - # yamllint disable-line rule:line-length - uses: lfreleng-actions/python-audit-action@fcb1b2e0cdbe19edf11057e598138f3d57f2b249 # v0.3.1 - with: - python_version: "${{ matrix.python-version }}" - artefact_name: python-nss-ng-x64-py${{ matrix.python-version }} - - python-audit-arm64: - name: "Python Audit ARM64 ${{ matrix.python-version }}" - runs-on: 'ubuntu-24.04-arm' - needs: ['python-metadata', 'python-build-arm64'] - strategy: - fail-fast: false - matrix: "${{ fromJson(needs.python-metadata.outputs.matrix_json) }}" - permissions: - contents: read - timeout-minutes: 10 - steps: - # Load the egress allow-list out-of-band from - # lfreleng-actions/.github and publish it as - # $CONNECTION_ALLOW_LIST for the harden-runner step below - # to consume in 'block' mode. Loading out-of-band means - # the workflow no longer depends on any org-level GitHub - # variable being exposed at runtime (org variables are - # unreachable from workflows triggered by PRs raised from - # forks, which previously forced a fallback to audit mode). - # yamllint disable-line rule:line-length - - uses: lfreleng-actions/harden-runner-block-action@42663a22f7abe31521cbc6120901353a4b2849bc # v0.2.0 - with: - # yamllint disable-line rule:line-length - config: 'lfreleng-actions//.github/harden-runner/lfreleng-actions/allow_list.txt@18d9c4446bea555d0783e850f6d295f844fe8f67' # v0.1.1 - - # Harden the runner with the just-loaded allow-list. - - name: 'Harden runner (block)' - # yamllint disable-line rule:line-length - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 - with: - egress-policy: 'block' - allowed-endpoints: > - ${{ env.CONNECTION_ALLOW_LIST }} - - # yamllint disable-line rule:line-length - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - - - name: Build NSS/NSPR and install system dependencies - run: | - make deps-nss deps-test-system env-github-actions - - - name: "Audit dependencies ${{ matrix.python-version }}" - # yamllint disable-line rule:line-length - uses: lfreleng-actions/python-audit-action@fcb1b2e0cdbe19edf11057e598138f3d57f2b249 # v0.3.1 - with: - python_version: "${{ matrix.python-version }}" - artefact_name: python-nss-ng-arm64-py${{ matrix.python-version }} - - sbom-x64: - name: "Generate SBOM x64" - runs-on: ubuntu-latest - needs: ['python-metadata', 'python-build-x64'] - timeout-minutes: 10 - permissions: - contents: read - steps: - # Load the egress allow-list out-of-band from - # lfreleng-actions/.github and publish it as - # $CONNECTION_ALLOW_LIST for the harden-runner step below - # to consume in 'block' mode. Loading out-of-band means - # the workflow no longer depends on any org-level GitHub - # variable being exposed at runtime (org variables are - # unreachable from workflows triggered by PRs raised from - # forks, which previously forced a fallback to audit mode). - # yamllint disable-line rule:line-length - - uses: lfreleng-actions/harden-runner-block-action@42663a22f7abe31521cbc6120901353a4b2849bc # v0.2.0 - with: - # yamllint disable-line rule:line-length - config: 'lfreleng-actions//.github/harden-runner/lfreleng-actions/allow_list.txt@18d9c4446bea555d0783e850f6d295f844fe8f67' # v0.1.1 - - # Harden the runner with the just-loaded allow-list. - - name: 'Harden runner (block)' - # yamllint disable-line rule:line-length - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 - with: - egress-policy: 'block' - allowed-endpoints: > - ${{ env.CONNECTION_ALLOW_LIST }} - - # yamllint disable-line rule:line-length - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 +concurrency: + group: "${{ github.workflow }}-${{ github.ref }}" + cancel-in-progress: true - - name: Build NSS/NSPR from source - run: | - make deps-nss env-github-actions - - - name: "Generate SBOM" - id: sbom - # yamllint disable-line rule:line-length - uses: lfreleng-actions/python-sbom-action@ae4aca2ef28d7da4ec95049cc78be43e632d322a # v0.1.0 - with: - include_dev: "false" - sbom_format: "both" - - - name: "Upload SBOM artifacts" - # yamllint disable-line rule:line-length - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 - with: - name: sbom-files-x64 - path: | - sbom-cyclonedx.json - sbom-cyclonedx.xml - retention-days: 45 - - - name: "Security scan with Grype (SARIF)" - # yamllint disable-line rule:line-length - uses: anchore/scan-action@e1165082ffb1fe366ebaf02d8526e7c4989ea9d2 # v7.4.0 - id: grype-sarif - with: - sbom: "${{ steps.sbom.outputs.sbom_json_path }}" - output-format: "sarif" - output-file: "grype-results.sarif" - fail-build: "true" - - - name: "Security scan with Grype (Text/Table)" - # yamllint disable-line rule:line-length - uses: anchore/scan-action@e1165082ffb1fe366ebaf02d8526e7c4989ea9d2 # v7.4.0 - id: grype-table - if: always() - with: - sbom: "${{ steps.sbom.outputs.sbom_json_path }}" - output-format: "table" - output-file: "grype-results.txt" - fail-build: "false" - - - name: "Upload Grype scan results" - # yamllint disable-line rule:line-length - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 - if: always() - with: - name: grype-scan-results-x64 - path: | - grype-results.sarif - grype-results.txt - retention-days: 90 +permissions: {} - - name: "Grype summary" - if: always() - run: | - # Grype summary - echo "## Grype Summary (x64)" >> "$GITHUB_STEP_SUMMARY" - [ -f grype-results.txt ] && cat grype-results.txt \ - >> "$GITHUB_STEP_SUMMARY" || echo "No scan results available" \ - >> "$GITHUB_STEP_SUMMARY" +env: + # Harden-runner egress allow-list shared by the publish jobs. Loaded + # out-of-band from lfreleng-actions/.github and matches the default used + # inside the reusable workflow. + # yamllint disable-line rule:line-length + HARDEN_RUNNER_ALLOWLIST: 'lfreleng-actions//.github/harden-runner/lfreleng-actions/allow_list.txt@18d9c4446bea555d0783e850f6d295f844fe8f67' # v0.1.1 - sbom-arm64: - name: "Generate SBOM ARM64" - runs-on: ubuntu-24.04-arm - needs: ['python-metadata', 'python-build-arm64'] - timeout-minutes: 10 +jobs: + release: + name: 'Build/Test/Release' permissions: - contents: read - steps: - # Load the egress allow-list out-of-band from - # lfreleng-actions/.github and publish it as - # $CONNECTION_ALLOW_LIST for the harden-runner step below - # to consume in 'block' mode. Loading out-of-band means - # the workflow no longer depends on any org-level GitHub - # variable being exposed at runtime (org variables are - # unreachable from workflows triggered by PRs raised from - # forks, which previously forced a fallback to audit mode). - # yamllint disable-line rule:line-length - - uses: lfreleng-actions/harden-runner-block-action@42663a22f7abe31521cbc6120901353a4b2849bc # v0.2.0 - with: - # yamllint disable-line rule:line-length - config: 'lfreleng-actions//.github/harden-runner/lfreleng-actions/allow_list.txt@18d9c4446bea555d0783e850f6d295f844fe8f67' # v0.1.1 - - # Harden the runner with the just-loaded allow-list. - - name: 'Harden runner (block)' - # yamllint disable-line rule:line-length - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 - with: - egress-policy: 'block' - allowed-endpoints: > - ${{ env.CONNECTION_ALLOW_LIST }} - - # yamllint disable-line rule:line-length - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - - - name: Build NSS/NSPR from source - run: | - make deps-nss env-github-actions - - - name: "Generate SBOM" - id: sbom - # yamllint disable-line rule:line-length - uses: lfreleng-actions/python-sbom-action@ae4aca2ef28d7da4ec95049cc78be43e632d322a # v0.1.0 - with: - include_dev: "false" - sbom_format: "both" - - - name: "Upload SBOM artifacts" - # yamllint disable-line rule:line-length - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 - with: - name: sbom-files-arm64 - path: | - sbom-cyclonedx.json - sbom-cyclonedx.xml - retention-days: 45 - - - name: "Security scan with Grype (SARIF)" - # yamllint disable-line rule:line-length - uses: anchore/scan-action@e1165082ffb1fe366ebaf02d8526e7c4989ea9d2 # v7.4.0 - id: grype-sarif - with: - sbom: "${{ steps.sbom.outputs.sbom_json_path }}" - output-format: "sarif" - output-file: "grype-results.sarif" - fail-build: "true" - - - name: "Security scan with Grype (Text/Table)" - # yamllint disable-line rule:line-length - uses: anchore/scan-action@e1165082ffb1fe366ebaf02d8526e7c4989ea9d2 # v7.4.0 - id: grype-table - if: always() - with: - sbom: "${{ steps.sbom.outputs.sbom_json_path }}" - output-format: "table" - output-file: "grype-results.txt" - fail-build: "false" - - - name: "Upload Grype scan results" - # yamllint disable-line rule:line-length - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 - if: always() - with: - name: grype-scan-results-arm64 - path: | - grype-results.sarif - grype-results.txt - retention-days: 90 - - - name: "Grype summary" - if: always() - run: | - # Grype summary - echo "## Grype Summary (ARM64)" >> "$GITHUB_STEP_SUMMARY" - [ -f grype-results.txt ] && cat grype-results.txt \ - >> "$GITHUB_STEP_SUMMARY" || echo "No scan results available" \ - >> "$GITHUB_STEP_SUMMARY" - + contents: write # Create the GitHub release / attach assets + id-token: write # OIDC for build provenance attestations + attestations: write # Build provenance attestations + # yamllint disable-line rule:line-length + uses: lfreleng-actions/python-workflows/.github/workflows/build-test-release-multiarch.yaml@4f48e1cd660f94ab9f1d4bbc15a948c1aca105ad # v0.1.1 + with: + # Build NSS/NSPR from source during the python-build step. + make: true + make_args: 'deps-nss env-github-actions' + # Native prerequisites (NSS/NSPR + system test deps) for the test, + # audit and SBOM jobs, plus LD_LIBRARY_PATH / PKG_CONFIG_PATH export. + setup_script: '.github/scripts/setup-nss.sh' + + # --------------------------------------------------------------------------- + # PyPI publishing — runs in THIS repository so publishing credentials + # remain scoped here. The multi-arch build produces several 'dist-*' + # artefacts, so the publish jobs download them with `artefact_pattern`. + # --------------------------------------------------------------------------- test-pypi: name: 'Test PyPI Publishing' + needs: release runs-on: 'ubuntu-latest' - needs: - - 'tag-validate' - - 'python-build-sdist' - - 'python-tests-x64' - - 'python-tests-arm64' - - 'python-audit-x64' - - 'python-audit-arm64' environment: name: 'development' permissions: @@ -773,21 +69,13 @@ jobs: id-token: write # IMPORTANT: mandatory for trusted publishing timeout-minutes: 5 steps: - # Load the egress allow-list out-of-band from - # lfreleng-actions/.github and publish it as - # $CONNECTION_ALLOW_LIST for the harden-runner step below - # to consume in 'block' mode. Loading out-of-band means - # the workflow no longer depends on any org-level GitHub - # variable being exposed at runtime (org variables are - # unreachable from workflows triggered by PRs raised from - # forks, which previously forced a fallback to audit mode). + # Load the egress allow-list out-of-band and publish it as + # $CONNECTION_ALLOW_LIST for the harden-runner step below. # yamllint disable-line rule:line-length - uses: lfreleng-actions/harden-runner-block-action@42663a22f7abe31521cbc6120901353a4b2849bc # v0.2.0 with: - # yamllint disable-line rule:line-length - config: 'lfreleng-actions//.github/harden-runner/lfreleng-actions/allow_list.txt@18d9c4446bea555d0783e850f6d295f844fe8f67' # v0.1.1 + config: ${{ env.HARDEN_RUNNER_ALLOWLIST }} - # Harden the runner with the just-loaded allow-list. - name: 'Harden runner (block)' # yamllint disable-line rule:line-length uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 @@ -801,17 +89,16 @@ jobs: uses: lfreleng-actions/pypi-publish-action@9ed3121c20fc5988b79d6655d8e7637018b54433 # v0.1.8 with: environment: 'development' - tag: "${{ needs.tag-validate.outputs.tag }}" - artefact_pattern: 'python-nss-ng-*' + tag: "${{ needs.release.outputs.tag }}" + artefact_pattern: 'dist-*' pypi_credential: "${{ secrets.TEST_PYPI_CREDENTIAL }}" pypi: name: 'Release PyPI Package' - runs-on: 'ubuntu-latest' needs: - - 'tag-validate' - - 'python-build-sdist' - - 'test-pypi' + - release + - test-pypi + runs-on: 'ubuntu-latest' environment: name: 'production' permissions: @@ -819,21 +106,13 @@ jobs: id-token: write # IMPORTANT: mandatory for trusted publishing timeout-minutes: 5 steps: - # Load the egress allow-list out-of-band from - # lfreleng-actions/.github and publish it as - # $CONNECTION_ALLOW_LIST for the harden-runner step below - # to consume in 'block' mode. Loading out-of-band means - # the workflow no longer depends on any org-level GitHub - # variable being exposed at runtime (org variables are - # unreachable from workflows triggered by PRs raised from - # forks, which previously forced a fallback to audit mode). + # Load the egress allow-list out-of-band and publish it as + # $CONNECTION_ALLOW_LIST for the harden-runner step below. # yamllint disable-line rule:line-length - uses: lfreleng-actions/harden-runner-block-action@42663a22f7abe31521cbc6120901353a4b2849bc # v0.2.0 with: - # yamllint disable-line rule:line-length - config: 'lfreleng-actions//.github/harden-runner/lfreleng-actions/allow_list.txt@18d9c4446bea555d0783e850f6d295f844fe8f67' # v0.1.1 + config: ${{ env.HARDEN_RUNNER_ALLOWLIST }} - # Harden the runner with the just-loaded allow-list. - name: 'Harden runner (block)' # yamllint disable-line rule:line-length uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 @@ -848,152 +127,6 @@ jobs: with: environment: 'production' attestations: true - tag: "${{ needs.tag-validate.outputs.tag }}" - artefact_pattern: 'python-nss-ng-*' + tag: "${{ needs.release.outputs.tag }}" + artefact_pattern: 'dist-*' pypi_credential: "${{ secrets.PYPI_CREDENTIAL }}" - - # Attach build artefacts prior to release promotion - # This enables the GitHub immutable releases feature - attach-artefacts: - name: 'Attach Artefacts to Release' - runs-on: 'ubuntu-latest' - needs: - - 'tag-validate' - - 'python-build-sdist' - - 'python-build-x64' - - 'python-build-arm64' - - 'pypi' - # yamllint disable-line rule:line-length - permissions: - contents: write # IMPORTANT: needed to edit release, attach artefacts - timeout-minutes: 5 - env: - GH_TOKEN: "${{ secrets.GITHUB_TOKEN }}" - steps: - # Load the egress allow-list out-of-band from - # lfreleng-actions/.github and publish it as - # $CONNECTION_ALLOW_LIST for the harden-runner step below - # to consume in 'block' mode. Loading out-of-band means - # the workflow no longer depends on any org-level GitHub - # variable being exposed at runtime (org variables are - # unreachable from workflows triggered by PRs raised from - # forks, which previously forced a fallback to audit mode). - # yamllint disable-line rule:line-length - - uses: lfreleng-actions/harden-runner-block-action@42663a22f7abe31521cbc6120901353a4b2849bc # v0.2.0 - with: - # yamllint disable-line rule:line-length - config: 'lfreleng-actions//.github/harden-runner/lfreleng-actions/allow_list.txt@18d9c4446bea555d0783e850f6d295f844fe8f67' # v0.1.1 - - # Harden the runner with the just-loaded allow-list. - - name: 'Harden runner (block)' - # yamllint disable-line rule:line-length - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 - with: - egress-policy: 'block' - allowed-endpoints: > - ${{ env.CONNECTION_ALLOW_LIST }} - - # yamllint disable-line rule:line-length - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - - - name: '⬇ Download build artefacts (wheels)' - # yamllint disable-line rule:line-length - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 - with: - pattern: 'python-nss-ng-*-py*' - path: 'dist' - merge-multiple: true - - - name: '⬇ Download build artefacts (sdist)' - # yamllint disable-line rule:line-length - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 - with: - name: 'python-nss-ng-sdist' - path: 'dist' - - - name: 'Attach build artefacts to release' - # yamllint disable-line rule:line-length - uses: lfreleng-actions/release-assets-action@985ecd2ba521dde165514af406dd114d3db5dab6 # v0.1.0 - with: - asset_paths: '["dist/**"]' - release_tag: "${{ needs.tag-validate.outputs.tag }}" - - promote-release: - name: 'Promote Draft Release' - # yamllint disable-line rule:line-length - needs: - - 'tag-validate' - - 'pypi' - - 'attach-artefacts' - runs-on: 'ubuntu-latest' - permissions: - # IMPORTANT: needed to edit a draft release and promote it - contents: write - timeout-minutes: 2 - outputs: - release_url: "${{ steps.promote-release.outputs.release_url }}" - steps: - # Load the egress allow-list out-of-band from - # lfreleng-actions/.github and publish it as - # $CONNECTION_ALLOW_LIST for the harden-runner step below - # to consume in 'block' mode. Loading out-of-band means - # the workflow no longer depends on any org-level GitHub - # variable being exposed at runtime (org variables are - # unreachable from workflows triggered by PRs raised from - # forks, which previously forced a fallback to audit mode). - # yamllint disable-line rule:line-length - - uses: lfreleng-actions/harden-runner-block-action@42663a22f7abe31521cbc6120901353a4b2849bc # v0.2.0 - with: - # yamllint disable-line rule:line-length - config: 'lfreleng-actions//.github/harden-runner/lfreleng-actions/allow_list.txt@18d9c4446bea555d0783e850f6d295f844fe8f67' # v0.1.1 - - # Harden the runner with the just-loaded allow-list. - - name: 'Harden runner (block)' - # yamllint disable-line rule:line-length - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 - with: - egress-policy: 'block' - allowed-endpoints: > - ${{ env.CONNECTION_ALLOW_LIST }} - - # yamllint disable-line rule:line-length - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - - - name: 'Check if release is already promoted' - id: 'check-promoted' - shell: bash - env: - GH_TOKEN: "${{ secrets.GITHUB_TOKEN }}" - TAG_NAME: "${{ needs.tag-validate.outputs.tag }}" - run: | - TAG="${TAG_NAME}" - if gh release view "$TAG" --json isDraft --jq '.isDraft' \ - 2>/dev/null | grep -q "false"; then - echo "Release $TAG is already promoted, skipping promotion" - echo "already_promoted=true" >> "$GITHUB_OUTPUT" - else - echo "Release $TAG is draft or doesn't exist, " \ - "proceeding with promotion" - echo "already_promoted=false" >> "$GITHUB_OUTPUT" - fi - - - name: 'Promote draft release' - id: 'promote-release' - if: steps.check-promoted.outputs.already_promoted == 'false' - # yamllint disable-line rule:line-length - uses: lfreleng-actions/draft-release-promote-action@072990900b99030363d81d4131c2bf2855f07df0 # v0.1.4 - with: - token: "${{ secrets.GITHUB_TOKEN }}" - tag: "${{ needs.tag-validate.outputs.tag }}" - latest: true - - - name: 'Set release URL for already promoted release' - if: steps.check-promoted.outputs.already_promoted == 'true' - shell: bash - env: - GH_TOKEN: "${{ secrets.GITHUB_TOKEN }}" - TAG_NAME: "${{ needs.tag-validate.outputs.tag }}" - run: | - TAG="${TAG_NAME}" - RELEASE_URL=$(gh release view "$TAG" --json url --jq '.url') - echo "release_url=$RELEASE_URL" >> "$GITHUB_OUTPUT" diff --git a/.github/workflows/build-test.yaml b/.github/workflows/build-test.yaml index fdd3776..6212344 100644 --- a/.github/workflows/build-test.yaml +++ b/.github/workflows/build-test.yaml @@ -1,19 +1,20 @@ --- # SPDX-License-Identifier: Apache-2.0 -# SPDX-FileCopyrightText: 2025 The Linux Foundation - -# Runs on a new pull request, performs build and runs tests +# SPDX-FileCopyrightText: 2026 The Linux Foundation + +# Runs on a new pull request, performs build and runs tests. +# +# Thin caller for the reusable multi-arch Python build/test pipeline. The +# entire pipeline (metadata, build, tests, audit, SBOM and Grype scan, +# fanned out across the x64 + arm64 architecture matrix) lives in +# lfreleng-actions/python-workflows. Native NSS/NSPR prerequisites are +# supplied through the committed setup script consumed by the reusable +# workflow's setup_script input. name: 'Python Build/Test' # yamllint disable-line rule:truthy on: workflow_dispatch: - inputs: - clear_cache: - description: 'Clear all Python dependency caches' - type: boolean - default: false - required: false pull_request: types: [opened, reopened, edited, synchronize] branches: @@ -29,789 +30,20 @@ concurrency: group: "${{ github.workflow }}-${{ github.ref }}" cancel-in-progress: true -permissions: - actions: write # Required for cache deletion when clear_cache is true +permissions: {} jobs: - repository-metadata: - name: "Repository Metadata" - runs-on: ubuntu-latest + build-test: + name: 'Build/Test' permissions: contents: read pull-requests: read - timeout-minutes: 5 - steps: - # Load the egress allow-list out-of-band from - # lfreleng-actions/.github and publish it as - # $CONNECTION_ALLOW_LIST for the harden-runner step below - # to consume in 'block' mode. Loading out-of-band means - # the workflow no longer depends on any org-level GitHub - # variable being exposed at runtime (org variables are - # unreachable from workflows triggered by PRs raised from - # forks, which previously forced a fallback to audit mode). - # yamllint disable-line rule:line-length - - uses: lfreleng-actions/harden-runner-block-action@42663a22f7abe31521cbc6120901353a4b2849bc # v0.2.0 - with: - # yamllint disable-line rule:line-length - config: 'lfreleng-actions//.github/harden-runner/lfreleng-actions/allow_list.txt@18d9c4446bea555d0783e850f6d295f844fe8f67' # v0.1.1 - - # Harden the runner with the just-loaded allow-list. - - name: 'Harden runner (block)' - # yamllint disable-line rule:line-length - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 - with: - egress-policy: 'block' - allowed-endpoints: > - ${{ env.CONNECTION_ALLOW_LIST }} - - # yamllint disable-line rule:line-length - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - with: - fetch-depth: 0 - - - name: "Gather repository metadata" - id: repo-metadata - # yamllint disable-line rule:line-length - uses: lfreleng-actions/repository-metadata-action@ceabcd987d13d7bfefd2372e01eebb0ddac45956 # v0.2.0 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - github_summary: 'false' - gerrit_summary: 'false' - artifact_upload: 'true' - artifact_formats: 'json' - - python-metadata: - name: 'Extract Project Metadata' - runs-on: ubuntu-latest - outputs: - matrix_json: "${{ steps.metadata.outputs.python_matrix_json }}" - project_name: "${{ steps.metadata.outputs.project_name }}" - permissions: - contents: read - timeout-minutes: 5 - steps: - # Load the egress allow-list out-of-band from - # lfreleng-actions/.github and publish it as - # $CONNECTION_ALLOW_LIST for the harden-runner step below - # to consume in 'block' mode. Loading out-of-band means - # the workflow no longer depends on any org-level GitHub - # variable being exposed at runtime (org variables are - # unreachable from workflows triggered by PRs raised from - # forks, which previously forced a fallback to audit mode). - # yamllint disable-line rule:line-length - - uses: lfreleng-actions/harden-runner-block-action@42663a22f7abe31521cbc6120901353a4b2849bc # v0.2.0 - with: - # yamllint disable-line rule:line-length - config: 'lfreleng-actions//.github/harden-runner/lfreleng-actions/allow_list.txt@18d9c4446bea555d0783e850f6d295f844fe8f67' # v0.1.1 - - # Harden the runner with the just-loaded allow-list. - - name: 'Harden runner (block)' - # yamllint disable-line rule:line-length - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 - with: - egress-policy: 'block' - allowed-endpoints: > - ${{ env.CONNECTION_ALLOW_LIST }} - - # yamllint disable-line rule:line-length - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - - - name: 'Extract Python project metadata' - id: metadata - # yamllint disable-line rule:line-length - uses: lfreleng-actions/build-metadata-action@bc866421c816f63e6ab09f3d42bf95566be50940 # v0.4.0 - with: - path_prefix: '.' - output_format: summary - include_environment: true - use_version_extract: true - verbose: true - - python-build-x64: - name: "Python Build x64 ${{ matrix.python-version }}" - runs-on: ubuntu-latest - needs: python-metadata - strategy: - fail-fast: false - matrix: "${{ fromJson(needs.python-metadata.outputs.matrix_json) }}" - permissions: - contents: read - actions: write # Required for cache deletion when clear_cache is true - timeout-minutes: 20 - env: - GH_TOKEN: "${{ secrets.GITHUB_TOKEN }}" - steps: - # Load the egress allow-list out-of-band from - # lfreleng-actions/.github and publish it as - # $CONNECTION_ALLOW_LIST for the harden-runner step below - # to consume in 'block' mode. Loading out-of-band means - # the workflow no longer depends on any org-level GitHub - # variable being exposed at runtime (org variables are - # unreachable from workflows triggered by PRs raised from - # forks, which previously forced a fallback to audit mode). - # yamllint disable-line rule:line-length - - uses: lfreleng-actions/harden-runner-block-action@42663a22f7abe31521cbc6120901353a4b2849bc # v0.2.0 - with: - # yamllint disable-line rule:line-length - config: 'lfreleng-actions//.github/harden-runner/lfreleng-actions/allow_list.txt@18d9c4446bea555d0783e850f6d295f844fe8f67' # v0.1.1 - - # Harden the runner with the just-loaded allow-list. - - name: 'Harden runner (block)' - # yamllint disable-line rule:line-length - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 - with: - egress-policy: 'block' - allowed-endpoints: > - ${{ env.CONNECTION_ALLOW_LIST }} - - # yamllint disable-line rule:line-length - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - - - name: "Build Python project ${{ matrix.python-version }}" - id: python-build - # yamllint disable-line rule:line-length - uses: lfreleng-actions/python-build-action@5f570d5d17a7315074a824a91c6a705b6fc5c7dd # v1.1.2 - with: - artefact_name: python-nss-ng-x64-py${{ matrix.python-version }} - python_version: ${{ matrix.python-version }} - auditwheel: true - manylinux_version: manylinux_2_38 - clear_cache: ${{ github.event.inputs.clear_cache || 'false' }} - make: true - make_args: 'deps-nss env-github-actions' - - python-build-arm64: - name: "Python Build ARM64 ${{ matrix.python-version }}" - runs-on: ubuntu-24.04-arm - needs: python-metadata - strategy: - fail-fast: false - matrix: "${{ fromJson(needs.python-metadata.outputs.matrix_json) }}" - permissions: - contents: read - actions: write # Required for cache deletion when clear_cache is true - timeout-minutes: 20 - env: - GH_TOKEN: "${{ secrets.GITHUB_TOKEN }}" - steps: - # Load the egress allow-list out-of-band from - # lfreleng-actions/.github and publish it as - # $CONNECTION_ALLOW_LIST for the harden-runner step below - # to consume in 'block' mode. Loading out-of-band means - # the workflow no longer depends on any org-level GitHub - # variable being exposed at runtime (org variables are - # unreachable from workflows triggered by PRs raised from - # forks, which previously forced a fallback to audit mode). - # yamllint disable-line rule:line-length - - uses: lfreleng-actions/harden-runner-block-action@42663a22f7abe31521cbc6120901353a4b2849bc # v0.2.0 - with: - # yamllint disable-line rule:line-length - config: 'lfreleng-actions//.github/harden-runner/lfreleng-actions/allow_list.txt@18d9c4446bea555d0783e850f6d295f844fe8f67' # v0.1.1 - - # Harden the runner with the just-loaded allow-list. - - name: 'Harden runner (block)' - # yamllint disable-line rule:line-length - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 - with: - egress-policy: 'block' - allowed-endpoints: > - ${{ env.CONNECTION_ALLOW_LIST }} - - # yamllint disable-line rule:line-length - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - - - name: "Build Python project ${{ matrix.python-version }}" - id: python-build - # yamllint disable-line rule:line-length - uses: lfreleng-actions/python-build-action@5f570d5d17a7315074a824a91c6a705b6fc5c7dd # v1.1.2 - with: - artefact_name: python-nss-ng-arm64-py${{ matrix.python-version }} - python_version: ${{ matrix.python-version }} - auditwheel: true - manylinux_version: manylinux_2_38 - clear_cache: ${{ github.event.inputs.clear_cache || 'false' }} - make: true - make_args: 'deps-nss env-github-actions' - - python-tests-x64: - name: "Python Tests x64 ${{ matrix.python-version }}" - runs-on: 'ubuntu-latest' - needs: ['python-metadata', 'python-build-x64'] - strategy: - fail-fast: false - matrix: "${{ fromJson(needs.python-metadata.outputs.matrix_json) }}" - permissions: - contents: read - timeout-minutes: 12 - steps: - # Load the egress allow-list out-of-band from - # lfreleng-actions/.github and publish it as - # $CONNECTION_ALLOW_LIST for the harden-runner step below - # to consume in 'block' mode. Loading out-of-band means - # the workflow no longer depends on any org-level GitHub - # variable being exposed at runtime (org variables are - # unreachable from workflows triggered by PRs raised from - # forks, which previously forced a fallback to audit mode). - # yamllint disable-line rule:line-length - - uses: lfreleng-actions/harden-runner-block-action@42663a22f7abe31521cbc6120901353a4b2849bc # v0.2.0 - with: - # yamllint disable-line rule:line-length - config: 'lfreleng-actions//.github/harden-runner/lfreleng-actions/allow_list.txt@18d9c4446bea555d0783e850f6d295f844fe8f67' # v0.1.1 - - # Harden the runner with the just-loaded allow-list. - - name: 'Harden runner (block)' - # yamllint disable-line rule:line-length - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 - with: - egress-policy: 'block' - allowed-endpoints: > - ${{ env.CONNECTION_ALLOW_LIST }} - - # yamllint disable-line rule:line-length - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - - - name: Build NSS/NSPR and install system dependencies - run: | - # Only install system-level (apt) deps here; pip deps are - # handled later by python-test-action under the correct - # actions/setup-python interpreter. - make deps-nss deps-test-system env-github-actions - # Ensure NSS libraries are in ldconfig cache - sudo ldconfig - # Export library path for subsequent steps - LIB_PATH="/usr/lib:/usr/lib/aarch64-linux-gnu" - LIB_PATH="${LIB_PATH}:/usr/lib/x86_64-linux-gnu" - echo "LD_LIBRARY_PATH=${LIB_PATH}:${LD_LIBRARY_PATH}" \ - >> "$GITHUB_ENV" - - - name: Verify NSS libraries and environment - run: | - echo "=== Library Path Diagnostics ===" - echo "LD_LIBRARY_PATH=${LD_LIBRARY_PATH}" - echo "PKG_CONFIG_PATH=${PKG_CONFIG_PATH}" - echo "" - echo "=== NSS Libraries in /usr/lib ===" - ls -la /usr/lib/libnss* /usr/lib/libnspr* 2>/dev/null || \ - echo "Not found in /usr/lib" - echo "" - echo "=== NSS Libraries in /usr/lib/x86_64-linux-gnu ===" - ls -la /usr/lib/x86_64-linux-gnu/libnss* \ - /usr/lib/x86_64-linux-gnu/libnspr* 2>/dev/null || \ - echo "Not found in /usr/lib/x86_64-linux-gnu" - echo "" - echo "=== ldconfig cache ===" - ldconfig -p | grep -E '(nss|nspr)' || \ - echo "NSS/NSPR not in ldconfig cache" - echo "" - echo "=== pkg-config ===" - pkg-config --exists nss && \ - echo "NSS found: $(pkg-config --modversion nss)" || \ - echo "NSS not found by pkg-config" - pkg-config --exists nspr && \ - echo "NSPR found: $(pkg-config --modversion nspr)" || \ - echo "NSPR not found by pkg-config" - - - name: "Python tests [pytest] ${{ matrix.python-version }}" - # yamllint disable-line rule:line-length - uses: lfreleng-actions/python-test-action@aa753462f090101dcb0c4708e9499f55e276e373 # v1.1.2 - with: - python_version: ${{ matrix.python-version }} - # yamllint disable-line rule:line-length - artefact_name: python-nss-ng-x64-py${{ matrix.python-version }}-coverage - report_artefact: 'true' - env: - LD_LIBRARY_PATH: /usr/lib:/usr/lib/x86_64-linux-gnu - - - name: Post-test diagnostics (if test failed) - if: failure() - env: - PYVER: ${{ matrix.python-version }} - run: | - echo "=== POST-TEST DIAGNOSTICS ===" - echo "Checking where package was actually installed..." - python3 -m pip list | grep python-nss-ng || \ - echo "Package not in pip list" - echo "" - echo "Getting pip show output:" - python3 -m pip show python-nss-ng || echo "pip show failed" - echo "" - echo "Extracting actual installation location:" - INSTALL_LOC=$(python3 -m pip show python-nss-ng | \ - grep "Location:" | cut -d' ' -f2) - echo "Package installed at: ${INSTALL_LOC}" - if [ -n "${INSTALL_LOC}" ]; then - echo "Checking for nss package in actual location:" - ls -la "${INSTALL_LOC}/nss/" 2>/dev/null || \ - echo "nss directory not found at ${INSTALL_LOC}" - echo "" - echo "Checking for .so files in actual location:" - find "${INSTALL_LOC}/nss/" -name "*.so" 2>/dev/null || \ - echo "No .so files found" - echo "" - echo "Checking library dependencies with ldd:" - for so_file in "${INSTALL_LOC}/nss/"*.so; do - if [ -f "$so_file" ]; then - echo "--- $(basename "$so_file") ---" - ldd "$so_file" 2>&1 | \ - grep -E "(nss|nspr|not found)" || true - fi - done - fi - echo "" - echo "Searching for nss package in all locations:" - find "/home/runner/.local/lib/python${PYVER}/" -name "nss" \ - -type d 2>/dev/null || echo "Not found in .local" - find "/usr/local/lib/python${PYVER}/" -name "nss" \ - -type d 2>/dev/null || echo "Not found in /usr/local" - find /usr/lib/python3/dist-packages/ -name "nss" \ - -type d 2>/dev/null || echo "Not found in dist-packages" - echo "" - echo "Searching for ANY python-nss-ng files:" - find "/home/runner/.local/lib/python${PYVER}/" \ - -name "*python*nss*" 2>/dev/null | head -20 || true - find "/usr/local/lib/python${PYVER}/" \ - -name "*python*nss*" 2>/dev/null | head -20 || true - echo "" - echo "Searching for .so files with nss:" - find "/home/runner/.local/lib/python${PYVER}/" \ - -name "*nss*.so" 2>/dev/null || echo "No .so files found" - echo "" - echo "Checking pip cache:" - ls -la /home/runner/.cache/pip/wheels/ 2>/dev/null || true - - python-tests-arm64: - name: "Python Tests ARM64 ${{ matrix.python-version }}" - runs-on: 'ubuntu-24.04-arm' - needs: ['python-metadata', 'python-build-arm64'] - strategy: - fail-fast: false - matrix: "${{ fromJson(needs.python-metadata.outputs.matrix_json) }}" - permissions: - contents: read - timeout-minutes: 12 - steps: - # Load the egress allow-list out-of-band from - # lfreleng-actions/.github and publish it as - # $CONNECTION_ALLOW_LIST for the harden-runner step below - # to consume in 'block' mode. Loading out-of-band means - # the workflow no longer depends on any org-level GitHub - # variable being exposed at runtime (org variables are - # unreachable from workflows triggered by PRs raised from - # forks, which previously forced a fallback to audit mode). - # yamllint disable-line rule:line-length - - uses: lfreleng-actions/harden-runner-block-action@42663a22f7abe31521cbc6120901353a4b2849bc # v0.2.0 - with: - # yamllint disable-line rule:line-length - config: 'lfreleng-actions//.github/harden-runner/lfreleng-actions/allow_list.txt@18d9c4446bea555d0783e850f6d295f844fe8f67' # v0.1.1 - - # Harden the runner with the just-loaded allow-list. - - name: 'Harden runner (block)' - # yamllint disable-line rule:line-length - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 - with: - egress-policy: 'block' - allowed-endpoints: > - ${{ env.CONNECTION_ALLOW_LIST }} - - # yamllint disable-line rule:line-length - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - - - name: Build NSS/NSPR and install system dependencies - run: | - # Only install system-level (apt) deps here; pip deps are - # handled later by python-test-action under the correct - # actions/setup-python interpreter. - make deps-nss deps-test-system env-github-actions - # Ensure NSS libraries are in ldconfig cache - sudo ldconfig - # Export library path for subsequent steps - LIB_PATH="/usr/lib:/usr/lib/aarch64-linux-gnu" - LIB_PATH="${LIB_PATH}:/usr/lib/x86_64-linux-gnu" - echo "LD_LIBRARY_PATH=${LIB_PATH}:${LD_LIBRARY_PATH}" >> "$GITHUB_ENV" - - - name: Verify NSS libraries and environment - run: | - echo "=== Library Path Diagnostics ===" - echo "LD_LIBRARY_PATH=${LD_LIBRARY_PATH}" - echo "PKG_CONFIG_PATH=${PKG_CONFIG_PATH}" - echo "" - echo "=== NSS Libraries in /usr/lib ===" - ls -la /usr/lib/libnss* /usr/lib/libnspr* 2>/dev/null || \ - echo "Not found in /usr/lib" - echo "" - echo "=== NSS Libraries in /usr/lib/aarch64-linux-gnu ===" - ls -la /usr/lib/aarch64-linux-gnu/libnss* \ - /usr/lib/aarch64-linux-gnu/libnspr* 2>/dev/null || \ - echo "Not found in /usr/lib/aarch64-linux-gnu" - echo "" - echo "=== ldconfig cache ===" - ldconfig -p | grep -E '(nss|nspr)' || \ - echo "NSS/NSPR not in ldconfig cache" - echo "" - echo "=== pkg-config ===" - pkg-config --exists nss && \ - echo "NSS found: $(pkg-config --modversion nss)" || \ - echo "NSS not found by pkg-config" - pkg-config --exists nspr && \ - echo "NSPR found: $(pkg-config --modversion nspr)" || \ - echo "NSPR not found by pkg-config" - - - name: "Python tests [pytest] (arm64) ${{ matrix.python-version }}" - # yamllint disable-line rule:line-length - uses: lfreleng-actions/python-test-action@aa753462f090101dcb0c4708e9499f55e276e373 # v1.1.2 - with: - python_version: ${{ matrix.python-version }} - # yamllint disable-line rule:line-length - artefact_name: python-nss-ng-arm64-py${{ matrix.python-version }}-coverage - report_artefact: 'true' - env: - LD_LIBRARY_PATH: /usr/lib:/usr/lib/aarch64-linux-gnu - - - name: Post-test diagnostics (if test failed) - if: failure() - env: - PYVER: ${{ matrix.python-version }} - run: | - echo "=== POST-TEST DIAGNOSTICS ===" - echo "Checking where package was actually installed..." - python3 -m pip list | grep python-nss-ng || \ - echo "Package not in pip list" - echo "" - echo "Getting pip show output:" - python3 -m pip show python-nss-ng || echo "pip show failed" - echo "" - echo "Extracting actual installation location:" - INSTALL_LOC=$(python3 -m pip show python-nss-ng | \ - grep "Location:" | cut -d' ' -f2) - echo "Package installed at: ${INSTALL_LOC}" - if [ -n "${INSTALL_LOC}" ]; then - echo "Checking for nss package in actual location:" - ls -la "${INSTALL_LOC}/nss/" 2>/dev/null || \ - echo "nss directory not found at ${INSTALL_LOC}" - echo "" - echo "Checking for .so files in actual location:" - find "${INSTALL_LOC}/nss/" -name "*.so" 2>/dev/null || \ - echo "No .so files found" - echo "" - echo "Checking library dependencies with ldd:" - for so_file in "${INSTALL_LOC}/nss/"*.so; do - if [ -f "$so_file" ]; then - echo "--- $(basename "$so_file") ---" - ldd "$so_file" 2>&1 | \ - grep -E "(nss|nspr|not found)" || true - fi - done - fi - echo "" - echo "Searching for nss package in all locations:" - find "/home/runner/.local/lib/python${PYVER}/" -name "nss" \ - -type d 2>/dev/null || echo "Not found in .local" - find "/usr/local/lib/python${PYVER}/" -name "nss" \ - -type d 2>/dev/null || echo "Not found in /usr/local" - find /usr/lib/python3/dist-packages/ -name "nss" \ - -type d 2>/dev/null || echo "Not found in dist-packages" - echo "" - echo "Searching for ANY python-nss-ng files:" - find "/home/runner/.local/lib/python${PYVER}/" \ - -name "*python*nss*" 2>/dev/null | head -20 || true - find "/usr/local/lib/python${PYVER}/" \ - -name "*python*nss*" 2>/dev/null | head -20 || true - echo "" - echo "Searching for .so files with nss:" - find "/home/runner/.local/lib/python${PYVER}/" \ - -name "*nss*.so" 2>/dev/null || echo "No .so files found" - echo "" - echo "Checking pip cache:" - ls -la /home/runner/.cache/pip/wheels/ 2>/dev/null || true - - python-audit-x64: - name: "Python Audit x64 ${{ matrix.python-version }}" - runs-on: 'ubuntu-latest' - needs: ['python-metadata', 'python-build-x64'] - strategy: - fail-fast: false - matrix: "${{ fromJson(needs.python-metadata.outputs.matrix_json) }}" - permissions: - contents: read - timeout-minutes: 10 - steps: - # Load the egress allow-list out-of-band from - # lfreleng-actions/.github and publish it as - # $CONNECTION_ALLOW_LIST for the harden-runner step below - # to consume in 'block' mode. Loading out-of-band means - # the workflow no longer depends on any org-level GitHub - # variable being exposed at runtime (org variables are - # unreachable from workflows triggered by PRs raised from - # forks, which previously forced a fallback to audit mode). - # yamllint disable-line rule:line-length - - uses: lfreleng-actions/harden-runner-block-action@42663a22f7abe31521cbc6120901353a4b2849bc # v0.2.0 - with: - # yamllint disable-line rule:line-length - config: 'lfreleng-actions//.github/harden-runner/lfreleng-actions/allow_list.txt@18d9c4446bea555d0783e850f6d295f844fe8f67' # v0.1.1 - - # Harden the runner with the just-loaded allow-list. - - name: 'Harden runner (block)' - # yamllint disable-line rule:line-length - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 - with: - egress-policy: 'block' - allowed-endpoints: > - ${{ env.CONNECTION_ALLOW_LIST }} - - # yamllint disable-line rule:line-length - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - - - name: Build NSS/NSPR and install system dependencies - run: | - make deps-nss deps-test-system env-github-actions - - - name: "Audit dependencies ${{ matrix.python-version }}" - # yamllint disable-line rule:line-length - uses: lfreleng-actions/python-audit-action@fcb1b2e0cdbe19edf11057e598138f3d57f2b249 # v0.3.1 - with: - python_version: ${{ matrix.python-version }} - # yamllint disable-line rule:line-length - artefact_name: python-nss-ng-x64-py${{ matrix.python-version }} - - python-audit-arm64: - name: "Python Audit ARM64 ${{ matrix.python-version }}" - runs-on: 'ubuntu-24.04-arm' - needs: ['python-metadata', 'python-build-arm64'] - strategy: - fail-fast: false - matrix: "${{ fromJson(needs.python-metadata.outputs.matrix_json) }}" - permissions: - contents: read - timeout-minutes: 10 - steps: - # Load the egress allow-list out-of-band from - # lfreleng-actions/.github and publish it as - # $CONNECTION_ALLOW_LIST for the harden-runner step below - # to consume in 'block' mode. Loading out-of-band means - # the workflow no longer depends on any org-level GitHub - # variable being exposed at runtime (org variables are - # unreachable from workflows triggered by PRs raised from - # forks, which previously forced a fallback to audit mode). - # yamllint disable-line rule:line-length - - uses: lfreleng-actions/harden-runner-block-action@42663a22f7abe31521cbc6120901353a4b2849bc # v0.2.0 - with: - # yamllint disable-line rule:line-length - config: 'lfreleng-actions//.github/harden-runner/lfreleng-actions/allow_list.txt@18d9c4446bea555d0783e850f6d295f844fe8f67' # v0.1.1 - - # Harden the runner with the just-loaded allow-list. - - name: 'Harden runner (block)' - # yamllint disable-line rule:line-length - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 - with: - egress-policy: 'block' - allowed-endpoints: > - ${{ env.CONNECTION_ALLOW_LIST }} - - # yamllint disable-line rule:line-length - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - - - name: Build NSS/NSPR and install system dependencies - run: | - make deps-nss deps-test-system env-github-actions - - - name: "Audit dependencies ${{ matrix.python-version }}" - # yamllint disable-line rule:line-length - uses: lfreleng-actions/python-audit-action@fcb1b2e0cdbe19edf11057e598138f3d57f2b249 # v0.3.1 - with: - python_version: ${{ matrix.python-version }} - # yamllint disable-line rule:line-length - artefact_name: python-nss-ng-arm64-py${{ matrix.python-version }} - - sbom-x64: - name: "Generate SBOM x64" - runs-on: ubuntu-latest - needs: ['python-metadata', 'python-build-x64'] - timeout-minutes: 10 - permissions: - contents: read - steps: - # Load the egress allow-list out-of-band from - # lfreleng-actions/.github and publish it as - # $CONNECTION_ALLOW_LIST for the harden-runner step below - # to consume in 'block' mode. Loading out-of-band means - # the workflow no longer depends on any org-level GitHub - # variable being exposed at runtime (org variables are - # unreachable from workflows triggered by PRs raised from - # forks, which previously forced a fallback to audit mode). - # yamllint disable-line rule:line-length - - uses: lfreleng-actions/harden-runner-block-action@42663a22f7abe31521cbc6120901353a4b2849bc # v0.2.0 - with: - # yamllint disable-line rule:line-length - config: 'lfreleng-actions//.github/harden-runner/lfreleng-actions/allow_list.txt@18d9c4446bea555d0783e850f6d295f844fe8f67' # v0.1.1 - - # Harden the runner with the just-loaded allow-list. - - name: 'Harden runner (block)' - # yamllint disable-line rule:line-length - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 - with: - egress-policy: 'block' - allowed-endpoints: > - ${{ env.CONNECTION_ALLOW_LIST }} - - # yamllint disable-line rule:line-length - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - - - name: Build NSS/NSPR from source - run: | - make deps-nss env-github-actions - - - name: "Generate SBOM" - id: sbom - # yamllint disable-line rule:line-length - uses: lfreleng-actions/python-sbom-action@ae4aca2ef28d7da4ec95049cc78be43e632d322a # v0.1.0 - with: - include_dev: "false" - sbom_format: "both" - - - name: "Upload SBOM artifacts" - # yamllint disable-line rule:line-length - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 - with: - name: sbom-files-x64 - path: | - sbom-cyclonedx.json - sbom-cyclonedx.xml - retention-days: 45 - - - name: "Security scan with Grype (SARIF)" - # yamllint disable-line rule:line-length - uses: anchore/scan-action@e1165082ffb1fe366ebaf02d8526e7c4989ea9d2 # v7.4.0 - id: grype-sarif - with: - sbom: "${{ steps.sbom.outputs.sbom_json_path }}" - output-format: "sarif" - output-file: "grype-results.sarif" - fail-build: "true" - - - name: "Security scan with Grype (Text/Table)" - # yamllint disable-line rule:line-length - uses: anchore/scan-action@e1165082ffb1fe366ebaf02d8526e7c4989ea9d2 # v7.4.0 - id: grype-table - if: always() - with: - sbom: "${{ steps.sbom.outputs.sbom_json_path }}" - output-format: "table" - output-file: "grype-results.txt" - fail-build: "false" - - - name: "Upload Grype scan results" - # yamllint disable-line rule:line-length - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 - if: always() - with: - name: grype-scan-results-x64 - path: | - grype-results.sarif - grype-results.txt - retention-days: 90 - - - name: "Grype summary" - if: always() - run: | - # Grype summary - echo "## Grype Summary (x64)" >> "$GITHUB_STEP_SUMMARY" - [ -f grype-results.txt ] && cat grype-results.txt \ - >> "$GITHUB_STEP_SUMMARY" || echo "No scan results available" \ - >> "$GITHUB_STEP_SUMMARY" - - sbom-arm64: - name: "Generate SBOM ARM64" - runs-on: ubuntu-24.04-arm - needs: ['python-metadata', 'python-build-arm64'] - timeout-minutes: 10 - permissions: - contents: read - steps: - # Load the egress allow-list out-of-band from - # lfreleng-actions/.github and publish it as - # $CONNECTION_ALLOW_LIST for the harden-runner step below - # to consume in 'block' mode. Loading out-of-band means - # the workflow no longer depends on any org-level GitHub - # variable being exposed at runtime (org variables are - # unreachable from workflows triggered by PRs raised from - # forks, which previously forced a fallback to audit mode). - # yamllint disable-line rule:line-length - - uses: lfreleng-actions/harden-runner-block-action@42663a22f7abe31521cbc6120901353a4b2849bc # v0.2.0 - with: - # yamllint disable-line rule:line-length - config: 'lfreleng-actions//.github/harden-runner/lfreleng-actions/allow_list.txt@18d9c4446bea555d0783e850f6d295f844fe8f67' # v0.1.1 - - # Harden the runner with the just-loaded allow-list. - - name: 'Harden runner (block)' - # yamllint disable-line rule:line-length - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 - with: - egress-policy: 'block' - allowed-endpoints: > - ${{ env.CONNECTION_ALLOW_LIST }} - - # yamllint disable-line rule:line-length - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - - - name: Build NSS/NSPR from source - run: | - make deps-nss env-github-actions - - - name: "Generate SBOM" - id: sbom - # yamllint disable-line rule:line-length - uses: lfreleng-actions/python-sbom-action@ae4aca2ef28d7da4ec95049cc78be43e632d322a # v0.1.0 - with: - include_dev: "false" - sbom_format: "both" - - - name: "Upload SBOM artifacts" - # yamllint disable-line rule:line-length - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 - with: - name: sbom-files-arm64 - path: | - sbom-cyclonedx.json - sbom-cyclonedx.xml - retention-days: 45 - - - name: "Security scan with Grype (SARIF)" - # yamllint disable-line rule:line-length - uses: anchore/scan-action@e1165082ffb1fe366ebaf02d8526e7c4989ea9d2 # v7.4.0 - id: grype-sarif - with: - sbom: "${{ steps.sbom.outputs.sbom_json_path }}" - output-format: "sarif" - output-file: "grype-results.sarif" - fail-build: "true" - - - name: "Security scan with Grype (Text/Table)" - # yamllint disable-line rule:line-length - uses: anchore/scan-action@e1165082ffb1fe366ebaf02d8526e7c4989ea9d2 # v7.4.0 - id: grype-table - if: always() - with: - sbom: "${{ steps.sbom.outputs.sbom_json_path }}" - output-format: "table" - output-file: "grype-results.txt" - fail-build: "false" - - - name: "Upload Grype scan results" - # yamllint disable-line rule:line-length - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 - if: always() - with: - name: grype-scan-results-arm64 - path: | - grype-results.sarif - grype-results.txt - retention-days: 90 - - - name: "Grype summary" - if: always() - run: | - # Grype summary - echo "## Grype Summary (ARM64)" >> "$GITHUB_STEP_SUMMARY" - [ -f grype-results.txt ] && cat grype-results.txt \ - >> "$GITHUB_STEP_SUMMARY" || echo "No scan results available" \ - >> "$GITHUB_STEP_SUMMARY" + # yamllint disable-line rule:line-length + uses: lfreleng-actions/python-workflows/.github/workflows/build-test-multiarch.yaml@4f48e1cd660f94ab9f1d4bbc15a948c1aca105ad # v0.1.1 + with: + # Build NSS/NSPR from source during the python-build step. + make: true + make_args: 'deps-nss env-github-actions' + # Native prerequisites (NSS/NSPR + system test deps) for the test, + # audit and SBOM jobs, plus LD_LIBRARY_PATH / PKG_CONFIG_PATH export. + setup_script: '.github/scripts/setup-nss.sh' diff --git a/.github/workflows/compatibility.yaml b/.github/workflows/compatibility.yaml index b16f6ee..262054e 100644 --- a/.github/workflows/compatibility.yaml +++ b/.github/workflows/compatibility.yaml @@ -51,11 +51,13 @@ jobs: # Testing on the same Fedora release that consumer ships on catches # NSS/Python incompatibilities before they reach that stack. # - # Pinning to a tag (not :latest) also keeps the NSS/Python versions - # the matrix depends on stable and satisfies zizmor's - # unpinned-images audit, while still receiving Fedora's security - # rebuilds (unlike a frozen digest). - container: fedora:44 + # Pinning to a tag (not :latest) keeps the NSS/Python versions the + # matrix depends on stable while still receiving Fedora's security + # rebuilds (unlike a frozen digest). A digest pin would freeze those + # rebuilds out, so zizmor's unpinned-images audit is deliberately + # suppressed here -- this is a CI test container, not a release or + # runtime artefact, so tracking the tag is the intended behaviour. + container: fedora:44 # zizmor: ignore[unpinned-images] strategy: fail-fast: false matrix: @@ -92,6 +94,7 @@ jobs: uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: fetch-depth: 0 # Full history needed for meson dist + persist-credentials: false - name: Install build dependencies in Fedora container env: @@ -197,6 +200,7 @@ jobs: uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: fetch-depth: 0 # Full history needed for meson dist + persist-credentials: false - name: Set up Python ${{ matrix.python-version }} # yamllint disable rule:line-length