Bump PyJWT from 2.12.1 to 2.13.0 (#24074) #4707
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: build ddev | |
| on: | |
| push: | |
| tags: | |
| - ddev-v* | |
| paths: | |
| - ddev/** | |
| branches: | |
| - master | |
| pull_request: | |
| paths: | |
| - .github/workflows/build-ddev.yml | |
| - ddev/** | |
| branches: | |
| - master | |
| schedule: | |
| - cron: 0 0 * * * | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }} | |
| cancel-in-progress: true | |
| defaults: | |
| run: | |
| shell: bash | |
| working-directory: ddev | |
| env: | |
| APP_NAME: ddev | |
| PYTHON_VERSION: "3.13" | |
| # renovate: datasource=pypi depName=pyoxidizer | |
| PYOXIDIZER_VERSION: "0.24.0" | |
| jobs: | |
| define-tags: | |
| name: Define Base Tags | |
| runs-on: ubuntu-latest | |
| defaults: | |
| run: | |
| # No need to checkout the code for this job yet | |
| working-directory: . | |
| outputs: | |
| base_tags: ${{ steps.tags.outputs.base_tags }} | |
| steps: | |
| - id: tags | |
| run: | | |
| context="master" | |
| if [[ "${{ github.event_name }}" == "schedule" ]]; then | |
| context="schedule" | |
| elif [[ "${{ github.event_name }}" == "pull_request" ]]; then | |
| context="pr" | |
| fi | |
| echo "base_tags=team:agent-integrations,service:ddev,context:$context" >> $GITHUB_OUTPUT | |
| python-artifacts: | |
| name: Build wheel and source distribution | |
| runs-on: ubuntu-latest | |
| needs: define-tags | |
| permissions: | |
| # needed for dd-sts | |
| id-token: write | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| fetch-depth: 0 | |
| - name: Get Datadog credentials | |
| id: dd-sts | |
| uses: DataDog/dd-sts-action@2e8187910199bd93129520183c093e19aa585c75 # v1.0.0 | |
| with: | |
| policy: integrations-core-api-key | |
| - name: Tag Job | |
| uses: ./.github/actions/tag-job | |
| if: ${{ github.event.pull_request.head.repo.fork != true }} | |
| with: | |
| tags: '${{ needs.define-tags.outputs.base_tags }},step:build-artifacts' | |
| dd_api_key: ${{ steps.dd-sts.outputs.api_key }} | |
| - name: Install build frontend | |
| run: python -m pip install --upgrade build | |
| - name: Build | |
| run: python -m build | |
| - name: Upload artifacts | |
| uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 | |
| with: | |
| name: python-artifacts | |
| path: ddev/dist/* | |
| if-no-files-found: error | |
| binaries: | |
| name: ${{ matrix.job.target }} (${{ matrix.job.os }}) | |
| needs: | |
| - define-tags | |
| - python-artifacts | |
| runs-on: ${{ matrix.job.os }} | |
| permissions: | |
| # needed for dd-sts | |
| id-token: write | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| job: | |
| # Linux | |
| - target: aarch64-unknown-linux-gnu | |
| os: ubuntu-22.04 | |
| cross: true | |
| - target: x86_64-unknown-linux-gnu | |
| os: ubuntu-22.04 | |
| cross: true | |
| - target: x86_64-unknown-linux-musl | |
| os: ubuntu-22.04 | |
| cross: true | |
| - target: powerpc64le-unknown-linux-gnu | |
| os: ubuntu-22.04 | |
| cross: true | |
| # Windows | |
| - target: x86_64-pc-windows-msvc | |
| os: windows-2022 | |
| - target: i686-pc-windows-msvc | |
| os: windows-2022 | |
| # macOS | |
| - target: aarch64-apple-darwin | |
| os: macos-14 | |
| - target: x86_64-apple-darwin | |
| os: macos-14-large | |
| outputs: | |
| version: ${{ steps.version.outputs.version }} | |
| env: | |
| CARGO: cargo | |
| CARGO_BUILD_TARGET: ${{ matrix.job.target }} | |
| PYAPP_REPO: pyapp | |
| PYAPP_VERSION: "0.24.0" | |
| PYAPP_PIP_EXTERNAL: "1" | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| fetch-depth: 0 | |
| - name: Get Datadog credentials | |
| id: dd-sts | |
| uses: DataDog/dd-sts-action@2e8187910199bd93129520183c093e19aa585c75 # v1.0.0 | |
| with: | |
| policy: integrations-core-api-key | |
| - name: Tag Job | |
| uses: ./.github/actions/tag-job | |
| if: ${{ github.event.pull_request.head.repo.fork != true }} | |
| with: | |
| tags: '${{ needs.define-tags.outputs.base_tags }},step:build-binary,os:${{ matrix.job.os }},target:${{ matrix.job.target }}' | |
| dd_api_key: ${{ steps.dd-sts.outputs.api_key }} | |
| - name: Fetch PyApp | |
| run: >- | |
| mkdir $PYAPP_REPO && curl -L | |
| https://github.com/ofek/pyapp/releases/download/v$PYAPP_VERSION/source.tar.gz | |
| | | |
| tar --strip-components=1 -xzf - -C $PYAPP_REPO | |
| - name: Set up Python ${{ env.PYTHON_VERSION }} | |
| uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 | |
| with: | |
| python-version: ${{ env.PYTHON_VERSION }} | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0 | |
| with: | |
| enable-cache: false | |
| # Both versions pinned for deterministic builds and stable cache reuse. | |
| # | |
| # virtualenv 21.0.0 (2026-02-25) split interpreter discovery out into the | |
| # `python-discovery` package and removed `propose_interpreters` from | |
| # `virtualenv.discovery.builtin`, which older hatch versions monkey-patched | |
| # directly — see https://github.com/pypa/hatch/issues/2193. hatch 1.16.5 | |
| # picks up the fix from https://github.com/pypa/hatch/pull/2196 and now | |
| # *requires* virtualenv>=21, so they must be bumped together. | |
| - name: Install Hatch | |
| run: uv pip install --system "hatch==1.16.5" "virtualenv==21.3.3" | |
| - name: Install Hatch environment collector plugin | |
| run: uv pip install --system -e . --no-deps | |
| - name: Install Rust toolchain | |
| # This action must be pinned to a commit reachable from the master branch — any other commit | |
| # will eventually be garbage-collected and break the workflow. See: | |
| # https://github.com/dtolnay/rust-toolchain#choice-of-full-length-commit-sha | |
| uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9 # master | |
| with: | |
| toolchain: stable | |
| targets: ${{ matrix.job.target }} | |
| - name: Set up cross compiling | |
| if: matrix.job.cross | |
| uses: taiki-e/install-action@d6e286fa45544157a02d45a43742857ebbc25d12 # v2.68.16 | |
| with: | |
| tool: cross | |
| - name: Configure cross compiling | |
| if: matrix.job.cross | |
| run: echo "CARGO=cross" >> $GITHUB_ENV | |
| - name: Configure target | |
| run: |- | |
| config_file="$PYAPP_REPO/.cargo/config_${{ matrix.job.target }}.toml" | |
| if [[ -f "$config_file" ]]; then | |
| mv "$config_file" "$PYAPP_REPO/.cargo/config.toml" | |
| fi | |
| - name: Download Python artifacts | |
| if: ${{ !startsWith(github.event.ref, 'refs/tags') }} | |
| uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.0 | |
| with: | |
| name: python-artifacts | |
| path: ddev/dist | |
| - name: Configure embedded project | |
| if: ${{ !startsWith(github.event.ref, 'refs/tags') }} | |
| run: |- | |
| cd dist | |
| wheel="$(echo *.whl)" | |
| mv "$wheel" "../$PYAPP_REPO" | |
| echo "PYAPP_PROJECT_PATH=$wheel" >> $GITHUB_ENV | |
| - name: Set project version | |
| id: version | |
| run: |- | |
| raw_version="$(hatch version)" | |
| version="${raw_version/dev/}" | |
| echo "raw-version=$raw_version" >> $GITHUB_OUTPUT | |
| echo "version=$version" >> $GITHUB_OUTPUT | |
| echo "$version" | |
| # We cannot use anchors because of https://github.com/actions/runner/issues/1182 and | |
| # other solutions like writing a composite action are burdensome | |
| - name: Set reusable script - Correct binary version | |
| id: script-version | |
| # Windows installers don't accept non-integer versions so we ubiquitously | |
| # perform the following transformation: X.Y.Z.devN -> X.Y.Z.N | |
| run: |- | |
| cat <<"OUTER" >> $GITHUB_OUTPUT | |
| script<<INNER | |
| cd dist/binary | |
| old_binary="$(ls)" | |
| binary="${old_binary/${{ steps.version.outputs.raw-version }}/${{ steps.version.outputs.version }}}" | |
| mv "$old_binary" "$binary" | |
| INNER | |
| OUTER | |
| - name: Set reusable script - Archive binary | |
| id: script-archive | |
| run: |- | |
| cat <<"OUTER" >> $GITHUB_OUTPUT | |
| script<<INNER | |
| mkdir packaging | |
| cd dist/binary | |
| binary="$(ls)" | |
| if [[ "$binary" =~ -pc-windows- ]]; then | |
| 7z a "../../packaging/${binary:0:-4}.zip" "$binary" | |
| else | |
| chmod +x "$binary" | |
| tar -czf "../../packaging/$binary.tar.gz" "$binary" | |
| fi | |
| INNER | |
| OUTER | |
| - name: Build managed binary | |
| env: | |
| PYAPP_SELF_COMMAND: "none" | |
| run: hatch build --target binary | |
| - name: Correct binary version | |
| if: steps.version.outputs.version != steps.version.outputs.raw-version | |
| run: ${{ steps.script-version.outputs.script }} | |
| - name: Archive binary | |
| run: ${{ steps.script-archive.outputs.script }} | |
| - name: Upload staged managed archive | |
| if: runner.os != 'Linux' | |
| uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 | |
| with: | |
| name: staged-managed-${{ runner.os }}-${{ matrix.job.target }} | |
| path: ddev/packaging/* | |
| if-no-files-found: error | |
| - name: Reset artifact directories | |
| run: rm -rf dist/binary packaging | |
| - name: Build standalone binary | |
| run: hatch build --target binary | |
| - name: Correct binary version | |
| if: steps.version.outputs.version != steps.version.outputs.raw-version | |
| run: ${{ steps.script-version.outputs.script }} | |
| - name: Archive binary | |
| run: ${{ steps.script-archive.outputs.script }} | |
| - name: Upload staged standalone archive | |
| if: runner.os != 'Linux' | |
| uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 | |
| with: | |
| name: staged-standalone-${{ runner.os }}-${{ matrix.job.target }} | |
| path: ddev/packaging/* | |
| if-no-files-found: error | |
| # There are no installers nor extra steps like signing for Linux so we | |
| # can upload directly at this point | |
| - name: Upload standalone archive | |
| if: runner.os == 'Linux' | |
| uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 | |
| with: | |
| name: standalone-${{ matrix.job.target }} | |
| path: ddev/packaging/* | |
| if-no-files-found: error | |
| windows-packaging: | |
| name: Build Windows installers | |
| if: github.event_name == 'push' || github.event_name == 'schedule' || github.event.pull_request.head.repo.full_name == github.repository | |
| needs: | |
| - define-tags | |
| - binaries | |
| runs-on: windows-2022 | |
| permissions: | |
| # needed for dd-sts | |
| id-token: write | |
| env: | |
| VERSION: ${{ needs.binaries.outputs.version }} | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| - name: Get Datadog credentials | |
| id: dd-sts | |
| uses: DataDog/dd-sts-action@2e8187910199bd93129520183c093e19aa585c75 # v1.0.0 | |
| with: | |
| policy: integrations-core-api-key | |
| - name: Tag Job | |
| uses: ./.github/actions/tag-job | |
| if: ${{ github.event.pull_request.head.repo.fork != true }} | |
| with: | |
| tags: '${{ needs.define-tags.outputs.base_tags }},step:package-windows,os:windows' | |
| dd_api_key: ${{ steps.dd-sts.outputs.api_key }} | |
| - name: Set up Python ${{ env.PYTHON_VERSION }} | |
| uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 | |
| with: | |
| python-version: ${{ env.PYTHON_VERSION }} | |
| - name: Install PyOxidizer ${{ env.PYOXIDIZER_VERSION }} | |
| run: pip install pyoxidizer==${{ env.PYOXIDIZER_VERSION }} | |
| # We cannot use anchors because of https://github.com/actions/runner/issues/1182 and | |
| # other solutions like writing a composite action are burdensome | |
| - name: Set reusable script - Extract binaries | |
| id: script-extract | |
| run: |- | |
| cat <<"OUTER" >> $GITHUB_OUTPUT | |
| script<<INNER | |
| mkdir bin | |
| for f in archives/*; do | |
| 7z e "$f" -obin | |
| done | |
| INNER | |
| OUTER | |
| - name: Set reusable script - Prepare binaries | |
| id: script-prepare | |
| # bin/<APP_NAME>-<VERSION>-<TARGET>.exe -> targets/<TARGET>/<APP_NAME>.exe | |
| run: |- | |
| cat <<"OUTER" >> $GITHUB_OUTPUT | |
| script<<INNER | |
| mkdir targets | |
| for f in bin/*; do | |
| if [[ "$f" =~ ${{ env.VERSION }}-(.+).exe$ ]]; then | |
| target="${BASH_REMATCH[1]}" | |
| mkdir "targets/$target" | |
| mv "$f" "targets/$target/${{ env.APP_NAME }}.exe" | |
| fi | |
| done | |
| INNER | |
| OUTER | |
| - name: Download staged standalone binaries | |
| uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.0 | |
| with: | |
| pattern: staged-standalone-${{ runner.os }}-* | |
| path: ddev/archives | |
| merge-multiple: true | |
| - name: Extract staged standalone binaries | |
| run: ${{ steps.script-extract.outputs.script }} | |
| - name: Prepare standalone binaries | |
| run: ${{ steps.script-prepare.outputs.script }} | |
| - name: Upload standalone binaries | |
| uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 | |
| with: | |
| name: standalone-${{ matrix.job.target }} | |
| path: ddev/archives/* | |
| if-no-files-found: error | |
| - name: Reset artifact directories | |
| run: rm -rf archives bin targets | |
| - name: Download staged managed binaries | |
| uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.0 | |
| with: | |
| pattern: staged-managed-${{ runner.os }}-* | |
| path: ddev/archives | |
| merge-multiple: true | |
| - name: Extract staged managed binaries | |
| run: ${{ steps.script-extract.outputs.script }} | |
| - name: Prepare managed binaries | |
| run: ${{ steps.script-prepare.outputs.script }} | |
| - name: Build installers | |
| run: >- | |
| pyoxidizer build windows_installers | |
| --release | |
| --var version ${{ env.VERSION }} | |
| - name: Prepare installers | |
| run: |- | |
| mkdir installers | |
| mv build/*/release/*/*.{exe,msi} installers | |
| - name: Upload installers | |
| if: github.event_name == 'schedule' || (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')) | |
| uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 | |
| with: | |
| name: installers-${{ runner.os }} | |
| path: ddev/installers/* | |
| if-no-files-found: error | |
| test-macos-build: | |
| name: Test macOS packaging | |
| if: (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository) || (github.event_name == 'push' && github.ref == 'refs/heads/master') | |
| needs: | |
| - define-tags | |
| - binaries | |
| runs-on: macos-14-large | |
| permissions: | |
| # needed for dd-sts | |
| id-token: write | |
| env: | |
| VERSION: ${{ needs.binaries.outputs.version }} | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| - name: Get Datadog credentials | |
| id: dd-sts | |
| uses: DataDog/dd-sts-action@2e8187910199bd93129520183c093e19aa585c75 # v1.0.0 | |
| with: | |
| policy: integrations-core-api-key | |
| - name: Tag Job | |
| uses: ./.github/actions/tag-job | |
| if: ${{ github.event.pull_request.head.repo.fork != true }} | |
| with: | |
| tags: '${{ needs.define-tags.outputs.base_tags }},step:test-package-macos,os:macos' | |
| dd_api_key: ${{ steps.dd-sts.outputs.api_key }} | |
| - name: Set up Python ${{ env.PYTHON_VERSION }} | |
| uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 | |
| with: | |
| python-version: ${{ env.PYTHON_VERSION }} | |
| - name: Install PyOxidizer ${{ env.PYOXIDIZER_VERSION }} | |
| run: pip install pyoxidizer==${{ env.PYOXIDIZER_VERSION }} | |
| - name: Download staged managed binaries | |
| uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.0 | |
| with: | |
| pattern: staged-managed-${{ runner.os }}-* | |
| path: ddev/archives | |
| merge-multiple: true | |
| - name: Extract staged managed binaries | |
| run: |- | |
| mkdir bin | |
| for f in archives/*; do | |
| tar -xzf "$f" -C bin | |
| done | |
| # bin/<APP_NAME>-<VERSION>-<TARGET> -> targets/<TARGET>/<APP_NAME> | |
| - name: Prepare managed binaries | |
| run: |- | |
| mkdir targets | |
| for f in bin/*; do | |
| if [[ "$f" =~ ${{ env.VERSION }}-(.+)$ ]]; then | |
| target="${BASH_REMATCH[1]}" | |
| mkdir "targets/$target" | |
| mv "$f" "targets/$target/${{ env.APP_NAME }}" | |
| fi | |
| done | |
| - name: Build universal binary | |
| run: >- | |
| pyoxidizer build macos_universal_binary | |
| --release | |
| --var version ${{ env.VERSION }} | |
| - name: Prepare universal binary | |
| id: binary | |
| run: |- | |
| binary=$(echo build/*/release/*/${{ env.APP_NAME }}) | |
| chmod +x "$binary" | |
| echo "path=$binary" >> "$GITHUB_OUTPUT" | |
| - name: Build PKG | |
| run: >- | |
| python release/macos/build_pkg.py | |
| --binary ${{ steps.binary.outputs.path }} | |
| --version ${{ env.VERSION }} | |
| staged | |
| - name: Verify PKG was produced | |
| run: ls staged/*.pkg | |
| macos-packaging: | |
| name: Build macOS installer and sign/notarize artifacts | |
| if: (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')) || github.event_name == 'schedule' | |
| needs: | |
| - define-tags | |
| - binaries | |
| runs-on: macos-14-large | |
| environment: ddev-sign-upload | |
| permissions: | |
| # needed for dd-sts | |
| id-token: write | |
| env: | |
| VERSION: ${{ needs.binaries.outputs.version }} | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| - name: Get Datadog credentials | |
| id: dd-sts | |
| uses: DataDog/dd-sts-action@2e8187910199bd93129520183c093e19aa585c75 # v1.0.0 | |
| with: | |
| policy: integrations-core-api-key | |
| - name: Tag Job | |
| uses: ./.github/actions/tag-job | |
| if: ${{ github.event.pull_request.head.repo.fork != true }} | |
| with: | |
| tags: '${{ needs.define-tags.outputs.base_tags }},step:package-macos,os:macos' | |
| dd_api_key: ${{ steps.dd-sts.outputs.api_key }} | |
| - name: Set up Python ${{ env.PYTHON_VERSION }} | |
| uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 | |
| with: | |
| python-version: ${{ env.PYTHON_VERSION }} | |
| - name: Install PyOxidizer ${{ env.PYOXIDIZER_VERSION }} | |
| run: pip install pyoxidizer==${{ env.PYOXIDIZER_VERSION }} | |
| - name: Install rcodesign | |
| env: | |
| ARCHIVE_NAME: "apple-codesign-0.27.0-x86_64-apple-darwin" | |
| run: >- | |
| curl -L | |
| "https://github.com/indygreg/apple-platform-rs/releases/download/apple-codesign%2F0.27.0/$ARCHIVE_NAME.tar.gz" | |
| | | |
| tar --strip-components=1 -xzf - -C /usr/local/bin "$ARCHIVE_NAME/rcodesign" | |
| - name: Write credentials | |
| env: | |
| APPLE_DEVELOPER_ID_APPLICATION_CERTIFICATE: "${{ secrets.APPLE_DEVELOPER_ID_APPLICATION_CERTIFICATE }}" | |
| APPLE_DEVELOPER_ID_APPLICATION_PRIVATE_KEY: "${{ secrets.APPLE_DEVELOPER_ID_APPLICATION_PRIVATE_KEY }}" | |
| APPLE_DEVELOPER_ID_INSTALLER_CERTIFICATE: "${{ secrets.APPLE_DEVELOPER_ID_INSTALLER_CERTIFICATE }}" | |
| APPLE_DEVELOPER_ID_INSTALLER_PRIVATE_KEY: "${{ secrets.APPLE_DEVELOPER_ID_INSTALLER_PRIVATE_KEY }}" | |
| APPLE_APP_STORE_CONNECT_API_DATA: "${{ secrets.APPLE_APP_STORE_CONNECT_API_DATA }}" | |
| run: |- | |
| echo "$APPLE_DEVELOPER_ID_APPLICATION_CERTIFICATE" > /tmp/certificate-application.pem | |
| echo "$APPLE_DEVELOPER_ID_APPLICATION_PRIVATE_KEY" > /tmp/private-key-application.pem | |
| echo "$APPLE_DEVELOPER_ID_INSTALLER_CERTIFICATE" > /tmp/certificate-installer.pem | |
| echo "$APPLE_DEVELOPER_ID_INSTALLER_PRIVATE_KEY" > /tmp/private-key-installer.pem | |
| echo "$APPLE_APP_STORE_CONNECT_API_DATA" > /tmp/app-store-connect.json | |
| # We cannot use anchors because of https://github.com/actions/runner/issues/1182 and | |
| # other solutions like writing a composite action are burdensome | |
| - name: Set reusable script - Extract binaries | |
| id: script-extract | |
| run: |- | |
| cat <<"OUTER" >> $GITHUB_OUTPUT | |
| script<<INNER | |
| mkdir bin | |
| for f in archives/*; do | |
| tar -xzf "$f" -C bin | |
| done | |
| INNER | |
| OUTER | |
| - name: Set reusable script - Sign binaries | |
| id: script-sign | |
| # https://developer.apple.com/documentation/security/hardened_runtime | |
| run: |- | |
| cat <<"OUTER" >> $GITHUB_OUTPUT | |
| script<<INNER | |
| for f in bin/*; do | |
| rcodesign sign -vv \ | |
| --pem-source /tmp/certificate-application.pem \ | |
| --pem-source /tmp/private-key-application.pem \ | |
| --code-signature-flags runtime \ | |
| "$f" | |
| done | |
| INNER | |
| OUTER | |
| - name: Set reusable script - Notarize binaries | |
| id: script-notarize | |
| # https://developer.apple.com/documentation/security/notarizing_macos_software_before_distribution | |
| # We pass the --wait flag to catch problems with signing sooner at the cost of slowing down the job a little bit. | |
| run: |- | |
| cat <<"OUTER" >> $GITHUB_OUTPUT | |
| script<<INNER | |
| mkdir notarize-bin | |
| cd bin | |
| for f in *; do | |
| zip "../notarize-bin/$f.zip" "$f" | |
| done | |
| cd ../notarize-bin | |
| for f in *; do | |
| rcodesign notary-submit -vv \ | |
| --wait \ | |
| --api-key-path /tmp/app-store-connect.json \ | |
| "$f" | |
| done | |
| INNER | |
| OUTER | |
| - name: Download staged standalone binaries | |
| uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.0 | |
| with: | |
| pattern: staged-standalone-${{ runner.os }}-* | |
| path: ddev/archives | |
| merge-multiple: true | |
| - name: Extract staged standalone binaries | |
| run: ${{ steps.script-extract.outputs.script }} | |
| - name: Sign standalone binaries | |
| run: ${{ steps.script-sign.outputs.script }} | |
| - name: Notarize standalone binaries | |
| run: ${{ steps.script-notarize.outputs.script }} | |
| - name: Archive standalone binaries | |
| run: |- | |
| rm archives/* | |
| cd bin | |
| for f in *; do | |
| tar -czf "../archives/$f.tar.gz" "$f" | |
| done | |
| - name: Upload standalone binaries | |
| uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 | |
| with: | |
| name: standalone-${{ runner.os }} | |
| path: ddev/archives/* | |
| if-no-files-found: error | |
| - name: Reset artifact directories | |
| run: rm -rf archives bin notarize-bin | |
| - name: Download staged managed binaries | |
| uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.0 | |
| with: | |
| pattern: staged-managed-${{ runner.os }}-* | |
| path: ddev/archives | |
| merge-multiple: true | |
| - name: Extract staged managed binaries | |
| run: ${{ steps.script-extract.outputs.script }} | |
| - name: Sign managed binaries | |
| run: ${{ steps.script-sign.outputs.script }} | |
| - name: Notarize managed binaries | |
| run: ${{ steps.script-notarize.outputs.script }} | |
| # bin/<APP_NAME>-<VERSION>-<TARGET> -> targets/<TARGET>/<APP_NAME> | |
| - name: Prepare managed binaries | |
| run: |- | |
| mkdir targets | |
| for f in bin/*; do | |
| if [[ "$f" =~ ${{ env.VERSION }}-(.+)$ ]]; then | |
| target="${BASH_REMATCH[1]}" | |
| mkdir "targets/$target" | |
| mv "$f" "targets/$target/${{ env.APP_NAME }}" | |
| fi | |
| done | |
| - name: Build universal binary | |
| run: >- | |
| pyoxidizer build macos_universal_binary | |
| --release | |
| --var version ${{ env.VERSION }} | |
| - name: Prepare universal binary | |
| id: binary | |
| run: |- | |
| binary=$(echo build/*/release/*/${{ env.APP_NAME }}) | |
| chmod +x "$binary" | |
| echo "path=$binary" >> "$GITHUB_OUTPUT" | |
| - name: Build PKG | |
| run: >- | |
| python release/macos/build_pkg.py | |
| --binary ${{ steps.binary.outputs.path }} | |
| --version ${{ env.VERSION }} | |
| staged | |
| - name: Stage PKG | |
| id: pkg | |
| run: |- | |
| mkdir signed | |
| pkg_file="$(ls staged)" | |
| echo "path=$pkg_file" >> "$GITHUB_OUTPUT" | |
| - name: Sign PKG | |
| run: >- | |
| rcodesign sign -vv | |
| --pem-source /tmp/certificate-installer.pem | |
| --pem-source /tmp/private-key-installer.pem | |
| "staged/${{ steps.pkg.outputs.path }}" | |
| "signed/${{ steps.pkg.outputs.path }}" | |
| - name: Notarize PKG | |
| run: >- | |
| rcodesign notary-submit | |
| --api-key-path /tmp/app-store-connect.json | |
| --staple | |
| "signed/${{ steps.pkg.outputs.path }}" | |
| - name: Upload installer | |
| uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 | |
| with: | |
| name: installers-${{ runner.os }} | |
| path: ddev/signed/${{ steps.pkg.outputs.path }} | |
| if-no-files-found: error | |
| # Extraction runs in its own unprivileged job so the dependency-resolving install of | |
| # ddev never executes inside the privileged publish job (which holds contents: write | |
| # and id-token: write). A compromised transitive dep can still execute here, but it | |
| # has no access to release credentials and cannot tamper with archives/installers. | |
| extract-release-notes: | |
| name: Extract release notes | |
| if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags') | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| # Extraction is best-effort end-to-end: any failure in setup, install, configure, | |
| # or the extraction itself must not block the release. We pre-create an empty | |
| # release-notes.md, run the install/extract steps with continue-on-error so they | |
| # never fail the job, and always upload the artifact. The publish job can rely on | |
| # extract-release-notes succeeding; the body it consumes may be empty. | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| - name: Initialize empty release notes | |
| working-directory: . | |
| run: ': > release-notes.md' | |
| - name: Set up Python ${{ env.PYTHON_VERSION }} | |
| uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 | |
| continue-on-error: true | |
| with: | |
| python-version: "${{ env.PYTHON_VERSION }}" | |
| - name: Install ddev from local folder | |
| continue-on-error: true | |
| uses: ./.github/actions/setup-ddev | |
| with: | |
| install-mode: local | |
| cache-profile: local-ddev-base | |
| - name: Configure ddev | |
| continue-on-error: true | |
| working-directory: . | |
| run: |- | |
| ddev config override | |
| ddev config set upgrade_check false | |
| - name: Extract release notes from CHANGELOG | |
| continue-on-error: true | |
| working-directory: . | |
| run: | | |
| version="${GITHUB_REF_NAME#ddev-v}" | |
| if ! ddev release changelog show ddev "$version" --file release-notes.md; then | |
| echo "::warning::Failed to extract changelog section for ddev $version; release body will be empty." | |
| : > release-notes.md | |
| fi | |
| - name: Upload release notes | |
| if: always() | |
| uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 | |
| with: | |
| name: release-notes | |
| path: release-notes.md | |
| if-no-files-found: error | |
| publish: | |
| name: Publish release | |
| if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags') | |
| needs: | |
| - define-tags | |
| - python-artifacts | |
| - binaries | |
| - windows-packaging | |
| - macos-packaging | |
| - extract-release-notes | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| id-token: write | |
| environment: pypi-ddev | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| - name: Get Datadog credentials | |
| id: dd-sts | |
| uses: DataDog/dd-sts-action@2e8187910199bd93129520183c093e19aa585c75 # v1.0.0 | |
| with: | |
| policy: integrations-core-api-key | |
| - name: Tag Job | |
| uses: ./.github/actions/tag-job | |
| if: ${{ github.event.pull_request.head.repo.fork != true }} | |
| with: | |
| tags: '${{ needs.define-tags.outputs.base_tags }},step:publish' | |
| dd_api_key: ${{ steps.dd-sts.outputs.api_key }} | |
| - name: Download Python artifacts | |
| uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.0 | |
| with: | |
| name: python-artifacts | |
| path: dist | |
| - name: Download binaries | |
| uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.0 | |
| with: | |
| pattern: standalone* | |
| path: archives | |
| merge-multiple: true | |
| - name: Download installers | |
| uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.0 | |
| with: | |
| pattern: installers-* | |
| path: installers | |
| merge-multiple: true | |
| # Downloaded by exact name (not pattern) so this step cannot pull in artifacts | |
| # uploaded by other jobs. | |
| - name: Download release notes | |
| uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.0 | |
| with: | |
| name: release-notes | |
| path: release-notes | |
| # Publish wheels to PyPI using Trusted Publishers. | |
| # https://docs.pypi.org/trusted-publishers/using-a-publisher/ | |
| # This job needs to run from within the pypi-ddev environment. PyPi validates the | |
| # workflow file name, environment and repository the request is comming from to | |
| # provide the valid JWT token. | |
| - name: Push Python artifacts to PyPI | |
| uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0 | |
| with: | |
| skip-existing: true | |
| - name: Add assets to current release | |
| uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b # v2.5.0 | |
| with: | |
| body_path: release-notes/release-notes.md | |
| files: |- | |
| archives/* | |
| installers/* |