diff --git a/.github/workflows/_docs.yml b/.github/workflows/_docs.yml deleted file mode 100644 index 9d4fc583..00000000 --- a/.github/workflows/_docs.yml +++ /dev/null @@ -1,55 +0,0 @@ -on: - workflow_call: - - -jobs: - build: - runs-on: ubuntu-latest - - steps: - - name: Avoid git conflicts when tag and branch pushed at same time - if: github.ref_type == 'tag' - run: sleep 60 - - - name: Checkout - uses: actions/checkout@v7 - with: - # Need this to get version number from last tag - fetch-depth: 0 - - - name: Install system packages - run: sudo apt-get install graphviz - - - name: Install uv - uses: astral-sh/setup-uv@v10.0.1 - - - name: Build docs - run: uv run --locked tox -e docs - - - name: Remove environment.pickle - run: rm build/html/.doctrees/environment.pickle - - - name: Upload built docs artifact - uses: actions/upload-artifact@v7 - with: - name: docs - path: build - - - name: Sanitize ref name for docs version - run: echo "DOCS_VERSION=${GITHUB_REF_NAME//[^A-Za-z0-9._-]/_}" >> $GITHUB_ENV - - - name: Move to versioned directory - run: mv build/html .github/pages/$DOCS_VERSION - - - name: Write switcher.json - run: python .github/pages/make_switcher.py --add $DOCS_VERSION ${{ github.repository }} .github/pages/switcher.json - - - name: Publish Docs to gh-pages - if: github.ref_type == 'tag' || github.ref_name == 'main' - # We pin to the SHA, not the tag, for security reasons. - # https://docs.github.com/en/actions/learn-github-actions/security-hardening-for-github-actions#using-third-party-actions - uses: peaceiris/actions-gh-pages@84c30a85c19949d7eee79c4ff27748b70285e453 # v4.1.0 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: .github/pages - keep_files: true diff --git a/.github/workflows/_release.yml b/.github/workflows/_release.yml deleted file mode 100644 index 14b4b269..00000000 --- a/.github/workflows/_release.yml +++ /dev/null @@ -1,32 +0,0 @@ -on: - workflow_call: - -jobs: - artifacts: - runs-on: ubuntu-latest - - steps: - - name: Download artifacts - uses: actions/download-artifact@v8 - with: - merge-multiple: true - - - name: Zip up docs - run: | - set -vxeuo pipefail - if [ -d html ]; then - mv html $GITHUB_REF_NAME - zip -r docs.zip $GITHUB_REF_NAME - rm -rf $GITHUB_REF_NAME - fi - - - name: Create GitHub Release - # We pin to the SHA, not the tag, for security reasons. - # https://docs.github.com/en/actions/learn-github-actions/security-hardening-for-github-actions#using-third-party-actions - uses: softprops/action-gh-release@3d0d9888cb7fd7b750713d6e236d1fcb99157228 # v3.0.2 - with: - prerelease: ${{ contains(github.ref_name, 'a') || contains(github.ref_name, 'b') || contains(github.ref_name, 'rc') }} - files: "*" - generate_release_notes: true - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2ccb5691..82b67804 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,12 +1,10 @@ name: CI on: - push: - branches: - - main - tags: - - '*' pull_request: + push: + branches: [main] + tags: ["*"] # '*' never matches '/', so e.g. release/x tags don't build jobs: lint: @@ -19,10 +17,13 @@ jobs: with: runs-on: ubuntu-latest - docs: - uses: ./.github/workflows/_docs.yml - permissions: - contents: write + docs: # Call the docs building workflow directly + uses: DiamondLightSource/myst-version-switcher-plugin/.github/workflows/docs.yml@v0.24.1 + with: + # Whatever turns your sources into docs/_build/html at $BASE_URL. uv and Node + # are preinstalled; so: make docs · tox -e docs · npm ci && npm run docs + build-command: uv run --locked tox -e docs + html-dir: build/html example: needs: test @@ -33,7 +34,21 @@ jobs: release: needs: [test, docs] - if: github.ref_type == 'tag' - uses: ./.github/workflows/_release.yml + if: github.ref_type == 'tag' # tag pushes only + uses: DiamondLightSource/myst-version-switcher-plugin/.github/workflows/release.yml@v0.24.1 + permissions: + contents: write # create the Release + attach assets + + publish: + needs: [docs] + # don't publish a pages site in the fork's org + if: github.repository == 'DiamondLightSource/python-copier-template' && github.ref_type == 'tag' # publish only on tags + uses: ./.github/workflows/publish-dispatch.yml # your workflow (below) + with: + version-name: ${{ needs.docs.outputs.version-name }} permissions: - contents: write + contents: read + actions: write + pages: write + id-token: write + statuses: write diff --git a/.github/workflows/publish-dispatch.yml b/.github/workflows/publish-dispatch.yml new file mode 100644 index 00000000..4a02e00d --- /dev/null +++ b/.github/workflows/publish-dispatch.yml @@ -0,0 +1,36 @@ +# .github/workflows/publish-dispatch.yml +name: Publish (dispatch) +on: + workflow_call: # ci.yml's `publish` job, for every event + inputs: + version-name: {required: false, default: "", type: string} + # tag re-dispatch + fork-PR preview + manual re-deploy + workflow_dispatch: + inputs: + pr: + description: "Fork PR to approve + preview (empty = re-deploy)" + required: false + default: "" + retry-until: + description: "Internal = epoch-second retry deadline. Don't set manually." + required: false + default: "" + +jobs: + publish: + uses: DiamondLightSource/myst-version-switcher-plugin/.github/workflows/publish.yml@v0.24 + with: + # "" on dispatch → pure durable gather + version-name: ${{ inputs.version-name }} + # set (dispatch) → pin that fork head SHA + pr: ${{ inputs.pr }} + # the file the tag re-dispatch re-fires + dispatch-workflow: publish-dispatch.yml + # forwarded so the re-dispatch job's auto-retry can re-fire this shim + retry-until: ${{ inputs.retry-until }} + permissions: + contents: read + actions: write + pages: write + id-token: write + statuses: write diff --git a/docs/conf.py b/docs/conf.py index f78540b5..d50ff7e7 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -3,11 +3,9 @@ # This file only contains a selection of the most common options. For a full # list see the documentation: # https://www.sphinx-doc.org/en/master/usage/configuration.html - +import os import sys from importlib.metadata import version -from pathlib import Path -from subprocess import check_output import requests @@ -19,14 +17,7 @@ # The full version, including alpha/beta/rc tags. release = version(project) -# The short X.Y version. -if "+" in release: - # Not on a tag, use branch name - root = Path(__file__).absolute().parent.parent - git_branch = check_output("git branch --show-current".split(), cwd=root) - version = git_branch.decode().strip() -else: - version = release +version = os.environ.get("VERSION_NAME", "local") extensions = [ # For graphviz diagrams @@ -135,8 +126,8 @@ "json_url": switcher_json, "version_match": version, }, - "check_switcher": True, - "navbar_end": ["theme-switcher", "icon-links", "version-switcher"], + "check_switcher": False, + "navbar_end": ["theme-switcher", "navbar-icon-links", "version-switcher"], } # A dictionary of values to pass into the template engine’s context for all pages diff --git a/pyproject.toml b/pyproject.toml index 52dbee00..40e3af96 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,9 @@ build-backend = "setuptools.build_meta" [project] name = "python-copier-template" +description = "Diamond's opinionated copier template for pure Python projects." dynamic = ["version"] +readme = "README.md" requires-python = ">=3.11" [dependency-groups] diff --git "a/template/{% if git_platform==\"github.com\" %}.github{% endif %}/workflows/_release.yml" "b/template/{% if git_platform==\"github.com\" %}.github{% endif %}/workflows/_release.yml" deleted file mode 120000 index d5d5c173..00000000 --- "a/template/{% if git_platform==\"github.com\" %}.github{% endif %}/workflows/_release.yml" +++ /dev/null @@ -1 +0,0 @@ -../../../.github/workflows/_release.yml \ No newline at end of file diff --git "a/template/{% if git_platform==\"github.com\" %}.github{% endif %}/workflows/ci.yml.jinja" "b/template/{% if git_platform==\"github.com\" %}.github{% endif %}/workflows/ci.yml.jinja" index ce155442..5d1133b5 100644 --- "a/template/{% if git_platform==\"github.com\" %}.github{% endif %}/workflows/ci.yml.jinja" +++ "b/template/{% if git_platform==\"github.com\" %}.github{% endif %}/workflows/ci.yml.jinja" @@ -1,13 +1,11 @@ name: CI on: - push: - branches: - - main - tags: - - '*' pull_request: - + push: + branches:[main] + tags:['*'] + jobs: lint: @@ -37,10 +35,13 @@ jobs: packages: write {% endraw %}{% endif %}{% if sphinx %} docs: - uses: ./.github/workflows/_docs.yml - permissions: - contents: write -{% endif %} + uses: DiamondLightSource/myst-version-switcher-plugin/.github/workflows/docs.yml@v0.24.1 + with: + # Whatever turns your sources into docs/_build/html at $BASE_URL. + # uv and Node are preinstalled; so: make docs · tox -e docs · npm ci && npm run docs + build-command: uv run --locked tox -e docs + html-dir: build/html + {% endif %} dist: uses: ./.github/workflows/_dist.yml {% if pypi %} @@ -54,6 +55,20 @@ jobs: release: needs: [dist, test{% if sphinx %}, docs{% endif %}] if: github.ref_type == 'tag' - uses: ./.github/workflows/_release.yml + uses: DiamondLightSource/myst-version-switcher-plugin/.github/workflows/release.yml@v0.24.1 permissions: contents: write + {% if sphinx %}{% raw %} + publish: + needs: [docs] + if: github.repository == 'DiamondLightSource/python-copier-template' && github.ref_type == 'tag' #publish only on tags + uses: ./.github/workflows/publish-dispatch.yml # your workflow (below) + with: + version-name: ${{ needs.docs.outputs.version-name }} + permissions: + contents: read + actions: write + pages: write + id-token: write + statuses: write + {% endraw %}{% endif %} diff --git "a/template/{% if git_platform==\"github.com\" %}.github{% endif %}/workflows/publish-dispatch.yml" "b/template/{% if git_platform==\"github.com\" %}.github{% endif %}/workflows/publish-dispatch.yml" new file mode 100644 index 00000000..90ca411d --- /dev/null +++ "b/template/{% if git_platform==\"github.com\" %}.github{% endif %}/workflows/publish-dispatch.yml" @@ -0,0 +1,36 @@ +# .github/workflows/publish-dispatch.yml +name: Publish (dispatch) +on: + workflow_call: # ci.yml's `publish` job, for every event + inputs: + version-name: {required: false, default: "", type: string} + # tag re-dispatch + fork-PR preview + manual re-deploy + workflow_dispatch: + inputs: + pr: + description: "Fork PR to approve + preview (empty = re-deploy)" + required: false + default: "" + retry-until: + description: "Internal = epoch-second retry deadline. Don't set manually." + required: false + default: "" + +jobs: + publish: + uses: DiamondLightSource/myst-version-switcher-plugin/.github/workflows/publish.yml@v0.24.1 + with: + # "" on dispatch → pure durable gather + version-name: ${{ inputs.version-name }} + # set (dispatch) → pin that fork head SHA + pr: ${{ inputs.pr }} + # the file the tag re-dispatch re-fires + dispatch-workflow: publish-dispatch.yml + # forwarded so the re-dispatch job's auto-retry can re-fire this shim + retry-until: ${{ inputs.retry-until }} + permissions: + contents: read + actions: write + pages: write + id-token: write + statuses: write diff --git "a/template/{% if git_platform==\"github.com\" %}.github{% endif %}/workflows/{% if sphinx %}_docs.yml{% endif %}" "b/template/{% if git_platform==\"github.com\" %}.github{% endif %}/workflows/{% if sphinx %}_docs.yml{% endif %}" deleted file mode 120000 index 6f47d301..00000000 --- "a/template/{% if git_platform==\"github.com\" %}.github{% endif %}/workflows/{% if sphinx %}_docs.yml{% endif %}" +++ /dev/null @@ -1 +0,0 @@ -../../../.github/workflows/_docs.yml \ No newline at end of file diff --git a/template/{% if sphinx %}docs{% endif %}/conf.py.jinja b/template/{% if sphinx %}docs{% endif %}/conf.py.jinja index 92ea6b5f..03eb6373 100644 --- a/template/{% if sphinx %}docs{% endif %}/conf.py.jinja +++ b/template/{% if sphinx %}docs{% endif %}/conf.py.jinja @@ -168,7 +168,7 @@ html_theme_options = { "version_match": version, }, "check_switcher": False, - "navbar_end": ["theme-switcher", "icon-links", "version-switcher"], + "navbar_end": ["theme-switcher", "navbar-icon-links", "version-switcher"], "navigation_with_keys": False, } diff --git a/uv.lock b/uv.lock index 76d76a1f..1c14cb4e 100644 --- a/uv.lock +++ b/uv.lock @@ -268,7 +268,7 @@ wheels = [ [[package]] name = "copier" -version = "9.17.1" +version = "9.17.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama" }, @@ -285,9 +285,9 @@ dependencies = [ { name = "pyyaml" }, { name = "questionary" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/40/65/11c8635a27ce06ef525946bb02b1d5271b0f11e5acf9c5ab6d242512598e/copier-9.17.1.tar.gz", hash = "sha256:778e85f1c2de86824a72ddf4a34140744921d6354450c427c4c8a475371b1bda", size = 647338, upload-time = "2026-08-04T09:15:04.826Z" } +sdist = { url = "https://files.pythonhosted.org/packages/2e/4c/2e593d85827c49f478ea4925d1008a144bb8ff2189c6e9f405c37bb56edb/copier-9.17.2.tar.gz", hash = "sha256:02e9c0d05281603c06d52f48350e48ffca0b4283d9f025664fbce4befabaa555", size = 650501, upload-time = "2026-08-19T13:49:17.456Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7f/bf/3adcb9b3091b36de729dad91c107179c8c7c51adb2b08c31177bb540bef1/copier-9.17.1-py3-none-any.whl", hash = "sha256:f6a48f296e2e536c635213e1000ea71099f9f58f3b464a60f2f0fd386e343628", size = 66364, upload-time = "2026-08-04T09:15:03.026Z" }, + { url = "https://files.pythonhosted.org/packages/ec/ec/466bbf501af8e9f718b3f4875cb32fe75a1f17538c2fba507f64a32c2b0f/copier-9.17.2-py3-none-any.whl", hash = "sha256:24757d8875cdf4e076ff338e5ea984e85f5d5da9afcecea8a9dde0f151310b19", size = 67003, upload-time = "2026-08-19T13:49:15.987Z" }, ] [[package]] @@ -358,11 +358,11 @@ wheels = [ [[package]] name = "idna" -version = "3.18" +version = "3.19" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/cd/63/9496c57188a2ee585e0f1db071d75089a11e98aa86eb99d9d7618fc1edce/idna-3.18.tar.gz", hash = "sha256:ffb385a7e039654cef1ab9ef32c6fafe283c0c0467bba1d9029738ce4a14a848", size = 196711, upload-time = "2026-06-02T14:34:07.794Z" } +sdist = { url = "https://files.pythonhosted.org/packages/5f/f7/abb373e5757eaec4b922b92f97ec8d6d7e057cf06778247604fbc4e7c3f3/idna-3.19.tar.gz", hash = "sha256:5e0811a4383b21dc5838069f801c4fb62113b7447663d2530d2bd6e77b49bf15", size = 215237, upload-time = "2026-08-18T05:14:24.27Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/1e/5e/d4e9f1a599fb8e573b7b87160658329fbf28d19eac2718f51fc3def3aa5a/idna-3.18-py3-none-any.whl", hash = "sha256:7f952cbe720b688055e3f87de14f5c3e5fdaa8bc3928985c4077ca689de849a2", size = 65455, upload-time = "2026-06-02T14:34:06.319Z" }, + { url = "https://files.pythonhosted.org/packages/57/b0/0e52c878c53f245edd3a11020f20979b3f490f245af532c7cae3027754b5/idna-3.19-py3-none-any.whl", hash = "sha256:815e7be7a7806d54abb586dc943addc79e8b2ee16915059658cbeff4b1b43bf4", size = 68550, upload-time = "2026-08-18T05:14:22.343Z" }, ] [[package]] @@ -757,11 +757,11 @@ wheels = [ [[package]] name = "pygments" -version = "2.20.0" +version = "2.21.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", size = 4955991, upload-time = "2026-03-29T13:29:33.898Z" } +sdist = { url = "https://files.pythonhosted.org/packages/49/2e/ced460408999b33da6b31b0021b0f37d329e202d4169aeb164493778f25b/pygments-2.21.0.tar.gz", hash = "sha256:610ca751c9bc2492b38eb9a38a7fbc93edbbb2d7182edaf34e66ae493dee5c8c", size = 5005329, upload-time = "2026-08-17T08:02:48.824Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" }, + { url = "https://files.pythonhosted.org/packages/71/46/17f022dd3e953bf20a04a028a21ec746d942f8d2af30fa0f124fa0e6a684/pygments-2.21.0-py3-none-any.whl", hash = "sha256:2363c69b61c4a97c838da3b130dcd6468f4848992b21a82f2a63ec34377137d9", size = 1250147, upload-time = "2026-08-17T08:02:44.912Z" }, ] [[package]] @@ -1259,15 +1259,15 @@ wheels = [ [[package]] name = "uvicorn" -version = "0.52.3" +version = "0.52.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "click" }, { name = "h11" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/2e/28/64ca011edf31c715b4fad359c587ea52391aaffa125065695590241ff617/uvicorn-0.52.3.tar.gz", hash = "sha256:18857b9e6579300be55c91c0a1cfd37d9a2cf0cabea33b88275f199eb73b8b58", size = 100621, upload-time = "2026-08-13T16:50:02.899Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f2/0f/3f86e61397dd33bf2ccf28188c40db6a740658aeebbbf6e7dbc101a1f487/uvicorn-0.52.4.tar.gz", hash = "sha256:73acfee47a0b133c5de13d219492d62d8a31e935f4fe6e41a232451a15379f86", size = 100627, upload-time = "2026-08-19T06:27:41.821Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/dc/2b/ebd108734a8204c6b4b93c681c9a38c5273b3ccd5d129fee4ffc1d97772c/uvicorn-0.52.3-py3-none-any.whl", hash = "sha256:116af2710dbf47c80f463cd20ee4884b6662f4c9f227d797ddc7279d2fcc2c7c", size = 79859, upload-time = "2026-08-13T16:50:01.323Z" }, + { url = "https://files.pythonhosted.org/packages/f1/79/4a20b54ab0491485ccd8c077db2d39187c7f12b3e15485d38a7be37c81b4/uvicorn-0.52.4-py3-none-any.whl", hash = "sha256:f86e41a149d7d05a9969337e3946a9c171c06a5d42680896daaba624aeac8da1", size = 79871, upload-time = "2026-08-19T06:27:40.36Z" }, ] [[package]]