diff --git a/.github/workflows/merge.yml b/.github/workflows/merge.yml index e4142a204..e3df88c17 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -18,26 +18,47 @@ jobs: publishing: name: Build and publish Python 🐍 distributions 📦 to PyPI runs-on: ubuntu-latest + environment: pypi + permissions: + contents: read # Required by actions/checkout + id-token: write # Needed for OIDC-based Trusted Publishing # Only trigger on merges, not just closes if: github.event.pull_request.merged == true steps: - name: Check out committed code uses: actions/checkout@v4 - - name: Set up Python ${{ env.DEFAULT_PYTHON }} - id: python - uses: actions/setup-python@v5 - with: - python-version: ${{ env.DEFAULT_PYTHON }} - - name: Install pypa/build - run: >- - python3 -m - pip install - build - --user - - name: Build a binary wheel and a source tarball - run: python3 -m build + - name: Prepare uv + run: | + pip install uv + uv venv --seed venv + . venv/bin/activate + uv pip install toml + - name: Check for existing package on PyPI + id: check_package + run: | + . venv/bin/activate + PACKAGE_VERSION=$(python -c "import toml; print(toml.load('pyproject.toml')['project']['version'])") + PACKAGE_NAME=$(python -c "import toml; print(toml.load('pyproject.toml')['project']['name'])") + + # Use jq to check for the version in the releases object + EXISTING_VERSIONS=$(curl -s "https://pypi.org/pypi/$PACKAGE_NAME/json" | jq '.releases | keys[]') + + echo "Checking for package: $PACKAGE_NAME==$PACKAGE_VERSION" + + if [[ "$EXISTING_VERSIONS" =~ "$PACKAGE_VERSION" ]]; then + echo "Package version already exists. Skipping upload." + echo "should_publish=false" >> $GITHUB_OUTPUT + else + echo "Package version does not exist. Proceeding with upload." + echo "should_publish=true" >> $GITHUB_OUTPUT + fi + - name: Build + if: steps.check_package.outputs.should_publish == 'true' + run: | + . venv/bin/activate + uv build - name: Publish distribution 📦 to PyPI - uses: pypa/gh-action-pypi-publish@release/v1 - with: - password: ${{ secrets.pypi_token }} - skip-existing: true + if: steps.check_package.outputs.should_publish == 'true' + run: | + . venv/bin/activate + uv publish diff --git a/.github/workflows/verify.yml b/.github/workflows/verify.yml index 4683a4fb4..3b94a21ae 100644 --- a/.github/workflows/verify.yml +++ b/.github/workflows/verify.yml @@ -57,7 +57,7 @@ jobs: ruff: runs-on: ubuntu-latest name: Ruff check and force - needs: + needs: - cache - prepare steps: @@ -126,7 +126,7 @@ jobs: pytest: runs-on: ubuntu-latest name: Run pytest using Python ${{ matrix.python-version }} - needs: + needs: - cache - prepare - commitcheck @@ -159,7 +159,7 @@ jobs: mypy: runs-on: ubuntu-latest name: Run mypy - needs: + needs: - cache - prepare - pytest @@ -205,7 +205,7 @@ jobs: coverage: name: Process test coverage runs-on: ubuntu-latest - needs: + needs: - cache - prepare - pytest @@ -237,6 +237,10 @@ jobs: test-publishing: name: Build and publish Python 🐍 distributions 📦 to TestPyPI runs-on: ubuntu-latest + environment: testpypi + permissions: + contents: read # Required by actions/checkout + id-token: write # Needed for OIDC-based Trusted Publishing needs: - cache - prepare @@ -245,34 +249,46 @@ jobs: steps: - name: Check out committed code uses: actions/checkout@v4 - - name: Restore cached environment - id: cache-reuse - uses: plugwise/gh-actions/restore-venv@v1 - with: - cache-key: ${{ needs.cache.outputs.cache-key }} - python-version: ${{ env.DEFAULT_PYTHON }} - venv-dir: ${{ env.VENV }} - precommit-home: ${{ env.PRE_COMMIT_HOME }} - - name: Install pypa/build + - name: Prepare uv run: | + pip install uv + uv venv --seed venv . venv/bin/activate - uv pip install build - - name: Build a binary wheel and a source tarball + uv pip install toml + - name: Check for existing package on TestPyPI + id: check_package run: | . venv/bin/activate - python3 -m build - - name: Publish distribution 📦 to Test PyPI - uses: pypa/gh-action-pypi-publish@release/v1 - continue-on-error: true - with: - password: ${{ secrets.testpypi_token }} - repository-url: https://test.pypi.org/legacy/ - skip-existing: true + PACKAGE_VERSION=$(python -c "import toml; print(toml.load('pyproject.toml')['project']['version'])") + PACKAGE_NAME=$(python -c "import toml; print(toml.load('pyproject.toml')['project']['name'])") + + # Use jq to check for the version in the releases object + EXISTING_VERSIONS=$(curl -s "https://test.pypi.org/pypi/$PACKAGE_NAME/json" | jq '.releases | keys[]') + + echo "Checking for package: $PACKAGE_NAME==$PACKAGE_VERSION" + + if [[ "$EXISTING_VERSIONS" =~ "$PACKAGE_VERSION" ]]; then + echo "Package version already exists. Skipping upload." + echo "should_publish=false" >> $GITHUB_OUTPUT + else + echo "Package version does not exist. Proceeding with upload." + echo "should_publish=true" >> $GITHUB_OUTPUT + fi + - name: Build + if: steps.check_package.outputs.should_publish == 'true' + run: | + . venv/bin/activate + uv build + - name: Publish distribution 📦 to TestPyPI + if: steps.check_package.outputs.should_publish == 'true' + run: | + . venv/bin/activate + uv publish --publish-url https://test.pypi.org/legacy/ complexity: name: Process test complexity runs-on: ubuntu-latest - needs: + needs: - cache - prepare - coverage diff --git a/CHANGELOG.md b/CHANGELOG.md index 858855752..954b3fbb1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## Ongoing / 1.7.8a0+1 + +- Chores move module publishing on (test)pypi to Trusted Publishing (and using uv) - released as alpha 1.7.8a0+1 to demonstrate functionality + ## v1.7.7 - Implement code quality improvements as suggested by SonarCloud via [#762](https://github.com/plugwise/python-plugwise/pull/762), [#763](https://github.com/plugwise/python-plugwise/pull/763), [#764](https://github.com/plugwise/python-plugwise/pull/764), and [#765](https://github.com/plugwise/python-plugwise/pull/765) diff --git a/pyproject.toml b/pyproject.toml index 4fc91a160..435561b88 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "plugwise" -version = "1.7.7" +version = "1.7.8a1" license = "MIT" description = "Plugwise Smile (Adam/Anna/P1) and Stretch module for Python 3." readme = "README.md"