diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6c6733bc..8393d18a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,7 +7,7 @@ on: - main concurrency: - group: ${{ github.ref }} + group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true defaults: @@ -161,29 +161,30 @@ jobs: needs: pre-commit uses: ./.github/workflows/python-package-create.yml with: - repository: beeware/${{ matrix.repo }} - tox-source: ${{ matrix.tox-source }} - tox-factors: ${{ matrix.tox-factors }} - distribution-path: ${{ matrix.dist-path }} + repository: beeware/${{ matrix.repo || matrix.name }} build-subdirectory: ${{ matrix.build-subdir }} + attest: ${{ matrix.attest || 'false' }} strategy: fail-fast: false matrix: - repo: [ briefcase, gbulb, rubicon-objc, toga ] + name: + - beeware + - briefcase + - gbulb + - rubicon-objc + - toga + - toga-android + - toga-chart + - travertino include: - - tox-source: .[dev] - - dist-path: dist - - repo: briefcase - tox-source: .[dev] - tox-factors: -with-automation - dist-path: dist - - repo: gbulb - tox-source: tox - dist-path: dist - - repo: toga - tox-source: ./core[dev] - dist-path: "*/dist/*" + - name: briefcase + attest: "true" + - name: toga build-subdir: core + attest: "true" + - name: toga-android + repo: toga + build-subdir: android test-verify-projects-briefcase: name: Verify Project diff --git a/.github/workflows/python-package-create.yml b/.github/workflows/python-package-create.yml index 5147069c..022ae6e3 100644 --- a/.github/workflows/python-package-create.yml +++ b/.github/workflows/python-package-create.yml @@ -1,49 +1,27 @@ name: Create Python Package ####### -# Creates a Python package via `tox -e package` and uploads it as an artifact named 'packages-'. +# Creates a Python package for an arbitrary repository and subdirectory with optional attestation. ####### on: workflow_call: inputs: - python-version: - description: "Python version to use; defaults to latest Python release." - default: "3.X" - type: string repository: description: "GitHub repository to checkout; defaults to repo running this workflow." default: ${{ github.repository }} type: string - tox-source: - description: "The arguments for `pip install` to install tox; use ./path/to/package[dev] for the repo's pinned version." - default: ".[dev]" - type: string - tox-factors: - description: "The tox factors to append to the package command." - default: "" - type: string build-subdirectory: description: "The subdirectory to build as a wheel." default: "" type: string - distribution-path: - description: "Relative filepath to distribution(s); e.g. */dist/*" - default: "dist" - type: string - runner-os: - description: "Runner OS to use to run tox; defaults to ubuntu-latest" - default: "ubuntu-latest" + attest: + description: "Whether provenance attestation should be created by GitHub for the package." + default: "false" type: string outputs: artifact-name: - description: > - Name of the uploaded artifact; use for artifact retrieval. - Note that if a `build-subdirectory` is specified, this value will be the "base" of the artifact name. - For instance, if the `core` subdirectory of Toga is being built, then this value will be `packages-toga` - but the name of the uploaded artifact will be `packages-toga-core`. - Therefore, when a `build-subdirectory` is used with this workflow, the `pattern` input for the - `actions\download-artifact` should be used to specify `${ needs.package.outputs.artifact-name }-*`. + description: "Name of the uploaded artifact; use for artifact retrieval." value: ${{ jobs.package.outputs.artifact-name }} env: @@ -52,14 +30,20 @@ env: jobs: package: name: Create Python Package - runs-on: ${{ inputs.runner-os }} + runs-on: ubuntu-latest + permissions: + id-token: write + contents: read + attestations: write outputs: - artifact-name: packages-${{ steps.package.outputs.name }} + artifact-name: ${{ steps.package.outputs.artifact-name }} steps: - name: Determine Package Name - id: package - run: echo "name=$(basename '${{ inputs.repository }}')" >> ${GITHUB_OUTPUT} + id: config + run: | + NAME=$(basename '${{ inputs.repository }}')${{ inputs.build-subdirectory && format('-{0}', inputs.build-subdirectory) || '' }} + echo "package-name=${NAME}" | tee -a ${GITHUB_OUTPUT} - name: Checkout uses: actions/checkout@v4.1.6 @@ -67,32 +51,10 @@ jobs: repository: ${{ inputs.repository }} fetch-depth: 0 # Fetch all refs so setuptools_scm can generate the correct version number - - name: Setup Python - uses: actions/setup-python@v5.1.0 - with: - python-version: ${{ inputs.python-version }} - cache: pip - cache-dependency-path: | - **/setup.cfg - **/pyproject.toml - - - name: Update pip - run: python -m pip install -U pip - - - name: Install tox - run: python -m pip install ${{ inputs.tox-source }} - - - name: Build Wheels - if: inputs.build-subdirectory == '' - run: tox -e package${{ inputs.tox-factors }} - - - name: Build Wheels from Subdirectory - if: inputs.build-subdirectory != '' - run: tox -e package${{ inputs.tox-factors }} -- ${{ inputs.build-subdirectory }} - - - name: Upload Package - uses: actions/upload-artifact@v4.3.3 + - name: Build & Upload Package + id: package + uses: hynek/build-and-inspect-python-package@v2.6.0 with: - name: packages-${{ steps.package.outputs.name }}${{ inputs.build-subdirectory && format('-{0}', inputs.build-subdirectory) || '' }} - path: ${{ inputs.distribution-path }} - if-no-files-found: error + path: ${{ inputs.build-subdirectory || '.' }} + upload-name-suffix: ${{ format('-{0}', steps.config.outputs.package-name) }} + attest-build-provenance-github: ${{ inputs.attest }}