From 876347ad1fc108935405ccfbd2fec994d136b33a Mon Sep 17 00:00:00 2001 From: James Frost Date: Fri, 21 Apr 2023 10:00:09 +0100 Subject: [PATCH 01/10] Add workflow for releasing to PyPI Currently has the test PyPI repository used. --- .github/workflows/release.yml | 59 +++++++++++++++++++++++++++++++++++ pyproject.toml | 6 ++++ 2 files changed, 65 insertions(+) create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 000000000..389df954e --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,59 @@ +name: Publish packages + +on: + release: + types: [released] + +# Allow only one concurrent deployment +concurrency: + group: "release" + cancel-in-progress: false + +jobs: + build-package: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - uses: actions/setup-python@v4 + with: + python-version: "3.x" + + - name: Install dependencies + run: python3 -m pip install tox tox-conda + + - uses: actions/cache@v3 + with: + key: tox|build-package|${{ runner.os }}-${{ runner.arch}}|${{ hashFiles('requirements/locks/*') }} + path: .tox + + - name: Build documentation + run: tox -e build-package + + - uses: actions/upload-artifact@v3 + with: + name: packages + path: dist + retention-days: 10 + if-no-files-found: error + + pypi-publish: + name: Publish to PyPI + runs-on: ubuntu-latest + needs: build-package + environment: + name: release + permissions: + id-token: write + steps: + - uses: actions/download-artifact@v3 + with: + name: packages + + - name: List files + run: ls * + + - name: Publish package distributions to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 + with: + repository-url: https://test.pypi.org/legacy/ diff --git a/pyproject.toml b/pyproject.toml index b142c396a..cb2835c1d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -92,6 +92,12 @@ conda_spec = usedevelop = true commands = sphinx-build -d "docs/build/doctree" docs/source "docs/build/html" --color -W -bhtml {posargs} +[testenv:build-package] +description = Build sdist and wheel packages. +deps = build +skip_install = true +commands = python3 -m build + [testenv:coverage-clean] deps = coverage skip_install = true From 854c6ba520efbe10273ff98d05f72ab73bd137c5 Mon Sep 17 00:00:00 2001 From: James Frost Date: Fri, 21 Apr 2023 10:47:01 +0100 Subject: [PATCH 02/10] Implement upload manually as action is blocked --- .github/workflows/release.yml | 46 ++++++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 4 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 389df954e..371bf15f7 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -27,7 +27,7 @@ jobs: key: tox|build-package|${{ runner.os }}-${{ runner.arch}}|${{ hashFiles('requirements/locks/*') }} path: .tox - - name: Build documentation + - name: Build package run: tox -e build-package - uses: actions/upload-artifact@v3 @@ -53,7 +53,45 @@ jobs: - name: List files run: ls * - - name: Publish package distributions to PyPI - uses: pypa/gh-action-pypi-publish@release/v1 + # External actions are disabled via organization policies therefore we + # must instead manually implement it. + # https://docs.pypi.org/trusted-publishers/using-a-publisher/#the-manual-way + # - name: Publish package distributions to PyPI + # uses: pypa/gh-action-pypi-publish@release/v1 + # with: + # repository-url: https://test.pypi.org/legacy/ + + - uses: actions/setup-python@v4 with: - repository-url: https://test.pypi.org/legacy/ + python-version: "3.x" + + - name: Install dependencies + run: python -m pip install twine + + - name: Check package metadata + run: python -m twine check --strict dist/* + + - name: mint API token + id: mint-token + run: | + # retrieve the ambient OIDC token + resp=$(curl -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \ + "$ACTIONS_ID_TOKEN_REQUEST_URL&audience=pypi") + oidc_token=$(jq '.value' <<< "${resp}") + + # exchange the OIDC token for an API token + resp=$(curl -X POST https://pypi.org/_/oidc/github/mint-token -d "{\"token\": \"${oidc_token}\"}") + api_token=$(jq '.token' <<< "${resp}") + + # mask the newly minted API token, so that we don't accidentally leak it + echo "::add-mask::${api_token}" + + # see the next step in the workflow for an example of using this step output + echo "api-token=${api_token}" >> "${GITHUB_OUTPUT}" + + - name: Upload to PyPI + env: + TWINE_USERNAME: __token__ + TWINE_PASSWORD: ${{ steps.mint-token.outputs.api-token }} + TWINE_REPOSITORY: testpypi + run: python3 -m twine upload --non-interactive dist/* From ea73bdd3fe4755ae219843a36159f3d6420a7a82 Mon Sep 17 00:00:00 2001 From: James Frost Date: Fri, 21 Apr 2023 11:21:08 +0100 Subject: [PATCH 03/10] Explicitly use dist/ as artifact download path Also comment out caching as I don't think it helps here. --- .github/workflows/release.yml | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 371bf15f7..3631ab3b6 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -22,10 +22,10 @@ jobs: - name: Install dependencies run: python3 -m pip install tox tox-conda - - uses: actions/cache@v3 - with: - key: tox|build-package|${{ runner.os }}-${{ runner.arch}}|${{ hashFiles('requirements/locks/*') }} - path: .tox + # - uses: actions/cache@v3 + # with: + # key: tox|build-package|${{ runner.os }}-${{ runner.arch}}|${{ hashFiles('requirements/locks/*') }} + # path: .tox - name: Build package run: tox -e build-package @@ -33,7 +33,7 @@ jobs: - uses: actions/upload-artifact@v3 with: name: packages - path: dist + path: dist/ retention-days: 10 if-no-files-found: error @@ -49,9 +49,10 @@ jobs: - uses: actions/download-artifact@v3 with: name: packages + path: dist/ - name: List files - run: ls * + run: ls -RA # External actions are disabled via organization policies therefore we # must instead manually implement it. From b41042de3ee7af0b3a93918e88764c700e4e4a6a Mon Sep 17 00:00:00 2001 From: James Frost Date: Fri, 21 Apr 2023 11:57:35 +0100 Subject: [PATCH 04/10] Readd caching as it seems to help a little --- .github/workflows/release.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3631ab3b6..67bd17988 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -22,10 +22,10 @@ jobs: - name: Install dependencies run: python3 -m pip install tox tox-conda - # - uses: actions/cache@v3 - # with: - # key: tox|build-package|${{ runner.os }}-${{ runner.arch}}|${{ hashFiles('requirements/locks/*') }} - # path: .tox + - uses: actions/cache@v3 + with: + key: tox|build-package|${{ runner.os }}-${{ runner.arch}}|${{ hashFiles('requirements/locks/*') }} + path: .tox - name: Build package run: tox -e build-package From 558daba3c555d897b15f9f15d4328230f417b2e5 Mon Sep 17 00:00:00 2001 From: James Frost Date: Fri, 21 Apr 2023 12:04:10 +0100 Subject: [PATCH 05/10] Add output to help diagnose auth issue Make twine upload verbose --- .github/workflows/release.yml | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 67bd17988..24c1cdf05 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -3,6 +3,8 @@ name: Publish packages on: release: types: [released] + # Just for testing + pull_request: # Allow only one concurrent deployment concurrency: @@ -72,20 +74,20 @@ jobs: - name: Check package metadata run: python -m twine check --strict dist/* - - name: mint API token + - name: Mint API token id: mint-token run: | # retrieve the ambient OIDC token - resp=$(curl -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \ + resp=$(curl -s -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \ "$ACTIONS_ID_TOKEN_REQUEST_URL&audience=pypi") oidc_token=$(jq '.value' <<< "${resp}") # exchange the OIDC token for an API token - resp=$(curl -X POST https://pypi.org/_/oidc/github/mint-token -d "{\"token\": \"${oidc_token}\"}") + resp=$(curl -s -X POST https://pypi.org/_/oidc/github/mint-token -d "{\"token\": \"${oidc_token}\"}") api_token=$(jq '.token' <<< "${resp}") # mask the newly minted API token, so that we don't accidentally leak it - echo "::add-mask::${api_token}" + # echo "::add-mask::${api_token}" # see the next step in the workflow for an example of using this step output echo "api-token=${api_token}" >> "${GITHUB_OUTPUT}" @@ -95,4 +97,7 @@ jobs: TWINE_USERNAME: __token__ TWINE_PASSWORD: ${{ steps.mint-token.outputs.api-token }} TWINE_REPOSITORY: testpypi - run: python3 -m twine upload --non-interactive dist/* + run: | + echo $TWINE_USERNAME + echo $TWINE_PASSWORD + python3 -m twine upload --disable-progress-bar --verbose --non-interactive dist/* From 852a3c753008fd80100ad80f53cf2707166ef496 Mon Sep 17 00:00:00 2001 From: James Frost Date: Fri, 21 Apr 2023 12:28:41 +0100 Subject: [PATCH 06/10] Use static token instead --- .github/workflows/release.yml | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 24c1cdf05..dc0448756 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -74,30 +74,30 @@ jobs: - name: Check package metadata run: python -m twine check --strict dist/* - - name: Mint API token - id: mint-token - run: | - # retrieve the ambient OIDC token - resp=$(curl -s -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \ - "$ACTIONS_ID_TOKEN_REQUEST_URL&audience=pypi") - oidc_token=$(jq '.value' <<< "${resp}") + # - name: Mint API token + # id: mint-token + # run: | + # # retrieve the ambient OIDC token + # resp=$(curl -s -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \ + # "$ACTIONS_ID_TOKEN_REQUEST_URL&audience=pypi") + # oidc_token=$(jq '.value' <<< "${resp}") - # exchange the OIDC token for an API token - resp=$(curl -s -X POST https://pypi.org/_/oidc/github/mint-token -d "{\"token\": \"${oidc_token}\"}") - api_token=$(jq '.token' <<< "${resp}") + # # exchange the OIDC token for an API token + # resp=$(curl -s -X POST https://pypi.org/_/oidc/github/mint-token -d "{\"token\": \"${oidc_token}\"}") + # api_token=$(jq '.token' <<< "${resp}") - # mask the newly minted API token, so that we don't accidentally leak it - # echo "::add-mask::${api_token}" + # # mask the newly minted API token, so that we don't accidentally leak it + # echo "::add-mask::${api_token}" - # see the next step in the workflow for an example of using this step output - echo "api-token=${api_token}" >> "${GITHUB_OUTPUT}" + # # see the next step in the workflow for an example of using this step output + # echo "api-token=${api_token}" >> "${GITHUB_OUTPUT}" - name: Upload to PyPI env: TWINE_USERNAME: __token__ - TWINE_PASSWORD: ${{ steps.mint-token.outputs.api-token }} + TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }} TWINE_REPOSITORY: testpypi run: | echo $TWINE_USERNAME - echo $TWINE_PASSWORD + echo $TWINE_PASSWORD | sha256sum python3 -m twine upload --disable-progress-bar --verbose --non-interactive dist/* From 50b3c34b9304842de27e99d9915e87037f7b472d Mon Sep 17 00:00:00 2001 From: James Frost Date: Fri, 21 Apr 2023 13:28:20 +0100 Subject: [PATCH 07/10] Remove unused code and bump version --- .github/workflows/release.yml | 25 +------------------ pyproject.toml | 4 +-- .../RECIPES/extract_instant_air_temp.toml | 2 +- 3 files changed, 4 insertions(+), 27 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index dc0448756..f2c47fa80 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -3,8 +3,6 @@ name: Publish packages on: release: types: [released] - # Just for testing - pull_request: # Allow only one concurrent deployment concurrency: @@ -74,30 +72,9 @@ jobs: - name: Check package metadata run: python -m twine check --strict dist/* - # - name: Mint API token - # id: mint-token - # run: | - # # retrieve the ambient OIDC token - # resp=$(curl -s -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \ - # "$ACTIONS_ID_TOKEN_REQUEST_URL&audience=pypi") - # oidc_token=$(jq '.value' <<< "${resp}") - - # # exchange the OIDC token for an API token - # resp=$(curl -s -X POST https://pypi.org/_/oidc/github/mint-token -d "{\"token\": \"${oidc_token}\"}") - # api_token=$(jq '.token' <<< "${resp}") - - # # mask the newly minted API token, so that we don't accidentally leak it - # echo "::add-mask::${api_token}" - - # # see the next step in the workflow for an example of using this step output - # echo "api-token=${api_token}" >> "${GITHUB_OUTPUT}" - - name: Upload to PyPI env: TWINE_USERNAME: __token__ TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }} TWINE_REPOSITORY: testpypi - run: | - echo $TWINE_USERNAME - echo $TWINE_PASSWORD | sha256sum - python3 -m twine upload --disable-progress-bar --verbose --non-interactive dist/* + run: python3 -m twine upload --disable-progress-bar --verbose --non-interactive dist/* diff --git a/pyproject.toml b/pyproject.toml index cb2835c1d..c78d75e77 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,10 +1,10 @@ [project] name = "CSET" -version = "0.0.2" +version = "0.0.3" description = "Convective Scale Evaluation Tool for evaluation and investigation of regional models." authors = [{ name = "Met Office" }, { name = "NIWA" }] readme = "README.md" -license = { file = "LICENCE" } +license = { text = "Apache-2.0" } requires-python = ">=3.8" classifiers = [ "License :: OSI Approved :: Apache Software License", diff --git a/src/CSET/operators/RECIPES/extract_instant_air_temp.toml b/src/CSET/operators/RECIPES/extract_instant_air_temp.toml index 35c43a39d..5bc8f476f 100644 --- a/src/CSET/operators/RECIPES/extract_instant_air_temp.toml +++ b/src/CSET/operators/RECIPES/extract_instant_air_temp.toml @@ -4,7 +4,7 @@ Extracts out the instantaneous 1.5m air temperature from a file and writes it to a new one. """ section = "Grid Stat" -major_cat ="Major Category 1" +major_cat = "Major Category 1" minor_cat = "Minor Category 1" [[steps]] From 78eb71aaaa3d9f090e431c204ecc564143405d91 Mon Sep 17 00:00:00 2001 From: James Frost Date: Fri, 21 Apr 2023 14:22:04 +0100 Subject: [PATCH 08/10] Add documentation on making a release Also bump the version number to 0.1.0 ready for our first release. --- .../source/working-practices/release_page.png | Bin 0 -> 20084 bytes docs/source/working-practices/releases.rst | 28 ++++++++++++++++++ pyproject.toml | 2 +- 3 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 docs/source/working-practices/release_page.png diff --git a/docs/source/working-practices/release_page.png b/docs/source/working-practices/release_page.png new file mode 100644 index 0000000000000000000000000000000000000000..d970eb7558122bcad30a051b84dd2ee3ce58fde5 GIT binary patch literal 20084 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 Date: Fri, 21 Apr 2023 15:06:55 +0100 Subject: [PATCH 09/10] Point release workflow to main PyPI instance We are now ready to make our release. --- .github/workflows/release.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f2c47fa80..f14d98ae4 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -51,16 +51,11 @@ jobs: name: packages path: dist/ - - name: List files - run: ls -RA - # External actions are disabled via organization policies therefore we # must instead manually implement it. # https://docs.pypi.org/trusted-publishers/using-a-publisher/#the-manual-way # - name: Publish package distributions to PyPI # uses: pypa/gh-action-pypi-publish@release/v1 - # with: - # repository-url: https://test.pypi.org/legacy/ - uses: actions/setup-python@v4 with: @@ -76,5 +71,4 @@ jobs: env: TWINE_USERNAME: __token__ TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }} - TWINE_REPOSITORY: testpypi run: python3 -m twine upload --disable-progress-bar --verbose --non-interactive dist/* From 126a67176e163817f5c2f269c1cfdd29e194c9e8 Mon Sep 17 00:00:00 2001 From: James Frost Date: Mon, 24 Apr 2023 10:59:43 +0100 Subject: [PATCH 10/10] Add links to release docs --- docs/source/working-practices/releases.rst | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/source/working-practices/releases.rst b/docs/source/working-practices/releases.rst index a656a1137..c10934cf9 100644 --- a/docs/source/working-practices/releases.rst +++ b/docs/source/working-practices/releases.rst @@ -46,8 +46,8 @@ Making a release is mostly automated. The only thing that needs to be done in the code is to ensure that the version number in ``pyproject.toml`` has been incremented since the last release. -To create a release you should use the GitHub web UI. Go to the "Releases" page, -and press "Create a new release". +To create a release you should use the GitHub web UI. Go to the `Releases`_ +page, and press `Draft a new release`_. .. image:: release_page.png :alt: The GitHub release making page. @@ -66,3 +66,6 @@ On this page you will need to add several things. Once that is all written you simply need to press "Publish release". A release will be automatically made, and the package will be pushed to PyPI and beyond. + +.. _Releases: https://github.com/MetOffice/CSET/releases +.. _Draft a new release: https://github.com/MetOffice/CSET/releases/new