python-distributions.yml 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. name: Build Python distributions
  2. on:
  3. push:
  4. branches: [ main, master ]
  5. pull_request:
  6. schedule:
  7. - cron: "0 6 * * *" # Daily 6AM UTC build
  8. jobs:
  9. define-matrix:
  10. runs-on: ubuntu-latest
  11. outputs:
  12. matrix: ${{ steps.merged-identifiers.outputs.merged-identifiers }}
  13. steps:
  14. - uses: actions/checkout@v4
  15. - uses: actions/setup-python@v5
  16. with:
  17. python-version: 3.x
  18. cache: pip
  19. - name: Install jq
  20. run: sudo apt-get update && sudo apt-get install -y jq
  21. - name: Install cibuildwheel
  22. run: pip install cibuildwheel
  23. - name: Find build identifiers using cibuildwheel --print-build-identifiers
  24. id: all-build-identifiers
  25. run: |
  26. echo "linux=$(cibuildwheel --platform linux --print-build-identifiers | tr '\n' ' ')" >> $GITHUB_OUTPUT
  27. echo "macos=$(cibuildwheel --platform macos --print-build-identifiers | tr '\n' ' ')" >> $GITHUB_OUTPUT
  28. echo "windows=$(cibuildwheel --platform windows --print-build-identifiers | tr '\n' ' ')" >> $GITHUB_OUTPUT
  29. - name: Select build identifiers
  30. id: select-build-identifiers
  31. run: |
  32. if [ "$GITHUB_REF" = "refs/heads/main" ] || [ "$GITHUB_REF" = "refs/heads/master" ] || [ "$GITHUB_REF" = "refs/tags/"* ]; then
  33. echo 'linux=${{ steps.all-build-identifiers.outputs.linux }}' >> $GITHUB_OUTPUT
  34. echo 'windows=${{ steps.all-build-identifiers.outputs.windows }}' >> $GITHUB_OUTPUT
  35. echo 'macos=${{ steps.all-build-identifiers.outputs.macos }}' >> $GITHUB_OUTPUT
  36. else
  37. echo "linux=$(echo -n '${{ steps.all-build-identifiers.outputs.linux }}' | awk '{print $NF}')" >> $GITHUB_OUTPUT
  38. echo "macos=$(echo -n '${{ steps.all-build-identifiers.outputs.macos }}' | awk '{print $NF}')" >> $GITHUB_OUTPUT
  39. echo "windows=$(echo -n '${{ steps.all-build-identifiers.outputs.windows }}' | awk '{print $NF}')" >> $GITHUB_OUTPUT
  40. fi
  41. - name: Output build identifiers
  42. id: json-identifiers
  43. run: |
  44. echo "linux=$(echo -n '${{ steps.select-build-identifiers.outputs.linux }}' | jq -R -s -c 'split(" ") | map(select(length > 0)) | [.[] | {os: "ubuntu-latest", "build-identifier": .}]')" >> $GITHUB_OUTPUT
  45. echo "macos=$(echo -n '${{ steps.select-build-identifiers.outputs.macos }}' | jq -R -s -c 'split(" ") | map(select(length > 0)) | [.[] | {os: "macos-latest", "build-identifier": .}]')" >> $GITHUB_OUTPUT
  46. echo "windows=$(echo -n '${{ steps.select-build-identifiers.outputs.windows }}' | jq -R -s -c 'split(" ") | map(select(length > 0)) | [.[] | {os: "windows-latest", "build-identifier": .}]')" >> $GITHUB_OUTPUT
  47. - name: Merge build identifiers
  48. id: merged-identifiers
  49. run: |
  50. echo merged-identifiers=$(echo -n '${{ steps.json-identifiers.outputs.linux }} ${{ steps.json-identifiers.outputs.macos }} ${{ steps.json-identifiers.outputs.windows }}' | jq -c -s 'add') >> $GITHUB_OUTPUT
  51. build-wheels:
  52. runs-on: ${{ matrix.os }}
  53. needs: define-matrix
  54. strategy:
  55. matrix:
  56. include: ${{ fromJSON(needs.define-matrix.outputs.matrix ) }}
  57. fail-fast: true
  58. steps:
  59. - uses: actions/checkout@v4
  60. - uses: actions/setup-python@v5
  61. with:
  62. cache: pip
  63. - name: Install dependencies
  64. run: |
  65. python -m pip install --upgrade pip
  66. pip install setuptools wheel cibuildwheel setuptools-rust
  67. - name: Set up QEMU
  68. uses: docker/setup-qemu-action@v3
  69. if: "matrix.os == 'ubuntu-latest'"
  70. - name: Build wheels
  71. run: python -m cibuildwheel --output-dir wheelhouse
  72. env:
  73. CIBW_BUILD: "${{ matrix.build-identifier }}*"
  74. - name: Upload wheels
  75. uses: actions/upload-artifact@v4
  76. with:
  77. name: artifact-${{ matrix.build-identifier }}
  78. path: ./wheelhouse/*.whl
  79. build-sdist:
  80. runs-on: ubuntu-latest
  81. steps:
  82. - uses: actions/checkout@v4
  83. - uses: actions/setup-python@v5
  84. with:
  85. cache: pip
  86. - name: Install dependencies
  87. run: |
  88. python -m pip install --upgrade pip
  89. pip install build
  90. - name: Build sdist
  91. run: python -m build --sdist
  92. - name: Upload sdist
  93. uses: actions/upload-artifact@v4
  94. with:
  95. name: artifact-source
  96. path: ./dist/*.tar.gz
  97. test-sdist:
  98. needs:
  99. - build-sdist
  100. runs-on: ubuntu-latest
  101. steps:
  102. - uses: actions/setup-python@v5
  103. with:
  104. cache: pip
  105. - name: Install dependencies
  106. run: |
  107. python -m pip install --upgrade pip
  108. pip install twine
  109. - name: Download sdist
  110. uses: actions/download-artifact@v4
  111. with:
  112. name: artifact-source
  113. path: dist
  114. - name: Test sdist
  115. run: twine check dist/*
  116. - name: Test installation from sdist
  117. run: pip install dist/*.tar.gz
  118. publish:
  119. runs-on: ubuntu-latest
  120. needs:
  121. - build-wheels
  122. - build-sdist
  123. if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/dulwich-')
  124. permissions:
  125. id-token: write
  126. environment:
  127. name: pypi
  128. url: https://pypi.org/p/dulwich
  129. steps:
  130. - name: Download distributions
  131. uses: actions/download-artifact@v4
  132. with:
  133. merge-multiple: true
  134. pattern: artifact-*
  135. path: dist
  136. - name: Publish package distributions to PyPI
  137. uses: pypa/gh-action-pypi-publish@release/v1