|
| 1 | + |
1 | 2 | name: release |
2 | 3 |
|
3 | 4 | on: |
4 | 5 | push: |
5 | | - branches: [deploy] |
| 6 | + branches: [release-test-pypi, release-test-github, release-test-full] |
6 | 7 | tags: [v*] |
7 | 8 | workflow_dispatch: |
8 | 9 |
|
| 10 | + |
9 | 11 | jobs: |
10 | | - build-and-deploy: |
| 12 | + build: |
11 | 13 | runs-on: ubuntu-latest |
12 | | - environment: release |
13 | | - |
14 | | - permissions: |
15 | | - id-token: write # Used to authenticate to PyPI via OIDC |
16 | | - |
17 | | - contents: write # Used to authenticate github release publish |
| 14 | + outputs: |
| 15 | + release-artifact-id: ${{ steps.upload-release.outputs.artifact-id }} |
| 16 | + wheel-artifact-id: ${{ steps.upload-wheel.outputs.artifact-id }} |
| 17 | + artifact-runner: ${{ github.job }} |
18 | 18 |
|
19 | 19 | steps: |
20 | 20 | - name: Checkout code |
21 | | - uses: actions/checkout@v4 |
| 21 | + uses: actions/checkout@v5 |
22 | 22 |
|
23 | 23 | - name: Reject any VCS dependencies |
24 | | - shell: python |
25 | | - continue-on-error: ${{ github.ref_type == 'branch' }} |
26 | | - run: | |
27 | | - import re, tomllib |
28 | | - manifest = tomllib.load(open('pyproject.toml', 'rb')) |
29 | | - deps = manifest['build-system']['requires'] |
30 | | - deps.extend(manifest['project']['dependencies']) |
31 | | - if rejects := list(filter(re.compile(r'@[^+]+').search, deps)): |
32 | | - rejects = " \n".join(sorted(rejects)) |
33 | | - raise Exception(f'VCS dependencies were detected in [build-system]:\n {rejects}') |
| 24 | + continue-on-error: ${{ github.ref_type == 'branch' && github.ref_name != 'release-test-full' }} |
| 25 | + uses: pkgcore/gh-actions/reject-python-vcs-deps@main |
34 | 26 |
|
35 | 27 | - name: Set up Python 3.13 |
36 | 28 | uses: actions/setup-python@v5 |
37 | 29 | with: |
38 | 30 | python-version: "3.13" |
| 31 | + cache: 'pip' |
| 32 | + cache-dependency-path: pyproject.toml |
39 | 33 |
|
40 | 34 | - name: Install dependencies |
41 | 35 | run: | |
42 | 36 | python -m pip install --upgrade pip |
43 | | - pip install build ".[test,doc]" |
| 37 | + pip install build ".[doc]" |
44 | 38 |
|
45 | | - - name: Test with pytest |
46 | | - env: |
47 | | - PY_COLORS: 1 # forcibly enable pytest colors |
48 | | - run: pytest |
49 | | - |
50 | | - - name: Build sdist |
| 39 | + - name: Build the release |
51 | 40 | run: | |
52 | | - git clean -fxd |
53 | | - make man |
54 | | - make sdist |
55 | | -
|
56 | | - - name: Build wheel |
57 | | - run: make wheel |
| 41 | + make release |
58 | 42 |
|
59 | 43 | - name: Output dist file info |
60 | 44 | run: | |
61 | 45 | sha512sum dist/* |
| 46 | + echo ::group::Release contents |
62 | 47 | tar -ztf dist/*.tar.gz | sort |
| 48 | + echo ::endgroup:: |
| 49 | + echo ::group::All generated content in dist |
| 50 | + find . |
| 51 | + echo ::endgroup:: |
| 52 | +
|
| 53 | + - name: Upload wheel |
| 54 | + id: upload-wheel |
| 55 | + uses: actions/upload-artifact@v5 |
| 56 | + with: |
| 57 | + name: wheel-release |
| 58 | + path: dist/*.whl |
| 59 | + if-no-files-found: error |
63 | 60 |
|
64 | | - - uses: actions/upload-artifact@v4 |
| 61 | + - name: Upload release source |
| 62 | + id: upload-release |
| 63 | + uses: actions/upload-artifact@v5 |
65 | 64 | with: |
66 | | - name: results |
67 | | - path: dist/* |
| 65 | + name: release-source |
| 66 | + path: dist/*.tar.gz |
| 67 | + if-no-files-found: error |
| 68 | + |
| 69 | + test: |
| 70 | + needs: [build] |
| 71 | + uses: ./.github/workflows/test.yml |
| 72 | + with: |
| 73 | + release-artifact-id: ${{ needs.build.outputs.release-artifact-id }} |
| 74 | + disable-format-check: true |
| 75 | + |
| 76 | + publish: |
| 77 | + if: github.ref_type == 'tag' |
| 78 | + needs: [build, test] |
| 79 | + environment: release |
| 80 | + permissions: |
| 81 | + id-token: write # Used to authenticate to PyPI via OIDC |
| 82 | + contents: write # release uploads |
| 83 | + runs-on: ubuntu-latest |
68 | 84 |
|
69 | | - - name: publish |
70 | | - uses: pypa/gh-action-pypi-publish@release/v1 |
71 | | - if: startsWith(github.ref, 'refs/tags/') |
| 85 | + steps: |
| 86 | + - &common_download_artifacts |
| 87 | + name: Download artifacts |
| 88 | + uses: actions/download-artifact@v5 |
| 89 | + with: |
| 90 | + merge-multiple: true # store both in the root, not in named directories |
| 91 | + artifact-ids: ${{ needs.build.outputs.release-artifact-id }},${{ needs.build.outputs.wheel-artifact-id }} |
| 92 | + |
| 93 | + - name: Publish github source |
| 94 | + uses: softprops/action-gh-release@v2 |
| 95 | + with: |
| 96 | + files: '*.tar.*' |
| 97 | + fail_on_unmatched_files: true |
| 98 | + |
| 99 | + - name: Publish to PyPi server |
| 100 | + uses: pypa/gh-action-pypi-publish@release/v1.13 |
| 101 | + with: |
| 102 | + packages-dir: . |
72 | 103 |
|
73 | | - - name: Create GitHub release |
74 | | - uses: softprops/action-gh-release@v1 |
75 | | - if: startsWith(github.ref, 'refs/tags/') |
| 104 | + test-publish: |
| 105 | + # use the full form to ensure insane tags and errors in 'on' filter still don't kick. |
| 106 | + if: github.ref_type == 'branch' |
| 107 | + needs: [build, test] |
| 108 | + environment: test-release |
| 109 | + permissions: |
| 110 | + id-token: write # Used to authenticate to PyPI via OIDC |
| 111 | + contents: write # release uploads- |
| 112 | + runs-on: ubuntu-latest |
| 113 | + |
| 114 | + steps: |
| 115 | + - *common_download_artifacts |
| 116 | + - name: Publish github source |
| 117 | + uses: softprops/action-gh-release@v2 |
| 118 | + if: github.ref_name == 'release-test-github' || github.ref_name == 'release-test-full' |
76 | 119 | with: |
77 | | - files: dist/*.tar.gz |
| 120 | + files: '*.tar.*' |
78 | 121 | fail_on_unmatched_files: true |
79 | 122 | draft: true |
80 | 123 |
|
| 124 | + - name: Publish to Test PyPi server |
| 125 | + if: github.ref_name == 'release-test-pypi' || github.ref_name == 'release-test-full' |
| 126 | + uses: pypa/gh-action-pypi-publish@release/v1.13 |
| 127 | + with: |
| 128 | + packages-dir: . |
| 129 | + repository-url: https://test.pypi.org/legacy/ |
| 130 | + # attestations are bound in a way re-releasing isn't possible. Disable for tests. |
| 131 | + attestations: false |
| 132 | + |
81 | 133 | build-and-push-docker-image: |
82 | 134 | if: startsWith(github.ref, 'refs/tags/') |
83 | | - needs: ["build-and-deploy"] |
| 135 | + needs: ["publish"] |
84 | 136 | runs-on: ubuntu-latest |
85 | 137 | environment: release |
86 | 138 |
|
|
0 commit comments