From 1aa143e70dbccffc2e9703852056fb9835b0b1a6 Mon Sep 17 00:00:00 2001 From: Quentin Kaiser Date: Mon, 31 Aug 2026 11:05:48 +0200 Subject: [PATCH] ci: move to PyPy Trusted Publishing Move to PyPi Trusted Publishing using an ID token instead of relying on a fixed token. Split the release workflow in 3 steps: - build phase with uv, followed by an artifact upload - publication to PyPi by pulling built artifacts first - publications to Test PyPi by pulling built artifacts first Publication to PyPi happens when pushing a tag to master. Publication to Test PyPi happens when pushing commits to master. This follows official guidance from https://packaging.python.org/en/latest/guides/publishing-package-distribution-releases-using-github-actions-ci-cd-workflows/ --- .github/workflows/publish.yml | 108 ++++++++++++++++++++++++++-------- 1 file changed, 82 insertions(+), 26 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index fd63864..769834a 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -1,37 +1,93 @@ -name: PyPI Publish +name: Publish Python distribution on: - release: - types: [published] - workflow_dispatch: - inputs: - test_release: - description: If true, publish to test.pypi.org - required: true - default: true - type: boolean + push: + branches: [master] + tags: ["*"] + +permissions: + contents: read + +# Publishing runs must not be cancelled: every default-branch push gets a +# distinct TestPyPI version. +concurrency: + group: ${{ github.workflow }}-${{ github.run_id }} + cancel-in-progress: false + +env: + PACKAGE_NAME: onekey_client jobs: - publish: + build: + name: Build distribution runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - - name: Install uv & Python + with: + persist-credentials: false + - name: Install uv uses: astral-sh/setup-uv@v7 with: enable-cache: true cache-dependency-glob: "uv.lock" - - run: uv build - - - name: Publish to TestPyPI - if: ${{ github.event_name == 'workflow_dispatch' && inputs.test_release == true }} - run: uv publish - env: - UV_PUBLISH_TOKEN: ${{ secrets.TEST_PYPI_API_TOKEN }} - UV_PUBLISH_URL: https://test.pypi.org/legacy/ - - - name: Publish to PyPI - if: ${{ github.event_name != 'workflow_dispatch' || inputs.test_release == false }} - run: uv publish - env: - UV_PUBLISH_TOKEN: ${{ secrets.POETRY_PYPI_TOKEN_PYPI }} + - name: Build distribution + run: uv build + - name: Store distribution packages + uses: actions/upload-artifact@v5 + + publish-to-testpypi: + name: Publish distribution to TestPyPI + if: github.ref == format('refs/heads/{0}', github.event.repository.default_branch) + needs: build + runs-on: ubuntu-latest + environment: + name: testpypi + url: https://test.pypi.org/p/onekey_client + permissions: + id-token: write + steps: + - uses: actions/download-artifact@v6 + with: + name: python-package-distributions + path: dist/ + - uses: pypa/gh-action-pypi-publish@release/v1 + with: + repository-url: https://test.pypi.org/legacy/ + + publish-to-pypi: + name: Publish distribution to PyPI + needs: build + if: startsWith(github.ref, 'refs/tags/') + runs-on: ubuntu-latest + environment: + name: pypi + url: https://pypi.org/p/onekey_client + permissions: + id-token: write + steps: + - uses: actions/download-artifact@v6 + with: + name: python-package-distributions + path: dist/ + - uses: pypa/gh-action-pypi-publish@release/v1 + + release: + name: Create GitHub Release + if: startsWith(github.ref, 'refs/tags/') + needs: [build, publish-to-pypi] + runs-on: ubuntu-latest + permissions: + attestations: write + contents: write + id-token: write + steps: + - uses: actions/download-artifact@v6 + with: + name: python-package-distributions + path: dist/ + - uses: actions/attest-build-provenance@v3 + with: + subject-path: dist/* + - env: + GH_TOKEN: ${{ github.token }} + run: gh release create "$GITHUB_REF_NAME" --title "$GITHUB_REF_NAME" --generate-notes dist/*