diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 7a97743..b299420 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,18 +1,32 @@ version: 2 updates: -- package-ecosystem: "pip" - directory: "/" - schedule: - interval: "weekly" - groups: - python: - patterns: - - "*" -- package-ecosystem: "cargo" - directory: "/" - schedule: - interval: "weekly" - groups: - rust: - patterns: - - "*" + - package-ecosystem: "pip" + directory: "/" + schedule: + interval: "monthly" + cooldown: + default-days: 14 + groups: + python: + patterns: + - "*" + - package-ecosystem: "cargo" + directory: "/" + schedule: + interval: "monthly" + cooldown: + default-days: 14 + groups: + rust: + patterns: + - "*" + - package-ecosystem: "github-actions" + directory: ".github/workflows" + schedule: + interval: "monthly" + cooldown: + default-days: 14 + groups: + actions: + patterns: + - "*" diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 5630ba4..ccf2ab8 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -12,13 +12,17 @@ concurrency: env: FORCE_COLOR: 1 +permissions: {} + jobs: check: runs-on: "ubuntu-latest" name: "check" steps: - - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false + - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 with: python-version: "3.12" diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 3b70b5f..3abc7bc 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -12,25 +12,32 @@ concurrency: env: FORCE_COLOR: 1 +permissions: {} + jobs: - pythonbuild: - if: ${{ needs.generate-matrix.outputs.pythonbuild_changed == 'true' || needs.generate-matrix.outputs.any_builds == 'true' || github.ref == 'refs/heads/main' }} + crate-build: needs: - generate-matrix - runs-on: depot-ubuntu-22.04 + runs-on: ${{ matrix.runner }} + strategy: + matrix: ${{ fromJson(needs.generate-matrix.outputs.crate-build-matrix) }} + fail-fast: false + name: crate / ${{ matrix.arch }} steps: - name: Install System Dependencies run: | sudo apt update sudo apt install -y --no-install-recommends libssl-dev pkg-config - - uses: actions/checkout@v4 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false - name: Emit rustc version run: | rustc --version > .rustc-version - - uses: actions/cache@v4 + - uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4 with: path: | ~/.cargo/registry @@ -43,9 +50,9 @@ jobs: cargo build --release - name: Upload pythonbuild Executable - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: - name: pythonbuild + name: ${{ matrix.crate_artifact_name }} path: target/release/pythonbuild image: @@ -54,29 +61,26 @@ jobs: - generate-matrix strategy: fail-fast: false - matrix: - image: - - build - - build.cross - - build.cross-riscv64 - - gcc - name: ${{ matrix.image }} - runs-on: depot-ubuntu-22.04 + matrix: ${{ fromJson(needs.generate-matrix.outputs.docker-build-matrix) }} + name: image / ${{ matrix.arch }} / ${{ matrix.name }} + runs-on: ${{ matrix.runner }} permissions: packages: write steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false - name: Install Python - uses: actions/setup-python@v5 + uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 with: - python-version: '3.11' + python-version: "3.11" - name: Set up Docker Buildx - uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3 + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 - name: Login to GitHub Container Registry - uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3 + uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0 with: registry: ghcr.io username: ${{ github.actor }} @@ -92,96 +96,114 @@ jobs: - name: Build Image id: build-image - uses: docker/build-push-action@v5 + uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 + env: + SOURCE_DATE_EPOCH: 0 with: context: . - file: build/${{ matrix.image }}.Dockerfile + file: build/${{ matrix.name }}.Dockerfile labels: org.opencontainers.image.source=https://github.com/${{ env.REPO_NAME }} # Cache from/to the current branch of the current repo as the primary cache key. # Cache from the default branch of the current repo so branches can have cache hits. # Cache from the default branch of the canonical repo so forks can have cache hits. # Ignore errors on cache writes so CI of forks works without a valid GHCR config. cache-from: | - type=registry,ref=ghcr.io/${{ env.REPO_NAME }}:${{ matrix.image }}-${{ env.GIT_REF_NAME }} - type=registry,ref=ghcr.io/${{ env.REPO_NAME }}:${{ matrix.image }}-main - type=registry,ref=ghcr.io/astral-sh/python-build-standalone:${{ matrix.image }}-main + type=registry,ref=ghcr.io/${{ env.REPO_NAME }}:${{ matrix.name }}-linux_${{ matrix.arch }}-${{ env.GIT_REF_NAME }} + type=registry,ref=ghcr.io/${{ env.REPO_NAME }}:${{ matrix.name }}-linux_${{ matrix.arch }}-main + type=registry,ref=ghcr.io/astral-sh/python-build-standalone:${{ matrix.name }}-linux_${{ matrix.arch }}-main cache-to: | - type=registry,ref=ghcr.io/${{ env.REPO_NAME }}:${{ matrix.image }}-${{ env.GIT_REF_NAME }},ignore-error=true + type=registry,ref=ghcr.io/${{ env.REPO_NAME }}:${{ matrix.name }}-linux_${{ matrix.arch }}-${{ env.GIT_REF_NAME }},ignore-error=true outputs: | - type=docker,dest=build/image-${{ matrix.image }}.tar + type=docker,dest=build/image-${{ matrix.name }}.linux_${{ matrix.arch }}.tar - name: Compress Image run: | - echo ${{ steps.build-image.outputs.imageid }} > build/image-${{ matrix.image }} + echo ${STEPS_BUILD_IMAGE_OUTPUTS_IMAGEID} > build/image-${MATRIX_NAME}.linux_${MATRIX_ARCH} zstd -v -T0 -6 --rm build/image-*.tar + touch -t 197001010000 build/image-* + env: + STEPS_BUILD_IMAGE_OUTPUTS_IMAGEID: ${{ steps.build-image.outputs.imageid }} + MATRIX_NAME: ${{ matrix.name }} + MATRIX_ARCH: ${{ matrix.arch }} - name: Upload Docker Image - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: - name: image-${{ matrix.image }} + name: image-${{ matrix.name }}-linux_${{ matrix.arch }} path: build/image-* + compression-level: '0' generate-matrix: + name: Generate build matrix runs-on: ubuntu-latest outputs: - matrix-0: ${{ steps.set-matrix.outputs.matrix-0 }} - matrix-1: ${{ steps.set-matrix.outputs.matrix-1 }} + python-build-matrix-0: ${{ steps.set-matrix.outputs.python-build-matrix-0 }} + python-build-matrix-1: ${{ steps.set-matrix.outputs.python-build-matrix-1 }} + docker-build-matrix: ${{ steps.set-matrix.outputs.docker-build-matrix }} + crate-build-matrix: ${{ steps.set-matrix.outputs.crate-build-matrix }} any_builds: ${{ steps.set-matrix.outputs.any_builds }} - pythonbuild_changed: ${{ steps.check-pythonbuild.outputs.changed }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: - fetch-depth: 0 # fetch history for subsequent `git diff` + fetch-depth: 0 + persist-credentials: false - name: Set up Python - uses: astral-sh/setup-uv@v4 + uses: astral-sh/setup-uv@38f3f104447c67c051c4a08e39b64a148898af3a # v4.2.0 - name: Get pull request labels id: get-labels + env: + PULL_REQUEST_LABELS: ${{ toJson(github.event.pull_request.labels.*.name) }} run: | # Convert GitHub labels array to comma-separated string - LABELS=$(echo '${{ toJson(github.event.pull_request.labels.*.name) }}' | jq -r 'join(",")') + LABELS=$(echo "${PULL_REQUEST_LABELS}" | jq -r 'join(",")') echo "labels=$LABELS" >> $GITHUB_OUTPUT + - name: Check if the `pythonbuild` crate changed + id: check-pythonbuild + env: + BASE_REF: ${{ github.event.pull_request.base.ref || 'main' }} + run: | + merge_base=$(git merge-base HEAD "origin/${BASE_REF}") + if git diff --quiet "${merge_base}...HEAD" -- ':src/*.rs'; then + echo "changed=false" >> "$GITHUB_OUTPUT" + else + echo "changed=true" >> "$GITHUB_OUTPUT" + fi + - name: Generate build matrix id: set-matrix run: | uv run ci-matrix.py \ --platform linux \ - --labels '${{ steps.get-labels.outputs.labels }}' \ + --labels "${STEPS_GET_LABELS_OUTPUTS_LABELS}" \ --max-shards 2 \ + ${{ (steps.check-pythonbuild.outputs.changed == 'true' || github.ref == 'refs/heads/main') && '--force-crate-build' || '' }} \ > matrix.json - echo "matrix-0=$(jq -c '.["0"]' matrix.json)" >> $GITHUB_OUTPUT - echo "matrix-1=$(jq -c '.["1"]' matrix.json)" >> $GITHUB_OUTPUT + echo "python-build-matrix-0=$(jq -c '."python-build"["0"]' matrix.json)" >> $GITHUB_OUTPUT + echo "python-build-matrix-1=$(jq -c '."python-build"["1"]' matrix.json)" >> $GITHUB_OUTPUT + echo "docker-build-matrix=$(jq -c '."docker-build"' matrix.json)" >> $GITHUB_OUTPUT + echo "crate-build-matrix=$(jq -c '."crate-build"' matrix.json)" >> $GITHUB_OUTPUT # Display the matrix for debugging too cat matrix.json | jq - if jq -e '.["0"].include | length > 0' matrix.json > /dev/null; then + if jq -e '."python-build"["0"].include | length > 0' matrix.json > /dev/null; then # Build matrix has entries echo "any_builds=true" >> $GITHUB_OUTPUT else # Build matrix is empty echo "any_builds=false" >> $GITHUB_OUTPUT fi - - - name: Check if the `pythonbuild` crate changed - id: check-pythonbuild env: - BASE_REF: ${{ github.event.pull_request.base.ref || 'main' }} - run: | - merge_base=$(git merge-base HEAD "origin/${BASE_REF}") - if git diff --quiet "${merge_base}...HEAD" -- ':src/*.rs'; then - echo "changed=false" >> "$GITHUB_OUTPUT" - else - echo "changed=true" >> "$GITHUB_OUTPUT" - fi + STEPS_GET_LABELS_OUTPUTS_LABELS: ${{ steps.get-labels.outputs.labels }} build-0: needs: - generate-matrix - - pythonbuild + - crate-build - image # Permissions used for actions/attest-build-provenance permissions: @@ -189,34 +211,35 @@ jobs: attestations: write runs-on: ${{ matrix.runner }} strategy: - matrix: ${{ fromJson(needs.generate-matrix.outputs.matrix-0) }} + matrix: ${{ fromJson(needs.generate-matrix.outputs.python-build-matrix-0) }} fail-fast: false name: ${{ matrix.target_triple }} / ${{ matrix.python }} / ${{ matrix.build_options }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: fetch-depth: 0 + persist-credentials: false - name: Install Python - uses: actions/setup-python@v5 + uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 with: - python-version: '3.11' + python-version: "3.11" - name: Download pythonbuild - uses: actions/download-artifact@v4 + uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0 with: - name: pythonbuild + name: ${{ matrix.crate_artifact_name }} path: build - name: Download images - uses: actions/download-artifact@v4 + uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0 with: pattern: image-* path: build merge-multiple: true - name: Cache downloads - uses: actions/cache@v4 + uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4 with: path: build/downloads key: ${{ matrix.target_triple }}-${{ hashFiles('pythonbuild/downloads.py')}} @@ -245,15 +268,32 @@ jobs: # Touch mtimes of all images so they are newer than autogenerated files above. touch build/image-* - ./build-linux.py --target-triple ${{ matrix.target_triple }} --python cpython-${{ matrix.python }} --options ${{ matrix.build_options }} + ./build-linux.py --target-triple ${MATRIX_TARGET_TRIPLE} --python cpython-${MATRIX_PYTHON} --options ${MATRIX_BUILD_OPTIONS} + env: + MATRIX_TARGET_TRIPLE: ${{ matrix.target_triple }} + MATRIX_PYTHON: ${{ matrix.python }} + MATRIX_BUILD_OPTIONS: ${{ matrix.build_options }} + + - name: Generate attestations + uses: actions/attest-build-provenance@e8998f949152b193b063cb0ec769d69d929409be # v2.4.0 + if: ${{ github.ref == 'refs/heads/main' }} + with: + subject-path: dist/* + + - name: Upload Distribution + if: ${{ ! matrix.dry-run }} + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + with: + name: cpython-${{ matrix.python }}-${{ matrix.target_triple }}-${{ matrix.build_options }} + path: dist/* - name: Validate Distribution if: ${{ ! matrix.dry-run }} run: | chmod +x build/pythonbuild - if [ "${{ matrix.run }}" == "true" ]; then - if [ "${{ matrix.libc }}" == "musl" ]; then + if [ "${MATRIX_RUN}" == "true" ]; then + if [ "${MATRIX_LIBC}" == "musl" ]; then sudo apt install musl-dev # GitHub's setup-python action sets `LD_LIBRARY_PATH` which overrides `RPATH` @@ -264,24 +304,14 @@ jobs: fi build/pythonbuild validate-distribution ${EXTRA_ARGS} dist/*.tar.zst - - - name: Generate attestations - uses: actions/attest-build-provenance@v2 - if: ${{ github.ref == 'refs/heads/main' }} - with: - subject-path: dist/* - - - name: Upload Distribution - if: ${{ ! matrix.dry-run }} - uses: actions/upload-artifact@v4 - with: - name: cpython-${{ matrix.python }}-${{ matrix.target_triple }}-${{ matrix.build_options }} - path: dist/* + env: + MATRIX_RUN: ${{ matrix.run }} + MATRIX_LIBC: ${{ matrix.libc }} build-1: needs: - generate-matrix - - pythonbuild + - crate-build - image # Permissions used for actions/attest-build-provenance permissions: @@ -289,34 +319,35 @@ jobs: attestations: write runs-on: ${{ matrix.runner }} strategy: - matrix: ${{ fromJson(needs.generate-matrix.outputs.matrix-1) }} + matrix: ${{ fromJson(needs.generate-matrix.outputs.python-build-matrix-1) }} fail-fast: false name: ${{ matrix.target_triple }} / ${{ matrix.python }} / ${{ matrix.build_options }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: fetch-depth: 0 + persist-credentials: false - name: Install Python - uses: actions/setup-python@v5 + uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 with: - python-version: '3.11' + python-version: "3.11" - name: Download pythonbuild - uses: actions/download-artifact@v4 + uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0 with: - name: pythonbuild + name: ${{ matrix.crate_artifact_name }} path: build - name: Download images - uses: actions/download-artifact@v4 + uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0 with: pattern: image-* path: build merge-multiple: true - name: Cache downloads - uses: actions/cache@v4 + uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4 with: path: build/downloads key: ${{ matrix.target_triple }}-${{ hashFiles('pythonbuild/downloads.py')}} @@ -345,15 +376,32 @@ jobs: # Touch mtimes of all images so they are newer than autogenerated files above. touch build/image-* - ./build-linux.py --target-triple ${{ matrix.target_triple }} --python cpython-${{ matrix.python }} --options ${{ matrix.build_options }} + ./build-linux.py --target-triple ${MATRIX_TARGET_TRIPLE} --python cpython-${MATRIX_PYTHON} --options ${MATRIX_BUILD_OPTIONS} + env: + MATRIX_TARGET_TRIPLE: ${{ matrix.target_triple }} + MATRIX_PYTHON: ${{ matrix.python }} + MATRIX_BUILD_OPTIONS: ${{ matrix.build_options }} + + - name: Generate attestations + uses: actions/attest-build-provenance@e8998f949152b193b063cb0ec769d69d929409be # v2.4.0 + if: ${{ github.ref == 'refs/heads/main' }} + with: + subject-path: dist/* + + - name: Upload Distribution + if: ${{ ! matrix.dry-run }} + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + with: + name: cpython-${{ matrix.python }}-${{ matrix.target_triple }}-${{ matrix.build_options }} + path: dist/* - name: Validate Distribution if: ${{ ! matrix.dry-run }} run: | chmod +x build/pythonbuild - if [ "${{ matrix.run }}" == "true" ]; then - if [ "${{ matrix.libc }}" == "musl" ]; then + if [ "${MATRIX_RUN}" == "true" ]; then + if [ "${MATRIX_LIBC}" == "musl" ]; then sudo apt install musl-dev # GitHub's setup-python action sets `LD_LIBRARY_PATH` which overrides `RPATH` @@ -364,16 +412,6 @@ jobs: fi build/pythonbuild validate-distribution ${EXTRA_ARGS} dist/*.tar.zst - - - name: Generate attestations - uses: actions/attest-build-provenance@v2 - if: ${{ github.ref == 'refs/heads/main' }} - with: - subject-path: dist/* - - - name: Upload Distribution - if: ${{ ! matrix.dry-run }} - uses: actions/upload-artifact@v4 - with: - name: cpython-${{ matrix.python }}-${{ matrix.target_triple }}-${{ matrix.build_options }} - path: dist/* + env: + MATRIX_RUN: ${{ matrix.run }} + MATRIX_LIBC: ${{ matrix.libc }} diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index af9a80f..cadaf4c 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -12,20 +12,27 @@ concurrency: env: FORCE_COLOR: 1 +permissions: {} + jobs: - pythonbuild: - if: ${{ needs.generate-matrix.outputs.pythonbuild_changed == 'true' || needs.generate-matrix.outputs.any_builds == 'true' || github.ref == 'refs/heads/main' }} + crate-build: needs: - generate-matrix - runs-on: depot-macos-latest + runs-on: ${{ matrix.runner }} + strategy: + matrix: ${{ fromJson(needs.generate-matrix.outputs.crate-build-matrix) }} + fail-fast: false + name: crate / ${{ matrix.arch }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false - name: Emit rustc version run: | rustc --version > .rustc-version - - uses: actions/cache@v4 + - uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4 with: path: | ~/.cargo/registry @@ -38,63 +45,74 @@ jobs: cargo build --release - name: Upload pythonbuild Executable - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: - name: pythonbuild + name: ${{ matrix.crate_artifact_name }} path: target/release/pythonbuild generate-matrix: + name: Generate build matrix runs-on: ubuntu-latest outputs: matrix: ${{ steps.set-matrix.outputs.matrix }} + crate-build-matrix: ${{ steps.set-matrix.outputs.crate-build-matrix }} any_builds: ${{ steps.set-matrix.outputs.any_builds }} - pythonbuild_changed: ${{ steps.check-pythonbuild.outputs.changed }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: - fetch-depth: 0 # fetch history for subsequent `git diff` + fetch-depth: 0 + persist-credentials: false - name: Set up Python - uses: astral-sh/setup-uv@v4 + uses: astral-sh/setup-uv@38f3f104447c67c051c4a08e39b64a148898af3a # v4.2.0 - name: Get pull request labels id: get-labels + env: + PULL_REQUEST_LABELS: ${{ toJson(github.event.pull_request.labels.*.name) }} run: | # Convert GitHub labels array to comma-separated string - LABELS=$(echo '${{ toJson(github.event.pull_request.labels.*.name) }}' | jq -r 'join(",")') + LABELS=$(echo "${PULL_REQUEST_LABELS}" | jq -r 'join(",")') echo "labels=$LABELS" >> $GITHUB_OUTPUT + - name: Check if the `pythonbuild` crate changed + id: check-pythonbuild + env: + BASE_REF: ${{ github.event.pull_request.base.ref || 'main' }} + run: | + merge_base=$(git merge-base HEAD "origin/${BASE_REF}") + if git diff --quiet "${merge_base}...HEAD" -- ':src/*.rs'; then + echo "changed=false" >> "$GITHUB_OUTPUT" + else + echo "changed=true" >> "$GITHUB_OUTPUT" + fi + - name: Generate build matrix id: set-matrix run: | - uv run ci-matrix.py --platform darwin --labels '${{ steps.get-labels.outputs.labels }}' > matrix.json && echo "matrix=$(cat matrix.json)" >> $GITHUB_OUTPUT + uv run ci-matrix.py --platform darwin --labels "${STEPS_GET_LABELS_OUTPUTS_LABELS}" ${{ (steps.check-pythonbuild.outputs.changed == 'true' || github.ref == 'refs/heads/main') && '--force-crate-build' || '' }} > matrix.json + + # Extract python-build matrix + echo "matrix=$(jq -c '."python-build"' matrix.json)" >> $GITHUB_OUTPUT + echo "crate-build-matrix=$(jq -c '."crate-build"' matrix.json)" >> $GITHUB_OUTPUT + # Display the matrix for debugging too cat matrix.json | jq - if jq -e '.include | length > 0' matrix.json > /dev/null; then + if jq -e '."python-build".include | length > 0' matrix.json > /dev/null; then # Build matrix has entries echo "any_builds=true" >> $GITHUB_OUTPUT else # Build matrix is empty echo "any_builds=false" >> $GITHUB_OUTPUT fi - - - name: Check if the `pythonbuild` crate changed - id: check-pythonbuild env: - BASE_REF: ${{ github.event.pull_request.base.ref || 'main' }} - run: | - merge_base=$(git merge-base HEAD "origin/${BASE_REF}") - if git diff --quiet "${merge_base}...HEAD" -- ':src/*.rs'; then - echo "changed=false" >> "$GITHUB_OUTPUT" - else - echo "changed=true" >> "$GITHUB_OUTPUT" - fi + STEPS_GET_LABELS_OUTPUTS_LABELS: ${{ steps.get-labels.outputs.labels }} build: needs: - generate-matrix - - pythonbuild + - crate-build # Permissions used for actions/attest-build-provenance permissions: id-token: write @@ -105,55 +123,61 @@ jobs: fail-fast: false name: ${{ matrix.target_triple }} / ${{ matrix.python }} / ${{ matrix.build_options }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: fetch-depth: 0 + persist-credentials: false - name: Install Python - uses: actions/setup-python@v5 + uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 with: - python-version: '3.11' + python-version: "3.11" - name: Download pythonbuild - uses: actions/download-artifact@v4 + uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0 with: - name: pythonbuild + name: ${{ matrix.crate_artifact_name }} path: build - name: Build if: ${{ ! matrix.dry-run }} run: | - if [ "${{ matrix.target_triple }}" = "aarch64-apple-darwin" ]; then + if [ "${MATRIX_TARGET_TRIPLE}" = "aarch64-apple-darwin" ]; then export APPLE_SDK_PATH=/Applications/Xcode_15.2.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.2.sdk - elif [ "${{ matrix.target_triple }}" = "x86_64-apple-darwin" ]; then + elif [ "${MATRIX_TARGET_TRIPLE}" = "x86_64-apple-darwin" ]; then export APPLE_SDK_PATH=/Applications/Xcode_15.2.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.2.sdk else - echo "unhandled target triple: ${{ matrix.target_triple }}" + echo "unhandled target triple: ${MATRIX_TARGET_TRIPLE}" exit 1 fi - ./build-macos.py --target-triple ${{ matrix.target_triple }} --python cpython-${{ matrix.python }} --options ${{ matrix.build_options }} + ./build-macos.py --target-triple ${MATRIX_TARGET_TRIPLE} --python cpython-${MATRIX_PYTHON} --options ${MATRIX_BUILD_OPTIONS} + env: + MATRIX_TARGET_TRIPLE: ${{ matrix.target_triple }} + MATRIX_PYTHON: ${{ matrix.python }} + MATRIX_BUILD_OPTIONS: ${{ matrix.build_options }} - name: Generate attestations - uses: actions/attest-build-provenance@v2 + uses: actions/attest-build-provenance@e8998f949152b193b063cb0ec769d69d929409be # v2.4.0 if: ${{ github.ref == 'refs/heads/main' }} with: subject-path: dist/* - name: Upload Distributions if: ${{ ! matrix.dry-run }} - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: cpython-${{ matrix.python }}-${{ matrix.target_triple }}-${{ matrix.build_options }} path: dist/* - name: Checkout macOS SDKs for validation if: ${{ ! matrix.dry-run }} - uses: actions/checkout@v4 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: - repository: 'phracker/MacOSX-SDKs' + repository: phracker/MacOSX-SDKs ref: master path: macosx-sdks + persist-credentials: false - name: Validate Distribution if: ${{ ! matrix.dry-run }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6381b3e..be9c3d1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -18,30 +18,39 @@ on: env: FORCE_COLOR: 1 -permissions: - contents: write - packages: write - # Permissions used for actions/attest-build-provenance - id-token: write - attestations: write +permissions: {} jobs: release: + name: Release env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - runs-on: github-ubuntu-24.04-x86_64-16 + runs-on: depot-ubuntu-24.04-8 + + permissions: + contents: write + packages: write + # Permissions used for actions/attest-build-provenance + id-token: write + attestations: write + steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: submodules: recursive + persist-credentials: true # needed for git operations below - - uses: extractions/setup-just@dd310ad5a97d8e7b41793f8ef055398d51ad4de6 # v2 + - uses: extractions/setup-crate@4993624604c307fbca528d28a3c8b60fa5ecc859 # v1.4.0 + with: + repo: casey/just + version: 1.42.4 # Perform a release in dry-run mode. - - run: just release-dry-run ${{ secrets.GITHUB_TOKEN }} ${{ github.event.inputs.sha }} ${{ github.event.inputs.tag }} + - run: just release-dry-run ${GH_TOKEN} ${GITHUB_EVENT_INPUTS_SHA} ${GITHUB_EVENT_INPUTS_TAG} if: ${{ github.event.inputs.dry-run == 'true' }} - - # Set our identity for git operations (on the latest-release branch). + env: + GITHUB_EVENT_INPUTS_SHA: ${{ github.event.inputs.sha }} + GITHUB_EVENT_INPUTS_TAG: ${{ github.event.inputs.tag }} - name: Configure Git identity if: ${{ github.event.inputs.dry-run == 'false' }} run: | @@ -51,30 +60,38 @@ jobs: # Fetch the commit so that it exists locally. - name: Fetch commit if: ${{ github.event.inputs.dry-run == 'false' }} - run: git fetch origin ${{ github.event.inputs.sha }} + run: git fetch origin ${GITHUB_EVENT_INPUTS_SHA} + env: + GITHUB_EVENT_INPUTS_SHA: ${{ github.event.inputs.sha }} # Associate the commit with the tag. - name: Create tag if: ${{ github.event.inputs.dry-run == 'false' }} - run: git tag ${{ github.event.inputs.tag }} ${{ github.event.inputs.sha }} - - # Push the tag to GitHub. + run: git tag ${GITHUB_EVENT_INPUTS_TAG} ${GITHUB_EVENT_INPUTS_SHA} + env: + GITHUB_EVENT_INPUTS_TAG: ${{ github.event.inputs.tag }} + GITHUB_EVENT_INPUTS_SHA: ${{ github.event.inputs.sha }} - name: Push tag if: ${{ github.event.inputs.dry-run == 'false' }} - run: git push origin ${{ github.event.inputs.tag }} + run: git push origin ${GITHUB_EVENT_INPUTS_TAG} + env: + GITHUB_EVENT_INPUTS_TAG: ${{ github.event.inputs.tag }} # Create a GitHub release. - name: Create GitHub Release if: ${{ github.event.inputs.dry-run == 'false' }} - run: just release-create ${{ github.event.inputs.tag }} + run: just release-create ${GITHUB_EVENT_INPUTS_TAG} + env: + GITHUB_EVENT_INPUTS_TAG: ${{ github.event.inputs.tag }} # Uploading the relevant artifact to the GitHub release. - - run: just release-run ${{ secrets.GITHUB_TOKEN }} ${{ github.event.inputs.sha }} ${{ github.event.inputs.tag }} + - run: just release-run ${GH_TOKEN} ${GITHUB_EVENT_INPUTS_SHA} ${GITHUB_EVENT_INPUTS_TAG} if: ${{ github.event.inputs.dry-run == 'false' }} - - # We filter by *.tar.@(zst|gz) since actions/attest-build-provenance only supports up to 1024 subjects + env: + GITHUB_EVENT_INPUTS_SHA: ${{ github.event.inputs.sha }} + GITHUB_EVENT_INPUTS_TAG: ${{ github.event.inputs.tag }} - name: Generate attestations - uses: actions/attest-build-provenance@v2 + uses: actions/attest-build-provenance@e8998f949152b193b063cb0ec769d69d929409be # v2.4.0 if: ${{ github.event.inputs.dry-run == 'false' }} with: subject-path: | diff --git a/.github/workflows/security-3rd-party-pr-checks.yml b/.github/workflows/security-3rd-party-pr-checks.yml new file mode 100644 index 0000000..5337dab --- /dev/null +++ b/.github/workflows/security-3rd-party-pr-checks.yml @@ -0,0 +1,10 @@ +name: security-3rd-party-pr-checks +on: + # Allow for manual run of security workflows + workflow_dispatch: + # Scan changed files in PRs (diff-aware scanning): + pull_request: {} +jobs: + running-3rd-party-pr-security-checks: + uses: verkada/securitybots/.github/workflows/3rd-party-pr-checks.yml@main + secrets: inherit diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index a7535c6..fc8c988 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -12,20 +12,27 @@ concurrency: env: FORCE_COLOR: 1 +permissions: {} + jobs: - pythonbuild: - if: ${{ needs.generate-matrix.outputs.pythonbuild_changed == 'true' || needs.generate-matrix.outputs.any_builds == 'true' || github.ref == 'refs/heads/main' }} + crate-build: needs: - generate-matrix - runs-on: 'windows-2022' + runs-on: ${{ matrix.runner }} + strategy: + matrix: ${{ fromJson(needs.generate-matrix.outputs.crate-build-matrix) }} + fail-fast: false + name: crate / ${{ matrix.arch }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false - name: Emit rustc version run: | rustc --version > .rustc-version - - uses: actions/cache@v4 + - uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4 with: path: | C:/Rust/.cargo/registry @@ -38,63 +45,75 @@ jobs: cargo build --release - name: Upload executable - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: - name: pythonbuild + name: ${{ matrix.crate_artifact_name }} path: target/release/pythonbuild.exe generate-matrix: + name: Generate build matrix runs-on: ubuntu-latest outputs: matrix: ${{ steps.set-matrix.outputs.matrix }} + crate-build-matrix: ${{ steps.set-matrix.outputs.crate-build-matrix }} any_builds: ${{ steps.set-matrix.outputs.any_builds }} - pythonbuild_changed: ${{ steps.check-pythonbuild.outputs.changed }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: - fetch-depth: 0 # fetch history for subsequent `git diff` + fetch-depth: 0 + persist-credentials: false - name: Set up Python - uses: astral-sh/setup-uv@v4 + uses: astral-sh/setup-uv@38f3f104447c67c051c4a08e39b64a148898af3a # v4.2.0 - name: Get pull request labels id: get-labels + env: + PULL_REQUEST_LABELS: ${{ toJson(github.event.pull_request.labels.*.name) }} run: | # Convert GitHub labels array to comma-separated string - LABELS=$(echo '${{ toJson(github.event.pull_request.labels.*.name) }}' | jq -r 'join(",")') + LABELS=$(echo "${PULL_REQUEST_LABELS}" | jq -r 'join(",")') echo "labels=$LABELS" >> $GITHUB_OUTPUT + - name: Check if the `pythonbuild` crate changed + id: check-pythonbuild + env: + BASE_REF: ${{ github.event.pull_request.base.ref || 'main' }} + run: | + merge_base=$(git merge-base HEAD "origin/${BASE_REF}") + if git diff --quiet "${merge_base}...HEAD" -- ':src/*.rs'; then + echo "changed=false" >> "$GITHUB_OUTPUT" + else + echo "changed=true" >> "$GITHUB_OUTPUT" + fi + - name: Generate build matrix id: set-matrix run: | - uv run ci-matrix.py --platform windows --labels '${{ steps.get-labels.outputs.labels }}' > matrix.json && echo "matrix=$(cat matrix.json)" >> $GITHUB_OUTPUT + uv run ci-matrix.py --platform windows --labels "${STEPS_GET_LABELS_OUTPUTS_LABELS}" ${{ (steps.check-pythonbuild.outputs.changed == 'true' || github.ref == 'refs/heads/main') && '--force-crate-build' || '' }} > matrix.json + + # Extract python-build matrix + echo "matrix=$(jq -c '."python-build"' matrix.json)" >> $GITHUB_OUTPUT + echo "crate-build-matrix=$(jq -c '."crate-build"' matrix.json)" >> $GITHUB_OUTPUT + # Display the matrix for debugging too cat matrix.json | jq - if jq -e '.include | length > 0' matrix.json > /dev/null; then + if jq -e '."python-build".include | length > 0' matrix.json > /dev/null; then # Build matrix has entries echo "any_builds=true" >> $GITHUB_OUTPUT else # Build matrix is empty echo "any_builds=false" >> $GITHUB_OUTPUT fi - - - name: Check if the `pythonbuild` crate changed - id: check-pythonbuild env: - BASE_REF: ${{ github.event.pull_request.base.ref || 'main' }} - run: | - merge_base=$(git merge-base HEAD "origin/${BASE_REF}") - if git diff --quiet "${merge_base}...HEAD" -- ':src/*.rs'; then - echo "changed=false" >> "$GITHUB_OUTPUT" - else - echo "changed=true" >> "$GITHUB_OUTPUT" - fi + STEPS_GET_LABELS_OUTPUTS_LABELS: ${{ steps.get-labels.outputs.labels }} build: + timeout-minutes: 90 needs: - generate-matrix - - pythonbuild + - crate-build # Permissions used for actions/attest-build-provenance permissions: id-token: write @@ -105,24 +124,25 @@ jobs: fail-fast: false name: ${{ matrix.target_triple }} / ${{ matrix.python }} / ${{ matrix.build_options }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: fetch-depth: 0 + persist-credentials: false - name: Install Cygwin Environment - uses: cygwin/cygwin-install-action@49f298a7ebb00d4b3ddf58000c3e78eff5fbd6b9 # v2 + uses: cygwin/cygwin-install-action@f2009323764960f80959895c7bc3bb30210afe4d # v6 with: packages: autoconf automake libtool - name: Install Python - uses: actions/setup-python@v5 + uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 with: - python-version: '3.12' + python-version: "3.12" - name: Download pythonbuild Executable - uses: actions/download-artifact@v4 + uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0 with: - name: pythonbuild + name: ${{ matrix.crate_artifact_name }} # We need to do this before we activate the VC++ environment or else binary packages # don't get compiled properly. @@ -134,23 +154,27 @@ jobs: if: ${{ ! matrix.dry-run }} shell: cmd run: | - call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\${{ matrix.vcvars }}" - py.exe -3.12 build-windows.py --python cpython-${{ matrix.python }} --sh c:\cygwin\bin\sh.exe --options ${{ matrix.build_options }} - - - name: Validate Distribution - if: ${{ ! matrix.dry-run }} - run: | - $Dists = Resolve-Path -Path "dist/*.tar.zst" -Relative - .\pythonbuild.exe validate-distribution --run $Dists + call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\%MATRIX_VCVARS%" + py.exe -3.12 build-windows.py --python cpython-%MATRIX_PYTHON% --sh c:\cygwin\bin\sh.exe --options %MATRIX_BUILD_OPTIONS% + env: + MATRIX_VCVARS: ${{ matrix.vcvars }} + MATRIX_PYTHON: ${{ matrix.python }} + MATRIX_BUILD_OPTIONS: ${{ matrix.build_options }} - name: Generate attestations - uses: actions/attest-build-provenance@v2 + uses: actions/attest-build-provenance@e8998f949152b193b063cb0ec769d69d929409be # v2.4.0 if: ${{ github.ref == 'refs/heads/main' }} with: subject-path: dist/* - name: Upload Distributions - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: cpython-${{ matrix.python }}-${{ matrix.vcvars }}-${{ matrix.build_options }} path: dist/* + + - name: Validate Distribution + if: ${{ ! matrix.dry-run }} + run: | + $Dists = Resolve-Path -Path "dist/*.tar.zst" -Relative + .\pythonbuild.exe validate-distribution --run $Dists diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml new file mode 100644 index 0000000..8601134 --- /dev/null +++ b/.github/workflows/zizmor.yml @@ -0,0 +1,24 @@ +name: zizmor + +on: + push: + branches: ["main"] + pull_request: + branches: ["**"] + +permissions: {} + +jobs: + zizmor: + name: Run zizmor + runs-on: ubuntu-latest + permissions: + security-events: write + steps: + - name: Checkout repository + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false + + - name: Run zizmor + uses: zizmorcore/zizmor-action@5ca5fc7a4779c5263a3ffa0e1f693009994446d1 # v0.1.2 diff --git a/.github/zizmor.yml b/.github/zizmor.yml new file mode 100644 index 0000000..e7920e8 --- /dev/null +++ b/.github/zizmor.yml @@ -0,0 +1,5 @@ +rules: + unpinned-uses: + config: + policies: + "*": hash-pin diff --git a/Cargo.lock b/Cargo.lock index b0db167..6a2f089 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -263,8 +263,10 @@ checksum = "7e36cc9d416881d2e24f9a963be5fb1cd90966419ac844274161d10488b3e825" dependencies = [ "android-tzdata", "iana-time-zone", + "js-sys", "num-traits", "serde", + "wasm-bindgen", "windows-targets", ] @@ -327,6 +329,16 @@ dependencies = [ "libc", ] +[[package]] +name = "core-foundation" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation-sys" version = "0.8.7" @@ -395,17 +407,6 @@ dependencies = [ "powerfmt", ] -[[package]] -name = "derive_more" -version = "0.99.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3da29a38df43d6f156149c9b43ded5e018ddff2a855cf2cfd62e8cd7d079c69f" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "digest" version = "0.10.7" @@ -782,25 +783,6 @@ dependencies = [ "want", ] -[[package]] -name = "hyper-rustls" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0bea761b46ae2b24eb4aef630d8d1c398157b6fc29e6350ecf090a0b70c952c" -dependencies = [ - "futures-util", - "http", - "hyper", - "hyper-util", - "log", - "rustls 0.22.4", - "rustls-native-certs", - "rustls-pki-types", - "tokio", - "tokio-rustls 0.25.0", - "tower-service", -] - [[package]] name = "hyper-rustls" version = "0.27.5" @@ -811,10 +793,12 @@ dependencies = [ "http", "hyper", "hyper-util", - "rustls 0.23.22", + "log", + "rustls", + "rustls-native-certs", "rustls-pki-types", "tokio", - "tokio-rustls 0.26.1", + "tokio-rustls", "tower-service", "webpki-roots", ] @@ -1217,7 +1201,7 @@ dependencies = [ "openssl-probe", "openssl-sys", "schannel", - "security-framework", + "security-framework 2.11.1", "security-framework-sys", "tempfile", ] @@ -1264,29 +1248,29 @@ dependencies = [ [[package]] name = "object" -version = "0.32.2" +version = "0.36.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" dependencies = [ - "flate2", "memchr", - "ruzstd", ] [[package]] name = "object" -version = "0.36.7" +version = "0.37.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" +checksum = "03fd943161069e1768b4b3d050890ba48730e590f57e56d4aa04e7e090e61b4a" dependencies = [ + "flate2", "memchr", + "ruzstd", ] [[package]] name = "octocrab" -version = "0.34.3" +version = "0.44.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c4e00a4268539fda6c431a0fd01d016d4b44c361f9c283d0eb8f1ab7408a517" +checksum = "86996964f8b721067b6ed238aa0ccee56ecad6ee5e714468aa567992d05d2b91" dependencies = [ "arc-swap", "async-trait", @@ -1302,7 +1286,7 @@ dependencies = [ "http-body", "http-body-util", "hyper", - "hyper-rustls 0.26.0", + "hyper-rustls", "hyper-timeout", "hyper-util", "jsonwebtoken", @@ -1316,10 +1300,11 @@ dependencies = [ "serde_urlencoded", "snafu", "tokio", - "tower 0.4.13", + "tower", "tower-http", "tracing", "url", + "web-time", ] [[package]] @@ -1567,7 +1552,7 @@ dependencies = [ "hyper", "hyper-util", "normalize-path", - "object 0.32.2", + "object 0.37.1", "octocrab", "once_cell", "pdb", @@ -1585,6 +1570,7 @@ dependencies = [ "tempfile", "text-stub-library", "tokio", + "tokio-util", "url", "version-compare", "zip", @@ -1611,7 +1597,7 @@ dependencies = [ "quinn-proto", "quinn-udp", "rustc-hash", - "rustls 0.23.22", + "rustls", "socket2", "thiserror 2.0.11", "tokio", @@ -1629,7 +1615,7 @@ dependencies = [ "rand", "ring", "rustc-hash", - "rustls 0.23.22", + "rustls", "rustls-pki-types", "slab", "thiserror 2.0.11", @@ -1745,7 +1731,7 @@ dependencies = [ "http-body", "http-body-util", "hyper", - "hyper-rustls 0.27.5", + "hyper-rustls", "hyper-tls", "hyper-util", "ipnet", @@ -1757,7 +1743,7 @@ dependencies = [ "percent-encoding", "pin-project-lite", "quinn", - "rustls 0.23.22", + "rustls", "rustls-pemfile", "rustls-pki-types", "serde", @@ -1767,9 +1753,9 @@ dependencies = [ "system-configuration", "tokio", "tokio-native-tls", - "tokio-rustls 0.26.1", + "tokio-rustls", "tokio-util", - "tower 0.5.2", + "tower", "tower-service", "url", "wasm-bindgen", @@ -1865,26 +1851,13 @@ dependencies = [ "windows-sys 0.59.0", ] -[[package]] -name = "rustls" -version = "0.22.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf4ef73721ac7bcd79b2b315da7779d8fc09718c6b3d2d1b2d94850eb8c18432" -dependencies = [ - "log", - "ring", - "rustls-pki-types", - "rustls-webpki", - "subtle", - "zeroize", -] - [[package]] name = "rustls" version = "0.23.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9fb9263ab4eb695e42321db096e3b8fbd715a59b154d5c88d82db2175b681ba7" dependencies = [ + "log", "once_cell", "ring", "rustls-pki-types", @@ -1895,15 +1868,14 @@ dependencies = [ [[package]] name = "rustls-native-certs" -version = "0.7.3" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5bfb394eeed242e909609f56089eecfe5fda225042e8b171791b9c95f5931e5" +checksum = "7fcff2dd52b58a8d98a70243663a0d234c4e2b79235637849d15913394a247d3" dependencies = [ "openssl-probe", - "rustls-pemfile", "rustls-pki-types", "schannel", - "security-framework", + "security-framework 3.2.0", ] [[package]] @@ -1943,12 +1915,10 @@ checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4" [[package]] name = "ruzstd" -version = "0.5.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58c4eb8a81997cf040a091d1f7e1938aeab6749d3a0dfa73af43cdc32393483d" +checksum = "3640bec8aad418d7d03c72ea2de10d5c646a598f9883c7babc160d91e3c1b26c" dependencies = [ - "byteorder", - "derive_more", "twox-hash", ] @@ -2001,9 +1971,9 @@ dependencies = [ [[package]] name = "secrecy" -version = "0.8.0" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bd1c54ea06cfd2f6b63219704de0b9b4f72dcc2b8fdef820be6cd799780e91e" +checksum = "e891af845473308773346dc847b2c23ee78fe442e0472ac50e22a18a93d3ae5a" dependencies = [ "zeroize", ] @@ -2015,7 +1985,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ "bitflags 2.8.0", - "core-foundation", + "core-foundation 0.9.4", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271720403f46ca04f7ba6f55d438f8bd878d6b8ca0a1046e8228c4145bcbb316" +dependencies = [ + "bitflags 2.8.0", + "core-foundation 0.10.1", "core-foundation-sys", "libc", "security-framework-sys", @@ -2206,12 +2189,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - [[package]] name = "strsim" version = "0.11.1" @@ -2262,7 +2239,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" dependencies = [ "bitflags 2.8.0", - "core-foundation", + "core-foundation 0.9.4", "system-configuration-sys", ] @@ -2433,24 +2410,13 @@ dependencies = [ "tokio", ] -[[package]] -name = "tokio-rustls" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f" -dependencies = [ - "rustls 0.22.4", - "rustls-pki-types", - "tokio", -] - [[package]] name = "tokio-rustls" version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f6d0975eaace0cf0fcadee4e4aaa5da15b5c079146f2cffb67c113be122bf37" dependencies = [ - "rustls 0.23.22", + "rustls", "tokio", ] @@ -2467,23 +2433,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "tower" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" -dependencies = [ - "futures-core", - "futures-util", - "pin-project", - "pin-project-lite", - "tokio", - "tokio-util", - "tower-layer", - "tower-service", - "tracing", -] - [[package]] name = "tower" version = "0.5.2" @@ -2495,25 +2444,26 @@ dependencies = [ "pin-project-lite", "sync_wrapper", "tokio", + "tokio-util", "tower-layer", "tower-service", + "tracing", ] [[package]] name = "tower-http" -version = "0.5.2" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5" +checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" dependencies = [ "bitflags 2.8.0", "bytes", "futures-util", "http", "http-body", - "http-body-util", "iri-string", "pin-project-lite", - "tower 0.4.13", + "tower", "tower-layer", "tower-service", "tracing", @@ -2571,13 +2521,9 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "twox-hash" -version = "1.6.3" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" -dependencies = [ - "cfg-if", - "static_assertions", -] +checksum = "8b907da542cbced5261bd3256de1b3a1bf340a3d37f93425a07362a1d687de56" [[package]] name = "typenum" @@ -2809,6 +2755,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" dependencies = [ "js-sys", + "serde", "wasm-bindgen", ] diff --git a/Cargo.toml b/Cargo.toml index 82f0298..beca9e8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "pythonbuild" version = "0.1.0" authors = ["Gregory Szorc "] -edition = "2021" +edition = "2024" [dependencies] anyhow = "1.0.80" @@ -19,8 +19,8 @@ http-body-util = "0.1.0" hyper = { version = "1.2.0", features = ["client"] } hyper-util = { version = "0.1.3" } normalize-path = "0.2.1" -object = "0.32.2" -octocrab = { version = "0.34.1", features = ["rustls", "stream"] } +object = "0.37.1" +octocrab = { version = "0.44.1", features = ["rustls", "stream"] } once_cell = "1.19.0" pdb = "0.8.0" pep440_rs = "0.6.6" @@ -37,6 +37,7 @@ tar = "0.4.40" tempfile = "3.10.0" text-stub-library = "0.9.0" tokio = "1.43.1" +tokio-util = "0.7.13" url = "2.5.0" version-compare = "0.1.1" zip = "0.6.6" diff --git a/build-windows.py b/build-windows.py index df836b6..4a8c897 100644 --- a/build-windows.py +++ b/build-windows.py @@ -5,6 +5,7 @@ import os import pathlib +import platform import subprocess import sys import venv @@ -15,7 +16,8 @@ VENV = BUILD / "venv" PIP = VENV / "Scripts" / "pip.exe" PYTHON = VENV / "Scripts" / "python.exe" -REQUIREMENTS = ROOT / "requirements.win.txt" +ARCH = "-arm64" if platform.machine() == "ARM64" else "" +REQUIREMENTS = ROOT / f"requirements.win{ARCH}.txt" WINDOWS_DIR = ROOT / "cpython-windows" diff --git a/ci-matrix.py b/ci-matrix.py index c9bccce..91cfa95 100644 --- a/ci-matrix.py +++ b/ci-matrix.py @@ -20,6 +20,21 @@ CI_MATRIX_SIZE_LIMIT = 256 # The maximum size of a matrix in GitHub Actions +# Docker images for building toolchains and dependencies +DOCKER_BUILD_IMAGES = [ + {"name": "build", "arch": "x86_64"}, + {"name": "build.cross", "arch": "x86_64"}, + {"name": "build.cross-riscv64", "arch": "x86_64"}, + {"name": "build.debian9", "arch": "aarch64"}, + {"name": "gcc", "arch": "x86_64"}, + {"name": "gcc.debian9", "arch": "aarch64"}, +] + + +def crate_artifact_name(platform: str, arch: str) -> str: + return f"crate-{platform}-{arch}" + + def meets_conditional_version(version: str, min_version: str) -> bool: return Version(version) >= Version(min_version) @@ -89,12 +104,87 @@ def should_include_entry(entry: dict[str, str], filters: dict[str, set[str]]) -> return True -def generate_matrix_entries( +def generate_docker_matrix_entries( + runners: dict[str, Any], + platform_filter: Optional[str] = None, +) -> list[dict[str, str]]: + """Generate matrix entries for docker image builds.""" + if platform_filter and platform_filter != "linux": + return [] + + matrix_entries = [] + for image in DOCKER_BUILD_IMAGES: + # Find appropriate runner for Linux platform with the specified architecture + runner = find_runner(runners, "linux", image["arch"], False) + + entry = { + "name": image["name"], + "arch": image["arch"], + "runner": runner, + } + matrix_entries.append(entry) + + return matrix_entries + + +def generate_crate_build_matrix_entries( + python_entries: list[dict[str, str]], + runners: dict[str, Any], + config: dict[str, Any], + force_crate_build: bool = False, + platform_filter: Optional[str] = None, +) -> list[dict[str, str]]: + """Generate matrix entries for crate builds based on python build matrix.""" + needed_builds = set() + for entry in python_entries: + # The crate build will need to match the runner's architecture + runner = runners[entry["runner"]] + needed_builds.add((entry["platform"], runner["arch"])) + + # If forcing crate build, also include all possible native builds + if force_crate_build: + for platform, platform_config in config.items(): + # Filter by platform if specified + if platform_filter and platform != platform_filter: + continue + + for target_config in platform_config.values(): + # Only include if native (run: true means native) + if not target_config.get("run"): + continue + + arch = target_config["arch"] + needed_builds.add((platform, arch)) + + # Create matrix entries for each needed build + return [ + { + "platform": platform, + "arch": arch, + # Use the GitHub runner for Windows, because the Depot one is + # missing a Rust toolchain. On Linux, it's important that the the + # `python-build` runner matches the `crate-build` runner because of + # GLIBC version mismatches. + "runner": find_runner( + runners, platform, arch, True if platform == "windows" else False + ), + "crate_artifact_name": crate_artifact_name( + platform, + arch, + ), + } + for platform, arch in needed_builds + if not platform_filter or platform == platform_filter + ] + + +def generate_python_build_matrix_entries( config: dict[str, Any], runners: dict[str, Any], platform_filter: Optional[str] = None, label_filters: Optional[dict[str, set[str]]] = None, ) -> list[dict[str, str]]: + """Generate matrix entries for python builds.""" matrix_entries = [] for platform, platform_config in config.items(): @@ -102,13 +192,13 @@ def generate_matrix_entries( continue for target_triple, target_config in platform_config.items(): - add_matrix_entries_for_config( + add_python_build_entries_for_config( matrix_entries, target_triple, target_config, platform, runners, - label_filters.get("directives", set()), + label_filters.get("directives", set()) if label_filters else set(), ) # Apply label filters if present @@ -122,10 +212,12 @@ def generate_matrix_entries( return matrix_entries -def find_runner(runners: dict[str, Any], platform: str, arch: str) -> str: +def find_runner(runners: dict[str, Any], platform: str, arch: str, free: bool) -> str: # Find a matching platform first match_platform = [ - runner for runner in runners if runners[runner]["platform"] == platform + runner + for runner in runners + if runners[runner]["platform"] == platform and runners[runner]["free"] == free ] # Then, find a matching architecture @@ -141,10 +233,12 @@ def find_runner(runners: dict[str, Any], platform: str, arch: str) -> str: if match_platform: return match_platform[0] - raise RuntimeError(f"No runner found for platform {platform!r} and arch {arch!r}") + raise RuntimeError( + f"No runner found for platform {platform!r} and arch {arch!r} with free={free}" + ) -def add_matrix_entries_for_config( +def add_python_build_entries_for_config( matrix_entries: list[dict[str, str]], target_triple: str, config: dict[str, Any], @@ -152,10 +246,11 @@ def add_matrix_entries_for_config( runners: dict[str, Any], directives: set[str], ) -> None: + """Add python build matrix entries for a specific target configuration.""" python_versions = config["python_versions"] build_options = config["build_options"] arch = config["arch"] - runner = find_runner(runners, platform, arch) + runner = find_runner(runners, platform, arch, False) # Create base entry that will be used for all variants base_entry = { @@ -166,6 +261,8 @@ def add_matrix_entries_for_config( # If `run` is in the config, use that — otherwise, default to if the # runner architecture matches the build architecture "run": str(config.get("run", runners[runner]["arch"] == arch)).lower(), + # Use the crate artifact built for the runner's architecture + "crate_artifact_name": crate_artifact_name(platform, runners[runner]["arch"]), } # Add optional fields if they exist @@ -233,6 +330,17 @@ def parse_args() -> argparse.Namespace: action="store_true", help="If only free runners should be used.", ) + parser.add_argument( + "--force-crate-build", + action="store_true", + help="Force crate builds to be included even without python builds.", + ) + parser.add_argument( + "--matrix-type", + choices=["python-build", "docker-build", "crate-build", "all"], + default="all", + help="Which matrix types to generate (default: all)", + ) return parser.parse_args() @@ -254,36 +362,70 @@ def main() -> None: if runner_config.get("free") } - entries = generate_matrix_entries( + result = {} + + # Generate python build entries + python_entries = generate_python_build_matrix_entries( config, runners, args.platform, labels, ) - if args.max_shards: - matrix = {} - shards = (len(entries) // CI_MATRIX_SIZE_LIMIT) + 1 - if shards > args.max_shards: - print( - f"error: matrix of size {len(entries)} requires {shards} shards, but the maximum is {args.max_shards}; consider increasing `--max-shards`", - file=sys.stderr, - ) - sys.exit(1) - for shard in range(args.max_shards): - shard_entries = entries[ - shard * CI_MATRIX_SIZE_LIMIT : (shard + 1) * CI_MATRIX_SIZE_LIMIT - ] - matrix[str(shard)] = {"include": shard_entries} - else: - if len(entries) > CI_MATRIX_SIZE_LIMIT: - print( - f"warning: matrix of size {len(entries)} exceeds limit of {CI_MATRIX_SIZE_LIMIT} but sharding is not enabled; consider setting `--max-shards`", - file=sys.stderr, + # Output python-build matrix if requested + if args.matrix_type in ["python-build", "all"]: + if args.max_shards: + python_build_matrix = {} + shards = (len(python_entries) // CI_MATRIX_SIZE_LIMIT) + 1 + if shards > args.max_shards: + print( + f"error: python-build matrix of size {len(python_entries)} requires {shards} shards, but the maximum is {args.max_shards}; consider increasing `--max-shards`", + file=sys.stderr, + ) + sys.exit(1) + for shard in range(args.max_shards): + shard_entries = python_entries[ + shard * CI_MATRIX_SIZE_LIMIT : (shard + 1) * CI_MATRIX_SIZE_LIMIT + ] + python_build_matrix[str(shard)] = {"include": shard_entries} + result["python-build"] = python_build_matrix + else: + if len(python_entries) > CI_MATRIX_SIZE_LIMIT: + print( + f"warning: python-build matrix of size {len(python_entries)} exceeds limit of {CI_MATRIX_SIZE_LIMIT} but sharding is not enabled; consider setting `--max-shards`", + file=sys.stderr, + ) + result["python-build"] = {"include": python_entries} + + # Generate docker-build matrix if requested + # Only include docker builds if there are Linux python builds + if args.matrix_type in ["docker-build", "all"]: + # Check if we have any Linux python builds + has_linux_builds = any( + entry.get("platform") == "linux" for entry in python_entries + ) + + # If no platform filter or explicitly requesting docker-build only, include docker builds + # Otherwise, only include if there are Linux python builds + if args.matrix_type == "docker-build" or has_linux_builds: + docker_entries = generate_docker_matrix_entries( + runners, + args.platform, ) - matrix = {"include": entries} - - print(json.dumps(matrix)) + result["docker-build"] = {"include": docker_entries} + + # Generate crate-build matrix if requested + if args.matrix_type in ["crate-build", "all"]: + crate_entries = generate_crate_build_matrix_entries( + python_entries, + runners, + config, + args.force_crate_build, + args.platform, + ) + result["crate-build"] = {"include": crate_entries} + + print(json.dumps(result)) if __name__ == "__main__": diff --git a/ci-runners.yaml b/ci-runners.yaml index aeb0e5c..dae6aab 100644 --- a/ci-runners.yaml +++ b/ci-runners.yaml @@ -5,11 +5,10 @@ depot-ubuntu-22.04: platform: linux free: false -# TODO: Enable this runner to perform native builds for aarch64 -# depot-ubuntu-22.04-arm: -# arch: aarch64 -# platform: linux -# free: false +depot-ubuntu-22.04-arm: + arch: aarch64 + platform: linux + free: false depot-macos-latest: arch: x86_64 @@ -26,6 +25,11 @@ macos-latest: platform: darwin free: true +depot-windows-2022-8: + arch: x86_64 + platform: windows + free: false + windows-latest-large: arch: x86_64 platform: windows @@ -35,3 +39,8 @@ windows-latest: arch: x86_64 platform: windows free: true + +windows-11-arm: + arch: aarch64 + platform: windows + free: false diff --git a/ci-targets.yaml b/ci-targets.yaml index 70078e8..0662bbe 100644 --- a/ci-targets.yaml +++ b/ci-targets.yaml @@ -50,13 +50,11 @@ linux: - "3.14" build_options: - debug - - noopt - - lto + - pgo+lto build_options_conditional: - options: - freethreaded+debug - - freethreaded+noopt - - freethreaded+lto + - freethreaded+pgo+lto minimum-python-version: "3.13" armv7-unknown-linux-gnueabi: @@ -350,6 +348,32 @@ linux: minimum-python-version: "3.13" run: true + aarch64-unknown-linux-musl: + arch: aarch64 + libc: musl + python_versions: + - "3.9" + - "3.10" + - "3.11" + - "3.12" + - "3.13" + - "3.14" + build_options: + # TODO: Static support is current blocked by some compiler-rt linking issues + # - debug+static + # - noopt+static + # - lto+static + - debug + - noopt + - lto + build_options_conditional: + - options: + - freethreaded+debug + - freethreaded+noopt + - freethreaded+lto + minimum-python-version: "3.13" + run: true + windows: i686-pc-windows-msvc: arch: x86 @@ -384,3 +408,21 @@ windows: - options: - freethreaded+pgo minimum-python-version: "3.13" + + aarch64-pc-windows-msvc: + arch: aarch64 + vcvars: vcvarsamd64_arm64.bat + python_versions: + # On 3.9 / 3.10, `_tkinter` is failing to be included in the build + # - "3.9" + # - "3.10" + - "3.11" + - "3.12" + - "3.13" + - "3.14" + build_options: + - pgo + build_options_conditional: + - options: + - freethreaded+pgo + minimum-python-version: "3.13" diff --git a/cpython-unix/Makefile b/cpython-unix/Makefile index 4cacaff..7e56414 100644 --- a/cpython-unix/Makefile +++ b/cpython-unix/Makefile @@ -66,7 +66,7 @@ TOOLCHAIN_DEPENDS := \ PYTHON_DEP_DEPENDS := \ $(OUTDIR)/targets/$(TARGET_TRIPLE) \ - $(if $(PYBUILD_NO_DOCKER),,$(OUTDIR)/image-$(DOCKER_IMAGE_BUILD).tar) \ + $(if $(PYBUILD_NO_DOCKER),,$(OUTDIR)/image-$(DOCKER_IMAGE_BUILD).$(HOST_PLATFORM).tar) \ $(TOOLCHAIN_DEPENDS) \ $(NULL) @@ -75,18 +75,18 @@ HOST_PYTHON_DEPENDS := $(OUTDIR)/cpython-$(PYTHON_MAJOR_VERSION)-$(CPYTHON_$(PYT default: $(OUTDIR)/cpython-$(CPYTHON_$(PYTHON_MAJOR_VERSION)_VERSION)-$(PACKAGE_SUFFIX).tar ifndef PYBUILD_NO_DOCKER -$(OUTDIR)/image-%.tar: $(OUTDIR)/%.Dockerfile +$(OUTDIR)/image-%.$(HOST_PLATFORM).tar: $(OUTDIR)/%.Dockerfile $(RUN_BUILD) --toolchain image-$* endif -$(OUTDIR)/binutils-$(BINUTILS_VERSION)-$(HOST_PLATFORM).tar: $(OUTDIR)/image-gcc.tar $(HERE)/build-binutils.sh - $(RUN_BUILD) --toolchain binutils +$(OUTDIR)/binutils-$(BINUTILS_VERSION)-$(HOST_PLATFORM).tar: $(OUTDIR)/image-$(DOCKER_IMAGE_GCC).$(HOST_PLATFORM).tar $(HERE)/build-binutils.sh + $(RUN_BUILD) --toolchain --docker-image $(DOCKER_IMAGE_GCC) binutils $(OUTDIR)/$(CLANG_FILENAME): $(RUN_BUILD) --toolchain clang --target-triple $(TARGET_TRIPLE) $(OUTDIR)/musl-$(MUSL_VERSION)-$(HOST_PLATFORM).tar: $(BASE_TOOLCHAIN_DEPENDS) $(HERE)/build-musl.sh - $(RUN_BUILD) --toolchain musl + $(RUN_BUILD) --toolchain musl --docker-image $(DOCKER_IMAGE_GCC) ifeq ($(HOST_PLATFORM),linux_x86_64) TOOLCHAIN_TARGET := $(OUTDIR)/musl-$(MUSL_VERSION)-$(HOST_PLATFORM).tar @@ -125,7 +125,7 @@ $(OUTDIR)/libffi-3.3-$(LIBFFI_3.3_VERSION)-$(PACKAGE_SUFFIX).tar: $(PYTHON_DEP_D $(OUTDIR)/libffi-$(LIBFFI_VERSION)-$(PACKAGE_SUFFIX).tar: $(PYTHON_DEP_DEPENDS) $(HERE)/build-libffi.sh $(RUN_BUILD) --docker-image $(DOCKER_IMAGE_BUILD) libffi -$(OUTDIR)/libpthread-stubs-$(LIBPTHREAD_STUBS_VERSION)-$(PACKAGE_SUFFIX).tar: $(PYTHON_DEP_DEPENDS) $(HERE)/build-libpthread-stubs.sh $(OUTDIR)/image-$(DOCKER_IMAGE_BUILD).tar +$(OUTDIR)/libpthread-stubs-$(LIBPTHREAD_STUBS_VERSION)-$(PACKAGE_SUFFIX).tar: $(PYTHON_DEP_DEPENDS) $(HERE)/build-libpthread-stubs.sh $(OUTDIR)/image-$(DOCKER_IMAGE_BUILD).$(HOST_PLATFORM).tar $(RUN_BUILD) --docker-image $(DOCKER_IMAGE_BUILD) libpthread-stubs LIBX11_DEPENDS = \ @@ -192,18 +192,14 @@ $(OUTDIR)/patchelf-$(PATCHELF_VERSION)-$(PACKAGE_SUFFIX).tar: $(PYTHON_DEP_DEPEN $(OUTDIR)/sqlite-$(SQLITE_VERSION)-$(PACKAGE_SUFFIX).tar: $(PYTHON_DEP_DEPENDS) $(HERE)/build-sqlite.sh $(RUN_BUILD) --docker-image $(DOCKER_IMAGE_BUILD) sqlite -$(OUTDIR)/tcl-$(TCL_VERSION)-$(PACKAGE_SUFFIX).tar: $(PYTHON_DEP_DEPENDS) $(HERE)/build-tcl.sh - $(RUN_BUILD) --docker-image $(DOCKER_IMAGE_BUILD) tcl - -TIX_DEPENDS = \ - $(HERE)/build-tix.sh \ - $(OUTDIR)/tcl-$(TCL_VERSION)-$(PACKAGE_SUFFIX).tar \ - $(OUTDIR)/tk-$(TK_VERSION)-$(PACKAGE_SUFFIX).tar \ - $(if $(NEED_LIBX11),$(OUTDIR)/libX11-$(LIBX11_VERSION)-$(PACKAGE_SUFFIX).tar) \ +TCL_DEPENDS = \ + $(PYTHON_DEP_DEPENDS) \ + $(HERE)/build-tcl.sh \ + $(OUTDIR)/zlib-$(ZLIB_VERSION)-$(PACKAGE_SUFFIX).tar \ $(NULL) -$(OUTDIR)/tix-$(TIX_VERSION)-$(PACKAGE_SUFFIX).tar: $(TIX_DEPENDS) - $(RUN_BUILD) --docker-image $(DOCKER_IMAGE_BUILD) tix +$(OUTDIR)/tcl-$(TCL_VERSION)-$(PACKAGE_SUFFIX).tar: $(TCL_DEPENDS) + $(RUN_BUILD) --docker-image $(DOCKER_IMAGE_BUILD) tcl TK_DEPENDS = \ $(HOST_PYTHON_DEPENDS) \ @@ -236,6 +232,9 @@ $(OUTDIR)/xz-$(XZ_VERSION)-$(PACKAGE_SUFFIX).tar: $(PYTHON_DEP_DEPENDS) $(HERE)/ $(OUTDIR)/zlib-$(ZLIB_VERSION)-$(PACKAGE_SUFFIX).tar: $(PYTHON_DEP_DEPENDS) $(HERE)/build-zlib.sh $(RUN_BUILD) --docker-image $(DOCKER_IMAGE_BUILD) zlib +$(OUTDIR)/zstd-$(ZSTD_VERSION)-$(PACKAGE_SUFFIX).tar: $(PYTHON_DEP_DEPENDS) $(HERE)/build-zstd.sh + $(RUN_BUILD) --docker-image $(DOCKER_IMAGE_BUILD) zstd + PYTHON_HOST_DEPENDS := \ $(PYTHON_DEP_DEPENDS) \ $(HERE)/build-cpython-host.sh \ @@ -268,10 +267,10 @@ PYTHON_DEPENDS_$(1) := \ $$(if $$(NEED_SQLITE),$$(OUTDIR)/sqlite-$$(SQLITE_VERSION)-$$(PACKAGE_SUFFIX).tar) \ $$(if $$(NEED_TCL),$$(OUTDIR)/tcl-$$(TCL_VERSION)-$$(PACKAGE_SUFFIX).tar) \ $$(if $$(NEED_TK),$$(OUTDIR)/tk-$$(TK_VERSION)-$$(PACKAGE_SUFFIX).tar) \ - $$(if $$(NEED_TIX),$$(OUTDIR)/tix-$$(TIX_VERSION)-$$(PACKAGE_SUFFIX).tar) \ $$(if $$(NEED_UUID),$$(OUTDIR)/uuid-$$(UUID_VERSION)-$$(PACKAGE_SUFFIX).tar) \ $$(if $$(NEED_XZ),$$(OUTDIR)/xz-$$(XZ_VERSION)-$$(PACKAGE_SUFFIX).tar) \ $$(if $$(NEED_ZLIB),$$(OUTDIR)/zlib-$$(ZLIB_VERSION)-$$(PACKAGE_SUFFIX).tar) \ + $$(if $$(NEED_ZSTD),$$(OUTDIR)/zstd-$$(ZSTD_VERSION)-$$(PACKAGE_SUFFIX).tar) \ $$(NULL) ALL_PYTHON_DEPENDS_$(1) = \ diff --git a/cpython-unix/base.Dockerfile b/cpython-unix/base.Dockerfile index 7e666e0..4838db4 100644 --- a/cpython-unix/base.Dockerfile +++ b/cpython-unix/base.Dockerfile @@ -1,6 +1,6 @@ # Debian Jessie. FROM debian@sha256:32ad5050caffb2c7e969dac873bce2c370015c2256ff984b70c1c08b3a2816a0 -MAINTAINER Gregory Szorc +LABEL org.opencontainers.image.authors="Gregory Szorc " RUN groupadd -g 1000 build && \ useradd -u 1000 -g 1000 -d /build -s /bin/bash -m build && \ diff --git a/cpython-unix/base.debian9.Dockerfile b/cpython-unix/base.debian9.Dockerfile new file mode 100644 index 0000000..28078a5 --- /dev/null +++ b/cpython-unix/base.debian9.Dockerfile @@ -0,0 +1,38 @@ +# Debian Stretch. +FROM debian@sha256:c5c5200ff1e9c73ffbf188b4a67eb1c91531b644856b4aefe86a58d2f0cb05be +LABEL org.opencontainers.image.authors="Gregory Szorc " + +RUN groupadd -g 1000 build && \ + useradd -u 1000 -g 1000 -d /build -s /bin/bash -m build && \ + mkdir /tools && \ + chown -R build:build /build /tools + +ENV HOME=/build \ + SHELL=/bin/bash \ + USER=build \ + LOGNAME=build \ + HOSTNAME=builder \ + DEBIAN_FRONTEND=noninteractive + +CMD ["/bin/bash", "--login"] +WORKDIR '/build' + +RUN for s in debian_stretch debian_stretch-updates debian-security_stretch/updates; do \ + echo "deb http://snapshot.debian.org/archive/${s%_*}/20230423T032736Z/ ${s#*_} main"; \ + done > /etc/apt/sources.list && \ + ( echo 'quiet "true";'; \ + echo 'APT::Get::Assume-Yes "true";'; \ + echo 'APT::Install-Recommends "false";'; \ + echo 'Acquire::Check-Valid-Until "false";'; \ + echo 'Acquire::Retries "5";'; \ + ) > /etc/apt/apt.conf.d/99cpython-portable + +# apt iterates all available file descriptors up to rlim_max and calls +# fcntl(fd, F_SETFD, FD_CLOEXEC). This can result in millions of system calls +# (we've seen 1B in the wild) and cause operations to take seconds to minutes. +# Setting a fd limit mitigates. +# +# Attempts at enforcing the limit globally via /etc/security/limits.conf and +# /root/.bashrc were not successful. Possibly because container image builds +# don't perform a login or use a shell the way we expect. +RUN ulimit -n 10000 && apt-get update diff --git a/cpython-unix/build-binutils.sh b/cpython-unix/build-binutils.sh index c52e823..2bb8936 100755 --- a/cpython-unix/build-binutils.sh +++ b/cpython-unix/build-binutils.sh @@ -11,9 +11,15 @@ tar -xf binutils-${BINUTILS_VERSION}.tar.xz mkdir binutils-objdir pushd binutils-objdir +if [ "$(uname -m)" = "x86_64" ]; then + triple="x86_64-unknown-linux-gnu" +else + triple="aarch64-unknown-linux-gnu" +fi + # gprofng requires a bison newer than what we have. So just disable it. ../binutils-${BINUTILS_VERSION}/configure \ - --build=x86_64-unknown-linux-gnu \ + --build=${triple} \ --prefix=/tools/host \ --enable-plugins \ --enable-gprofng=no \ diff --git a/cpython-unix/build-cpython-host.sh b/cpython-unix/build-cpython-host.sh index 99b021d..ff7c3a4 100755 --- a/cpython-unix/build-cpython-host.sh +++ b/cpython-unix/build-cpython-host.sh @@ -70,6 +70,11 @@ case "${BUILD_TRIPLE}" in EXTRA_HOST_CPPFLAGS="${EXTRA_HOST_CPPFLAGS} -I/usr/include/x86_64-linux-gnu" EXTRA_HOST_LDFLAGS="${EXTRA_HOST_LDFLAGS} -L/usr/lib/x86_64-linux-gnu" ;; + aarch64-unknown-linux-gnu) + EXTRA_HOST_CFLAGS="${EXTRA_HOST_CFLAGS} -I/usr/include/aarch64-linux-gnu" + EXTRA_HOST_CPPFLAGS="${EXTRA_HOST_CPPFLAGS} -I/usr/include/aarch64-linux-gnu" + EXTRA_HOST_LDFLAGS="${EXTRA_HOST_LDFLAGS} -L/usr/lib/aarch64-linux-gnu" + ;; *) ;; esac diff --git a/cpython-unix/build-cpython.sh b/cpython-unix/build-cpython.sh index 820b6a2..aeebf8b 100755 --- a/cpython-unix/build-cpython.sh +++ b/cpython-unix/build-cpython.sh @@ -44,7 +44,7 @@ sed "${sed_args[@]}" "s|/tools/host|${TOOLS_PATH}/host|g" ${TOOLS_PATH}/host/sha # We force linking of external static libraries by removing the shared # libraries. This is hacky. But we're building in a temporary container # and it gets the job done. -find ${TOOLS_PATH}/deps -name '*.so*' -exec rm {} \; +find ${TOOLS_PATH}/deps -name '*.so*' -a \! \( -name 'libtcl*.so*' -or -name 'libtk*.so*' \) -exec rm {} \; tar -xf Python-${PYTHON_VERSION}.tar.xz @@ -69,6 +69,15 @@ if [[ "${PYBUILD_PLATFORM}" = macos* ]]; then fi fi +# configure doesn't support cross-compiling on LoongArch. Teach it. +if [ "${PYBUILD_PLATFORM}" != "macos" ]; then + case "${PYTHON_MAJMIN_VERSION}" in + 3.9|3.10|3.11) + patch -p1 -i ${ROOT}/patch-configure-add-loongarch-triplet.patch + ;; + esac +fi + # disable readelf check when cross-compiling on older Python versions if [ -n "${CROSS_COMPILING}" ]; then if [ -n "${PYTHON_MEETS_MAXIMUM_VERSION_3_11}" ]; then @@ -76,13 +85,6 @@ if [ -n "${CROSS_COMPILING}" ]; then fi fi -# `uuid.getnode()` is not stable on our libuuid, CPython should fallback to another method -# Cherry-pick https://github.com/python/cpython/pull/134704 until it is released -# We could backport this to more versions too, it won't be done by the upstream -if [[ -n "${PYTHON_MEETS_MINIMUM_VERSION_3_13}" && -n "${PYTHON_MEETS_MAXIMUM_VERSION_3_13}" ]]; then - patch -p1 -i ${ROOT}/patch-uuid-getnode-stable-3.13.patch -fi - # This patch is slightly different on Python 3.10+. if [ -n "${PYTHON_MEETS_MINIMUM_VERSION_3_10}" ]; then patch -p1 -i ${ROOT}/patch-xopen-source-ios.patch @@ -90,12 +92,6 @@ else patch -p1 -i ${ROOT}/patch-xopen-source-ios-legacy.patch fi -# See https://github.com/python/cpython/pull/135146 -# TODO(zanieb): Drop in 3.14b3 -if [ -n "${PYTHON_MEETS_MINIMUM_VERSION_3_14}" ]; then - patch -p1 -i ${ROOT}/patch-static-remote-debug-3.14.patch -fi - # LIBTOOL_CRUFT is unused and breaks cross-compiling on macOS. Nuke it. # Submitted upstream at https://github.com/python/cpython/pull/101048. if [ -n "${PYTHON_MEETS_MAXIMUM_VERSION_3_11}" ]; then @@ -122,17 +118,12 @@ fi # Clang 13 actually prints something with --print-multiarch, confusing CPython's # configure. This is reported as https://bugs.python.org/issue45405. We nerf the # check since we know what we're doing. -if [ "${CC}" = "clang" ]; then +if [[ "${CC}" = "clang" || "${CC}" = "musl-clang" ]]; then if [ -n "${PYTHON_MEETS_MINIMUM_VERSION_3_13}" ]; then patch -p1 -i ${ROOT}/patch-disable-multiarch-13.patch else patch -p1 -i ${ROOT}/patch-disable-multiarch.patch fi -elif [ "${CC}" = "musl-clang" ]; then - # Similarly, this is a problem for musl Clang on Python 3.13+ - if [ -n "${PYTHON_MEETS_MINIMUM_VERSION_3_13}" ]; then - patch -p1 -i ${ROOT}/patch-disable-multiarch-13.patch - fi fi # Python 3.11 supports using a provided Python to use during bootstrapping @@ -383,6 +374,16 @@ if [[ -n "${PYTHON_MEETS_MINIMUM_VERSION_3_12}" && "${TARGET_TRIPLE}" = "ppc64le LDFLAGS="${LDFLAGS} -Wl,--no-tls-get-addr-optimize" fi +# We're calling install_name_tool -add_rpath on extension modules, which +# eats up 0x20 bytes of space in the Mach-O header, and we need to make +# sure there's still enough room to add a code signature (0x10 bytes) on +# non-arm64 where there's no automatic ad-hoc signature. We are somehow +# on a toolchain that doesn't make sure there's enough space by default +# so give it plenty of space. +if [[ "${PYBUILD_PLATFORM}" = macos* ]]; then + LDFLAGS="${LDFLAGS} -Wl,-headerpad,40" +fi + CPPFLAGS=$CFLAGS CONFIGURE_FLAGS=" @@ -478,17 +479,16 @@ if [ -n "${CPYTHON_OPTIMIZED}" ]; then if [[ -n "${PYTHON_MEETS_MINIMUM_VERSION_3_13}" ]]; then # Do not enable on x86-64 macOS because the JIT requires macOS 11+ and we are currently - # using 10.15 as a miniumum version. + # using 10.15 as a minimum version. # Do not enable when free-threading, because they're not compatible yet. if [[ ! ( "${TARGET_TRIPLE}" == "x86_64-apple-darwin" || -n "${CPYTHON_FREETHREADED}" ) ]]; then CONFIGURE_FLAGS="${CONFIGURE_FLAGS} --enable-experimental-jit=yes-off" fi # Respect CFLAGS during JIT compilation. + # # Backports https://github.com/python/cpython/pull/134276 - if [ -n "${PYTHON_MEETS_MINIMUM_VERSION_3_14}" ]; then - patch -p1 -i ${ROOT}/patch-jit-cflags-314.patch - elif [ -n "${PYTHON_MEETS_MINIMUM_VERSION_3_13}" ]; then + if [[ -n "${PYTHON_MEETS_MINIMUM_VERSION_3_13}" && -n "${PYTHON_MEETS_MAXIMUM_VERSION_3_13}" ]]; then patch -p1 -i ${ROOT}/patch-jit-cflags-313.patch fi @@ -653,7 +653,19 @@ fi # We patched configure.ac above. Reflect those changes. autoconf -CFLAGS=$CFLAGS CPPFLAGS=$CFLAGS LDFLAGS=$LDFLAGS \ +# Ensure `CFLAGS` are propagated to JIT compilation for 3.13+ (note this variable has no effect on +# 3.12 and earlier) +CFLAGS_JIT="${CFLAGS}" + +# In 3.14+, the JIT compiler on x86-64 Linux uses a model that conflicts with `-fPIC`, so strip it +# from the flags. See: +# - https://github.com/python/cpython/issues/135690 +# - https://github.com/python/cpython/pull/130097 +if [[ -n "${PYTHON_MEETS_MINIMUM_VERSION_3_14}" && "${TARGET_TRIPLE}" == x86_64* ]]; then + CFLAGS_JIT="${CFLAGS_JIT//-fPIC/}" +fi + +CFLAGS=$CFLAGS CPPFLAGS=$CFLAGS CFLAGS_JIT=$CFLAGS_JIT LDFLAGS=$LDFLAGS \ ./configure ${CONFIGURE_FLAGS} # Supplement produced Makefile with our modifications. @@ -700,6 +712,8 @@ if [ "${PYBUILD_SHARED}" = "1" ]; then ${ROOT}/out/python/install/bin/python${PYTHON_MAJMIN_VERSION} # Python's build system doesn't make this file writable. + # TODO(geofft): @executable_path/ is a weird choice here, who is + # relying on it? Should probably be @loader_path. chmod 755 ${ROOT}/out/python/install/lib/${LIBPYTHON_SHARED_LIBRARY_BASENAME} install_name_tool \ -change /install/lib/${LIBPYTHON_SHARED_LIBRARY_BASENAME} @executable_path/${LIBPYTHON_SHARED_LIBRARY_BASENAME} \ @@ -718,6 +732,13 @@ if [ "${PYBUILD_SHARED}" = "1" ]; then -change /install/lib/${LIBPYTHON_SHARED_LIBRARY_BASENAME} @executable_path/../lib/${LIBPYTHON_SHARED_LIBRARY_BASENAME} \ ${ROOT}/out/python/install/bin/python${PYTHON_MAJMIN_VERSION}${PYTHON_BINARY_SUFFIX} fi + + # At the moment, python3 and libpython don't have shared-library + # dependencies, but at some point we will want to run this for + # them too. + for module in ${ROOT}/out/python/install/lib/python*/lib-dynload/*.so; do + install_name_tool -add_rpath @loader_path/../.. "$module" + done else # (not macos) LIBPYTHON_SHARED_LIBRARY_BASENAME=libpython${PYTHON_MAJMIN_VERSION}${PYTHON_BINARY_SUFFIX}.so.1.0 LIBPYTHON_SHARED_LIBRARY=${ROOT}/out/python/install/lib/${LIBPYTHON_SHARED_LIBRARY_BASENAME} @@ -1075,8 +1096,14 @@ touch "${LIB_DYNLOAD}/.empty" # Symlink libpython so we don't have 2 copies. case "${TARGET_TRIPLE}" in -aarch64-unknown-linux-gnu) - PYTHON_ARCH="aarch64-linux-gnu" +aarch64-unknown-linux-*) + # In Python 3.13+, the musl target is identified in cross compiles and the output directory + # is named accordingly. + if [[ "${CC}" = "musl-clang" && -n "${PYTHON_MEETS_MINIMUM_VERSION_3_13}" ]]; then + PYTHON_ARCH="aarch64-linux-musl" + else + PYTHON_ARCH="aarch64-linux-gnu" + fi ;; # This is too aggressive. But we don't have patches in place for # setting the platform name properly on non-Darwin. @@ -1089,6 +1116,9 @@ armv7-unknown-linux-gnueabi) armv7-unknown-linux-gnueabihf) PYTHON_ARCH="arm-linux-gnueabihf" ;; +loongarch64-unknown-linux-gnu) + PYTHON_ARCH="loongarch64-linux-gnu" + ;; mips-unknown-linux-gnu) PYTHON_ARCH="mips-linux-gnu" ;; @@ -1205,7 +1235,7 @@ ${BUILD_PYTHON} ${ROOT}/fix_shebangs.py ${ROOT}/out/python/install # downstream consumers. OBJECT_DIRS="Objects Parser Parser/lexer Parser/pegen Parser/tokenizer Programs Python Python/deepfreeze" OBJECT_DIRS="${OBJECT_DIRS} Modules" -for ext in _blake2 cjkcodecs _ctypes _ctypes/darwin _decimal _expat _hacl _io _multiprocessing _sha3 _sqlite _sre _testinternalcapi _xxtestfuzz ; do +for ext in _blake2 cjkcodecs _ctypes _ctypes/darwin _decimal _expat _hacl _io _multiprocessing _sha3 _sqlite _sre _testinternalcapi _xxtestfuzz _zstd; do OBJECT_DIRS="${OBJECT_DIRS} Modules/${ext}" done @@ -1239,16 +1269,20 @@ fi rm -f ${ROOT}/out/python/build/lib/{libdb-6.0,libxcb-*,libX11-xcb}.a if [ -d "${TOOLS_PATH}/deps/lib/tcl8" ]; then - # Copy tcl/tk/tix resources needed by tkinter. + # Copy tcl/tk resources needed by tkinter. mkdir ${ROOT}/out/python/install/lib/tcl # Keep this list in sync with tcl_library_paths. for source in ${TOOLS_PATH}/deps/lib/{itcl4.2.4,tcl8,tcl8.6,thread2.8.9,tk8.6}; do cp -av $source ${ROOT}/out/python/install/lib/ done - if [[ "${PYBUILD_PLATFORM}" != macos* ]]; then - cp -av ${TOOLS_PATH}/deps/lib/Tix8.4.3 ${ROOT}/out/python/install/lib/ - fi + ( + shopt -s nullglob + dylibs=(${TOOLS_PATH}/deps/lib/lib*.dylib ${TOOLS_PATH}/deps/lib/lib*.so) + if [ "${#dylibs[@]}" -gt 0 ]; then + cp -av "${dylibs[@]}" ${ROOT}/out/python/install/lib/ + fi + ) fi # Copy the terminfo database if present. diff --git a/cpython-unix/build-libX11.sh b/cpython-unix/build-libX11.sh index bb45028..7407570 100755 --- a/cpython-unix/build-libX11.sh +++ b/cpython-unix/build-libX11.sh @@ -54,6 +54,9 @@ if [ -n "${CROSS_COMPILING}" ]; then armv7-unknown-linux-gnueabihf) EXTRA_FLAGS="${EXTRA_FLAGS} --enable-malloc0returnsnull" ;; + loongarch64-unknown-linux-gnu) + EXTRA_FLAGS="${EXTRA_FLAGS} --enable-malloc0returnsnull" + ;; mips-unknown-linux-gnu) EXTRA_FLAGS="${EXTRA_FLAGS} --enable-malloc0returnsnull" ;; @@ -78,6 +81,9 @@ if [ -n "${CROSS_COMPILING}" ]; then aarch64-unknown-linux-musl) EXTRA_FLAGS="${EXTRA_FLAGS} --enable-malloc0returnsnull" ;; + loongarch64-unknown-linux-musl) + EXTRA_FLAGS="${EXTRA_FLAGS} --enable-malloc0returnsnull" + ;; mips-unknown-linux-musl) EXTRA_FLAGS="${EXTRA_FLAGS} --enable-malloc0returnsnull" ;; @@ -99,6 +105,11 @@ if [ -n "${CROSS_COMPILING}" ]; then esac fi +# Avoid dlopen("libXcursor.so.1") from the OS, which can go horribly wrong. We +# might not need to avoid this if we switch to shipping X11 as shared +# libraries, and ideally if we ship libXcursor ourselves. +EXTRA_FLAGS="${EXTRA_FLAGS} --disable-loadable-xcursor" + # CC_FOR_BUILD is here because configure doesn't look for `clang` when # cross-compiling. So we force it. CFLAGS="${EXTRA_TARGET_CFLAGS} -fPIC -I/tools/deps/include" \ diff --git a/cpython-unix/build-libedit.sh b/cpython-unix/build-libedit.sh index 08387ec..6122059 100755 --- a/cpython-unix/build-libedit.sh +++ b/cpython-unix/build-libedit.sh @@ -82,6 +82,32 @@ index 614795f..4671f1b 100755 fi EOF +# When libedit receives a signal, it re-broadcasts it to its entire pgroup. +# This seems intended to preserve normal ^C behavior in "raw" mode when the +# terminal's ISIG flag is cleared? However, libedit does not in fact clear +# ISIG. (And Jack can't find any evidence of any version that ever did.) This +# sometimes results in the parent process receiving ^C twice back-to-back, +# depending on the vagaries of signal coalescing. More pathologically, if the +# parent tries to signal the child directly with e.g. `kill(pid, SIGTERM)`, +# libedit *signals the parent right back* (not to mention any other pgroup +# siblings or grandparents). This is just wild behavior, even though it's +# probably rare that it matters in practice. Patch it out. See also: +# https://github.com/astral-sh/uv/issues/13919#issuecomment-2960501229. +patch -p1 << "EOF" +diff --git i/src/sig.c w/src/sig.c +index d2b77e7..884b2dd 100644 +--- i/src/sig.c ++++ w/src/sig.c +@@ -107,7 +107,7 @@ sig_handler(int signo) + sel->el_signal->sig_action[i].sa_flags = 0; + sigemptyset(&sel->el_signal->sig_action[i].sa_mask); + (void) sigprocmask(SIG_SETMASK, &oset, NULL); +- (void) kill(0, signo); ++ (void) raise(signo); + errno = save_errno; + } +EOF + cflags="${EXTRA_TARGET_CFLAGS} -fPIC -I${TOOLS_PATH}/deps/include -I${TOOLS_PATH}/deps/include/ncursesw" ldflags="${EXTRA_TARGET_LDFLAGS} -L${TOOLS_PATH}/deps/lib" diff --git a/cpython-unix/build-libffi.sh b/cpython-unix/build-libffi.sh index 9b18802..562d4d5 100755 --- a/cpython-unix/build-libffi.sh +++ b/cpython-unix/build-libffi.sh @@ -225,7 +225,7 @@ index 60cfa50..6a9a561 100644 BTI_C - /* Sign the lr with x1 since that is where it will be stored */ + PAC_CFI_WINDOW_SAVE -+ /* Sign the lr with x1 since that is the CFA which is the modifer used in auth instructions */ ++ /* Sign the lr with x1 since that is the CFA which is the modifier used in auth instructions */ SIGN_LR_WITH_REG(x1) - /* Use a stack frame allocated by our caller. */ @@ -352,7 +352,7 @@ index 6a9a561..e83bc65 100644 + cfi_startproc BTI_C PAC_CFI_WINDOW_SAVE - /* Sign the lr with x1 since that is the CFA which is the modifer used in auth instructions */ + /* Sign the lr with x1 since that is the CFA which is the modifier used in auth instructions */ @@ -348,8 +348,8 @@ CNAME(ffi_closure_SYSV_V): #endif diff --git a/cpython-unix/build-libxcb.sh b/cpython-unix/build-libxcb.sh index 0b6cb91..1076157 100755 --- a/cpython-unix/build-libxcb.sh +++ b/cpython-unix/build-libxcb.sh @@ -13,6 +13,12 @@ export PKG_CONFIG_PATH=/tools/deps/share/pkgconfig:/tools/deps/lib/pkgconfig tar -xf libxcb-${LIBXCB_VERSION}.tar.gz pushd libxcb-${LIBXCB_VERSION} +if [[ "${TARGET_TRIPLE}" = loongarch64* ]]; then + rm -f build-aux/config.guess build-aux/config.sub + curl -sSL -o build-aux/config.guess 'https://git.savannah.gnu.org/cgit/config.git/plain/config.guess' + curl -sSL -o build-aux/config.sub 'https://git.savannah.gnu.org/cgit/config.git/plain/config.sub' +fi + if [ "${CC}" = "musl-clang" ]; then EXTRA_FLAGS="--disable-shared" fi diff --git a/cpython-unix/build-main.py b/cpython-unix/build-main.py index a353daf..e4276be 100755 --- a/cpython-unix/build-main.py +++ b/cpython-unix/build-main.py @@ -95,6 +95,8 @@ def main(): "toolchain-image-build", "toolchain-image-build.cross", "toolchain-image-build.cross-riscv64", + "toolchain-image-build.cross-loongarch64", + "toolchain-image-build.debian9", "toolchain-image-gcc", "toolchain-image-xcb", "toolchain-image-xcb.cross", @@ -181,7 +183,7 @@ def main(): # because we can get some speedup from parallel operations. But we also don't # share a make job server with each build. So if we didn't limit the # parallelism we could easily oversaturate the CPU. Higher levels of - # parallelism don't result in meaningful build speedups because tk/tix has + # parallelism don't result in meaningful build speedups because tk has # a long, serial dependency chain that can't be built in parallel. parallelism = min(1 if args.serial else 4, multiprocessing.cpu_count()) diff --git a/cpython-unix/build-ncurses.sh b/cpython-unix/build-ncurses.sh index 25df7e2..cedeb70 100755 --- a/cpython-unix/build-ncurses.sh +++ b/cpython-unix/build-ncurses.sh @@ -109,6 +109,8 @@ else " fi +mkdir -p ${ROOT}/out/usr/lib + CFLAGS="${EXTRA_TARGET_CFLAGS} -fPIC" CPPFLAGS="${EXTRA_TARGET_CFLAGS} -fPIC" LDFLAGS="${EXTRA_TARGET_LDFLAGS}" ./configure ${CONFIGURE_FLAGS} make -j ${NUM_CPUS} make -j ${NUM_CPUS} install DESTDIR=${ROOT}/out diff --git a/cpython-unix/build-sqlite.sh b/cpython-unix/build-sqlite.sh index b045bb8..ef7c6a6 100755 --- a/cpython-unix/build-sqlite.sh +++ b/cpython-unix/build-sqlite.sh @@ -14,7 +14,7 @@ pushd sqlite-autoconf-${SQLITE_VERSION} CONFIGURE_FLAGS="--build=${BUILD_TRIPLE} --host=${TARGET_TRIPLE}" -CONFIGURE_FLAGS="${CONFIGURE_FLAGS} --prefix /tools/deps --disable-shared" +CONFIGURE_FLAGS="${CONFIGURE_FLAGS} --prefix=/tools/deps --disable-shared" if [ "${TARGET_TRIPLE}" = "aarch64-apple-ios" ]; then CONFIGURE_FLAGS="${CONFIGURE_FLAGS} ac_cv_search_system=no" @@ -22,7 +22,26 @@ elif [ "${TARGET_TRIPLE}" = "x86_64-apple-ios" ]; then CONFIGURE_FLAGS="${CONFIGURE_FLAGS} ac_cv_search_system=no" fi -CFLAGS="${EXTRA_TARGET_CFLAGS} -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_FTS3 -DSQLITE_ENABLE_FTS3_PARENTHESIS -DSQLITE_ENABLE_FTS3_TOKENIZER -fPIC" CPPFLAGS="${EXTRA_TARGET_CFLAGS} -fPIC" LDFLAGS="${EXTRA_TARGET_LDFLAGS}" ./configure ${CONFIGURE_FLAGS} - -make -j ${NUM_CPUS} -make -j ${NUM_CPUS} install DESTDIR=${ROOT}/out +# The SQLite autosetup looks for the C++ compiler if the variable is set and will fail if it's not +# found, even if it's not needed. We don't actually have a C++ compiler in some builds, so ensure +# it's not looked for. +unset CXX + +CC_FOR_BUILD="${HOST_CC}" \ +CFLAGS="${EXTRA_TARGET_CFLAGS} \ + -DSQLITE_ENABLE_DBSTAT_VTAB \ + -DSQLITE_ENABLE_FTS3 \ + -DSQLITE_ENABLE_FTS3_PARENTHESIS \ + -DSQLITE_ENABLE_FTS3_TOKENIZER \ + -DSQLITE_ENABLE_FTS4 \ + -DSQLITE_ENABLE_FTS5 \ + -DSQLITE_ENABLE_GEOPOLY \ + -DSQLITE_ENABLE_RTREE \ + -fPIC" \ +CPPFLAGS="${EXTRA_TARGET_CFLAGS} -fPIC" \ +LDFLAGS="${EXTRA_TARGET_LDFLAGS}" ./configure ${CONFIGURE_FLAGS} + +make -j ${NUM_CPUS} libsqlite3.a +make install-lib DESTDIR=${ROOT}/out +make install-headers DESTDIR=${ROOT}/out +make install-pc DESTDIR=${ROOT}/out diff --git a/cpython-unix/build-tcl.sh b/cpython-unix/build-tcl.sh index 43a4a6a..bfbc22f 100755 --- a/cpython-unix/build-tcl.sh +++ b/cpython-unix/build-tcl.sh @@ -7,6 +7,12 @@ set -ex ROOT=`pwd` +# Force linking to static libraries from our dependencies. +# TODO(geofft): This is copied from build-cpython.sh. Really this should +# be done at the end of the build of each dependency, rather than before +# the build of each consumer. +find ${TOOLS_PATH}/deps -name '*.so*' -exec rm {} \; + export PATH=${TOOLS_PATH}/${TOOLCHAIN}/bin:${TOOLS_PATH}/host/bin:$PATH export PKG_CONFIG_PATH=${TOOLS_PATH}/deps/share/pkgconfig:${TOOLS_PATH}/deps/lib/pkgconfig @@ -20,9 +26,8 @@ if [ -n "${STATIC}" ]; then # `checking whether musl-clang accepts -g...` fails with a duplicate definition error TARGET_TRIPLE="$(echo "${TARGET_TRIPLE}" | sed -e 's/-unknown-linux-musl/-unknown-linux-gnu/g')" fi -fi -patch -p1 << 'EOF' + patch -p1 << 'EOF' diff --git a/unix/Makefile.in b/unix/Makefile.in --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -36,6 +41,7 @@ diff --git a/unix/Makefile.in b/unix/Makefile.in fi; \ fi; \ EOF +fi # Remove packages we don't care about and can pull in unwanted symbols. rm -rf pkgs/sqlite* pkgs/tdbc* @@ -43,17 +49,23 @@ rm -rf pkgs/sqlite* pkgs/tdbc* pushd unix CFLAGS="${EXTRA_TARGET_CFLAGS} -fPIC -I${TOOLS_PATH}/deps/include" +LDFLAGS="${EXTRA_TARGET_CFLAGS} -L${TOOLS_PATH}/deps/lib" +if [[ "${PYBUILD_PLATFORM}" != macos* ]]; then + LDFLAGS="${LDFLAGS} -Wl,--exclude-libs,ALL" +fi -CFLAGS="${CFLAGS}" CPPFLAGS="${CFLAGS}" LDFLAGS="${EXTRA_TARGET_LDFLAGS}" ./configure \ +CFLAGS="${CFLAGS}" CPPFLAGS="${CFLAGS}" LDFLAGS="${LDFLAGS}" ./configure \ --build=${BUILD_TRIPLE} \ --host=${TARGET_TRIPLE} \ --prefix=/tools/deps \ - --enable-shared=no \ + --enable-shared"${STATIC:+=no}" \ --enable-threads -make -j ${NUM_CPUS} -make -j ${NUM_CPUS} install DESTDIR=${ROOT}/out +make -j ${NUM_CPUS} DYLIB_INSTALL_DIR=@rpath +make -j ${NUM_CPUS} install DESTDIR=${ROOT}/out DYLIB_INSTALL_DIR=@rpath make -j ${NUM_CPUS} install-private-headers DESTDIR=${ROOT}/out -# For some reason libtcl*.a have weird permissions. Fix that. -chmod 644 ${ROOT}/out/tools/deps/lib/libtcl*.a +if [ -n "${STATIC}" ]; then + # For some reason libtcl*.a have weird permissions. Fix that. + chmod 644 ${ROOT}/out/tools/deps/lib/libtcl*.a +fi diff --git a/cpython-unix/build-tk.sh b/cpython-unix/build-tk.sh index 2769a63..bd936c8 100755 --- a/cpython-unix/build-tk.sh +++ b/cpython-unix/build-tk.sh @@ -7,6 +7,12 @@ set -ex ROOT=`pwd` +# Force linking to static libraries from our dependencies. +# TODO(geofft): This is copied from build-cpython.sh. Really this should +# be done at the end of the build of each dependency, rather than before +# the build of each consumer. +find ${TOOLS_PATH}/deps -name '*.so*' -exec rm {} \; + export PATH=${TOOLS_PATH}/deps/bin:${TOOLS_PATH}/${TOOLCHAIN}/bin:${TOOLS_PATH}/host/bin:$PATH export PKG_CONFIG_PATH=${TOOLS_PATH}/deps/share/pkgconfig:${TOOLS_PATH}/deps/lib/pkgconfig @@ -23,6 +29,7 @@ if [[ "${PYBUILD_PLATFORM}" = macos* ]]; then LDFLAGS="-L${TOOLS_PATH}/deps/lib" EXTRA_CONFIGURE_FLAGS="--enable-aqua=yes --without-x" else + LDFLAGS="${LDFLAGS} -Wl,--exclude-libs,ALL" EXTRA_CONFIGURE_FLAGS="--x-includes=${TOOLS_PATH}/deps/include --x-libraries=${TOOLS_PATH}/deps/lib" fi @@ -31,29 +38,38 @@ CFLAGS="${CFLAGS}" CPPFLAGS="${CFLAGS}" LDFLAGS="${LDFLAGS}" ./configure \ --host=${TARGET_TRIPLE} \ --prefix=/tools/deps \ --with-tcl=${TOOLS_PATH}/deps/lib \ - --enable-shared=no \ + --enable-shared"${STATIC:+=no}" \ --enable-threads \ ${EXTRA_CONFIGURE_FLAGS} # Remove wish, since we don't need it. -if [[ "${PYBUILD_PLATFORM}" != macos* ]]; then - sed -i 's/all: binaries libraries doc/all: libraries/' Makefile - sed -i 's/install-binaries: $(TK_STUB_LIB_FILE) $(TK_LIB_FILE) ${WISH_EXE}/install-binaries: $(TK_STUB_LIB_FILE) $(TK_LIB_FILE)/' Makefile +if [[ "${PYBUILD_PLATFORM}" = macos* ]]; then + sed_args=(-i '' -e) +else + sed_args=(-i) fi +sed "${sed_args[@]}" 's/all: binaries libraries doc/all: libraries/' Makefile +sed "${sed_args[@]}" 's/install-binaries: $(TK_STUB_LIB_FILE) $(TK_LIB_FILE) ${WISH_EXE}/install-binaries: $(TK_STUB_LIB_FILE) $(TK_LIB_FILE)/' Makefile -# For some reason musl isn't link libXau and libxcb. So we hack the Makefile -# to do what we want. -if [ "${CC}" = "musl-clang" ]; then - sed -i 's/-ldl -lpthread /-ldl -lpthread -lXau -lxcb/' tkConfig.sh - sed -i 's/-lpthread $(X11_LIB_SWITCHES) -ldl -lpthread/-lpthread $(X11_LIB_SWITCHES) -ldl -lpthread -lXau -lxcb/' Makefile +# We are statically linking libX11, and static libraries do not carry +# information about dependencies. pkg-config --static does, but Tcl/Tk's +# build system apparently is too old for that. So we need to manually +# inform the build process that libX11.a needs libxcb.a and libXau.a. +# Note that the order is significant, for static libraries: X11 requires +# xcb, which requires Xau. +MAKE_VARS=(DYLIB_INSTALL_DIR=@rpath) +if [[ "${PYBUILD_PLATFORM}" != macos* ]]; then + MAKE_VARS+=(X11_LIB_SWITCHES="-lX11 -lxcb -lXau") fi -make -j ${NUM_CPUS} +make -j ${NUM_CPUS} "${MAKE_VARS[@]}" touch wish -make -j ${NUM_CPUS} install DESTDIR=${ROOT}/out +make -j ${NUM_CPUS} install DESTDIR=${ROOT}/out "${MAKE_VARS[@]}" make -j ${NUM_CPUS} install-private-headers DESTDIR=${ROOT}/out # For some reason libtk*.a have weird permissions. Fix that. -chmod 644 /${ROOT}/out/tools/deps/lib/libtk*.a +if [ -n "${STATIC}" ]; then + chmod 644 /${ROOT}/out/tools/deps/lib/libtk*.a +fi rm ${ROOT}/out/tools/deps/bin/wish* diff --git a/cpython-unix/build-xorgproto.sh b/cpython-unix/build-xorgproto.sh index 97c1aa4..99c5db0 100755 --- a/cpython-unix/build-xorgproto.sh +++ b/cpython-unix/build-xorgproto.sh @@ -15,6 +15,12 @@ export PKG_CONFIG_PATH=/tools/deps/share/pkgconfig tar -xf xorgproto-${XORGPROTO_VERSION}.tar.gz pushd xorgproto-${XORGPROTO_VERSION} +if [[ "${TARGET_TRIPLE}" = loongarch64* ]]; then + rm -f config.guess.sub config.sub + curl -sSL -o config.guess 'https://git.savannah.gnu.org/cgit/config.git/plain/config.guess' + curl -sSL -o config.sub 'https://git.savannah.gnu.org/cgit/config.git/plain/config.sub' +fi + CFLAGS="${EXTRA_TARGET_CFLAGS} -fPIC" CPPFLAGS="${EXTRA_TARGET_CFLAGS} -fPIC" LDFLAGS="${EXTRA_TARGET_LDFLAGS}" ./configure \ --build=${BUILD_TRIPLE} \ --host=${TARGET_TRIPLE} \ diff --git a/cpython-unix/build-zstd.sh b/cpython-unix/build-zstd.sh new file mode 100755 index 0000000..bcce804 --- /dev/null +++ b/cpython-unix/build-zstd.sh @@ -0,0 +1,85 @@ +#!/usr/bin/env bash +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at https://mozilla.org/MPL/2.0/. + +set -ex + +ROOT=`pwd` + +export PATH=${TOOLS_PATH}/${TOOLCHAIN}/bin:${TOOLS_PATH}/host/bin:$PATH +export PREFIX="/tools/deps" + +tar -xf zstd-${ZSTD_VERSION}.tar.gz + +pushd cpython-source-deps-zstd-${ZSTD_VERSION}/lib + +if [ "${CC}" = "musl-clang" ]; then + # In order to build the library with intrinsics, we need musl-clang to find + # headers that provide access to the intrinsics, as they are not provided by musl. These are + # part of the include files that are part of clang. But musl-clang eliminates them from the + # default include path. So copy them into place. + for h in ${TOOLS_PATH}/${TOOLCHAIN}/lib/clang/*/include/*intrin.h ${TOOLS_PATH}/${TOOLCHAIN}/lib/clang/*/include/{__wmmintrin_aes.h,__wmmintrin_pclmul.h,emmintrin.h,immintrin.h,mm_malloc.h,arm_neon.h,arm_neon_sve_bridge.h,arm_bf16.h,arm_fp16.h,arm_acle.h,arm_vector_types.h}; do + filename=$(basename "$h") + if [ -f "$h" ]; then + if [ -e "${TOOLS_PATH}/host/include/${filename}" ]; then + echo "warning: ${filename} already exists" + fi + cp "$h" ${TOOLS_PATH}/host/include/ + else + echo "warning: ${filename} not found (skipping)" + fi + done + EXTRA_TARGET_CFLAGS="${EXTRA_TARGET_CFLAGS} -I${TOOLS_PATH}/host/include/" + + # `qsort_r` is only available in musl 1.2.3+ but we use 1.2.2. The zstd source provides a + # fallback implementation, but they do not have a `configure`-style detection of whether + # `qsort_r` is actually available so we patch it to include a check for glibc. + patch -p1 <suffix, ctx->suffixSize, sizeof(U32), + ctx, + (ctx->d <= 8 ? &COVER_strict_cmp8 : &COVER_strict_cmp)); +-#elif defined(_GNU_SOURCE) ++#elif defined(_GNU_SOURCE) && defined(__GLIBC__) + qsort_r(ctx->suffix, ctx->suffixSize, sizeof(U32), + (ctx->d <= 8 ? &COVER_strict_cmp8 : &COVER_strict_cmp), + ctx); +EOF +fi + +CFLAGS="${EXTRA_TARGET_CFLAGS} -fPIC -DZSTD_MULTITHREAD -O3" LDFLAGS="${EXTRA_TARGET_LDFLAGS}" make -j ${NUM_CPUS} VERBOSE=1 libzstd.a +make -j ${NUM_CPUS} install-static DESTDIR=${ROOT}/out +make -j ${NUM_CPUS} install-includes DESTDIR=${ROOT}/out +MT=1 make -j ${NUM_CPUS} install-pc DESTDIR=${ROOT}/out diff --git a/cpython-unix/build.Dockerfile b/cpython-unix/build.Dockerfile index e44d0a2..5a5dcad 100644 --- a/cpython-unix/build.Dockerfile +++ b/cpython-unix/build.Dockerfile @@ -9,6 +9,8 @@ # Various other build tools are needed for various building. RUN ulimit -n 10000 && apt-get install \ bzip2 \ + ca-certificates \ + curl \ file \ libc6-dev \ libffi-dev \ diff --git a/cpython-unix/build.cross-loongarch64.Dockerfile b/cpython-unix/build.cross-loongarch64.Dockerfile new file mode 100644 index 0000000..fc1f27b --- /dev/null +++ b/cpython-unix/build.cross-loongarch64.Dockerfile @@ -0,0 +1,64 @@ +# Debian Trixie. +FROM debian@sha256:5e64db7e29879fbb479ab2c6324656c9c0e489423e4885ed7e2f22c5b58a7a9b +LABEL org.opencontainers.image.authors="Gregory Szorc " + +RUN groupadd -g 1000 build && \ + useradd -u 1000 -g 1000 -d /build -s /bin/bash -m build && \ + mkdir /tools && \ + chown -R build:build /build /tools + +ENV HOME=/build \ + SHELL=/bin/bash \ + USER=build \ + LOGNAME=build \ + HOSTNAME=builder \ + DEBIAN_FRONTEND=noninteractive + +CMD ["/bin/bash", "--login"] +WORKDIR '/build' + +RUN for s in debian_trixie debian_trixie-updates; do \ + echo "deb http://snapshot.debian.org/archive/${s%_*}/20240812T212427Z/ ${s#*_} main"; \ + done > /etc/apt/sources.list && \ + for s in debian-security_trixie-security/updates; do \ + echo "deb http://snapshot.debian.org/archive/${s%_*}/20240813T064849Z/ ${s#*_} main"; \ + done >> /etc/apt/sources.list && \ + ( echo 'quiet "true";'; \ + echo 'APT::Get::Assume-Yes "true";'; \ + echo 'APT::Install-Recommends "false";'; \ + echo 'Acquire::Check-Valid-Until "false";'; \ + echo 'Acquire::Retries "5";'; \ + ) > /etc/apt/apt.conf.d/99cpython-portable && \ + rm -f /etc/apt/sources.list.d/* + +RUN apt-get update + +# Host building. +RUN apt-get install \ + bzip2 \ + ca-certificates \ + curl \ + gcc \ + g++ \ + libc6-dev \ + libffi-dev \ + make \ + patch \ + perl \ + pkg-config \ + tar \ + xz-utils \ + unzip \ + zip \ + zlib1g-dev + +RUN apt-get install \ + gcc-loongarch64-linux-gnu \ + libc6-dev-loong64-cross + +RUN cd /tmp && \ + curl -LO https://snapshot.debian.org/archive/debian-ports/20240812T192057Z/pool-loong64/main/libx/libxcrypt/libcrypt-dev_4.4.36-4_loong64.deb && \ + curl -LO https://snapshot.debian.org/archive/debian-ports/20240812T192057Z/pool-loong64/main/libx/libxcrypt/libcrypt1_4.4.36-4_loong64.deb && \ + dpkg -x libcrypt-dev_4.4.36-4_loong64.deb / && \ + dpkg -x libcrypt1_4.4.36-4_loong64.deb / && \ + rm -f /tmp/*.deb diff --git a/cpython-unix/build.cross-riscv64.Dockerfile b/cpython-unix/build.cross-riscv64.Dockerfile index 740a098..6114fe7 100644 --- a/cpython-unix/build.cross-riscv64.Dockerfile +++ b/cpython-unix/build.cross-riscv64.Dockerfile @@ -1,6 +1,6 @@ # Debian Buster. FROM debian@sha256:2a0c1b9175adf759420fe0fbd7f5b449038319171eb76554bb76cbe172b62b42 -MAINTAINER Gregory Szorc +LABEL org.opencontainers.image.authors="Gregory Szorc " RUN groupadd -g 1000 build && \ useradd -u 1000 -g 1000 -d /build -s /bin/bash -m build && \ diff --git a/cpython-unix/build.cross.Dockerfile b/cpython-unix/build.cross.Dockerfile index aa17d6c..d8e557f 100644 --- a/cpython-unix/build.cross.Dockerfile +++ b/cpython-unix/build.cross.Dockerfile @@ -1,6 +1,6 @@ # Debian Stretch. FROM debian@sha256:cebe6e1c30384958d471467e231f740e8f0fd92cbfd2a435a186e9bada3aee1c -MAINTAINER Gregory Szorc +LABEL org.opencontainers.image.authors="Gregory Szorc " RUN groupadd -g 1000 build && \ useradd -u 1000 -g 1000 -d /build -s /bin/bash -m build && \ diff --git a/cpython-unix/build.debian9.Dockerfile b/cpython-unix/build.debian9.Dockerfile new file mode 100644 index 0000000..1f7c91b --- /dev/null +++ b/cpython-unix/build.debian9.Dockerfile @@ -0,0 +1,16 @@ +{% include 'base.debian9.Dockerfile' %} + +RUN ulimit -n 10000 && apt-get install \ + bzip2 \ + file \ + libc6-dev \ + libffi-dev \ + make \ + patch \ + perl \ + pkg-config \ + tar \ + xz-utils \ + unzip \ + zip \ + zlib1g-dev diff --git a/cpython-unix/build.py b/cpython-unix/build.py index 6f98e99..c5d73a1 100755 --- a/cpython-unix/build.py +++ b/cpython-unix/build.py @@ -88,14 +88,26 @@ def add_target_env(env, build_platform, target_triple, build_env): extra_host_cflags = [] extra_host_ldflags = [] - if build_platform == "linux_x86_64": - env["BUILD_TRIPLE"] = "x86_64-unknown-linux-gnu" + # Add compiler-rt for aarch64-musl to resolve missing builtins + if target_triple == "aarch64-unknown-linux-musl": + extra_target_cflags.append("--rtlib=compiler-rt") + extra_target_ldflags.append("--rtlib=compiler-rt") - env["TARGET_TRIPLE"] = ( - target_triple.replace("x86_64_v2-", "x86_64-") - .replace("x86_64_v3-", "x86_64-") - .replace("x86_64_v4-", "x86_64-") - ) + if build_platform.startswith("linux_"): + machine = platform.machine() + + if machine == "aarch64": + env["BUILD_TRIPLE"] = "aarch64-unknown-linux-gnu" + env["TARGET_TRIPLE"] = target_triple + elif machine == "x86_64": + env["BUILD_TRIPLE"] = "x86_64-unknown-linux-gnu" + env["TARGET_TRIPLE"] = ( + target_triple.replace("x86_64_v2-", "x86_64-") + .replace("x86_64_v3-", "x86_64-") + .replace("x86_64_v4-", "x86_64-") + ) + else: + raise Exception("unhandled Linux machine value: %s" % machine) # This will make x86_64_v2, etc count as cross-compiling. This is # semantically correct, since the current machine may not support @@ -105,7 +117,7 @@ def add_target_env(env, build_platform, target_triple, build_env): ): env["CROSS_COMPILING"] = "1" - if build_platform.startswith("macos_"): + elif build_platform.startswith("macos_"): machine = platform.machine() if machine == "arm64": @@ -188,6 +200,8 @@ def add_target_env(env, build_platform, target_triple, build_env): extra_host_cflags.extend(["-isysroot", host_sdk_path]) extra_host_ldflags.extend(["-isysroot", host_sdk_path]) + else: + raise Exception("unhandled build platform: %s" % build_platform) env["EXTRA_HOST_CFLAGS"] = " ".join(extra_host_cflags) env["EXTRA_HOST_LDFLAGS"] = " ".join(extra_host_ldflags) @@ -370,48 +384,6 @@ def build_libedit( build_env.get_tools_archive(dest_archive, "deps") -def build_tix( - settings, client, image, host_platform, target_triple, build_options, dest_archive -): - tcl_archive = download_entry("tcl", DOWNLOADS_PATH) - tk_archive = download_entry("tk", DOWNLOADS_PATH) - tix_archive = download_entry("tix", DOWNLOADS_PATH) - - with build_environment(client, image) as build_env: - if settings.get("needs_toolchain"): - build_env.install_toolchain( - BUILD, - host_platform, - target_triple, - binutils=install_binutils(host_platform), - clang=True, - musl="musl" in target_triple, - static="static" in build_options, - ) - - depends = {"tcl", "tk"} - if not host_platform.startswith("macos_"): - depends |= {"libX11", "xorgproto"} - - for p in sorted(depends): - build_env.install_artifact_archive(BUILD, p, target_triple, build_options) - - for p in (tcl_archive, tk_archive, tix_archive, SUPPORT / "build-tix.sh"): - build_env.copy_file(p) - - env = { - "TOOLCHAIN": "clang-%s" % host_platform, - "TCL_VERSION": DOWNLOADS["tcl"]["version"], - "TIX_VERSION": DOWNLOADS["tix"]["version"], - "TK_VERSION": DOWNLOADS["tk"]["version"], - } - - add_target_env(env, host_platform, target_triple, build_env) - - build_env.run("build-tix.sh", environment=env) - build_env.get_tools_archive(dest_archive, "deps") - - def build_cpython_host( client, image, @@ -496,10 +468,14 @@ def python_build_info( binary_suffix = "" - if platform == "linux_x86_64": + if platform in ("linux_x86_64", "linux_aarch64"): + arch = platform.removeprefix("linux_") + bi["core"]["static_lib"] = ( - "install/lib/python{version}/config-{version}{binary_suffix}-x86_64-linux-gnu/libpython{version}{binary_suffix}.a".format( - version=version, binary_suffix=binary_suffix + "install/lib/python{version}/config-{version}{binary_suffix}-{arch}-linux-gnu/libpython{version}{binary_suffix}.a".format( + version=version, + binary_suffix=binary_suffix, + arch=arch, ) ) @@ -541,7 +517,7 @@ def python_build_info( bi["object_file_format"] = object_file_format - # Determine allowed libaries on Linux + # Determine allowed libraries on Linux libs = extra_metadata["python_config_vars"].get("LIBS", "").split() mips = target_triple.split("-")[0] in {"mips", "mipsel"} linux_allowed_system_libraries = LINUX_ALLOW_SYSTEM_LIBRARIES.copy() @@ -579,7 +555,10 @@ def python_build_info( if lib.startswith("-l"): lib = lib[2:] - if platform == "linux_x86_64" and lib not in linux_allowed_system_libraries: + if ( + platform in ("linux_x86_64", "linux_aarch64") + and lib not in linux_allowed_system_libraries + ): raise Exception("unexpected library in LIBS (%s): %s" % (libs, lib)) elif ( platform.startswith("macos_") @@ -851,7 +830,7 @@ def build_cpython( extension_module_loading = ["builtin"] crt_features = [] - if host_platform == "linux_x86_64": + if host_platform in ("linux_x86_64", "linux_aarch64"): if "static" in parsed_build_options: crt_features.append("static") else: @@ -930,9 +909,6 @@ def build_cpython( "tk8.6", ] - if "-apple" not in target_triple: - python_info["tcl_library_paths"].append("Tix8.4.3") - if "-apple" in target_triple: python_info["apple_sdk_platform"] = env["APPLE_SDK_PLATFORM"] python_info["apple_sdk_version"] = env["APPLE_SDK_VERSION"] @@ -1080,10 +1056,14 @@ def main(): with image_path.open("rb") as fh: image_data = fh.read() - build_docker_image(client, image_data, BUILD, image_name) + build_docker_image(client, image_data, BUILD, image_name, host_platform) elif action == "binutils": - build_binutils(client, get_image(client, ROOT, BUILD, "gcc"), host_platform) + build_binutils( + client, + get_image(client, ROOT, BUILD, docker_image, host_platform), + host_platform, + ) elif action == "clang": materialize_clang(host_platform, target_triple) @@ -1091,7 +1071,7 @@ def main(): elif action == "musl": build_musl( client, - get_image(client, ROOT, BUILD, "gcc"), + get_image(client, ROOT, BUILD, docker_image, host_platform), host_platform, target_triple, build_options, @@ -1101,7 +1081,7 @@ def main(): simple_build( settings, client, - get_image(client, ROOT, BUILD, docker_image), + get_image(client, ROOT, BUILD, docker_image, host_platform), action, host_platform=host_platform, target_triple=target_triple, @@ -1115,7 +1095,7 @@ def main(): build_libedit( settings, client, - get_image(client, ROOT, BUILD, docker_image), + get_image(client, ROOT, BUILD, docker_image, host_platform), host_platform=host_platform, target_triple=target_triple, build_options=build_options, @@ -1143,18 +1123,23 @@ def main(): "xtrans", "xz", "zlib", + "zstd", ): tools_path = "host" if action in ("m4", "patchelf") else "deps" + extra_archives = { + "tcl": {"zlib"}, + }.get(action) simple_build( settings, client, - get_image(client, ROOT, BUILD, docker_image), + get_image(client, ROOT, BUILD, docker_image, host_platform), action, host_platform=host_platform, target_triple=target_triple, build_options=build_options, dest_archive=dest_archive, + extra_archives=extra_archives, tools_path=tools_path, ) @@ -1162,7 +1147,7 @@ def main(): simple_build( settings, client, - get_image(client, ROOT, BUILD, docker_image), + get_image(client, ROOT, BUILD, docker_image, host_platform), action, host_platform=host_platform, target_triple=target_triple, @@ -1182,7 +1167,7 @@ def main(): simple_build( settings, client, - get_image(client, ROOT, BUILD, docker_image), + get_image(client, ROOT, BUILD, docker_image, host_platform), action, host_platform=host_platform, target_triple=target_triple, @@ -1195,7 +1180,7 @@ def main(): simple_build( settings, client, - get_image(client, ROOT, BUILD, docker_image), + get_image(client, ROOT, BUILD, docker_image, host_platform), action, host_platform=host_platform, target_triple=target_triple, @@ -1208,7 +1193,7 @@ def main(): simple_build( settings, client, - get_image(client, ROOT, BUILD, docker_image), + get_image(client, ROOT, BUILD, docker_image, host_platform), action, host_platform=host_platform, target_triple=target_triple, @@ -1218,19 +1203,8 @@ def main(): python_host_version=python_host_version, ) - elif action == "tix": - build_tix( - settings, - client, - get_image(client, ROOT, BUILD, docker_image), - host_platform=host_platform, - target_triple=target_triple, - build_options=build_options, - dest_archive=dest_archive, - ) - elif action == "tk": - extra_archives = {"tcl"} + extra_archives = {"tcl", "zlib"} if not host_platform.startswith("macos_"): extra_archives |= { "libX11", @@ -1243,7 +1217,7 @@ def main(): simple_build( settings, client, - get_image(client, ROOT, BUILD, docker_image), + get_image(client, ROOT, BUILD, docker_image, host_platform), action, host_platform=host_platform, target_triple=target_triple, @@ -1256,7 +1230,7 @@ def main(): elif action.startswith("cpython-") and action.endswith("-host"): build_cpython_host( client, - get_image(client, ROOT, BUILD, docker_image), + get_image(client, ROOT, BUILD, docker_image, host_platform), action[:-5], host_platform=host_platform, target_triple=target_triple, @@ -1275,7 +1249,7 @@ def main(): build_cpython( settings, client, - get_image(client, ROOT, BUILD, docker_image), + get_image(client, ROOT, BUILD, docker_image, host_platform), host_platform=host_platform, target_triple=target_triple, build_options=build_options, diff --git a/cpython-unix/extension-modules.yml b/cpython-unix/extension-modules.yml index 3d69f04..3d4f1bf 100644 --- a/cpython-unix/extension-modules.yml +++ b/cpython-unix/extension-modules.yml @@ -145,6 +145,7 @@ _ctypes: - dl _ctypes_test: + build-mode: shared sources: - _ctypes/_ctypes_test.c links: @@ -206,6 +207,9 @@ _curses_panel: _datetime: sources: - _datetimemodule.c + setup-enabled-conditional: + - enabled: true + minimum-python-version: "3.14" _dbm: sources: @@ -257,6 +261,7 @@ _decimal: - define: CONFIG_64=1 targets: - aarch64-.* + - loongarch64-unknown-linux.* - ppc64le-unknown-linux.* - riscv64-unknown-linux.* - s390x-unknown-linux-.* @@ -529,8 +534,6 @@ _sqlite3: - include includes: - Modules/_sqlite - defines: - - "MODULE_NAME=\\\"sqlite3\\\"" defines-conditional: # Require dynamic binaries to load extensions. Cannot load on iOS. # 3.11+ uses opt in. <3.11 uses opt out. @@ -544,6 +547,8 @@ _sqlite3: - define: SQLITE_OMIT_LOAD_EXTENSION=1 targets: - .*-ios + - define: "MODULE_NAME=\\\"sqlite3\\\"" + maximum-python-version: "3.9" links: - sqlite3 @@ -670,45 +675,27 @@ _tkinter: sources: - _tkinter.c - tkappinit.c - # TODO consider adding WITH_TIX, as Modules/Setup seems to recommend it. This also - # initializes tix at init time, which seems desirable. defines: - WITH_APPINIT includes-deps: - include/X11 + build-mode: shared links: - tcl8.6 - tk8.6 - - # Without -ObjC, we get a crash: -[TKApplication tkProcessEvent:]: unrecognized selector sent to instance. - # See also https://core.tcl-lang.org/tk/tktview/85f316beb15108ac43b03fa6c8608e31f3ae5f92. - # This is apparently an issue with static linking Objective-C binaries. - linker-args: - - args: ["-ObjC"] - targets: - - .*-apple-darwin links-conditional: - name: X11 targets: - .*-unknown-linux-.* + build-mode: static - name: xcb targets: - .*-unknown-linux-.* + build-mode: static - name: Xau targets: - .*-unknown-linux-.* - # Many of these are dependencies of libtcl and libtk. - frameworks: - - AppKit - - ApplicationServices - - Carbon - - Cocoa - - CoreFoundation - - CoreServices - - CoreGraphics - - IOKit - - QuartzCore - - UniformTypeIdentifiers + build-mode: static _tokenize: minimum-python-version: "3.11" @@ -772,15 +759,14 @@ _xxtestfuzz: - _xxtestfuzz/fuzzer.c _zstd: - # Disable on all targets until we add a zstd library - disabled-targets: - - .* minimum-python-version: '3.14' sources: - _zstd/_zstdmodule.c - - _zstd/zdict.c + - _zstd/zstddict.c - _zstd/compressor.c - _zstd/decompressor.c + links: + - zstd _zoneinfo: minimum-python-version: "3.9" diff --git a/cpython-unix/gcc.debian9.Dockerfile b/cpython-unix/gcc.debian9.Dockerfile new file mode 100644 index 0000000..92d764e --- /dev/null +++ b/cpython-unix/gcc.debian9.Dockerfile @@ -0,0 +1,14 @@ +{% include 'base.debian9.Dockerfile' %} +RUN ulimit -n 10000 && apt-get install \ + autoconf \ + automake \ + bison \ + build-essential \ + gawk \ + gcc \ + libtool \ + make \ + tar \ + texinfo \ + xz-utils \ + unzip diff --git a/cpython-unix/patch-configure-add-loongarch-triplet.patch b/cpython-unix/patch-configure-add-loongarch-triplet.patch new file mode 100644 index 0000000..30b9e5a --- /dev/null +++ b/cpython-unix/patch-configure-add-loongarch-triplet.patch @@ -0,0 +1,50 @@ +diff --git a/configure b/configure +index b7be60e..d799415 100755 +--- a/configure ++++ b/configure +@@ -5261,6 +5261,20 @@ cat >> conftest.c <=6) && defined(_MIPSEL) +diff --git a/configure.ac b/configure.ac +index aa515da..b5bad6e 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -779,6 +779,20 @@ cat >> conftest.c <=6) && defined(_MIPSEL) diff --git a/cpython-unix/patch-jit-cflags-314.patch b/cpython-unix/patch-jit-cflags-314.patch deleted file mode 100644 index 3a16fb5..0000000 --- a/cpython-unix/patch-jit-cflags-314.patch +++ /dev/null @@ -1,74 +0,0 @@ -diff --git a/Tools/jit/_targets.py b/Tools/jit/_targets.py -index d0a1c081ffe..deb83f275d2 100644 ---- a/Tools/jit/_targets.py -+++ b/Tools/jit/_targets.py -@@ -10,6 +10,7 @@ - import sys - import tempfile - import typing -+import shlex - - import _llvm - import _schema -@@ -46,6 +47,7 @@ class _Target(typing.Generic[_S, _R]): - stable: bool = False - debug: bool = False - verbose: bool = False -+ cflags: str = "" - known_symbols: dict[str, int] = dataclasses.field(default_factory=dict) - pyconfig_dir: pathlib.Path = pathlib.Path.cwd().resolve() - -@@ -120,6 +122,7 @@ async def _compile( - ) -> _stencils.StencilGroup: - o = tempdir / f"{opname}.o" - args = [ -+ *shlex.split(self.cflags), - f"--target={self.triple}", - "-DPy_BUILD_CORE_MODULE", - "-D_DEBUG" if self.debug else "-DNDEBUG", -diff --git a/Tools/jit/build.py b/Tools/jit/build.py -index 1afd0c76bad..96c4cb07593 100644 ---- a/Tools/jit/build.py -+++ b/Tools/jit/build.py -@@ -39,11 +39,15 @@ - parser.add_argument( - "-v", "--verbose", action="store_true", help="echo commands as they are run" - ) -+ parser.add_argument( -+ "--with-cflags", help="additional flags to pass to the compiler", default="" -+ ) - args = parser.parse_args() - for target in args.target: - target.debug = args.debug - target.force = args.force - target.verbose = args.verbose -+ target.cflags = args.with_cflags - target.pyconfig_dir = args.pyconfig_dir - target.build( - comment=comment, -diff --git a/configure b/configure -index 884f8a4b068..2e6740c33d9 100755 ---- a/configure -+++ b/configure -@@ -10863,7 +10863,7 @@ then : - - else case e in #( - e) as_fn_append CFLAGS_NODIST " $jit_flags" -- REGEN_JIT_COMMAND="\$(PYTHON_FOR_REGEN) \$(srcdir)/Tools/jit/build.py ${ARCH_TRIPLES:-$host} --output-dir . --pyconfig-dir ." -+ REGEN_JIT_COMMAND="\$(PYTHON_FOR_REGEN) \$(srcdir)/Tools/jit/build.py ${ARCH_TRIPLES:-$host} --output-dir . --pyconfig-dir . --with-cflags=\"\$(CONFIGURE_CFLAGS)\"" - JIT_STENCILS_H="jit_stencils.h" - if test "x$Py_DEBUG" = xtrue - then : -diff --git a/configure.ac b/configure.ac -index cf25148bad2..f8bfab7bf96 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -2776,7 +2776,7 @@ AS_VAR_IF([jit_flags], - [], - [AS_VAR_APPEND([CFLAGS_NODIST], [" $jit_flags"]) - AS_VAR_SET([REGEN_JIT_COMMAND], -- ["\$(PYTHON_FOR_REGEN) \$(srcdir)/Tools/jit/build.py ${ARCH_TRIPLES:-$host} --output-dir . --pyconfig-dir ."]) -+ ["\$(PYTHON_FOR_REGEN) \$(srcdir)/Tools/jit/build.py ${ARCH_TRIPLES:-$host} --output-dir . --pyconfig-dir . --with-cflags=\"\$(CONFIGURE_CFLAGS)\""]) - AS_VAR_SET([JIT_STENCILS_H], ["jit_stencils.h"]) - AS_VAR_IF([Py_DEBUG], - [true], diff --git a/cpython-unix/patch-static-remote-debug-3.14.patch b/cpython-unix/patch-static-remote-debug-3.14.patch deleted file mode 100644 index 1c359c3..0000000 --- a/cpython-unix/patch-static-remote-debug-3.14.patch +++ /dev/null @@ -1,22 +0,0 @@ -diff --git a/Python/remote_debug.h b/Python/remote_debug.h -index 6cbf1c8deaa..ab494ea71da 100644 ---- a/Python/remote_debug.h -+++ b/Python/remote_debug.h -@@ -131,7 +131,7 @@ _Py_RemoteDebug_FreePageCache(proc_handle_t *handle) - } - } - --void -+static void - _Py_RemoteDebug_ClearCache(proc_handle_t *handle) - { - for (int i = 0; i < MAX_PAGES; i++) { -@@ -989,7 +989,7 @@ _Py_RemoteDebug_ReadRemoteMemory(proc_handle_t *handle, uintptr_t remote_address - #endif - } - --int -+static int - _Py_RemoteDebug_PagedReadRemoteMemory(proc_handle_t *handle, - uintptr_t addr, - size_t size, diff --git a/cpython-unix/patch-uuid-getnode-stable-3.13.patch b/cpython-unix/patch-uuid-getnode-stable-3.13.patch deleted file mode 100644 index 11bdf83..0000000 --- a/cpython-unix/patch-uuid-getnode-stable-3.13.patch +++ /dev/null @@ -1,708 +0,0 @@ -diff --git a/Lib/test/test_uuid.py b/Lib/test/test_uuid.py -index e7e44c6413c2e2..ce396aa942b6ed 100755 ---- a/Lib/test/test_uuid.py -+++ b/Lib/test/test_uuid.py -@@ -1,6 +1,7 @@ - import unittest - from test import support - from test.support import import_helper -+from test.support.script_helper import assert_python_ok - import builtins - import contextlib - import copy -@@ -773,10 +774,37 @@ def test_cli_uuid5_ouputted_with_valid_namespace_and_name(self): - class TestUUIDWithoutExtModule(BaseTestUUID, unittest.TestCase): - uuid = py_uuid - -+ - @unittest.skipUnless(c_uuid, 'requires the C _uuid module') - class TestUUIDWithExtModule(BaseTestUUID, unittest.TestCase): - uuid = c_uuid - -+ def check_has_stable_libuuid_extractable_node(self): -+ if not self.uuid._has_stable_extractable_node: -+ self.skipTest("libuuid cannot deduce MAC address") -+ -+ @unittest.skipUnless(os.name == 'posix', 'POSIX only') -+ def test_unix_getnode_from_libuuid(self): -+ self.check_has_stable_libuuid_extractable_node() -+ script = 'import uuid; print(uuid._unix_getnode())' -+ _, n_a, _ = assert_python_ok('-c', script) -+ _, n_b, _ = assert_python_ok('-c', script) -+ n_a, n_b = n_a.decode().strip(), n_b.decode().strip() -+ self.assertTrue(n_a.isdigit()) -+ self.assertTrue(n_b.isdigit()) -+ self.assertEqual(n_a, n_b) -+ -+ @unittest.skipUnless(os.name == 'nt', 'Windows only') -+ def test_windows_getnode_from_libuuid(self): -+ self.check_has_stable_libuuid_extractable_node() -+ script = 'import uuid; print(uuid._windll_getnode())' -+ _, n_a, _ = assert_python_ok('-c', script) -+ _, n_b, _ = assert_python_ok('-c', script) -+ n_a, n_b = n_a.decode().strip(), n_b.decode().strip() -+ self.assertTrue(n_a.isdigit()) -+ self.assertTrue(n_b.isdigit()) -+ self.assertEqual(n_a, n_b) -+ - - class BaseTestInternals: - _uuid = py_uuid -diff --git a/Lib/uuid.py b/Lib/uuid.py -index c286eac38e1ef4..6ab1658cc5249a 100644 ---- a/Lib/uuid.py -+++ b/Lib/uuid.py -@@ -572,22 +572,24 @@ def _netstat_getnode(): - try: - import _uuid - _generate_time_safe = getattr(_uuid, "generate_time_safe", None) -+ _has_stable_extractable_node = getattr(_uuid, "has_stable_extractable_node", False) - _UuidCreate = getattr(_uuid, "UuidCreate", None) - except ImportError: - _uuid = None - _generate_time_safe = None -+ _has_stable_extractable_node = False - _UuidCreate = None - - - def _unix_getnode(): - """Get the hardware address on Unix using the _uuid extension module.""" -- if _generate_time_safe: -+ if _generate_time_safe and _has_stable_extractable_node: - uuid_time, _ = _generate_time_safe() - return UUID(bytes=uuid_time).node - - def _windll_getnode(): - """Get the hardware address on Windows using the _uuid extension module.""" -- if _UuidCreate: -+ if _UuidCreate and _has_stable_extractable_node: - uuid_bytes = _UuidCreate() - return UUID(bytes_le=uuid_bytes).node - -diff --git a/Modules/_uuidmodule.c b/Modules/_uuidmodule.c -index c5e78b1510b5e3..c31a7e8fea5608 100644 ---- a/Modules/_uuidmodule.c -+++ b/Modules/_uuidmodule.c -@@ -78,23 +78,47 @@ py_UuidCreate(PyObject *Py_UNUSED(context), - return NULL; - } - -+static int -+py_windows_has_stable_node(void) -+{ -+ UUID uuid; -+ RPC_STATUS res; -+ Py_BEGIN_ALLOW_THREADS -+ res = UuidCreateSequential(&uuid); -+ Py_END_ALLOW_THREADS -+ return res == RPC_S_OK; -+} - #endif /* MS_WINDOWS */ - - - static int --uuid_exec(PyObject *module) { -+uuid_exec(PyObject *module) -+{ -+#define ADD_INT(NAME, VALUE) \ -+ do { \ -+ if (PyModule_AddIntConstant(module, (NAME), (VALUE)) < 0) { \ -+ return -1; \ -+ } \ -+ } while (0) -+ - assert(sizeof(uuid_t) == 16); - #if defined(MS_WINDOWS) -- int has_uuid_generate_time_safe = 0; -+ ADD_INT("has_uuid_generate_time_safe", 0); - #elif defined(HAVE_UUID_GENERATE_TIME_SAFE) -- int has_uuid_generate_time_safe = 1; -+ ADD_INT("has_uuid_generate_time_safe", 1); - #else -- int has_uuid_generate_time_safe = 0; -+ ADD_INT("has_uuid_generate_time_safe", 0); - #endif -- if (PyModule_AddIntConstant(module, "has_uuid_generate_time_safe", -- has_uuid_generate_time_safe) < 0) { -- return -1; -- } -+ -+#if defined(MS_WINDOWS) -+ ADD_INT("has_stable_extractable_node", py_windows_has_stable_node()); -+#elif defined(HAVE_UUID_GENERATE_TIME_SAFE_STABLE_MAC) -+ ADD_INT("has_stable_extractable_node", 1); -+#else -+ ADD_INT("has_stable_extractable_node", 0); -+#endif -+ -+#undef ADD_INT - return 0; - } - -diff --git a/configure b/configure -index 1cd1f690f7b9c1..cc976aafc09b34 100755 ---- a/configure -+++ b/configure -@@ -13381,6 +13381,7 @@ fi - - - -+ - have_uuid=missing - - for ac_header in uuid.h -@@ -13390,6 +13391,7 @@ if test "x$ac_cv_header_uuid_h" = xyes - then : - printf "%s\n" "#define HAVE_UUID_H 1" >>confdefs.h - -+ - for ac_func in uuid_create uuid_enc_be - do : - as_ac_var=`printf "%s\n" "ac_cv_func_$ac_func" | $as_tr_sh` -@@ -13399,7 +13401,9 @@ then : - cat >>confdefs.h <<_ACEOF - #define `printf "%s\n" "HAVE_$ac_func" | $as_tr_cpp` 1 - _ACEOF -- have_uuid=yes -+ -+ have_uuid=yes -+ ac_cv_have_uuid_h=yes - LIBUUID_CFLAGS=${LIBUUID_CFLAGS-""} - LIBUUID_LIBS=${LIBUUID_LIBS-""} - -@@ -13489,6 +13493,7 @@ if test "x$ac_cv_header_uuid_uuid_h" = xyes - then : - printf "%s\n" "#define HAVE_UUID_UUID_H 1" >>confdefs.h - -+ ac_cv_have_uuid_uuid_h=yes - py_check_lib_save_LIBS=$LIBS - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for uuid_generate_time in -luuid" >&5 - printf %s "checking for uuid_generate_time in -luuid... " >&6; } -@@ -13570,8 +13575,9 @@ fi - printf "%s\n" "$ac_cv_lib_uuid_uuid_generate_time_safe" >&6; } - if test "x$ac_cv_lib_uuid_uuid_generate_time_safe" = xyes - then : -- have_uuid=yes -- printf "%s\n" "#define HAVE_UUID_GENERATE_TIME_SAFE 1" >>confdefs.h -+ -+ have_uuid=yes -+ ac_cv_have_uuid_generate_time_safe=yes - - fi - -@@ -13615,6 +13621,7 @@ if test "x$ac_cv_header_uuid_uuid_h" = xyes - then : - printf "%s\n" "#define HAVE_UUID_UUID_H 1" >>confdefs.h - -+ ac_cv_have_uuid_uuid_h=yes - py_check_lib_save_LIBS=$LIBS - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for uuid_generate_time in -luuid" >&5 - printf %s "checking for uuid_generate_time in -luuid... " >&6; } -@@ -13696,8 +13703,9 @@ fi - printf "%s\n" "$ac_cv_lib_uuid_uuid_generate_time_safe" >&6; } - if test "x$ac_cv_lib_uuid_uuid_generate_time_safe" = xyes - then : -- have_uuid=yes -- printf "%s\n" "#define HAVE_UUID_GENERATE_TIME_SAFE 1" >>confdefs.h -+ -+ have_uuid=yes -+ ac_cv_have_uuid_generate_time_safe=yes - - fi - -@@ -13727,11 +13735,25 @@ else - LIBUUID_LIBS=$pkg_cv_LIBUUID_LIBS - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 - printf "%s\n" "yes" >&6; } -+<<<<<<< HEAD - have_uuid=yes - printf "%s\n" "#define HAVE_UUID_H 1" >>confdefs.h - - printf "%s\n" "#define HAVE_UUID_GENERATE_TIME_SAFE 1" >>confdefs.h - -+======= -+ have_uuid=yes -+ ac_cv_have_uuid_generate_time_safe=yes -+ # The uuid.h file to include may be *or* . -+ # Since pkg-config --cflags uuid may return -I/usr/include/uuid, -+ # it's possible to write '#include ' in _uuidmodule.c, -+ # assuming that the compiler flags are properly updated. -+ # -+ # Ideally, we should have defined HAVE_UUID_H if and only if -+ # #include can be written, *without* assuming extra -+ # include path. -+ ac_cv_have_uuid_h=yes -+>>>>>>> 3bffada4672 (gh-132710: only use stable `_uuid.generate_time_safe()` to deduce MAC address (#132901)) - - fi - -@@ -13752,6 +13774,7 @@ if test "x$ac_cv_func_uuid_generate_time" = xyes - then : - - have_uuid=yes -+ ac_cv_have_uuid_uuid_h=yes - LIBUUID_CFLAGS=${LIBUUID_CFLAGS-""} - LIBUUID_LIBS=${LIBUUID_LIBS-""} - -@@ -13764,11 +13787,198 @@ done - - fi - -+<<<<<<< HEAD -+======= -+if test "x$ac_cv_have_uuid_h" = xyes -+then : -+ printf "%s\n" "#define HAVE_UUID_H 1" >>confdefs.h -+ -+fi -+if test "x$ac_cv_have_uuid_uuid_h" = xyes -+then : -+ printf "%s\n" "#define HAVE_UUID_UUID_H 1" >>confdefs.h -+ -+fi -+if test "x$ac_cv_have_uuid_generate_time_safe" = xyes -+then : -+ -+ printf "%s\n" "#define HAVE_UUID_GENERATE_TIME_SAFE 1" >>confdefs.h -+ -+ -+fi -+ -+# gh-124228: While the libuuid library is available on NetBSD, it supports only UUID version 4. -+# This restriction inhibits the proper generation of time-based UUIDs. -+if test "$ac_sys_system" = "NetBSD"; then -+ have_uuid=missing -+ printf "%s\n" "#define HAVE_UUID_H 0" >>confdefs.h -+ -+fi -+ -+>>>>>>> 3bffada4672 (gh-132710: only use stable `_uuid.generate_time_safe()` to deduce MAC address (#132901)) - if test "x$have_uuid" = xmissing - then : - have_uuid=no - fi - -+# gh-132710: The UUID node is fetched by using libuuid when possible -+# and cached. While the node is constant within the same process, -+# different interpreters may have different values as libuuid may -+# randomize the node value if the latter cannot be deduced. -+# -+# Consumers may define HAVE_UUID_GENERATE_TIME_SAFE_STABLE_MAC -+# to indicate that libuuid is unstable and should not be relied -+# upon to deduce the MAC address. -+ -+ -+if test "$have_uuid" = "yes" -a "$HAVE_UUID_GENERATE_TIME_SAFE" = "1" -+then -+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if uuid_generate_time_safe() node value is stable" >&5 -+printf %s "checking if uuid_generate_time_safe() node value is stable... " >&6; } -+ save_CFLAGS=$CFLAGS -+save_CPPFLAGS=$CPPFLAGS -+save_LDFLAGS=$LDFLAGS -+save_LIBS=$LIBS -+ -+ -+ # Be sure to add the extra include path if we used pkg-config -+ # as HAVE_UUID_H may be set even though is only reachable -+ # by adding extra -I flags. -+ # -+ # If the following script does not compile, we simply assume that -+ # libuuid is missing. -+ CFLAGS="$CFLAGS $LIBUUID_CFLAGS" -+ LIBS="$LIBS $LIBUUID_LIBS" -+ if test "$cross_compiling" = yes -+then : -+ -+ -+else case e in #( -+ e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext -+/* end confdefs.h. */ -+ -+ #include // PRIu64 -+ #include // uint64_t -+ #include // fopen(), fclose() -+ -+ #ifdef HAVE_UUID_H -+ #include -+ #else -+ #include -+ #endif -+ -+ #define ERR 1 -+ int main(void) { -+ uuid_t uuid; // unsigned char[16] -+ (void)uuid_generate_time_safe(uuid); -+ uint64_t node = 0; -+ for (size_t i = 0; i < 6; i++) { -+ node |= (uint64_t)uuid[15 - i] << (8 * i); -+ } -+ FILE *fp = fopen("conftest.out", "w"); -+ if (fp == NULL) { -+ return ERR; -+ } -+ int rc = fprintf(fp, "%" PRIu64 "\n", node) >= 0; -+ rc |= fclose(fp); -+ return rc == 0 ? 0 : ERR; -+ } -+_ACEOF -+if ac_fn_c_try_run "$LINENO" -+then : -+ -+ py_cv_uuid_node1=`cat conftest.out` -+ -+fi -+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ -+ conftest.$ac_objext conftest.beam conftest.$ac_ext ;; -+esac -+fi -+ -+CFLAGS=$save_CFLAGS -+CPPFLAGS=$save_CPPFLAGS -+LDFLAGS=$save_LDFLAGS -+LIBS=$save_LIBS -+ -+ -+ save_CFLAGS=$CFLAGS -+save_CPPFLAGS=$CPPFLAGS -+save_LDFLAGS=$LDFLAGS -+save_LIBS=$LIBS -+ -+ -+ # Be sure to add the extra include path if we used pkg-config -+ # as HAVE_UUID_H may be set even though is only reachable -+ # by adding extra -I flags. -+ # -+ # If the following script does not compile, we simply assume that -+ # libuuid is missing. -+ CFLAGS="$CFLAGS $LIBUUID_CFLAGS" -+ LIBS="$LIBS $LIBUUID_LIBS" -+ if test "$cross_compiling" = yes -+then : -+ -+ -+else case e in #( -+ e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext -+/* end confdefs.h. */ -+ -+ #include // PRIu64 -+ #include // uint64_t -+ #include // fopen(), fclose() -+ -+ #ifdef HAVE_UUID_H -+ #include -+ #else -+ #include -+ #endif -+ -+ #define ERR 1 -+ int main(void) { -+ uuid_t uuid; // unsigned char[16] -+ (void)uuid_generate_time_safe(uuid); -+ uint64_t node = 0; -+ for (size_t i = 0; i < 6; i++) { -+ node |= (uint64_t)uuid[15 - i] << (8 * i); -+ } -+ FILE *fp = fopen("conftest.out", "w"); -+ if (fp == NULL) { -+ return ERR; -+ } -+ int rc = fprintf(fp, "%" PRIu64 "\n", node) >= 0; -+ rc |= fclose(fp); -+ return rc == 0 ? 0 : ERR; -+ } -+_ACEOF -+if ac_fn_c_try_run "$LINENO" -+then : -+ -+ py_cv_uuid_node2=`cat conftest.out` -+ -+fi -+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ -+ conftest.$ac_objext conftest.beam conftest.$ac_ext ;; -+esac -+fi -+ -+CFLAGS=$save_CFLAGS -+CPPFLAGS=$save_CPPFLAGS -+LDFLAGS=$save_LDFLAGS -+LIBS=$save_LIBS -+ -+ -+ if test -n "$py_cv_uuid_node1" -a "$py_cv_uuid_node1" = "$py_cv_uuid_node2" -+ then -+ printf "%s\n" "#define HAVE_UUID_GENERATE_TIME_SAFE_STABLE_MAC 1" >>confdefs.h -+ -+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: stable" >&5 -+printf "%s\n" "stable" >&6; } -+ else -+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unstable" >&5 -+printf "%s\n" "unstable" >&6; } -+ fi -+fi -+ - # 'Real Time' functions on Solaris - # posix4 on Solaris 2.6 - # pthread (first!) on Linux -diff --git a/configure.ac b/configure.ac -index 3fcb18922c5330..9898af7ffd5f25 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -3740,15 +3740,17 @@ dnl check for uuid dependencies - AH_TEMPLATE([HAVE_UUID_H], [Define to 1 if you have the header file.]) - AH_TEMPLATE([HAVE_UUID_UUID_H], [Define to 1 if you have the header file.]) - AH_TEMPLATE([HAVE_UUID_GENERATE_TIME_SAFE], [Define if uuid_generate_time_safe() exists.]) -+AH_TEMPLATE([HAVE_UUID_GENERATE_TIME_SAFE_STABLE_MAC], [Define if uuid_generate_time_safe() is able to deduce a MAC address.]) - have_uuid=missing - - dnl AIX provides support for RFC4122 (uuid) in libc.a starting with AIX 6.1 - dnl (anno 2007). FreeBSD and OpenBSD provides support in libc as well. - dnl Little-endian FreeBSD, OpenBSD and NetBSD needs encoding into an octet - dnl stream in big-endian byte-order --AC_CHECK_HEADERS([uuid.h], -- [AC_CHECK_FUNCS([uuid_create uuid_enc_be], -- [have_uuid=yes -+AC_CHECK_HEADERS([uuid.h], [ -+ AC_CHECK_FUNCS([uuid_create uuid_enc_be], [ -+ have_uuid=yes -+ ac_cv_have_uuid_h=yes - LIBUUID_CFLAGS=${LIBUUID_CFLAGS-""} - LIBUUID_LIBS=${LIBUUID_LIBS-""} - ]) -@@ -3758,19 +3760,29 @@ AS_VAR_IF([have_uuid], [missing], [ - PKG_CHECK_MODULES( - [LIBUUID], [uuid >= 2.20], - [dnl linux-util's libuuid has uuid_generate_time_safe() since v2.20 (2011) -- dnl and provides . -+ dnl and provides assuming specific include paths are given - have_uuid=yes -- AC_DEFINE([HAVE_UUID_H], [1]) -- AC_DEFINE([HAVE_UUID_GENERATE_TIME_SAFE], [1]) -+ ac_cv_have_uuid_generate_time_safe=yes -+ # The uuid.h file to include may be *or* . -+ # Since pkg-config --cflags uuid may return -I/usr/include/uuid, -+ # it's possible to write '#include ' in _uuidmodule.c, -+ # assuming that the compiler flags are properly updated. -+ # -+ # Ideally, we should have defined HAVE_UUID_H if and only if -+ # #include can be written, *without* assuming extra -+ # include path. -+ ac_cv_have_uuid_h=yes - ], [ - WITH_SAVE_ENV([ - CPPFLAGS="$CPPFLAGS $LIBUUID_CFLAGS" - LIBS="$LIBS $LIBUUID_LIBS" - AC_CHECK_HEADERS([uuid/uuid.h], [ -+ ac_cv_have_uuid_uuid_h=yes - PY_CHECK_LIB([uuid], [uuid_generate_time], [have_uuid=yes]) -- PY_CHECK_LIB([uuid], [uuid_generate_time_safe], -- [have_uuid=yes -- AC_DEFINE([HAVE_UUID_GENERATE_TIME_SAFE], [1]) ]) ]) -+ PY_CHECK_LIB([uuid], [uuid_generate_time_safe], [ -+ have_uuid=yes -+ ac_cv_have_uuid_generate_time_safe=yes -+ ])]) - AS_VAR_IF([have_uuid], [yes], [ - LIBUUID_CFLAGS=${LIBUUID_CFLAGS-""} - LIBUUID_LIBS=${LIBUUID_LIBS-"-luuid"} -@@ -3785,14 +3797,90 @@ AS_VAR_IF([have_uuid], [missing], [ - AC_CHECK_HEADERS([uuid/uuid.h], [ - AC_CHECK_FUNC([uuid_generate_time], [ - have_uuid=yes -+ ac_cv_have_uuid_uuid_h=yes - LIBUUID_CFLAGS=${LIBUUID_CFLAGS-""} - LIBUUID_LIBS=${LIBUUID_LIBS-""} - ]) - ]) - ]) - -+AS_VAR_IF([ac_cv_have_uuid_h], [yes], [AC_DEFINE([HAVE_UUID_H], [1])]) -+AS_VAR_IF([ac_cv_have_uuid_uuid_h], [yes], [AC_DEFINE([HAVE_UUID_UUID_H], [1])]) -+AS_VAR_IF([ac_cv_have_uuid_generate_time_safe], [yes], [ -+ AC_DEFINE([HAVE_UUID_GENERATE_TIME_SAFE], [1]) -+]) -+ -+# gh-124228: While the libuuid library is available on NetBSD, it supports only UUID version 4. -+# This restriction inhibits the proper generation of time-based UUIDs. -+if test "$ac_sys_system" = "NetBSD"; then -+ have_uuid=missing -+ AC_DEFINE([HAVE_UUID_H], [0]) -+fi -+ - AS_VAR_IF([have_uuid], [missing], [have_uuid=no]) - -+# gh-132710: The UUID node is fetched by using libuuid when possible -+# and cached. While the node is constant within the same process, -+# different interpreters may have different values as libuuid may -+# randomize the node value if the latter cannot be deduced. -+# -+# Consumers may define HAVE_UUID_GENERATE_TIME_SAFE_STABLE_MAC -+# to indicate that libuuid is unstable and should not be relied -+# upon to deduce the MAC address. -+AC_DEFUN([PY_EXTRACT_UUID_GENERATE_TIME_SAFE_MAC], [WITH_SAVE_ENV([ -+ # Be sure to add the extra include path if we used pkg-config -+ # as HAVE_UUID_H may be set even though is only reachable -+ # by adding extra -I flags. -+ # -+ # If the following script does not compile, we simply assume that -+ # libuuid is missing. -+ CFLAGS="$CFLAGS $LIBUUID_CFLAGS" -+ LIBS="$LIBS $LIBUUID_LIBS" -+ AC_RUN_IFELSE([AC_LANG_SOURCE([[ -+ #include // PRIu64 -+ #include // uint64_t -+ #include // fopen(), fclose() -+ -+ #ifdef HAVE_UUID_H -+ #include -+ #else -+ #include -+ #endif -+ -+ #define ERR 1 -+ int main(void) { -+ uuid_t uuid; // unsigned char[16] -+ (void)uuid_generate_time_safe(uuid); -+ uint64_t node = 0; -+ for (size_t i = 0; i < 6; i++) { -+ node |= (uint64_t)uuid[15 - i] << (8 * i); -+ } -+ FILE *fp = fopen("conftest.out", "w"); -+ if (fp == NULL) { -+ return ERR; -+ } -+ int rc = fprintf(fp, "%" PRIu64 "\n", node) >= 0; -+ rc |= fclose(fp); -+ return rc == 0 ? 0 : ERR; -+ }]])], [ -+ AS_VAR_SET([$1], [`cat conftest.out`]) -+ ], [], [] -+ )])]) -+ -+if test "$have_uuid" = "yes" -a "$HAVE_UUID_GENERATE_TIME_SAFE" = "1" -+then -+ AC_MSG_CHECKING([if uuid_generate_time_safe() node value is stable]) -+ PY_EXTRACT_UUID_GENERATE_TIME_SAFE_MAC([py_cv_uuid_node1]) -+ PY_EXTRACT_UUID_GENERATE_TIME_SAFE_MAC([py_cv_uuid_node2]) -+ if test -n "$py_cv_uuid_node1" -a "$py_cv_uuid_node1" = "$py_cv_uuid_node2" -+ then -+ AC_DEFINE([HAVE_UUID_GENERATE_TIME_SAFE_STABLE_MAC], [1]) -+ AC_MSG_RESULT([stable]) -+ else -+ AC_MSG_RESULT([unstable]) -+ fi -+fi -+ - # 'Real Time' functions on Solaris - # posix4 on Solaris 2.6 - # pthread (first!) on Linux -diff --git a/pyconfig.h.in b/pyconfig.h.in -index 3c16c694c84599..73358a0f35ae82 100644 ---- a/pyconfig.h.in -+++ b/pyconfig.h.in -@@ -1548,6 +1548,9 @@ - /* Define if uuid_generate_time_safe() exists. */ - #undef HAVE_UUID_GENERATE_TIME_SAFE - -+/* Define if uuid_generate_time_safe() is able to deduce a MAC address. */ -+#undef HAVE_UUID_GENERATE_TIME_SAFE_STABLE_MAC -+ - /* Define to 1 if you have the header file. */ - #undef HAVE_UUID_H - - -From cb0f32a7d64b6dc4a63c4a683bb52a97ebe1d78a Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= - <10796600+picnixz@users.noreply.github.com> -Date: Mon, 26 May 2025 12:34:00 +0200 -Subject: [PATCH 2/2] rgen - ---- - configure | 25 ++++++------------------- - 1 file changed, 6 insertions(+), 19 deletions(-) - -diff --git a/configure b/configure -index cc976aafc09b34..47e4f29e23a7ac 100755 ---- a/configure -+++ b/configure -@@ -13735,14 +13735,7 @@ else - LIBUUID_LIBS=$pkg_cv_LIBUUID_LIBS - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 - printf "%s\n" "yes" >&6; } --<<<<<<< HEAD - have_uuid=yes -- printf "%s\n" "#define HAVE_UUID_H 1" >>confdefs.h -- -- printf "%s\n" "#define HAVE_UUID_GENERATE_TIME_SAFE 1" >>confdefs.h -- --======= -- have_uuid=yes - ac_cv_have_uuid_generate_time_safe=yes - # The uuid.h file to include may be *or* . - # Since pkg-config --cflags uuid may return -I/usr/include/uuid, -@@ -13753,7 +13746,6 @@ printf "%s\n" "yes" >&6; } - # #include can be written, *without* assuming extra - # include path. - ac_cv_have_uuid_h=yes -->>>>>>> 3bffada4672 (gh-132710: only use stable `_uuid.generate_time_safe()` to deduce MAC address (#132901)) - - fi - -@@ -13787,8 +13779,6 @@ done - - fi - --<<<<<<< HEAD --======= - if test "x$ac_cv_have_uuid_h" = xyes - then : - printf "%s\n" "#define HAVE_UUID_H 1" >>confdefs.h -@@ -13815,7 +13805,6 @@ if test "$ac_sys_system" = "NetBSD"; then - - fi - -->>>>>>> 3bffada4672 (gh-132710: only use stable `_uuid.generate_time_safe()` to deduce MAC address (#132901)) - if test "x$have_uuid" = xmissing - then : - have_uuid=no -@@ -13853,8 +13842,8 @@ save_LIBS=$LIBS - then : - - --else case e in #( -- e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext -+else $as_nop -+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext - /* end confdefs.h. */ - - #include // PRIu64 -@@ -13891,8 +13880,7 @@ then : - - fi - rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ -- conftest.$ac_objext conftest.beam conftest.$ac_ext ;; --esac -+ conftest.$ac_objext conftest.beam conftest.$ac_ext - fi - - CFLAGS=$save_CFLAGS -@@ -13919,8 +13907,8 @@ save_LIBS=$LIBS - then : - - --else case e in #( -- e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext -+else $as_nop -+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext - /* end confdefs.h. */ - - #include // PRIu64 -@@ -13957,8 +13945,7 @@ then : - - fi - rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ -- conftest.$ac_objext conftest.beam conftest.$ac_ext ;; --esac -+ conftest.$ac_objext conftest.beam conftest.$ac_ext - fi - - CFLAGS=$save_CFLAGS diff --git a/cpython-unix/targets.yml b/cpython-unix/targets.yml index 1b47dba..221a0e4 100644 --- a/cpython-unix/targets.yml +++ b/cpython-unix/targets.yml @@ -108,6 +108,7 @@ aarch64-apple-darwin: - tk - uuid - xz + - zstd openssl_target: darwin64-arm64-cc aarch64-apple-ios: @@ -151,11 +152,13 @@ aarch64-apple-ios: - openssl-3.0 - sqlite - xz + - zstd openssl_target: ios64-cross aarch64-unknown-linux-gnu: host_platforms: - linux_x86_64 + - linux_aarch64 pythons_supported: - '3.9' - '3.10' @@ -163,11 +166,16 @@ aarch64-unknown-linux-gnu: - '3.12' - '3.13' - '3.14' - docker_image_suffix: .cross - host_cc: /usr/bin/x86_64-linux-gnu-gcc - host_cxx: /usr/bin/x86_64-linux-gnu-g++ - target_cc: /usr/bin/aarch64-linux-gnu-gcc - target_cxx: /usr/bin/aarch64-linux-gnu-g++ + docker_image_suffix: .debian9 + needs_toolchain: true + host_cc: clang + host_cxx: clang++ + target_cc: clang + target_cxx: clang++ + target_cflags: + - '-fvisibility=hidden' + # Needed to prevent BOLT from crashing. + - '-fdebug-default-version=4' needs: - autoconf - bdb @@ -187,12 +195,17 @@ aarch64-unknown-linux-gnu: - sqlite - tcl - tk - - tix - uuid - xorgproto - xz - zlib + - zstd openssl_target: linux-aarch64 + # Blocked on: + # BOLT-ERROR: Cannot relax adr in non-simple function + # trampoline_code_table/1. Use --strict option to override + # See https://github.com/llvm/llvm-project/issues/146541 + # bolt_capable: true arm64-apple-tvos: host_platforms: @@ -234,6 +247,7 @@ arm64-apple-tvos: - openssl-3.0 - sqlite - xz + - zstd openssl_target: todo armv7-unknown-linux-gnueabi: @@ -270,11 +284,11 @@ armv7-unknown-linux-gnueabi: - sqlite - tcl - tk - - tix - uuid - xorgproto - xz - zlib + - zstd openssl_target: linux-armv4 armv7-unknown-linux-gnueabihf: @@ -311,13 +325,54 @@ armv7-unknown-linux-gnueabihf: - sqlite - tcl - tk - - tix - uuid - xorgproto - xz - zlib + - zstd openssl_target: linux-armv4 +loongarch64-unknown-linux-gnu: + host_platforms: + - linux_x86_64 + pythons_supported: + - '3.9' + - '3.10' + - '3.11' + - '3.12' + - '3.13' + - '3.14' + docker_image_suffix: .cross-loongarch64 + host_cc: /usr/bin/x86_64-linux-gnu-gcc + host_cxx: /usr/bin/x86_64-linux-gnu-g++ + target_cc: /usr/bin/loongarch64-linux-gnu-gcc + target_cxx: /usr/bin/loongarch64-linux-gnu-g++ + needs: + - autoconf + - bdb + - binutils + - bzip2 + - expat + - libedit + - libffi + - libX11 + - libXau + - libxcb + - m4 + - mpdecimal + - ncurses + - openssl-3.0 + - patchelf + - sqlite + - tcl + - tk + - uuid + - xorgproto + - xz + - zlib + - zstd + openssl_target: linux64-loongarch64 + mips-unknown-linux-gnu: host_platforms: - linux_x86_64 @@ -352,11 +407,11 @@ mips-unknown-linux-gnu: - sqlite - tcl - tk - - tix - uuid - xorgproto - xz - zlib + - zstd openssl_target: linux-mips32 mipsel-unknown-linux-gnu: @@ -393,11 +448,11 @@ mipsel-unknown-linux-gnu: - sqlite - tcl - tk - - tix - uuid - xorgproto - xz - zlib + - zstd openssl_target: linux-mips32 ppc64le-unknown-linux-gnu: @@ -434,11 +489,11 @@ ppc64le-unknown-linux-gnu: - sqlite - tcl - tk - - tix - uuid - xorgproto - xz - zlib + - zstd openssl_target: linux-ppc64le riscv64-unknown-linux-gnu: @@ -475,11 +530,11 @@ riscv64-unknown-linux-gnu: - sqlite - tcl - tk - - tix - uuid - xorgproto - xz - zlib + - zstd openssl_target: linux64-riscv64 s390x-unknown-linux-gnu: @@ -516,11 +571,11 @@ s390x-unknown-linux-gnu: - sqlite - tcl - tk - - tix - uuid - xorgproto - xz - zlib + - zstd openssl_target: linux64-s390x thumb7k-apple-watchos: @@ -563,6 +618,7 @@ thumb7k-apple-watchos: - openssl-3.0 - sqlite - xz + - zstd openssl_target: todo # Intel macOS. @@ -618,6 +674,7 @@ x86_64-apple-darwin: - tk - uuid - xz + - zstd openssl_target: darwin64-x86_64-cc x86_64-apple-ios: @@ -661,6 +718,7 @@ x86_64-apple-ios: - openssl-3.0 - sqlite - xz + - zstd openssl_target: darwin64-x86_64-cc x86_64-apple-tvos: @@ -703,6 +761,7 @@ x86_64-apple-tvos: - openssl-3.0 - sqlite - xz + - zstd openssl_target: todo x86_64-apple-watchos: @@ -745,6 +804,7 @@ x86_64-apple-watchos: - openssl-3.0 - sqlite - xz + - zstd openssl_target: todo x86_64-unknown-linux-gnu: @@ -785,11 +845,11 @@ x86_64-unknown-linux-gnu: - sqlite - tcl - tk - - tix - uuid - xorgproto - xz - zlib + - zstd openssl_target: linux-x86_64 bolt_capable: true @@ -832,11 +892,11 @@ x86_64_v2-unknown-linux-gnu: - sqlite - tcl - tk - - tix - uuid - xorgproto - xz - zlib + - zstd openssl_target: linux-x86_64 bolt_capable: true @@ -879,11 +939,11 @@ x86_64_v3-unknown-linux-gnu: - sqlite - tcl - tk - - tix - uuid - xorgproto - xz - zlib + - zstd openssl_target: linux-x86_64 bolt_capable: true @@ -926,11 +986,11 @@ x86_64_v4-unknown-linux-gnu: - sqlite - tcl - tk - - tix - uuid - xorgproto - xz - zlib + - zstd openssl_target: linux-x86_64 bolt_capable: true @@ -971,11 +1031,11 @@ x86_64-unknown-linux-musl: - sqlite - tcl - tk - - tix - uuid - xorgproto - xz - zlib + - zstd openssl_target: linux-x86_64 x86_64_v2-unknown-linux-musl: @@ -1016,11 +1076,11 @@ x86_64_v2-unknown-linux-musl: - sqlite - tcl - tk - - tix - uuid - xorgproto - xz - zlib + - zstd openssl_target: linux-x86_64 x86_64_v3-unknown-linux-musl: @@ -1061,11 +1121,11 @@ x86_64_v3-unknown-linux-musl: - sqlite - tcl - tk - - tix - uuid - xorgproto - xz - zlib + - zstd openssl_target: linux-x86_64 x86_64_v4-unknown-linux-musl: @@ -1106,9 +1166,56 @@ x86_64_v4-unknown-linux-musl: - sqlite - tcl - tk - - tix - uuid - xorgproto - xz - zlib + - zstd openssl_target: linux-x86_64 + +aarch64-unknown-linux-musl: + host_platforms: + - linux_x86_64 + - linux_aarch64 + pythons_supported: + - '3.9' + - '3.10' + - '3.11' + - '3.12' + - '3.13' + - '3.14' + needs_toolchain: true + docker_image_suffix: .debian9 + needs_toolchain: true + host_cc: clang + host_cxx: clang++ + target_cc: musl-clang + target_cxx: clang++ + target_cflags: + - '-fvisibility=hidden' + needs: + - autoconf + - bdb + - binutils + - bzip2 + - expat + - libedit + - libffi-3.3 + - libX11 + - libXau + - libxcb + - m4 + - mpdecimal + - musl + - ncurses + - openssl-3.0 + - patchelf + - sqlite + - tcl + - tk + - uuid + - xorgproto + - xz + - zlib + - zstd + openssl_target: linux-aarch64 diff --git a/cpython-windows/build.py b/cpython-windows/build.py index 15b0a44..5fce1ab 100644 --- a/cpython-windows/build.py +++ b/cpython-windows/build.py @@ -370,7 +370,7 @@ def hack_props( mpdecimal_version = DOWNLOADS["mpdecimal"]["version"] - if meets_python_minimum_version(python_version, "3.14"): + if meets_python_minimum_version(python_version, "3.14") or arch == "arm64": tcltk_commit = DOWNLOADS["tk-windows-bin"]["git_commit"] else: tcltk_commit = DOWNLOADS["tk-windows-bin-8612"]["git_commit"] @@ -464,6 +464,8 @@ def hack_props( suffix = b"-x64" elif arch == "win32": suffix = b"" + elif arch == "arm64": + suffix = b"" else: raise Exception("unhandled architecture: %s" % arch) @@ -505,6 +507,7 @@ def hack_project_files( build_directory: str, python_version: str, zlib_entry: str, + arch: str, ): """Hacks Visual Studio project files to work with our build.""" @@ -518,6 +521,17 @@ def hack_project_files( zlib_entry, ) + # `--include-tcltk` is forced off on arm64, undo that + # See https://github.com/python/cpython/pull/132650 + try: + static_replace_in_file( + cpython_source_path / "PC" / "layout" / "main.py", + rb'if ns.arch in ("arm32", "arm64"):', + rb'if ns.arch == "arm32":', + ) + except NoSearchStringError: + pass + # Our SQLite directory is named weirdly. This throws off version detection # in the project file. Replace the parsing logic with a static string. sqlite3_version = DOWNLOADS["sqlite"]["actual_version"].encode("ascii") @@ -603,14 +617,18 @@ def hack_project_files( # have a standalone zlib DLL, so we remove references to it. For Python # 3.14+, we're using tk-windows-bin 8.6.14 which includes a prebuilt zlib # DLL, so we skip this patch there. - if meets_python_minimum_version( - python_version, "3.12" - ) and meets_python_maximum_version(python_version, "3.13"): - static_replace_in_file( - pcbuild_path / "_tkinter.vcxproj", - rb'<_TclTkDLL Include="$(tcltkdir)\bin\$(tclZlibDllName)" />', - rb"", - ) + # On arm64, we use the new version of tk-windows-bin for all versions. + if meets_python_minimum_version(python_version, "3.12") and ( + meets_python_maximum_version(python_version, "3.13") or arch == "arm64" + ): + try: + static_replace_in_file( + pcbuild_path / "_tkinter.vcxproj", + rb'<_TclTkDLL Include="$(tcltkdir)\bin\$(tclZlibDllName)" />', + rb"", + ) + except NoSearchStringError: + pass # We don't need to produce python_uwp.exe and its *w variant. Or the # python3.dll, pyshellext, or pylauncher. @@ -730,9 +748,11 @@ def build_openssl_for_arch( elif arch == "amd64": configure = "VC-WIN64A" prefix = "64" + elif arch == "arm64": + configure = "VC-WIN64-ARM" + prefix = "arm64" else: - print("invalid architecture: %s" % arch) - sys.exit(1) + raise Exception("unhandled architecture: %s" % arch) # The official CPython OpenSSL builds hack ms/uplink.c to change the # ``GetModuleHandle(NULL)`` invocation to load things from _ssl.pyd @@ -780,6 +800,12 @@ def build_openssl_for_arch( log("copying %s to %s" % (source, dest)) shutil.copyfile(source, dest) + # Copy `applink.c` to the include directory. + source_applink = source_root / "ms" / "applink.c" + dest_applink = install_root / "include" / "openssl" / "applink.c" + log("copying %s to %s" % (source_applink, dest_applink)) + shutil.copyfile(source_applink, dest_applink) + def build_openssl( entry: str, @@ -801,6 +827,7 @@ def build_openssl( root_32 = td / "x86" root_64 = td / "x64" + root_arm64 = td / "arm64" if arch == "x86": root_32.mkdir() @@ -824,13 +851,28 @@ def build_openssl( root_64, jom_archive=jom_archive, ) + elif arch == "arm64": + root_arm64.mkdir() + build_openssl_for_arch( + perl_path, + "arm64", + openssl_archive, + openssl_version, + nasm_archive, + root_arm64, + jom_archive=jom_archive, + ) else: - raise ValueError("unhandled arch: %s" % arch) + raise Exception("unhandled architecture: %s" % arch) install = td / "out" if arch == "x86": shutil.copytree(root_32 / "install" / "32", install / "openssl" / "win32") + elif arch == "arm64": + shutil.copytree( + root_arm64 / "install" / "arm64", install / "openssl" / "arm64" + ) else: shutil.copytree(root_64 / "install" / "64", install / "openssl" / "amd64") @@ -901,9 +943,14 @@ def build_libffi( if arch == "x86": args.append("-x86") artifacts_path = ffi_source_path / "i686-pc-cygwin" - else: + elif arch == "arm64": + args.append("-arm64") + artifacts_path = ffi_source_path / "aarch64-w64-cygwin" + elif arch == "amd64": args.append("-x64") artifacts_path = ffi_source_path / "x86_64-w64-cygwin" + else: + raise Exception("unhandled architecture: %s" % arch) subprocess.run(args, env=env, check=True) @@ -1069,8 +1116,10 @@ def find_additional_dependencies(project: pathlib.Path): abi_platform = "win_amd64" elif arch == "win32": abi_platform = "win32" + elif arch == "arm64": + abi_platform = "win_arm64" else: - raise ValueError("unhandled arch: %s" % arch) + raise Exception("unhandled architecture: %s" % arch) if freethreaded: abi_tag = ".cp%st-%s" % (python_majmin, abi_platform) @@ -1171,8 +1220,8 @@ def find_additional_dependencies(project: pathlib.Path): if name == "zlib": name = zlib_entry - # On 3.14+, we use the latest tcl/tk version - if ext == "_tkinter" and python_majmin == "314": + # On 3.14+ and aarch64, we use the latest tcl/tk version + if ext == "_tkinter" and (python_majmin == "314" or arch == "arm64"): name = name.replace("-8612", "") download_entry = DOWNLOADS[name] @@ -1258,16 +1307,18 @@ def build_cpython( setuptools_wheel = download_entry("setuptools", BUILD) pip_wheel = download_entry("pip", BUILD) - # On CPython 3.14+, we use the latest tcl/tk version which has additional runtime - # dependencies, so we are conservative and use the old version elsewhere. - if meets_python_minimum_version(python_version, "3.14"): - tk_bin_archive = download_entry( - "tk-windows-bin", BUILD, local_name="tk-windows-bin.tar.gz" - ) - else: - tk_bin_archive = download_entry( - "tk-windows-bin-8612", BUILD, local_name="tk-windows-bin.tar.gz" - ) + # On CPython 3.14+, we use the latest tcl/tk version which has additional + # runtime dependencies, so we are conservative and use the old version + # elsewhere. The old version isn't built for arm64, so we use the new + # version there too + tk_bin_entry = ( + "tk-windows-bin" + if meets_python_minimum_version(python_version, "3.14") or arch == "arm64" + else "tk-windows-bin-8612" + ) + tk_bin_archive = download_entry( + tk_bin_entry, BUILD, local_name="tk-windows-bin.tar.gz" + ) # On CPython 3.14+, zstd is included if meets_python_minimum_version(python_version, "3.14"): @@ -1297,8 +1348,11 @@ def build_cpython( elif arch == "x86": build_platform = "win32" build_directory = "win32" + elif arch == "arm64": + build_platform = "arm64" + build_directory = "arm64" else: - raise ValueError("unhandled arch: %s" % arch) + raise Exception("unhandled architecture: %s" % arch) tempdir_opts = ( {"ignore_cleanup_errors": True} if sys.version_info >= (3, 12) else {} @@ -1332,7 +1386,7 @@ def build_cpython( # We need all the OpenSSL library files in the same directory to appease # install rules. - openssl_arch = {"amd64": "amd64", "x86": "win32"}[arch] + openssl_arch = {"amd64": "amd64", "x86": "win32", "arm64": "arm64"}[arch] openssl_root = td / "openssl" / openssl_arch openssl_bin_path = openssl_root / "bin" openssl_lib_path = openssl_root / "lib" @@ -1346,6 +1400,18 @@ def build_cpython( log("copying %s to %s" % (source, dest)) shutil.copyfile(source, dest) + # Delete the tk nmake helper, it's not needed and links msvc + if tk_bin_entry == "tk-windows-bin": + tcltk_commit: str = DOWNLOADS[tk_bin_entry]["git_commit"] + tcltk_path = td / ("cpython-bin-deps-%s" % tcltk_commit) + ( + tcltk_path + / build_directory + / "lib" + / "nmake" + / "x86_64-w64-mingw32-nmakehlp.exe" + ).unlink() + cpython_source_path = td / ("Python-%s" % python_version) pcbuild_path = cpython_source_path / "PCbuild" @@ -1368,6 +1434,7 @@ def build_cpython( build_directory, python_version=python_version, zlib_entry=zlib_entry, + arch=arch, ) if pgo: @@ -1509,7 +1576,7 @@ def build_cpython( # import their contents. According to # https://github.com/pypa/pip/issues/11146 running pip from a wheel is not # supported. But it has historically worked and is simple. So do this until - # it stops working and we need to switch to running pip from the filesytem. + # it stops working and we need to switch to running pip from the filesystem. pip_env = dict(os.environ) pip_env["PYTHONPATH"] = str(pip_wheel) @@ -1775,7 +1842,7 @@ def main() -> None: ) parser.add_argument( "--windows-sdk-version", - default="10.0.20348.0", + default="10.0.26100.0", help="Windows SDK version to build with", ) @@ -1790,9 +1857,14 @@ def main() -> None: if os.environ.get("Platform") == "x86": target_triple = "i686-pc-windows-msvc" arch = "x86" - else: + elif os.environ.get("Platform") == "arm64": + target_triple = "aarch64-pc-windows-msvc" + arch = "arm64" + elif os.environ.get("Platform") == "x64": target_triple = "x86_64-pc-windows-msvc" arch = "amd64" + else: + raise Exception("unhandled architecture: %s" % os.environ.get("Platform")) # TODO need better dependency checking. diff --git a/docs/building.rst b/docs/building.rst index c6a07e2..4557072 100644 --- a/docs/building.rst +++ b/docs/building.rst @@ -39,6 +39,7 @@ As are various other targets:: $ ./build-linux.py --target aarch64-unknown-linux-gnu $ ./build-linux.py --target armv7-unknown-linux-gnueabi $ ./build-linux.py --target armv7-unknown-linux-gnueabihf + $ ./build-linux.py --target loongarch64-unknown-linux-gnu $ ./build-linux.py --target mips-unknown-linux-gnu $ ./build-linux.py --target mipsel-unknown-linux-gnu $ ./build-linux.py --target ppc64le-unknown-linux-gnu @@ -87,7 +88,7 @@ Visual Studio 2017 (or later) is required. A compatible Windows SDK is required (10.0.17763.0 as per CPython 3.7.2). * A ``git.exe`` on ``PATH`` (to clone ``libffi`` from source). -* An installation of Cywgin with the ``autoconf``, ``automake``, ``libtool``, +* An installation of Cygwin with the ``autoconf``, ``automake``, ``libtool``, and ``make`` packages installed. (``libffi`` build dependency.) To build a dynamically linked Python distribution for Windows x64:: diff --git a/docs/distributions.rst b/docs/distributions.rst index 3dd6125..16fb238 100644 --- a/docs/distributions.rst +++ b/docs/distributions.rst @@ -112,7 +112,7 @@ python_implementation_cache_tag (Version 5 or above only.) python_implementation_hex_version - Hexidecimal expression of implementation version. + Hexadecimal expression of implementation version. This is the value exposed by ``sys.implementation.hexversion``. @@ -237,7 +237,7 @@ python_suffixes (Version 5 or above only.) python_bytecode_magic_number - Magic number to use for bytecode files, expressed as a hexidecimal + Magic number to use for bytecode files, expressed as a hexadecimal string. (Version 5 or above only.) @@ -388,8 +388,8 @@ license_path tcl_library_path Relative path to location of tcl library files. The path should be a directory tree containing tcl files to support the tkinter extension. - This will include a subset of the library files provided by the tcl, tk, - and tix packages. + This will include a subset of the library files provided by the tcl + and tk packages. This points to the root directory containing tcl resources. Actual tcl resources are in sub-directories underneath, as identified by diff --git a/docs/quirks.rst b/docs/quirks.rst index 8900cd6..84b2e1e 100644 --- a/docs/quirks.rst +++ b/docs/quirks.rst @@ -71,18 +71,21 @@ ncurses/libedit/readline are loaded. .. _quirk_macos_no_tix: -No tix on macOS -=============== +No tix on UNIX +============== + +Tix is an old widget library for Tcl/Tk. Python previously had a wrapper +for it in ``tkinter.tix``, but it was deprecated in Python 3.6 (the +recommendation is to use ``tkinter.ttk``) and removed in Python 3.13. -macOS distributions do not contain tix tcl support files. This means that -``tkinter.tix`` module functionality will likely break at run-time. The -module will import fine. But attempting to instantiate a ``tkinter.tix.Tk`` -instance or otherwise attempt to run tix tcl files will result in a run-time -error. +The macOS and Linux distributions from this project do not build and +ship Tix, even for Python versions 3.12 and below. -``tkinter.tix`` has been deprecated since Python 3.6 and the official Python -macOS installers do not ship the tix support files. So this project behaves -similarly to the official CPython distributions. +We had previously attempted to ship Tix support on Linux, but it was +broken and nobody reported an issue about it. The macOS distributions +from this project never shipped support for Tix. The official Python.org +macOS installers and Apple's build of Python do not ship support for +Tix, either, so this project behaves similarly to those distributions. .. _quirk_windows_no_pip: @@ -139,64 +142,6 @@ Some functionality may behave subtly differently as a result of our choice to link ``libedit`` by default. (We choose ``libedit`` by default to avoid GPL licensing requirements of ``readline``.) -.. _quirk_linux_libx11: - -Static Linking of ``libX11`` / Incompatibility with PyQt on Linux -================================================================= - -The ``_tkinter`` Python extension module in the Python standard library -statically links against ``libX11``, ``libxcb``, and ``libXau`` on Linux. -In addition, the ``_tkinter`` extension module is statically linked into -``libpython`` and isn't a standalone shared library file. This effectively -means that all these X11 libraries are statically linked into the main -Python interpreter. - -On typical builds of Python on Linux, ``_tkinter`` will link against -external shared libraries. e.g.:: - - $ ldd /usr/lib/python3.9/lib-dynload/_tkinter.cpython-39-x86_64-linux-gnu.so - linux-vdso.so.1 (0x00007fff3be9d000) - libBLT.2.5.so.8.6 => /lib/libBLT.2.5.so.8.6 (0x00007fdb6a6f8000) - libtk8.6.so => /lib/x86_64-linux-gnu/libtk8.6.so (0x00007fdb6a584000) - libtcl8.6.so => /lib/x86_64-linux-gnu/libtcl8.6.so (0x00007fdb6a3c1000) - libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fdb6a1d5000) - libX11.so.6 => /lib/x86_64-linux-gnu/libX11.so.6 (0x00007fdb6a097000) - libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fdb69f49000) - libXft.so.2 => /lib/x86_64-linux-gnu/libXft.so.2 (0x00007fdb69f2e000) - libfontconfig.so.1 => /lib/x86_64-linux-gnu/libfontconfig.so.1 (0x00007fdb69ee6000) - libXss.so.1 => /lib/x86_64-linux-gnu/libXss.so.1 (0x00007fdb69ee1000) - libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fdb69eda000) - libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007fdb69ebe000) - libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fdb69e9c000) - /lib64/ld-linux-x86-64.so.2 (0x00007fdb6a892000) - libxcb.so.1 => /lib/x86_64-linux-gnu/libxcb.so.1 (0x00007fdb69e70000) - libfreetype.so.6 => /lib/x86_64-linux-gnu/libfreetype.so.6 (0x00007fdb69dad000) - libXrender.so.1 => /lib/x86_64-linux-gnu/libXrender.so.1 (0x00007fdb69da0000) - libexpat.so.1 => /lib/x86_64-linux-gnu/libexpat.so.1 (0x00007fdb69d71000) - libuuid.so.1 => /lib/x86_64-linux-gnu/libuuid.so.1 (0x00007fdb69d68000) - libXext.so.6 => /lib/x86_64-linux-gnu/libXext.so.6 (0x00007fdb69d53000) - libXau.so.6 => /lib/x86_64-linux-gnu/libXau.so.6 (0x00007fdb69d4b000) - libXdmcp.so.6 => /lib/x86_64-linux-gnu/libXdmcp.so.6 (0x00007fdb69d43000) - libpng16.so.16 => /lib/x86_64-linux-gnu/libpng16.so.16 (0x00007fdb69d08000) - libbrotlidec.so.1 => /lib/x86_64-linux-gnu/libbrotlidec.so.1 (0x00007fdb69cfa000) - libbsd.so.0 => /lib/x86_64-linux-gnu/libbsd.so.0 (0x00007fdb69ce2000) - libbrotlicommon.so.1 => /lib/x86_64-linux-gnu/libbrotlicommon.so.1 (0x00007fdb69cbd000) - libmd.so.0 => /lib/x86_64-linux-gnu/libmd.so.0 (0x00007fdb69cb0000) - -The static linking of ``libX11`` and other libraries can cause problems when -3rd party Python extension modules also loading similar libraries are also -loaded into the process. For example, extension modules associated with ``PyQt`` -are known to link against a shared ``libX11.so.6``. If multiple versions of -``libX11`` are loaded into the same process, run-time crashes / segfaults can -occur. See e.g. https://github.com/astral-sh/python-build-standalone/issues/95. - -The conceptual workaround is to not statically link ``libX11`` and similar -libraries into ``libpython``. However, this requires re-linking a custom -``libpython`` without ``_tkinter``. It is possible to do this with the object -files included in the distributions. But there isn't a turnkey way to do this. -And you can't easily remove ``_tkinter`` and its symbols from the pre-built -and ready-to-use Python install included in this project's distribution -artifacts. .. _quirk_references_to_build_paths: @@ -251,6 +196,7 @@ make distributions more portable, please file a GitHub issue. .. _quirk_former: .. _quirk_missing_libcrypt: +.. _quirk_linux_libx11: Former quirks ============= @@ -280,4 +226,13 @@ been resolved. New in Python 3.13`_ about third-party replacements for the ``crypt`` module. +* "Static Linking of ``libX11`` / Incompatibility with PyQt on Linux": + The 20220318 release and earlier exported dynamic symbols for the + internal, statically-linked build of ``libX11`` and other libraries. + These would cause conflicts and potential crashes when using + third-party extension modules such as PyQt that load an actual shared + ``libX11`` library (usually provided by your OS). Starting with the + 20220502 release, symbols from internal dependencies are no longer + exported. + .. _What's New in Python 3.13: https://docs.python.org/3/whatsnew/3.13.html#whatsnew313-pep594 diff --git a/docs/status.rst b/docs/status.rst index ef172e0..cd50e07 100644 --- a/docs/status.rst +++ b/docs/status.rst @@ -285,7 +285,7 @@ test_spwd test_startfile object has no attribute 'startfile' test_tix - cannot run without OS X gui process + tix is not built by this project test_tk cannot run without OS X gui process test_ttk_guionly diff --git a/pythonbuild/cpython.py b/pythonbuild/cpython.py index f339037..bd7213b 100644 --- a/pythonbuild/cpython.py +++ b/pythonbuild/cpython.py @@ -69,6 +69,7 @@ "properties": { "name": {"type": "string"}, "targets": {"type": "array", "items": {"type": "string"}}, + "build-mode": {"type": "string"}, }, "additionalProperties": False, }, @@ -535,7 +536,17 @@ def derive_setup_local( python_version, entry.get("maximum-python-version", "100.0") ) - if target_match and (python_min_match and python_max_match): + if build_mode := entry.get("build-mode"): + build_mode_match = section == build_mode + else: + build_mode_match = True + + if ( + target_match + and python_min_match + and python_max_match + and build_mode_match + ): if source := entry.get("source"): line += f" {source}" for source in entry.get("sources", []): @@ -672,7 +683,7 @@ def derive_setup_local( } -RE_INITTAB_ENTRY = re.compile('\{"([^"]+)", ([^\}]+)\},') +RE_INITTAB_ENTRY = re.compile(r'\{"([^"]+)", ([^\}]+)\},') def parse_config_c(s: str): diff --git a/pythonbuild/docker.py b/pythonbuild/docker.py index 4269b2b..0be78e4 100644 --- a/pythonbuild/docker.py +++ b/pythonbuild/docker.py @@ -29,8 +29,10 @@ def write_dockerfiles(source_dir: pathlib.Path, dest_dir: pathlib.Path): write_if_different(dest_dir / f, data.encode("utf-8")) -def build_docker_image(client, image_data: bytes, image_dir: pathlib.Path, name): - image_path = image_dir / ("image-%s" % name) +def build_docker_image( + client, image_data: bytes, image_dir: pathlib.Path, name, host_platform +): + image_path = image_dir / f"image-{name}.{host_platform}" return ensure_docker_image(client, io.BytesIO(image_data), image_path=image_path) @@ -66,11 +68,14 @@ def ensure_docker_image(client, fh, image_path=None): return image -def get_image(client, source_dir: pathlib.Path, image_dir: pathlib.Path, name): +def get_image( + client, source_dir: pathlib.Path, image_dir: pathlib.Path, name, host_platform +): if client is None: return None - image_path = image_dir / ("image-%s" % name) + image_name = f"image-{name}.{host_platform}" + image_path = image_dir / image_name tar_path = image_path.with_suffix(".tar") with image_path.open("r") as fh: @@ -88,7 +93,9 @@ def get_image(client, source_dir: pathlib.Path, image_dir: pathlib.Path, name): return image_id else: - return build_docker_image(client, str(source_dir).encode(), image_dir, name) + return build_docker_image( + client, str(source_dir).encode(), image_dir, name, host_platform + ) def copy_file_to_container(path, container, container_path, archive_path=None): diff --git a/pythonbuild/downloads.py b/pythonbuild/downloads.py index f59afd8..e1562c0 100644 --- a/pythonbuild/downloads.py +++ b/pythonbuild/downloads.py @@ -73,19 +73,19 @@ "python_tag": "cp312", }, "cpython-3.13": { - "url": "https://www.python.org/ftp/python/3.13.5/Python-3.13.5.tar.xz", - "size": 22856016, - "sha256": "93e583f243454e6e9e4588ca2c2662206ad961659863277afcdb96801647d640", - "version": "3.13.5", + "url": "https://www.python.org/ftp/python/3.13.7/Python-3.13.7.tar.xz", + "size": 22769492, + "sha256": "5462f9099dfd30e238def83c71d91897d8caa5ff6ebc7a50f14d4802cdaaa79a", + "version": "3.13.7", "licenses": ["Python-2.0", "CNRI-Python"], "license_file": "LICENSE.cpython.txt", "python_tag": "cp313", }, "cpython-3.14": { - "url": "https://www.python.org/ftp/python/3.14.0/Python-3.14.0b2.tar.xz", - "size": 23579860, - "sha256": "7ac9e84844bbc0a5a8f1f79a37a68b3b8caf2a58b4aa5999c49227cb36e70ea6", - "version": "3.14.0b2", + "url": "https://www.python.org/ftp/python/3.14.0/Python-3.14.0rc2.tar.xz", + "size": 23566140, + "sha256": "bc62854cf232345bd22c9091a68464e01e056c6473a3fffa84572c8a342da656", + "version": "3.14.0rc2", "licenses": ["Python-2.0", "CNRI-Python"], "license_file": "LICENSE.cpython.txt", "python_tag": "cp314", @@ -172,6 +172,13 @@ "version": "14.0.3+20220508", }, # Remember to update LLVM_URL in src/release.rs whenever upgrading. + "llvm-20-aarch64-linux": { + "url": "https://github.com/indygreg/toolchain-tools/releases/download/toolchain-bootstrap%2F20250511/llvm-20.1.4+20250511-gnu_only-aarch64-unknown-linux-gnu.tar.zst", + "size": 255946687, + "sha256": "e70753f294b8f83fffbaf07af36857c27ceaef0291cb10f724ada6af11b0a5bc", + "version": "20.1.4+20250511", + }, + # Remember to update LLVM_URL in src/release.rs whenever upgrading. "llvm-20-x86_64-linux": { "url": "https://github.com/indygreg/toolchain-tools/releases/download/toolchain-bootstrap%2F20250511/llvm-20.1.4+20250511-gnu_only-x86_64-unknown-linux-gnu.tar.zst", "size": 299883811, @@ -288,11 +295,11 @@ }, # Remember to update verify_distribution.py when version changed. "sqlite": { - "url": "https://www.sqlite.org/2024/sqlite-autoconf-3470100.tar.gz", - "size": 3328564, - "sha256": "416a6f45bf2cacd494b208fdee1beda509abda951d5f47bc4f2792126f01b452", - "version": "3470100", - "actual_version": "3.47.1.0", + "url": "https://www.sqlite.org/2025/sqlite-autoconf-3500400.tar.gz", + "size": 3173050, + "sha256": "a3db587a1b92ee5ddac2f66b3edb41b26f9c867275782d46c3a088977d6a5b18", + "version": "3500400", + "actual_version": "3.50.4.0", "library_names": ["sqlite3"], "licenses": [], "license_file": "LICENSE.sqlite.txt", @@ -372,10 +379,10 @@ "license_file": "LICENSE.libuuid.txt", }, "x11-util-macros": { - "url": "https://www.x.org/archive/individual/util/util-macros-1.20.1.tar.gz", - "size": 105481, - "sha256": "b373f72887b1394ce2193180a60cb0d1fb8b17bc96ddd770cfd7a808cb489a15", - "version": "1.20.1", + "url": "https://www.x.org/archive/individual/util/util-macros-1.20.2.tar.gz", + "size": 105410, + "sha256": "f642f8964d81acdf06653fdf9dbc210c43ce4bd308bd644a8d573148d0ced76b", + "version": "1.20.2", }, "xcb-proto": { "url": "https://xcb.freedesktop.org/dist/xcb-proto-1.17.0.tar.xz", @@ -383,19 +390,17 @@ "sha256": "2c1bacd2110f4799f74de6ebb714b94cf6f80fb112316b1219480fd22562148c", "version": "1.17.0", }, - # Newer versions from at least 2023 have build failures for reasons we haven't - # fully investigated. "xorgproto": { - "url": "https://www.x.org/archive/individual/proto/xorgproto-2019.1.tar.gz", - "size": 1119813, - "sha256": "38ad1d8316515785d53c5162b4b7022918e03c11d72a5bd9df0a176607f42bca", - "version": "2019.1", + "url": "https://www.x.org/archive/individual/proto/xorgproto-2024.1.tar.gz", + "size": 1115486, + "sha256": "4f6b9b4faf91e5df8265b71843a91fc73dc895be6210c84117a996545df296ce", + "version": "2024.1", }, "xtrans": { - "url": "https://www.x.org/archive/individual/lib/xtrans-1.5.0.tar.gz", - "size": 230197, - "sha256": "a806f8a92f879dcd0146f3f1153fdffe845f2fc0df9b1a26c19312b7b0a29c86", - "version": "1.5.0", + "url": "https://www.x.org/archive/individual/lib/xtrans-1.6.0.tar.gz", + "size": 239113, + "sha256": "936b74c60b19c317c3f3cb1b114575032528dbdaf428740483200ea874c2ca0a", + "version": "1.6.0", }, # IMPORTANT: xz 5.6 has a backdoor. Be extremely cautious before taking any xz # upgrade since it isn't clear which versions are safe. diff --git a/pythonbuild/utils.py b/pythonbuild/utils.py index a8132ca..9e581c5 100644 --- a/pythonbuild/utils.py +++ b/pythonbuild/utils.py @@ -39,6 +39,8 @@ def current_host_platform() -> str: if sys.platform == "linux": if machine == "x86_64": return "linux_x86_64" + elif machine == "aarch64": + return "linux_aarch64" else: raise Exception(f"unsupported Linux host platform: {machine}") elif sys.platform == "darwin": @@ -57,6 +59,8 @@ def default_target_triple() -> str: host = current_host_platform() if host == "linux_x86_64": return "x86_64-unknown-linux-gnu" + elif host == "linux_aarch64": + return "aarch64-unknown-linux-gnu" elif host == "macos_arm64": return "aarch64-apple-darwin" elif host == "macos_x86_64": @@ -84,6 +88,8 @@ def supported_targets(yaml_path: pathlib.Path): for host_platform in settings["host_platforms"]: if sys.platform == "linux" and host_platform == "linux_x86_64": targets.add(target) + elif sys.platform == "linux" and host_platform == "linux_aarch64": + targets.add(target) elif sys.platform == "darwin" and host_platform.startswith("macos_"): targets.add(target) @@ -194,7 +200,13 @@ def write_triples_makefiles( image_suffix = settings.get("docker_image_suffix", "") + # On cross builds, we can just use the bare `gcc` image + gcc_image_suffix = ( + image_suffix if not image_suffix.startswith(".cross") else "" + ) + lines.append("DOCKER_IMAGE_BUILD := build%s\n" % image_suffix) + lines.append("DOCKER_IMAGE_GCC := gcc%s\n" % gcc_image_suffix) entry = clang_toolchain(host_platform, triple) lines.append( @@ -470,6 +482,8 @@ def clang_toolchain(host_platform: str, target_triple: str) -> str: return "llvm-14-x86_64-linux" else: return "llvm-20-x86_64-linux" + elif host_platform == "linux_aarch64": + return "llvm-20-aarch64-linux" elif host_platform == "macos_arm64": return "llvm-aarch64-macos" elif host_platform == "macos_x86_64": @@ -639,21 +653,22 @@ def validate_python_json(info, extension_modules): def release_download_statistics(mode="by_asset"): - with urllib.request.urlopen( - "https://api.github.com/repos/astral-sh/python-build-standalone/releases" - ) as fh: - data = json.load(fh) + import github by_tag = collections.Counter() by_build = collections.Counter() by_build_install_only = collections.Counter() - for release in data: - tag = release["tag_name"] + # Default paging settings time out. Reduce page size as a workaround. + gh = github.Github(per_page=5) + + repo = gh.get_repo("astral-sh/python-build-standalone") + for release in repo.get_releases(): + tag = release.tag_name - for asset in release["assets"]: - name = asset["name"] - count = asset["download_count"] + for asset in release.assets: + name = asset.name + count = asset.download_count by_tag[tag] += count diff --git a/requirements.dev.in b/requirements.dev.in index 2f64d57..b06a90a 100644 --- a/requirements.dev.in +++ b/requirements.dev.in @@ -2,6 +2,7 @@ ruff mypy +PyGithub types-jsonschema types-PyYAML types-jinja2 diff --git a/requirements.dev.txt b/requirements.dev.txt index 68171eb..d050fe1 100644 --- a/requirements.dev.txt +++ b/requirements.dev.txt @@ -13,6 +13,78 @@ certifi==2024.12.14 \ # via # -r requirements.txt # requests +cffi==1.17.1 \ + --hash=sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8 \ + --hash=sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2 \ + --hash=sha256:0e2b1fac190ae3ebfe37b979cc1ce69c81f4e4fe5746bb401dca63a9062cdaf1 \ + --hash=sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15 \ + --hash=sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36 \ + --hash=sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824 \ + --hash=sha256:1d599671f396c4723d016dbddb72fe8e0397082b0a77a4fab8028923bec050e8 \ + --hash=sha256:28b16024becceed8c6dfbc75629e27788d8a3f9030691a1dbf9821a128b22c36 \ + --hash=sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17 \ + --hash=sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf \ + --hash=sha256:31000ec67d4221a71bd3f67df918b1f88f676f1c3b535a7eb473255fdc0b83fc \ + --hash=sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3 \ + --hash=sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed \ + --hash=sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702 \ + --hash=sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1 \ + --hash=sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8 \ + --hash=sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903 \ + --hash=sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6 \ + --hash=sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d \ + --hash=sha256:636062ea65bd0195bc012fea9321aca499c0504409f413dc88af450b57ffd03b \ + --hash=sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e \ + --hash=sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be \ + --hash=sha256:6f17be4345073b0a7b8ea599688f692ac3ef23ce28e5df79c04de519dbc4912c \ + --hash=sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683 \ + --hash=sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9 \ + --hash=sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c \ + --hash=sha256:7596d6620d3fa590f677e9ee430df2958d2d6d6de2feeae5b20e82c00b76fbf8 \ + --hash=sha256:78122be759c3f8a014ce010908ae03364d00a1f81ab5c7f4a7a5120607ea56e1 \ + --hash=sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4 \ + --hash=sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655 \ + --hash=sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67 \ + --hash=sha256:9755e4345d1ec879e3849e62222a18c7174d65a6a92d5b346b1863912168b595 \ + --hash=sha256:98e3969bcff97cae1b2def8ba499ea3d6f31ddfdb7635374834cf89a1a08ecf0 \ + --hash=sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65 \ + --hash=sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41 \ + --hash=sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6 \ + --hash=sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401 \ + --hash=sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6 \ + --hash=sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3 \ + --hash=sha256:b2ab587605f4ba0bf81dc0cb08a41bd1c0a5906bd59243d56bad7668a6fc6c16 \ + --hash=sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93 \ + --hash=sha256:c03e868a0b3bc35839ba98e74211ed2b05d2119be4e8a0f224fba9384f1fe02e \ + --hash=sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4 \ + --hash=sha256:c7eac2ef9b63c79431bc4b25f1cd649d7f061a28808cbc6c47b534bd789ef964 \ + --hash=sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c \ + --hash=sha256:ca74b8dbe6e8e8263c0ffd60277de77dcee6c837a3d0881d8c1ead7268c9e576 \ + --hash=sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0 \ + --hash=sha256:cdf5ce3acdfd1661132f2a9c19cac174758dc2352bfe37d98aa7512c6b7178b3 \ + --hash=sha256:d016c76bdd850f3c626af19b0542c9677ba156e4ee4fccfdd7848803533ef662 \ + --hash=sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3 \ + --hash=sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff \ + --hash=sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5 \ + --hash=sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd \ + --hash=sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f \ + --hash=sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5 \ + --hash=sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14 \ + --hash=sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d \ + --hash=sha256:e221cf152cff04059d011ee126477f0d9588303eb57e88923578ace7baad17f9 \ + --hash=sha256:e31ae45bc2e29f6b2abd0de1cc3b9d5205aa847cafaecb8af1476a609a2f6eb7 \ + --hash=sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382 \ + --hash=sha256:f1e22e8c4419538cb197e4dd60acc919d7696e5ef98ee4da4e01d3f8cfa4cc5a \ + --hash=sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e \ + --hash=sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a \ + --hash=sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4 \ + --hash=sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99 \ + --hash=sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87 \ + --hash=sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b + # via + # -r requirements.txt + # cryptography + # pynacl charset-normalizer==3.4.1 \ --hash=sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537 \ --hash=sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa \ @@ -109,6 +181,53 @@ charset-normalizer==3.4.1 \ # via # -r requirements.txt # requests +cryptography==45.0.5 \ + --hash=sha256:0027d566d65a38497bc37e0dd7c2f8ceda73597d2ac9ba93810204f56f52ebc7 \ + --hash=sha256:101ee65078f6dd3e5a028d4f19c07ffa4dd22cce6a20eaa160f8b5219911e7d8 \ + --hash=sha256:12e55281d993a793b0e883066f590c1ae1e802e3acb67f8b442e721e475e6463 \ + --hash=sha256:14d96584701a887763384f3c47f0ca7c1cce322aa1c31172680eb596b890ec30 \ + --hash=sha256:1e1da5accc0c750056c556a93c3e9cb828970206c68867712ca5805e46dc806f \ + --hash=sha256:206210d03c1193f4e1ff681d22885181d47efa1ab3018766a7b32a7b3d6e6afd \ + --hash=sha256:2089cc8f70a6e454601525e5bf2779e665d7865af002a5dec8d14e561002e135 \ + --hash=sha256:3a264aae5f7fbb089dbc01e0242d3b67dffe3e6292e1f5182122bdf58e65215d \ + --hash=sha256:3af26738f2db354aafe492fb3869e955b12b2ef2e16908c8b9cb928128d42c57 \ + --hash=sha256:3fcfbefc4a7f332dece7272a88e410f611e79458fab97b5efe14e54fe476f4fd \ + --hash=sha256:460f8c39ba66af7db0545a8c6f2eabcbc5a5528fc1cf6c3fa9a1e44cec33385e \ + --hash=sha256:57c816dfbd1659a367831baca4b775b2a5b43c003daf52e9d57e1d30bc2e1b0e \ + --hash=sha256:5aa1e32983d4443e310f726ee4b071ab7569f58eedfdd65e9675484a4eb67bd1 \ + --hash=sha256:6ff8728d8d890b3dda5765276d1bc6fb099252915a2cd3aff960c4c195745dd0 \ + --hash=sha256:7259038202a47fdecee7e62e0fd0b0738b6daa335354396c6ddebdbe1206af2a \ + --hash=sha256:72e76caa004ab63accdf26023fccd1d087f6d90ec6048ff33ad0445abf7f605a \ + --hash=sha256:7760c1c2e1a7084153a0f68fab76e754083b126a47d0117c9ed15e69e2103492 \ + --hash=sha256:8c4a6ff8a30e9e3d38ac0539e9a9e02540ab3f827a3394f8852432f6b0ea152e \ + --hash=sha256:9024beb59aca9d31d36fcdc1604dd9bbeed0a55bface9f1908df19178e2f116e \ + --hash=sha256:90cb0a7bb35959f37e23303b7eed0a32280510030daba3f7fdfbb65defde6a97 \ + --hash=sha256:91098f02ca81579c85f66df8a588c78f331ca19089763d733e34ad359f474174 \ + --hash=sha256:926c3ea71a6043921050eaa639137e13dbe7b4ab25800932a8498364fc1abec9 \ + --hash=sha256:982518cd64c54fcada9d7e5cf28eabd3ee76bd03ab18e08a48cad7e8b6f31b18 \ + --hash=sha256:9b4cf6318915dccfe218e69bbec417fdd7c7185aa7aab139a2c0beb7468c89f0 \ + --hash=sha256:ad0caded895a00261a5b4aa9af828baede54638754b51955a0ac75576b831b27 \ + --hash=sha256:b85980d1e345fe769cfc57c57db2b59cff5464ee0c045d52c0df087e926fbe63 \ + --hash=sha256:b8fa8b0a35a9982a3c60ec79905ba5bb090fc0b9addcfd3dc2dd04267e45f25e \ + --hash=sha256:b9e38e0a83cd51e07f5a48ff9691cae95a79bea28fe4ded168a8e5c6c77e819d \ + --hash=sha256:bd4c45986472694e5121084c6ebbd112aa919a25e783b87eb95953c9573906d6 \ + --hash=sha256:be97d3a19c16a9be00edf79dca949c8fa7eff621763666a145f9f9535a5d7f42 \ + --hash=sha256:c648025b6840fe62e57107e0a25f604db740e728bd67da4f6f060f03017d5097 \ + --hash=sha256:d05a38884db2ba215218745f0781775806bde4f32e07b135348355fe8e4991d9 \ + --hash=sha256:dd420e577921c8c2d31289536c386aaa30140b473835e97f83bc71ea9d2baf2d \ + --hash=sha256:e357286c1b76403dd384d938f93c46b2b058ed4dfcdce64a770f0537ed3feb6f \ + --hash=sha256:e6c00130ed423201c5bc5544c23359141660b07999ad82e34e7bb8f882bb78e0 \ + --hash=sha256:e74d30ec9c7cb2f404af331d5b4099a9b322a8a6b25c4632755c8757345baac5 \ + --hash=sha256:f3562c2f23c612f2e4a6964a61d942f891d29ee320edb62ff48ffb99f3de9ae8 + # via + # -r requirements.txt + # pyjwt +deprecated==1.2.18 \ + --hash=sha256:422b6f6d859da6f2ef57857761bfb392480502a64c3028ca9bbe86085d72115d \ + --hash=sha256:bd5011788200372a32418f888e326a09ff80d0214bd961147cfed01b5c018eec + # via + # -r requirements.txt + # pygithub docker==7.1.0 \ --hash=sha256:ad8c70e6e3f8926cb8a92619b832b4ea5299e2831c14284663184e200546fa6c \ --hash=sha256:c96b93b7f0a746f9e77d325bcfb87422a3d8bd4f03136ae8a85b37f1898d5fc0 @@ -198,39 +317,45 @@ markupsafe==3.0.2 \ # via # -r requirements.txt # jinja2 -mypy==1.16.0 \ - --hash=sha256:021a68568082c5b36e977d54e8f1de978baf401a33884ffcea09bd8e88a98f4c \ - --hash=sha256:089bedc02307c2548eb51f426e085546db1fa7dd87fbb7c9fa561575cf6eb1ff \ - --hash=sha256:09a8da6a0ee9a9770b8ff61b39c0bb07971cda90e7297f4213741b48a0cc8d93 \ - --hash=sha256:0b07e107affb9ee6ce1f342c07f51552d126c32cd62955f59a7db94a51ad12c0 \ - --hash=sha256:15486beea80be24ff067d7d0ede673b001d0d684d0095803b3e6e17a886a2a92 \ - --hash=sha256:29e1499864a3888bca5c1542f2d7232c6e586295183320caa95758fc84034031 \ - --hash=sha256:2e7e0ad35275e02797323a5aa1be0b14a4d03ffdb2e5f2b0489fa07b89c67b21 \ - --hash=sha256:4086883a73166631307fdd330c4a9080ce24913d4f4c5ec596c601b3a4bdd777 \ - --hash=sha256:54066fed302d83bf5128632d05b4ec68412e1f03ef2c300434057d66866cea4b \ - --hash=sha256:55f9076c6ce55dd3f8cd0c6fff26a008ca8e5131b89d5ba6d86bd3f47e736eeb \ - --hash=sha256:6a2322896003ba66bbd1318c10d3afdfe24e78ef12ea10e2acd985e9d684a666 \ - --hash=sha256:7909541fef256527e5ee9c0a7e2aeed78b6cda72ba44298d1334fe7881b05c5c \ - --hash=sha256:82d056e6faa508501af333a6af192c700b33e15865bda49611e3d7d8358ebea2 \ - --hash=sha256:84b94283f817e2aa6350a14b4a8fb2a35a53c286f97c9d30f53b63620e7af8ab \ - --hash=sha256:936ccfdd749af4766be824268bfe22d1db9eb2f34a3ea1d00ffbe5b5265f5491 \ - --hash=sha256:9f826aaa7ff8443bac6a494cf743f591488ea940dd360e7dd330e30dd772a5ab \ - --hash=sha256:a5fcfdb7318c6a8dd127b14b1052743b83e97a970f0edb6c913211507a255e20 \ - --hash=sha256:a7e32297a437cc915599e0578fa6bc68ae6a8dc059c9e009c628e1c47f91495d \ - --hash=sha256:a9e056237c89f1587a3be1a3a70a06a698d25e2479b9a2f57325ddaaffc3567b \ - --hash=sha256:afe420c9380ccec31e744e8baff0d406c846683681025db3531b32db56962d52 \ - --hash=sha256:b4968f14f44c62e2ec4a038c8797a87315be8df7740dc3ee8d3bfe1c6bf5dba8 \ - --hash=sha256:bd4e1ebe126152a7bbaa4daedd781c90c8f9643c79b9748caa270ad542f12bec \ - --hash=sha256:c5436d11e89a3ad16ce8afe752f0f373ae9620841c50883dc96f8b8805620b13 \ - --hash=sha256:c6fb60cbd85dc65d4d63d37cb5c86f4e3a301ec605f606ae3a9173e5cf34997b \ - --hash=sha256:d045d33c284e10a038f5e29faca055b90eee87da3fc63b8889085744ebabb5a1 \ - --hash=sha256:e71d6f0090c2256c713ed3d52711d01859c82608b5d68d4fa01a3fe30df95571 \ - --hash=sha256:eb14a4a871bb8efb1e4a50360d4e3c8d6c601e7a31028a2c79f9bb659b63d730 \ - --hash=sha256:eb5fbc8063cb4fde7787e4c0406aa63094a34a2daf4673f359a1fb64050e9cb2 \ - --hash=sha256:f2622af30bf01d8fc36466231bdd203d120d7a599a6d88fb22bdcb9dbff84090 \ - --hash=sha256:f2ed0e0847a80655afa2c121835b848ed101cc7b8d8d6ecc5205aedc732b1436 \ - --hash=sha256:f56236114c425620875c7cf71700e3d60004858da856c6fc78998ffe767b73d3 \ - --hash=sha256:feec38097f71797da0231997e0de3a58108c51845399669ebc532c815f93866b +mypy==1.17.1 \ + --hash=sha256:03b6d0ed2b188e35ee6d5c36b5580cffd6da23319991c49ab5556c023ccf1341 \ + --hash=sha256:064e2ff508e5464b4bd807a7c1625bc5047c5022b85c70f030680e18f37273a5 \ + --hash=sha256:099b9a5da47de9e2cb5165e581f158e854d9e19d2e96b6698c0d64de911dd849 \ + --hash=sha256:15a83369400454c41ed3a118e0cc58bd8123921a602f385cb6d6ea5df050c733 \ + --hash=sha256:15d54056f7fe7a826d897789f53dd6377ec2ea8ba6f776dc83c2902b899fee81 \ + --hash=sha256:1b16708a66d38abb1e6b5702f5c2c87e133289da36f6a1d15f6a5221085c6403 \ + --hash=sha256:209a58fed9987eccc20f2ca94afe7257a8f46eb5df1fb69958650973230f91e6 \ + --hash=sha256:25e01ec741ab5bb3eec8ba9cdb0f769230368a22c959c4937360efb89b7e9f01 \ + --hash=sha256:397fba5d7616a5bc60b45c7ed204717eaddc38f826e3645402c426057ead9a91 \ + --hash=sha256:3fbe6d5555bf608c47203baa3e72dbc6ec9965b3d7c318aa9a4ca76f465bd972 \ + --hash=sha256:43808d9476c36b927fbcd0b0255ce75efe1b68a080154a38ae68a7e62de8f0f8 \ + --hash=sha256:55b918670f692fc9fba55c3298d8a3beae295c5cded0a55dccdc5bbead814acd \ + --hash=sha256:5d1092694f166a7e56c805caaf794e0585cabdbf1df36911c414e4e9abb62ae9 \ + --hash=sha256:62761474061feef6f720149d7ba876122007ddc64adff5ba6f374fda35a018a0 \ + --hash=sha256:665afab0963a4b39dff7c1fa563cc8b11ecff7910206db4b2e64dd1ba25aed19 \ + --hash=sha256:69e83ea6553a3ba79c08c6e15dbd9bfa912ec1e493bf75489ef93beb65209aeb \ + --hash=sha256:70401bbabd2fa1aa7c43bb358f54037baf0586f41e83b0ae67dd0534fc64edfd \ + --hash=sha256:79d44f9bfb004941ebb0abe8eff6504223a9c1ac51ef967d1263c6572bbebc99 \ + --hash=sha256:80ef5c058b7bce08c83cac668158cb7edea692e458d21098c7d3bce35a5d43e7 \ + --hash=sha256:89e972c0035e9e05823907ad5398c5a73b9f47a002b22359b177d40bdaee7056 \ + --hash=sha256:93378d3203a5c0800c6b6d850ad2f19f7a3cdf1a3701d3416dbf128805c6a6a7 \ + --hash=sha256:9a2b7d9180aed171f033c9f2fc6c204c1245cf60b0cb61cf2e7acc24eea78e0a \ + --hash=sha256:9d6b20b97d373f41617bd0708fd46aa656059af57f2ef72aa8c7d6a2b73b74ed \ + --hash=sha256:a76906f26bd8d51ea9504966a9c25419f2e668f012e0bdf3da4ea1526c534d94 \ + --hash=sha256:a9f52c0351c21fe24c21d8c0eb1f62967b262d6729393397b6f443c3b773c3b9 \ + --hash=sha256:ad37544be07c5d7fba814eb370e006df58fed8ad1ef33ed1649cb1889ba6ff58 \ + --hash=sha256:b01586eed696ec905e61bd2568f48740f7ac4a45b3a468e6423a03d3788a51a8 \ + --hash=sha256:c1fdf4abb29ed1cb091cf432979e162c208a5ac676ce35010373ff29247bcad5 \ + --hash=sha256:c49562d3d908fd49ed0938e5423daed8d407774a479b595b143a3d7f87cdae6a \ + --hash=sha256:c4a580f8a70c69e4a75587bd925d298434057fe2a428faaf927ffe6e4b9a98df \ + --hash=sha256:c837b896b37cd103570d776bda106eabb8737aa6dd4f248451aecf53030cdbeb \ + --hash=sha256:d7598cf74c3e16539d4e2f0b8d8c318e00041553d83d4861f87c7a72e95ac24d \ + --hash=sha256:dd86bb649299f09d987a2eebb4d52d10603224500792e1bee18303bbcc1ce390 \ + --hash=sha256:e79311f2d904ccb59787477b7bd5d26f3347789c06fcd7656fa500875290264b \ + --hash=sha256:e92bdc656b7757c438660f775f872a669b8ff374edc4d18277d86b63edba6b8b \ + --hash=sha256:fa6ffadfbe6994d724c5a1bb6123a7d27dd68fc9c059561cd33b664a79578e14 \ + --hash=sha256:feb8cc32d319edd5859da2cc084493b3e2ce5e49a946377663cc90f6c15fb259 \ + --hash=sha256:ff2933428516ab63f961644bc49bc4cbe42bbffb2cd3b71cc7277c07d16b1a8b # via -r requirements.dev.in mypy-extensions==1.0.0 \ --hash=sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d \ @@ -240,6 +365,38 @@ pathspec==0.12.1 \ --hash=sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08 \ --hash=sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712 # via mypy +pycparser==2.22 \ + --hash=sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6 \ + --hash=sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc + # via + # -r requirements.txt + # cffi +pygithub==2.6.1 \ + --hash=sha256:6f2fa6d076ccae475f9fc392cc6cdbd54db985d4f69b8833a28397de75ed6ca3 \ + --hash=sha256:b5c035392991cca63959e9453286b41b54d83bf2de2daa7d7ff7e4312cebf3bf + # via + # -r requirements.dev.in + # -r requirements.txt +pyjwt[crypto]==2.10.1 \ + --hash=sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953 \ + --hash=sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb + # via + # -r requirements.txt + # pygithub +pynacl==1.5.0 \ + --hash=sha256:06b8f6fa7f5de8d5d2f7573fe8c863c051225a27b61e6860fd047b1775807858 \ + --hash=sha256:0c84947a22519e013607c9be43706dd42513f9e6ae5d39d3613ca1e142fba44d \ + --hash=sha256:20f42270d27e1b6a29f54032090b972d97f0a1b0948cc52392041ef7831fee93 \ + --hash=sha256:401002a4aaa07c9414132aaed7f6836ff98f59277a234704ff66878c2ee4a0d1 \ + --hash=sha256:52cb72a79269189d4e0dc537556f4740f7f0a9ec41c1322598799b0bdad4ef92 \ + --hash=sha256:61f642bf2378713e2c2e1de73444a3778e5f0a38be6fee0fe532fe30060282ff \ + --hash=sha256:8ac7448f09ab85811607bdd21ec2464495ac8b7c66d146bf545b0f08fb9220ba \ + --hash=sha256:a36d4a9dda1f19ce6e03c9a784a2921a4b726b02e1c736600ca9c22029474394 \ + --hash=sha256:a422368fc821589c228f4c49438a368831cb5bbc0eab5ebe1d7fac9dded6567b \ + --hash=sha256:e46dae94e34b085175f8abb3b0aaa7da40767865ac82c928eeb9e57e1ea8a543 + # via + # -r requirements.txt + # pygithub pyyaml==6.0.2 \ --hash=sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff \ --hash=sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48 \ @@ -309,6 +466,7 @@ requests==2.32.3 \ # via # -r requirements.txt # docker + # pygithub rpds-py==0.22.3 \ --hash=sha256:009de23c9c9ee54bf11303a966edf4d9087cd43a6003672e6aa7def643d06518 \ --hash=sha256:02fbb9c288ae08bcb34fb41d516d5eeb0455ac35b5512d03181d755d80810059 \ @@ -417,25 +575,26 @@ rpds-py==0.22.3 \ # -r requirements.txt # jsonschema # referencing -ruff==0.11.13 \ - --hash=sha256:1808b3ed53e1a777c2ef733aca9051dc9bf7c99b26ece15cb59a0320fbdbd629 \ - --hash=sha256:26816a218ca6ef02142343fd24c70f7cd8c5aa6c203bca284407adf675984432 \ - --hash=sha256:26fa247dc68d1d4e72c179e08889a25ac0c7ba4d78aecfc835d49cbfd60bf514 \ - --hash=sha256:29c3189895a8a6a657b7af4e97d330c8a3afd2c9c8f46c81e2fc5a31866517e3 \ - --hash=sha256:4a9ddd3ec62a9a89578c85842b836e4ac832d4a2e0bfaad3b02243f930ceafcc \ - --hash=sha256:4bdfbf1240533f40042ec00c9e09a3aade6f8c10b6414cf11b519488d2635d46 \ - --hash=sha256:4ffbc82d70424b275b089166310448051afdc6e914fdab90e08df66c43bb5ca9 \ - --hash=sha256:51c3f95abd9331dc5b87c47ac7f376db5616041173826dfd556cfe3d4977f492 \ - --hash=sha256:53b15a9dfdce029c842e9a5aebc3855e9ab7771395979ff85b7c1dedb53ddc2b \ - --hash=sha256:55e4bc3a77842da33c16d55b32c6cac1ec5fb0fbec9c8c513bdce76c4f922165 \ - --hash=sha256:633bf2c6f35678c56ec73189ba6fa19ff1c5e4807a78bf60ef487b9dd272cc71 \ - --hash=sha256:6c51f93029d54a910d3d24f7dd0bb909e31b6cd989a5e4ac513f4eb41629f0dc \ - --hash=sha256:96c27935418e4e8e77a26bb05962817f28b8ef3843a6c6cc49d8783b5507f250 \ - --hash=sha256:ab153241400789138d13f362c43f7edecc0edfffce2afa6a68434000ecd8f69a \ - --hash=sha256:aef9c9ed1b5ca28bb15c7eac83b8670cf3b20b478195bd49c8d756ba0a36cf48 \ - --hash=sha256:b4385285e9179d608ff1d2fb9922062663c658605819a6876d8beef0c30b7f3b \ - --hash=sha256:d237a496e0778d719efb05058c64d28b757c77824e04ffe8796c7436e26712b7 \ - --hash=sha256:d28ce58b5ecf0f43c1b71edffabe6ed7f245d5336b17805803312ec9bc665933 +ruff==0.12.9 \ + --hash=sha256:07adb221c54b6bba24387911e5734357f042e5669fa5718920ee728aba3cbadc \ + --hash=sha256:17d5b6b0b3a25259b69ebcba87908496e6830e03acfb929ef9fd4c58675fa2ea \ + --hash=sha256:1b15599931a1a7a03c388b9c5df1bfa62be7ede6eb7ef753b272381f39c3d0ff \ + --hash=sha256:3d02faa2977fb6f3f32ddb7828e212b7dd499c59eb896ae6c03ea5c303575756 \ + --hash=sha256:43f07a3ccfc62cdb4d3a3348bf0588358a66da756aa113e071b8ca8c3b9826af \ + --hash=sha256:5b15ea354c6ff0d7423814ba6d44be2807644d0c05e9ed60caca87e963e93f70 \ + --hash=sha256:63c8c819739d86b96d500cce885956a1a48ab056bbcbc61b747ad494b2485089 \ + --hash=sha256:6fb15b1977309741d7d098c8a3cb7a30bc112760a00fb6efb7abc85f00ba5908 \ + --hash=sha256:72db7521860e246adbb43f6ef464dd2a532ef2ef1f5dd0d470455b8d9f1773e0 \ + --hash=sha256:881465ed56ba4dd26a691954650de6ad389a2d1fdb130fe51ff18a25639fe4bb \ + --hash=sha256:9fc83e4e9751e6c13b5046d7162f205d0a7bac5840183c5beebf824b08a27340 \ + --hash=sha256:a03242c1522b4e0885af63320ad754d53983c9599157ee33e77d748363c561ce \ + --hash=sha256:aed9d15f8c5755c0e74467731a007fcad41f19bcce41cd75f768bbd687f8535f \ + --hash=sha256:cc7a37bd2509974379d0115cc5608a1a4a6c4bff1b452ea69db83c8855d53f93 \ + --hash=sha256:d596c2d0393c2502eaabfef723bd74ca35348a8dac4267d18a94910087807c53 \ + --hash=sha256:f5cd34fabfdea3933ab85d72359f118035882a01bff15bd1d2b15261d85d5f66 \ + --hash=sha256:f6be1d2ca0686c54564da8e7ee9e25f93bdd6868263805f8c0b8fc6a449db6d7 \ + --hash=sha256:fbd94b2e3c623f659962934e52c2bea6fc6da11f667a427a368adaf3af2c866a \ + --hash=sha256:fcebc6c79fcae3f220d05585229463621f5dbf24d79fdc4936d9302e177cfa3e # via -r requirements.dev.in six==1.17.0 \ --hash=sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 \ @@ -481,29 +640,116 @@ types-jinja2==2.11.9 \ --hash=sha256:60a1e21e8296979db32f9374d8a239af4cb541ff66447bb915d8ad398f9c63b2 \ --hash=sha256:dbdc74a40aba7aed520b7e4d89e8f0fe4286518494208b35123bcf084d4b8c81 # via -r requirements.dev.in -types-jsonschema==4.24.0.20250528 \ - --hash=sha256:6a906b5ff73ac11c8d1e0b6c30a9693e1e4e1ab56c56c932b3a7e081b86d187b \ - --hash=sha256:7e28c64e0ae7980eeb158105b20663fc6a6b8f81d5f86ea6614aa0014417bd1e +types-jsonschema==4.25.0.20250809 \ + --hash=sha256:83c2a0ed5365c731a68d6e815e2063ea22ccf4547a74b1d5ed0ac234dd3de86e \ + --hash=sha256:dcd0fee69feb0f0763555c0307f0c5d58cc0c1a55984e66a04f4ef4ae1efb507 # via -r requirements.dev.in types-markupsafe==1.1.10 \ --hash=sha256:85b3a872683d02aea3a5ac2a8ef590193c344092032f58457287fbf8e06711b1 \ --hash=sha256:ca2bee0f4faafc45250602567ef38d533e877d2ddca13003b319c551ff5b3cc5 # via types-jinja2 -types-pyyaml==6.0.12.20250516 \ - --hash=sha256:8478208feaeb53a34cb5d970c56a7cd76b72659442e733e268a94dc72b2d0530 \ - --hash=sha256:9f21a70216fc0fa1b216a8176db5f9e0af6eb35d2f2932acb87689d03a5bf6ba +types-pyyaml==6.0.12.20250809 \ + --hash=sha256:032b6003b798e7de1a1ddfeefee32fac6486bdfe4845e0ae0e7fb3ee4512b52f \ + --hash=sha256:af4a1aca028f18e75297da2ee0da465f799627370d74073e96fee876524f61b5 # via -r requirements.dev.in -typing-extensions==4.9.0 \ - --hash=sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783 \ - --hash=sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd - # via mypy +typing-extensions==4.14.1 \ + --hash=sha256:38b39f4aeeab64884ce9f74c94263ef78f3c22467c8724005483154c26648d36 \ + --hash=sha256:d1e1e3b58374dc93031d6eda2420a48ea44a36c2b4766a4fdeb3710755731d76 + # via + # -r requirements.txt + # mypy + # pygithub urllib3==2.3.0 \ --hash=sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df \ --hash=sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d # via # -r requirements.txt # docker + # pygithub # requests +wrapt==1.17.2 \ + --hash=sha256:08e7ce672e35efa54c5024936e559469436f8b8096253404faeb54d2a878416f \ + --hash=sha256:0a6e821770cf99cc586d33833b2ff32faebdbe886bd6322395606cf55153246c \ + --hash=sha256:0b929ac182f5ace000d459c59c2c9c33047e20e935f8e39371fa6e3b85d56f4a \ + --hash=sha256:129a150f5c445165ff941fc02ee27df65940fcb8a22a61828b1853c98763a64b \ + --hash=sha256:13e6afb7fe71fe7485a4550a8844cc9ffbe263c0f1a1eea569bc7091d4898555 \ + --hash=sha256:1473400e5b2733e58b396a04eb7f35f541e1fb976d0c0724d0223dd607e0f74c \ + --hash=sha256:18983c537e04d11cf027fbb60a1e8dfd5190e2b60cc27bc0808e653e7b218d1b \ + --hash=sha256:1a7ed2d9d039bd41e889f6fb9364554052ca21ce823580f6a07c4ec245c1f5d6 \ + --hash=sha256:1e1fe0e6ab7775fd842bc39e86f6dcfc4507ab0ffe206093e76d61cde37225c8 \ + --hash=sha256:1fb5699e4464afe5c7e65fa51d4f99e0b2eadcc176e4aa33600a3df7801d6662 \ + --hash=sha256:2696993ee1eebd20b8e4ee4356483c4cb696066ddc24bd70bcbb80fa56ff9061 \ + --hash=sha256:35621ae4c00e056adb0009f8e86e28eb4a41a4bfa8f9bfa9fca7d343fe94f998 \ + --hash=sha256:36ccae62f64235cf8ddb682073a60519426fdd4725524ae38874adf72b5f2aeb \ + --hash=sha256:3cedbfa9c940fdad3e6e941db7138e26ce8aad38ab5fe9dcfadfed9db7a54e62 \ + --hash=sha256:3d57c572081fed831ad2d26fd430d565b76aa277ed1d30ff4d40670b1c0dd984 \ + --hash=sha256:3fc7cb4c1c744f8c05cd5f9438a3caa6ab94ce8344e952d7c45a8ed59dd88392 \ + --hash=sha256:4011d137b9955791f9084749cba9a367c68d50ab8d11d64c50ba1688c9b457f2 \ + --hash=sha256:40d615e4fe22f4ad3528448c193b218e077656ca9ccb22ce2cb20db730f8d306 \ + --hash=sha256:410a92fefd2e0e10d26210e1dfb4a876ddaf8439ef60d6434f21ef8d87efc5b7 \ + --hash=sha256:41388e9d4d1522446fe79d3213196bd9e3b301a336965b9e27ca2788ebd122f3 \ + --hash=sha256:468090021f391fe0056ad3e807e3d9034e0fd01adcd3bdfba977b6fdf4213ea9 \ + --hash=sha256:49703ce2ddc220df165bd2962f8e03b84c89fee2d65e1c24a7defff6f988f4d6 \ + --hash=sha256:4a721d3c943dae44f8e243b380cb645a709ba5bd35d3ad27bc2ed947e9c68192 \ + --hash=sha256:4afd5814270fdf6380616b321fd31435a462019d834f83c8611a0ce7484c7317 \ + --hash=sha256:4c82b8785d98cdd9fed4cac84d765d234ed3251bd6afe34cb7ac523cb93e8b4f \ + --hash=sha256:4db983e7bca53819efdbd64590ee96c9213894272c776966ca6306b73e4affda \ + --hash=sha256:582530701bff1dec6779efa00c516496968edd851fba224fbd86e46cc6b73563 \ + --hash=sha256:58455b79ec2661c3600e65c0a716955adc2410f7383755d537584b0de41b1d8a \ + --hash=sha256:58705da316756681ad3c9c73fd15499aa4d8c69f9fd38dc8a35e06c12468582f \ + --hash=sha256:5bb1d0dbf99411f3d871deb6faa9aabb9d4e744d67dcaaa05399af89d847a91d \ + --hash=sha256:5c803c401ea1c1c18de70a06a6f79fcc9c5acfc79133e9869e730ad7f8ad8ef9 \ + --hash=sha256:5cbabee4f083b6b4cd282f5b817a867cf0b1028c54d445b7ec7cfe6505057cf8 \ + --hash=sha256:612dff5db80beef9e649c6d803a8d50c409082f1fedc9dbcdfde2983b2025b82 \ + --hash=sha256:62c2caa1585c82b3f7a7ab56afef7b3602021d6da34fbc1cf234ff139fed3cd9 \ + --hash=sha256:69606d7bb691b50a4240ce6b22ebb319c1cfb164e5f6569835058196e0f3a845 \ + --hash=sha256:6d9187b01bebc3875bac9b087948a2bccefe464a7d8f627cf6e48b1bbae30f82 \ + --hash=sha256:6ed6ffac43aecfe6d86ec5b74b06a5be33d5bb9243d055141e8cabb12aa08125 \ + --hash=sha256:703919b1633412ab54bcf920ab388735832fdcb9f9a00ae49387f0fe67dad504 \ + --hash=sha256:766d8bbefcb9e00c3ac3b000d9acc51f1b399513f44d77dfe0eb026ad7c9a19b \ + --hash=sha256:80dd7db6a7cb57ffbc279c4394246414ec99537ae81ffd702443335a61dbf3a7 \ + --hash=sha256:8112e52c5822fc4253f3901b676c55ddf288614dc7011634e2719718eaa187dc \ + --hash=sha256:8c8b293cd65ad716d13d8dd3624e42e5a19cc2a2f1acc74b30c2c13f15cb61a6 \ + --hash=sha256:8fdbdb757d5390f7c675e558fd3186d590973244fab0c5fe63d373ade3e99d40 \ + --hash=sha256:91bd7d1773e64019f9288b7a5101f3ae50d3d8e6b1de7edee9c2ccc1d32f0c0a \ + --hash=sha256:95c658736ec15602da0ed73f312d410117723914a5c91a14ee4cdd72f1d790b3 \ + --hash=sha256:99039fa9e6306880572915728d7f6c24a86ec57b0a83f6b2491e1d8ab0235b9a \ + --hash=sha256:9a2bce789a5ea90e51a02dfcc39e31b7f1e662bc3317979aa7e5538e3a034f72 \ + --hash=sha256:9a7d15bbd2bc99e92e39f49a04653062ee6085c0e18b3b7512a4f2fe91f2d681 \ + --hash=sha256:9abc77a4ce4c6f2a3168ff34b1da9b0f311a8f1cfd694ec96b0603dff1c79438 \ + --hash=sha256:9e8659775f1adf02eb1e6f109751268e493c73716ca5761f8acb695e52a756ae \ + --hash=sha256:9fee687dce376205d9a494e9c121e27183b2a3df18037f89d69bd7b35bcf59e2 \ + --hash=sha256:a5aaeff38654462bc4b09023918b7f21790efb807f54c000a39d41d69cf552cb \ + --hash=sha256:a604bf7a053f8362d27eb9fefd2097f82600b856d5abe996d623babd067b1ab5 \ + --hash=sha256:abbb9e76177c35d4e8568e58650aa6926040d6a9f6f03435b7a522bf1c487f9a \ + --hash=sha256:acc130bc0375999da18e3d19e5a86403667ac0c4042a094fefb7eec8ebac7cf3 \ + --hash=sha256:b18f2d1533a71f069c7f82d524a52599053d4c7166e9dd374ae2136b7f40f7c8 \ + --hash=sha256:b4e42a40a5e164cbfdb7b386c966a588b1047558a990981ace551ed7e12ca9c2 \ + --hash=sha256:b5e251054542ae57ac7f3fba5d10bfff615b6c2fb09abeb37d2f1463f841ae22 \ + --hash=sha256:b60fb58b90c6d63779cb0c0c54eeb38941bae3ecf7a73c764c52c88c2dcb9d72 \ + --hash=sha256:b870b5df5b71d8c3359d21be8f0d6c485fa0ebdb6477dda51a1ea54a9b558061 \ + --hash=sha256:ba0f0eb61ef00ea10e00eb53a9129501f52385c44853dbd6c4ad3f403603083f \ + --hash=sha256:bb87745b2e6dc56361bfde481d5a378dc314b252a98d7dd19a651a3fa58f24a9 \ + --hash=sha256:bb90fb8bda722a1b9d48ac1e6c38f923ea757b3baf8ebd0c82e09c5c1a0e7a04 \ + --hash=sha256:bc570b5f14a79734437cb7b0500376b6b791153314986074486e0b0fa8d71d98 \ + --hash=sha256:c86563182421896d73858e08e1db93afdd2b947a70064b813d515d66549e15f9 \ + --hash=sha256:c958bcfd59bacc2d0249dcfe575e71da54f9dcf4a8bdf89c4cb9a68a1170d73f \ + --hash=sha256:d18a4865f46b8579d44e4fe1e2bcbc6472ad83d98e22a26c963d46e4c125ef0b \ + --hash=sha256:d5e2439eecc762cd85e7bd37161d4714aa03a33c5ba884e26c81559817ca0925 \ + --hash=sha256:e3890b508a23299083e065f435a492b5435eba6e304a7114d2f919d400888cc6 \ + --hash=sha256:e496a8ce2c256da1eb98bd15803a79bee00fc351f5dfb9ea82594a3f058309e0 \ + --hash=sha256:e8b2816ebef96d83657b56306152a93909a83f23994f4b30ad4573b00bd11bb9 \ + --hash=sha256:eaf675418ed6b3b31c7a989fd007fa7c3be66ce14e5c3b27336383604c9da85c \ + --hash=sha256:ec89ed91f2fa8e3f52ae53cd3cf640d6feff92ba90d62236a81e4e563ac0e991 \ + --hash=sha256:ecc840861360ba9d176d413a5489b9a0aff6d6303d7e733e2c4623cfa26904a6 \ + --hash=sha256:f09b286faeff3c750a879d336fb6d8713206fc97af3adc14def0cdd349df6000 \ + --hash=sha256:f393cda562f79828f38a819f4788641ac7c4085f30f1ce1a68672baa686482bb \ + --hash=sha256:f917c1180fdb8623c2b75a99192f4025e412597c50b2ac870f156de8fb101119 \ + --hash=sha256:fc78a84e2dfbc27afe4b2bd7c80c8db9bca75cc5b85df52bfe634596a1da846b \ + --hash=sha256:ff04ef6eec3eee8a5efef2401495967a916feaa353643defcc03fc74fe213b58 + # via + # -r requirements.txt + # deprecated zstandard==0.23.0 \ --hash=sha256:034b88913ecc1b097f528e42b539453fa82c3557e414b3de9d5632c80439a473 \ --hash=sha256:0a7f0804bb3799414af278e9ad51be25edf67f78f916e08afdb983e74161b916 \ diff --git a/requirements.in b/requirements.in index 0e9ae39..e9159b6 100644 --- a/requirements.in +++ b/requirements.in @@ -1,6 +1,9 @@ docker jinja2 jsonschema +# This does not built on the aarch64-windows runners yet, and is only needed for +# development so we'll just skip it for now. +PyGithub; sys_platform != "win32" or platform_machine != "aarch64" PyYAML # Undeclared dependency in docker 5.0 package. six diff --git a/requirements.txt b/requirements.txt index 2baa344..9ad29ed 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,6 +10,77 @@ certifi==2024.12.14 \ --hash=sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56 \ --hash=sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db # via requests +cffi==1.17.1 \ + --hash=sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8 \ + --hash=sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2 \ + --hash=sha256:0e2b1fac190ae3ebfe37b979cc1ce69c81f4e4fe5746bb401dca63a9062cdaf1 \ + --hash=sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15 \ + --hash=sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36 \ + --hash=sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824 \ + --hash=sha256:1d599671f396c4723d016dbddb72fe8e0397082b0a77a4fab8028923bec050e8 \ + --hash=sha256:28b16024becceed8c6dfbc75629e27788d8a3f9030691a1dbf9821a128b22c36 \ + --hash=sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17 \ + --hash=sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf \ + --hash=sha256:31000ec67d4221a71bd3f67df918b1f88f676f1c3b535a7eb473255fdc0b83fc \ + --hash=sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3 \ + --hash=sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed \ + --hash=sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702 \ + --hash=sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1 \ + --hash=sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8 \ + --hash=sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903 \ + --hash=sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6 \ + --hash=sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d \ + --hash=sha256:636062ea65bd0195bc012fea9321aca499c0504409f413dc88af450b57ffd03b \ + --hash=sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e \ + --hash=sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be \ + --hash=sha256:6f17be4345073b0a7b8ea599688f692ac3ef23ce28e5df79c04de519dbc4912c \ + --hash=sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683 \ + --hash=sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9 \ + --hash=sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c \ + --hash=sha256:7596d6620d3fa590f677e9ee430df2958d2d6d6de2feeae5b20e82c00b76fbf8 \ + --hash=sha256:78122be759c3f8a014ce010908ae03364d00a1f81ab5c7f4a7a5120607ea56e1 \ + --hash=sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4 \ + --hash=sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655 \ + --hash=sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67 \ + --hash=sha256:9755e4345d1ec879e3849e62222a18c7174d65a6a92d5b346b1863912168b595 \ + --hash=sha256:98e3969bcff97cae1b2def8ba499ea3d6f31ddfdb7635374834cf89a1a08ecf0 \ + --hash=sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65 \ + --hash=sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41 \ + --hash=sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6 \ + --hash=sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401 \ + --hash=sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6 \ + --hash=sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3 \ + --hash=sha256:b2ab587605f4ba0bf81dc0cb08a41bd1c0a5906bd59243d56bad7668a6fc6c16 \ + --hash=sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93 \ + --hash=sha256:c03e868a0b3bc35839ba98e74211ed2b05d2119be4e8a0f224fba9384f1fe02e \ + --hash=sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4 \ + --hash=sha256:c7eac2ef9b63c79431bc4b25f1cd649d7f061a28808cbc6c47b534bd789ef964 \ + --hash=sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c \ + --hash=sha256:ca74b8dbe6e8e8263c0ffd60277de77dcee6c837a3d0881d8c1ead7268c9e576 \ + --hash=sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0 \ + --hash=sha256:cdf5ce3acdfd1661132f2a9c19cac174758dc2352bfe37d98aa7512c6b7178b3 \ + --hash=sha256:d016c76bdd850f3c626af19b0542c9677ba156e4ee4fccfdd7848803533ef662 \ + --hash=sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3 \ + --hash=sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff \ + --hash=sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5 \ + --hash=sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd \ + --hash=sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f \ + --hash=sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5 \ + --hash=sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14 \ + --hash=sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d \ + --hash=sha256:e221cf152cff04059d011ee126477f0d9588303eb57e88923578ace7baad17f9 \ + --hash=sha256:e31ae45bc2e29f6b2abd0de1cc3b9d5205aa847cafaecb8af1476a609a2f6eb7 \ + --hash=sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382 \ + --hash=sha256:f1e22e8c4419538cb197e4dd60acc919d7696e5ef98ee4da4e01d3f8cfa4cc5a \ + --hash=sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e \ + --hash=sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a \ + --hash=sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4 \ + --hash=sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99 \ + --hash=sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87 \ + --hash=sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b + # via + # cryptography + # pynacl charset-normalizer==3.4.1 \ --hash=sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537 \ --hash=sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa \ @@ -104,6 +175,49 @@ charset-normalizer==3.4.1 \ --hash=sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00 \ --hash=sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616 # via requests +cryptography==45.0.5 \ + --hash=sha256:0027d566d65a38497bc37e0dd7c2f8ceda73597d2ac9ba93810204f56f52ebc7 \ + --hash=sha256:101ee65078f6dd3e5a028d4f19c07ffa4dd22cce6a20eaa160f8b5219911e7d8 \ + --hash=sha256:12e55281d993a793b0e883066f590c1ae1e802e3acb67f8b442e721e475e6463 \ + --hash=sha256:14d96584701a887763384f3c47f0ca7c1cce322aa1c31172680eb596b890ec30 \ + --hash=sha256:1e1da5accc0c750056c556a93c3e9cb828970206c68867712ca5805e46dc806f \ + --hash=sha256:206210d03c1193f4e1ff681d22885181d47efa1ab3018766a7b32a7b3d6e6afd \ + --hash=sha256:2089cc8f70a6e454601525e5bf2779e665d7865af002a5dec8d14e561002e135 \ + --hash=sha256:3a264aae5f7fbb089dbc01e0242d3b67dffe3e6292e1f5182122bdf58e65215d \ + --hash=sha256:3af26738f2db354aafe492fb3869e955b12b2ef2e16908c8b9cb928128d42c57 \ + --hash=sha256:3fcfbefc4a7f332dece7272a88e410f611e79458fab97b5efe14e54fe476f4fd \ + --hash=sha256:460f8c39ba66af7db0545a8c6f2eabcbc5a5528fc1cf6c3fa9a1e44cec33385e \ + --hash=sha256:57c816dfbd1659a367831baca4b775b2a5b43c003daf52e9d57e1d30bc2e1b0e \ + --hash=sha256:5aa1e32983d4443e310f726ee4b071ab7569f58eedfdd65e9675484a4eb67bd1 \ + --hash=sha256:6ff8728d8d890b3dda5765276d1bc6fb099252915a2cd3aff960c4c195745dd0 \ + --hash=sha256:7259038202a47fdecee7e62e0fd0b0738b6daa335354396c6ddebdbe1206af2a \ + --hash=sha256:72e76caa004ab63accdf26023fccd1d087f6d90ec6048ff33ad0445abf7f605a \ + --hash=sha256:7760c1c2e1a7084153a0f68fab76e754083b126a47d0117c9ed15e69e2103492 \ + --hash=sha256:8c4a6ff8a30e9e3d38ac0539e9a9e02540ab3f827a3394f8852432f6b0ea152e \ + --hash=sha256:9024beb59aca9d31d36fcdc1604dd9bbeed0a55bface9f1908df19178e2f116e \ + --hash=sha256:90cb0a7bb35959f37e23303b7eed0a32280510030daba3f7fdfbb65defde6a97 \ + --hash=sha256:91098f02ca81579c85f66df8a588c78f331ca19089763d733e34ad359f474174 \ + --hash=sha256:926c3ea71a6043921050eaa639137e13dbe7b4ab25800932a8498364fc1abec9 \ + --hash=sha256:982518cd64c54fcada9d7e5cf28eabd3ee76bd03ab18e08a48cad7e8b6f31b18 \ + --hash=sha256:9b4cf6318915dccfe218e69bbec417fdd7c7185aa7aab139a2c0beb7468c89f0 \ + --hash=sha256:ad0caded895a00261a5b4aa9af828baede54638754b51955a0ac75576b831b27 \ + --hash=sha256:b85980d1e345fe769cfc57c57db2b59cff5464ee0c045d52c0df087e926fbe63 \ + --hash=sha256:b8fa8b0a35a9982a3c60ec79905ba5bb090fc0b9addcfd3dc2dd04267e45f25e \ + --hash=sha256:b9e38e0a83cd51e07f5a48ff9691cae95a79bea28fe4ded168a8e5c6c77e819d \ + --hash=sha256:bd4c45986472694e5121084c6ebbd112aa919a25e783b87eb95953c9573906d6 \ + --hash=sha256:be97d3a19c16a9be00edf79dca949c8fa7eff621763666a145f9f9535a5d7f42 \ + --hash=sha256:c648025b6840fe62e57107e0a25f604db740e728bd67da4f6f060f03017d5097 \ + --hash=sha256:d05a38884db2ba215218745f0781775806bde4f32e07b135348355fe8e4991d9 \ + --hash=sha256:dd420e577921c8c2d31289536c386aaa30140b473835e97f83bc71ea9d2baf2d \ + --hash=sha256:e357286c1b76403dd384d938f93c46b2b058ed4dfcdce64a770f0537ed3feb6f \ + --hash=sha256:e6c00130ed423201c5bc5544c23359141660b07999ad82e34e7bb8f882bb78e0 \ + --hash=sha256:e74d30ec9c7cb2f404af331d5b4099a9b322a8a6b25c4632755c8757345baac5 \ + --hash=sha256:f3562c2f23c612f2e4a6964a61d942f891d29ee320edb62ff48ffb99f3de9ae8 + # via pyjwt +deprecated==1.2.18 \ + --hash=sha256:422b6f6d859da6f2ef57857761bfb392480502a64c3028ca9bbe86085d72115d \ + --hash=sha256:bd5011788200372a32418f888e326a09ff80d0214bd961147cfed01b5c018eec + # via pygithub docker==7.1.0 \ --hash=sha256:ad8c70e6e3f8926cb8a92619b832b4ea5299e2831c14284663184e200546fa6c \ --hash=sha256:c96b93b7f0a746f9e77d325bcfb87422a3d8bd4f03136ae8a85b37f1898d5fc0 @@ -187,6 +301,30 @@ markupsafe==3.0.2 \ --hash=sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430 \ --hash=sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50 # via jinja2 +pycparser==2.22 \ + --hash=sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6 \ + --hash=sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc + # via cffi +pygithub==2.6.1 \ + --hash=sha256:6f2fa6d076ccae475f9fc392cc6cdbd54db985d4f69b8833a28397de75ed6ca3 \ + --hash=sha256:b5c035392991cca63959e9453286b41b54d83bf2de2daa7d7ff7e4312cebf3bf + # via -r requirements.in +pyjwt==2.10.1 \ + --hash=sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953 \ + --hash=sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb + # via pygithub +pynacl==1.5.0 \ + --hash=sha256:06b8f6fa7f5de8d5d2f7573fe8c863c051225a27b61e6860fd047b1775807858 \ + --hash=sha256:0c84947a22519e013607c9be43706dd42513f9e6ae5d39d3613ca1e142fba44d \ + --hash=sha256:20f42270d27e1b6a29f54032090b972d97f0a1b0948cc52392041ef7831fee93 \ + --hash=sha256:401002a4aaa07c9414132aaed7f6836ff98f59277a234704ff66878c2ee4a0d1 \ + --hash=sha256:52cb72a79269189d4e0dc537556f4740f7f0a9ec41c1322598799b0bdad4ef92 \ + --hash=sha256:61f642bf2378713e2c2e1de73444a3778e5f0a38be6fee0fe532fe30060282ff \ + --hash=sha256:8ac7448f09ab85811607bdd21ec2464495ac8b7c66d146bf545b0f08fb9220ba \ + --hash=sha256:a36d4a9dda1f19ce6e03c9a784a2921a4b726b02e1c736600ca9c22029474394 \ + --hash=sha256:a422368fc821589c228f4c49438a368831cb5bbc0eab5ebe1d7fac9dded6567b \ + --hash=sha256:e46dae94e34b085175f8abb3b0aaa7da40767865ac82c928eeb9e57e1ea8a543 + # via pygithub pyyaml==6.0.2 \ --hash=sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff \ --hash=sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48 \ @@ -251,7 +389,9 @@ referencing==0.35.1 \ requests==2.32.3 \ --hash=sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760 \ --hash=sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6 - # via docker + # via + # docker + # pygithub rpds-py==0.22.3 \ --hash=sha256:009de23c9c9ee54bf11303a966edf4d9087cd43a6003672e6aa7def643d06518 \ --hash=sha256:02fbb9c288ae08bcb34fb41d516d5eeb0455ac35b5512d03181d755d80810059 \ @@ -397,12 +537,100 @@ tomli==2.2.1 \ --hash=sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a \ --hash=sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7 # via -r requirements.in +typing-extensions==4.14.1 \ + --hash=sha256:38b39f4aeeab64884ce9f74c94263ef78f3c22467c8724005483154c26648d36 \ + --hash=sha256:d1e1e3b58374dc93031d6eda2420a48ea44a36c2b4766a4fdeb3710755731d76 + # via + # -r requirements.in + # pygithub urllib3==2.3.0 \ --hash=sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df \ --hash=sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d # via # docker + # pygithub # requests +wrapt==1.17.2 \ + --hash=sha256:08e7ce672e35efa54c5024936e559469436f8b8096253404faeb54d2a878416f \ + --hash=sha256:0a6e821770cf99cc586d33833b2ff32faebdbe886bd6322395606cf55153246c \ + --hash=sha256:0b929ac182f5ace000d459c59c2c9c33047e20e935f8e39371fa6e3b85d56f4a \ + --hash=sha256:129a150f5c445165ff941fc02ee27df65940fcb8a22a61828b1853c98763a64b \ + --hash=sha256:13e6afb7fe71fe7485a4550a8844cc9ffbe263c0f1a1eea569bc7091d4898555 \ + --hash=sha256:1473400e5b2733e58b396a04eb7f35f541e1fb976d0c0724d0223dd607e0f74c \ + --hash=sha256:18983c537e04d11cf027fbb60a1e8dfd5190e2b60cc27bc0808e653e7b218d1b \ + --hash=sha256:1a7ed2d9d039bd41e889f6fb9364554052ca21ce823580f6a07c4ec245c1f5d6 \ + --hash=sha256:1e1fe0e6ab7775fd842bc39e86f6dcfc4507ab0ffe206093e76d61cde37225c8 \ + --hash=sha256:1fb5699e4464afe5c7e65fa51d4f99e0b2eadcc176e4aa33600a3df7801d6662 \ + --hash=sha256:2696993ee1eebd20b8e4ee4356483c4cb696066ddc24bd70bcbb80fa56ff9061 \ + --hash=sha256:35621ae4c00e056adb0009f8e86e28eb4a41a4bfa8f9bfa9fca7d343fe94f998 \ + --hash=sha256:36ccae62f64235cf8ddb682073a60519426fdd4725524ae38874adf72b5f2aeb \ + --hash=sha256:3cedbfa9c940fdad3e6e941db7138e26ce8aad38ab5fe9dcfadfed9db7a54e62 \ + --hash=sha256:3d57c572081fed831ad2d26fd430d565b76aa277ed1d30ff4d40670b1c0dd984 \ + --hash=sha256:3fc7cb4c1c744f8c05cd5f9438a3caa6ab94ce8344e952d7c45a8ed59dd88392 \ + --hash=sha256:4011d137b9955791f9084749cba9a367c68d50ab8d11d64c50ba1688c9b457f2 \ + --hash=sha256:40d615e4fe22f4ad3528448c193b218e077656ca9ccb22ce2cb20db730f8d306 \ + --hash=sha256:410a92fefd2e0e10d26210e1dfb4a876ddaf8439ef60d6434f21ef8d87efc5b7 \ + --hash=sha256:41388e9d4d1522446fe79d3213196bd9e3b301a336965b9e27ca2788ebd122f3 \ + --hash=sha256:468090021f391fe0056ad3e807e3d9034e0fd01adcd3bdfba977b6fdf4213ea9 \ + --hash=sha256:49703ce2ddc220df165bd2962f8e03b84c89fee2d65e1c24a7defff6f988f4d6 \ + --hash=sha256:4a721d3c943dae44f8e243b380cb645a709ba5bd35d3ad27bc2ed947e9c68192 \ + --hash=sha256:4afd5814270fdf6380616b321fd31435a462019d834f83c8611a0ce7484c7317 \ + --hash=sha256:4c82b8785d98cdd9fed4cac84d765d234ed3251bd6afe34cb7ac523cb93e8b4f \ + --hash=sha256:4db983e7bca53819efdbd64590ee96c9213894272c776966ca6306b73e4affda \ + --hash=sha256:582530701bff1dec6779efa00c516496968edd851fba224fbd86e46cc6b73563 \ + --hash=sha256:58455b79ec2661c3600e65c0a716955adc2410f7383755d537584b0de41b1d8a \ + --hash=sha256:58705da316756681ad3c9c73fd15499aa4d8c69f9fd38dc8a35e06c12468582f \ + --hash=sha256:5bb1d0dbf99411f3d871deb6faa9aabb9d4e744d67dcaaa05399af89d847a91d \ + --hash=sha256:5c803c401ea1c1c18de70a06a6f79fcc9c5acfc79133e9869e730ad7f8ad8ef9 \ + --hash=sha256:5cbabee4f083b6b4cd282f5b817a867cf0b1028c54d445b7ec7cfe6505057cf8 \ + --hash=sha256:612dff5db80beef9e649c6d803a8d50c409082f1fedc9dbcdfde2983b2025b82 \ + --hash=sha256:62c2caa1585c82b3f7a7ab56afef7b3602021d6da34fbc1cf234ff139fed3cd9 \ + --hash=sha256:69606d7bb691b50a4240ce6b22ebb319c1cfb164e5f6569835058196e0f3a845 \ + --hash=sha256:6d9187b01bebc3875bac9b087948a2bccefe464a7d8f627cf6e48b1bbae30f82 \ + --hash=sha256:6ed6ffac43aecfe6d86ec5b74b06a5be33d5bb9243d055141e8cabb12aa08125 \ + --hash=sha256:703919b1633412ab54bcf920ab388735832fdcb9f9a00ae49387f0fe67dad504 \ + --hash=sha256:766d8bbefcb9e00c3ac3b000d9acc51f1b399513f44d77dfe0eb026ad7c9a19b \ + --hash=sha256:80dd7db6a7cb57ffbc279c4394246414ec99537ae81ffd702443335a61dbf3a7 \ + --hash=sha256:8112e52c5822fc4253f3901b676c55ddf288614dc7011634e2719718eaa187dc \ + --hash=sha256:8c8b293cd65ad716d13d8dd3624e42e5a19cc2a2f1acc74b30c2c13f15cb61a6 \ + --hash=sha256:8fdbdb757d5390f7c675e558fd3186d590973244fab0c5fe63d373ade3e99d40 \ + --hash=sha256:91bd7d1773e64019f9288b7a5101f3ae50d3d8e6b1de7edee9c2ccc1d32f0c0a \ + --hash=sha256:95c658736ec15602da0ed73f312d410117723914a5c91a14ee4cdd72f1d790b3 \ + --hash=sha256:99039fa9e6306880572915728d7f6c24a86ec57b0a83f6b2491e1d8ab0235b9a \ + --hash=sha256:9a2bce789a5ea90e51a02dfcc39e31b7f1e662bc3317979aa7e5538e3a034f72 \ + --hash=sha256:9a7d15bbd2bc99e92e39f49a04653062ee6085c0e18b3b7512a4f2fe91f2d681 \ + --hash=sha256:9abc77a4ce4c6f2a3168ff34b1da9b0f311a8f1cfd694ec96b0603dff1c79438 \ + --hash=sha256:9e8659775f1adf02eb1e6f109751268e493c73716ca5761f8acb695e52a756ae \ + --hash=sha256:9fee687dce376205d9a494e9c121e27183b2a3df18037f89d69bd7b35bcf59e2 \ + --hash=sha256:a5aaeff38654462bc4b09023918b7f21790efb807f54c000a39d41d69cf552cb \ + --hash=sha256:a604bf7a053f8362d27eb9fefd2097f82600b856d5abe996d623babd067b1ab5 \ + --hash=sha256:abbb9e76177c35d4e8568e58650aa6926040d6a9f6f03435b7a522bf1c487f9a \ + --hash=sha256:acc130bc0375999da18e3d19e5a86403667ac0c4042a094fefb7eec8ebac7cf3 \ + --hash=sha256:b18f2d1533a71f069c7f82d524a52599053d4c7166e9dd374ae2136b7f40f7c8 \ + --hash=sha256:b4e42a40a5e164cbfdb7b386c966a588b1047558a990981ace551ed7e12ca9c2 \ + --hash=sha256:b5e251054542ae57ac7f3fba5d10bfff615b6c2fb09abeb37d2f1463f841ae22 \ + --hash=sha256:b60fb58b90c6d63779cb0c0c54eeb38941bae3ecf7a73c764c52c88c2dcb9d72 \ + --hash=sha256:b870b5df5b71d8c3359d21be8f0d6c485fa0ebdb6477dda51a1ea54a9b558061 \ + --hash=sha256:ba0f0eb61ef00ea10e00eb53a9129501f52385c44853dbd6c4ad3f403603083f \ + --hash=sha256:bb87745b2e6dc56361bfde481d5a378dc314b252a98d7dd19a651a3fa58f24a9 \ + --hash=sha256:bb90fb8bda722a1b9d48ac1e6c38f923ea757b3baf8ebd0c82e09c5c1a0e7a04 \ + --hash=sha256:bc570b5f14a79734437cb7b0500376b6b791153314986074486e0b0fa8d71d98 \ + --hash=sha256:c86563182421896d73858e08e1db93afdd2b947a70064b813d515d66549e15f9 \ + --hash=sha256:c958bcfd59bacc2d0249dcfe575e71da54f9dcf4a8bdf89c4cb9a68a1170d73f \ + --hash=sha256:d18a4865f46b8579d44e4fe1e2bcbc6472ad83d98e22a26c963d46e4c125ef0b \ + --hash=sha256:d5e2439eecc762cd85e7bd37161d4714aa03a33c5ba884e26c81559817ca0925 \ + --hash=sha256:e3890b508a23299083e065f435a492b5435eba6e304a7114d2f919d400888cc6 \ + --hash=sha256:e496a8ce2c256da1eb98bd15803a79bee00fc351f5dfb9ea82594a3f058309e0 \ + --hash=sha256:e8b2816ebef96d83657b56306152a93909a83f23994f4b30ad4573b00bd11bb9 \ + --hash=sha256:eaf675418ed6b3b31c7a989fd007fa7c3be66ce14e5c3b27336383604c9da85c \ + --hash=sha256:ec89ed91f2fa8e3f52ae53cd3cf640d6feff92ba90d62236a81e4e563ac0e991 \ + --hash=sha256:ecc840861360ba9d176d413a5489b9a0aff6d6303d7e733e2c4623cfa26904a6 \ + --hash=sha256:f09b286faeff3c750a879d336fb6d8713206fc97af3adc14def0cdd349df6000 \ + --hash=sha256:f393cda562f79828f38a819f4788641ac7c4085f30f1ce1a68672baa686482bb \ + --hash=sha256:f917c1180fdb8623c2b75a99192f4025e412597c50b2ac870f156de8fb101119 \ + --hash=sha256:fc78a84e2dfbc27afe4b2bd7c80c8db9bca75cc5b85df52bfe634596a1da846b \ + --hash=sha256:ff04ef6eec3eee8a5efef2401495967a916feaa353643defcc03fc74fe213b58 + # via deprecated zstandard==0.23.0 \ --hash=sha256:034b88913ecc1b097f528e42b539453fa82c3557e414b3de9d5632c80439a473 \ --hash=sha256:0a7f0804bb3799414af278e9ad51be25edf67f78f916e08afdb983e74161b916 \ diff --git a/requirements.win-arm64.txt b/requirements.win-arm64.txt new file mode 100644 index 0000000..3a41726 --- /dev/null +++ b/requirements.win-arm64.txt @@ -0,0 +1,571 @@ +# This file was autogenerated by uv via the following command: +# uv pip compile --python-platform aarch64-pc-windows-msvc --generate-hashes requirements.in -o requirements.win-arm64.txt +attrs==25.3.0 \ + --hash=sha256:427318ce031701fea540783410126f03899a97ffc6f61596ad581ac2e40e3bc3 \ + --hash=sha256:75d7cefc7fb576747b2c81b4442d4d4a1ce0900973527c011d1030fd3bf4af1b + # via + # jsonschema + # referencing +certifi==2025.8.3 \ + --hash=sha256:e564105f78ded564e3ae7c923924435e1daa7463faeab5bb932bc53ffae63407 \ + --hash=sha256:f6c12493cfb1b06ba2ff328595af9350c65d6644968e5d3a2ffd78699af217a5 + # via requests +charset-normalizer==3.4.3 \ + --hash=sha256:00237675befef519d9af72169d8604a067d92755e84fe76492fef5441db05b91 \ + --hash=sha256:02425242e96bcf29a49711b0ca9f37e451da7c70562bc10e8ed992a5a7a25cc0 \ + --hash=sha256:027b776c26d38b7f15b26a5da1044f376455fb3766df8fc38563b4efbc515154 \ + --hash=sha256:07a0eae9e2787b586e129fdcbe1af6997f8d0e5abaa0bc98c0e20e124d67e601 \ + --hash=sha256:0cacf8f7297b0c4fcb74227692ca46b4a5852f8f4f24b3c766dd94a1075c4884 \ + --hash=sha256:0e78314bdc32fa80696f72fa16dc61168fda4d6a0c014e0380f9d02f0e5d8a07 \ + --hash=sha256:0f2be7e0cf7754b9a30eb01f4295cc3d4358a479843b31f328afd210e2c7598c \ + --hash=sha256:13faeacfe61784e2559e690fc53fa4c5ae97c6fcedb8eb6fb8d0a15b475d2c64 \ + --hash=sha256:14c2a87c65b351109f6abfc424cab3927b3bdece6f706e4d12faaf3d52ee5efe \ + --hash=sha256:1606f4a55c0fd363d754049cdf400175ee96c992b1f8018b993941f221221c5f \ + --hash=sha256:16a8770207946ac75703458e2c743631c79c59c5890c80011d536248f8eaa432 \ + --hash=sha256:18343b2d246dc6761a249ba1fb13f9ee9a2bcd95decc767319506056ea4ad4dc \ + --hash=sha256:18b97b8404387b96cdbd30ad660f6407799126d26a39ca65729162fd810a99aa \ + --hash=sha256:1bb60174149316da1c35fa5233681f7c0f9f514509b8e399ab70fea5f17e45c9 \ + --hash=sha256:1e8ac75d72fa3775e0b7cb7e4629cec13b7514d928d15ef8ea06bca03ef01cae \ + --hash=sha256:1ef99f0456d3d46a50945c98de1774da86f8e992ab5c77865ea8b8195341fc19 \ + --hash=sha256:2001a39612b241dae17b4687898843f254f8748b796a2e16f1051a17078d991d \ + --hash=sha256:23b6b24d74478dc833444cbd927c338349d6ae852ba53a0d02a2de1fce45b96e \ + --hash=sha256:252098c8c7a873e17dd696ed98bbe91dbacd571da4b87df3736768efa7a792e4 \ + --hash=sha256:257f26fed7d7ff59921b78244f3cd93ed2af1800ff048c33f624c87475819dd7 \ + --hash=sha256:2c322db9c8c89009a990ef07c3bcc9f011a3269bc06782f916cd3d9eed7c9312 \ + --hash=sha256:30a96e1e1f865f78b030d65241c1ee850cdf422d869e9028e2fc1d5e4db73b92 \ + --hash=sha256:30d006f98569de3459c2fc1f2acde170b7b2bd265dc1943e87e1a4efe1b67c31 \ + --hash=sha256:31a9a6f775f9bcd865d88ee350f0ffb0e25936a7f930ca98995c05abf1faf21c \ + --hash=sha256:320e8e66157cc4e247d9ddca8e21f427efc7a04bbd0ac8a9faf56583fa543f9f \ + --hash=sha256:34a7f768e3f985abdb42841e20e17b330ad3aaf4bb7e7aeeb73db2e70f077b99 \ + --hash=sha256:3653fad4fe3ed447a596ae8638b437f827234f01a8cd801842e43f3d0a6b281b \ + --hash=sha256:3cd35b7e8aedeb9e34c41385fda4f73ba609e561faedfae0a9e75e44ac558a15 \ + --hash=sha256:3cfb2aad70f2c6debfbcb717f23b7eb55febc0bb23dcffc0f076009da10c6392 \ + --hash=sha256:416175faf02e4b0810f1f38bcb54682878a4af94059a1cd63b8747244420801f \ + --hash=sha256:41d1fc408ff5fdfb910200ec0e74abc40387bccb3252f3f27c0676731df2b2c8 \ + --hash=sha256:42e5088973e56e31e4fa58eb6bd709e42fc03799c11c42929592889a2e54c491 \ + --hash=sha256:4ca4c094de7771a98d7fbd67d9e5dbf1eb73efa4f744a730437d8a3a5cf994f0 \ + --hash=sha256:511729f456829ef86ac41ca78c63a5cb55240ed23b4b737faca0eb1abb1c41bc \ + --hash=sha256:53cd68b185d98dde4ad8990e56a58dea83a4162161b1ea9272e5c9182ce415e0 \ + --hash=sha256:585f3b2a80fbd26b048a0be90c5aae8f06605d3c92615911c3a2b03a8a3b796f \ + --hash=sha256:5b413b0b1bfd94dbf4023ad6945889f374cd24e3f62de58d6bb102c4d9ae534a \ + --hash=sha256:5d8d01eac18c423815ed4f4a2ec3b439d654e55ee4ad610e153cf02faf67ea40 \ + --hash=sha256:6aab0f181c486f973bc7262a97f5aca3ee7e1437011ef0c2ec04b5a11d16c927 \ + --hash=sha256:6cf8fd4c04756b6b60146d98cd8a77d0cdae0e1ca20329da2ac85eed779b6849 \ + --hash=sha256:6fb70de56f1859a3f71261cbe41005f56a7842cc348d3aeb26237560bfa5e0ce \ + --hash=sha256:6fce4b8500244f6fcb71465d4a4930d132ba9ab8e71a7859e6a5d59851068d14 \ + --hash=sha256:70bfc5f2c318afece2f5838ea5e4c3febada0be750fcf4775641052bbba14d05 \ + --hash=sha256:73dc19b562516fc9bcf6e5d6e596df0b4eb98d87e4f79f3ae71840e6ed21361c \ + --hash=sha256:74d77e25adda8581ffc1c720f1c81ca082921329452eba58b16233ab1842141c \ + --hash=sha256:78deba4d8f9590fe4dae384aeff04082510a709957e968753ff3c48399f6f92a \ + --hash=sha256:86df271bf921c2ee3818f0522e9a5b8092ca2ad8b065ece5d7d9d0e9f4849bcc \ + --hash=sha256:88ab34806dea0671532d3f82d82b85e8fc23d7b2dd12fa837978dad9bb392a34 \ + --hash=sha256:8999f965f922ae054125286faf9f11bc6932184b93011d138925a1773830bbe9 \ + --hash=sha256:8dcfc373f888e4fb39a7bc57e93e3b845e7f462dacc008d9749568b1c4ece096 \ + --hash=sha256:939578d9d8fd4299220161fdd76e86c6a251987476f5243e8864a7844476ba14 \ + --hash=sha256:96b2b3d1a83ad55310de8c7b4a2d04d9277d5591f40761274856635acc5fcb30 \ + --hash=sha256:a2d08ac246bb48479170408d6c19f6385fa743e7157d716e144cad849b2dd94b \ + --hash=sha256:b256ee2e749283ef3ddcff51a675ff43798d92d746d1a6e4631bf8c707d22d0b \ + --hash=sha256:b5e3b2d152e74e100a9e9573837aba24aab611d39428ded46f4e4022ea7d1942 \ + --hash=sha256:b89bc04de1d83006373429975f8ef9e7932534b8cc9ca582e4db7d20d91816db \ + --hash=sha256:bd28b817ea8c70215401f657edef3a8aa83c29d447fb0b622c35403780ba11d5 \ + --hash=sha256:c60e092517a73c632ec38e290eba714e9627abe9d301c8c8a12ec32c314a2a4b \ + --hash=sha256:c6dbd0ccdda3a2ba7c2ecd9d77b37f3b5831687d8dc1b6ca5f56a4880cc7b7ce \ + --hash=sha256:c6e490913a46fa054e03699c70019ab869e990270597018cef1d8562132c2669 \ + --hash=sha256:c6f162aabe9a91a309510d74eeb6507fab5fff92337a15acbe77753d88d9dcf0 \ + --hash=sha256:c6fd51128a41297f5409deab284fecbe5305ebd7e5a1f959bee1c054622b7018 \ + --hash=sha256:cc34f233c9e71701040d772aa7490318673aa7164a0efe3172b2981218c26d93 \ + --hash=sha256:cc9370a2da1ac13f0153780040f465839e6cccb4a1e44810124b4e22483c93fe \ + --hash=sha256:ccf600859c183d70eb47e05a44cd80a4ce77394d1ac0f79dbd2dd90a69a3a049 \ + --hash=sha256:ce571ab16d890d23b5c278547ba694193a45011ff86a9162a71307ed9f86759a \ + --hash=sha256:cf1ebb7d78e1ad8ec2a8c4732c7be2e736f6e5123a4146c5b89c9d1f585f8cef \ + --hash=sha256:d0e909868420b7049dafd3a31d45125b31143eec59235311fc4c57ea26a4acd2 \ + --hash=sha256:d22dbedd33326a4a5190dd4fe9e9e693ef12160c77382d9e87919bce54f3d4ca \ + --hash=sha256:d716a916938e03231e86e43782ca7878fb602a125a91e7acb8b5112e2e96ac16 \ + --hash=sha256:d79c198e27580c8e958906f803e63cddb77653731be08851c7df0b1a14a8fc0f \ + --hash=sha256:d95bfb53c211b57198bb91c46dd5a2d8018b3af446583aab40074bf7988401cb \ + --hash=sha256:e28e334d3ff134e88989d90ba04b47d84382a828c061d0d1027b1b12a62b39b1 \ + --hash=sha256:ec557499516fc90fd374bf2e32349a2887a876fbf162c160e3c01b6849eaf557 \ + --hash=sha256:fb6fecfd65564f208cbf0fba07f107fb661bcd1a7c389edbced3f7a493f70e37 \ + --hash=sha256:fb731e5deb0c7ef82d698b0f4c5bb724633ee2a489401594c5c88b02e6cb15f7 \ + --hash=sha256:fb7f67a1bfa6e40b438170ebdc8158b78dc465a5a67b6dde178a46987b244a72 \ + --hash=sha256:fd10de089bcdcd1be95a2f73dbe6254798ec1bda9f450d5828c96f93e2536b9c \ + --hash=sha256:fdabf8315679312cfa71302f9bd509ded4f2f263fb5b765cf1433b39106c3cc9 + # via requests +docker==7.1.0 \ + --hash=sha256:ad8c70e6e3f8926cb8a92619b832b4ea5299e2831c14284663184e200546fa6c \ + --hash=sha256:c96b93b7f0a746f9e77d325bcfb87422a3d8bd4f03136ae8a85b37f1898d5fc0 + # via -r requirements.in +idna==3.10 \ + --hash=sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9 \ + --hash=sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3 + # via requests +jinja2==3.1.6 \ + --hash=sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d \ + --hash=sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67 + # via -r requirements.in +jsonschema==4.25.1 \ + --hash=sha256:3fba0169e345c7175110351d456342c364814cfcf3b964ba4587f22915230a63 \ + --hash=sha256:e4a9655ce0da0c0b67a085847e00a3a51449e1157f4f75e9fb5aa545e122eb85 + # via -r requirements.in +jsonschema-specifications==2025.4.1 \ + --hash=sha256:4653bffbd6584f7de83a67e0d620ef16900b390ddc7939d56684d6c81e33f1af \ + --hash=sha256:630159c9f4dbea161a6a2205c3011cc4f18ff381b189fff48bb39b9bf26ae608 + # via jsonschema +markupsafe==3.0.2 \ + --hash=sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4 \ + --hash=sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30 \ + --hash=sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0 \ + --hash=sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9 \ + --hash=sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396 \ + --hash=sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13 \ + --hash=sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028 \ + --hash=sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca \ + --hash=sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557 \ + --hash=sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832 \ + --hash=sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0 \ + --hash=sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b \ + --hash=sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579 \ + --hash=sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a \ + --hash=sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c \ + --hash=sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff \ + --hash=sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c \ + --hash=sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22 \ + --hash=sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094 \ + --hash=sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb \ + --hash=sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e \ + --hash=sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5 \ + --hash=sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a \ + --hash=sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d \ + --hash=sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a \ + --hash=sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b \ + --hash=sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8 \ + --hash=sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225 \ + --hash=sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c \ + --hash=sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144 \ + --hash=sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f \ + --hash=sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87 \ + --hash=sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d \ + --hash=sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93 \ + --hash=sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf \ + --hash=sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158 \ + --hash=sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84 \ + --hash=sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb \ + --hash=sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48 \ + --hash=sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171 \ + --hash=sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c \ + --hash=sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6 \ + --hash=sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd \ + --hash=sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d \ + --hash=sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1 \ + --hash=sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d \ + --hash=sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca \ + --hash=sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a \ + --hash=sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29 \ + --hash=sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe \ + --hash=sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798 \ + --hash=sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c \ + --hash=sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8 \ + --hash=sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f \ + --hash=sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f \ + --hash=sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a \ + --hash=sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178 \ + --hash=sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0 \ + --hash=sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79 \ + --hash=sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430 \ + --hash=sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50 + # via jinja2 +pywin32==311 \ + --hash=sha256:0502d1facf1fed4839a9a51ccbcc63d952cf318f78ffc00a7e78528ac27d7a2b \ + --hash=sha256:184eb5e436dea364dcd3d2316d577d625c0351bf237c4e9a5fabbcfa5a58b151 \ + --hash=sha256:3aca44c046bd2ed8c90de9cb8427f581c479e594e99b5c0bb19b29c10fd6cb87 \ + --hash=sha256:3ce80b34b22b17ccbd937a6e78e7225d80c52f5ab9940fe0506a1a16f3dab503 \ + --hash=sha256:62ea666235135fee79bb154e695f3ff67370afefd71bd7fea7512fc70ef31e3d \ + --hash=sha256:6c6f2969607b5023b0d9ce2541f8d2cbb01c4f46bc87456017cf63b73f1e2d8c \ + --hash=sha256:718a38f7e5b058e76aee1c56ddd06908116d35147e133427e59a3983f703a20d \ + --hash=sha256:750ec6e621af2b948540032557b10a2d43b0cee2ae9758c54154d711cc852d31 \ + --hash=sha256:797c2772017851984b97180b0bebe4b620bb86328e8a884bb626156295a63b3b \ + --hash=sha256:7b4075d959648406202d92a2310cb990fea19b535c7f4a78d3f5e10b926eeb8a \ + --hash=sha256:a508e2d9025764a8270f93111a970e1d0fbfc33f4153b388bb649b7eec4f9b42 \ + --hash=sha256:a733f1388e1a842abb67ffa8e7aad0e70ac519e09b0f6a784e65a136ec7cefd2 \ + --hash=sha256:aba8f82d551a942cb20d4a83413ccbac30790b50efb89a75e4f586ac0bb8056b \ + --hash=sha256:b7a2c10b93f8986666d0c803ee19b5990885872a7de910fc460f9b0c2fbf92ee \ + --hash=sha256:b8c095edad5c211ff31c05223658e71bf7116daa0ecf3ad85f3201ea3190d067 \ + --hash=sha256:c8015b09fb9a5e188f83b7b04de91ddca4658cee2ae6f3bc483f0b21a77ef6cd \ + --hash=sha256:d03ff496d2a0cd4a5893504789d4a15399133fe82517455e78bad62efbb7f0a3 \ + --hash=sha256:e0c4cfb0621281fe40387df582097fd796e80430597cb9944f0ae70447bacd91 \ + --hash=sha256:e286f46a9a39c4a18b319c28f59b61de793654af2f395c102b4f819e584b5852 \ + --hash=sha256:f95ba5a847cba10dd8c4d8fefa9f2a6cf283b8b88ed6178fa8a6c1ab16054d0d + # via docker +pyyaml==6.0.2 \ + --hash=sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff \ + --hash=sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48 \ + --hash=sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086 \ + --hash=sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e \ + --hash=sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133 \ + --hash=sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5 \ + --hash=sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484 \ + --hash=sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee \ + --hash=sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5 \ + --hash=sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68 \ + --hash=sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a \ + --hash=sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf \ + --hash=sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99 \ + --hash=sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8 \ + --hash=sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85 \ + --hash=sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19 \ + --hash=sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc \ + --hash=sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a \ + --hash=sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1 \ + --hash=sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317 \ + --hash=sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c \ + --hash=sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631 \ + --hash=sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d \ + --hash=sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652 \ + --hash=sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5 \ + --hash=sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e \ + --hash=sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b \ + --hash=sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8 \ + --hash=sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476 \ + --hash=sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706 \ + --hash=sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563 \ + --hash=sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237 \ + --hash=sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b \ + --hash=sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083 \ + --hash=sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180 \ + --hash=sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425 \ + --hash=sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e \ + --hash=sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f \ + --hash=sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725 \ + --hash=sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183 \ + --hash=sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab \ + --hash=sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774 \ + --hash=sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725 \ + --hash=sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e \ + --hash=sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5 \ + --hash=sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d \ + --hash=sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290 \ + --hash=sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44 \ + --hash=sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed \ + --hash=sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4 \ + --hash=sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba \ + --hash=sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12 \ + --hash=sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4 + # via -r requirements.in +referencing==0.36.2 \ + --hash=sha256:df2e89862cd09deabbdba16944cc3f10feb6b3e6f18e902f7cc25609a34775aa \ + --hash=sha256:e8699adbbf8b5c7de96d8ffa0eb5c158b3beafce084968e2ea8bb08c6794dcd0 + # via + # jsonschema + # jsonschema-specifications +requests==2.32.5 \ + --hash=sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6 \ + --hash=sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf + # via docker +rpds-py==0.27.0 \ + --hash=sha256:010c4843a3b92b54373e3d2291a7447d6c3fc29f591772cc2ea0e9f5c1da434b \ + --hash=sha256:05284439ebe7d9f5f5a668d4d8a0a1d851d16f7d47c78e1fab968c8ad30cab04 \ + --hash=sha256:0665be515767dc727ffa5f74bd2ef60b0ff85dad6bb8f50d91eaa6b5fb226f51 \ + --hash=sha256:069e0384a54f427bd65d7fda83b68a90606a3835901aaff42185fcd94f5a9295 \ + --hash=sha256:08680820d23df1df0a0260f714d12966bc6c42d02e8055a91d61e03f0c47dda0 \ + --hash=sha256:0954e3a92e1d62e83a54ea7b3fdc9efa5d61acef8488a8a3d31fdafbfb00460d \ + --hash=sha256:09965b314091829b378b60607022048953e25f0b396c2b70e7c4c81bcecf932e \ + --hash=sha256:0c431bfb91478d7cbe368d0a699978050d3b112d7f1d440a41e90faa325557fd \ + --hash=sha256:0f401c369186a5743694dd9fc08cba66cf70908757552e1f714bfc5219c655b5 \ + --hash=sha256:0f4f69d7a4300fbf91efb1fb4916421bd57804c01ab938ab50ac9c4aa2212f03 \ + --hash=sha256:11e8e28c0ba0373d052818b600474cfee2fafa6c9f36c8587d217b13ee28ca7d \ + --hash=sha256:130c1ffa5039a333f5926b09e346ab335f0d4ec393b030a18549a7c7e7c2cea4 \ + --hash=sha256:1321bce595ad70e80f97f998db37356b2e22cf98094eba6fe91782e626da2f71 \ + --hash=sha256:13bbc4846ae4c993f07c93feb21a24d8ec637573d567a924b1001e81c8ae80f9 \ + --hash=sha256:14f028eb47f59e9169bfdf9f7ceafd29dd64902141840633683d0bad5b04ff34 \ + --hash=sha256:15ea4d2e182345dd1b4286593601d766411b43f868924afe297570658c31a62b \ + --hash=sha256:181bc29e59e5e5e6e9d63b143ff4d5191224d355e246b5a48c88ce6b35c4e466 \ + --hash=sha256:183f5e221ba3e283cd36fdfbe311d95cd87699a083330b4f792543987167eff1 \ + --hash=sha256:184f0d7b342967f6cda94a07d0e1fae177d11d0b8f17d73e06e36ac02889f303 \ + --hash=sha256:190d7285cd3bb6d31d37a0534d7359c1ee191eb194c511c301f32a4afa5a1dd4 \ + --hash=sha256:19c990fdf5acecbf0623e906ae2e09ce1c58947197f9bced6bbd7482662231c4 \ + --hash=sha256:1d66f45b9399036e890fb9c04e9f70c33857fd8f58ac8db9f3278cfa835440c3 \ + --hash=sha256:203f581accef67300a942e49a37d74c12ceeef4514874c7cede21b012613ca2c \ + --hash=sha256:20e222a44ae9f507d0f2678ee3dd0c45ec1e930f6875d99b8459631c24058aec \ + --hash=sha256:2406d034635d1497c596c40c85f86ecf2bf9611c1df73d14078af8444fe48031 \ + --hash=sha256:249ab91ceaa6b41abc5f19513cb95b45c6f956f6b89f1fe3d99c81255a849f9e \ + --hash=sha256:25a4aebf8ca02bbb90a9b3e7a463bbf3bee02ab1c446840ca07b1695a68ce424 \ + --hash=sha256:27bac29bbbf39601b2aab474daf99dbc8e7176ca3389237a23944b17f8913d97 \ + --hash=sha256:299a245537e697f28a7511d01038c310ac74e8ea213c0019e1fc65f52c0dcb23 \ + --hash=sha256:2cff9bdd6c7b906cc562a505c04a57d92e82d37200027e8d362518df427f96cd \ + --hash=sha256:2e307cb5f66c59ede95c00e93cd84190a5b7f3533d7953690b2036780622ba81 \ + --hash=sha256:2e39169ac6aae06dd79c07c8a69d9da867cef6a6d7883a0186b46bb46ccfb0c3 \ + --hash=sha256:2fe6e18e5c8581f0361b35ae575043c7029d0a92cb3429e6e596c2cdde251432 \ + --hash=sha256:3001013dae10f806380ba739d40dee11db1ecb91684febb8406a87c2ded23dae \ + --hash=sha256:32196b5a99821476537b3f7732432d64d93a58d680a52c5e12a190ee0135d8b5 \ + --hash=sha256:33ba649a6e55ae3808e4c39e01580dc9a9b0d5b02e77b66bb86ef117922b1264 \ + --hash=sha256:341d8acb6724c0c17bdf714319c393bb27f6d23d39bc74f94221b3e59fc31828 \ + --hash=sha256:343cf24de9ed6c728abefc5d5c851d5de06497caa7ac37e5e65dd572921ed1b5 \ + --hash=sha256:36184b44bf60a480863e51021c26aca3dfe8dd2f5eeabb33622b132b9d8b8b54 \ + --hash=sha256:3841f66c1ffdc6cebce8aed64e36db71466f1dc23c0d9a5592e2a782a3042c79 \ + --hash=sha256:4045e2fc4b37ec4b48e8907a5819bdd3380708c139d7cc358f03a3653abedb89 \ + --hash=sha256:419dd9c98bcc9fb0242be89e0c6e922df333b975d4268faa90d58499fd9c9ebe \ + --hash=sha256:42894616da0fc0dcb2ec08a77896c3f56e9cb2f4b66acd76fc8992c3557ceb1c \ + --hash=sha256:42ccc57ff99166a55a59d8c7d14f1a357b7749f9ed3584df74053fd098243451 \ + --hash=sha256:4300e15e7d03660f04be84a125d1bdd0e6b2f674bc0723bc0fd0122f1a4585dc \ + --hash=sha256:443d239d02d9ae55b74015234f2cd8eb09e59fbba30bf60baeb3123ad4c6d5ff \ + --hash=sha256:44524b96481a4c9b8e6c46d6afe43fa1fb485c261e359fbe32b63ff60e3884d8 \ + --hash=sha256:45d04a73c54b6a5fd2bab91a4b5bc8b426949586e61340e212a8484919183859 \ + --hash=sha256:46f48482c1a4748ab2773f75fffbdd1951eb59794e32788834b945da857c47a8 \ + --hash=sha256:4790c9d5dd565ddb3e9f656092f57268951398cef52e364c405ed3112dc7c7c1 \ + --hash=sha256:4bc262ace5a1a7dc3e2eac2fa97b8257ae795389f688b5adf22c5db1e2431c43 \ + --hash=sha256:4c3f8a0d4802df34fcdbeb3dfe3a4d8c9a530baea8fafdf80816fcaac5379d83 \ + --hash=sha256:5355527adaa713ab693cbce7c1e0ec71682f599f61b128cf19d07e5c13c9b1f1 \ + --hash=sha256:555ed147cbe8c8f76e72a4c6cd3b7b761cbf9987891b9448808148204aed74a5 \ + --hash=sha256:55d42a0ef2bdf6bc81e1cc2d49d12460f63c6ae1423c4f4851b828e454ccf6f1 \ + --hash=sha256:59195dc244fc183209cf8a93406889cadde47dfd2f0a6b137783aa9c56d67c85 \ + --hash=sha256:59714ab0a5af25d723d8e9816638faf7f4254234decb7d212715c1aa71eee7be \ + --hash=sha256:5b3a5c8089eed498a3af23ce87a80805ff98f6ef8f7bdb70bd1b7dae5105f6ac \ + --hash=sha256:5d6790ff400254137b81b8053b34417e2c46921e302d655181d55ea46df58cf7 \ + --hash=sha256:5df559e9e7644d9042f626f2c3997b555f347d7a855a15f170b253f6c5bfe358 \ + --hash=sha256:5fa01b3d5e3b7d97efab65bd3d88f164e289ec323a8c033c5c38e53ee25c007e \ + --hash=sha256:61490d57e82e23b45c66f96184237994bfafa914433b8cd1a9bb57fecfced59d \ + --hash=sha256:6168af0be75bba990a39f9431cdfae5f0ad501f4af32ae62e8856307200517b8 \ + --hash=sha256:64a0fe3f334a40b989812de70160de6b0ec7e3c9e4a04c0bbc48d97c5d3600ae \ + --hash=sha256:64f689ab822f9b5eb6dfc69893b4b9366db1d2420f7db1f6a2adf2a9ca15ad64 \ + --hash=sha256:699c346abc73993962cac7bb4f02f58e438840fa5458a048d3a178a7a670ba86 \ + --hash=sha256:6b96b0b784fe5fd03beffff2b1533dc0d85e92bab8d1b2c24ef3a5dc8fac5669 \ + --hash=sha256:6bde37765564cd22a676dd8101b657839a1854cfaa9c382c5abf6ff7accfd4ae \ + --hash=sha256:6c135708e987f46053e0a1246a206f53717f9fadfba27174a9769ad4befba5c3 \ + --hash=sha256:6c27a7054b5224710fcfb1a626ec3ff4f28bcb89b899148c72873b18210e446b \ + --hash=sha256:6de6a7f622860af0146cb9ee148682ff4d0cea0b8fd3ad51ce4d40efb2f061d0 \ + --hash=sha256:737005088449ddd3b3df5a95476ee1c2c5c669f5c30eed909548a92939c0e12d \ + --hash=sha256:7451ede3560086abe1aa27dcdcf55cd15c96b56f543fb12e5826eee6f721f858 \ + --hash=sha256:7873b65686a6471c0037139aa000d23fe94628e0daaa27b6e40607c90e3f5ec4 \ + --hash=sha256:79af163a4b40bbd8cfd7ca86ec8b54b81121d3b213b4435ea27d6568bcba3e9d \ + --hash=sha256:7aed8118ae20515974650d08eb724150dc2e20c2814bcc307089569995e88a14 \ + --hash=sha256:7cf9bc4508efb18d8dff6934b602324eb9f8c6644749627ce001d6f38a490889 \ + --hash=sha256:7e57906e38583a2cba67046a09c2637e23297618dc1f3caddbc493f2be97c93f \ + --hash=sha256:7ec85994f96a58cf7ed288caa344b7fe31fd1d503bdf13d7331ead5f70ab60d5 \ + --hash=sha256:81f81bbd7cdb4bdc418c09a73809abeda8f263a6bf8f9c7f93ed98b5597af39d \ + --hash=sha256:86aca1616922b40d8ac1b3073a1ead4255a2f13405e5700c01f7c8d29a03972d \ + --hash=sha256:88051c3b7d5325409f433c5a40328fcb0685fc04e5db49ff936e910901d10114 \ + --hash=sha256:887ab1f12b0d227e9260558a4a2320024b20102207ada65c43e1ffc4546df72e \ + --hash=sha256:8a06aa1197ec0281eb1d7daf6073e199eb832fe591ffa329b88bae28f25f5fe5 \ + --hash=sha256:8a1dca5507fa1337f75dcd5070218b20bc68cf8844271c923c1b79dfcbc20391 \ + --hash=sha256:8b23cf252f180cda89220b378d917180f29d313cd6a07b2431c0d3b776aae86f \ + --hash=sha256:8d0e09cf4863c74106b5265c2c310f36146e2b445ff7b3018a56799f28f39f6f \ + --hash=sha256:8de567dec6d451649a781633d36f5c7501711adee329d76c095be2178855b042 \ + --hash=sha256:90fb790138c1a89a2e58c9282fe1089638401f2f3b8dddd758499041bc6e0774 \ + --hash=sha256:92f3b3ec3e6008a1fe00b7c0946a170f161ac00645cde35e3c9a68c2475e8156 \ + --hash=sha256:935afcdea4751b0ac918047a2df3f720212892347767aea28f5b3bf7be4f27c0 \ + --hash=sha256:9a0ff7ee28583ab30a52f371b40f54e7138c52ca67f8ca17ccb7ccf0b383cb5f \ + --hash=sha256:9ad08547995a57e74fea6abaf5940d399447935faebbd2612b3b0ca6f987946b \ + --hash=sha256:9b2a4e17bfd68536c3b801800941c95a1d4a06e3cada11c146093ba939d9638d \ + --hash=sha256:9b78430703cfcf5f5e86eb74027a1ed03a93509273d7c705babb547f03e60016 \ + --hash=sha256:9d0f92b78cfc3b74a42239fdd8c1266f4715b573204c234d2f9fc3fc7a24f185 \ + --hash=sha256:9da162b718b12c4219eeeeb68a5b7552fbc7aadedf2efee440f88b9c0e54b45d \ + --hash=sha256:a00c91104c173c9043bc46f7b30ee5e6d2f6b1149f11f545580f5d6fdff42c0b \ + --hash=sha256:a029be818059870664157194e46ce0e995082ac49926f1423c1f058534d2aaa9 \ + --hash=sha256:a1b3db5fae5cbce2131b7420a3f83553d4d89514c03d67804ced36161fe8b6b2 \ + --hash=sha256:a4cf32a26fa744101b67bfd28c55d992cd19438aff611a46cac7f066afca8fd4 \ + --hash=sha256:aa0bf113d15e8abdfee92aa4db86761b709a09954083afcb5bf0f952d6065fdb \ + --hash=sha256:ab47fe727c13c09d0e6f508e3a49e545008e23bf762a245b020391b621f5b726 \ + --hash=sha256:af22763a0a1eff106426a6e1f13c4582e0d0ad89c1493ab6c058236174cd6c6a \ + --hash=sha256:af9d4fd79ee1cc8e7caf693ee02737daabfc0fcf2773ca0a4735b356c8ad6f7c \ + --hash=sha256:b1fef1f13c842a39a03409e30ca0bf87b39a1e2a305a9924deadb75a43105d23 \ + --hash=sha256:b2eff8ee57c5996b0d2a07c3601fb4ce5fbc37547344a26945dd9e5cbd1ed27a \ + --hash=sha256:b4c4fbbcff474e1e5f38be1bf04511c03d492d42eec0babda5d03af3b5589374 \ + --hash=sha256:b8a4131698b6992b2a56015f51646711ec5d893a0b314a4b985477868e240c87 \ + --hash=sha256:b8a7acf04fda1f30f1007f3cc96d29d8cf0a53e626e4e1655fdf4eabc082d367 \ + --hash=sha256:ba783541be46f27c8faea5a6645e193943c17ea2f0ffe593639d906a327a9bcc \ + --hash=sha256:be0744661afbc4099fef7f4e604e7f1ea1be1dd7284f357924af12a705cc7d5c \ + --hash=sha256:be3964f7312ea05ed283b20f87cb533fdc555b2e428cc7be64612c0b2124f08c \ + --hash=sha256:be806e2961cd390a89d6c3ce8c2ae34271cfcd05660f716257838bb560f1c3b6 \ + --hash=sha256:bec77545d188f8bdd29d42bccb9191682a46fb2e655e3d1fb446d47c55ac3b8d \ + --hash=sha256:c10d92fb6d7fd827e44055fcd932ad93dac6a11e832d51534d77b97d1d85400f \ + --hash=sha256:c3782fb753aa825b4ccabc04292e07897e2fd941448eabf666856c5530277626 \ + --hash=sha256:c9ce7a9e967afc0a2af7caa0d15a3e9c1054815f73d6a8cb9225b61921b419bd \ + --hash=sha256:cb0702c12983be3b2fab98ead349ac63a98216d28dda6f518f52da5498a27a1b \ + --hash=sha256:cbc619e84a5e3ab2d452de831c88bdcad824414e9c2d28cd101f94dbdf26329c \ + --hash=sha256:ce4ed8e0c7dbc5b19352b9c2c6131dd23b95fa8698b5cdd076307a33626b72dc \ + --hash=sha256:ce96ab0bdfcef1b8c371ada2100767ace6804ea35aacce0aef3aeb4f3f499ca8 \ + --hash=sha256:cf824aceaeffff029ccfba0da637d432ca71ab21f13e7f6f5179cd88ebc77a8a \ + --hash=sha256:d2a81bdcfde4245468f7030a75a37d50400ac2455c3a4819d9d550c937f90ab5 \ + --hash=sha256:d2cc2b34f9e1d31ce255174da82902ad75bd7c0d88a33df54a77a22f2ef421ee \ + --hash=sha256:d2f184336bc1d6abfaaa1262ed42739c3789b1e3a65a29916a615307d22ffd2e \ + --hash=sha256:d3c622c39f04d5751408f5b801ecb527e6e0a471b367f420a877f7a660d583f6 \ + --hash=sha256:d7cf5e726b6fa977e428a61880fb108a62f28b6d0c7ef675b117eaff7076df49 \ + --hash=sha256:d85d784c619370d9329bbd670f41ff5f2ae62ea4519761b679d0f57f0f0ee267 \ + --hash=sha256:d93ebdb82363d2e7bec64eecdc3632b59e84bd270d74fe5be1659f7787052f9b \ + --hash=sha256:db8a6313dbac934193fc17fe7610f70cd8181c542a91382531bef5ed785e5615 \ + --hash=sha256:dbc2ab5d10544eb485baa76c63c501303b716a5c405ff2469a1d8ceffaabf622 \ + --hash=sha256:dbd749cff1defbde270ca346b69b3baf5f1297213ef322254bf2a28537f0b046 \ + --hash=sha256:dc662bc9375a6a394b62dfd331874c434819f10ee3902123200dbcf116963f89 \ + --hash=sha256:dc6b0d5a1ea0318ef2def2b6a55dccf1dcaf77d605672347271ed7b829860765 \ + --hash=sha256:dc79d192fb76fc0c84f2c58672c17bbbc383fd26c3cdc29daae16ce3d927e8b2 \ + --hash=sha256:dd2c1d27ebfe6a015cfa2005b7fe8c52d5019f7bbdd801bc6f7499aab9ae739e \ + --hash=sha256:dea0808153f1fbbad772669d906cddd92100277533a03845de6893cadeffc8be \ + --hash=sha256:e0d7151a1bd5d0a203a5008fc4ae51a159a610cb82ab0a9b2c4d80241745582e \ + --hash=sha256:e14aab02258cb776a108107bd15f5b5e4a1bbaa61ef33b36693dfab6f89d54f9 \ + --hash=sha256:e24d8031a2c62f34853756d9208eeafa6b940a1efcbfe36e8f57d99d52bb7261 \ + --hash=sha256:e36c80c49853b3ffda7aa1831bf175c13356b210c73128c861f3aa93c3cc4015 \ + --hash=sha256:e377e4cf8795cdbdff75b8f0223d7b6c68ff4fef36799d88ccf3a995a91c0112 \ + --hash=sha256:e3acb9c16530362aeaef4e84d57db357002dc5cbfac9a23414c3e73c08301ab2 \ + --hash=sha256:e3dc8d4ede2dbae6c0fc2b6c958bf51ce9fd7e9b40c0f5b8835c3fde44f5807d \ + --hash=sha256:e6491658dd2569f05860bad645569145c8626ac231877b0fb2d5f9bcb7054089 \ + --hash=sha256:eb91d252b35004a84670dfeafadb042528b19842a0080d8b53e5ec1128e8f433 \ + --hash=sha256:f0396e894bd1e66c74ecbc08b4f6a03dc331140942c4b1d345dd131b68574a60 \ + --hash=sha256:f09c9d4c26fa79c1bad927efb05aca2391350b8e61c38cbc0d7d3c814e463124 \ + --hash=sha256:f3cd110e02c5bf17d8fb562f6c9df5c20e73029d587cf8602a2da6c5ef1e32cb \ + --hash=sha256:f7a37dd208f0d658e0487522078b1ed68cd6bce20ef4b5a915d2809b9094b410 \ + --hash=sha256:fae4a01ef8c4cb2bbe92ef2063149596907dc4a881a8d26743b3f6b304713171 \ + --hash=sha256:fc327f4497b7087d06204235199daf208fd01c82d80465dc5efa4ec9df1c5b4e \ + --hash=sha256:fcc01c57ce6e70b728af02b2401c5bc853a9e14eb07deda30624374f0aebfe42 \ + --hash=sha256:fde355b02934cc6b07200cc3b27ab0c15870a757d1a72fd401aa92e2ea3c6bfe + # via + # jsonschema + # referencing +six==1.17.0 \ + --hash=sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 \ + --hash=sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81 + # via -r requirements.in +tomli==2.2.1 \ + --hash=sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6 \ + --hash=sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd \ + --hash=sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c \ + --hash=sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b \ + --hash=sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8 \ + --hash=sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6 \ + --hash=sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77 \ + --hash=sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff \ + --hash=sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea \ + --hash=sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192 \ + --hash=sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249 \ + --hash=sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee \ + --hash=sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4 \ + --hash=sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98 \ + --hash=sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8 \ + --hash=sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4 \ + --hash=sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281 \ + --hash=sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744 \ + --hash=sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69 \ + --hash=sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13 \ + --hash=sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140 \ + --hash=sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e \ + --hash=sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e \ + --hash=sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc \ + --hash=sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff \ + --hash=sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec \ + --hash=sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2 \ + --hash=sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222 \ + --hash=sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106 \ + --hash=sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272 \ + --hash=sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a \ + --hash=sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7 + # via -r requirements.in +typing-extensions==4.14.1 \ + --hash=sha256:38b39f4aeeab64884ce9f74c94263ef78f3c22467c8724005483154c26648d36 \ + --hash=sha256:d1e1e3b58374dc93031d6eda2420a48ea44a36c2b4766a4fdeb3710755731d76 + # via -r requirements.in +urllib3==2.5.0 \ + --hash=sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760 \ + --hash=sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc + # via + # docker + # requests +zstandard==0.24.0 \ + --hash=sha256:0101f835da7de08375f380192ff75135527e46e3f79bef224e3c49cb640fef6a \ + --hash=sha256:010302face38c9a909b8934e3bf6038266d6afc69523f3efa023c5cb5d38271b \ + --hash=sha256:05d27c953f2e0a3ecc8edbe91d6827736acc4c04d0479672e0400ccdb23d818c \ + --hash=sha256:09887301001e7a81a3618156bc1759e48588de24bddfdd5b7a4364da9a8fbc20 \ + --hash=sha256:0a416814608610abf5488889c74e43ffa0343ca6cf43957c6b6ec526212422da \ + --hash=sha256:0a9e95ceb180ccd12a8b3437bac7e8a8a089c9094e39522900a8917745542184 \ + --hash=sha256:0c9c3cba57f5792532a3df3f895980d47d78eda94b0e5b800651b53e96e0b604 \ + --hash=sha256:0d66da2649bb0af4471699aeb7a83d6f59ae30236fb9f6b5d20fb618ef6c6777 \ + --hash=sha256:0dc5654586613aebe5405c1ba180e67b3f29e7d98cf3187c79efdcc172f39457 \ + --hash=sha256:0ed8345b504df1cab280af923ef69ec0d7d52f7b22f78ec7982fde7c33a43c4f \ + --hash=sha256:0f6d9a146e07458cb41423ca2d783aefe3a3a97fe72838973c13b8f1ecc7343a \ + --hash=sha256:10e284748a7e7fbe2815ca62a9d6e84497d34cfdd0143fa9e8e208efa808d7c4 \ + --hash=sha256:13fc548e214df08d896ee5f29e1f91ee35db14f733fef8eabea8dca6e451d1e2 \ + --hash=sha256:1b14bc92af065d0534856bf1b30fc48753163ea673da98857ea4932be62079b1 \ + --hash=sha256:1bda8a85e5b9d5e73af2e61b23609a8cc1598c1b3b2473969912979205a1ff25 \ + --hash=sha256:1e133a9dd51ac0bcd5fd547ba7da45a58346dbc63def883f999857b0d0c003c4 \ + --hash=sha256:1f578fab202f4df67a955145c3e3ca60ccaaaf66c97808545b2625efeecdef10 \ + --hash=sha256:27b6fa72b57824a3f7901fc9cc4ce1c1c834b28f3a43d1d4254c64c8f11149d4 \ + --hash=sha256:2825a3951f945fb2613ded0f517d402b1e5a68e87e0ee65f5bd224a8333a9a46 \ + --hash=sha256:2fc67eb15ed573950bc6436a04b3faea6c36c7db98d2db030d48391c6736a0dc \ + --hash=sha256:337572a7340e1d92fd7fb5248c8300d0e91071002d92e0b8cabe8d9ae7b58159 \ + --hash=sha256:35f13501a8accf834457d8e40e744568287a215818778bc4d79337af2f3f0d97 \ + --hash=sha256:388aad2d693707f4a0f6cc687eb457b33303d6b57ecf212c8ff4468c34426892 \ + --hash=sha256:3aa3b4344b206941385a425ea25e6dd63e5cb0f535a4b88d56e3f8902086be9e \ + --hash=sha256:3adb4b5414febf074800d264ddf69ecade8c658837a83a19e8ab820e924c9933 \ + --hash=sha256:3b95fc06489aa9388400d1aab01a83652bc040c9c087bd732eb214909d7fb0dd \ + --hash=sha256:3f2fe35ec84908dddf0fbf66b35d7c2878dbe349552dd52e005c755d3493d61c \ + --hash=sha256:3f96a9130171e01dbb6c3d4d9925d604e2131a97f540e223b88ba45daf56d6fb \ + --hash=sha256:444633b487a711e34f4bccc46a0c5dfbe1aee82c1a511e58cdc16f6bd66f187c \ + --hash=sha256:498f88f5109666c19531f0243a90d2fdd2252839cd6c8cc6e9213a3446670fa8 \ + --hash=sha256:51a86bd963de3f36688553926a84e550d45d7f9745bd1947d79472eca27fcc75 \ + --hash=sha256:52788e7c489069e317fde641de41b757fa0ddc150e06488f153dd5daebac7192 \ + --hash=sha256:52cd7d9fa0a115c9446abb79b06a47171b7d916c35c10e0c3aa6f01d57561382 \ + --hash=sha256:55872e818598319f065e8192ebefecd6ac05f62a43f055ed71884b0a26218f41 \ + --hash=sha256:561123d05681197c0e24eb8ab3cfdaf299e2b59c293d19dad96e1610ccd8fbc6 \ + --hash=sha256:57be3abb4313e0dd625596376bbb607f40059d801d51c1a1da94d7477e63b255 \ + --hash=sha256:5e941654cef13a1d53634ec30933722eda11f44f99e1d0bc62bbce3387580d50 \ + --hash=sha256:622e1e04bd8a085994e02313ba06fbcf4f9ed9a488c6a77a8dbc0692abab6a38 \ + --hash=sha256:6324fde5cf5120fbf6541d5ff3c86011ec056e8d0f915d8e7822926a5377193a \ + --hash=sha256:6374feaf347e6b83ec13cc5dcfa70076f06d8f7ecd46cc71d58fac798ff08b76 \ + --hash=sha256:63d39b161000aeeaa06a1cb77c9806e939bfe460dfd593e4cbf24e6bc717ae94 \ + --hash=sha256:656ed895b28c7e42dd5b40dfcea3217cfc166b6b7eef88c3da2f5fc62484035b \ + --hash=sha256:663848a8bac4fdbba27feea2926049fdf7b55ec545d5b9aea096ef21e7f0b079 \ + --hash=sha256:6885ae4b33aee8835dbdb4249d3dfec09af55e705d74d9b660bfb9da51baaa8b \ + --hash=sha256:6b005bcee4be9c3984b355336283afe77b2defa76ed6b89332eced7b6fa68b68 \ + --hash=sha256:76cdfe7f920738ea871f035568f82bad3328cbc8d98f1f6988264096b5264efd \ + --hash=sha256:77b8b7b98893eaf47da03d262816f01f251c2aa059c063ed8a45c50eada123a5 \ + --hash=sha256:7ac6e4d727521d86d20ec291a3f4e64a478e8a73eaee80af8f38ec403e77a409 \ + --hash=sha256:7de5869e616d426b56809be7dc6dba4d37b95b90411ccd3de47f421a42d4d42c \ + --hash=sha256:869bf13f66b124b13be37dd6e08e4b728948ff9735308694e0b0479119e08ea7 \ + --hash=sha256:87ae1684bc3c02d5c35884b3726525eda85307073dbefe68c3c779e104a59036 \ + --hash=sha256:8ecd3b1f7a601f79e0cd20c26057d770219c0dc2f572ea07390248da2def79a4 \ + --hash=sha256:92be52ca4e6e604f03d5daa079caec9e04ab4cbf6972b995aaebb877d3d24e13 \ + --hash=sha256:92ea7855d5bcfb386c34557516c73753435fb2d4a014e2c9343b5f5ba148b5d8 \ + --hash=sha256:962ea3aecedcc944f8034812e23d7200d52c6e32765b8da396eeb8b8ffca71ce \ + --hash=sha256:98ca91dc9602cf351497d5600aa66e6d011a38c085a8237b370433fcb53e3409 \ + --hash=sha256:9b84c6c210684286e504022d11ec294d2b7922d66c823e87575d8b23eba7c81f \ + --hash=sha256:a0f6fc2ea6e07e20df48752e7700e02e1892c61f9a6bfbacaf2c5b24d5ad504b \ + --hash=sha256:a2bda8f2790add22773ee7a4e43c90ea05598bffc94c21c40ae0a9000b0133c3 \ + --hash=sha256:aa705beb74ab116563f4ce784fa94771f230c05d09ab5de9c397793e725bb1db \ + --hash=sha256:aadf32c389bb7f02b8ec5c243c38302b92c006da565e120dfcb7bf0378f4f848 \ + --hash=sha256:ab2357353894a5ec084bb8508ff892aa43fb7fe8a69ad310eac58221ee7f72aa \ + --hash=sha256:ad9fd176ff6800a0cf52bcf59c71e5de4fa25bf3ba62b58800e0f84885344d34 \ + --hash=sha256:addfc23e3bd5f4b6787b9ca95b2d09a1a67ad5a3c318daaa783ff90b2d3a366e \ + --hash=sha256:af1394c2c5febc44e0bbf0fc6428263fa928b50d1b1982ce1d870dc793a8e5f4 \ + --hash=sha256:b04c94718f7a8ed7cdd01b162b6caa1954b3c9d486f00ecbbd300f149d2b2606 \ + --hash=sha256:b4f20417a4f511c656762b001ec827500cbee54d1810253c6ca2df2c0a307a5f \ + --hash=sha256:b7a8c30d9bf4bd5e4dcfe26900bef0fcd9749acde45cdf0b3c89e2052fda9a13 \ + --hash=sha256:b7fa260dd2731afd0dfa47881c30239f422d00faee4b8b341d3e597cface1483 \ + --hash=sha256:b91380aefa9c7ac831b011368daf378d3277e0bdeb6bad9535e21251e26dd55a \ + --hash=sha256:bb2446a55b3a0fd8aa02aa7194bd64740015464a2daaf160d2025204e1d7c282 \ + --hash=sha256:bc05f8a875eb651d1cc62e12a4a0e6afa5cd0cc231381adb830d2e9c196ea895 \ + --hash=sha256:bcf69e0bcddbf2adcfafc1a7e864edcc204dd8171756d3a8f3340f6f6cc87b7b \ + --hash=sha256:bf02f915fa7934ea5dfc8d96757729c99a8868b7c340b97704795d6413cf5fe6 \ + --hash=sha256:c39d2b6161f3c5c5d12e9207ecf1006bb661a647a97a6573656b09aaea3f00ef \ + --hash=sha256:c59740682a686bf835a1a4d8d0ed1eefe31ac07f1c5a7ed5f2e72cf577692b00 \ + --hash=sha256:cc76de75300f65b8eb574d855c12518dc25a075dadb41dd18f6322bda3fe15d5 \ + --hash=sha256:cd0d3d16e63873253bad22b413ec679cf6586e51b5772eb10733899832efec42 \ + --hash=sha256:cda61c46343809ecda43dc620d1333dd7433a25d0a252f2dcc7667f6331c7b61 \ + --hash=sha256:cf7fbb4e54136e9a03c7ed7691843c4df6d2ecc854a2541f840665f4f2bb2edd \ + --hash=sha256:d2b3b4bda1a025b10fe0269369475f420177f2cb06e0f9d32c95b4873c9f80b8 \ + --hash=sha256:d5e3b9310fd7f0d12edc75532cd9a56da6293840c84da90070d692e0bb15f186 \ + --hash=sha256:d64899cc0f33a8f446f1e60bffc21fa88b99f0e8208750d9144ea717610a80ce \ + --hash=sha256:d6975f2d903bc354916a17b91a7aaac7299603f9ecdb788145060dde6e573a16 \ + --hash=sha256:d82ac87017b734f2fb70ff93818c66f0ad2c3810f61040f077ed38d924e19980 \ + --hash=sha256:dd91b0134a32dfcd8be504e8e46de44ad0045a569efc25101f2a12ccd41b5759 \ + --hash=sha256:df4be1cf6e8f0f2bbe2a3eabfff163ef592c84a40e1a20a8d7db7f27cfe08fc2 \ + --hash=sha256:e05d66239d14a04b4717998b736a25494372b1b2409339b04bf42aa4663bf251 \ + --hash=sha256:e40cd0fc734aa1d4bd0e7ad102fd2a1aefa50ce9ef570005ffc2273c5442ddc3 \ + --hash=sha256:e46eb6702691b24ddb3e31e88b4a499e31506991db3d3724a85bd1c5fc3cfe4e \ + --hash=sha256:e4ebb000c0fe24a6d0f3534b6256844d9dbf042fdf003efe5cf40690cf4e0f3e \ + --hash=sha256:e69f8e534b4e254f523e2f9d4732cf9c169c327ca1ce0922682aac9a5ee01155 \ + --hash=sha256:e91a4e5d62da7cb3f53e04fe254f1aa41009af578801ee6477fe56e7bef74ee2 \ + --hash=sha256:ec194197e90ca063f5ecb935d6c10063d84208cac5423c07d0f1a09d1c2ea42b \ + --hash=sha256:f6ae9fc67e636fc0fa9adee39db87dfbdeabfa8420bc0e678a1ac8441e01b22b \ + --hash=sha256:f7d3fe9e1483171e9183ffdb1fab07c5fef80a9c3840374a38ec2ab869ebae20 \ + --hash=sha256:fdc7a52a4cdaf7293e10813fd6a3abc0c7753660db12a3b864ab1fb5a0c60c16 \ + --hash=sha256:fe3198b81c00032326342d973e526803f183f97aa9e9a98e3f897ebafe21178f \ + --hash=sha256:ff19efaa33e7f136fe95f9bbcc90ab7fb60648453b03f95d1de3ab6997de0f32 + # via -r requirements.in diff --git a/requirements.win.txt b/requirements.win.txt index d37a96f..39aa173 100644 --- a/requirements.win.txt +++ b/requirements.win.txt @@ -6,104 +6,205 @@ attrs==25.3.0 \ # via # jsonschema # referencing -certifi==2025.4.26 \ - --hash=sha256:0a816057ea3cdefcef70270d2c515e4506bbc954f417fa5ade2021213bb8f0c6 \ - --hash=sha256:30350364dfe371162649852c63336a15c70c6510c2ad5015b21c2345311805f3 +certifi==2025.8.3 \ + --hash=sha256:e564105f78ded564e3ae7c923924435e1daa7463faeab5bb932bc53ffae63407 \ + --hash=sha256:f6c12493cfb1b06ba2ff328595af9350c65d6644968e5d3a2ffd78699af217a5 # via requests -charset-normalizer==3.4.2 \ - --hash=sha256:005fa3432484527f9732ebd315da8da8001593e2cf46a3d817669f062c3d9ed4 \ - --hash=sha256:046595208aae0120559a67693ecc65dd75d46f7bf687f159127046628178dc45 \ - --hash=sha256:0c29de6a1a95f24b9a1aa7aefd27d2487263f00dfd55a77719b530788f75cff7 \ - --hash=sha256:0c8c57f84ccfc871a48a47321cfa49ae1df56cd1d965a09abe84066f6853b9c0 \ - --hash=sha256:0f5d9ed7f254402c9e7d35d2f5972c9bbea9040e99cd2861bd77dc68263277c7 \ - --hash=sha256:18dd2e350387c87dabe711b86f83c9c78af772c748904d372ade190b5c7c9d4d \ - --hash=sha256:1b1bde144d98e446b056ef98e59c256e9294f6b74d7af6846bf5ffdafd687a7d \ - --hash=sha256:1c95a1e2902a8b722868587c0e1184ad5c55631de5afc0eb96bc4b0d738092c0 \ - --hash=sha256:1cad5f45b3146325bb38d6855642f6fd609c3f7cad4dbaf75549bf3b904d3184 \ - --hash=sha256:21b2899062867b0e1fde9b724f8aecb1af14f2778d69aacd1a5a1853a597a5db \ - --hash=sha256:24498ba8ed6c2e0b56d4acbf83f2d989720a93b41d712ebd4f4979660db4417b \ - --hash=sha256:25a23ea5c7edc53e0f29bae2c44fcb5a1aa10591aae107f2a2b2583a9c5cbc64 \ - --hash=sha256:289200a18fa698949d2b39c671c2cc7a24d44096784e76614899a7ccf2574b7b \ - --hash=sha256:28a1005facc94196e1fb3e82a3d442a9d9110b8434fc1ded7a24a2983c9888d8 \ - --hash=sha256:32fc0341d72e0f73f80acb0a2c94216bd704f4f0bce10aedea38f30502b271ff \ - --hash=sha256:36b31da18b8890a76ec181c3cf44326bf2c48e36d393ca1b72b3f484113ea344 \ - --hash=sha256:3c21d4fca343c805a52c0c78edc01e3477f6dd1ad7c47653241cf2a206d4fc58 \ - --hash=sha256:3fddb7e2c84ac87ac3a947cb4e66d143ca5863ef48e4a5ecb83bd48619e4634e \ - --hash=sha256:43e0933a0eff183ee85833f341ec567c0980dae57c464d8a508e1b2ceb336471 \ - --hash=sha256:4a476b06fbcf359ad25d34a057b7219281286ae2477cc5ff5e3f70a246971148 \ - --hash=sha256:4e594135de17ab3866138f496755f302b72157d115086d100c3f19370839dd3a \ - --hash=sha256:50bf98d5e563b83cc29471fa114366e6806bc06bc7a25fd59641e41445327836 \ - --hash=sha256:5a9979887252a82fefd3d3ed2a8e3b937a7a809f65dcb1e068b090e165bbe99e \ - --hash=sha256:5baececa9ecba31eff645232d59845c07aa030f0c81ee70184a90d35099a0e63 \ - --hash=sha256:5bf4545e3b962767e5c06fe1738f951f77d27967cb2caa64c28be7c4563e162c \ - --hash=sha256:6333b3aa5a12c26b2a4d4e7335a28f1475e0e5e17d69d55141ee3cab736f66d1 \ - --hash=sha256:65c981bdbd3f57670af8b59777cbfae75364b483fa8a9f420f08094531d54a01 \ - --hash=sha256:68a328e5f55ec37c57f19ebb1fdc56a248db2e3e9ad769919a58672958e8f366 \ - --hash=sha256:6a0289e4589e8bdfef02a80478f1dfcb14f0ab696b5a00e1f4b8a14a307a3c58 \ - --hash=sha256:6b66f92b17849b85cad91259efc341dce9c1af48e2173bf38a85c6329f1033e5 \ - --hash=sha256:6c9379d65defcab82d07b2a9dfbfc2e95bc8fe0ebb1b176a3190230a3ef0e07c \ - --hash=sha256:6fc1f5b51fa4cecaa18f2bd7a003f3dd039dd615cd69a2afd6d3b19aed6775f2 \ - --hash=sha256:70f7172939fdf8790425ba31915bfbe8335030f05b9913d7ae00a87d4395620a \ - --hash=sha256:721c76e84fe669be19c5791da68232ca2e05ba5185575086e384352e2c309597 \ - --hash=sha256:7222ffd5e4de8e57e03ce2cef95a4c43c98fcb72ad86909abdfc2c17d227fc1b \ - --hash=sha256:75d10d37a47afee94919c4fab4c22b9bc2a8bf7d4f46f87363bcf0573f3ff4f5 \ - --hash=sha256:76af085e67e56c8816c3ccf256ebd136def2ed9654525348cfa744b6802b69eb \ - --hash=sha256:770cab594ecf99ae64c236bc9ee3439c3f46be49796e265ce0cc8bc17b10294f \ - --hash=sha256:7a6ab32f7210554a96cd9e33abe3ddd86732beeafc7a28e9955cdf22ffadbab0 \ - --hash=sha256:7c48ed483eb946e6c04ccbe02c6b4d1d48e51944b6db70f697e089c193404941 \ - --hash=sha256:7f56930ab0abd1c45cd15be65cc741c28b1c9a34876ce8c17a2fa107810c0af0 \ - --hash=sha256:8075c35cd58273fee266c58c0c9b670947c19df5fb98e7b66710e04ad4e9ff86 \ - --hash=sha256:8272b73e1c5603666618805fe821edba66892e2870058c94c53147602eab29c7 \ - --hash=sha256:82d8fd25b7f4675d0c47cf95b594d4e7b158aca33b76aa63d07186e13c0e0ab7 \ - --hash=sha256:844da2b5728b5ce0e32d863af26f32b5ce61bc4273a9c720a9f3aa9df73b1455 \ - --hash=sha256:8755483f3c00d6c9a77f490c17e6ab0c8729e39e6390328e42521ef175380ae6 \ - --hash=sha256:915f3849a011c1f593ab99092f3cecfcb4d65d8feb4a64cf1bf2d22074dc0ec4 \ - --hash=sha256:926ca93accd5d36ccdabd803392ddc3e03e6d4cd1cf17deff3b989ab8e9dbcf0 \ - --hash=sha256:982bb1e8b4ffda883b3d0a521e23abcd6fd17418f6d2c4118d257a10199c0ce3 \ - --hash=sha256:98f862da73774290f251b9df8d11161b6cf25b599a66baf087c1ffe340e9bfd1 \ - --hash=sha256:9cbfacf36cb0ec2897ce0ebc5d08ca44213af24265bd56eca54bee7923c48fd6 \ - --hash=sha256:a370b3e078e418187da8c3674eddb9d983ec09445c99a3a263c2011993522981 \ - --hash=sha256:a955b438e62efdf7e0b7b52a64dc5c3396e2634baa62471768a64bc2adb73d5c \ - --hash=sha256:aa6af9e7d59f9c12b33ae4e9450619cf2488e2bbe9b44030905877f0b2324980 \ - --hash=sha256:aa88ca0b1932e93f2d961bf3addbb2db902198dca337d88c89e1559e066e7645 \ - --hash=sha256:aaeeb6a479c7667fbe1099af9617c83aaca22182d6cf8c53966491a0f1b7ffb7 \ - --hash=sha256:aaf27faa992bfee0264dc1f03f4c75e9fcdda66a519db6b957a3f826e285cf12 \ - --hash=sha256:b2680962a4848b3c4f155dc2ee64505a9c57186d0d56b43123b17ca3de18f0fa \ - --hash=sha256:b2d318c11350e10662026ad0eb71bb51c7812fc8590825304ae0bdd4ac283acd \ - --hash=sha256:b33de11b92e9f75a2b545d6e9b6f37e398d86c3e9e9653c4864eb7e89c5773ef \ - --hash=sha256:b3daeac64d5b371dea99714f08ffc2c208522ec6b06fbc7866a450dd446f5c0f \ - --hash=sha256:be1e352acbe3c78727a16a455126d9ff83ea2dfdcbc83148d2982305a04714c2 \ - --hash=sha256:bee093bf902e1d8fc0ac143c88902c3dfc8941f7ea1d6a8dd2bcb786d33db03d \ - --hash=sha256:c72fbbe68c6f32f251bdc08b8611c7b3060612236e960ef848e0a517ddbe76c5 \ - --hash=sha256:c9e36a97bee9b86ef9a1cf7bb96747eb7a15c2f22bdb5b516434b00f2a599f02 \ - --hash=sha256:cddf7bd982eaa998934a91f69d182aec997c6c468898efe6679af88283b498d3 \ - --hash=sha256:cf713fe9a71ef6fd5adf7a79670135081cd4431c2943864757f0fa3a65b1fafd \ - --hash=sha256:d11b54acf878eef558599658b0ffca78138c8c3655cf4f3a4a673c437e67732e \ - --hash=sha256:d41c4d287cfc69060fa91cae9683eacffad989f1a10811995fa309df656ec214 \ - --hash=sha256:d524ba3f1581b35c03cb42beebab4a13e6cdad7b36246bd22541fa585a56cccd \ - --hash=sha256:daac4765328a919a805fa5e2720f3e94767abd632ae410a9062dff5412bae65a \ - --hash=sha256:db4c7bf0e07fc3b7d89ac2a5880a6a8062056801b83ff56d8464b70f65482b6c \ - --hash=sha256:dc7039885fa1baf9be153a0626e337aa7ec8bf96b0128605fb0d77788ddc1681 \ - --hash=sha256:dccab8d5fa1ef9bfba0590ecf4d46df048d18ffe3eec01eeb73a42e0d9e7a8ba \ - --hash=sha256:dedb8adb91d11846ee08bec4c8236c8549ac721c245678282dcb06b221aab59f \ - --hash=sha256:e45ba65510e2647721e35323d6ef54c7974959f6081b58d4ef5d87c60c84919a \ - --hash=sha256:e53efc7c7cee4c1e70661e2e112ca46a575f90ed9ae3fef200f2a25e954f4b28 \ - --hash=sha256:e635b87f01ebc977342e2697d05b56632f5f879a4f15955dfe8cef2448b51691 \ - --hash=sha256:e70e990b2137b29dc5564715de1e12701815dacc1d056308e2b17e9095372a82 \ - --hash=sha256:e8082b26888e2f8b36a042a58307d5b917ef2b1cacab921ad3323ef91901c71a \ - --hash=sha256:e8323a9b031aa0393768b87f04b4164a40037fb2a3c11ac06a03ffecd3618027 \ - --hash=sha256:e92fca20c46e9f5e1bb485887d074918b13543b1c2a1185e69bb8d17ab6236a7 \ - --hash=sha256:eb30abc20df9ab0814b5a2524f23d75dcf83cde762c161917a2b4b7b55b1e518 \ - --hash=sha256:eba9904b0f38a143592d9fc0e19e2df0fa2e41c3c3745554761c5f6447eedabf \ - --hash=sha256:ef8de666d6179b009dce7bcb2ad4c4a779f113f12caf8dc77f0162c29d20490b \ - --hash=sha256:efd387a49825780ff861998cd959767800d54f8308936b21025326de4b5a42b9 \ - --hash=sha256:f0aa37f3c979cf2546b73e8222bbfa3dc07a641585340179d768068e3455e544 \ - --hash=sha256:f4074c5a429281bf056ddd4c5d3b740ebca4d43ffffe2ef4bf4d2d05114299da \ - --hash=sha256:f69a27e45c43520f5487f27627059b64aaf160415589230992cec34c5e18a509 \ - --hash=sha256:fb707f3e15060adf5b7ada797624a6c6e0138e2a26baa089df64c68ee98e040f \ - --hash=sha256:fcbe676a55d7445b22c10967bceaaf0ee69407fbe0ece4d032b6eb8d4565982a \ - --hash=sha256:fdb20a30fe1175ecabed17cbf7812f7b804b8a315a25f24678bcdf120a90077f +cffi==1.17.1 \ + --hash=sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8 \ + --hash=sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2 \ + --hash=sha256:0e2b1fac190ae3ebfe37b979cc1ce69c81f4e4fe5746bb401dca63a9062cdaf1 \ + --hash=sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15 \ + --hash=sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36 \ + --hash=sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824 \ + --hash=sha256:1d599671f396c4723d016dbddb72fe8e0397082b0a77a4fab8028923bec050e8 \ + --hash=sha256:28b16024becceed8c6dfbc75629e27788d8a3f9030691a1dbf9821a128b22c36 \ + --hash=sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17 \ + --hash=sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf \ + --hash=sha256:31000ec67d4221a71bd3f67df918b1f88f676f1c3b535a7eb473255fdc0b83fc \ + --hash=sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3 \ + --hash=sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed \ + --hash=sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702 \ + --hash=sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1 \ + --hash=sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8 \ + --hash=sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903 \ + --hash=sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6 \ + --hash=sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d \ + --hash=sha256:636062ea65bd0195bc012fea9321aca499c0504409f413dc88af450b57ffd03b \ + --hash=sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e \ + --hash=sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be \ + --hash=sha256:6f17be4345073b0a7b8ea599688f692ac3ef23ce28e5df79c04de519dbc4912c \ + --hash=sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683 \ + --hash=sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9 \ + --hash=sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c \ + --hash=sha256:7596d6620d3fa590f677e9ee430df2958d2d6d6de2feeae5b20e82c00b76fbf8 \ + --hash=sha256:78122be759c3f8a014ce010908ae03364d00a1f81ab5c7f4a7a5120607ea56e1 \ + --hash=sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4 \ + --hash=sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655 \ + --hash=sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67 \ + --hash=sha256:9755e4345d1ec879e3849e62222a18c7174d65a6a92d5b346b1863912168b595 \ + --hash=sha256:98e3969bcff97cae1b2def8ba499ea3d6f31ddfdb7635374834cf89a1a08ecf0 \ + --hash=sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65 \ + --hash=sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41 \ + --hash=sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6 \ + --hash=sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401 \ + --hash=sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6 \ + --hash=sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3 \ + --hash=sha256:b2ab587605f4ba0bf81dc0cb08a41bd1c0a5906bd59243d56bad7668a6fc6c16 \ + --hash=sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93 \ + --hash=sha256:c03e868a0b3bc35839ba98e74211ed2b05d2119be4e8a0f224fba9384f1fe02e \ + --hash=sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4 \ + --hash=sha256:c7eac2ef9b63c79431bc4b25f1cd649d7f061a28808cbc6c47b534bd789ef964 \ + --hash=sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c \ + --hash=sha256:ca74b8dbe6e8e8263c0ffd60277de77dcee6c837a3d0881d8c1ead7268c9e576 \ + --hash=sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0 \ + --hash=sha256:cdf5ce3acdfd1661132f2a9c19cac174758dc2352bfe37d98aa7512c6b7178b3 \ + --hash=sha256:d016c76bdd850f3c626af19b0542c9677ba156e4ee4fccfdd7848803533ef662 \ + --hash=sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3 \ + --hash=sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff \ + --hash=sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5 \ + --hash=sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd \ + --hash=sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f \ + --hash=sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5 \ + --hash=sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14 \ + --hash=sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d \ + --hash=sha256:e221cf152cff04059d011ee126477f0d9588303eb57e88923578ace7baad17f9 \ + --hash=sha256:e31ae45bc2e29f6b2abd0de1cc3b9d5205aa847cafaecb8af1476a609a2f6eb7 \ + --hash=sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382 \ + --hash=sha256:f1e22e8c4419538cb197e4dd60acc919d7696e5ef98ee4da4e01d3f8cfa4cc5a \ + --hash=sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e \ + --hash=sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a \ + --hash=sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4 \ + --hash=sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99 \ + --hash=sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87 \ + --hash=sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b + # via + # cryptography + # pynacl +charset-normalizer==3.4.3 \ + --hash=sha256:00237675befef519d9af72169d8604a067d92755e84fe76492fef5441db05b91 \ + --hash=sha256:02425242e96bcf29a49711b0ca9f37e451da7c70562bc10e8ed992a5a7a25cc0 \ + --hash=sha256:027b776c26d38b7f15b26a5da1044f376455fb3766df8fc38563b4efbc515154 \ + --hash=sha256:07a0eae9e2787b586e129fdcbe1af6997f8d0e5abaa0bc98c0e20e124d67e601 \ + --hash=sha256:0cacf8f7297b0c4fcb74227692ca46b4a5852f8f4f24b3c766dd94a1075c4884 \ + --hash=sha256:0e78314bdc32fa80696f72fa16dc61168fda4d6a0c014e0380f9d02f0e5d8a07 \ + --hash=sha256:0f2be7e0cf7754b9a30eb01f4295cc3d4358a479843b31f328afd210e2c7598c \ + --hash=sha256:13faeacfe61784e2559e690fc53fa4c5ae97c6fcedb8eb6fb8d0a15b475d2c64 \ + --hash=sha256:14c2a87c65b351109f6abfc424cab3927b3bdece6f706e4d12faaf3d52ee5efe \ + --hash=sha256:1606f4a55c0fd363d754049cdf400175ee96c992b1f8018b993941f221221c5f \ + --hash=sha256:16a8770207946ac75703458e2c743631c79c59c5890c80011d536248f8eaa432 \ + --hash=sha256:18343b2d246dc6761a249ba1fb13f9ee9a2bcd95decc767319506056ea4ad4dc \ + --hash=sha256:18b97b8404387b96cdbd30ad660f6407799126d26a39ca65729162fd810a99aa \ + --hash=sha256:1bb60174149316da1c35fa5233681f7c0f9f514509b8e399ab70fea5f17e45c9 \ + --hash=sha256:1e8ac75d72fa3775e0b7cb7e4629cec13b7514d928d15ef8ea06bca03ef01cae \ + --hash=sha256:1ef99f0456d3d46a50945c98de1774da86f8e992ab5c77865ea8b8195341fc19 \ + --hash=sha256:2001a39612b241dae17b4687898843f254f8748b796a2e16f1051a17078d991d \ + --hash=sha256:23b6b24d74478dc833444cbd927c338349d6ae852ba53a0d02a2de1fce45b96e \ + --hash=sha256:252098c8c7a873e17dd696ed98bbe91dbacd571da4b87df3736768efa7a792e4 \ + --hash=sha256:257f26fed7d7ff59921b78244f3cd93ed2af1800ff048c33f624c87475819dd7 \ + --hash=sha256:2c322db9c8c89009a990ef07c3bcc9f011a3269bc06782f916cd3d9eed7c9312 \ + --hash=sha256:30a96e1e1f865f78b030d65241c1ee850cdf422d869e9028e2fc1d5e4db73b92 \ + --hash=sha256:30d006f98569de3459c2fc1f2acde170b7b2bd265dc1943e87e1a4efe1b67c31 \ + --hash=sha256:31a9a6f775f9bcd865d88ee350f0ffb0e25936a7f930ca98995c05abf1faf21c \ + --hash=sha256:320e8e66157cc4e247d9ddca8e21f427efc7a04bbd0ac8a9faf56583fa543f9f \ + --hash=sha256:34a7f768e3f985abdb42841e20e17b330ad3aaf4bb7e7aeeb73db2e70f077b99 \ + --hash=sha256:3653fad4fe3ed447a596ae8638b437f827234f01a8cd801842e43f3d0a6b281b \ + --hash=sha256:3cd35b7e8aedeb9e34c41385fda4f73ba609e561faedfae0a9e75e44ac558a15 \ + --hash=sha256:3cfb2aad70f2c6debfbcb717f23b7eb55febc0bb23dcffc0f076009da10c6392 \ + --hash=sha256:416175faf02e4b0810f1f38bcb54682878a4af94059a1cd63b8747244420801f \ + --hash=sha256:41d1fc408ff5fdfb910200ec0e74abc40387bccb3252f3f27c0676731df2b2c8 \ + --hash=sha256:42e5088973e56e31e4fa58eb6bd709e42fc03799c11c42929592889a2e54c491 \ + --hash=sha256:4ca4c094de7771a98d7fbd67d9e5dbf1eb73efa4f744a730437d8a3a5cf994f0 \ + --hash=sha256:511729f456829ef86ac41ca78c63a5cb55240ed23b4b737faca0eb1abb1c41bc \ + --hash=sha256:53cd68b185d98dde4ad8990e56a58dea83a4162161b1ea9272e5c9182ce415e0 \ + --hash=sha256:585f3b2a80fbd26b048a0be90c5aae8f06605d3c92615911c3a2b03a8a3b796f \ + --hash=sha256:5b413b0b1bfd94dbf4023ad6945889f374cd24e3f62de58d6bb102c4d9ae534a \ + --hash=sha256:5d8d01eac18c423815ed4f4a2ec3b439d654e55ee4ad610e153cf02faf67ea40 \ + --hash=sha256:6aab0f181c486f973bc7262a97f5aca3ee7e1437011ef0c2ec04b5a11d16c927 \ + --hash=sha256:6cf8fd4c04756b6b60146d98cd8a77d0cdae0e1ca20329da2ac85eed779b6849 \ + --hash=sha256:6fb70de56f1859a3f71261cbe41005f56a7842cc348d3aeb26237560bfa5e0ce \ + --hash=sha256:6fce4b8500244f6fcb71465d4a4930d132ba9ab8e71a7859e6a5d59851068d14 \ + --hash=sha256:70bfc5f2c318afece2f5838ea5e4c3febada0be750fcf4775641052bbba14d05 \ + --hash=sha256:73dc19b562516fc9bcf6e5d6e596df0b4eb98d87e4f79f3ae71840e6ed21361c \ + --hash=sha256:74d77e25adda8581ffc1c720f1c81ca082921329452eba58b16233ab1842141c \ + --hash=sha256:78deba4d8f9590fe4dae384aeff04082510a709957e968753ff3c48399f6f92a \ + --hash=sha256:86df271bf921c2ee3818f0522e9a5b8092ca2ad8b065ece5d7d9d0e9f4849bcc \ + --hash=sha256:88ab34806dea0671532d3f82d82b85e8fc23d7b2dd12fa837978dad9bb392a34 \ + --hash=sha256:8999f965f922ae054125286faf9f11bc6932184b93011d138925a1773830bbe9 \ + --hash=sha256:8dcfc373f888e4fb39a7bc57e93e3b845e7f462dacc008d9749568b1c4ece096 \ + --hash=sha256:939578d9d8fd4299220161fdd76e86c6a251987476f5243e8864a7844476ba14 \ + --hash=sha256:96b2b3d1a83ad55310de8c7b4a2d04d9277d5591f40761274856635acc5fcb30 \ + --hash=sha256:a2d08ac246bb48479170408d6c19f6385fa743e7157d716e144cad849b2dd94b \ + --hash=sha256:b256ee2e749283ef3ddcff51a675ff43798d92d746d1a6e4631bf8c707d22d0b \ + --hash=sha256:b5e3b2d152e74e100a9e9573837aba24aab611d39428ded46f4e4022ea7d1942 \ + --hash=sha256:b89bc04de1d83006373429975f8ef9e7932534b8cc9ca582e4db7d20d91816db \ + --hash=sha256:bd28b817ea8c70215401f657edef3a8aa83c29d447fb0b622c35403780ba11d5 \ + --hash=sha256:c60e092517a73c632ec38e290eba714e9627abe9d301c8c8a12ec32c314a2a4b \ + --hash=sha256:c6dbd0ccdda3a2ba7c2ecd9d77b37f3b5831687d8dc1b6ca5f56a4880cc7b7ce \ + --hash=sha256:c6e490913a46fa054e03699c70019ab869e990270597018cef1d8562132c2669 \ + --hash=sha256:c6f162aabe9a91a309510d74eeb6507fab5fff92337a15acbe77753d88d9dcf0 \ + --hash=sha256:c6fd51128a41297f5409deab284fecbe5305ebd7e5a1f959bee1c054622b7018 \ + --hash=sha256:cc34f233c9e71701040d772aa7490318673aa7164a0efe3172b2981218c26d93 \ + --hash=sha256:cc9370a2da1ac13f0153780040f465839e6cccb4a1e44810124b4e22483c93fe \ + --hash=sha256:ccf600859c183d70eb47e05a44cd80a4ce77394d1ac0f79dbd2dd90a69a3a049 \ + --hash=sha256:ce571ab16d890d23b5c278547ba694193a45011ff86a9162a71307ed9f86759a \ + --hash=sha256:cf1ebb7d78e1ad8ec2a8c4732c7be2e736f6e5123a4146c5b89c9d1f585f8cef \ + --hash=sha256:d0e909868420b7049dafd3a31d45125b31143eec59235311fc4c57ea26a4acd2 \ + --hash=sha256:d22dbedd33326a4a5190dd4fe9e9e693ef12160c77382d9e87919bce54f3d4ca \ + --hash=sha256:d716a916938e03231e86e43782ca7878fb602a125a91e7acb8b5112e2e96ac16 \ + --hash=sha256:d79c198e27580c8e958906f803e63cddb77653731be08851c7df0b1a14a8fc0f \ + --hash=sha256:d95bfb53c211b57198bb91c46dd5a2d8018b3af446583aab40074bf7988401cb \ + --hash=sha256:e28e334d3ff134e88989d90ba04b47d84382a828c061d0d1027b1b12a62b39b1 \ + --hash=sha256:ec557499516fc90fd374bf2e32349a2887a876fbf162c160e3c01b6849eaf557 \ + --hash=sha256:fb6fecfd65564f208cbf0fba07f107fb661bcd1a7c389edbced3f7a493f70e37 \ + --hash=sha256:fb731e5deb0c7ef82d698b0f4c5bb724633ee2a489401594c5c88b02e6cb15f7 \ + --hash=sha256:fb7f67a1bfa6e40b438170ebdc8158b78dc465a5a67b6dde178a46987b244a72 \ + --hash=sha256:fd10de089bcdcd1be95a2f73dbe6254798ec1bda9f450d5828c96f93e2536b9c \ + --hash=sha256:fdabf8315679312cfa71302f9bd509ded4f2f263fb5b765cf1433b39106c3cc9 # via requests +cryptography==45.0.6 \ + --hash=sha256:00e8724bdad672d75e6f069b27970883179bd472cd24a63f6e620ca7e41cc0c5 \ + --hash=sha256:048e7ad9e08cf4c0ab07ff7f36cc3115924e22e2266e034450a890d9e312dd74 \ + --hash=sha256:0d9ef57b6768d9fa58e92f4947cea96ade1233c0e236db22ba44748ffedca394 \ + --hash=sha256:18f878a34b90d688982e43f4b700408b478102dd58b3e39de21b5ebf6509c301 \ + --hash=sha256:1b7fa6a1c1188c7ee32e47590d16a5a0646270921f8020efc9a511648e1b2e08 \ + --hash=sha256:20ae4906a13716139d6d762ceb3e0e7e110f7955f3bc3876e3a07f5daadec5f3 \ + --hash=sha256:20d15aed3ee522faac1a39fbfdfee25d17b1284bafd808e1640a74846d7c4d1b \ + --hash=sha256:2384f2ab18d9be88a6e4f8972923405e2dbb8d3e16c6b43f15ca491d7831bd18 \ + --hash=sha256:275ba5cc0d9e320cd70f8e7b96d9e59903c815ca579ab96c1e37278d231fc402 \ + --hash=sha256:2dac5ec199038b8e131365e2324c03d20e97fe214af051d20c49db129844e8b3 \ + --hash=sha256:31a2b9a10530a1cb04ffd6aa1cd4d3be9ed49f7d77a4dafe198f3b382f41545c \ + --hash=sha256:3436128a60a5e5490603ab2adbabc8763613f638513ffa7d311c900a8349a2a0 \ + --hash=sha256:3b5bf5267e98661b9b888a9250d05b063220dfa917a8203744454573c7eb79db \ + --hash=sha256:3de77e4df42ac8d4e4d6cdb342d989803ad37707cf8f3fbf7b088c9cbdd46427 \ + --hash=sha256:44647c5d796f5fc042bbc6d61307d04bf29bccb74d188f18051b635f20a9c75f \ + --hash=sha256:550ae02148206beb722cfe4ef0933f9352bab26b087af00e48fdfb9ade35c5b3 \ + --hash=sha256:599c8d7df950aa68baa7e98f7b73f4f414c9f02d0e8104a30c0182a07732638b \ + --hash=sha256:5b64e668fc3528e77efa51ca70fadcd6610e8ab231e3e06ae2bab3b31c2b8ed9 \ + --hash=sha256:5bd6020c80c5b2b2242d6c48487d7b85700f5e0038e67b29d706f98440d66eb5 \ + --hash=sha256:5c966c732cf6e4a276ce83b6e4c729edda2df6929083a952cc7da973c539c719 \ + --hash=sha256:629127cfdcdc6806dfe234734d7cb8ac54edaf572148274fa377a7d3405b0043 \ + --hash=sha256:705bb7c7ecc3d79a50f236adda12ca331c8e7ecfbea51edd931ce5a7a7c4f012 \ + --hash=sha256:780c40fb751c7d2b0c6786ceee6b6f871e86e8718a8ff4bc35073ac353c7cd02 \ + --hash=sha256:7a3085d1b319d35296176af31c90338eeb2ddac8104661df79f80e1d9787b8b2 \ + --hash=sha256:826b46dae41a1155a0c0e66fafba43d0ede1dc16570b95e40c4d83bfcf0a451d \ + --hash=sha256:833dc32dfc1e39b7376a87b9a6a4288a10aae234631268486558920029b086ec \ + --hash=sha256:cc4d66f5dc4dc37b89cfef1bd5044387f7a1f6f0abb490815628501909332d5d \ + --hash=sha256:d063341378d7ee9c91f9d23b431a3502fc8bfacd54ef0a27baa72a0843b29159 \ + --hash=sha256:e2a21a8eda2d86bb604934b6b37691585bd095c1f788530c1fcefc53a82b3453 \ + --hash=sha256:e40b80ecf35ec265c452eea0ba94c9587ca763e739b8e559c128d23bff7ebbbf \ + --hash=sha256:e5b3dda1b00fb41da3af4c5ef3f922a200e33ee5ba0f0bc9ecf0b0c173958385 \ + --hash=sha256:ea3c42f2016a5bbf71825537c2ad753f2870191134933196bee408aac397b3d9 \ + --hash=sha256:eccddbd986e43014263eda489abbddfbc287af5cddfd690477993dbb31e31016 \ + --hash=sha256:ee411a1b977f40bd075392c80c10b58025ee5c6b47a822a33c1198598a7a5f05 \ + --hash=sha256:f4028f29a9f38a2025abedb2e409973709c660d44319c61762202206ed577c42 \ + --hash=sha256:f68f833a9d445cc49f01097d95c83a850795921b3f7cc6488731e69bde3288da \ + --hash=sha256:fc022c1fa5acff6def2fc6d7819bbbd31ccddfe67d075331a65d9cfb28a20983 + # via pyjwt +deprecated==1.2.18 \ + --hash=sha256:422b6f6d859da6f2ef57857761bfb392480502a64c3028ca9bbe86085d72115d \ + --hash=sha256:bd5011788200372a32418f888e326a09ff80d0214bd961147cfed01b5c018eec + # via pygithub docker==7.1.0 \ --hash=sha256:ad8c70e6e3f8926cb8a92619b832b4ea5299e2831c14284663184e200546fa6c \ --hash=sha256:c96b93b7f0a746f9e77d325bcfb87422a3d8bd4f03136ae8a85b37f1898d5fc0 @@ -116,9 +217,9 @@ jinja2==3.1.6 \ --hash=sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d \ --hash=sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67 # via -r requirements.in -jsonschema==4.24.0 \ - --hash=sha256:0b4e8069eb12aedfa881333004bccaec24ecef5a8a6a4b6df142b2cc9599d196 \ - --hash=sha256:a462455f19f5faf404a7902952b6f0e3ce868f3ee09a359b05eca6673bd8412d +jsonschema==4.25.1 \ + --hash=sha256:3fba0169e345c7175110351d456342c364814cfcf3b964ba4587f22915230a63 \ + --hash=sha256:e4a9655ce0da0c0b67a085847e00a3a51449e1157f4f75e9fb5aa545e122eb85 # via -r requirements.in jsonschema-specifications==2025.4.1 \ --hash=sha256:4653bffbd6584f7de83a67e0d620ef16900b390ddc7939d56684d6c81e33f1af \ @@ -187,76 +288,106 @@ markupsafe==3.0.2 \ --hash=sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430 \ --hash=sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50 # via jinja2 -pywin32==310 \ - --hash=sha256:0867beb8addefa2e3979d4084352e4ac6e991ca45373390775f7084cc0209b9c \ - --hash=sha256:126298077a9d7c95c53823934f000599f66ec9296b09167810eb24875f32689c \ - --hash=sha256:19ec5fc9b1d51c4350be7bb00760ffce46e6c95eaf2f0b2f1150657b1a43c582 \ - --hash=sha256:1e765f9564e83011a63321bb9d27ec456a0ed90d3732c4b2e312b855365ed8bd \ - --hash=sha256:2349cc906eae872d0663d4d6290d13b90621eaf78964bb1578632ff20e152966 \ - --hash=sha256:30f0a9b3138fb5e07eb4973b7077e1883f558e40c578c6925acc7a94c34eaa36 \ - --hash=sha256:33babed0cf0c92a6f94cc6cc13546ab24ee13e3e800e61ed87609ab91e4c8213 \ - --hash=sha256:5d241a659c496ada3253cd01cfaa779b048e90ce4b2b38cd44168ad555ce74ab \ - --hash=sha256:667827eb3a90208ddbdcc9e860c81bde63a135710e21e4cb3348968e4bd5249e \ - --hash=sha256:6dd97011efc8bf51d6793a82292419eba2c71cf8e7250cfac03bba284454abc1 \ - --hash=sha256:851c8d927af0d879221e616ae1f66145253537bbdd321a77e8ef701b443a9a1a \ - --hash=sha256:8a75a5cc3893e83a108c05d82198880704c44bbaee4d06e442e471d3c9ea4f3d \ - --hash=sha256:96867217335559ac619f00ad70e513c0fcf84b8a3af9fc2bba3b59b97da70475 \ - --hash=sha256:bf5c397c9a9a19a6f62f3fb821fbf36cac08f03770056711f765ec1503972060 \ - --hash=sha256:c3e78706e4229b915a0821941a84e7ef420bf2b77e08c9dae3c76fd03fd2ae3d \ - --hash=sha256:e308f831de771482b7cf692a1f308f8fca701b2d8f9dde6cc440c7da17e47b33 +pycparser==2.22 \ + --hash=sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6 \ + --hash=sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc + # via cffi +pygithub==2.7.0 \ + --hash=sha256:40ecbfe26dc55cc34ab4b0ffa1d455e6f816ef9a2bc8d6f5ad18ce572f163700 \ + --hash=sha256:7cd6eafabb09b5369afba3586d86b1f1ad6f1326d2ff01bc47bb26615dce4cbb + # via -r requirements.in +pyjwt==2.10.1 \ + --hash=sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953 \ + --hash=sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb + # via pygithub +pynacl==1.5.0 \ + --hash=sha256:06b8f6fa7f5de8d5d2f7573fe8c863c051225a27b61e6860fd047b1775807858 \ + --hash=sha256:0c84947a22519e013607c9be43706dd42513f9e6ae5d39d3613ca1e142fba44d \ + --hash=sha256:20f42270d27e1b6a29f54032090b972d97f0a1b0948cc52392041ef7831fee93 \ + --hash=sha256:401002a4aaa07c9414132aaed7f6836ff98f59277a234704ff66878c2ee4a0d1 \ + --hash=sha256:52cb72a79269189d4e0dc537556f4740f7f0a9ec41c1322598799b0bdad4ef92 \ + --hash=sha256:61f642bf2378713e2c2e1de73444a3778e5f0a38be6fee0fe532fe30060282ff \ + --hash=sha256:8ac7448f09ab85811607bdd21ec2464495ac8b7c66d146bf545b0f08fb9220ba \ + --hash=sha256:a36d4a9dda1f19ce6e03c9a784a2921a4b726b02e1c736600ca9c22029474394 \ + --hash=sha256:a422368fc821589c228f4c49438a368831cb5bbc0eab5ebe1d7fac9dded6567b \ + --hash=sha256:e46dae94e34b085175f8abb3b0aaa7da40767865ac82c928eeb9e57e1ea8a543 + # via pygithub +pywin32==311 \ + --hash=sha256:0502d1facf1fed4839a9a51ccbcc63d952cf318f78ffc00a7e78528ac27d7a2b \ + --hash=sha256:184eb5e436dea364dcd3d2316d577d625c0351bf237c4e9a5fabbcfa5a58b151 \ + --hash=sha256:3aca44c046bd2ed8c90de9cb8427f581c479e594e99b5c0bb19b29c10fd6cb87 \ + --hash=sha256:3ce80b34b22b17ccbd937a6e78e7225d80c52f5ab9940fe0506a1a16f3dab503 \ + --hash=sha256:62ea666235135fee79bb154e695f3ff67370afefd71bd7fea7512fc70ef31e3d \ + --hash=sha256:6c6f2969607b5023b0d9ce2541f8d2cbb01c4f46bc87456017cf63b73f1e2d8c \ + --hash=sha256:718a38f7e5b058e76aee1c56ddd06908116d35147e133427e59a3983f703a20d \ + --hash=sha256:750ec6e621af2b948540032557b10a2d43b0cee2ae9758c54154d711cc852d31 \ + --hash=sha256:797c2772017851984b97180b0bebe4b620bb86328e8a884bb626156295a63b3b \ + --hash=sha256:7b4075d959648406202d92a2310cb990fea19b535c7f4a78d3f5e10b926eeb8a \ + --hash=sha256:a508e2d9025764a8270f93111a970e1d0fbfc33f4153b388bb649b7eec4f9b42 \ + --hash=sha256:a733f1388e1a842abb67ffa8e7aad0e70ac519e09b0f6a784e65a136ec7cefd2 \ + --hash=sha256:aba8f82d551a942cb20d4a83413ccbac30790b50efb89a75e4f586ac0bb8056b \ + --hash=sha256:b7a2c10b93f8986666d0c803ee19b5990885872a7de910fc460f9b0c2fbf92ee \ + --hash=sha256:b8c095edad5c211ff31c05223658e71bf7116daa0ecf3ad85f3201ea3190d067 \ + --hash=sha256:c8015b09fb9a5e188f83b7b04de91ddca4658cee2ae6f3bc483f0b21a77ef6cd \ + --hash=sha256:d03ff496d2a0cd4a5893504789d4a15399133fe82517455e78bad62efbb7f0a3 \ + --hash=sha256:e0c4cfb0621281fe40387df582097fd796e80430597cb9944f0ae70447bacd91 \ + --hash=sha256:e286f46a9a39c4a18b319c28f59b61de793654af2f395c102b4f819e584b5852 \ + --hash=sha256:f95ba5a847cba10dd8c4d8fefa9f2a6cf283b8b88ed6178fa8a6c1ab16054d0d # via docker -pyyaml==6.0.1 \ - --hash=sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5 \ - --hash=sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc \ - --hash=sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df \ - --hash=sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741 \ - --hash=sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206 \ - --hash=sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27 \ - --hash=sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595 \ - --hash=sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62 \ - --hash=sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98 \ - --hash=sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696 \ - --hash=sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290 \ - --hash=sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9 \ - --hash=sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d \ - --hash=sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6 \ - --hash=sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867 \ - --hash=sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47 \ - --hash=sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486 \ - --hash=sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6 \ - --hash=sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3 \ - --hash=sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007 \ - --hash=sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938 \ - --hash=sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0 \ - --hash=sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c \ - --hash=sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735 \ - --hash=sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d \ - --hash=sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28 \ - --hash=sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4 \ - --hash=sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba \ - --hash=sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8 \ - --hash=sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef \ - --hash=sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5 \ - --hash=sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd \ - --hash=sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3 \ - --hash=sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0 \ - --hash=sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515 \ - --hash=sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c \ - --hash=sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c \ - --hash=sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924 \ - --hash=sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34 \ - --hash=sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43 \ - --hash=sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859 \ - --hash=sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673 \ - --hash=sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54 \ - --hash=sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a \ - --hash=sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b \ - --hash=sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab \ - --hash=sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa \ - --hash=sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c \ - --hash=sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585 \ - --hash=sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d \ - --hash=sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f +pyyaml==6.0.2 \ + --hash=sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff \ + --hash=sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48 \ + --hash=sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086 \ + --hash=sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e \ + --hash=sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133 \ + --hash=sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5 \ + --hash=sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484 \ + --hash=sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee \ + --hash=sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5 \ + --hash=sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68 \ + --hash=sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a \ + --hash=sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf \ + --hash=sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99 \ + --hash=sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8 \ + --hash=sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85 \ + --hash=sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19 \ + --hash=sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc \ + --hash=sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a \ + --hash=sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1 \ + --hash=sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317 \ + --hash=sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c \ + --hash=sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631 \ + --hash=sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d \ + --hash=sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652 \ + --hash=sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5 \ + --hash=sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e \ + --hash=sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b \ + --hash=sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8 \ + --hash=sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476 \ + --hash=sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706 \ + --hash=sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563 \ + --hash=sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237 \ + --hash=sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b \ + --hash=sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083 \ + --hash=sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180 \ + --hash=sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425 \ + --hash=sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e \ + --hash=sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f \ + --hash=sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725 \ + --hash=sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183 \ + --hash=sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab \ + --hash=sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774 \ + --hash=sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725 \ + --hash=sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e \ + --hash=sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5 \ + --hash=sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d \ + --hash=sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290 \ + --hash=sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44 \ + --hash=sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed \ + --hash=sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4 \ + --hash=sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba \ + --hash=sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12 \ + --hash=sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4 # via -r requirements.in referencing==0.36.2 \ --hash=sha256:df2e89862cd09deabbdba16944cc3f10feb6b3e6f18e902f7cc25609a34775aa \ @@ -264,128 +395,168 @@ referencing==0.36.2 \ # via # jsonschema # jsonschema-specifications -requests==2.32.4 \ - --hash=sha256:27babd3cda2a6d50b30443204ee89830707d396671944c998b5975b031ac2b2c \ - --hash=sha256:27d0316682c8a29834d3264820024b62a36942083d52caf2f14c0591336d3422 - # via docker -rpds-py==0.25.1 \ - --hash=sha256:0317177b1e8691ab5879f4f33f4b6dc55ad3b344399e23df2e499de7b10a548d \ - --hash=sha256:036ded36bedb727beeabc16dc1dad7cb154b3fa444e936a03b67a86dc6a5066e \ - --hash=sha256:048893e902132fd6548a2e661fb38bf4896a89eea95ac5816cf443524a85556f \ - --hash=sha256:0701942049095741a8aeb298a31b203e735d1c61f4423511d2b1a41dcd8a16da \ - --hash=sha256:083a9513a33e0b92cf6e7a6366036c6bb43ea595332c1ab5c8ae329e4bcc0a9c \ - --hash=sha256:09eab132f41bf792c7a0ea1578e55df3f3e7f61888e340779b06050a9a3f16e9 \ - --hash=sha256:0e6a327af8ebf6baba1c10fadd04964c1965d375d318f4435d5f3f9651550f4a \ - --hash=sha256:0eb90e94f43e5085623932b68840b6f379f26db7b5c2e6bcef3179bd83c9330f \ - --hash=sha256:114a07e85f32b125404f28f2ed0ba431685151c037a26032b213c882f26eb908 \ - --hash=sha256:115874ae5e2fdcfc16b2aedc95b5eef4aebe91b28e7e21951eda8a5dc0d3461b \ - --hash=sha256:140f61d9bed7839446bdd44852e30195c8e520f81329b4201ceead4d64eb3a9f \ - --hash=sha256:1521031351865e0181bc585147624d66b3b00a84109b57fcb7a779c3ec3772cd \ - --hash=sha256:1c0c434a53714358532d13539272db75a5ed9df75a4a090a753ac7173ec14e11 \ - --hash=sha256:1d1fadd539298e70cac2f2cb36f5b8a65f742b9b9f1014dd4ea1f7785e2470bf \ - --hash=sha256:1de336a4b164c9188cb23f3703adb74a7623ab32d20090d0e9bf499a2203ad65 \ - --hash=sha256:1ee3e26eb83d39b886d2cb6e06ea701bba82ef30a0de044d34626ede51ec98b0 \ - --hash=sha256:245550f5a1ac98504147cba96ffec8fabc22b610742e9150138e5d60774686d7 \ - --hash=sha256:2a40046a529cc15cef88ac5ab589f83f739e2d332cb4d7399072242400ed68c9 \ - --hash=sha256:2c2cd1a4b0c2b8c5e31ffff50d09f39906fe351389ba143c195566056c13a7ea \ - --hash=sha256:2cb9e5b5e26fc02c8a4345048cd9998c2aca7c2712bd1b36da0c72ee969a3523 \ - --hash=sha256:33358883a4490287e67a2c391dfaea4d9359860281db3292b6886bf0be3d8692 \ - --hash=sha256:35634369325906bcd01577da4c19e3b9541a15e99f31e91a02d010816b49bfda \ - --hash=sha256:35a8d1a24b5936b35c5003313bc177403d8bdef0f8b24f28b1c4a255f94ea992 \ - --hash=sha256:3af5b4cc10fa41e5bc64e5c198a1b2d2864337f8fcbb9a67e747e34002ce812b \ - --hash=sha256:3bcce0edc1488906c2d4c75c94c70a0417e83920dd4c88fec1078c94843a6ce9 \ - --hash=sha256:3c5b317ecbd8226887994852e85de562f7177add602514d4ac40f87de3ae45a8 \ - --hash=sha256:3c6564c0947a7f52e4792983f8e6cf9bac140438ebf81f527a21d944f2fd0a40 \ - --hash=sha256:3ebd879ab996537fc510a2be58c59915b5dd63bccb06d1ef514fee787e05984a \ - --hash=sha256:3f0b1798cae2bbbc9b9db44ee068c556d4737911ad53a4e5093d09d04b3bbc24 \ - --hash=sha256:401ca1c4a20cc0510d3435d89c069fe0a9ae2ee6495135ac46bdd49ec0495763 \ - --hash=sha256:454601988aab2c6e8fd49e7634c65476b2b919647626208e376afcd22019eeb8 \ - --hash=sha256:4593c4eae9b27d22df41cde518b4b9e4464d139e4322e2127daa9b5b981b76be \ - --hash=sha256:45e484db65e5380804afbec784522de84fa95e6bb92ef1bd3325d33d13efaebd \ - --hash=sha256:48d64155d02127c249695abb87d39f0faf410733428d499867606be138161d65 \ - --hash=sha256:4fbb0dbba559959fcb5d0735a0f87cdbca9e95dac87982e9b95c0f8f7ad10255 \ - --hash=sha256:4fd52d3455a0aa997734f3835cbc4c9f32571345143960e7d7ebfe7b5fbfa3b2 \ - --hash=sha256:50f2c501a89c9a5f4e454b126193c5495b9fb441a75b298c60591d8a2eb92e1b \ - --hash=sha256:58f77c60956501a4a627749a6dcb78dac522f249dd96b5c9f1c6af29bfacfb66 \ - --hash=sha256:5a3ddb74b0985c4387719fc536faced33cadf2172769540c62e2a94b7b9be1c4 \ - --hash=sha256:5c4a128527fe415d73cf1f70a9a688d06130d5810be69f3b553bf7b45e8acf79 \ - --hash=sha256:5d473be2b13600b93a5675d78f59e63b51b1ba2d0476893415dfbb5477e65b31 \ - --hash=sha256:5d9e40f32745db28c1ef7aad23f6fc458dc1e29945bd6781060f0d15628b8ddf \ - --hash=sha256:5f048bbf18b1f9120685c6d6bb70cc1a52c8cc11bdd04e643d28d3be0baf666d \ - --hash=sha256:605ffe7769e24b1800b4d024d24034405d9404f0bc2f55b6db3362cd34145a6f \ - --hash=sha256:6099263f526efff9cf3883dfef505518730f7a7a93049b1d90d42e50a22b4793 \ - --hash=sha256:659d87430a8c8c704d52d094f5ba6fa72ef13b4d385b7e542a08fc240cb4a559 \ - --hash=sha256:666fa7b1bd0a3810a7f18f6d3a25ccd8866291fbbc3c9b912b917a6715874bb9 \ - --hash=sha256:68f6f060f0bbdfb0245267da014d3a6da9be127fe3e8cc4a68c6f833f8a23bb1 \ - --hash=sha256:6d273f136e912aa101a9274c3145dcbddbe4bac560e77e6d5b3c9f6e0ed06d34 \ - --hash=sha256:6d50841c425d16faf3206ddbba44c21aa3310a0cebc3c1cdfc3e3f4f9f6f5728 \ - --hash=sha256:771c16060ff4e79584dc48902a91ba79fd93eade3aa3a12d6d2a4aadaf7d542b \ - --hash=sha256:785ffacd0ee61c3e60bdfde93baa6d7c10d86f15655bd706c89da08068dc5038 \ - --hash=sha256:796ad874c89127c91970652a4ee8b00d56368b7e00d3477f4415fe78164c8000 \ - --hash=sha256:79dc317a5f1c51fd9c6a0c4f48209c6b8526d0524a6904fc1076476e79b00f98 \ - --hash=sha256:7c9409b47ba0650544b0bb3c188243b83654dfe55dcc173a86832314e1a6a35d \ - --hash=sha256:7d779b325cc8238227c47fbc53964c8cc9a941d5dbae87aa007a1f08f2f77b23 \ - --hash=sha256:816568614ecb22b18a010c7a12559c19f6fe993526af88e95a76d5a60b8b75fb \ - --hash=sha256:8378fa4a940f3fb509c081e06cb7f7f2adae8cf46ef258b0e0ed7519facd573e \ - --hash=sha256:85608eb70a659bf4c1142b2781083d4b7c0c4e2c90eff11856a9754e965b2540 \ - --hash=sha256:85fc223d9c76cabe5d0bff82214459189720dc135db45f9f66aa7cffbf9ff6c1 \ - --hash=sha256:88ec04afe0c59fa64e2f6ea0dd9657e04fc83e38de90f6de201954b4d4eb59bd \ - --hash=sha256:8960b6dac09b62dac26e75d7e2c4a22efb835d827a7278c34f72b2b84fa160e3 \ - --hash=sha256:89706d0683c73a26f76a5315d893c051324d771196ae8b13e6ffa1ffaf5e574f \ - --hash=sha256:89c24300cd4a8e4a51e55c31a8ff3918e6651b241ee8876a42cc2b2a078533ba \ - --hash=sha256:8c742af695f7525e559c16f1562cf2323db0e3f0fbdcabdf6865b095256b2d40 \ - --hash=sha256:8dbd586bfa270c1103ece2109314dd423df1fa3d9719928b5d09e4840cec0d72 \ - --hash=sha256:8eb8c84ecea987a2523e057c0d950bcb3f789696c0499290b8d7b3107a719d78 \ - --hash=sha256:921954d7fbf3fccc7de8f717799304b14b6d9a45bbeec5a8d7408ccbf531faf5 \ - --hash=sha256:9a46c2fb2545e21181445515960006e85d22025bd2fe6db23e76daec6eb689fe \ - --hash=sha256:9c006f3aadeda131b438c3092124bd196b66312f0caa5823ef09585a669cf449 \ - --hash=sha256:9ceca1cf097ed77e1a51f1dbc8d174d10cb5931c188a4505ff9f3e119dfe519b \ - --hash=sha256:9e5fc7484fa7dce57e25063b0ec9638ff02a908304f861d81ea49273e43838c1 \ - --hash=sha256:9f2f48ab00181600ee266a095fe815134eb456163f7d6699f525dee471f312cf \ - --hash=sha256:9fca84a15333e925dd59ce01da0ffe2ffe0d6e5d29a9eeba2148916d1824948c \ - --hash=sha256:a49e1d7a4978ed554f095430b89ecc23f42014a50ac385eb0c4d163ce213c325 \ - --hash=sha256:a58d1ed49a94d4183483a3ce0af22f20318d4a1434acee255d683ad90bf78129 \ - --hash=sha256:a61d0b2c7c9a0ae45732a77844917b427ff16ad5464b4d4f5e4adb955f582890 \ - --hash=sha256:a714bf6e5e81b0e570d01f56e0c89c6375101b8463999ead3a93a5d2a4af91fa \ - --hash=sha256:a7b74e92a3b212390bdce1d93da9f6488c3878c1d434c5e751cbc202c5e09500 \ - --hash=sha256:a8bd2f19e312ce3e1d2c635618e8a8d8132892bb746a7cf74780a489f0f6cdcb \ - --hash=sha256:b0be9965f93c222fb9b4cc254235b3b2b215796c03ef5ee64f995b1b69af0762 \ - --hash=sha256:b24bf3cd93d5b6ecfbedec73b15f143596c88ee249fa98cefa9a9dc9d92c6f28 \ - --hash=sha256:b5ffe453cde61f73fea9430223c81d29e2fbf412a6073951102146c84e19e34c \ - --hash=sha256:bc120d1132cff853ff617754196d0ac0ae63befe7c8498bd67731ba368abe451 \ - --hash=sha256:bd035756830c712b64725a76327ce80e82ed12ebab361d3a1cdc0f51ea21acb0 \ - --hash=sha256:bffcf57826d77a4151962bf1701374e0fc87f536e56ec46f1abdd6a903354042 \ - --hash=sha256:c2013ee878c76269c7b557a9a9c042335d732e89d482606990b70a839635feb7 \ - --hash=sha256:c4feb9211d15d9160bc85fa72fed46432cdc143eb9cf6d5ca377335a921ac37b \ - --hash=sha256:c8980cde3bb8575e7c956a530f2c217c1d6aac453474bf3ea0f9c89868b531b6 \ - --hash=sha256:c98f126c4fc697b84c423e387337d5b07e4a61e9feac494362a59fd7a2d9ed80 \ - --hash=sha256:ccc6f3ddef93243538be76f8e47045b4aad7a66a212cd3a0f23e34469473d36b \ - --hash=sha256:ccfa689b9246c48947d31dd9d8b16d89a0ecc8e0e26ea5253068efb6c542b76e \ - --hash=sha256:cda776f1967cb304816173b30994faaf2fd5bcb37e73118a47964a02c348e1bc \ - --hash=sha256:ce4c8e485a3c59593f1a6f683cf0ea5ab1c1dc94d11eea5619e4fb5228b40fbd \ - --hash=sha256:d3c10228d6cf6fe2b63d2e7985e94f6916fa46940df46b70449e9ff9297bd3d1 \ - --hash=sha256:d4ca54b9cf9d80b4016a67a0193ebe0bcf29f6b0a96f09db942087e294d3d4c2 \ - --hash=sha256:d4cb2b3ddc16710548801c6fcc0cfcdeeff9dafbc983f77265877793f2660309 \ - --hash=sha256:d50e4864498a9ab639d6d8854b25e80642bd362ff104312d9770b05d66e5fb13 \ - --hash=sha256:d74ec9bc0e2feb81d3f16946b005748119c0f52a153f6db6a29e8cd68636f295 \ - --hash=sha256:d8222acdb51a22929c3b2ddb236b69c59c72af4019d2cba961e2f9add9b6e634 \ - --hash=sha256:db58483f71c5db67d643857404da360dce3573031586034b7d59f245144cc192 \ - --hash=sha256:dc3c1ff0abc91444cd20ec643d0f805df9a3661fcacf9c95000329f3ddf268a4 \ - --hash=sha256:dd326a81afe332ede08eb39ab75b301d5676802cdffd3a8f287a5f0b694dc3f5 \ - --hash=sha256:dec21e02e6cc932538b5203d3a8bd6aa1480c98c4914cb88eea064ecdbc6396a \ - --hash=sha256:e1dafef8df605fdb46edcc0bf1573dea0d6d7b01ba87f85cd04dc855b2b4479e \ - --hash=sha256:e2f6a2347d3440ae789505693a02836383426249d5293541cd712e07e7aecf54 \ - --hash=sha256:e37caa8cdb3b7cf24786451a0bdb853f6347b8b92005eeb64225ae1db54d1c2b \ - --hash=sha256:e43a005671a9ed5a650f3bc39e4dbccd6d4326b24fb5ea8be5f3a43a6f576c72 \ - --hash=sha256:e5e2f7280d8d0d3ef06f3ec1b4fd598d386cc6f0721e54f09109a8132182fbfe \ - --hash=sha256:e87798852ae0b37c88babb7f7bbbb3e3fecc562a1c340195b44c7e24d403e380 \ - --hash=sha256:ee86d81551ec68a5c25373c5643d343150cc54672b5e9a0cafc93c1870a53954 \ - --hash=sha256:f251bf23deb8332823aef1da169d5d89fa84c89f67bdfb566c49dea1fccfd50d \ - --hash=sha256:f3d86373ff19ca0441ebeb696ef64cb58b8b5cbacffcda5a0ec2f3911732a194 \ - --hash=sha256:f4ad628b5174d5315761b67f212774a32f5bad5e61396d38108bd801c0a8f5d9 \ - --hash=sha256:f70316f760174ca04492b5ab01be631a8ae30cadab1d1081035136ba12738cfa \ - --hash=sha256:f73ce1512e04fbe2bc97836e89830d6b4314c171587a99688082d090f934d20a \ - --hash=sha256:ff7c23ba0a88cb7b104281a99476cccadf29de2a0ef5ce864959a52675b1ca83 +requests==2.32.5 \ + --hash=sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6 \ + --hash=sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf + # via + # docker + # pygithub +rpds-py==0.27.0 \ + --hash=sha256:010c4843a3b92b54373e3d2291a7447d6c3fc29f591772cc2ea0e9f5c1da434b \ + --hash=sha256:05284439ebe7d9f5f5a668d4d8a0a1d851d16f7d47c78e1fab968c8ad30cab04 \ + --hash=sha256:0665be515767dc727ffa5f74bd2ef60b0ff85dad6bb8f50d91eaa6b5fb226f51 \ + --hash=sha256:069e0384a54f427bd65d7fda83b68a90606a3835901aaff42185fcd94f5a9295 \ + --hash=sha256:08680820d23df1df0a0260f714d12966bc6c42d02e8055a91d61e03f0c47dda0 \ + --hash=sha256:0954e3a92e1d62e83a54ea7b3fdc9efa5d61acef8488a8a3d31fdafbfb00460d \ + --hash=sha256:09965b314091829b378b60607022048953e25f0b396c2b70e7c4c81bcecf932e \ + --hash=sha256:0c431bfb91478d7cbe368d0a699978050d3b112d7f1d440a41e90faa325557fd \ + --hash=sha256:0f401c369186a5743694dd9fc08cba66cf70908757552e1f714bfc5219c655b5 \ + --hash=sha256:0f4f69d7a4300fbf91efb1fb4916421bd57804c01ab938ab50ac9c4aa2212f03 \ + --hash=sha256:11e8e28c0ba0373d052818b600474cfee2fafa6c9f36c8587d217b13ee28ca7d \ + --hash=sha256:130c1ffa5039a333f5926b09e346ab335f0d4ec393b030a18549a7c7e7c2cea4 \ + --hash=sha256:1321bce595ad70e80f97f998db37356b2e22cf98094eba6fe91782e626da2f71 \ + --hash=sha256:13bbc4846ae4c993f07c93feb21a24d8ec637573d567a924b1001e81c8ae80f9 \ + --hash=sha256:14f028eb47f59e9169bfdf9f7ceafd29dd64902141840633683d0bad5b04ff34 \ + --hash=sha256:15ea4d2e182345dd1b4286593601d766411b43f868924afe297570658c31a62b \ + --hash=sha256:181bc29e59e5e5e6e9d63b143ff4d5191224d355e246b5a48c88ce6b35c4e466 \ + --hash=sha256:183f5e221ba3e283cd36fdfbe311d95cd87699a083330b4f792543987167eff1 \ + --hash=sha256:184f0d7b342967f6cda94a07d0e1fae177d11d0b8f17d73e06e36ac02889f303 \ + --hash=sha256:190d7285cd3bb6d31d37a0534d7359c1ee191eb194c511c301f32a4afa5a1dd4 \ + --hash=sha256:19c990fdf5acecbf0623e906ae2e09ce1c58947197f9bced6bbd7482662231c4 \ + --hash=sha256:1d66f45b9399036e890fb9c04e9f70c33857fd8f58ac8db9f3278cfa835440c3 \ + --hash=sha256:203f581accef67300a942e49a37d74c12ceeef4514874c7cede21b012613ca2c \ + --hash=sha256:20e222a44ae9f507d0f2678ee3dd0c45ec1e930f6875d99b8459631c24058aec \ + --hash=sha256:2406d034635d1497c596c40c85f86ecf2bf9611c1df73d14078af8444fe48031 \ + --hash=sha256:249ab91ceaa6b41abc5f19513cb95b45c6f956f6b89f1fe3d99c81255a849f9e \ + --hash=sha256:25a4aebf8ca02bbb90a9b3e7a463bbf3bee02ab1c446840ca07b1695a68ce424 \ + --hash=sha256:27bac29bbbf39601b2aab474daf99dbc8e7176ca3389237a23944b17f8913d97 \ + --hash=sha256:299a245537e697f28a7511d01038c310ac74e8ea213c0019e1fc65f52c0dcb23 \ + --hash=sha256:2cff9bdd6c7b906cc562a505c04a57d92e82d37200027e8d362518df427f96cd \ + --hash=sha256:2e307cb5f66c59ede95c00e93cd84190a5b7f3533d7953690b2036780622ba81 \ + --hash=sha256:2e39169ac6aae06dd79c07c8a69d9da867cef6a6d7883a0186b46bb46ccfb0c3 \ + --hash=sha256:2fe6e18e5c8581f0361b35ae575043c7029d0a92cb3429e6e596c2cdde251432 \ + --hash=sha256:3001013dae10f806380ba739d40dee11db1ecb91684febb8406a87c2ded23dae \ + --hash=sha256:32196b5a99821476537b3f7732432d64d93a58d680a52c5e12a190ee0135d8b5 \ + --hash=sha256:33ba649a6e55ae3808e4c39e01580dc9a9b0d5b02e77b66bb86ef117922b1264 \ + --hash=sha256:341d8acb6724c0c17bdf714319c393bb27f6d23d39bc74f94221b3e59fc31828 \ + --hash=sha256:343cf24de9ed6c728abefc5d5c851d5de06497caa7ac37e5e65dd572921ed1b5 \ + --hash=sha256:36184b44bf60a480863e51021c26aca3dfe8dd2f5eeabb33622b132b9d8b8b54 \ + --hash=sha256:3841f66c1ffdc6cebce8aed64e36db71466f1dc23c0d9a5592e2a782a3042c79 \ + --hash=sha256:4045e2fc4b37ec4b48e8907a5819bdd3380708c139d7cc358f03a3653abedb89 \ + --hash=sha256:419dd9c98bcc9fb0242be89e0c6e922df333b975d4268faa90d58499fd9c9ebe \ + --hash=sha256:42894616da0fc0dcb2ec08a77896c3f56e9cb2f4b66acd76fc8992c3557ceb1c \ + --hash=sha256:42ccc57ff99166a55a59d8c7d14f1a357b7749f9ed3584df74053fd098243451 \ + --hash=sha256:4300e15e7d03660f04be84a125d1bdd0e6b2f674bc0723bc0fd0122f1a4585dc \ + --hash=sha256:443d239d02d9ae55b74015234f2cd8eb09e59fbba30bf60baeb3123ad4c6d5ff \ + --hash=sha256:44524b96481a4c9b8e6c46d6afe43fa1fb485c261e359fbe32b63ff60e3884d8 \ + --hash=sha256:45d04a73c54b6a5fd2bab91a4b5bc8b426949586e61340e212a8484919183859 \ + --hash=sha256:46f48482c1a4748ab2773f75fffbdd1951eb59794e32788834b945da857c47a8 \ + --hash=sha256:4790c9d5dd565ddb3e9f656092f57268951398cef52e364c405ed3112dc7c7c1 \ + --hash=sha256:4bc262ace5a1a7dc3e2eac2fa97b8257ae795389f688b5adf22c5db1e2431c43 \ + --hash=sha256:4c3f8a0d4802df34fcdbeb3dfe3a4d8c9a530baea8fafdf80816fcaac5379d83 \ + --hash=sha256:5355527adaa713ab693cbce7c1e0ec71682f599f61b128cf19d07e5c13c9b1f1 \ + --hash=sha256:555ed147cbe8c8f76e72a4c6cd3b7b761cbf9987891b9448808148204aed74a5 \ + --hash=sha256:55d42a0ef2bdf6bc81e1cc2d49d12460f63c6ae1423c4f4851b828e454ccf6f1 \ + --hash=sha256:59195dc244fc183209cf8a93406889cadde47dfd2f0a6b137783aa9c56d67c85 \ + --hash=sha256:59714ab0a5af25d723d8e9816638faf7f4254234decb7d212715c1aa71eee7be \ + --hash=sha256:5b3a5c8089eed498a3af23ce87a80805ff98f6ef8f7bdb70bd1b7dae5105f6ac \ + --hash=sha256:5d6790ff400254137b81b8053b34417e2c46921e302d655181d55ea46df58cf7 \ + --hash=sha256:5df559e9e7644d9042f626f2c3997b555f347d7a855a15f170b253f6c5bfe358 \ + --hash=sha256:5fa01b3d5e3b7d97efab65bd3d88f164e289ec323a8c033c5c38e53ee25c007e \ + --hash=sha256:61490d57e82e23b45c66f96184237994bfafa914433b8cd1a9bb57fecfced59d \ + --hash=sha256:6168af0be75bba990a39f9431cdfae5f0ad501f4af32ae62e8856307200517b8 \ + --hash=sha256:64a0fe3f334a40b989812de70160de6b0ec7e3c9e4a04c0bbc48d97c5d3600ae \ + --hash=sha256:64f689ab822f9b5eb6dfc69893b4b9366db1d2420f7db1f6a2adf2a9ca15ad64 \ + --hash=sha256:699c346abc73993962cac7bb4f02f58e438840fa5458a048d3a178a7a670ba86 \ + --hash=sha256:6b96b0b784fe5fd03beffff2b1533dc0d85e92bab8d1b2c24ef3a5dc8fac5669 \ + --hash=sha256:6bde37765564cd22a676dd8101b657839a1854cfaa9c382c5abf6ff7accfd4ae \ + --hash=sha256:6c135708e987f46053e0a1246a206f53717f9fadfba27174a9769ad4befba5c3 \ + --hash=sha256:6c27a7054b5224710fcfb1a626ec3ff4f28bcb89b899148c72873b18210e446b \ + --hash=sha256:6de6a7f622860af0146cb9ee148682ff4d0cea0b8fd3ad51ce4d40efb2f061d0 \ + --hash=sha256:737005088449ddd3b3df5a95476ee1c2c5c669f5c30eed909548a92939c0e12d \ + --hash=sha256:7451ede3560086abe1aa27dcdcf55cd15c96b56f543fb12e5826eee6f721f858 \ + --hash=sha256:7873b65686a6471c0037139aa000d23fe94628e0daaa27b6e40607c90e3f5ec4 \ + --hash=sha256:79af163a4b40bbd8cfd7ca86ec8b54b81121d3b213b4435ea27d6568bcba3e9d \ + --hash=sha256:7aed8118ae20515974650d08eb724150dc2e20c2814bcc307089569995e88a14 \ + --hash=sha256:7cf9bc4508efb18d8dff6934b602324eb9f8c6644749627ce001d6f38a490889 \ + --hash=sha256:7e57906e38583a2cba67046a09c2637e23297618dc1f3caddbc493f2be97c93f \ + --hash=sha256:7ec85994f96a58cf7ed288caa344b7fe31fd1d503bdf13d7331ead5f70ab60d5 \ + --hash=sha256:81f81bbd7cdb4bdc418c09a73809abeda8f263a6bf8f9c7f93ed98b5597af39d \ + --hash=sha256:86aca1616922b40d8ac1b3073a1ead4255a2f13405e5700c01f7c8d29a03972d \ + --hash=sha256:88051c3b7d5325409f433c5a40328fcb0685fc04e5db49ff936e910901d10114 \ + --hash=sha256:887ab1f12b0d227e9260558a4a2320024b20102207ada65c43e1ffc4546df72e \ + --hash=sha256:8a06aa1197ec0281eb1d7daf6073e199eb832fe591ffa329b88bae28f25f5fe5 \ + --hash=sha256:8a1dca5507fa1337f75dcd5070218b20bc68cf8844271c923c1b79dfcbc20391 \ + --hash=sha256:8b23cf252f180cda89220b378d917180f29d313cd6a07b2431c0d3b776aae86f \ + --hash=sha256:8d0e09cf4863c74106b5265c2c310f36146e2b445ff7b3018a56799f28f39f6f \ + --hash=sha256:8de567dec6d451649a781633d36f5c7501711adee329d76c095be2178855b042 \ + --hash=sha256:90fb790138c1a89a2e58c9282fe1089638401f2f3b8dddd758499041bc6e0774 \ + --hash=sha256:92f3b3ec3e6008a1fe00b7c0946a170f161ac00645cde35e3c9a68c2475e8156 \ + --hash=sha256:935afcdea4751b0ac918047a2df3f720212892347767aea28f5b3bf7be4f27c0 \ + --hash=sha256:9a0ff7ee28583ab30a52f371b40f54e7138c52ca67f8ca17ccb7ccf0b383cb5f \ + --hash=sha256:9ad08547995a57e74fea6abaf5940d399447935faebbd2612b3b0ca6f987946b \ + --hash=sha256:9b2a4e17bfd68536c3b801800941c95a1d4a06e3cada11c146093ba939d9638d \ + --hash=sha256:9b78430703cfcf5f5e86eb74027a1ed03a93509273d7c705babb547f03e60016 \ + --hash=sha256:9d0f92b78cfc3b74a42239fdd8c1266f4715b573204c234d2f9fc3fc7a24f185 \ + --hash=sha256:9da162b718b12c4219eeeeb68a5b7552fbc7aadedf2efee440f88b9c0e54b45d \ + --hash=sha256:a00c91104c173c9043bc46f7b30ee5e6d2f6b1149f11f545580f5d6fdff42c0b \ + --hash=sha256:a029be818059870664157194e46ce0e995082ac49926f1423c1f058534d2aaa9 \ + --hash=sha256:a1b3db5fae5cbce2131b7420a3f83553d4d89514c03d67804ced36161fe8b6b2 \ + --hash=sha256:a4cf32a26fa744101b67bfd28c55d992cd19438aff611a46cac7f066afca8fd4 \ + --hash=sha256:aa0bf113d15e8abdfee92aa4db86761b709a09954083afcb5bf0f952d6065fdb \ + --hash=sha256:ab47fe727c13c09d0e6f508e3a49e545008e23bf762a245b020391b621f5b726 \ + --hash=sha256:af22763a0a1eff106426a6e1f13c4582e0d0ad89c1493ab6c058236174cd6c6a \ + --hash=sha256:af9d4fd79ee1cc8e7caf693ee02737daabfc0fcf2773ca0a4735b356c8ad6f7c \ + --hash=sha256:b1fef1f13c842a39a03409e30ca0bf87b39a1e2a305a9924deadb75a43105d23 \ + --hash=sha256:b2eff8ee57c5996b0d2a07c3601fb4ce5fbc37547344a26945dd9e5cbd1ed27a \ + --hash=sha256:b4c4fbbcff474e1e5f38be1bf04511c03d492d42eec0babda5d03af3b5589374 \ + --hash=sha256:b8a4131698b6992b2a56015f51646711ec5d893a0b314a4b985477868e240c87 \ + --hash=sha256:b8a7acf04fda1f30f1007f3cc96d29d8cf0a53e626e4e1655fdf4eabc082d367 \ + --hash=sha256:ba783541be46f27c8faea5a6645e193943c17ea2f0ffe593639d906a327a9bcc \ + --hash=sha256:be0744661afbc4099fef7f4e604e7f1ea1be1dd7284f357924af12a705cc7d5c \ + --hash=sha256:be3964f7312ea05ed283b20f87cb533fdc555b2e428cc7be64612c0b2124f08c \ + --hash=sha256:be806e2961cd390a89d6c3ce8c2ae34271cfcd05660f716257838bb560f1c3b6 \ + --hash=sha256:bec77545d188f8bdd29d42bccb9191682a46fb2e655e3d1fb446d47c55ac3b8d \ + --hash=sha256:c10d92fb6d7fd827e44055fcd932ad93dac6a11e832d51534d77b97d1d85400f \ + --hash=sha256:c3782fb753aa825b4ccabc04292e07897e2fd941448eabf666856c5530277626 \ + --hash=sha256:c9ce7a9e967afc0a2af7caa0d15a3e9c1054815f73d6a8cb9225b61921b419bd \ + --hash=sha256:cb0702c12983be3b2fab98ead349ac63a98216d28dda6f518f52da5498a27a1b \ + --hash=sha256:cbc619e84a5e3ab2d452de831c88bdcad824414e9c2d28cd101f94dbdf26329c \ + --hash=sha256:ce4ed8e0c7dbc5b19352b9c2c6131dd23b95fa8698b5cdd076307a33626b72dc \ + --hash=sha256:ce96ab0bdfcef1b8c371ada2100767ace6804ea35aacce0aef3aeb4f3f499ca8 \ + --hash=sha256:cf824aceaeffff029ccfba0da637d432ca71ab21f13e7f6f5179cd88ebc77a8a \ + --hash=sha256:d2a81bdcfde4245468f7030a75a37d50400ac2455c3a4819d9d550c937f90ab5 \ + --hash=sha256:d2cc2b34f9e1d31ce255174da82902ad75bd7c0d88a33df54a77a22f2ef421ee \ + --hash=sha256:d2f184336bc1d6abfaaa1262ed42739c3789b1e3a65a29916a615307d22ffd2e \ + --hash=sha256:d3c622c39f04d5751408f5b801ecb527e6e0a471b367f420a877f7a660d583f6 \ + --hash=sha256:d7cf5e726b6fa977e428a61880fb108a62f28b6d0c7ef675b117eaff7076df49 \ + --hash=sha256:d85d784c619370d9329bbd670f41ff5f2ae62ea4519761b679d0f57f0f0ee267 \ + --hash=sha256:d93ebdb82363d2e7bec64eecdc3632b59e84bd270d74fe5be1659f7787052f9b \ + --hash=sha256:db8a6313dbac934193fc17fe7610f70cd8181c542a91382531bef5ed785e5615 \ + --hash=sha256:dbc2ab5d10544eb485baa76c63c501303b716a5c405ff2469a1d8ceffaabf622 \ + --hash=sha256:dbd749cff1defbde270ca346b69b3baf5f1297213ef322254bf2a28537f0b046 \ + --hash=sha256:dc662bc9375a6a394b62dfd331874c434819f10ee3902123200dbcf116963f89 \ + --hash=sha256:dc6b0d5a1ea0318ef2def2b6a55dccf1dcaf77d605672347271ed7b829860765 \ + --hash=sha256:dc79d192fb76fc0c84f2c58672c17bbbc383fd26c3cdc29daae16ce3d927e8b2 \ + --hash=sha256:dd2c1d27ebfe6a015cfa2005b7fe8c52d5019f7bbdd801bc6f7499aab9ae739e \ + --hash=sha256:dea0808153f1fbbad772669d906cddd92100277533a03845de6893cadeffc8be \ + --hash=sha256:e0d7151a1bd5d0a203a5008fc4ae51a159a610cb82ab0a9b2c4d80241745582e \ + --hash=sha256:e14aab02258cb776a108107bd15f5b5e4a1bbaa61ef33b36693dfab6f89d54f9 \ + --hash=sha256:e24d8031a2c62f34853756d9208eeafa6b940a1efcbfe36e8f57d99d52bb7261 \ + --hash=sha256:e36c80c49853b3ffda7aa1831bf175c13356b210c73128c861f3aa93c3cc4015 \ + --hash=sha256:e377e4cf8795cdbdff75b8f0223d7b6c68ff4fef36799d88ccf3a995a91c0112 \ + --hash=sha256:e3acb9c16530362aeaef4e84d57db357002dc5cbfac9a23414c3e73c08301ab2 \ + --hash=sha256:e3dc8d4ede2dbae6c0fc2b6c958bf51ce9fd7e9b40c0f5b8835c3fde44f5807d \ + --hash=sha256:e6491658dd2569f05860bad645569145c8626ac231877b0fb2d5f9bcb7054089 \ + --hash=sha256:eb91d252b35004a84670dfeafadb042528b19842a0080d8b53e5ec1128e8f433 \ + --hash=sha256:f0396e894bd1e66c74ecbc08b4f6a03dc331140942c4b1d345dd131b68574a60 \ + --hash=sha256:f09c9d4c26fa79c1bad927efb05aca2391350b8e61c38cbc0d7d3c814e463124 \ + --hash=sha256:f3cd110e02c5bf17d8fb562f6c9df5c20e73029d587cf8602a2da6c5ef1e32cb \ + --hash=sha256:f7a37dd208f0d658e0487522078b1ed68cd6bce20ef4b5a915d2809b9094b410 \ + --hash=sha256:fae4a01ef8c4cb2bbe92ef2063149596907dc4a881a8d26743b3f6b304713171 \ + --hash=sha256:fc327f4497b7087d06204235199daf208fd01c82d80465dc5efa4ec9df1c5b4e \ + --hash=sha256:fcc01c57ce6e70b728af02b2401c5bc853a9e14eb07deda30624374f0aebfe42 \ + --hash=sha256:fde355b02934cc6b07200cc3b27ab0c15870a757d1a72fd401aa92e2ea3c6bfe # via # jsonschema # referencing @@ -427,112 +598,200 @@ tomli==2.2.1 \ --hash=sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a \ --hash=sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7 # via -r requirements.in -typing-extensions==4.13.2 \ - --hash=sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c \ - --hash=sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef - # via -r requirements.in -urllib3==2.4.0 \ - --hash=sha256:414bc6535b787febd7567804cc015fee39daab8ad86268f1310a9250697de466 \ - --hash=sha256:4e16665048960a0900c702d4a66415956a584919c03361cac9f1df5c5dd7e813 +typing-extensions==4.14.1 \ + --hash=sha256:38b39f4aeeab64884ce9f74c94263ef78f3c22467c8724005483154c26648d36 \ + --hash=sha256:d1e1e3b58374dc93031d6eda2420a48ea44a36c2b4766a4fdeb3710755731d76 + # via + # -r requirements.in + # pygithub +urllib3==2.5.0 \ + --hash=sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760 \ + --hash=sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc # via # docker + # pygithub # requests -zstandard==0.23.0 \ - --hash=sha256:034b88913ecc1b097f528e42b539453fa82c3557e414b3de9d5632c80439a473 \ - --hash=sha256:0a7f0804bb3799414af278e9ad51be25edf67f78f916e08afdb983e74161b916 \ - --hash=sha256:11e3bf3c924853a2d5835b24f03eeba7fc9b07d8ca499e247e06ff5676461a15 \ - --hash=sha256:12a289832e520c6bd4dcaad68e944b86da3bad0d339ef7989fb7e88f92e96072 \ - --hash=sha256:1516c8c37d3a053b01c1c15b182f3b5f5eef19ced9b930b684a73bad121addf4 \ - --hash=sha256:157e89ceb4054029a289fb504c98c6a9fe8010f1680de0201b3eb5dc20aa6d9e \ - --hash=sha256:1bfe8de1da6d104f15a60d4a8a768288f66aa953bbe00d027398b93fb9680b26 \ - --hash=sha256:1e172f57cd78c20f13a3415cc8dfe24bf388614324d25539146594c16d78fcc8 \ - --hash=sha256:1fd7e0f1cfb70eb2f95a19b472ee7ad6d9a0a992ec0ae53286870c104ca939e5 \ - --hash=sha256:203d236f4c94cd8379d1ea61db2fce20730b4c38d7f1c34506a31b34edc87bdd \ - --hash=sha256:27d3ef2252d2e62476389ca8f9b0cf2bbafb082a3b6bfe9d90cbcbb5529ecf7c \ - --hash=sha256:29a2bc7c1b09b0af938b7a8343174b987ae021705acabcbae560166567f5a8db \ - --hash=sha256:2ef230a8fd217a2015bc91b74f6b3b7d6522ba48be29ad4ea0ca3a3775bf7dd5 \ - --hash=sha256:2ef3775758346d9ac6214123887d25c7061c92afe1f2b354f9388e9e4d48acfc \ - --hash=sha256:2f146f50723defec2975fb7e388ae3a024eb7151542d1599527ec2aa9cacb152 \ - --hash=sha256:2fb4535137de7e244c230e24f9d1ec194f61721c86ebea04e1581d9d06ea1269 \ - --hash=sha256:32ba3b5ccde2d581b1e6aa952c836a6291e8435d788f656fe5976445865ae045 \ - --hash=sha256:34895a41273ad33347b2fc70e1bff4240556de3c46c6ea430a7ed91f9042aa4e \ - --hash=sha256:379b378ae694ba78cef921581ebd420c938936a153ded602c4fea612b7eaa90d \ - --hash=sha256:38302b78a850ff82656beaddeb0bb989a0322a8bbb1bf1ab10c17506681d772a \ - --hash=sha256:3aa014d55c3af933c1315eb4bb06dd0459661cc0b15cd61077afa6489bec63bb \ - --hash=sha256:4051e406288b8cdbb993798b9a45c59a4896b6ecee2f875424ec10276a895740 \ - --hash=sha256:40b33d93c6eddf02d2c19f5773196068d875c41ca25730e8288e9b672897c105 \ - --hash=sha256:43da0f0092281bf501f9c5f6f3b4c975a8a0ea82de49ba3f7100e64d422a1274 \ - --hash=sha256:445e4cb5048b04e90ce96a79b4b63140e3f4ab5f662321975679b5f6360b90e2 \ - --hash=sha256:48ef6a43b1846f6025dde6ed9fee0c24e1149c1c25f7fb0a0585572b2f3adc58 \ - --hash=sha256:50a80baba0285386f97ea36239855f6020ce452456605f262b2d33ac35c7770b \ - --hash=sha256:519fbf169dfac1222a76ba8861ef4ac7f0530c35dd79ba5727014613f91613d4 \ - --hash=sha256:53dd9d5e3d29f95acd5de6802e909ada8d8d8cfa37a3ac64836f3bc4bc5512db \ - --hash=sha256:53ea7cdc96c6eb56e76bb06894bcfb5dfa93b7adcf59d61c6b92674e24e2dd5e \ - --hash=sha256:576856e8594e6649aee06ddbfc738fec6a834f7c85bf7cadd1c53d4a58186ef9 \ - --hash=sha256:59556bf80a7094d0cfb9f5e50bb2db27fefb75d5138bb16fb052b61b0e0eeeb0 \ - --hash=sha256:5d41d5e025f1e0bccae4928981e71b2334c60f580bdc8345f824e7c0a4c2a813 \ - --hash=sha256:61062387ad820c654b6a6b5f0b94484fa19515e0c5116faf29f41a6bc91ded6e \ - --hash=sha256:61f89436cbfede4bc4e91b4397eaa3e2108ebe96d05e93d6ccc95ab5714be512 \ - --hash=sha256:62136da96a973bd2557f06ddd4e8e807f9e13cbb0bfb9cc06cfe6d98ea90dfe0 \ - --hash=sha256:64585e1dba664dc67c7cdabd56c1e5685233fbb1fc1966cfba2a340ec0dfff7b \ - --hash=sha256:65308f4b4890aa12d9b6ad9f2844b7ee42c7f7a4fd3390425b242ffc57498f48 \ - --hash=sha256:66b689c107857eceabf2cf3d3fc699c3c0fe8ccd18df2219d978c0283e4c508a \ - --hash=sha256:6a41c120c3dbc0d81a8e8adc73312d668cd34acd7725f036992b1b72d22c1772 \ - --hash=sha256:6f77fa49079891a4aab203d0b1744acc85577ed16d767b52fc089d83faf8d8ed \ - --hash=sha256:72c68dda124a1a138340fb62fa21b9bf4848437d9ca60bd35db36f2d3345f373 \ - --hash=sha256:752bf8a74412b9892f4e5b58f2f890a039f57037f52c89a740757ebd807f33ea \ - --hash=sha256:76e79bc28a65f467e0409098fa2c4376931fd3207fbeb6b956c7c476d53746dd \ - --hash=sha256:774d45b1fac1461f48698a9d4b5fa19a69d47ece02fa469825b442263f04021f \ - --hash=sha256:77da4c6bfa20dd5ea25cbf12c76f181a8e8cd7ea231c673828d0386b1740b8dc \ - --hash=sha256:77ea385f7dd5b5676d7fd943292ffa18fbf5c72ba98f7d09fc1fb9e819b34c23 \ - --hash=sha256:80080816b4f52a9d886e67f1f96912891074903238fe54f2de8b786f86baded2 \ - --hash=sha256:80a539906390591dd39ebb8d773771dc4db82ace6372c4d41e2d293f8e32b8db \ - --hash=sha256:82d17e94d735c99621bf8ebf9995f870a6b3e6d14543b99e201ae046dfe7de70 \ - --hash=sha256:837bb6764be6919963ef41235fd56a6486b132ea64afe5fafb4cb279ac44f259 \ - --hash=sha256:84433dddea68571a6d6bd4fbf8ff398236031149116a7fff6f777ff95cad3df9 \ - --hash=sha256:8c24f21fa2af4bb9f2c492a86fe0c34e6d2c63812a839590edaf177b7398f700 \ - --hash=sha256:8ed7d27cb56b3e058d3cf684d7200703bcae623e1dcc06ed1e18ecda39fee003 \ - --hash=sha256:9206649ec587e6b02bd124fb7799b86cddec350f6f6c14bc82a2b70183e708ba \ - --hash=sha256:983b6efd649723474f29ed42e1467f90a35a74793437d0bc64a5bf482bedfa0a \ - --hash=sha256:98da17ce9cbf3bfe4617e836d561e433f871129e3a7ac16d6ef4c680f13a839c \ - --hash=sha256:9c236e635582742fee16603042553d276cca506e824fa2e6489db04039521e90 \ - --hash=sha256:9da6bc32faac9a293ddfdcb9108d4b20416219461e4ec64dfea8383cac186690 \ - --hash=sha256:a05e6d6218461eb1b4771d973728f0133b2a4613a6779995df557f70794fd60f \ - --hash=sha256:a0817825b900fcd43ac5d05b8b3079937073d2b1ff9cf89427590718b70dd840 \ - --hash=sha256:a4ae99c57668ca1e78597d8b06d5af837f377f340f4cce993b551b2d7731778d \ - --hash=sha256:a8c86881813a78a6f4508ef9daf9d4995b8ac2d147dcb1a450448941398091c9 \ - --hash=sha256:a8fffdbd9d1408006baaf02f1068d7dd1f016c6bcb7538682622c556e7b68e35 \ - --hash=sha256:a9b07268d0c3ca5c170a385a0ab9fb7fdd9f5fd866be004c4ea39e44edce47dd \ - --hash=sha256:ab19a2d91963ed9e42b4e8d77cd847ae8381576585bad79dbd0a8837a9f6620a \ - --hash=sha256:ac184f87ff521f4840e6ea0b10c0ec90c6b1dcd0bad2f1e4a9a1b4fa177982ea \ - --hash=sha256:b0e166f698c5a3e914947388c162be2583e0c638a4703fc6a543e23a88dea3c1 \ - --hash=sha256:b2170c7e0367dde86a2647ed5b6f57394ea7f53545746104c6b09fc1f4223573 \ - --hash=sha256:b2d8c62d08e7255f68f7a740bae85b3c9b8e5466baa9cbf7f57f1cde0ac6bc09 \ - --hash=sha256:b4567955a6bc1b20e9c31612e615af6b53733491aeaa19a6b3b37f3b65477094 \ - --hash=sha256:b69bb4f51daf461b15e7b3db033160937d3ff88303a7bc808c67bbc1eaf98c78 \ - --hash=sha256:b8c0bd73aeac689beacd4e7667d48c299f61b959475cdbb91e7d3d88d27c56b9 \ - --hash=sha256:be9b5b8659dff1f913039c2feee1aca499cfbc19e98fa12bc85e037c17ec6ca5 \ - --hash=sha256:bf0a05b6059c0528477fba9054d09179beb63744355cab9f38059548fedd46a9 \ - --hash=sha256:c16842b846a8d2a145223f520b7e18b57c8f476924bda92aeee3a88d11cfc391 \ - --hash=sha256:c363b53e257246a954ebc7c488304b5592b9c53fbe74d03bc1c64dda153fb847 \ - --hash=sha256:c7c517d74bea1a6afd39aa612fa025e6b8011982a0897768a2f7c8ab4ebb78a2 \ - --hash=sha256:d20fd853fbb5807c8e84c136c278827b6167ded66c72ec6f9a14b863d809211c \ - --hash=sha256:d2240ddc86b74966c34554c49d00eaafa8200a18d3a5b6ffbf7da63b11d74ee2 \ - --hash=sha256:d477ed829077cd945b01fc3115edd132c47e6540ddcd96ca169facff28173057 \ - --hash=sha256:d50d31bfedd53a928fed6707b15a8dbeef011bb6366297cc435accc888b27c20 \ - --hash=sha256:dc1d33abb8a0d754ea4763bad944fd965d3d95b5baef6b121c0c9013eaf1907d \ - --hash=sha256:dc5d1a49d3f8262be192589a4b72f0d03b72dcf46c51ad5852a4fdc67be7b9e4 \ - --hash=sha256:e2d1a054f8f0a191004675755448d12be47fa9bebbcffa3cdf01db19f2d30a54 \ - --hash=sha256:e7792606d606c8df5277c32ccb58f29b9b8603bf83b48639b7aedf6df4fe8171 \ - --hash=sha256:ed1708dbf4d2e3a1c5c69110ba2b4eb6678262028afd6c6fbcc5a8dac9cda68e \ - --hash=sha256:f2d4380bf5f62daabd7b751ea2339c1a21d1c9463f1feb7fc2bdcea2c29c3160 \ - --hash=sha256:f3513916e8c645d0610815c257cbfd3242adfd5c4cfa78be514e5a3ebb42a41b \ - --hash=sha256:f8346bfa098532bc1fb6c7ef06783e969d87a99dd1d2a5a18a892c1d7a643c58 \ - --hash=sha256:f83fa6cae3fff8e98691248c9320356971b59678a17f20656a9e59cd32cee6d8 \ - --hash=sha256:fa6ce8b52c5987b3e34d5674b0ab529a4602b632ebab0a93b07bfb4dfc8f8a33 \ - --hash=sha256:fb2b1ecfef1e67897d336de3a0e3f52478182d6a47eda86cbd42504c5cbd009a \ - --hash=sha256:fc9ca1c9718cb3b06634c7c8dec57d24e9438b2aa9a0f02b8bb36bf478538880 \ - --hash=sha256:fd30d9c67d13d891f2360b2a120186729c111238ac63b43dbd37a5a40670b8ca \ - --hash=sha256:fd7699e8fd9969f455ef2926221e0233f81a2542921471382e77a9e2f2b57f4b \ - --hash=sha256:fe3b385d996ee0822fd46528d9f0443b880d4d05528fd26a9119a54ec3f91c69 +wrapt==1.17.3 \ + --hash=sha256:02b551d101f31694fc785e58e0720ef7d9a10c4e62c1c9358ce6f63f23e30a56 \ + --hash=sha256:042ec3bb8f319c147b1301f2393bc19dba6e176b7da446853406d041c36c7828 \ + --hash=sha256:0610b46293c59a3adbae3dee552b648b984176f8562ee0dba099a56cfbe4df1f \ + --hash=sha256:0b02e424deef65c9f7326d8c19220a2c9040c51dc165cddb732f16198c168396 \ + --hash=sha256:0b1831115c97f0663cb77aa27d381237e73ad4f721391a9bfb2fe8bc25fa6e77 \ + --hash=sha256:0ed61b7c2d49cee3c027372df5809a59d60cf1b6c2f81ee980a091f3afed6a2d \ + --hash=sha256:0f5f51a6466667a5a356e6381d362d259125b57f059103dd9fdc8c0cf1d14139 \ + --hash=sha256:16ecf15d6af39246fe33e507105d67e4b81d8f8d2c6598ff7e3ca1b8a37213f7 \ + --hash=sha256:1f0b2f40cf341ee8cc1a97d51ff50dddb9fcc73241b9143ec74b30fc4f44f6cb \ + --hash=sha256:1f23fa283f51c890eda8e34e4937079114c74b4c81d2b2f1f1d94948f5cc3d7f \ + --hash=sha256:223db574bb38637e8230eb14b185565023ab624474df94d2af18f1cdb625216f \ + --hash=sha256:249f88ed15503f6492a71f01442abddd73856a0032ae860de6d75ca62eed8067 \ + --hash=sha256:24c2ed34dc222ed754247a2702b1e1e89fdbaa4016f324b4b8f1a802d4ffe87f \ + --hash=sha256:273a736c4645e63ac582c60a56b0acb529ef07f78e08dc6bfadf6a46b19c0da7 \ + --hash=sha256:281262213373b6d5e4bb4353bc36d1ba4084e6d6b5d242863721ef2bf2c2930b \ + --hash=sha256:30ce38e66630599e1193798285706903110d4f057aab3168a34b7fdc85569afc \ + --hash=sha256:33486899acd2d7d3066156b03465b949da3fd41a5da6e394ec49d271baefcf05 \ + --hash=sha256:343e44b2a8e60e06a7e0d29c1671a0d9951f59174f3709962b5143f60a2a98bd \ + --hash=sha256:373342dd05b1d07d752cecbec0c41817231f29f3a89aa8b8843f7b95992ed0c7 \ + --hash=sha256:3af60380ba0b7b5aeb329bc4e402acd25bd877e98b3727b0135cb5c2efdaefe9 \ + --hash=sha256:3e62d15d3cfa26e3d0788094de7b64efa75f3a53875cdbccdf78547aed547a81 \ + --hash=sha256:41b1d2bc74c2cac6f9074df52b2efbef2b30bdfe5f40cb78f8ca22963bc62977 \ + --hash=sha256:423ed5420ad5f5529db9ce89eac09c8a2f97da18eb1c870237e84c5a5c2d60aa \ + --hash=sha256:46acc57b331e0b3bcb3e1ca3b421d65637915cfcd65eb783cb2f78a511193f9b \ + --hash=sha256:4da9f45279fff3543c371d5ababc57a0384f70be244de7759c85a7f989cb4ebe \ + --hash=sha256:507553480670cab08a800b9463bdb881b2edeed77dc677b0a5915e6106e91a58 \ + --hash=sha256:53e5e39ff71b3fc484df8a522c933ea2b7cdd0d5d15ae82e5b23fde87d44cbd8 \ + --hash=sha256:54a30837587c6ee3cd1a4d1c2ec5d24e77984d44e2f34547e2323ddb4e22eb77 \ + --hash=sha256:5531d911795e3f935a9c23eb1c8c03c211661a5060aab167065896bbf62a5f85 \ + --hash=sha256:55cbbc356c2842f39bcc553cf695932e8b30e30e797f961860afb308e6b1bb7c \ + --hash=sha256:59923aa12d0157f6b82d686c3fd8e1166fa8cdfb3e17b42ce3b6147ff81528df \ + --hash=sha256:5a03a38adec8066d5a37bea22f2ba6bbf39fcdefbe2d91419ab864c3fb515454 \ + --hash=sha256:5a7b3c1ee8265eb4c8f1b7d29943f195c00673f5ab60c192eba2d4a7eae5f46a \ + --hash=sha256:5d4478d72eb61c36e5b446e375bbc49ed002430d17cdec3cecb36993398e1a9e \ + --hash=sha256:5ea5eb3c0c071862997d6f3e02af1d055f381b1d25b286b9d6644b79db77657c \ + --hash=sha256:604d076c55e2fdd4c1c03d06dc1a31b95130010517b5019db15365ec4a405fc6 \ + --hash=sha256:656873859b3b50eeebe6db8b1455e99d90c26ab058db8e427046dbc35c3140a5 \ + --hash=sha256:65d1d00fbfb3ea5f20add88bbc0f815150dbbde3b026e6c24759466c8b5a9ef9 \ + --hash=sha256:6b538e31eca1a7ea4605e44f81a48aa24c4632a277431a6ed3f328835901f4fd \ + --hash=sha256:6fd1ad24dc235e4ab88cda009e19bf347aabb975e44fd5c2fb22a3f6e4141277 \ + --hash=sha256:70d86fa5197b8947a2fa70260b48e400bf2ccacdcab97bb7de47e3d1e6312225 \ + --hash=sha256:7171ae35d2c33d326ac19dd8facb1e82e5fd04ef8c6c0e394d7af55a55051c22 \ + --hash=sha256:73d496de46cd2cdbdbcce4ae4bcdb4afb6a11234a1df9c085249d55166b95116 \ + --hash=sha256:7425ac3c54430f5fc5e7b6f41d41e704db073309acfc09305816bc6a0b26bb16 \ + --hash=sha256:74afa28374a3c3a11b3b5e5fca0ae03bef8450d6aa3ab3a1e2c30e3a75d023dc \ + --hash=sha256:758895b01d546812d1f42204bd443b8c433c44d090248bf22689df673ccafe00 \ + --hash=sha256:79573c24a46ce11aab457b472efd8d125e5a51da2d1d24387666cd85f54c05b2 \ + --hash=sha256:7e18f01b0c3e4a07fe6dfdb00e29049ba17eadbc5e7609a2a3a4af83ab7d710a \ + --hash=sha256:88547535b787a6c9ce4086917b6e1d291aa8ed914fdd3a838b3539dc95c12804 \ + --hash=sha256:88bbae4d40d5a46142e70d58bf664a89b6b4befaea7b2ecc14e03cedb8e06c04 \ + --hash=sha256:8cccf4f81371f257440c88faed6b74f1053eef90807b77e31ca057b2db74edb1 \ + --hash=sha256:9baa544e6acc91130e926e8c802a17f3b16fbea0fd441b5a60f5cf2cc5c3deba \ + --hash=sha256:a36692b8491d30a8c75f1dfee65bef119d6f39ea84ee04d9f9311f83c5ad9390 \ + --hash=sha256:a47681378a0439215912ef542c45a783484d4dd82bac412b71e59cf9c0e1cea0 \ + --hash=sha256:a7c06742645f914f26c7f1fa47b8bc4c91d222f76ee20116c43d5ef0912bba2d \ + --hash=sha256:a9a2203361a6e6404f80b99234fe7fb37d1fc73487b5a78dc1aa5b97201e0f22 \ + --hash=sha256:ab232e7fdb44cdfbf55fc3afa31bcdb0d8980b9b95c38b6405df2acb672af0e0 \ + --hash=sha256:ad85e269fe54d506b240d2d7b9f5f2057c2aa9a2ea5b32c66f8902f768117ed2 \ + --hash=sha256:af338aa93554be859173c39c85243970dc6a289fa907402289eeae7543e1ae18 \ + --hash=sha256:afd964fd43b10c12213574db492cb8f73b2f0826c8df07a68288f8f19af2ebe6 \ + --hash=sha256:b32888aad8b6e68f83a8fdccbf3165f5469702a7544472bdf41f582970ed3311 \ + --hash=sha256:c31eebe420a9a5d2887b13000b043ff6ca27c452a9a22fa71f35f118e8d4bf89 \ + --hash=sha256:caea3e9c79d5f0d2c6d9ab96111601797ea5da8e6d0723f77eabb0d4068d2b2f \ + --hash=sha256:cf30f6e3c077c8e6a9a7809c94551203c8843e74ba0c960f4a98cd80d4665d39 \ + --hash=sha256:d40770d7c0fd5cbed9d84b2c3f2e156431a12c9a37dc6284060fb4bec0b7ffd4 \ + --hash=sha256:d8a210b158a34164de8bb68b0e7780041a903d7b00c87e906fb69928bf7890d5 \ + --hash=sha256:dc4a8d2b25efb6681ecacad42fca8859f88092d8732b170de6a5dddd80a1c8fa \ + --hash=sha256:df7d30371a2accfe4013e90445f6388c570f103d61019b6b7c57e0265250072a \ + --hash=sha256:e01375f275f010fcbf7f643b4279896d04e571889b8a5b3f848423d91bf07050 \ + --hash=sha256:e1a4120ae5705f673727d3253de3ed0e016f7cd78dc463db1b31e2463e1f3cf6 \ + --hash=sha256:e228514a06843cae89621384cfe3a80418f3c04aadf8a3b14e46a7be704e4235 \ + --hash=sha256:e405adefb53a435f01efa7ccdec012c016b5a1d3f35459990afc39b6be4d5056 \ + --hash=sha256:e6b13af258d6a9ad602d57d889f83b9d5543acd471eee12eb51f5b01f8eb1bc2 \ + --hash=sha256:e6f40a8aa5a92f150bdb3e1c44b7e98fb7113955b2e5394122fa5532fec4b418 \ + --hash=sha256:e71d5c6ebac14875668a1e90baf2ea0ef5b7ac7918355850c0908ae82bcb297c \ + --hash=sha256:ed7c635ae45cfbc1a7371f708727bf74690daedc49b4dba310590ca0bd28aa8a \ + --hash=sha256:f38e60678850c42461d4202739f9bf1e3a737c7ad283638251e79cc49effb6b6 \ + --hash=sha256:f66eb08feaa410fe4eebd17f2a2c8e2e46d3476e9f8c783daa8e09e0faa666d0 \ + --hash=sha256:f9b2601381be482f70e5d1051a5965c25fb3625455a2bf520b5a077b22afb775 \ + --hash=sha256:fbd3c8319de8e1dc79d346929cd71d523622da527cca14e0c1d257e31c2b8b10 \ + --hash=sha256:fd341868a4b6714a5962c1af0bd44f7c404ef78720c7de4892901e540417111c + # via deprecated +zstandard==0.24.0 \ + --hash=sha256:0101f835da7de08375f380192ff75135527e46e3f79bef224e3c49cb640fef6a \ + --hash=sha256:010302face38c9a909b8934e3bf6038266d6afc69523f3efa023c5cb5d38271b \ + --hash=sha256:05d27c953f2e0a3ecc8edbe91d6827736acc4c04d0479672e0400ccdb23d818c \ + --hash=sha256:09887301001e7a81a3618156bc1759e48588de24bddfdd5b7a4364da9a8fbc20 \ + --hash=sha256:0a416814608610abf5488889c74e43ffa0343ca6cf43957c6b6ec526212422da \ + --hash=sha256:0a9e95ceb180ccd12a8b3437bac7e8a8a089c9094e39522900a8917745542184 \ + --hash=sha256:0c9c3cba57f5792532a3df3f895980d47d78eda94b0e5b800651b53e96e0b604 \ + --hash=sha256:0d66da2649bb0af4471699aeb7a83d6f59ae30236fb9f6b5d20fb618ef6c6777 \ + --hash=sha256:0dc5654586613aebe5405c1ba180e67b3f29e7d98cf3187c79efdcc172f39457 \ + --hash=sha256:0ed8345b504df1cab280af923ef69ec0d7d52f7b22f78ec7982fde7c33a43c4f \ + --hash=sha256:0f6d9a146e07458cb41423ca2d783aefe3a3a97fe72838973c13b8f1ecc7343a \ + --hash=sha256:10e284748a7e7fbe2815ca62a9d6e84497d34cfdd0143fa9e8e208efa808d7c4 \ + --hash=sha256:13fc548e214df08d896ee5f29e1f91ee35db14f733fef8eabea8dca6e451d1e2 \ + --hash=sha256:1b14bc92af065d0534856bf1b30fc48753163ea673da98857ea4932be62079b1 \ + --hash=sha256:1bda8a85e5b9d5e73af2e61b23609a8cc1598c1b3b2473969912979205a1ff25 \ + --hash=sha256:1e133a9dd51ac0bcd5fd547ba7da45a58346dbc63def883f999857b0d0c003c4 \ + --hash=sha256:1f578fab202f4df67a955145c3e3ca60ccaaaf66c97808545b2625efeecdef10 \ + --hash=sha256:27b6fa72b57824a3f7901fc9cc4ce1c1c834b28f3a43d1d4254c64c8f11149d4 \ + --hash=sha256:2825a3951f945fb2613ded0f517d402b1e5a68e87e0ee65f5bd224a8333a9a46 \ + --hash=sha256:2fc67eb15ed573950bc6436a04b3faea6c36c7db98d2db030d48391c6736a0dc \ + --hash=sha256:337572a7340e1d92fd7fb5248c8300d0e91071002d92e0b8cabe8d9ae7b58159 \ + --hash=sha256:35f13501a8accf834457d8e40e744568287a215818778bc4d79337af2f3f0d97 \ + --hash=sha256:388aad2d693707f4a0f6cc687eb457b33303d6b57ecf212c8ff4468c34426892 \ + --hash=sha256:3aa3b4344b206941385a425ea25e6dd63e5cb0f535a4b88d56e3f8902086be9e \ + --hash=sha256:3adb4b5414febf074800d264ddf69ecade8c658837a83a19e8ab820e924c9933 \ + --hash=sha256:3b95fc06489aa9388400d1aab01a83652bc040c9c087bd732eb214909d7fb0dd \ + --hash=sha256:3f2fe35ec84908dddf0fbf66b35d7c2878dbe349552dd52e005c755d3493d61c \ + --hash=sha256:3f96a9130171e01dbb6c3d4d9925d604e2131a97f540e223b88ba45daf56d6fb \ + --hash=sha256:444633b487a711e34f4bccc46a0c5dfbe1aee82c1a511e58cdc16f6bd66f187c \ + --hash=sha256:498f88f5109666c19531f0243a90d2fdd2252839cd6c8cc6e9213a3446670fa8 \ + --hash=sha256:51a86bd963de3f36688553926a84e550d45d7f9745bd1947d79472eca27fcc75 \ + --hash=sha256:52788e7c489069e317fde641de41b757fa0ddc150e06488f153dd5daebac7192 \ + --hash=sha256:52cd7d9fa0a115c9446abb79b06a47171b7d916c35c10e0c3aa6f01d57561382 \ + --hash=sha256:55872e818598319f065e8192ebefecd6ac05f62a43f055ed71884b0a26218f41 \ + --hash=sha256:561123d05681197c0e24eb8ab3cfdaf299e2b59c293d19dad96e1610ccd8fbc6 \ + --hash=sha256:57be3abb4313e0dd625596376bbb607f40059d801d51c1a1da94d7477e63b255 \ + --hash=sha256:5e941654cef13a1d53634ec30933722eda11f44f99e1d0bc62bbce3387580d50 \ + --hash=sha256:622e1e04bd8a085994e02313ba06fbcf4f9ed9a488c6a77a8dbc0692abab6a38 \ + --hash=sha256:6324fde5cf5120fbf6541d5ff3c86011ec056e8d0f915d8e7822926a5377193a \ + --hash=sha256:6374feaf347e6b83ec13cc5dcfa70076f06d8f7ecd46cc71d58fac798ff08b76 \ + --hash=sha256:63d39b161000aeeaa06a1cb77c9806e939bfe460dfd593e4cbf24e6bc717ae94 \ + --hash=sha256:656ed895b28c7e42dd5b40dfcea3217cfc166b6b7eef88c3da2f5fc62484035b \ + --hash=sha256:663848a8bac4fdbba27feea2926049fdf7b55ec545d5b9aea096ef21e7f0b079 \ + --hash=sha256:6885ae4b33aee8835dbdb4249d3dfec09af55e705d74d9b660bfb9da51baaa8b \ + --hash=sha256:6b005bcee4be9c3984b355336283afe77b2defa76ed6b89332eced7b6fa68b68 \ + --hash=sha256:76cdfe7f920738ea871f035568f82bad3328cbc8d98f1f6988264096b5264efd \ + --hash=sha256:77b8b7b98893eaf47da03d262816f01f251c2aa059c063ed8a45c50eada123a5 \ + --hash=sha256:7ac6e4d727521d86d20ec291a3f4e64a478e8a73eaee80af8f38ec403e77a409 \ + --hash=sha256:7de5869e616d426b56809be7dc6dba4d37b95b90411ccd3de47f421a42d4d42c \ + --hash=sha256:869bf13f66b124b13be37dd6e08e4b728948ff9735308694e0b0479119e08ea7 \ + --hash=sha256:87ae1684bc3c02d5c35884b3726525eda85307073dbefe68c3c779e104a59036 \ + --hash=sha256:8ecd3b1f7a601f79e0cd20c26057d770219c0dc2f572ea07390248da2def79a4 \ + --hash=sha256:92be52ca4e6e604f03d5daa079caec9e04ab4cbf6972b995aaebb877d3d24e13 \ + --hash=sha256:92ea7855d5bcfb386c34557516c73753435fb2d4a014e2c9343b5f5ba148b5d8 \ + --hash=sha256:962ea3aecedcc944f8034812e23d7200d52c6e32765b8da396eeb8b8ffca71ce \ + --hash=sha256:98ca91dc9602cf351497d5600aa66e6d011a38c085a8237b370433fcb53e3409 \ + --hash=sha256:9b84c6c210684286e504022d11ec294d2b7922d66c823e87575d8b23eba7c81f \ + --hash=sha256:a0f6fc2ea6e07e20df48752e7700e02e1892c61f9a6bfbacaf2c5b24d5ad504b \ + --hash=sha256:a2bda8f2790add22773ee7a4e43c90ea05598bffc94c21c40ae0a9000b0133c3 \ + --hash=sha256:aa705beb74ab116563f4ce784fa94771f230c05d09ab5de9c397793e725bb1db \ + --hash=sha256:aadf32c389bb7f02b8ec5c243c38302b92c006da565e120dfcb7bf0378f4f848 \ + --hash=sha256:ab2357353894a5ec084bb8508ff892aa43fb7fe8a69ad310eac58221ee7f72aa \ + --hash=sha256:ad9fd176ff6800a0cf52bcf59c71e5de4fa25bf3ba62b58800e0f84885344d34 \ + --hash=sha256:addfc23e3bd5f4b6787b9ca95b2d09a1a67ad5a3c318daaa783ff90b2d3a366e \ + --hash=sha256:af1394c2c5febc44e0bbf0fc6428263fa928b50d1b1982ce1d870dc793a8e5f4 \ + --hash=sha256:b04c94718f7a8ed7cdd01b162b6caa1954b3c9d486f00ecbbd300f149d2b2606 \ + --hash=sha256:b4f20417a4f511c656762b001ec827500cbee54d1810253c6ca2df2c0a307a5f \ + --hash=sha256:b7a8c30d9bf4bd5e4dcfe26900bef0fcd9749acde45cdf0b3c89e2052fda9a13 \ + --hash=sha256:b7fa260dd2731afd0dfa47881c30239f422d00faee4b8b341d3e597cface1483 \ + --hash=sha256:b91380aefa9c7ac831b011368daf378d3277e0bdeb6bad9535e21251e26dd55a \ + --hash=sha256:bb2446a55b3a0fd8aa02aa7194bd64740015464a2daaf160d2025204e1d7c282 \ + --hash=sha256:bc05f8a875eb651d1cc62e12a4a0e6afa5cd0cc231381adb830d2e9c196ea895 \ + --hash=sha256:bcf69e0bcddbf2adcfafc1a7e864edcc204dd8171756d3a8f3340f6f6cc87b7b \ + --hash=sha256:bf02f915fa7934ea5dfc8d96757729c99a8868b7c340b97704795d6413cf5fe6 \ + --hash=sha256:c39d2b6161f3c5c5d12e9207ecf1006bb661a647a97a6573656b09aaea3f00ef \ + --hash=sha256:c59740682a686bf835a1a4d8d0ed1eefe31ac07f1c5a7ed5f2e72cf577692b00 \ + --hash=sha256:cc76de75300f65b8eb574d855c12518dc25a075dadb41dd18f6322bda3fe15d5 \ + --hash=sha256:cd0d3d16e63873253bad22b413ec679cf6586e51b5772eb10733899832efec42 \ + --hash=sha256:cda61c46343809ecda43dc620d1333dd7433a25d0a252f2dcc7667f6331c7b61 \ + --hash=sha256:cf7fbb4e54136e9a03c7ed7691843c4df6d2ecc854a2541f840665f4f2bb2edd \ + --hash=sha256:d2b3b4bda1a025b10fe0269369475f420177f2cb06e0f9d32c95b4873c9f80b8 \ + --hash=sha256:d5e3b9310fd7f0d12edc75532cd9a56da6293840c84da90070d692e0bb15f186 \ + --hash=sha256:d64899cc0f33a8f446f1e60bffc21fa88b99f0e8208750d9144ea717610a80ce \ + --hash=sha256:d6975f2d903bc354916a17b91a7aaac7299603f9ecdb788145060dde6e573a16 \ + --hash=sha256:d82ac87017b734f2fb70ff93818c66f0ad2c3810f61040f077ed38d924e19980 \ + --hash=sha256:dd91b0134a32dfcd8be504e8e46de44ad0045a569efc25101f2a12ccd41b5759 \ + --hash=sha256:df4be1cf6e8f0f2bbe2a3eabfff163ef592c84a40e1a20a8d7db7f27cfe08fc2 \ + --hash=sha256:e05d66239d14a04b4717998b736a25494372b1b2409339b04bf42aa4663bf251 \ + --hash=sha256:e40cd0fc734aa1d4bd0e7ad102fd2a1aefa50ce9ef570005ffc2273c5442ddc3 \ + --hash=sha256:e46eb6702691b24ddb3e31e88b4a499e31506991db3d3724a85bd1c5fc3cfe4e \ + --hash=sha256:e4ebb000c0fe24a6d0f3534b6256844d9dbf042fdf003efe5cf40690cf4e0f3e \ + --hash=sha256:e69f8e534b4e254f523e2f9d4732cf9c169c327ca1ce0922682aac9a5ee01155 \ + --hash=sha256:e91a4e5d62da7cb3f53e04fe254f1aa41009af578801ee6477fe56e7bef74ee2 \ + --hash=sha256:ec194197e90ca063f5ecb935d6c10063d84208cac5423c07d0f1a09d1c2ea42b \ + --hash=sha256:f6ae9fc67e636fc0fa9adee39db87dfbdeabfa8420bc0e678a1ac8441e01b22b \ + --hash=sha256:f7d3fe9e1483171e9183ffdb1fab07c5fef80a9c3840374a38ec2ab869ebae20 \ + --hash=sha256:fdc7a52a4cdaf7293e10813fd6a3abc0c7753660db12a3b864ab1fb5a0c60c16 \ + --hash=sha256:fe3198b81c00032326342d973e526803f183f97aa9e9a98e3f897ebafe21178f \ + --hash=sha256:ff19efaa33e7f136fe95f9bbcc90ab7fb60648453b03f95d1de3ab6997de0f32 # via -r requirements.in diff --git a/src/github.rs b/src/github.rs index 0d3bc97..87e316e 100644 --- a/src/github.rs +++ b/src/github.rs @@ -4,23 +4,22 @@ use { crate::release::{ - bootstrap_llvm, produce_install_only, produce_install_only_stripped, RELEASE_TRIPLES, + RELEASE_TRIPLES, bootstrap_llvm, produce_install_only, produce_install_only_stripped, }, - anyhow::{anyhow, Result}, + anyhow::{Result, anyhow}, bytes::Bytes, clap::ArgMatches, futures::StreamExt, octocrab::{ + Octocrab, OctocrabBuilder, models::{repos::Release, workflows::WorkflowListArtifact}, params::actions::ArchiveFormat, - Octocrab, OctocrabBuilder, }, rayon::prelude::*, reqwest::{Client, StatusCode}, - reqwest_middleware::{self, ClientWithMiddleware}, reqwest_retry::{ - default_on_request_failure, policies::ExponentialBackoff, RetryTransientMiddleware, - Retryable, RetryableStrategy, + RetryPolicy, Retryable, RetryableStrategy, default_on_request_failure, + policies::ExponentialBackoff, }, sha2::{Digest, Sha256}, std::{ @@ -28,6 +27,7 @@ use { io::Read, path::PathBuf, str::FromStr, + time::{Duration, SystemTime}, }, url::Url, zip::ZipArchive, @@ -65,12 +65,20 @@ async fn fetch_artifact( Ok(res) } +enum UploadSource { + Filename(PathBuf), + Data(Bytes), +} + +#[allow(clippy::too_many_arguments)] async fn upload_release_artifact( - client: &ClientWithMiddleware, + client: &Client, + retry_policy: &impl RetryPolicy, + retryable_strategy: &impl RetryableStrategy, auth_token: String, release: &Release, filename: String, - data: Bytes, + body: UploadSource, dry_run: bool, ) -> Result<()> { if release.assets.iter().any(|asset| asset.name == filename) { @@ -93,17 +101,52 @@ async fn upload_release_artifact( return Ok(()); } - // Octocrab doesn't yet support release artifact upload. And the low-level HTTP API - // forces the use of strings on us. So we have to make our own HTTP client. - - let response = client - .put(url) - .header("Authorization", format!("Bearer {auth_token}")) - .header("Content-Length", data.len()) - .header("Content-Type", "application/x-tar") - .body(data) - .send() - .await?; + // Octocrab's high-level API for uploading release artifacts doesn't yet support streaming + // bodies, and their low-level API isn't more helpful than using our own HTTP client. + // + // Because we are streaming the body, we can't use the standard retry middleware for reqwest + // (see e.g. https://github.com/seanmonstar/reqwest/issues/2416), so we have to recreate the + // request on each retry and handle the retry logic ourself. This logic is inspired by + // uv/crates/uv-publish/src/lib.rs (which has the same problem), which in turn is inspired by + // reqwest-middleware/reqwest-retry/src/middleware.rs. + // + // (While Octocrab's API would work fine for the non-streaming case, we just use this function + // for both cases so that we can make a homogeneous Vec later in the file.) + + let mut n_past_retries = 0; + let start_time = SystemTime::now(); + let response = loop { + let request = client + .put(url.clone()) + .timeout(Duration::from_secs(60)) + .header("Authorization", format!("Bearer {auth_token}")) + .header("Content-Type", "application/octet-stream"); + let request = match body { + UploadSource::Filename(ref path) => { + let file = tokio::fs::File::open(&path).await?; + let len = file.metadata().await?.len(); + request.header("Content-Length", len).body(file) + } + UploadSource::Data(ref bytes) => request + .header("Content-Length", bytes.len()) + .body(bytes.clone()), + }; + let result = request.send().await.map_err(|e| e.into()); + + if retryable_strategy.handle(&result) == Some(Retryable::Transient) { + let retry_decision = retry_policy.should_retry(start_time, n_past_retries); + if let reqwest_retry::RetryDecision::Retry { execute_after } = retry_decision { + println!("retrying upload to {url} after {result:?}"); + let duration = execute_after + .duration_since(SystemTime::now()) + .unwrap_or_else(|_| Duration::default()); + tokio::time::sleep(duration).await; + n_past_retries += 1; + continue; + } + } + break result?; + }; if !response.status().is_success() { return Err(anyhow!("HTTP {}", response.status())); @@ -112,6 +155,20 @@ async fn upload_release_artifact( Ok(()) } +fn new_github_client(args: &ArgMatches) -> Result<(Octocrab, String)> { + let token = args + .get_one::("token") + .expect("token should be specified") + .to_string(); + let github_uri = args.get_one::("github-uri"); + + let mut builder = OctocrabBuilder::new().personal_token(token.clone()); + if let Some(github_uri) = github_uri { + builder = builder.base_uri(github_uri.clone())?; + } + Ok((builder.build()?, token)) +} + pub async fn command_fetch_release_distributions(args: &ArgMatches) -> Result<()> { let dest_dir = args .get_one::("dest") @@ -121,13 +178,7 @@ pub async fn command_fetch_release_distributions(args: &ArgMatches) -> Result<() .expect("organization should be set"); let repo = args.get_one::("repo").expect("repo should be set"); - let client = OctocrabBuilder::new() - .personal_token( - args.get_one::("token") - .expect("token should be required argument") - .to_string(), - ) - .build()?; + let (client, _) = new_github_client(args)?; let release_version_range = pep440_rs::VersionSpecifier::from_str(">=3.9")?; @@ -207,10 +258,11 @@ pub async fn command_fetch_release_distributions(args: &ArgMatches) -> Result<() .await?; for artifact in artifacts { - if matches!( - artifact.name.as_str(), - "pythonbuild" | "toolchain" - ) || artifact.name.contains("install-only") + if matches!(artifact.name.as_str(), "pythonbuild" | "toolchain") + || artifact.name.contains("install-only") + || artifact.name.contains("dockerbuild") + || artifact.name.contains("crate-") + || artifact.name.contains("image-") { continue; } @@ -235,16 +287,13 @@ pub async fn command_fetch_release_distributions(args: &ArgMatches) -> Result<() let parts = name.split('-').collect::>(); if parts[0] != "cpython" { - println!("ignoring {} not a cpython artifact", name); + println!("ignoring {name} not a cpython artifact"); continue; }; let python_version = pep440_rs::Version::from_str(parts[1])?; if !release_version_range.contains(&python_version) { - println!( - "{} not in release version range {}", - name, release_version_range - ); + println!("{name} not in release version range {release_version_range}"); continue; } @@ -259,17 +308,14 @@ pub async fn command_fetch_release_distributions(args: &ArgMatches) -> Result<() } }) else { - println!( - "ignoring {} does not match any registered release triples", - name - ); + println!("ignoring {name} does not match any registered release triples"); continue; }; let stripped_name = if let Some(s) = name.strip_suffix(".tar.zst") { s } else { - println!("ignoring {} not a .tar.zst artifact", name); + println!("ignoring {name} not a .tar.zst artifact"); continue; }; @@ -282,7 +328,7 @@ pub async fn command_fetch_release_distributions(args: &ArgMatches) -> Result<() let build_suffix = &stripped_name[triple_start + triple.len() + 1..]; if !release.suffixes(None).any(|suffix| build_suffix == suffix) { - println!("ignoring {} not a release artifact for triple", name); + println!("ignoring {name} not a release artifact for triple"); continue; } @@ -291,7 +337,7 @@ pub async fn command_fetch_release_distributions(args: &ArgMatches) -> Result<() zf.read_to_end(&mut buf)?; std::fs::write(&dest_path, &buf)?; - println!("prepared {} for release", name); + println!("prepared {name} for release"); if build_suffix == release.install_only_suffix { install_paths.push(dest_path); @@ -358,10 +404,6 @@ pub async fn command_upload_release_distributions(args: &ArgMatches) -> Result<( .get_one::("tag") .expect("tag should be specified"); let ignore_missing = args.get_flag("ignore_missing"); - let token = args - .get_one::("token") - .expect("token should be specified") - .to_string(); let organization = args .get_one::("organization") .expect("organization should be specified"); @@ -405,34 +447,19 @@ pub async fn command_upload_release_distributions(args: &ArgMatches) -> Result<( for suffix in release.suffixes(Some(&python_version)) { wanted_filenames.insert( - format!( - "cpython-{}-{}-{}-{}.tar.zst", - version, triple, suffix, datetime - ), - format!( - "cpython-{}+{}-{}-{}-full.tar.zst", - version, tag, triple, suffix - ), + format!("cpython-{version}-{triple}-{suffix}-{datetime}.tar.zst"), + format!("cpython-{version}+{tag}-{triple}-{suffix}-full.tar.zst"), ); } wanted_filenames.insert( - format!( - "cpython-{}-{}-install_only-{}.tar.gz", - version, triple, datetime - ), - format!("cpython-{}+{}-{}-install_only.tar.gz", version, tag, triple), + format!("cpython-{version}-{triple}-install_only-{datetime}.tar.gz"), + format!("cpython-{version}+{tag}-{triple}-install_only.tar.gz"), ); wanted_filenames.insert( - format!( - "cpython-{}-{}-install_only_stripped-{}.tar.gz", - version, triple, datetime - ), - format!( - "cpython-{}+{}-{}-install_only_stripped.tar.gz", - version, tag, triple - ), + format!("cpython-{version}-{triple}-install_only_stripped-{datetime}.tar.gz"), + format!("cpython-{version}+{tag}-{triple}-install_only_stripped.tar.gz"), ); } } @@ -443,7 +470,7 @@ pub async fn command_upload_release_distributions(args: &ArgMatches) -> Result<( .collect::>(); for f in &missing { - println!("missing release artifact: {}", f); + println!("missing release artifact: {f}"); } if missing.is_empty() { println!("found all {} release artifacts", wanted_filenames.len()); @@ -451,9 +478,7 @@ pub async fn command_upload_release_distributions(args: &ArgMatches) -> Result<( return Err(anyhow!("missing {} release artifacts", missing.len())); } - let client = OctocrabBuilder::new() - .personal_token(token.clone()) - .build()?; + let (client, token) = new_github_client(args)?; let repo_handler = client.repos(organization, repo); let releases = repo_handler.releases(); @@ -473,12 +498,7 @@ pub async fn command_upload_release_distributions(args: &ArgMatches) -> Result<( let mut digests = BTreeMap::new(); let retry_policy = ExponentialBackoff::builder().build_with_max_retries(5); - let raw_client = reqwest_middleware::ClientBuilder::new(Client::new()) - .with(RetryTransientMiddleware::new_with_policy_and_strategy( - retry_policy, - GitHubUploadRetryStrategy, - )) - .build(); + let raw_client = Client::new(); { let mut fs = vec![]; @@ -488,31 +508,31 @@ pub async fn command_upload_release_distributions(args: &ArgMatches) -> Result<( continue; } - let file_data = Bytes::copy_from_slice(&std::fs::read(dist_dir.join(&source))?); - - let mut digest = Sha256::new(); - digest.update(&file_data); - - let digest = hex::encode(digest.finalize()); - - digests.insert(dest.clone(), digest.clone()); - + let local_filename = dist_dir.join(&source); fs.push(upload_release_artifact( &raw_client, + &retry_policy, + &GitHubUploadRetryStrategy, token.clone(), &release, dest.clone(), - file_data, - dry_run, - )); - fs.push(upload_release_artifact( - &raw_client, - token.clone(), - &release, - format!("{}.sha256", dest), - Bytes::copy_from_slice(format!("{}\n", digest).as_bytes()), + UploadSource::Filename(local_filename.clone()), dry_run, )); + + // reqwest wants to take ownership of the body, so it's hard for us to do anything + // clever with reading the file once and calculating the sha256sum while we read. + // So we open and read the file again. + let digest = { + let file = tokio::fs::File::open(local_filename).await?; + let mut stream = tokio_util::io::ReaderStream::with_capacity(file, 1048576); + let mut hasher = Sha256::new(); + while let Some(chunk) = stream.next().await { + hasher.update(&chunk?); + } + hex::encode(hasher.finalize()) + }; + digests.insert(dest.clone(), digest.clone()); } let mut buffered = futures::stream::iter(fs).buffer_unordered(16); @@ -524,7 +544,7 @@ pub async fn command_upload_release_distributions(args: &ArgMatches) -> Result<( let shasums = digests .iter() - .map(|(filename, digest)| format!("{} {}\n", digest, filename)) + .map(|(filename, digest)| format!("{digest} {filename}\n")) .collect::>() .join(""); @@ -532,10 +552,12 @@ pub async fn command_upload_release_distributions(args: &ArgMatches) -> Result<( upload_release_artifact( &raw_client, + &retry_policy, + &GitHubUploadRetryStrategy, token.clone(), &release, "SHA256SUMS".to_string(), - Bytes::copy_from_slice(shasums.as_bytes()), + UploadSource::Data(Bytes::copy_from_slice(shasums.as_bytes())), dry_run, ) .await?; @@ -559,8 +581,8 @@ pub async fn command_upload_release_distributions(args: &ArgMatches) -> Result<( let mut stream = client .repos(organization, repo) - .releases() - .stream_asset(shasums_asset.id) + .release_assets() + .stream(shasums_asset.id.into_inner()) .await?; let mut asset_bytes = Vec::::new(); diff --git a/src/github_api_tester.py b/src/github_api_tester.py new file mode 100755 index 0000000..9ff4bc0 --- /dev/null +++ b/src/github_api_tester.py @@ -0,0 +1,340 @@ +#!/usr/bin/env -S uv run +# +# A fake GitHub API server for testing upload-release-distributions's +# behavior in the presence of API failures. +# +# Call with no arguments or with pytest CLI arguments to run the tests +# at the bottom which invoke `cargo run`. +# +# Call with one argument "serve" to start an HTTP server on 0.0.0.0. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at https://mozilla.org/MPL/2.0/. +# +# /// script +# requires-python = ">=3.13" +# dependencies = [ +# "quart>=0.20.0", +# "quart-trio>=0.12.0", +# # Pinned because we mess with hypercorn internals, see below. +# "hypercorn==0.17.3", +# "pytest", +# "pytest-trio", +# ] +# /// + +import dataclasses +import hashlib +import logging +import os +import sys +from collections.abc import Callable + +import hypercorn +import pytest +import quart +import trio +from quart import request +from quart_trio import QuartTrio + +app = QuartTrio(__name__) +app.config["MAX_CONTENT_LENGTH"] = None + + +async def drop_connection(): + """Drop the (HTTP/1.1) connection belonging to the current Quart request.""" + # We need to do two things: + # - Convince hypercorn (specifically, around HTTPStream.app_send()) + # that it doesn't need to send a 500 and can just close the socket. + # - Convince h11's state machine that it's okay to close the socket + # without sending a response. + # We can't do this at the ASGI layer: hypercorn will insert the 500 + # for protocol compliance if the ASGI app doesn't provide a + # response. We need to modify the actual HTTP server, either with a + # pull request or by digging into its internals as follows: + # - Grab the HTTPStream whose bound method app_send was passed into + # the Quart request + # - Grab the H11Protocol whose bound method stream_send was passed + # into the HTTPStream's constructor + # - Tell the H11Protocol's underlying h11 state machine to act as if + # the remote side errored, so it thinks dropping the connection is + # the appropriate next step and not misbehavior on our end + # - Tell the HTTPStream to move the state machine forward with no + # further send on our side, which will drop the connection (and + # not consider it for keepalive) + import hypercorn.protocol as hp + + http_stream: hp.http_stream.HTTPStream = request._send_push_promise.args[0].__self__ + protocol: hp.h11.H11Protocol = http_stream.send.__self__ + protocol.connection._process_error(protocol.connection.their_role) + await http_stream.send(hp.events.EndBody(stream_id=http_stream.stream_id)) + await http_stream.app_send(None) + + # Some other things I tried, kept for reference: + # http_stream.state = hypercorn.protocol.http_stream.ASGIHTTPState.RESPONSE + # await http_stream._send_closed() + # http_stream.state = hypercorn.protocol.http_stream.ASGIHTTPState.CLOSED + + +# The following GitHub API datatypes are complete enough to satisfy +# octocrab's deserialization. + + +@dataclasses.dataclass +class Asset: + name: str + label: str | None + sha256: str + contents: bytes | None + + _ASSETS = [] + + def __post_init__(self): + self.id = len(self._ASSETS) + self._ASSETS.append(self) + + def render(self) -> dict: + return { + "url": quart.url_for("get_asset", id=self.id, _external=True), + "browser_download_url": "https://github.invalid/unneeded", + "id": self.id, + "node_id": "fakenode", + "name": self.name, + "label": self.label, + "state": "uploaded", + "content_type": "application/octet-stream", + "size": 1000, + "download_count": 1000, + "created_at": "2020-01-01T00:00:00Z", + "updated_at": "2020-01-01T00:00:00Z", + "uploader": None, + } + + +@dataclasses.dataclass +class Upload: + name: str + label: str | None + + def __post_init__(self): + self.hasher = hashlib.sha256() + if self.name == "SHA256SUMS": + self.contents = b"" + else: + self.contents = None + + def update(self, chunk: bytes) -> None: + self.hasher.update(chunk) + if self.contents is not None: + self.contents += chunk + + def to_asset(self) -> Asset: + return Asset(self.name, self.label, self.hasher.hexdigest(), self.contents) + + +@dataclasses.dataclass +class Release: + release_id: int + tag_name: str + assets: list = dataclasses.field(default_factory=list) + # fault0 and fault1 are called before and after receiving the first + # chunk of a PUT request, respectively. Each is called once per + # release - the first upload that hits it will disarm it. + fault0: Callable[[], None] | None = None + fault1: Callable[[], None] | None = None + + def render(self) -> dict: + upload_asset = quart.url_for( + "upload_asset", release=self.release_id, _external=True + ) + return { + "url": request.url, + "html_url": "https://github.invalid/unneeded", + "assets_url": "https://github.invalid/unneeded", + "upload_url": upload_asset + "{?name,label}", + "id": self.release_id, + "node_id": "fakenode", + "tag_name": self.tag_name, + "target_commitish": "main", + "draft": False, + "prerelease": True, + "assets": [i.render() for i in self.assets], + } + + +releases = [ + Release(1, "basic"), + Release(11, "early-drop", fault0=drop_connection), + Release(12, "late-drop", fault1=drop_connection), + Release(4011, "early-401", fault0=lambda: quart.abort(401)), + Release(4012, "late-401", fault1=lambda: quart.abort(401)), + Release(4031, "early-403", fault0=lambda: quart.abort(403)), + Release(4032, "late-403", fault1=lambda: quart.abort(403)), + Release(5001, "early-500", fault0=lambda: quart.abort(500)), + Release(5002, "late-500", fault1=lambda: quart.abort(500)), +] + + +def get_release(*, tag=None, release=None) -> Release: + if tag is not None: + condition = lambda r: r.tag_name == tag + elif release is not None: + condition = lambda r: r.release_id == release + else: + raise TypeError("tag or release must be set") + + for r in releases: + if condition(r): + return r + quart.abort(404, response=quart.jsonify({"message": "Not Found", "status": "404"})) + + +# GitHub API functions + + +@app.route("/repos///releases/tags/") +async def get_release_by_tag(org, repo, tag): + return get_release(tag=tag).render() + + +@app.route("/repos///releases/") +async def get_release_by_id(org, repo, release): + return get_release(release=release).render() + + +@app.put("/upload//assets") +async def upload_asset(release): + filename = request.args["name"] + release = get_release(release=release) + + if (fault := release.fault0) is not None: + logging.info(f"{filename}: injecting fault0") + release.fault0 = None + return await fault() + + logging.info(f"{filename}: upload begin") + upload = Upload(filename, request.args.get("label")) + async for chunk in request.body: + logging.debug(f"{filename}: {len(chunk)=}") + upload.update(chunk) + if (fault := release.fault1) is not None: + if "SHA256" not in filename: + logging.info(f"{filename}: injecting fault1") + release.fault1 = None + return await fault() + + asset = upload.to_asset() + logging.info(f"{filename}: upload complete, {asset.sha256=}") + release.assets.append(asset) + return asset.render() + + +@app.route("/get_asset/") +@app.route("/repos///releases/assets/") +async def get_asset(id, org=None, repo=None): + try: + asset = Asset._ASSETS[id] + except IndexError: + quart.abort( + 404, response=quart.jsonify({"message": "Not Found", "status": "404"}) + ) + + if "application/octet-stream" in request.accept_mimetypes: + if asset.contents is None: + print( + f"USAGE ERROR: Received request for contents of {asset.filename=} which was not stored" + ) + return "Did not store contents", 410 + return asset.contents + else: + return asset.render() + + +# Generic upload function, useful for testing clients in isolation + + +@app.put("/file/") +async def upload_file(path): + logging.info(f"{path}: upload begin") + s = hashlib.sha256() + async for chunk in request.body: + logging.debug(f"{path}: {len(chunk)=}") + if "drop" in request.args: + await drop_connection() + s.update(chunk) + digest = s.hexdigest() + logging.info(f"{path}: {digest=}") + return f"{digest} {path}\n", 500 + + +# Test cases + + +@pytest.fixture +async def server(nursery): + await nursery.start(app.run_task) + + +FILENAME = "cpython-3.0.0-x86_64-unknown-linux-gnu-install_only-19700101T1234.tar.gz" +SHA256_20MEG = "9e21c61969cd3e077a1b2b58ddb583b175e13c6479d2d83912eaddc23c0cdd52" + + +@pytest.fixture(scope="session") +def upload_release_distributions(tmp_path_factory): + dist = tmp_path_factory.mktemp("dist") + filename = dist / FILENAME + filename.touch() + os.truncate(filename, 20_000_000) + + async def upload_release_distributions(*args): + return await trio.run_process( + [ + "cargo", + "run", + "--", + "upload-release-distributions", + "--github-uri", + "http://localhost:5000", + "--token", + "no-token-needed", + "--dist", + dist, + "--datetime", + "19700101T1234", + "--ignore-missing", + ] + + list(args) + ) + + return upload_release_distributions + + +# TODO: test all of [r.tag_name for r in releases] +TAGS_TO_TEST = ["basic", "early-drop", "late-drop", "early-403", "late-403"] + + +@pytest.mark.parametrize("tag", TAGS_TO_TEST) +async def test_upload(server, upload_release_distributions, tag): + with trio.fail_after(300): + await upload_release_distributions("--tag", tag) + release = get_release(tag=tag) + assets = sorted(release.assets, key=lambda a: a.name) + assert len(assets) == 2 + assert assets[0].name == "SHA256SUMS" + filename = FILENAME.replace("3.0.0", f"3.0.0+{tag}").replace("-19700101T1234", "") + assert assets[1].name == filename + assert assets[1].sha256 == SHA256_20MEG + assert assets[0].contents == f"{SHA256_20MEG} {filename}\n".encode() + + +# Work around https://github.com/pgjones/hypercorn/issues/238 not being in a release +# Without it, test failures are unnecessarily noisy +hypercorn.trio.lifespan.LifespanFailureError = trio.Cancelled + +if __name__ == "__main__": + if len(sys.argv) > 1 and sys.argv[1] == "serve": + logging.basicConfig(level=logging.INFO) + app.run("0.0.0.0") + else: + pytest.main(["-o", "trio_mode=true", __file__] + sys.argv[1:]) diff --git a/src/macho.rs b/src/macho.rs index 4717fb9..2173ee7 100644 --- a/src/macho.rs +++ b/src/macho.rs @@ -4,7 +4,7 @@ use { crate::validation::ValidationContext, - anyhow::{anyhow, Context, Result}, + anyhow::{Context, Result, anyhow}, apple_sdk::{AppleSdk, SdkSearch, SdkSearchLocation, SdkSorting, SdkVersion, SimpleSdk}, semver::Version, std::{ @@ -53,7 +53,7 @@ impl std::fmt::Display for MachOPackedVersion { let minor = (self.value >> 8) & 0xff; let subminor = self.value & 0xff; - f.write_str(&format!("{}.{}.{}", major, minor, subminor)) + f.write_str(&format!("{major}.{minor}.{subminor}")) } } @@ -128,9 +128,9 @@ impl RequiredSymbols { fn tbd_relative_path(path: &str) -> Result { if let Some(stripped) = path.strip_prefix('/') { if let Some(stem) = stripped.strip_suffix(".dylib") { - Ok(format!("{}.tbd", stem)) + Ok(format!("{stem}.tbd")) } else { - Ok(format!("{}.tbd", stripped)) + Ok(format!("{stripped}.tbd")) } } else { Err(anyhow!("could not determine tbd path from {}", path)) @@ -165,13 +165,13 @@ impl TbdMetadata { export .objc_classes .iter() - .map(|cls| format!("_OBJC_CLASS_${}", cls)), + .map(|cls| format!("_OBJC_CLASS_${cls}")), ) .chain( export .objc_classes .iter() - .map(|cls| format!("_OBJC_METACLASS_${}", cls)), + .map(|cls| format!("_OBJC_METACLASS_${cls}")), ), ); @@ -214,13 +214,13 @@ impl TbdMetadata { export .objc_classes .iter() - .map(|cls| format!("_OBJC_CLASS_$_{}", cls)), + .map(|cls| format!("_OBJC_CLASS_$_{cls}")), ) .chain( export .objc_classes .iter() - .map(|cls| format!("_OBJC_METACLASS_$_{}", cls)), + .map(|cls| format!("_OBJC_METACLASS_$_{cls}")), ), ); @@ -249,13 +249,13 @@ impl TbdMetadata { export .objc_classes .iter() - .map(|cls| format!("_OBJC_CLASS_$_{}", cls)), + .map(|cls| format!("_OBJC_CLASS_$_{cls}")), ) .chain( export .objc_classes .iter() - .map(|cls| format!("_OBJC_METACLASS_$_{}", cls)), + .map(|cls| format!("_OBJC_METACLASS_$_{cls}")), ), ); res.weak_symbols @@ -370,8 +370,7 @@ impl IndexedSdks { "x86_64-apple-darwin" => "x86_64-macos", _ => { context.errors.push(format!( - "unknown target triple for Mach-O symbol analysis: {}", - triple + "unknown target triple for Mach-O symbol analysis: {triple}" )); return Ok(()); } diff --git a/src/main.rs b/src/main.rs index df441e1..99ef5b5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,8 +9,8 @@ mod release; mod validation; use { - anyhow::{anyhow, Context, Result}, - clap::{value_parser, Arg, ArgAction, Command}, + anyhow::{Context, Result, anyhow}, + clap::{Arg, ArgAction, Command, value_parser}, std::{ io::Read, path::{Path, PathBuf}, @@ -70,6 +70,12 @@ fn main_impl() -> Result<()> { .action(ArgAction::Set) .default_value("python-build-standalone") .help("GitHub repository name"), + ) + .arg( + Arg::new("github-uri") + .long("github-uri") + .action(ArgAction::Set) + .help("Alternative GitHub URI"), ), ); @@ -154,6 +160,12 @@ fn main_impl() -> Result<()> { .action(ArgAction::Set) .default_value("python-build-standalone") .help("GitHub repository name"), + ) + .arg( + Arg::new("github-uri") + .long("github-uri") + .action(ArgAction::Set) + .help("Alternative GitHub URI"), ), ); @@ -228,7 +240,7 @@ fn main() { let exit_code = match main_impl() { Ok(()) => 0, Err(err) => { - eprintln!("Error: {:?}", err); + eprintln!("Error: {err:?}"); 1 } }; diff --git a/src/release.rs b/src/release.rs index 60e46c9..b49f0fa 100644 --- a/src/release.rs +++ b/src/release.rs @@ -13,7 +13,7 @@ use std::{ use url::Url; use { crate::json::parse_python_json, - anyhow::{anyhow, Result}, + anyhow::{Result, anyhow}, once_cell::sync::Lazy, pep440_rs::VersionSpecifier, std::{ @@ -129,6 +129,18 @@ pub static RELEASE_TRIPLES: Lazy> = Lazy:: }], }, ); + h.insert( + "aarch64-pc-windows-msvc", + TripleRelease { + suffixes: vec!["pgo"], + install_only_suffix: "pgo", + python_version_requirement: Some(VersionSpecifier::from_str(">=3.11").unwrap()), + conditional_suffixes: vec![ConditionalSuffixes { + python_version_requirement: VersionSpecifier::from_str(">=3.13").unwrap(), + suffixes: vec!["freethreaded+pgo"], + }], + }, + ); // Linux. let linux_suffixes_pgo = vec!["debug", "pgo+lto"]; @@ -156,12 +168,12 @@ pub static RELEASE_TRIPLES: Lazy> = Lazy:: h.insert( "aarch64-unknown-linux-gnu", TripleRelease { - suffixes: linux_suffixes_nopgo.clone(), - install_only_suffix: "lto", + suffixes: linux_suffixes_pgo.clone(), + install_only_suffix: "pgo+lto", python_version_requirement: None, conditional_suffixes: vec![ConditionalSuffixes { python_version_requirement: VersionSpecifier::from_str(">=3.13").unwrap(), - suffixes: linux_suffixes_nopgo_freethreaded.clone(), + suffixes: linux_suffixes_pgo_freethreaded.clone(), }], }, ); @@ -327,6 +339,18 @@ pub static RELEASE_TRIPLES: Lazy> = Lazy:: }], }, ); + h.insert( + "aarch64-unknown-linux-musl", + TripleRelease { + suffixes: vec!["debug", "lto", "noopt"], + install_only_suffix: "lto", + python_version_requirement: None, + conditional_suffixes: vec![ConditionalSuffixes { + python_version_requirement: VersionSpecifier::from_str(">=3.13").unwrap(), + suffixes: linux_suffixes_musl_freethreaded.clone(), + }], + }, + ); h }); @@ -604,7 +628,7 @@ static LLVM_URL: Lazy = Lazy::new(|| { /// Returns the path to the top-level `llvm` directory. pub async fn bootstrap_llvm() -> Result { let url = &*LLVM_URL; - let filename = url.path_segments().unwrap().last().unwrap(); + let filename = url.path_segments().unwrap().next_back().unwrap(); let llvm_dir = Path::new("build").join("llvm"); std::fs::create_dir_all(&llvm_dir)?; @@ -622,7 +646,7 @@ pub async fn bootstrap_llvm() -> Result { // Download the tarball. let tarball_path = temp_dir .path() - .join(url.path_segments().unwrap().last().unwrap()); + .join(url.path_segments().unwrap().next_back().unwrap()); let mut tarball_file = tokio::fs::File::create(&tarball_path).await?; let mut bytes_stream = reqwest::Client::new() .get(url.clone()) diff --git a/src/validation.rs b/src/validation.rs index 19aace0..dbe8976 100644 --- a/src/validation.rs +++ b/src/validation.rs @@ -4,21 +4,21 @@ use { crate::{json::*, macho::*}, - anyhow::{anyhow, Context, Result}, + anyhow::{Context, Result, anyhow}, clap::ArgMatches, normalize_path::NormalizePath, object::{ + Architecture, Endianness, FileKind, Object, SectionIndex, SymbolScope, elf::{ - FileHeader32, FileHeader64, ET_DYN, ET_EXEC, STB_GLOBAL, STB_WEAK, STV_DEFAULT, - STV_HIDDEN, + ET_DYN, ET_EXEC, FileHeader32, FileHeader64, SHN_UNDEF, STB_GLOBAL, STB_WEAK, + STV_DEFAULT, STV_HIDDEN, }, - macho::{MachHeader32, MachHeader64, MH_OBJECT, MH_TWOLEVEL}, + macho::{LC_CODE_SIGNATURE, MH_OBJECT, MH_TWOLEVEL, MachHeader32, MachHeader64}, read::{ elf::{Dyn, FileHeader, SectionHeader, Sym}, - macho::{LoadCommandVariant, MachHeader, Nlist}, + macho::{LoadCommandVariant, MachHeader, Nlist, Section, Segment}, pe::{ImageNtHeaders, PeFile, PeFile32, PeFile64}, }, - Endianness, FileKind, Object, SectionIndex, SymbolScope, }, once_cell::sync::Lazy, std::{ @@ -33,7 +33,9 @@ use { const RECOGNIZED_TRIPLES: &[&str] = &[ "aarch64-apple-darwin", "aarch64-apple-ios", + "aarch64-pc-windows-msvc", "aarch64-unknown-linux-gnu", + "aarch64-unknown-linux-musl", "armv7-unknown-linux-gnueabi", "armv7-unknown-linux-gnueabihf", "arm64-apple-tvos", @@ -117,11 +119,13 @@ const PE_ALLOWED_LIBRARIES: &[&str] = &[ "libcrypto-1_1.dll", "libcrypto-1_1-x64.dll", "libcrypto-3.dll", + "libcrypto-3-arm64.dll", "libcrypto-3-x64.dll", "libffi-8.dll", "libssl-1_1.dll", "libssl-1_1-x64.dll", "libssl-3.dll", + "libssl-3-arm64.dll", "libssl-3-x64.dll", "python3.dll", "python39.dll", @@ -137,8 +141,14 @@ const PE_ALLOWED_LIBRARIES: &[&str] = &[ "tk86t.dll", ]; -// CPython 3.14 uses tcl/tk 8.6.14+ which includes a bundled zlib and dynamically links to msvcrt. -const PE_ALLOWED_LIBRARIES_314: &[&str] = &["msvcrt.dll", "zlib1.dll"]; +// CPython 3.14 and ARM64 use a newer version of tcl/tk (8.6.14+) which includes a bundled zlib that +// dynamically links some system libraries +const PE_ALLOWED_LIBRARIES_314: &[&str] = &[ + "zlib1.dll", + "api-ms-win-crt-private-l1-1-0.dll", // zlib loads this library on arm64, 3.14+ + "msvcrt.dll", // zlib loads this library +]; +const PE_ALLOWED_LIBRARIES_ARM64: &[&str] = &["msvcrt.dll", "zlib1.dll"]; static GLIBC_MAX_VERSION_BY_TRIPLE: Lazy>> = Lazy::new(|| { @@ -202,6 +212,10 @@ static GLIBC_MAX_VERSION_BY_TRIPLE: Lazy>> = + Lazy::new(|| { + [ + ( + // libcrypt is provided by the system, but only on older distros. + "_crypt", + vec!["libcrypt.so.1"], + ), + ( + // libtcl and libtk are shipped in our distribution. + "_tkinter", + vec!["libtcl8.6.so", "libtk8.6.so"], + ), + ] + .iter() + .cloned() + .collect() + }); + static DARWIN_ALLOWED_DYLIBS: Lazy> = Lazy::new(|| { [ MachOAllowedDylib { @@ -492,11 +525,36 @@ static IOS_ALLOWED_DYLIBS: Lazy> = Lazy::new(|| { .to_vec() }); +static ALLOWED_DYLIBS_BY_MODULE: Lazy>> = + Lazy::new(|| { + [( + // libtcl and libtk are shipped in our distribution. + "_tkinter", + vec![ + MachOAllowedDylib { + name: "@rpath/libtcl8.6.dylib".to_string(), + max_compatibility_version: "8.6.0".try_into().unwrap(), + required: true, + }, + MachOAllowedDylib { + name: "@rpath/libtk8.6.dylib".to_string(), + max_compatibility_version: "8.6.0".try_into().unwrap(), + required: true, + }, + ], + )] + .iter() + .cloned() + .collect() + }); + static PLATFORM_TAG_BY_TRIPLE: Lazy> = Lazy::new(|| { [ ("aarch64-apple-darwin", "macosx-11.0-arm64"), ("aarch64-apple-ios", "iOS-aarch64"), + ("aarch64-pc-windows-msvc", "win-arm64"), ("aarch64-unknown-linux-gnu", "linux-aarch64"), + ("aarch64-unknown-linux-musl", "linux-aarch64"), ("armv7-unknown-linux-gnueabi", "linux-arm"), ("armv7-unknown-linux-gnueabihf", "linux-arm"), ("i686-pc-windows-msvc", "win32"), @@ -534,9 +592,12 @@ const ELF_BANNED_SYMBOLS: &[&str] = &[ /// We use this list to spot test behavior of symbols belonging to dependency packages. /// The list is obviously not complete. const DEPENDENCY_PACKAGE_SYMBOLS: &[&str] = &[ - // libX11 - "XClearWindow", - "XFlush", + /* TODO(geofft): Tk provides these as no-op stubs on macOS, make it + * stop doing that so we can re-enable the check + * // libX11 + * "XClearWindow", + * "XFlush", + */ // OpenSSL "BIO_ADDR_new", "BN_new", @@ -581,6 +642,11 @@ const DEPENDENCY_PACKAGE_SYMBOLS: &[&str] = &[ // liblzma "lzma_index_init", "lzma_stream_encoder", +]; + +// TODO(geofft): Conditionally prohibit these exported symbols +// everywhere except libtcl and libtk. This should be a hashmap +const _DEPENDENCY_PACKAGE_SYMBOLS_BUNDLED: &[&str] = &[ // tcl "Tcl_Alloc", "Tcl_ChannelName", @@ -589,6 +655,10 @@ const DEPENDENCY_PACKAGE_SYMBOLS: &[&str] = &[ "TkBindInit", "TkCreateFrame", "Tk_FreeGC", + // _ctypes_test module + "my_free", + "mystrdup", + "top", ]; const PYTHON_EXPORTED_SYMBOLS: &[&str] = &[ @@ -768,6 +838,7 @@ const GLOBAL_EXTENSIONS_PYTHON_3_14: &[&str] = &[ "_zoneinfo", "_hmac", "_types", + "_zstd", ]; const GLOBAL_EXTENSIONS_MACOS: &[&str] = &["_scproxy"]; @@ -803,8 +874,7 @@ const GLOBAL_EXTENSIONS_WINDOWS: &[&str] = &[ "winsound", ]; -// TODO(zanieb): Move `_zstd` to non-Windows specific once we add support on Unix. -const GLOBAL_EXTENSIONS_WINDOWS_3_14: &[&str] = &["_wmi", "_zstd"]; +const GLOBAL_EXTENSIONS_WINDOWS_3_14: &[&str] = &["_wmi"]; const GLOBAL_EXTENSIONS_WINDOWS_PRE_3_13: &[&str] = &["_msi"]; @@ -812,7 +882,7 @@ const GLOBAL_EXTENSIONS_WINDOWS_PRE_3_13: &[&str] = &["_msi"]; const GLOBAL_EXTENSIONS_WINDOWS_NO_STATIC: &[&str] = &["_testinternalcapi", "_tkinter"]; /// Extension modules that should be built as shared libraries. -const SHARED_LIBRARY_EXTENSIONS: &[&str] = &["_crypt"]; +const SHARED_LIBRARY_EXTENSIONS: &[&str] = &["_crypt", "_ctypes_test", "_tkinter"]; const PYTHON_VERIFICATIONS: &str = include_str!("verify_distribution.py"); @@ -885,6 +955,7 @@ fn validate_elf>( let wanted_cpu_type = match target_triple { "aarch64-unknown-linux-gnu" => object::elf::EM_AARCH64, + "aarch64-unknown-linux-musl" => object::elf::EM_AARCH64, "armv7-unknown-linux-gnueabi" => object::elf::EM_ARM, "armv7-unknown-linux-gnueabihf" => object::elf::EM_ARM, "i686-unknown-linux-gnu" => object::elf::EM_386, @@ -902,7 +973,7 @@ fn validate_elf>( "x86_64_v2-unknown-linux-musl" => object::elf::EM_X86_64, "x86_64_v3-unknown-linux-musl" => object::elf::EM_X86_64, "x86_64_v4-unknown-linux-musl" => object::elf::EM_X86_64, - _ => panic!("unhandled target triple: {}", target_triple), + _ => panic!("unhandled target triple: {target_triple}"), }; let endian = elf.endian()?; @@ -927,27 +998,23 @@ fn validate_elf>( if json.libpython_link_mode == "shared" { if target_triple.contains("-musl") { // On musl, we link to `libpython` and rely on `RUN PATH` - allowed_libraries.push(format!("libpython{}.so.1.0", python_major_minor)); - allowed_libraries.push(format!("libpython{}d.so.1.0", python_major_minor)); - allowed_libraries.push(format!("libpython{}t.so.1.0", python_major_minor)); - allowed_libraries.push(format!("libpython{}td.so.1.0", python_major_minor)); + allowed_libraries.push(format!("libpython{python_major_minor}.so.1.0")); + allowed_libraries.push(format!("libpython{python_major_minor}d.so.1.0")); + allowed_libraries.push(format!("libpython{python_major_minor}t.so.1.0")); + allowed_libraries.push(format!("libpython{python_major_minor}td.so.1.0")); } else { // On glibc, we can use `$ORIGIN` for relative, reloctable linking allowed_libraries.push(format!( - "$ORIGIN/../lib/libpython{}.so.1.0", - python_major_minor + "$ORIGIN/../lib/libpython{python_major_minor}.so.1.0" )); allowed_libraries.push(format!( - "$ORIGIN/../lib/libpython{}d.so.1.0", - python_major_minor + "$ORIGIN/../lib/libpython{python_major_minor}d.so.1.0" )); allowed_libraries.push(format!( - "$ORIGIN/../lib/libpython{}t.so.1.0", - python_major_minor + "$ORIGIN/../lib/libpython{python_major_minor}t.so.1.0" )); allowed_libraries.push(format!( - "$ORIGIN/../lib/libpython{}td.so.1.0", - python_major_minor + "$ORIGIN/../lib/libpython{python_major_minor}td.so.1.0" )); } } @@ -957,11 +1024,13 @@ fn validate_elf>( allowed_libraries.push("libc.so".to_string()); } - // Allow the _crypt extension module - and only it - to link against libcrypt, - // which is no longer universally present in Linux distros. + // Allow certain extension modules to link against shared libraries + // (either from the system or from our distribution). if let Some(filename) = path.file_name() { - if filename.to_string_lossy().starts_with("_crypt") { - allowed_libraries.push("libcrypt.so.1".to_string()); + if let Some((module, _)) = filename.to_string_lossy().split_once(".cpython-") { + if let Some(extra) = ELF_ALLOWED_LIBRARIES_BY_MODULE.get(module) { + allowed_libraries.extend(extra.iter().map(|x| x.to_string())); + } } } @@ -1041,7 +1110,7 @@ fn validate_elf>( { let strings = symbols.strings(); - for (symbol_index, symbol) in symbols.iter().enumerate() { + for (symbol_index, symbol) in symbols.enumerate() { let name = String::from_utf8_lossy(symbol.name(endian, strings)?); // If symbol versions are defined and we're in the .dynsym section, there should @@ -1099,6 +1168,7 @@ fn validate_elf>( // to prevent them from being exported. if DEPENDENCY_PACKAGE_SYMBOLS.contains(&name.as_ref()) && matches!(symbol.st_bind(), STB_GLOBAL | STB_WEAK) + && symbol.st_shndx(endian) != SHN_UNDEF && symbol.st_visibility() != STV_HIDDEN { context.errors.push(format!( @@ -1114,6 +1184,7 @@ fn validate_elf>( if filename.starts_with("libpython") && filename.ends_with(".so.1.0") && matches!(symbol.st_bind(), STB_GLOBAL | STB_WEAK) + && symbol.st_shndx(endian) != SHN_UNDEF && symbol.st_visibility() == STV_DEFAULT { context.libpython_exported_symbols.insert(name.to_string()); @@ -1154,8 +1225,8 @@ fn validate_macho>( bytes: &[u8], ) -> Result<()> { let advertised_target_version = - semver::Version::parse(&format!("{}.0", advertised_target_version))?; - let advertised_sdk_version = semver::Version::parse(&format!("{}.0", advertised_sdk_version))?; + semver::Version::parse(&format!("{advertised_target_version}.0"))?; + let advertised_sdk_version = semver::Version::parse(&format!("{advertised_sdk_version}.0"))?; let endian = header.endian()?; @@ -1189,6 +1260,8 @@ fn validate_macho>( let mut undefined_symbols = vec![]; let mut target_version = None; let mut sdk_version = None; + let mut has_code_signature = false; + let mut lowest_file_offset = u64::MAX; while let Some(load_command) = load_commands.next()? { match load_command.variant()? { @@ -1215,7 +1288,16 @@ fn validate_macho>( dylib_names.push(lib.clone()); - let allowed = allowed_dylibs_for_triple(target_triple); + let mut allowed = allowed_dylibs_for_triple(target_triple); + // Allow certain extension modules to link against shared libraries + // (either from the system or from our distribution). + if let Some(filename) = path.file_name() { + if let Some((module, _)) = filename.to_string_lossy().split_once(".cpython-") { + if let Some(extra) = ALLOWED_DYLIBS_BY_MODULE.get(module) { + allowed.extend(extra.clone()); + } + } + } if let Some(entry) = allowed.iter().find(|l| l.name == lib) { let load_version = @@ -1302,10 +1384,38 @@ fn validate_macho>( } } } + LoadCommandVariant::Segment32(segment, segment_data) => { + for section in segment.sections(endian, segment_data)? { + if let Some((offset, _)) = section.file_range(endian) { + lowest_file_offset = lowest_file_offset.min(offset); + } + } + } + LoadCommandVariant::Segment64(segment, segment_data) => { + for section in segment.sections(endian, segment_data)? { + if let Some((offset, _)) = section.file_range(endian) { + lowest_file_offset = lowest_file_offset.min(offset); + } + } + } + LoadCommandVariant::LinkeditData(c) if c.cmd.get(endian) == LC_CODE_SIGNATURE => { + has_code_signature = true; + } _ => {} } } + let end_of_load_commands = + std::mem::size_of_val(header) as u64 + header.sizeofcmds(endian) as u64; + if header.filetype(endian) != MH_OBJECT + && end_of_load_commands + if has_code_signature { 0 } else { 16 } > lowest_file_offset + { + context.errors.push(format!( + "{}: Insufficient headerpad between end of load commands {end_of_load_commands:#x} and beginning of code {lowest_file_offset:#x}", + path.display(), + )); + } + if let Some(actual_target_version) = target_version { if actual_target_version != advertised_target_version { context.errors.push(format!( @@ -1375,15 +1485,17 @@ fn validate_pe<'data, Pe: ImageNtHeaders>( let lib = String::from_utf8(lib.to_vec())?; match python_major_minor { - "3.9" | "3.10" | "3.11" | "3.12" | "3.13" => {} + "3.11" | "3.12" | "3.13" if pe.architecture() == Architecture::Aarch64 => { + if PE_ALLOWED_LIBRARIES_ARM64.contains(&lib.as_str()) { + continue; + } + } "3.14" => { if PE_ALLOWED_LIBRARIES_314.contains(&lib.as_str()) { continue; } } - _ => { - panic!("unhandled Python version: {}", python_major_minor); - } + _ => {} } if !PE_ALLOWED_LIBRARIES.contains(&lib.as_str()) { @@ -1545,7 +1657,7 @@ fn validate_extension_modules( wanted.extend(GLOBAL_EXTENSIONS_PYTHON_3_14); } _ => { - panic!("unhandled Python version: {}", python_major_minor); + panic!("unhandled Python version: {python_major_minor}"); } } @@ -1616,11 +1728,11 @@ fn validate_extension_modules( } for extra in have_extensions.difference(&wanted) { - errors.push(format!("extra/unknown extension module: {}", extra)); + errors.push(format!("extra/unknown extension module: {extra}")); } for missing in wanted.difference(have_extensions) { - errors.push(format!("missing extension module: {}", missing)); + errors.push(format!("missing extension module: {missing}")); } Ok(errors) @@ -1675,7 +1787,7 @@ fn validate_json(json: &PythonJsonMain, triple: &str, is_debug: bool) -> Result< for extension in json.build_info.extensions.keys() { if GLOBALLY_BANNED_EXTENSIONS.contains(&extension.as_str()) { - errors.push(format!("banned extension detected: {}", extension)); + errors.push(format!("banned extension detected: {extension}")); } } @@ -1712,11 +1824,7 @@ fn validate_distribution( let triple = RECOGNIZED_TRIPLES .iter() - .find(|triple| { - dist_path - .to_string_lossy() - .contains(&format!("-{}-", triple)) - }) + .find(|triple| dist_path.to_string_lossy().contains(&format!("-{triple}-"))) .ok_or_else(|| { anyhow!( "could not identify triple from distribution filename: {}", @@ -1767,7 +1875,7 @@ fn validate_distribution( .unwrap() .python_paths .values() - .map(|x| format!("python/{}", x)), + .map(|x| format!("python/{x}")), ); } else { context.errors.push(format!( @@ -1915,8 +2023,7 @@ fn validate_distribution( for path in wanted_python_paths { context.errors.push(format!( - "path prefix {} seen in python_paths does not appear in archive", - path + "path prefix {path} seen in python_paths does not appear in archive" )); } @@ -1930,7 +2037,7 @@ fn validate_distribution( for lib in wanted_dylibs.difference(&context.seen_dylibs) { context .errors - .push(format!("required library dependency {} not seen", lib)); + .push(format!("required library dependency {lib} not seen")); } if triple.contains("-windows-") && is_static { @@ -1967,8 +2074,7 @@ fn validate_distribution( if let Some(shared) = &ext.shared_lib { if !seen_paths.contains(&PathBuf::from("python").join(shared)) { context.errors.push(format!( - "extension module {} references missing shared library path {}", - name, shared + "extension module {name} references missing shared library path {shared}" )); } } @@ -1990,13 +2096,11 @@ fn validate_distribution( if want_shared && ext.shared_lib.is_none() { context.errors.push(format!( - "extension module {} does not have a shared library", - name + "extension module {name} does not have a shared library" )); } else if !want_shared && ext.shared_lib.is_some() { context.errors.push(format!( - "extension module {} contains a shared library unexpectedly", - name + "extension module {name} contains a shared library unexpectedly" )); } @@ -2049,7 +2153,7 @@ fn validate_distribution( if triple.contains("-apple-darwin") { if let Some(sdks) = macos_sdks { if let Some(value) = json.as_ref().unwrap().apple_sdk_deployment_target.as_ref() { - let target_minimum_sdk = semver::Version::parse(&format!("{}.0", value))?; + let target_minimum_sdk = semver::Version::parse(&format!("{value}.0"))?; sdks.validate_context(&mut context, target_minimum_sdk, triple)?; } else { @@ -2137,7 +2241,7 @@ pub fn command_validate_distribution(args: &ArgMatches) -> Result<()> { println!(" {} OK", path.display()); } else { for error in errors { - println!(" error: {}", error); + println!(" error: {error}"); } success = false; diff --git a/src/verify_distribution.py b/src/verify_distribution.py index 2131d7a..62d58f9 100644 --- a/src/verify_distribution.py +++ b/src/verify_distribution.py @@ -114,7 +114,7 @@ def test_hashlib(self): def test_sqlite(self): import sqlite3 - self.assertEqual(sqlite3.sqlite_version_info, (3, 47, 1)) + self.assertEqual(sqlite3.sqlite_version_info, (3, 50, 4)) # Optional SQLite3 features are enabled. conn = sqlite3.connect(":memory:") @@ -122,6 +122,22 @@ def test_sqlite(self): self.assertTrue(hasattr(conn, "enable_load_extension")) # Backup feature requires modern SQLite, which we always have. self.assertTrue(hasattr(conn, "backup")) + # Ensure that various extensions are present. These will raise if they are not. Note that + # CPython upstream carries configuration flags for the Windows build, so geopoly is missing + # on all versions and rtree is missing in 3.9. On non-Windows platforms, we configure + # SQLite ourselves. We might want to patch the build to enable these on Windows, see #666. + extensions = ["fts3", "fts4", "fts5"] + if os.name != "nt": + extensions.append("geopoly") + if os.name != "nt" or sys.version_info[0:2] > (3, 9): + extensions.append("rtree") + cursor = conn.cursor() + for extension in extensions: + with self.subTest(extension=extension): + cursor.execute( + f"CREATE VIRTUAL TABLE test{extension} USING {extension}(a, b, c);" + ) + conn.close() def test_ssl(self): import ssl @@ -156,6 +172,18 @@ def test_gil_disabled(self): self.assertEqual(sysconfig.get_config_var("Py_GIL_DISABLED"), wanted) + @unittest.skipIf( + sys.version_info[:2] < (3, 14), + "zstd is only available in 3.14+", + ) + def test_zstd_multithreaded(self): + from compression import zstd + + max_threads = zstd.CompressionParameter.nb_workers.bounds()[1] + assert max_threads > 0, ( + "Expected multithreading to be enabled but max threads is zero" + ) + @unittest.skipIf("TCL_LIBRARY" not in os.environ, "TCL_LIBRARY not set") @unittest.skipIf("DISPLAY" not in os.environ, "DISPLAY not set") def test_tkinter(self):