From e88cb440a1e24dd51633a71f2a8c33ac4d4c459c Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Fri, 17 Nov 2023 11:51:18 -0500 Subject: [PATCH 01/36] fix: loosen pin on repo-review Signed-off-by: Henry Schreiner --- docs/_includes/interactive_repo_review.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/_includes/interactive_repo_review.html b/docs/_includes/interactive_repo_review.html index ad19b2b7..f7a91365 100644 --- a/docs/_includes/interactive_repo_review.html +++ b/docs/_includes/interactive_repo_review.html @@ -21,10 +21,10 @@ header={false} deps={[ "sp-repo-review==2023.11.17", - "repo-review==0.10.1", - "validate-pyproject==0.15", - "scikit-build-core==0.6.1", - "cibuildwheel==2.16.2", + "repo-review~=0.10.0", + "validate-pyproject~=0.15.0", + "scikit-build-core~=0.6.0", + "cibuildwheel~=2.16.0", ]} />, ); From 3ae7529a09cd55f17eb7acefae2c06d261481510 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Mon, 27 Nov 2023 18:24:20 -0500 Subject: [PATCH 02/36] fix: add license file and test (#320) Signed-off-by: Henry Schreiner --- docs/_includes/pyproject.md | 1 + noxfile.py | 24 ++++++++++++++++++++ {{cookiecutter.project_name}}/pyproject.toml | 1 + 3 files changed, 26 insertions(+) diff --git a/docs/_includes/pyproject.md b/docs/_includes/pyproject.md index f6831edc..e5eb6ec1 100644 --- a/docs/_includes/pyproject.md +++ b/docs/_includes/pyproject.md @@ -7,6 +7,7 @@ The metadata is specified in a [standards-based][metadata] format: name = "package" description = "A great package." readme = "README.md" +license.file = "LICENSE" authors = [ { name = "My Name", email = "me@email.com" }, ] diff --git a/noxfile.py b/noxfile.py index 8d780eeb..5b9c864d 100644 --- a/noxfile.py +++ b/noxfile.py @@ -8,13 +8,16 @@ from __future__ import annotations import difflib +import email.message import json import os import re import shutil import stat import sys +import tarfile import urllib.request +import zipfile from collections.abc import Callable from pathlib import Path @@ -270,6 +273,27 @@ def dist(session: nox.Session, backend: str, vcs: bool) -> None: session.run("twine", "check", f"{sdist}", f"{wheel}") + # Check for LICENSE in SDist + with tarfile.open(sdist) as tf: + names = tf.getnames() + if not any(n.endswith("LICENSE") for n in names): + msg = f"license file missing from {backend} vcs={vcs}'s sdist. Found: {names}" + session.error(msg) + + # Check for LICENSE in wheel + with zipfile.ZipFile(wheel) as zf: + names = zf.namelist() + metadata_path = next(iter(n for n in names if n.endswith("METADATA"))) + with zf.open(metadata_path) as mfile: + txt = mfile.read() + license_fields = email.message.EmailMessage(txt).get_all("License", []) + if license_fields: + msg = f"Should not have anything in the License slot, got {license_fields}" + session.error(msg) + if not any(n.endswith("LICENSE") for n in names): + msg = f"license file missing from {backend} vcs={vcs}'s wheel. Found: {names}" + session.error(msg) + dist = DIR / "dist" dist.mkdir(exist_ok=True) sdist.rename(dist / sdist.stem) diff --git a/{{cookiecutter.project_name}}/pyproject.toml b/{{cookiecutter.project_name}}/pyproject.toml index 5c5cfa03..41175675 100644 --- a/{{cookiecutter.project_name}}/pyproject.toml +++ b/{{cookiecutter.project_name}}/pyproject.toml @@ -162,6 +162,7 @@ maintainers = [ {%- endif %} description = "{{ cookiecutter.project_short_description }}" readme = "README.md" +license.file = "LICENSE" requires-python = ">=3.8" classifiers = [ "Development Status :: 1 - Planning", From 60dd4b1459be551d7e9076999f6465aa7962f0ba Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Tue, 28 Nov 2023 10:11:07 -0500 Subject: [PATCH 03/36] fix: autoupdate for nox (#321) Signed-off-by: Henry Schreiner --- noxfile.py | 43 ++++++++++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/noxfile.py b/noxfile.py index 5b9c864d..c5912a2b 100644 --- a/noxfile.py +++ b/noxfile.py @@ -9,6 +9,7 @@ import difflib import email.message +import functools import json import os import re @@ -20,6 +21,7 @@ import zipfile from collections.abc import Callable from pathlib import Path +from typing import Any import nox @@ -401,6 +403,32 @@ def pc_bump(session: nox.Session) -> None: page.write_text(txt) +@functools.lru_cache(maxsize=None) # noqa: UP033 +def get_latest_version_tag(repo: str, old_version: str) -> dict[str, Any] | None: + auth = os.environ.get("GITHUB_TOKEN", os.environ.get("GITHUB_API_TOKEN", "")) + request = urllib.request.Request( + f"https://api.github.com/repos/{repo}/tags?per_page=100" + ) + request.add_header("Accept", "application/vnd.github+json") + request.add_header("X-GitHub-Api-Version", "2022-11-28") + if auth: + request.add_header("Authorization", f"Bearer: {auth}") + response = urllib.request.urlopen(request) + results = json.loads(response.read()) + if not results: + msg = f"No results for {repo}" + raise RuntimeError(msg) + tags = [ + x["name"] + for x in results + if x["name"].count(".") == old_version.count(".") + and x["name"].startswith("v") == old_version.startswith("v") + ] + if tags: + return tags[0] + return None + + @nox.session(venv_backend="none") def gha_bump(session: nox.Session) -> None: """ @@ -415,23 +443,12 @@ def gha_bump(session: nox.Session) -> None: # This assumes there is a single version per action old_versions = {m[1]: m[2] for m in GHA_VERS.finditer(full_txt)} - versions = {} for repo, old_version in old_versions.items(): session.log(f"{repo}: {old_version}") - if repo not in versions: - response = urllib.request.urlopen( - f"https://api.github.com/repos/{repo}/tags" - ) - versions[repo] = json.loads(response.read()) - tags = [ - x["name"] - for x in versions[repo] - if x["name"].count(".") == old_version.count(".") - ] - if not tags: + new_version = get_latest_version_tag(repo, old_version) + if not new_version: continue - new_version = tags[0] if new_version != old_version: session.log(f"Convert {repo}: {old_version} -> {new_version}") for page in pages: From c39738fef86777b70d4e6be4e08b8bd3c7c54c57 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 28 Nov 2023 16:08:35 -0500 Subject: [PATCH 04/36] chore(deps): bump versions (#317) [create-pull-request] automated change Co-authored-by: henryiii --- .pre-commit-config.yaml | 4 ++-- docs/pages/guides/style.md | 6 +++--- {{cookiecutter.project_name}}/.pre-commit-config.yaml | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ee7dfca6..1b8200f6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -29,7 +29,7 @@ repos: additional_dependencies: [black==23.*] - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.1.5" + rev: "v0.1.6" hooks: - id: ruff args: ["--fix", "--show-fixes"] @@ -43,7 +43,7 @@ repos: - id: rst-inline-touching-normal - repo: https://github.com/pre-commit/mirrors-mypy - rev: "v1.7.0" + rev: "v1.7.1" hooks: - id: mypy files: "(src|tests)" diff --git a/docs/pages/guides/style.md b/docs/pages/guides/style.md index 8fb781f6..968b4fe5 100644 --- a/docs/pages/guides/style.md +++ b/docs/pages/guides/style.md @@ -136,7 +136,7 @@ look like Black, but run 30x faster. Here is the snippet to add Black to your ```yaml - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.1.5" + rev: "v0.1.6" hooks: # id: ruff would go here if using both - id: ruff-format @@ -197,7 +197,7 @@ pre-commit hook. ```yaml - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.1.5" + rev: "v0.1.6" hooks: - id: ruff args: ["--fix", "--show-fixes"] @@ -529,7 +529,7 @@ The MyPy addition for pre-commit: ```yaml - repo: https://github.com/pre-commit/mirrors-mypy - rev: "v1.7.0" + rev: "v1.7.1" hooks: - id: mypy files: src diff --git a/{{cookiecutter.project_name}}/.pre-commit-config.yaml b/{{cookiecutter.project_name}}/.pre-commit-config.yaml index 7d89b640..357404c9 100644 --- a/{{cookiecutter.project_name}}/.pre-commit-config.yaml +++ b/{{cookiecutter.project_name}}/.pre-commit-config.yaml @@ -45,7 +45,7 @@ repos: args: [--prose-wrap=always] - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.1.5" + rev: "v0.1.6" hooks: - id: ruff args: ["--fix", "--show-fixes"] @@ -71,7 +71,7 @@ repos: {%- endif %} - repo: https://github.com/pre-commit/mirrors-mypy - rev: "v1.7.0" + rev: "v1.7.1" hooks: - id: mypy files: src|tests From 2dc3b36c8edacf1652509660a4280b4d350d7fbe Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Wed, 29 Nov 2023 10:12:36 -0500 Subject: [PATCH 05/36] fix: grant, not coop agreement (#324) Signed-off-by: Henry Schreiner --- docs/pages/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/pages/index.md b/docs/pages/index.md index 10474da8..e6fbc9ef 100644 --- a/docs/pages/index.md +++ b/docs/pages/index.md @@ -68,7 +68,7 @@ basic facility with git to use these tools successfully. We recommend the > in 2020. It was merged with the [NSLS-II][] guidelines and moved to Scientific > Python at the [2023 Scientific Python Developer Summit][2023 spdev], along > with many updates. Improved support for compiled components supported in part -> by NSF cooperative agreement [OAC-2209877][]. +> by NSF grant [OAC-2209877][]. [simple]: {% link pages/guides/packaging_simple.md %} From 36b045279c42cdd9e1b06f2276fc2f89ab0ddd8f Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Wed, 29 Nov 2023 10:12:49 -0500 Subject: [PATCH 06/36] fix: use build-and-inspect-packages, fix typo in guide (#322) Signed-off-by: Henry Schreiner --- docs/pages/guides/gha_pure.md | 6 ++++-- ...okiecutter.__type!='compiled' %}cd.yml{% endif %} | 12 ++---------- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/docs/pages/guides/gha_pure.md b/docs/pages/guides/gha_pure.md index d6cca353..582d28d1 100644 --- a/docs/pages/guides/gha_pure.md +++ b/docs/pages/guides/gha_pure.md @@ -123,7 +123,7 @@ later in the upload action for the release job, as well). > ``` > > The artifact it produces is named `Packages`, so that's what you need to use -> later to publish. +> later to publish. This will be used instead of the manual steps below. And then, you need a release job: @@ -201,6 +201,7 @@ name: CD on: workflow_dispatch: + pull_request: push: branches: - main @@ -229,7 +230,7 @@ jobs: steps: - uses: actions/download-artifact@v3 with: - name: artifact + name: Packages path: dist - uses: pypa/gh-action-pypi-publish@release/v1 @@ -246,6 +247,7 @@ name: CD on: workflow_dispatch: + pull_request: push: branches: - main diff --git a/{{cookiecutter.project_name}}/.github/workflows/{% if cookiecutter.__type!='compiled' %}cd.yml{% endif %} b/{{cookiecutter.project_name}}/.github/workflows/{% if cookiecutter.__type!='compiled' %}cd.yml{% endif %} index 7c8cb433..9cdc3f98 100644 --- a/{{cookiecutter.project_name}}/.github/workflows/{% if cookiecutter.__type!='compiled' %}cd.yml{% endif %} +++ b/{{cookiecutter.project_name}}/.github/workflows/{% if cookiecutter.__type!='compiled' %}cd.yml{% endif %} @@ -27,15 +27,7 @@ jobs: with: fetch-depth: 0 - - name: Build sdist and wheel - run: pipx run build - - - uses: actions/upload-artifact@v3 - with: - path: dist - - - name: Check products - run: pipx run twine check dist/* + - uses: hynek/build-and-inspect-python-package@v1 publish: needs: [dist] @@ -49,7 +41,7 @@ jobs: steps: - uses: actions/download-artifact@v3 with: - name: artifact + name: Packages path: dist - uses: pypa/gh-action-pypi-publish@release/v1 From 1b9bb38b09e523e05a3d4c6e0dc8d6323d35ef21 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Wed, 29 Nov 2023 10:13:44 -0500 Subject: [PATCH 07/36] fix: change default formatter to ruff-format (#323) Signed-off-by: Henry Schreiner --- docs/pages/guides/style.md | 100 ++++++++++-------- .../.pre-commit-config.yaml | 6 +- {{cookiecutter.project_name}}/pyproject.toml | 46 ++++---- 3 files changed, 78 insertions(+), 74 deletions(-) diff --git a/docs/pages/guides/style.md b/docs/pages/guides/style.md index 968b4fe5..31df5b81 100644 --- a/docs/pages/guides/style.md +++ b/docs/pages/guides/style.md @@ -102,57 +102,61 @@ There are a _few_ options, mostly to enable/disable certain files, remove string normalization, and to change the line length, and those go in your `pyproject.toml` file. -{% tabs %} {% tab black Black %} +{% tabs %} {% tab ruff Ruff-format %} -Here is the snippet to add Black to your `.pre-commit-config.yml`: +Ruff, the powerful Rust-based linter, has a formatter that is designed with the +help of some of the Black authors to look 99.9% like Black, but run 30x faster. +Here is the snippet to add the formatter to your `.pre-commit-config.yml` +(combine with the Ruff linter below): ```yaml -- repo: https://github.com/psf/black-pre-commit-mirror - rev: "23.11.0" +- repo: https://github.com/astral-sh/ruff-pre-commit + rev: "v0.1.6" hooks: - - id: black + # id: ruff would go here if using both + - id: ruff-format ``` -{% details You can add a Black badge to your repo as well %} +As you likely will be using Ruff if you follow this guide, the formatter is +recommended as well. -[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) +{% details You can add a Ruff badge to your repo as well %} + +[![Code style: Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/format.json)](https://github.com/astral-sh/ruff) ```md -[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) +[![Code style: Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/format.json)](https://github.com/astral-sh/ruff) ``` ``` -.. image:: https://img.shields.io/badge/code%20style-black-000000.svg - :target: https://github.com/psf/black +.. image:: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/format.json + :target: https://github.com/astral-sh/ruff ``` {% enddetails %} -{% endtab %} {% tab ruff Ruff-format %} +{% endtab %} {% tab black Black %} -Ruff, the powerful Rust-based linter, also has a formatter that is designed to -look like Black, but run 30x faster. Here is the snippet to add Black to your -`.pre-commit-config.yml` (combine with Ruff below): +Here is the snippet to add Black to your `.pre-commit-config.yml`: ```yaml -- repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.1.6" +- repo: https://github.com/psf/black-pre-commit-mirror + rev: "23.11.0" hooks: - # id: ruff would go here if using both - - id: ruff-format + - id: black ``` -{% details You can add a Ruff badge to your repo as well %} +{% details You can add a Black badge to your repo as well %} -[![Code style: Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/format.json)](https://github.com/astral-sh/ruff) +[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) ```md -[![Code style: Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/format.json)](https://github.com/astral-sh/ruff) +[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) ``` ``` -.. image:: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/format.json - :target: https://github.com/astral-sh/ruff +.. image:: https://img.shields.io/badge/code%20style-black-000000.svg + :target: https://github.com/psf/black ``` {% enddetails %} @@ -214,32 +218,34 @@ src = ["src"] [tool.ruff.lint] extend-select = [ - "B", # flake8-bugbear - "I", # isort - "ARG", # flake8-unused-arguments - "C4", # flake8-comprehensions - "EM", # flake8-errmsg - "ICN", # flake8-import-conventions - "G", # flake8-logging-format - "PGH", # pygrep-hooks - "PIE", # flake8-pie - "PL", # pylint - "PT", # flake8-pytest-style - "PTH", # flake8-use-pathlib - "RET", # flake8-return - "RUF", # Ruff-specific - "SIM", # flake8-simplify - "T20", # flake8-print - "UP", # pyupgrade - "YTT", # flake8-2020 - "EXE", # flake8-executable - "NPY", # NumPy specific rules - "PD", # pandas-vet - "FURB", # refurb - "PYI", # flake8-pyi + "B", # flake8-bugbear + "I", # isort + "ARG", # flake8-unused-arguments + "C4", # flake8-comprehensions + "EM", # flake8-errmsg + "ICN", # flake8-import-conventions + "G", # flake8-logging-format + "PGH", # pygrep-hooks + "PIE", # flake8-pie + "PL", # pylint + "PT", # flake8-pytest-style + "PTH", # flake8-use-pathlib + "RET", # flake8-return + "RUF", # Ruff-specific + "SIM", # flake8-simplify + "T20", # flake8-print + "UP", # pyupgrade + "YTT", # flake8-2020 + "EXE", # flake8-executable + "NPY", # NumPy specific rules + "PD", # pandas-vet + "FURB", # refurb + "PYI", # flake8-pyi ] ignore = [ - "PLR", # Design related pylint codes + "PLR09", # Too many <...> + "PLR2004", # Magic value used in comparison + "ISC001", # Conflicts with formatter ] typing-modules = ["mypackage._compat.typing"] isort.required-imports = ["from __future__ import annotations"] diff --git a/{{cookiecutter.project_name}}/.pre-commit-config.yaml b/{{cookiecutter.project_name}}/.pre-commit-config.yaml index 357404c9..7f59e38c 100644 --- a/{{cookiecutter.project_name}}/.pre-commit-config.yaml +++ b/{{cookiecutter.project_name}}/.pre-commit-config.yaml @@ -3,11 +3,6 @@ ci: autofix_commit_msg: "style: pre-commit fixes" repos: - - repo: https://github.com/psf/black-pre-commit-mirror - rev: "23.11.0" - hooks: - - id: black-jupyter - - repo: https://github.com/adamchainz/blacken-docs rev: "1.16.0" hooks: @@ -49,6 +44,7 @@ repos: hooks: - id: ruff args: ["--fix", "--show-fixes"] + - id: ruff-format {%- if cookiecutter.backend == "setuptools" or cookiecutter.backend == "pybind11" %} diff --git a/{{cookiecutter.project_name}}/pyproject.toml b/{{cookiecutter.project_name}}/pyproject.toml index 41175675..d574060c 100644 --- a/{{cookiecutter.project_name}}/pyproject.toml +++ b/{{cookiecutter.project_name}}/pyproject.toml @@ -346,30 +346,32 @@ target-version = "py38" [tool.ruff.lint] extend-select = [ - "B", # flake8-bugbear - "I", # isort - "ARG", # flake8-unused-arguments - "C4", # flake8-comprehensions - "EM", # flake8-errmsg - "ICN", # flake8-import-conventions - "G", # flake8-logging-format - "PGH", # pygrep-hooks - "PIE", # flake8-pie - "PL", # pylint - "PT", # flake8-pytest-style - "PTH", # flake8-use-pathlib - "RET", # flake8-return - "RUF", # Ruff-specific - "SIM", # flake8-simplify - "T20", # flake8-print - "UP", # pyupgrade - "YTT", # flake8-2020 - "EXE", # flake8-executable - "NPY", # NumPy specific rules - "PD", # pandas-vet + "B", # flake8-bugbear + "I", # isort + "ARG", # flake8-unused-arguments + "C4", # flake8-comprehensions + "EM", # flake8-errmsg + "ICN", # flake8-import-conventions + "G", # flake8-logging-format + "PGH", # pygrep-hooks + "PIE", # flake8-pie + "PL", # pylint + "PT", # flake8-pytest-style + "PTH", # flake8-use-pathlib + "RET", # flake8-return + "RUF", # Ruff-specific + "SIM", # flake8-simplify + "T20", # flake8-print + "UP", # pyupgrade + "YTT", # flake8-2020 + "EXE", # flake8-executable + "NPY", # NumPy specific rules + "PD", # pandas-vet ] ignore = [ - "PLR", # Design related pylint codes + "PLR09", # Too many <...> + "PLR2004", # Magic value used in comparison + "ISC001", # Conflicts with formatter ] isort.required-imports = ["from __future__ import annotations"] # Uncomment if using a _compat.typing backport From 4e796a6170292ede51774c52583767049f8f30b2 Mon Sep 17 00:00:00 2001 From: Blake Naccarato Date: Wed, 29 Nov 2023 08:33:33 -0800 Subject: [PATCH 08/36] docs: reword an incomplete sentence in tutorial intro (#325) * Reword an incomplete sentence in tutorial intro Looks like this sentence was in the midst of being reworded, and some bits got left out. Here's one possible way to finish the sentence. * style: pre-commit fixes --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- docs/pages/tutorials/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/pages/tutorials/index.md b/docs/pages/tutorials/index.md index 074db356..408f6a6c 100644 --- a/docs/pages/tutorials/index.md +++ b/docs/pages/tutorials/index.md @@ -10,8 +10,8 @@ has_children: true Do you have a pile of scientific Python scripts or Jupyter notebooks that are becoming unwieldy? Are changes to some parts of your code accidentally breaking -other parts of your code? Do you want to more maintainable, reusable, and -shareable form? +other parts of your code? Do you want to present them in a more maintainable, +reusable, and shareable form? This tutorial aims to help scientists who write code find good practices and standard tools, and to help small- and medium-sized scientific software projects From fbdc19246c1c19cb666527b89c3080875a3bae47 Mon Sep 17 00:00:00 2001 From: James Frost Date: Thu, 30 Nov 2023 18:12:44 +0000 Subject: [PATCH 09/36] fix: accept other filenames for LICENSE (#327) * fix: accept other filenames for LICENSE The added filenames are LICENCE and COPYING, both of which are commonly used. There might be others accepted by GitHub, but the list can easily be extended. This check could be a little slower due to having to do three times the number of string comparisons, but hoefully that is counteracted by the switch to using a generator, ensuring that an intermediate list doesn't have to be built, and that the check can terminate as soon as a file is found. Fixes https://github.com/scientific-python/cookie/issues/326 * fix: rearrange comprehension for clarity Co-authored-by: Henry Schreiner * style: pre-commit fixes * Remove unneeded any * Reorder loops due to lack of comprehension * Check that LICENCE is at start of filename * style: pre-commit fixes --------- Co-authored-by: Henry Schreiner Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- src/sp_repo_review/checks/general.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/sp_repo_review/checks/general.py b/src/sp_repo_review/checks/general.py index 047e4d8b..6caccc46 100644 --- a/src/sp_repo_review/checks/general.py +++ b/src/sp_repo_review/checks/general.py @@ -50,7 +50,12 @@ class PY003(General): @staticmethod def check(package: Traversable) -> bool: "Projects must have a license" - return len([p for p in package.iterdir() if "LICENSE" in p.name]) > 0 + spellings = ("LICENSE", "LICENCE", "COPYING") + return any( + p.name.startswith(spelling) + for p in package.iterdir() + for spelling in spellings + ) class PY004(General): From ed74738a64cd55926d5ef6c6754a18e209cdf8ed Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 4 Dec 2023 14:25:46 -0500 Subject: [PATCH 10/36] chore(deps): bump versions (#328) [create-pull-request] automated change Co-authored-by: henryiii --- docs/pages/guides/style.md | 2 +- {{cookiecutter.project_name}}/.pre-commit-config.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/pages/guides/style.md b/docs/pages/guides/style.md index 31df5b81..2b4e8fd0 100644 --- a/docs/pages/guides/style.md +++ b/docs/pages/guides/style.md @@ -747,7 +747,7 @@ following pre-commit config: ```yaml - repo: https://github.com/pre-commit/mirrors-clang-format - rev: "v17.0.5" + rev: "v17.0.6" hooks: - id: clang-format types_or: [c++, c, cuda] diff --git a/{{cookiecutter.project_name}}/.pre-commit-config.yaml b/{{cookiecutter.project_name}}/.pre-commit-config.yaml index 7f59e38c..98c8e2d7 100644 --- a/{{cookiecutter.project_name}}/.pre-commit-config.yaml +++ b/{{cookiecutter.project_name}}/.pre-commit-config.yaml @@ -59,7 +59,7 @@ repos: {%- if cookiecutter.backend in ["pybind11", "skbuild", "mesonpy"] %} - repo: https://github.com/pre-commit/mirrors-clang-format - rev: "v17.0.5" + rev: "v17.0.6" hooks: - id: clang-format types_or: [c++, c, cuda] From 77d44a09dae727b3acfd921243933e75ea5ff834 Mon Sep 17 00:00:00 2001 From: Lukas Burgholzer Date: Fri, 8 Dec 2023 14:47:48 +0100 Subject: [PATCH 11/36] fix: docs serve command (#333) --- {{cookiecutter.project_name}}/.github/CONTRIBUTING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/{{cookiecutter.project_name}}/.github/CONTRIBUTING.md b/{{cookiecutter.project_name}}/.github/CONTRIBUTING.md index 3b27c7c7..16e7a396 100644 --- a/{{cookiecutter.project_name}}/.github/CONTRIBUTING.md +++ b/{{cookiecutter.project_name}}/.github/CONTRIBUTING.md @@ -19,7 +19,7 @@ specific jobs: ```console $ nox -s lint # Lint only $ nox -s tests # Python tests -$ nox -s docs -- serve # Build and serve the docs +$ nox -s docs -- --serve # Build and serve the docs $ nox -s build # Make an SDist and wheel ``` @@ -95,7 +95,7 @@ nox -s docs You can see a preview with: ```bash -nox -s docs -- serve +nox -s docs -- --serve ``` # Pre-commit From 85cfb6e3f94876cdb8f7ff5dcce24b461697e60b Mon Sep 17 00:00:00 2001 From: Lukas Burgholzer Date: Fri, 8 Dec 2023 14:48:59 +0100 Subject: [PATCH 12/36] fix: incomplete coverage config (#332) --- {{cookiecutter.project_name}}/pyproject.toml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/{{cookiecutter.project_name}}/pyproject.toml b/{{cookiecutter.project_name}}/pyproject.toml index d574060c..ff17bc22 100644 --- a/{{cookiecutter.project_name}}/pyproject.toml +++ b/{{cookiecutter.project_name}}/pyproject.toml @@ -316,8 +316,7 @@ testpaths = [ [tool.coverage] run.source = ["{{ cookiecutter.__project_slug }}"] -port.exclude_lines = [ - 'pragma: no cover', +report.exclude_also = [ '\.\.\.', 'if typing.TYPE_CHECKING:', ] From 51b9a8c7c666e7f5565a5f67f499b615c51c1d9b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 8 Dec 2023 08:49:41 -0500 Subject: [PATCH 13/36] chore(deps): bump actions/setup-python from 4 to 5 (#329) Bumps [actions/setup-python](https://github.com/actions/setup-python) from 4 to 5. - [Release notes](https://github.com/actions/setup-python/releases) - [Commits](https://github.com/actions/setup-python/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/setup-python dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/reusable-cookie.yml | 2 +- .github/workflows/reusable-rr-tests.yml | 4 ++-- action.yml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/reusable-cookie.yml b/.github/workflows/reusable-cookie.yml index 7186c6ca..946a3842 100644 --- a/.github/workflows/reusable-cookie.yml +++ b/.github/workflows/reusable-cookie.yml @@ -32,7 +32,7 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} allow-prereleases: true diff --git a/.github/workflows/reusable-rr-tests.yml b/.github/workflows/reusable-rr-tests.yml index cea1a990..1153ffbb 100644 --- a/.github/workflows/reusable-rr-tests.yml +++ b/.github/workflows/reusable-rr-tests.yml @@ -21,7 +21,7 @@ jobs: with: fetch-depth: 0 - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} @@ -52,7 +52,7 @@ jobs: with: fetch-depth: 0 - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: "3.11" diff --git a/action.yml b/action.yml index 19a9d58b..6c6b886b 100644 --- a/action.yml +++ b/action.yml @@ -9,7 +9,7 @@ inputs: runs: using: composite steps: - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 id: python with: python-version: "3.11" From 7250955345ad4ba4a3c3341c9895c9758b82bb41 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 14 Dec 2023 16:58:45 -0500 Subject: [PATCH 14/36] chore(deps): bump versions (#334) * [create-pull-request] automated change * Apply suggestions from code review * fix: revert v3->v4 update Signed-off-by: Henry Schreiner --------- Signed-off-by: Henry Schreiner Co-authored-by: henryiii Co-authored-by: Henry Schreiner Co-authored-by: Henry Schreiner --- .pre-commit-config.yaml | 2 +- docs/pages/guides/gha_basic.md | 10 +++++----- docs/pages/guides/style.md | 8 ++++---- {{cookiecutter.project_name}}/.github/workflows/ci.yml | 4 ++-- {{cookiecutter.project_name}}/.pre-commit-config.yaml | 2 +- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 1b8200f6..3f4dfc8d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -29,7 +29,7 @@ repos: additional_dependencies: [black==23.*] - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.1.6" + rev: "v0.1.8" hooks: - id: ruff args: ["--fix", "--show-fixes"] diff --git a/docs/pages/guides/gha_basic.md b/docs/pages/guides/gha_basic.md index fb81a659..33579b07 100644 --- a/docs/pages/guides/gha_basic.md +++ b/docs/pages/guides/gha_basic.md @@ -60,7 +60,7 @@ lint: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: "3.x" - uses: pre-commit/action@v3.0.0 @@ -102,7 +102,7 @@ tests: fetch-depth: 0 # Only needed if using setuptools-scm - name: Setup Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} allow-prereleases: true @@ -395,7 +395,7 @@ Python version might come as a surprise. You can do that, though, using {% raw %} ```yaml -- uses: actions/setup-python@v4 +- uses: actions/setup-python@v5 id: python with: python-version: "3.11" @@ -639,7 +639,7 @@ configure Pages. ```yaml - name: Setup Pages id: pages - uses: actions/configure-pages@v3 + uses: actions/configure-pages@v4 ``` {% raw %} @@ -676,7 +676,7 @@ deploy: steps: - name: Deploy to GitHub Pages id: deployment - uses: actions/deploy-pages@v2 + uses: actions/deploy-pages@v3 ``` {% endraw %} diff --git a/docs/pages/guides/style.md b/docs/pages/guides/style.md index 2b4e8fd0..e2137719 100644 --- a/docs/pages/guides/style.md +++ b/docs/pages/guides/style.md @@ -111,7 +111,7 @@ Here is the snippet to add the formatter to your `.pre-commit-config.yml` ```yaml - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.1.6" + rev: "v0.1.8" hooks: # id: ruff would go here if using both - id: ruff-format @@ -141,7 +141,7 @@ Here is the snippet to add Black to your `.pre-commit-config.yml`: ```yaml - repo: https://github.com/psf/black-pre-commit-mirror - rev: "23.11.0" + rev: "23.12.0" hooks: - id: black ``` @@ -201,7 +201,7 @@ pre-commit hook. ```yaml - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.1.6" + rev: "v0.1.8" hooks: - id: ruff args: ["--fix", "--show-fixes"] @@ -465,7 +465,7 @@ pre-commit config will work: ```yaml - repo: https://github.com/PyCQA/isort - rev: "5.12.0" + rev: "5.13.2" hooks: - id: isort ``` diff --git a/{{cookiecutter.project_name}}/.github/workflows/ci.yml b/{{cookiecutter.project_name}}/.github/workflows/ci.yml index b5898356..87d769d9 100644 --- a/{{cookiecutter.project_name}}/.github/workflows/ci.yml +++ b/{{cookiecutter.project_name}}/.github/workflows/ci.yml @@ -22,7 +22,7 @@ jobs: - uses: actions/checkout@v4 with: fetch-depth: 0 - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: "3.x" - uses: pre-commit/action@v3.0.0 @@ -52,7 +52,7 @@ jobs: with: fetch-depth: 0 - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: {% raw %}${{ matrix.python-version }}{% endraw %} allow-prereleases: true diff --git a/{{cookiecutter.project_name}}/.pre-commit-config.yaml b/{{cookiecutter.project_name}}/.pre-commit-config.yaml index 98c8e2d7..725bda8b 100644 --- a/{{cookiecutter.project_name}}/.pre-commit-config.yaml +++ b/{{cookiecutter.project_name}}/.pre-commit-config.yaml @@ -40,7 +40,7 @@ repos: args: [--prose-wrap=always] - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.1.6" + rev: "v0.1.8" hooks: - id: ruff args: ["--fix", "--show-fixes"] From 002126af364bd7084f5cf0820b09daab62849e4f Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Fri, 15 Dec 2023 23:28:57 -0500 Subject: [PATCH 15/36] fix: prepare for artifact v4 (#335) * fix: prepare for artifact v4 Signed-off-by: Henry Schreiner * Apply suggestions from code review * Apply suggestions from code review --------- Signed-off-by: Henry Schreiner --- .github/workflows/reusable-cookie.yml | 1 + docs/pages/guides/gha_pure.md | 10 +++++++-- docs/pages/guides/gha_wheels.md | 22 ++++++++++++++----- ...ter.__type=='compiled' %}cd.yml{% endif %} | 8 ++++++- 4 files changed, 32 insertions(+), 9 deletions(-) diff --git a/.github/workflows/reusable-cookie.yml b/.github/workflows/reusable-cookie.yml index 946a3842..9ff3dfd3 100644 --- a/.github/workflows/reusable-cookie.yml +++ b/.github/workflows/reusable-cookie.yml @@ -171,6 +171,7 @@ jobs: - uses: actions/upload-artifact@v3 with: + name: Packages path: dist pass: diff --git a/docs/pages/guides/gha_pure.md b/docs/pages/guides/gha_pure.md index 582d28d1..27ec454d 100644 --- a/docs/pages/guides/gha_pure.md +++ b/docs/pages/guides/gha_pure.md @@ -79,6 +79,7 @@ dist: - uses: actions/upload-artifact@v3 with: + name: Packages path: dist/* - name: Check metadata @@ -104,6 +105,11 @@ GitHub Actions (in fact, they use it to setup other applications). We upload the artifact just to make it available via the GitHub PR/Checks API. You can download a file to test locally if you want without making a release. +{: .warning } + +> As of `upload-artifact@v4`, the artifact name must be unique. Extending an +> existing artifact is no longer supported. + We also add an optional check using twine for the metadata (it will be tested later in the upload action for the release job, as well). @@ -142,7 +148,7 @@ publish: steps: - uses: actions/download-artifact@v3 with: - name: artifact + name: Packages path: dist - uses: pypa/gh-action-pypi-publish@release/v1 @@ -168,7 +174,7 @@ publish: steps: - uses: actions/download-artifact@v3 with: - name: artifact + name: Packages path: dist - uses: pypa/gh-action-pypi-publish@release/v1 diff --git a/docs/pages/guides/gha_wheels.md b/docs/pages/guides/gha_wheels.md index 0bafe2c1..21add009 100644 --- a/docs/pages/guides/gha_wheels.md +++ b/docs/pages/guides/gha_wheels.md @@ -38,8 +38,8 @@ This will run on releases. If you use a develop branch, you could include `pull_request: branches: [stable]`, since it changes rarely. GitHub actions also [has a `workflow_dispatch` option][workflow_dispatch], which will allow you to click a button in the GUI to trigger a build, which is perfect for testing -wheels before making a release; you can download them from "artifacts". You can -even define variables that you can set in the GUI and access in the CI! +wheels before making a release; you can download them from the "artifacts". You +can even define variables that you can set in the GUI and access in the CI! [workflow_dispatch]: https://github.blog/changelog/2020-07-06-github-actions-manual-triggers-with-workflow_dispatch/ @@ -94,6 +94,7 @@ make_sdist: - uses: actions/upload-artifact@v3 with: + name: SDist path: dist/*.tar.gz ``` @@ -126,6 +127,7 @@ build_wheels: - name: Upload wheels uses: actions/upload-artifact@v3 with: + name: Wheels-${{ matrix.os }} path: wheelhouse/*.whl ``` @@ -177,8 +179,12 @@ upload_all: steps: - uses: actions/download-artifact@v3 with: - name: artifact - path: dist + path: all + + - name: Merge files + run: | + mkdir dist + mv all/*/* dist - uses: pypa/gh-action-pypi-publish@release/v1 ``` @@ -203,8 +209,12 @@ upload_all: steps: - uses: actions/download-artifact@v3 with: - name: artifact - path: dist + path: all + + - name: Merge files + run: | + mkdir dist + mv all/*/* dist - uses: pypa/gh-action-pypi-publish@release/v1 with: diff --git a/{{cookiecutter.project_name}}/.github/workflows/{% if cookiecutter.__type=='compiled' %}cd.yml{% endif %} b/{{cookiecutter.project_name}}/.github/workflows/{% if cookiecutter.__type=='compiled' %}cd.yml{% endif %} index a5a1b16e..7e7aabc8 100644 --- a/{{cookiecutter.project_name}}/.github/workflows/{% if cookiecutter.__type=='compiled' %}cd.yml{% endif %} +++ b/{{cookiecutter.project_name}}/.github/workflows/{% if cookiecutter.__type=='compiled' %}cd.yml{% endif %} @@ -27,6 +27,7 @@ jobs: - uses: actions/upload-artifact@v3 with: + name: SDist path: dist/*.tar.gz build_wheels: @@ -47,6 +48,7 @@ jobs: - name: Upload wheels uses: actions/upload-artifact@v3 with: + name: Wheel-{% raw %}${{ matrix.os }}{% endraw %} path: wheelhouse/*.whl upload_all: @@ -60,9 +62,13 @@ jobs: steps: - uses: actions/download-artifact@v3 with: - name: artifact path: dist + - name: Merge files + run: | + mkdir dist + mv all/*/* dist + - uses: pypa/gh-action-pypi-publish@release/v1 with: # Remember to tell (test-)pypi about this repo before publishing From 1dcf83ed6c8537c84dc79935940f75e7f3669e01 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Tue, 19 Dec 2023 12:41:32 -0500 Subject: [PATCH 16/36] ci: filter pre-releases (#345) Signed-off-by: Henry Schreiner --- noxfile.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/noxfile.py b/noxfile.py index c5912a2b..2343dc3f 100644 --- a/noxfile.py +++ b/noxfile.py @@ -390,7 +390,12 @@ def pc_bump(session: nox.Session) -> None: for proj, (old_version, space) in old_versions.items(): if proj not in versions: versions[proj] = session.run( - "lastversion", "--at=github", "--format=tag", proj, silent=True + "lastversion", + "--at=github", + "--format=tag", + "--exclude=alpha|beta|rc", + proj, + silent=True, ).strip() new_version = versions[proj] From 2b5c715c9235836dd3830b3b1a182b0fe4f1b06c Mon Sep 17 00:00:00 2001 From: edsq Date: Tue, 19 Dec 2023 14:38:46 -0500 Subject: [PATCH 17/36] fix: correct tutorial src layout (#340) (#346) * fix: correct tutorial src layout (#340) * Update docs/pages/tutorials/packaging.md --------- Co-authored-by: Henry Schreiner --- docs/pages/tutorials/packaging.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/pages/tutorials/packaging.md b/docs/pages/tutorials/packaging.md index ef75420f..9b268692 100644 --- a/docs/pages/tutorials/packaging.md +++ b/docs/pages/tutorials/packaging.md @@ -41,21 +41,22 @@ git init ``` Within the package directory `example`, create subdirectories `src` ("source") -for the source code. +and `src/example` for the source code. ```bash mkdir src +mkdir src/example ``` -Create a file at `src/__init__.py`. This is what identifies the directory as a -"package" to Python. It may remain empty. +Create a file at `src/example/__init__.py`. This is what identifies the +directory as a "package" to Python. It may remain empty. ```bash -touch src/__init__.py +touch src/example/__init__.py ``` Place `refraction.py`, our code from the previous section, next to it, at -`src/refraction.py`. +`src/example/refraction.py`. The last element your package needs is a `pyproject.toml` file, placed in the root directory. From 46f8858d222b23df7ce22d08328245e1d44d5678 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Tue, 19 Dec 2023 15:16:41 -0500 Subject: [PATCH 18/36] ci: fix syntax for regex (#347) Signed-off-by: Henry Schreiner --- noxfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/noxfile.py b/noxfile.py index 2343dc3f..18ae97fe 100644 --- a/noxfile.py +++ b/noxfile.py @@ -393,7 +393,7 @@ def pc_bump(session: nox.Session) -> None: "lastversion", "--at=github", "--format=tag", - "--exclude=alpha|beta|rc", + "--exclude=~alpha|beta|rc", proj, silent=True, ).strip() From 31940ff83a199b637d2b1828ffca7b322074c9d4 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Wed, 20 Dec 2023 17:47:33 -0500 Subject: [PATCH 19/36] feat: groups for dependabot (#348) * ci: group dependabot updates Signed-off-by: Henry Schreiner * feat: grouped updates for Dependabot Signed-off-by: Henry Schreiner --------- Signed-off-by: Henry Schreiner --- .github/dependabot.yml | 4 +++ README.md | 1 + docs/pages/guides/gha_basic.md | 10 ++++-- src/sp_repo_review/checks/github.py | 35 ++++++++++++++++++- .../.github/dependabot.yml | 4 +++ 5 files changed, 51 insertions(+), 3 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 2c7d1708..9ecc51dc 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -5,3 +5,7 @@ updates: directory: "/" schedule: interval: "daily" + groups: + actions: + patterns: + - "*" diff --git a/README.md b/README.md index c6cb5bdf..cb901948 100644 --- a/README.md +++ b/README.md @@ -348,6 +348,7 @@ for family, grp in itertools.groupby(collected.checks.items(), key=lambda x: x[1 - [`GH200`](https://learn.scientific-python.org/development/guides/gha-basic#GH200): Maintained by Dependabot - [`GH210`](https://learn.scientific-python.org/development/guides/gha-basic#GH210): Maintains the GitHub action versions with Dependabot - [`GH211`](https://learn.scientific-python.org/development/guides/gha-basic#GH211): Do not pin core actions as major versions +- [`GH212`](https://learn.scientific-python.org/development/guides/gha-basic#GH212): Require GHA update grouping ### MyPy - [`MY100`](https://learn.scientific-python.org/development/guides/style#MY100): Uses MyPy (pyproject config) diff --git a/docs/pages/guides/gha_basic.md b/docs/pages/guides/gha_basic.md index 33579b07..20f54382 100644 --- a/docs/pages/guides/gha_basic.md +++ b/docs/pages/guides/gha_basic.md @@ -142,14 +142,20 @@ updates: directory: "/" schedule: interval: "weekly" + groups: + actions: + patterns: + - "*" ``` This will check to see if there are updates to the action weekly, and will make a PR if there are updates, including the changelog and commit summary in the PR. If you select a name like `v1`, this should only look for updates of the same form (since April 2022) - there is no need to restrict updates for "moving tag" -updates anymore {% rr PY006 %}. You can also use SHA's and dependabot will -respect that too. +updates anymore {% rr GH211 %}. You can also use SHA's and dependabot will +respect that too. And `groups` will combine actions updates {% rr GH212 %}, +which is both cleaner and sometimes required for dependent actions, like +`upload-artifact`/`download-artifact`. You can use this for other ecosystems too, including Python. diff --git a/src/sp_repo_review/checks/github.py b/src/sp_repo_review/checks/github.py index b09edcf5..c3d22c65 100644 --- a/src/sp_repo_review/checks/github.py +++ b/src/sp_repo_review/checks/github.py @@ -149,7 +149,11 @@ def check(dependabot: dict[str, Any]) -> bool: - package-ecosystem: "github-actions" directory: "/" schedule: - interval: "weekly" + interval: "weekly" + groups: + actions: + patterns: + - "*" ``` """ for ecosystem in dependabot.get("updates", []): @@ -179,5 +183,34 @@ def check(dependabot: dict[str, Any]) -> bool: return True +class GH212(GitHub): + "Require GHA update grouping" + + requires = {"GH200", "GH210"} + url = mk_url("gha-basic") + + @staticmethod + def check(dependabot: dict[str, Any]) -> bool: + """ + Projects should group their updates to avoid extra PRs and stay in sync. + This is now supported by dependabot since June 2023. + + ```yaml + groups: + actions: + patterns: + - "*" + ``` + """ + + for ecosystem in dependabot.get("updates", []): + if ( + ecosystem.get("package-ecosystem", "") == "github-actions" + and "groups" not in ecosystem + ): + return False + return True + + def repo_review_checks() -> dict[str, GitHub]: return {p.__name__: p() for p in GitHub.__subclasses__()} diff --git a/{{cookiecutter.project_name}}/.github/dependabot.yml b/{{cookiecutter.project_name}}/.github/dependabot.yml index 6fddca0d..6c4b3695 100644 --- a/{{cookiecutter.project_name}}/.github/dependabot.yml +++ b/{{cookiecutter.project_name}}/.github/dependabot.yml @@ -5,3 +5,7 @@ updates: directory: "/" schedule: interval: "weekly" + groups: + actions: + patterns: + - "*" From 4bf4c91a02992c90044666ca77e649baecdb7fe8 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Wed, 20 Dec 2023 18:14:47 -0500 Subject: [PATCH 20/36] feat: support archive v4 (#350) Signed-off-by: Henry Schreiner --- README.md | 1 + docs/pages/guides/gha_basic.md | 4 +- docs/pages/guides/gha_pure.md | 16 ++++---- docs/pages/guides/gha_wheels.md | 30 ++++++--------- src/sp_repo_review/checks/github.py | 38 +++++++++++++++++++ ...ter.__type!='compiled' %}cd.yml{% endif %} | 4 +- ...ter.__type=='compiled' %}cd.yml{% endif %} | 17 ++++----- 7 files changed, 70 insertions(+), 40 deletions(-) diff --git a/README.md b/README.md index cb901948..2a670486 100644 --- a/README.md +++ b/README.md @@ -345,6 +345,7 @@ for family, grp in itertools.groupby(collected.checks.items(), key=lambda x: x[1 - [`GH101`](https://learn.scientific-python.org/development/guides/gha-basic#GH101): Has nice names - [`GH102`](https://learn.scientific-python.org/development/guides/gha-basic#GH102): Auto-cancel on repeated PRs - [`GH103`](https://learn.scientific-python.org/development/guides/gha-basic#GH103): At least one workflow with manual dispatch trigger +- [`GH104`](https://learn.scientific-python.org/development/guides/gha-wheel#GH104): Use unique names for upload-artifact - [`GH200`](https://learn.scientific-python.org/development/guides/gha-basic#GH200): Maintained by Dependabot - [`GH210`](https://learn.scientific-python.org/development/guides/gha-basic#GH210): Maintains the GitHub action versions with Dependabot - [`GH211`](https://learn.scientific-python.org/development/guides/gha-basic#GH211): Do not pin core actions as major versions diff --git a/docs/pages/guides/gha_basic.md b/docs/pages/guides/gha_basic.md index 20f54382..70603e09 100644 --- a/docs/pages/guides/gha_basic.md +++ b/docs/pages/guides/gha_basic.md @@ -660,7 +660,7 @@ this action later; specifically, may want to use ```yaml - name: Upload artifact - uses: actions/upload-pages-artifact@v2 + uses: actions/upload-pages-artifact@v3 ``` This actions defaults to uploading `_site`, but you can give any `with: path:` @@ -682,7 +682,7 @@ deploy: steps: - name: Deploy to GitHub Pages id: deployment - uses: actions/deploy-pages@v3 + uses: actions/deploy-pages@v4 ``` {% endraw %} diff --git a/docs/pages/guides/gha_pure.md b/docs/pages/guides/gha_pure.md index 27ec454d..aea102fc 100644 --- a/docs/pages/guides/gha_pure.md +++ b/docs/pages/guides/gha_pure.md @@ -77,7 +77,7 @@ dist: - name: Build SDist and wheel run: pipx run build - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: Packages path: dist/* @@ -125,7 +125,7 @@ later in the upload action for the release job, as well). > ```yaml > steps: > - uses: actions/checkout@v4 -> - uses: hynek/build-and-inspect-python-package@v1 +> - uses: hynek/build-and-inspect-python-package@v2 > ``` > > The artifact it produces is named `Packages`, so that's what you need to use @@ -146,7 +146,7 @@ publish: runs-on: ubuntu-latest if: github.event_name == 'release' && github.event.action == 'published' steps: - - uses: actions/download-artifact@v3 + - uses: actions/download-artifact@v4 with: name: Packages path: dist @@ -172,7 +172,7 @@ publish: runs-on: ubuntu-latest if: github.event_name == 'release' && github.event.action == 'published' steps: - - uses: actions/download-artifact@v3 + - uses: actions/download-artifact@v4 with: name: Packages path: dist @@ -223,7 +223,7 @@ jobs: with: fetch-depth: 0 - - uses: hynek/build-and-inspect-python-package@v1 + - uses: hynek/build-and-inspect-python-package@v2 publish: needs: [dist] @@ -234,7 +234,7 @@ jobs: if: github.event_name == 'release' && github.event.action == 'published' steps: - - uses: actions/download-artifact@v3 + - uses: actions/download-artifact@v4 with: name: Packages path: dist @@ -269,7 +269,7 @@ jobs: with: fetch-depth: 0 - - uses: hynek/build-and-inspect-python-package@v1 + - uses: hynek/build-and-inspect-python-package@v2 publish: needs: [dist] @@ -277,7 +277,7 @@ jobs: if: github.event_name == 'release' && github.event.action == 'published' steps: - - uses: actions/download-artifact@v3 + - uses: actions/download-artifact@v4 with: name: Packages path: dist diff --git a/docs/pages/guides/gha_wheels.md b/docs/pages/guides/gha_wheels.md index 21add009..30d00422 100644 --- a/docs/pages/guides/gha_wheels.md +++ b/docs/pages/guides/gha_wheels.md @@ -92,9 +92,9 @@ make_sdist: - name: Build SDist run: pipx run build --sdist - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: - name: SDist + name: cibw-sdist path: dist/*.tar.gz ``` @@ -125,9 +125,9 @@ build_wheels: - uses: pypa/cibuildwheel@v2.16 - name: Upload wheels - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: - name: Wheels-${{ matrix.os }} + name: cibw-wheels-${{ matrix.os }} path: wheelhouse/*.whl ``` @@ -177,14 +177,11 @@ upload_all: runs-on: ubuntu-latest if: github.event_name == 'release' && github.event.action == 'published' steps: - - uses: actions/download-artifact@v3 + - uses: actions/download-artifact@v4 with: - path: all - - - name: Merge files - run: | - mkdir dist - mv all/*/* dist + pattern: cibw-* + path: dist + merge-multiple: true - uses: pypa/gh-action-pypi-publish@release/v1 ``` @@ -207,14 +204,11 @@ upload_all: runs-on: ubuntu-latest if: github.event_name == 'release' && github.event.action == 'published' steps: - - uses: actions/download-artifact@v3 + - uses: actions/download-artifact@v4 with: - path: all - - - name: Merge files - run: | - mkdir dist - mv all/*/* dist + pattern: cibw-* + path: dist + merge-multiple: true - uses: pypa/gh-action-pypi-publish@release/v1 with: diff --git a/src/sp_repo_review/checks/github.py b/src/sp_repo_review/checks/github.py index c3d22c65..8043d315 100644 --- a/src/sp_repo_review/checks/github.py +++ b/src/sp_repo_review/checks/github.py @@ -107,6 +107,44 @@ def check(workflows: dict[str, Any]) -> bool: return any("workflow_dispatch" in w.get(True, {}) for w in workflows.values()) +class GH104(GitHub): + "Use unique names for upload-artifact" + + requires = {"GH100"} + url = mk_url("gha-wheel") + + @staticmethod + def check(workflows: dict[str, Any]) -> bool: + """ + Multiple upload-artifact usages _must_ have unique names to be + compatible with `v4` (which no longer merge artifacts, but instead + errors out). The most general solution is: + + ```yaml + - uses: actions/upload-artifact@v4 + with: + name: prefix-${{ github.job }}-${{ strategy.job-index }} + + - uses: actions/download-artifact@v4 + with: + pattern: prefix-* + merge-multiple: true + ``` + """ + + for workflow in workflows.values(): + names = [ + step.get("with", {}).get("name", "") + for job in workflow.get("jobs", {}).values() + for step in job.get("steps", []) + if step.get("uses", "").startswith("actions/upload-artifact") + ] + names = [n for n in names if "${{" not in n] + if len(names) != len(set(names)): + return False + return True + + class GH200(GitHub): "Maintained by Dependabot" diff --git a/{{cookiecutter.project_name}}/.github/workflows/{% if cookiecutter.__type!='compiled' %}cd.yml{% endif %} b/{{cookiecutter.project_name}}/.github/workflows/{% if cookiecutter.__type!='compiled' %}cd.yml{% endif %} index 9cdc3f98..98d8d8b2 100644 --- a/{{cookiecutter.project_name}}/.github/workflows/{% if cookiecutter.__type!='compiled' %}cd.yml{% endif %} +++ b/{{cookiecutter.project_name}}/.github/workflows/{% if cookiecutter.__type!='compiled' %}cd.yml{% endif %} @@ -27,7 +27,7 @@ jobs: with: fetch-depth: 0 - - uses: hynek/build-and-inspect-python-package@v1 + - uses: hynek/build-and-inspect-python-package@v2 publish: needs: [dist] @@ -39,7 +39,7 @@ jobs: if: github.event_name == 'release' && github.event.action == 'published' steps: - - uses: actions/download-artifact@v3 + - uses: actions/download-artifact@v4 with: name: Packages path: dist diff --git a/{{cookiecutter.project_name}}/.github/workflows/{% if cookiecutter.__type=='compiled' %}cd.yml{% endif %} b/{{cookiecutter.project_name}}/.github/workflows/{% if cookiecutter.__type=='compiled' %}cd.yml{% endif %} index 7e7aabc8..5124675e 100644 --- a/{{cookiecutter.project_name}}/.github/workflows/{% if cookiecutter.__type=='compiled' %}cd.yml{% endif %} +++ b/{{cookiecutter.project_name}}/.github/workflows/{% if cookiecutter.__type=='compiled' %}cd.yml{% endif %} @@ -25,9 +25,9 @@ jobs: - name: Build SDist run: pipx run build --sdist - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: - name: SDist + name: cibw-sdist path: dist/*.tar.gz build_wheels: @@ -46,9 +46,9 @@ jobs: - uses: pypa/cibuildwheel@v2.16 - name: Upload wheels - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: - name: Wheel-{% raw %}${{ matrix.os }}{% endraw %} + name: cibw-wheels-{% raw %}${{ matrix.os }}-${{ strategy.job-index }}{% endraw %} path: wheelhouse/*.whl upload_all: @@ -60,14 +60,11 @@ jobs: if: github.event_name == 'release' && github.event.action == 'published' steps: - - uses: actions/download-artifact@v3 + - uses: actions/download-artifact@v4 with: + pattern: cibw-* path: dist - - - name: Merge files - run: | - mkdir dist - mv all/*/* dist + merge-multiple: true - uses: pypa/gh-action-pypi-publish@release/v1 with: From af9935e16f619f95dc2e20c3413fac6f5bf55400 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 20 Dec 2023 18:15:18 -0500 Subject: [PATCH 21/36] chore(deps): bump the actions group with 3 updates (#349) Bumps the actions group with 3 updates: [hynek/build-and-inspect-python-package](https://github.com/hynek/build-and-inspect-python-package), [actions/download-artifact](https://github.com/actions/download-artifact) and [actions/upload-artifact](https://github.com/actions/upload-artifact). Updates `hynek/build-and-inspect-python-package` from 1 to 2 - [Release notes](https://github.com/hynek/build-and-inspect-python-package/releases) - [Changelog](https://github.com/hynek/build-and-inspect-python-package/blob/main/CHANGELOG.md) - [Commits](https://github.com/hynek/build-and-inspect-python-package/compare/v1...v2) Updates `actions/download-artifact` from 3 to 4 - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](https://github.com/actions/download-artifact/compare/v3...v4) Updates `actions/upload-artifact` from 3 to 4 - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/v3...v4) --- updated-dependencies: - dependency-name: hynek/build-and-inspect-python-package dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions - dependency-name: actions/download-artifact dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions - dependency-name: actions/upload-artifact dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/cd.yml | 4 ++-- .github/workflows/reusable-cookie.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index 1a68f1bc..bb08c26a 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -16,7 +16,7 @@ jobs: with: fetch-depth: 0 - - uses: hynek/build-and-inspect-python-package@v1 + - uses: hynek/build-and-inspect-python-package@v2 publish: name: Publish @@ -29,7 +29,7 @@ jobs: runs-on: ubuntu-latest if: github.event_name == 'release' && github.event.action == 'published' steps: - - uses: actions/download-artifact@v3 + - uses: actions/download-artifact@v4 with: name: Packages path: dist diff --git a/.github/workflows/reusable-cookie.yml b/.github/workflows/reusable-cookie.yml index 9ff3dfd3..d6c7a118 100644 --- a/.github/workflows/reusable-cookie.yml +++ b/.github/workflows/reusable-cookie.yml @@ -169,7 +169,7 @@ jobs: - name: Show results run: ls -l dist - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: Packages path: dist From 275c43dcbf38e00c2f2239b8d90af1f627f9c3d4 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Thu, 21 Dec 2023 16:51:01 -0500 Subject: [PATCH 22/36] docs: fix link to homepage (#351) I think this was a replacement mistake when moving over. This the the homepage for sp-repo-review, so linking to the GitHub page seems to make sense. --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index ad9e1fd6..149103f2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -47,7 +47,7 @@ dev = [ [project.urls] Guide = "https://learn.scientific-python.org/development" -Homepage = "https://scientific-python.github.io/cookie" +Homepage = "https://github.com/scientific-python/cookie" Preview = "https://scientific-python-cookie.readthedocs.io" Source = "https://github.com/scientific-python/cookie" From 65fcacc25e6216dbe165e907dd4fdfdc9b053074 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 21 Dec 2023 18:30:36 -0500 Subject: [PATCH 23/36] chore(deps): bump versions (#352) --- .pre-commit-config.yaml | 2 +- docs/pages/guides/style.md | 4 ++-- {{cookiecutter.project_name}}/.pre-commit-config.yaml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3f4dfc8d..00022fd1 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -29,7 +29,7 @@ repos: additional_dependencies: [black==23.*] - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.1.8" + rev: "v0.1.9" hooks: - id: ruff args: ["--fix", "--show-fixes"] diff --git a/docs/pages/guides/style.md b/docs/pages/guides/style.md index e2137719..c0e692e8 100644 --- a/docs/pages/guides/style.md +++ b/docs/pages/guides/style.md @@ -111,7 +111,7 @@ Here is the snippet to add the formatter to your `.pre-commit-config.yml` ```yaml - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.1.8" + rev: "v0.1.9" hooks: # id: ruff would go here if using both - id: ruff-format @@ -201,7 +201,7 @@ pre-commit hook. ```yaml - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.1.8" + rev: "v0.1.9" hooks: - id: ruff args: ["--fix", "--show-fixes"] diff --git a/{{cookiecutter.project_name}}/.pre-commit-config.yaml b/{{cookiecutter.project_name}}/.pre-commit-config.yaml index 725bda8b..74c8987d 100644 --- a/{{cookiecutter.project_name}}/.pre-commit-config.yaml +++ b/{{cookiecutter.project_name}}/.pre-commit-config.yaml @@ -40,7 +40,7 @@ repos: args: [--prose-wrap=always] - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.1.8" + rev: "v0.1.9" hooks: - id: ruff args: ["--fix", "--show-fixes"] From c07eb4b42e9f645e77e5d7a818064382dbc2dda9 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Thu, 21 Dec 2023 22:42:20 -0500 Subject: [PATCH 24/36] chore: bump webapp Signed-off-by: Henry Schreiner --- docs/_includes/interactive_repo_review.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/_includes/interactive_repo_review.html b/docs/_includes/interactive_repo_review.html index f7a91365..f6c98177 100644 --- a/docs/_includes/interactive_repo_review.html +++ b/docs/_includes/interactive_repo_review.html @@ -20,10 +20,10 @@ , From 8dbc2a6d66f236c9ae948bea1b918ebb0caa1357 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Fri, 22 Dec 2023 16:20:03 -0500 Subject: [PATCH 25/36] fix: allow warn_unreachable to be set to False explicitly (#353) --- src/sp_repo_review/checks/mypy.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sp_repo_review/checks/mypy.py b/src/sp_repo_review/checks/mypy.py index 92683034..1ee5e025 100644 --- a/src/sp_repo_review/checks/mypy.py +++ b/src/sp_repo_review/checks/mypy.py @@ -68,7 +68,7 @@ def check(pyproject: dict[str, Any]) -> bool: """ match pyproject: - case {"tool": {"mypy": {"show_error_codes": object()}}}: + case {"tool": {"mypy": {"show_error_codes": bool()}}}: return False case _: return True @@ -83,10 +83,10 @@ class MY103(MyPy): @staticmethod def check(pyproject: dict[str, Any]) -> bool: """ - Must have `warn_unreachable = true` to pass this check. There are + Must have `warn_unreachable` (true/false) to pass this check. There are occasionally false positives (often due to platform or Python version - static checks), so it's okay to ignore this check. But try it first - it - can catch real bugs too. + static checks), so it's okay to set it to false if you need to. But try + it first - it can catch real bugs too. ```toml [tool.mypy] @@ -95,7 +95,7 @@ def check(pyproject: dict[str, Any]) -> bool: """ match pyproject: - case {"tool": {"mypy": {"warn_unreachable": True}}}: + case {"tool": {"mypy": {"warn_unreachable": bool()}}}: return True case _: return False From 38fb67ac35c74fd41d3e587aeaa034530a0692e1 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 4 Jan 2024 18:32:41 -0500 Subject: [PATCH 26/36] chore: update pre-commit hooks (#355) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore: update pre-commit hooks updates: - [github.com/pre-commit/mirrors-mypy: v1.7.1 → v1.8.0](https://github.com/pre-commit/mirrors-mypy/compare/v1.7.1...v1.8.0) - [github.com/pre-commit/mirrors-prettier: v3.1.0 → v4.0.0-alpha.8](https://github.com/pre-commit/mirrors-prettier/compare/v3.1.0...v4.0.0-alpha.8) * style: pre-commit fixes * chore: fix mypy type for tomli Signed-off-by: Henry Schreiner * Apply suggestions from code review --------- Signed-off-by: Henry Schreiner Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Henry Schreiner Co-authored-by: Henry Schreiner --- .pre-commit-config.yaml | 2 +- docs/pages/guides/docs.md | 2 +- src/sp_repo_review/checks/ruff.py | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 00022fd1..c8d046bf 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -43,7 +43,7 @@ repos: - id: rst-inline-touching-normal - repo: https://github.com/pre-commit/mirrors-mypy - rev: "v1.7.1" + rev: "v1.8.0" hooks: - id: mypy files: "(src|tests)" diff --git a/docs/pages/guides/docs.md b/docs/pages/guides/docs.md index ecf364f3..6e0a8405 100644 --- a/docs/pages/guides/docs.md +++ b/docs/pages/guides/docs.md @@ -84,7 +84,7 @@ from __future__ import annotations import importlib.metadata project = "package" -copyright = "2023, My Name" +copyright = "2024, My Name" author = "My Name" version = release = importlib.metadata.version("package") diff --git a/src/sp_repo_review/checks/ruff.py b/src/sp_repo_review/checks/ruff.py index 640ff5d6..9c60192c 100644 --- a/src/sp_repo_review/checks/ruff.py +++ b/src/sp_repo_review/checks/ruff.py @@ -31,7 +31,8 @@ def ruff(pyproject: dict[str, Any], root: Traversable) -> dict[str, Any] | None: for path in paths: if path.is_file(): with path.open("rb") as f: - contents = tomllib.load(f) + # Type ignore fixed in https://github.com/hukkin/tomli/pull/215 + contents = tomllib.load(f) # type: ignore[arg-type] if contents.get("extend", "") == "pyproject.toml": extend = pyproject.get("tool", {}).get("ruff", {}) return merge(extend, contents) From ac8cff3187afaa5ff3f7d7062cc1b852232a7959 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 4 Jan 2024 18:47:59 -0500 Subject: [PATCH 27/36] chore(deps): bump versions (#354) [create-pull-request] automated change Co-authored-by: henryiii --- .pre-commit-config.yaml | 2 +- docs/pages/guides/style.md | 8 ++++---- {{cookiecutter.project_name}}/.pre-commit-config.yaml | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c8d046bf..20be1c47 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -29,7 +29,7 @@ repos: additional_dependencies: [black==23.*] - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.1.9" + rev: "v0.1.11" hooks: - id: ruff args: ["--fix", "--show-fixes"] diff --git a/docs/pages/guides/style.md b/docs/pages/guides/style.md index c0e692e8..8d3f815f 100644 --- a/docs/pages/guides/style.md +++ b/docs/pages/guides/style.md @@ -111,7 +111,7 @@ Here is the snippet to add the formatter to your `.pre-commit-config.yml` ```yaml - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.1.9" + rev: "v0.1.11" hooks: # id: ruff would go here if using both - id: ruff-format @@ -141,7 +141,7 @@ Here is the snippet to add Black to your `.pre-commit-config.yml`: ```yaml - repo: https://github.com/psf/black-pre-commit-mirror - rev: "23.12.0" + rev: "23.12.1" hooks: - id: black ``` @@ -201,7 +201,7 @@ pre-commit hook. ```yaml - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.1.9" + rev: "v0.1.11" hooks: - id: ruff args: ["--fix", "--show-fixes"] @@ -535,7 +535,7 @@ The MyPy addition for pre-commit: ```yaml - repo: https://github.com/pre-commit/mirrors-mypy - rev: "v1.7.1" + rev: "v1.8.0" hooks: - id: mypy files: src diff --git a/{{cookiecutter.project_name}}/.pre-commit-config.yaml b/{{cookiecutter.project_name}}/.pre-commit-config.yaml index 74c8987d..999b6972 100644 --- a/{{cookiecutter.project_name}}/.pre-commit-config.yaml +++ b/{{cookiecutter.project_name}}/.pre-commit-config.yaml @@ -40,7 +40,7 @@ repos: args: [--prose-wrap=always] - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.1.9" + rev: "v0.1.11" hooks: - id: ruff args: ["--fix", "--show-fixes"] @@ -67,7 +67,7 @@ repos: {%- endif %} - repo: https://github.com/pre-commit/mirrors-mypy - rev: "v1.7.1" + rev: "v1.8.0" hooks: - id: mypy files: src|tests From 73768ec1be24987aa57b9082ace80cb079d2f976 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Fri, 5 Jan 2024 15:48:56 -0500 Subject: [PATCH 28/36] fix: include matrix logic & location of errors in GH104 (#356) Signed-off-by: Henry Schreiner --- src/sp_repo_review/checks/github.py | 71 +++++++++++++++++------------ 1 file changed, 42 insertions(+), 29 deletions(-) diff --git a/src/sp_repo_review/checks/github.py b/src/sp_repo_review/checks/github.py index 8043d315..708b9ba2 100644 --- a/src/sp_repo_review/checks/github.py +++ b/src/sp_repo_review/checks/github.py @@ -107,6 +107,25 @@ def check(workflows: dict[str, Any]) -> bool: return any("workflow_dispatch" in w.get(True, {}) for w in workflows.values()) +GH104_ERROR_MSG = """ +Multiple upload-artifact usages _must_ have unique names to be +compatible with `v4` (which no longer merge artifacts, but instead +errors out). The most general solution is: + +```yaml +- uses: actions/upload-artifact@v4 + with: + name: prefix-${{ github.job }}-${{ strategy.job-index }} + +- uses: actions/download-artifact@v4 + with: + pattern: prefix-* + merge-multiple: true +``` + +""" + + class GH104(GitHub): "Use unique names for upload-artifact" @@ -114,35 +133,29 @@ class GH104(GitHub): url = mk_url("gha-wheel") @staticmethod - def check(workflows: dict[str, Any]) -> bool: - """ - Multiple upload-artifact usages _must_ have unique names to be - compatible with `v4` (which no longer merge artifacts, but instead - errors out). The most general solution is: - - ```yaml - - uses: actions/upload-artifact@v4 - with: - name: prefix-${{ github.job }}-${{ strategy.job-index }} - - - uses: actions/download-artifact@v4 - with: - pattern: prefix-* - merge-multiple: true - ``` - """ - - for workflow in workflows.values(): - names = [ - step.get("with", {}).get("name", "") - for job in workflow.get("jobs", {}).values() - for step in job.get("steps", []) - if step.get("uses", "").startswith("actions/upload-artifact") - ] - names = [n for n in names if "${{" not in n] - if len(names) != len(set(names)): - return False - return True + def check(workflows: dict[str, Any]) -> str: + errors = [] + for wname, workflow in workflows.items(): + for jname, job in workflow.get("jobs", {}).items(): + names = [ + step.get("with", {}).get("name", "") + for step in job.get("steps", []) + if step.get("uses", "").startswith("actions/upload-artifact") + ] + if "matrix" in job.get("strategy", {}) and not all( + "${{" in n for n in names + ): + errors.append( + f"* No variable substitutions were detected in `{wname}.yml:{jname}`." + ) + names = [n for n in names if "${{" not in n] + if len(names) != len(set(names)): + errors.append( + f"* Multiple matching upload artifact names detected in `{wname}.yml:{jname}`." + ) + if errors: + return GH104_ERROR_MSG + "\n\n".join(errors) + return "" class GH200(GitHub): From 57fc35295e5cfc79b9152a82d183cb8c73c6865b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 10 Jan 2024 15:37:19 -0500 Subject: [PATCH 29/36] chore(deps): bump versions (#357) [create-pull-request] automated change Co-authored-by: henryiii --- docs/pages/guides/style.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/pages/guides/style.md b/docs/pages/guides/style.md index 8d3f815f..b5f5f064 100644 --- a/docs/pages/guides/style.md +++ b/docs/pages/guides/style.md @@ -392,7 +392,7 @@ the flake8 addition for pre-commit, with the `bugbear` plugin: ```yaml - repo: https://github.com/pycqa/flake8 - rev: "6.1.0" + rev: "7.0.0" hooks: - id: flake8 additional_dependencies: [flake8-bugbear] From 8f360797391ec23ec00e1219e4727680157d2870 Mon Sep 17 00:00:00 2001 From: Agriya Khetarpal <74401230+agriyakhetarpal@users.noreply.github.com> Date: Sat, 13 Jan 2024 02:57:44 +0530 Subject: [PATCH 30/36] docs: assert correct file extension reference for wheels & sdists (#358) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update file extensions for SDists and wheels A minor documentation fix, this section referred to the wheel as a `.tar.gz` file while it isn't – it is fairly known that it is a `.zip` file. I added the correct file extension for the SDist in the point above it, just for the sake of clarity. --- docs/pages/guides/packaging_classic.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/pages/guides/packaging_classic.md b/docs/pages/guides/packaging_classic.md index f59a0132..165952cd 100644 --- a/docs/pages/guides/packaging_classic.md +++ b/docs/pages/guides/packaging_classic.md @@ -403,15 +403,15 @@ Python packaging goes through a 3-stage procedure if you have the above recommended `pyproject.toml` file. If you type `pip install .`, then 1. Source is processed to make an SDist (in a virtual environment mandated by - pyproject.toml). + pyproject.toml). This SDist bears a `.tar.gz` file format. 2. SDist is processed to make a wheel (same virtual environment). 3. The wheel is installed. The wheel does _not_ contain `setup.*`, `pyproject.toml`, or other build code. -It simply is a `.tar.gz` file that is named `.whl` and has a simple mapping of -directories to installation paths and a generic metadata format. "Installing" -really is just copying files around, and pip also pre-compiles some bytecode for -you while doing so. +It simply is a `.zip` format archive with the `.whl` suffix and has a simple +mapping of directories to installation paths and a generic metadata format. +"Installing" really is just copying files around, and pip also pre-compiles some +bytecode for you while doing so. If you don't have a `MANIFEST.in`, the "legacy" build procedure will skip the SDist step, making it possible for a development build to work while a published From b7bdbe37af054a0f9022f9bf5767764f67e2e205 Mon Sep 17 00:00:00 2001 From: "David V. Lu!!" Date: Mon, 15 Jan 2024 10:38:58 -0500 Subject: [PATCH 31/36] docs: add missing words (#360) * Add missing words? * style: pre-commit fixes --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- docs/pages/guides/docs.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/pages/guides/docs.md b/docs/pages/guides/docs.md index 6e0a8405..35642e5d 100644 --- a/docs/pages/guides/docs.md +++ b/docs/pages/guides/docs.md @@ -67,9 +67,9 @@ with render_cookie() as package: ## Hand-written docs Create `docs/` directory within your project (i.e. next to `src/`). There is a -sphinx-quickstart tool, but unnecessary files (make/bat, we recommend a -cross-platform noxfile instead), and uses RST instead of Markdown. Instead, this -is our recommended starting point for `conf.py`: +sphinx-quickstart tool, but it creates unnecessary files (make/bat, we recommend +a cross-platform noxfile instead), and uses RST instead of Markdown. Instead, +this is our recommended starting point for `conf.py`: ### conf.py From 176292f3c65addc4aa6015ce028a3dc21a378ba3 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 15 Jan 2024 10:51:31 -0500 Subject: [PATCH 32/36] chore(deps): bump versions (#359) [create-pull-request] automated change Co-authored-by: henryiii --- .pre-commit-config.yaml | 2 +- docs/pages/guides/style.md | 4 ++-- {{cookiecutter.project_name}}/.pre-commit-config.yaml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 20be1c47..66414a51 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -29,7 +29,7 @@ repos: additional_dependencies: [black==23.*] - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.1.11" + rev: "v0.1.13" hooks: - id: ruff args: ["--fix", "--show-fixes"] diff --git a/docs/pages/guides/style.md b/docs/pages/guides/style.md index b5f5f064..ba290edb 100644 --- a/docs/pages/guides/style.md +++ b/docs/pages/guides/style.md @@ -111,7 +111,7 @@ Here is the snippet to add the formatter to your `.pre-commit-config.yml` ```yaml - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.1.11" + rev: "v0.1.13" hooks: # id: ruff would go here if using both - id: ruff-format @@ -201,7 +201,7 @@ pre-commit hook. ```yaml - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.1.11" + rev: "v0.1.13" hooks: - id: ruff args: ["--fix", "--show-fixes"] diff --git a/{{cookiecutter.project_name}}/.pre-commit-config.yaml b/{{cookiecutter.project_name}}/.pre-commit-config.yaml index 999b6972..af3b6f76 100644 --- a/{{cookiecutter.project_name}}/.pre-commit-config.yaml +++ b/{{cookiecutter.project_name}}/.pre-commit-config.yaml @@ -40,7 +40,7 @@ repos: args: [--prose-wrap=always] - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.1.11" + rev: "v0.1.13" hooks: - id: ruff args: ["--fix", "--show-fixes"] From 84859da28d50c734c8bd6b21913f371bf672a025 Mon Sep 17 00:00:00 2001 From: Tetsuo Koyama Date: Sat, 20 Jan 2024 11:58:40 +0900 Subject: [PATCH 33/36] docs: fix links of PY rules in packaging_simple.md (#362) * docs: fix links of PY rules in packaging_simple.md * style: pre-commit fixes --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- docs/pages/guides/packaging_simple.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/pages/guides/packaging_simple.md b/docs/pages/guides/packaging_simple.md index aef9133e..6febc6f0 100644 --- a/docs/pages/guides/packaging_simple.md +++ b/docs/pages/guides/packaging_simple.md @@ -98,8 +98,8 @@ for very special cases), you will likely need extra configuration here. You should have a `README` {% rr PY002 %} and a `LICENSE` {% rr PY003 %} file. You should have a `docs/` folder {% -rr PY003 %}. You should have a `/tests` folder (recommended) and/or a `src//tests` -folder. +rr PY004 %}. You should have a `/tests` folder {% +rr PY005 %} (recommended) and/or a `src//tests` folder. ## Versioning From 0f33f77051e9deaf00f23a9fb7bc913ec1d20ac2 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 23 Jan 2024 08:17:43 -0500 Subject: [PATCH 34/36] chore(deps): bump versions (#363) [create-pull-request] automated change Co-authored-by: henryiii --- .pre-commit-config.yaml | 2 +- docs/pages/guides/style.md | 4 ++-- {{cookiecutter.project_name}}/.pre-commit-config.yaml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 66414a51..c31b7de1 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -29,7 +29,7 @@ repos: additional_dependencies: [black==23.*] - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.1.13" + rev: "v0.1.14" hooks: - id: ruff args: ["--fix", "--show-fixes"] diff --git a/docs/pages/guides/style.md b/docs/pages/guides/style.md index ba290edb..94588945 100644 --- a/docs/pages/guides/style.md +++ b/docs/pages/guides/style.md @@ -111,7 +111,7 @@ Here is the snippet to add the formatter to your `.pre-commit-config.yml` ```yaml - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.1.13" + rev: "v0.1.14" hooks: # id: ruff would go here if using both - id: ruff-format @@ -201,7 +201,7 @@ pre-commit hook. ```yaml - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.1.13" + rev: "v0.1.14" hooks: - id: ruff args: ["--fix", "--show-fixes"] diff --git a/{{cookiecutter.project_name}}/.pre-commit-config.yaml b/{{cookiecutter.project_name}}/.pre-commit-config.yaml index af3b6f76..55eb6591 100644 --- a/{{cookiecutter.project_name}}/.pre-commit-config.yaml +++ b/{{cookiecutter.project_name}}/.pre-commit-config.yaml @@ -40,7 +40,7 @@ repos: args: [--prose-wrap=always] - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.1.13" + rev: "v0.1.14" hooks: - id: ruff args: ["--fix", "--show-fixes"] From 4aaa0c42fec7d7e50403704a96c80b0267a7ea79 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Wed, 24 Jan 2024 12:30:57 -0500 Subject: [PATCH 35/36] chore: add validate-pyproject-schema-store (#364) * chore: add validate-pyproject-schema-store Signed-off-by: Henry Schreiner * fix: use quotes Signed-off-by: Henry Schreiner * fix: fix hatch def error from validate-pyproject-schema-store Signed-off-by: Henry Schreiner --------- Signed-off-by: Henry Schreiner --- docs/_includes/interactive_repo_review.html | 7 +++---- docs/pages/guides/style.md | 12 +++++++----- noxfile.py | 14 +++++++------- .../.pre-commit-config.yaml | 12 +++--------- {{cookiecutter.project_name}}/pyproject.toml | 2 +- 5 files changed, 21 insertions(+), 26 deletions(-) diff --git a/docs/_includes/interactive_repo_review.html b/docs/_includes/interactive_repo_review.html index f6c98177..baa27ace 100644 --- a/docs/_includes/interactive_repo_review.html +++ b/docs/_includes/interactive_repo_review.html @@ -20,11 +20,10 @@ , ); diff --git a/docs/pages/guides/style.md b/docs/pages/guides/style.md index 94588945..c4521fec 100644 --- a/docs/pages/guides/style.md +++ b/docs/pages/guides/style.md @@ -804,17 +804,19 @@ There are two tools, both based on JSON Schema, that you can use to validate various configuration files. The first, [validate-pyproject][], validates your `pyproject.toml` file. By default, it checks the standards-defined sections (`build-system` and `project`), along with `tool.setuptools`. There are also -plugins for some other tools, like `scikit-build-core` and `cibuildwheel`. Using -it looks like this: +plugins for some other tools, like `scikit-build-core` and `cibuildwheel`. You +can even get all [SchemaStore][]'s plugins with the +[validate-pyproject-schema-store][] plugin. Using it looks like this: ```yaml - repo: https://github.com/abravalheri/validate-pyproject - rev: v0.15 + rev: "v0.16" hooks: - id: validate-pyproject + additional_dependencies: ["validate-pyproject-schema-store[all]"] ``` -You can also validate various other types of files with [check-jsonschema]. It +You can also validate various other types of files with [check-jsonschema][]. It supports a variety of common files built-in ([see the docs][cjs-common]) like various CI configuration files. You can also write/provide your own schemas and validate using those - [SchemaStore][] provides a few hundred different common @@ -822,7 +824,7 @@ schemas, and you can load them via URL. It work on JSON, YAML, and TOML. ```yaml - repo: https://github.com/python-jsonschema/check-jsonschema - rev: 0.27.0 + rev: "0.27.3" hooks: - id: check-dependabot - id: check-github-workflows diff --git a/noxfile.py b/noxfile.py index 18ae97fe..7d019c64 100644 --- a/noxfile.py +++ b/noxfile.py @@ -362,9 +362,9 @@ def compare_cruft(session): re.MULTILINE, ) -PC_REPL_LINE = '''\ +PC_REPL_LINE = """\ {2}- repo: {0} -{2} rev: "{1}"''' +{2} rev: {3}{1}{3}""" GHA_VERS = re.compile(r"[\s\-]+uses: (.*?)@([^\s]+)") @@ -375,7 +375,7 @@ def pc_bump(session: nox.Session) -> None: """ Bump the pre-commit versions. """ - session.install("lastversion") + session.install("lastversion>=3.4") versions = {} pages = [ Path("docs/pages/guides/style.md"), @@ -399,11 +399,11 @@ def pc_bump(session: nox.Session) -> None: ).strip() new_version = versions[proj] - before = PC_REPL_LINE.format(proj, old_version, space) - after = PC_REPL_LINE.format(proj, new_version, space) + after = PC_REPL_LINE.format(proj, new_version, space, '"') - session.log(f"Bump: {old_version} -> {new_version} ({page})") - txt = txt.replace(before, after) + session.log(f"Bump {proj}: {old_version} -> {new_version} ({page})") + txt = txt.replace(PC_REPL_LINE.format(proj, old_version, space, '"'), after) + txt = txt.replace(PC_REPL_LINE.format(proj, old_version, space, ""), after) page.write_text(txt) diff --git a/{{cookiecutter.project_name}}/.pre-commit-config.yaml b/{{cookiecutter.project_name}}/.pre-commit-config.yaml index 55eb6591..5e3172b6 100644 --- a/{{cookiecutter.project_name}}/.pre-commit-config.yaml +++ b/{{cookiecutter.project_name}}/.pre-commit-config.yaml @@ -112,19 +112,13 @@ repos: {%- endif %} - repo: https://github.com/abravalheri/validate-pyproject - rev: v0.15 + rev: "v0.16" hooks: - id: validate-pyproject -{%- if cookiecutter.backend == "skbuild" %} - additional_dependencies: - [scikit-build-core, cibuildwheel, tomli, packaging, trove-classifiers] -{%- elif cookiecutter.__type == "compiled" %} - additional_dependencies: - [cibuildwheel, tomli, packaging, trove-classifiers] -{%- endif %} + additional_dependencies: ["validate-pyproject-schema-store[all]"] - repo: https://github.com/python-jsonschema/check-jsonschema - rev: 0.27.0 + rev: "0.27.3" hooks: {%- if cookiecutter.__ci == "github" %} - id: check-dependabot diff --git a/{{cookiecutter.project_name}}/pyproject.toml b/{{cookiecutter.project_name}}/pyproject.toml index ff17bc22..83055906 100644 --- a/{{cookiecutter.project_name}}/pyproject.toml +++ b/{{cookiecutter.project_name}}/pyproject.toml @@ -255,7 +255,7 @@ version.source = "vcs" build.hooks.vcs.version-file = "src/{{ cookiecutter.__project_slug }}/_version.py" {%- endif %} -[tool.hatch.env.default] +[tool.hatch.envs.default] features = ["test"] scripts.test = "pytest {args}" From 0bfc28b9eed761077be7188e05b3ee531ad41f60 Mon Sep 17 00:00:00 2001 From: Tetsuo Koyama Date: Thu, 25 Jan 2024 03:59:15 +0900 Subject: [PATCH 36/36] docs: standardize .reathedocs.yml to .readthedocs.yaml (#361) * Typo fix from .reathedocs.yml to .readthedocs.yaml * style: pre-commit fixes * fix: move remaining readthedocs to yaml ext Signed-off-by: Henry Schreiner --------- Signed-off-by: Henry Schreiner Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Henry Schreiner --- docs/pages/guides/docs.md | 5 +++-- .../{.readthedocs.yml => .readthedocs.yaml} | 0 ...end in ['setuptools','pybind11'] %}MANIFEST.in{% endif %} | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) rename {{cookiecutter.project_name}}/{.readthedocs.yml => .readthedocs.yaml} (100%) diff --git a/docs/pages/guides/docs.md b/docs/pages/guides/docs.md index 35642e5d..6e3cddad 100644 --- a/docs/pages/guides/docs.md +++ b/docs/pages/guides/docs.md @@ -59,7 +59,7 @@ from cog_helpers import code_fence, render_cookie, Matcher with render_cookie() as package: docs_conf_py = package.joinpath("docs/conf.py").read_text(encoding="utf-8").strip() docs_index_md = package.joinpath("docs/index.md").read_text(encoding="utf-8").strip() - readthedocs_yaml = package.joinpath(".readthedocs.yml").read_text(encoding="utf-8").strip() + readthedocs_yaml = package.joinpath(".readthedocs.yaml").read_text(encoding="utf-8").strip() noxfile = Matcher.from_file(package / "noxfile.py") ]]] --> @@ -235,7 +235,8 @@ plugins and try to build against an uninstalled version of your project. ### .readthedocs.yaml In order to use to build, host, and preview your -documentation, you must have a `.reathedocs.yml` file {% rr RTD100 %} like this: +documentation, you must have a `.readthedocs.yaml` file {% rr RTD100 %} like +this: