From af198644662bacbf323b36b5e8b11b0049f3b668 Mon Sep 17 00:00:00 2001 From: LuukBlom <153174893+LuukBlom@users.noreply.github.com> Date: Wed, 18 Dec 2024 10:14:30 +0100 Subject: [PATCH] feat(ci): Create release workflow --- .github/workflows/publish-to-pypi.yml | 171 ++++++++++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 .github/workflows/publish-to-pypi.yml diff --git a/.github/workflows/publish-to-pypi.yml b/.github/workflows/publish-to-pypi.yml new file mode 100644 index 0000000..a52dca5 --- /dev/null +++ b/.github/workflows/publish-to-pypi.yml @@ -0,0 +1,171 @@ +name: release + +# This workflow will build a Python package and publish it to PyPI when a new tag is created. + +# Usage: +# - Create a new tag with the version number in the format v*.*.* where * are integers: `git tag v1.2.3` +# - Push the tag to the repository: `git push --tags` + +# Result: +# - Check if the new version is greater than the latest version on PyPI +# - Install dependencies +# - Build the package +# - Publish it to PyPI +# - Create a GitHub release with the tag name and the release notes + +# Checklist for using this workflow up for a new project: + +# 1. In github settings: +# - Create an environment called `release` (GH_ENV_NAME) and setup the permissions (https://github.com///settings/environments) + +# 2. On PyPi: +# - Create the project and add a trusted publisher (https://pypi.org/manage/project//settings/publishing/ or https://pypi.org/manage/account/publishing if the project is not on pypi yet) +# - Ensure the publisher is configured to use: +# - environment name: `release` (can be changed, but should be the one created in the github settings) +# - the filename of this workflow yml (in this case: publish-to-pypi.yml) + +# 3. In this file: +# - In the `env` section (~L45): +# - Update the name of your package (PACKAGE_NAME) +# - Update the version of Python you want to use (PYTHON_VERSION) +# - Update the name name of the environment you created in github settings (GH_ENV_NAME) + +# - In the `setup_and_build` job: +# - Update the the shell commands to install your package + +on: + push: + tags: + # https://peps.python.org/pep-0440/ + - r"v[0-9]+\.[0-9]+\.[0-9]" + +env: + GH_ENV_NAME: "release" + PACKAGE_NAME: "cht-observations" + PYTHON_VERSION: "3.10" + +jobs: + details: + runs-on: ubuntu-latest + outputs: + new_version: ${{ steps.release.outputs.new_version }} + tag_name: ${{ steps.release.outputs.tag_name }} + steps: + - uses: actions/checkout@v2 + + - name: Extract tag and Details + id: release + run: | + if [ "${{ github.ref_type }}" = "tag" ]; then + TAG_NAME=${GITHUB_REF#refs/tags/} + NEW_VERSION=$(echo $TAG_NAME | awk -F'-' '{print $1}') + echo "new_version=$NEW_VERSION" >> "$GITHUB_OUTPUT" + echo "tag_name=$TAG_NAME" >> "$GITHUB_OUTPUT" + echo "Version is $NEW_VERSION" + echo "Tag name is $TAG_NAME" + else + echo "No tag found" + exit 1 + fi + + check_pypi: + needs: details + runs-on: ubuntu-latest + steps: + - name: Fetch information from PyPI + run: | + response=$(curl -s https://pypi.org/pypi/${{ env.PACKAGE_NAME }}/json || echo "{}") + latest_previous_version=$(echo $response | jq --raw-output "select(.releases != null) | .releases | keys_unsorted | last") + if [ -z "$latest_previous_version" ]; then + echo "Package not found on PyPI." + latest_previous_version="0.0.0" + fi + echo "Latest version on PyPI: $latest_previous_version" + echo "latest_previous_version=$latest_previous_version" >> $GITHUB_ENV + + - name: Compare versions and exit if not newer + run: | + NEW_VERSION=${{ needs.details.outputs.new_version }} + LATEST_VERSION=$latest_previous_version + if [ "$(printf '%s\n' "$LATEST_VERSION" "$NEW_VERSION" | sort -rV | head -n 1)" != "$NEW_VERSION" ] || [ "$NEW_VERSION" == "$LATEST_VERSION" ]; then + echo "The new version $NEW_VERSION is not greater than the latest version $LATEST_VERSION on PyPI." + exit 1 + else + echo "The new version $NEW_VERSION is greater than the latest version $LATEST_VERSION on PyPI." + fi + + setup_and_build: + needs: [details, check_pypi] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: conda-incubator/setup-miniconda@v3 + with: + auto-update-conda: true + activate-environment: publish + python-version: ${{ env.PYTHON_VERSION }} + channels: conda-forge + + - name: Install Build tools + shell: bash -el {0} + run: | + conda run -n publish pip install --upgrade build pip setuptools + + - name: Install dependencies + shell: bash -el {0} + run: | + conda run -n publish pip install . + + - name: Build source and wheel distribution + run: | + conda run -n publish python -m build + + - name: Upload artifacts + uses: actions/upload-artifact@v3 + with: + name: dist + path: dist/ + + pypi_publish: + name: Upload release to PyPI + needs: [setup_and_build, details] + runs-on: ubuntu-latest + environment: + name: ${{ env.GH_ENV_NAME }} + permissions: + id-token: write + steps: + - name: Download artifacts + uses: actions/download-artifact@v3 + with: + name: dist + path: dist/ + + - name: Publish distribution to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 + + github_release: + name: Create GitHub Release + needs: [setup_and_build, details] + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - name: Checkout Code + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Download artifacts + uses: actions/download-artifact@v3 + with: + name: dist + path: dist/ + + - name: Create GitHub Release + id: create_release + env: + GH_TOKEN: ${{ github.token }} + run: | + gh release create ${{ needs.details.outputs.tag_name }} dist/* --title ${{ needs.details.outputs.tag_name }} --generate-notes