diff --git a/.github/containers/test-installation/Dockerfile b/.github/containers/test-installation/Dockerfile index ac3de243..f053472d 100644 --- a/.github/containers/test-installation/Dockerfile +++ b/.github/containers/test-installation/Dockerfile @@ -4,7 +4,7 @@ # This Dockerfile is used to test the installation of the python package in # multiple platforms in the CI. It is not used to build the package itself. -FROM --platform=${TARGETPLATFORM} python:3.11-slim +FROM python:3.11-slim RUN apt-get update -y && \ apt-get install --no-install-recommends -y \ diff --git a/.github/cookiecutter-migrate.template.py b/.github/cookiecutter-migrate.template.py new file mode 100644 index 00000000..c7311177 --- /dev/null +++ b/.github/cookiecutter-migrate.template.py @@ -0,0 +1,107 @@ +#!/usr/bin/env python3 +# License: MIT +# Copyright © 2024 Frequenz Energy-as-a-Service GmbH + +"""Script to migrate existing projects to new versions of the cookiecutter template. + +This script migrates existing projects to new versions of the cookiecutter +template, removing the need to completely regenerate the project from +scratch. + +To run it, the simplest way is to fetch it from GitHub and run it directly: + + curl -sSL https://raw.githubusercontent.com/frequenz-floss/frequenz-repo-config-python//cookiecutter/migrate.py | python3 + +Make sure to replace the `` to the version you want to migrate to in the URL. + +For jumping multiple versions you should run the script multiple times, once +for each version. + +And remember to follow any manual instructions for each run. +""" # noqa: E501 + +import os +import subprocess +import tempfile +from pathlib import Path +from typing import SupportsIndex + + +def main() -> None: + """Run the migration steps.""" + # Add a separation line like this one after each migration step. + print("=" * 72) + + +def apply_patch(patch_content: str) -> None: + """Apply a patch using the patch utility.""" + subprocess.run(["patch", "-p1"], input=patch_content.encode(), check=True) + + +def replace_file_contents_atomically( # noqa; DOC501 + filepath: str | Path, + old: str, + new: str, + count: SupportsIndex = -1, + *, + content: str | None = None, +) -> None: + """Replace a file atomically with new content. + + Args: + filepath: The path to the file to replace. + old: The string to replace. + new: The string to replace it with. + count: The maximum number of occurrences to replace. If negative, all occurrences are + replaced. + content: The content to replace. If not provided, the file is read from disk. + + The replacement is done atomically by writing to a temporary file and + then moving it to the target location. + """ + if isinstance(filepath, str): + filepath = Path(filepath) + + if content is None: + content = filepath.read_text(encoding="utf-8") + + content = content.replace(old, new, count) + + # Create temporary file in the same directory to ensure atomic move + tmp_dir = filepath.parent + + # pylint: disable-next=consider-using-with + tmp = tempfile.NamedTemporaryFile(mode="w", dir=tmp_dir, delete=False) + + try: + # Copy original file permissions + st = os.stat(filepath) + + # Write the new content + tmp.write(content) + + # Ensure all data is written to disk + tmp.flush() + os.fsync(tmp.fileno()) + tmp.close() + + # Copy original file permissions to the new file + os.chmod(tmp.name, st.st_mode) + + # Perform atomic replace + os.rename(tmp.name, filepath) + + except BaseException: + # Clean up the temporary file in case of errors + tmp.close() + os.unlink(tmp.name) + raise + + +def manual_step(message: str) -> None: + """Print a manual step message in yellow.""" + print(f"\033[0;33m>>> {message}\033[0m") + + +if __name__ == "__main__": + main() diff --git a/.github/cookiecutter-migrate.template.sh b/.github/cookiecutter-migrate.template.sh deleted file mode 100644 index 81f1ed0c..00000000 --- a/.github/cookiecutter-migrate.template.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/sh -# License: MIT -# Copyright © 2024 Frequenz Energy-as-a-Service GmbH -# -# This script migrates existing projects to new versions of the cookiecutter -# template, removing the need to completely regenerate the project from -# scratch. -# -# To run it, the simplest way is to fetch it from GitHub and run it directly: -# -# curl -sSL https://raw.githubusercontent.com/frequenz-floss/frequenz-repo-config-python/v0.10.0/cookiecutter/migrate.sh | sh -# -# Make sure the version you want to migrate to is correct in the URL. -# -# For jumping multiple versions you should run the script multiple times, once -# for each version. -# -# And remember to follow any manual instructions for each run. -set -eu - -manual_step() { - echo "\033[0;33m>>> $@\033[0m" -} - -echo "TODO: Describe your migration step here." -# Add your migration steps here. -manual_step "Add any manual instructions for this step here." - -# Add a separation line like this one after each migration step. -echo "========================================================================" diff --git a/.github/dependabot.yml b/.github/dependabot.yml index d9456c45..53bdd6c3 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -39,3 +39,11 @@ updates: labels: - "part:tooling" - "type:tech-debt" + groups: + compatible: + update-types: + - "minor" + - "patch" + artifacts: + patterns: + - "actions/*-artifact" diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 523f97cf..5a3616cd 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -187,7 +187,7 @@ These are the steps to create a new release: ```sh cp .github/RELEASE_NOTES.template.md RELEASE_NOTES.md - cp .github/cookiecutter-migrate.template.sh cookiecutter/migrate.sh + cp .github/cookiecutter-migrate.template.py cookiecutter/migrate.py ``` Commit the new release notes and migration script, and create a PR (this step diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 87fd8333..d5242cb3 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -2,51 +2,32 @@ ## Summary -This release includes quite a few enhancements and bug fixes for the cookiecutter template, but most importantly a new script for migrating to new templates, generating the templates is no longer needed for upgrading. +This version accumulates a few improvements, and bumps the dependency of setuptools to use v75, which is compatible with PEP625, which is necessary to be able to keep uploading to PyPI, so you should upgrade to this version as soon as possible. -## Upgrading - -### Cookiecutter template - -- A new script for migrating to new templates (instead of regenerating all files) is provided. It can't handle the upgrade 100% automatically, but should make the migration process much easier and less error prone. - - To run it, the simplest way is to fetch it from GitHub and run it directly: - - ```console - curl -sSL https://raw.githubusercontent.com/frequenz-floss/frequenz-repo-config-python/v0.10.0/cookiecutter/migrate.sh | sh - ``` - - Make sure the version you want to migrate to is correct in the URL. +The migration script was also rewritten in Python, so it should be more compatible with different OSes. - For jumping multiple versions you should run the script multiple times, once for each version. +## Upgrading - And remember to follow any manual instructions for each run. +- The `frequenz.repo.config.github.abort()` function now takes most arguments as keyword-only arguments. +- The *Queue PRs for v0.x.x* GitHub ruleset was renamed to *Queue PRs for the default branch* and now targets the default branch. It also only have the merge queue restriction, all other restrictions were removed as they are already present in the *Protect version branches* ruleset. You might want to re-import this ruleset to your repositories. ## New Features -- A new GitHub ruleset is provided to configure the merge queue, so branch protection rules are not needed anymore. - -## Enhancements - -- The generated docs now show the symbol type in the table of contents. +* Added a new GitHub branch ruleset for Rust projects. ### Cookiecutter template -- The `Markdown` dependency was bumped so we don't need to add a `type: ignore` due to incorrect type hints. -- The generated docs now show the symbol type in the table of contents. -- The dependecies were updated to the latest versions. -- Disabled some `pylint` checks that are already checked by other tools. -- The generated documentation now uses symlinks for aliases, which allows deep linking when using aliases too. +* Group GitHub Actions dependabot updates. +* API projects don't include the `google-common-protos` dependency by default. +* API projects updated the `grpcio` dependency to `1.66.1`. +* API projects updated the `frequenz-api-common` dependency to `0.6`. +* Bump most of the dependencies. +* Change `edit_uri` default branch to v0.x.x in mkdocs.yml. +* Added a new default option `asyncio_default_fixture_loop_scope = "function"` for `pytest-asyncio` as not providing a value is deprecated. +* The migration script is now written in Python, so it should be (hopefully) more compatible with different OSes. +* Disable more `pylint` checks that are also checked by `mypy` to avoid false positives. +* Remove the redundant `--platform` from the testing dockerfile. ## Bug Fixes -- The code example extractor relied on a bug in the upstream sybil project that was recently fixed, thus our code also needed to be fixed. - -### Cookiecutter template - -- Fixed a bug where the pip cache post action fails in the CI workflow because of permissions issues. -- Make the `nox-cross-arch-all` job fail if any `nox-cross-arch` matrix job fails. -- Fix credentials not being passed to the `test-installation` job in the CI workflow. -- Make sure credentials are configured for all jobs that check out the repository in the CI workflow. -- Disable the new `check-class-attributes` check in pydoclint 0.5.3, as we use a different way to document class attributes. -- Fix permissions issues with the `release-notes-check` workflow when the repository Actions configuration is set up without full access. +* Sybil now parses the `__init__.py` file as well. Previously it was disabled due to an upstream bug. diff --git a/cookiecutter/migrate.py b/cookiecutter/migrate.py new file mode 100644 index 00000000..9ca36736 --- /dev/null +++ b/cookiecutter/migrate.py @@ -0,0 +1,227 @@ +#!/usr/bin/env python3 +# License: MIT +# Copyright © 2024 Frequenz Energy-as-a-Service GmbH + +"""Script to migrate existing projects to new versions of the cookiecutter template. + +This script migrates existing projects to new versions of the cookiecutter +template, removing the need to completely regenerate the project from +scratch. + +To run it, the simplest way is to fetch it from GitHub and run it directly: + + curl -sSL https://raw.githubusercontent.com/frequenz-floss/frequenz-repo-config-python//cookiecutter/migrate.py | python3 + +Make sure to replace the `` to the version you want to migrate to in the URL. + +For jumping multiple versions you should run the script multiple times, once +for each version. + +And remember to follow any manual instructions for each run. +""" # noqa: E501 + +import os +import subprocess +import tempfile +from pathlib import Path +from typing import SupportsIndex + + +def apply_patch(patch_content: str) -> None: + """Apply a patch using the patch utility.""" + subprocess.run(["patch", "-p1"], input=patch_content.encode(), check=True) + + +def replace_file_contents_atomically( # noqa; DOC501 + filepath: str | Path, + old: str, + new: str, + count: SupportsIndex = -1, + *, + content: str | None = None, +) -> None: + """Replace a file atomically with new content. + + Args: + filepath: The path to the file to replace. + old: The string to replace. + new: The string to replace it with. + count: The maximum number of occurrences to replace. If negative, all occurrences are + replaced. + content: The content to replace. If not provided, the file is read from disk. + + The replacement is done atomically by writing to a temporary file and + then moving it to the target location. + """ + if isinstance(filepath, str): + filepath = Path(filepath) + + if content is None: + content = filepath.read_text(encoding="utf-8") + + content = content.replace(old, new, count) + + # Create temporary file in the same directory to ensure atomic move + tmp_dir = filepath.parent + + # pylint: disable-next=consider-using-with + tmp = tempfile.NamedTemporaryFile(mode="w", dir=tmp_dir, delete=False) + + try: + # Copy original file permissions + st = os.stat(filepath) + + # Write the new content + tmp.write(content) + + # Ensure all data is written to disk + tmp.flush() + os.fsync(tmp.fileno()) + tmp.close() + + # Copy original file permissions to the new file + os.chmod(tmp.name, st.st_mode) + + # Perform atomic replace + os.rename(tmp.name, filepath) + + except BaseException: + # Clean up the temporary file in case of errors + tmp.close() + os.unlink(tmp.name) + raise + + +def add_pylint_checks() -> None: + """Add new pylint checks to the project.""" + pyproject_toml = Path("pyproject.toml") + print( + f"{pyproject_toml}: Skip some flaky pylint checks that are checked better by mypy." + ) + marker = ' "no-member",\n' + pyproject_toml_content = pyproject_toml.read_text(encoding="utf-8") + if pyproject_toml_content.find(marker) == -1: + manual_step( + f"""\ +{pyproject_toml}: We couldn't find the marker {marker!r} in the file. +Please add the following lines to the file manually in the +`[tool.pylint.messages_control]` section, under the `disable` key (ideally below other +checks that are disabled because `mypy` already checks them) if they are missing: + "no-name-in-module", + "possibly-used-before-assignment", +""" + ) + return + + replacement = "" + if pyproject_toml_content.find("possibly-used-before-assignment") == -1: + replacement += ' "possibly-used-before-assignment",\n' + if pyproject_toml_content.find("no-name-in-module") == -1: + replacement += ' "no-name-in-module",\n' + + if not replacement: + print(f"{pyproject_toml}: seems to be already up-to-date.") + return + + replace_file_contents_atomically( + pyproject_toml, marker, marker + replacement, content=pyproject_toml_content + ) + + +def fix_default_fixture_scope() -> None: + """Fix the default scope of fixtures to 'function'.""" + pyproject_toml = Path("pyproject.toml") + print(f"{pyproject_toml}: Fix the default scope of fixtures to 'function'.") + marker = 'asyncio_mode = "auto"\n' + pyproject_toml_content = pyproject_toml.read_text(encoding="utf-8") + if pyproject_toml_content.find(marker) == -1: + manual_step( + f"""\ +{pyproject_toml}: We couldn't find the marker {marker!r} in the file. +Please add the following line to the file manually in the +`[tool.pytest.ini_options]` section if it is missing: +asyncio_default_fixture_loop_scope = "function" +""" + ) + return + + replacement = 'asyncio_default_fixture_loop_scope = "function"\n' + if pyproject_toml_content.find(replacement) >= 0: + print(f"{pyproject_toml}: seems to be already up-to-date.") + return + replace_file_contents_atomically( + pyproject_toml, marker, marker + replacement, content=pyproject_toml_content + ) + + +def main() -> None: + """Run the migration steps.""" + # Dependabot patch + dependabot_yaml = Path(".github/dependabot.yml") + print(f"{dependabot_yaml}: Add new grouping for actions/*-artifact updates.") + if dependabot_yaml.read_text(encoding="utf-8").find("actions/*-artifact") == -1: + apply_patch( + """\ +--- a/.github/dependabot.yml ++++ b/.github/dependabot.yml +@@ -39,3 +39,11 @@ updates: + labels: + - "part:tooling" + - "type:tech-debt" ++ groups: ++ compatible: ++ update-types: ++ - "minor" ++ - "patch" ++ artifacts: ++ patterns: ++ - "actions/*-artifact" +""" + ) + else: + print(f"{dependabot_yaml}: seems to be already up-to-date.") + print("=" * 72) + + # Fix labeler configuration + labeler_yml = ".github/labeler.yml" + print(f"{labeler_yml}: Fix the labeler configuration example.") + replace_file_contents_atomically( + labeler_yml, "all-glob-to-all-file", "all-globs-to-all-files" + ) + print("=" * 72) + + # Add new pylint checks + add_pylint_checks() + print("=" * 72) + + # Remove redundant --platform from the dockerfile + dockerfile = Path(".github/containers/test-installation/Dockerfile") + print(f"{dockerfile}: Removing redundant --platform.") + if dockerfile.is_file(): + replace_file_contents_atomically( + dockerfile, "--platform=${TARGETPLATFORM} ", "" + ) + else: + print(f"{dockerfile}: Not found.") + print("=" * 72) + + # Make sure `edit_uri` points to the default branch + manual_step( + "Make sure that the `edit_uri` in the `mkdocs.yml` file points to the default branch." + ) + print("=" * 72) + + # Fix the default scope of fixtures to 'function' + fix_default_fixture_scope() + + # Add a separation line like this one after each migration step. + print("=" * 72) + + +def manual_step(message: str) -> None: + """Print a manual step message in yellow.""" + print(f"\033[0;33m>>> {message}\033[0m") + + +if __name__ == "__main__": + main() diff --git a/cookiecutter/migrate.sh b/cookiecutter/migrate.sh deleted file mode 100644 index 3cf384cc..00000000 --- a/cookiecutter/migrate.sh +++ /dev/null @@ -1,269 +0,0 @@ -#!/bin/sh -# License: MIT -# Copyright © 2024 Frequenz Energy-as-a-Service GmbH -# -# This script migrates existing projects to new versions of the cookiecutter -# template, removing the need to completely regenerate the project from -# scratch. -# -# To run it, the simplest way is to fetch it from GitHub and run it directly: -# -# curl -sSL https://raw.githubusercontent.com/frequenz-floss/frequenz-repo-config-python/v0.10.0/cookiecutter/migrate.sh | sh -# -# Make sure the version you want to migrate to is correct in the URL. -# -# For jumping multiple versions you should run the script multiple times, once -# for each version. -# -# And remember to follow any manual instructions for each run. -set -eu - -manual_step() { - echo "\033[0;33m>>> $@\033[0m" -} - -echo "Removing the 'Markdown' type:ignore from docs/_scripts/macros.py" -sed -i \ - -e 's|return toc.slugify_unicode(text, "-") # type: ignore\[attr-defined,no-any-return\]|return toc.slugify_unicode(text, "-")|' \ - -e '/# The type of the return value is not defined for the markdown library./d' \ - -e '/# Also for some reason `mypy` thinks the `toc` module doesn'\''t have a/d' \ - -e '/# `slugify_unicode` function, but it definitely does./d' \ - docs/_scripts/macros.py -echo -manual_step "Please make sure that the 'Markdown' and 'types-Markdown' dependencies are at version 3.5.2 or higher in 'pyproject.toml':" -grep 'Markdown' pyproject.toml - -echo "========================================================================" - -echo "Adding the new 'show_symbol_type_toc' option for MkDocs" -sed -i '/^ show_source: true$/a \ show_symbol_type_toc: true' mkdocs.yml -sed -i '/^ "mkdocstrings\[python\] == .*",$/a \ "mkdocstrings-python == 1.9.2",' pyproject.toml - -echo "========================================================================" - -manual_step "To configure merge queues via repository rulesets you need to:" -manual_step " 1. Go to your repository settings and click on 'Rules' -> 'Rulesets' in the sidebar." -manual_step " 2. Click on 'New ruleset' on the top right and select 'Import a ruleset'." -manual_step " 3. Select the file 'github-rulesets/Queue PRs for v0.x.x.json'." -manual_step " 4. Make sure the branch name is correct (matches the branch you want to configure the merge queue for) and click 'Create'." -manual_step " 5. Go to the 'Branches' section in the sidebar." -manual_step " 6. Remove any branch protection rules that are not needed anymore (you should probably have only one configuring the merge queue if you were using other rulesets before)." - -echo "========================================================================" - -echo "Fixing pip cache in '.github/workflows/ci.yaml'" -sed -i "s|hashFiles('\*\*/pyproject.toml')|hashFiles('pyproject.toml')|" .github/workflows/ci.yaml - -echo "========================================================================" - -echo "Fixing nox-(cross-arch-)all jobs to fail on child jobs failure in '.github/workflows/ci.yaml'" -sed -i \ - -e '/^ needs: \["nox-cross-arch"\]$/,/^ run: "true"$/c\ - needs: \["nox-cross-arch"\]\ - # We skip this job only if nox-cross-arch was also skipped\ - if: always() && needs.nox-cross-arch.result != '"'"'skipped'"'"'\ - runs-on: ubuntu-20.04\ - env:\ - DEPS_RESULT: ${{ needs.nox-cross-arch.result }}\ - steps:\ - - name: Check matrix job result\ - run: test "$DEPS_RESULT" = "success"' \ - -e '/^ needs: \["nox"\]$/,/^ run: "true"$/c\ - needs: ["nox"]\ - # We skip this job only if nox was also skipped\ - if: always() && needs.nox.result != '"'"'skipped'"'"'\ - runs-on: ubuntu-20.04\ - env:\ - DEPS_RESULT: ${{ needs.nox.result }}\ - steps:\ - - name: Check matrix job result\ - run: test "$DEPS_RESULT" = "success"' \ - .github/workflows/ci.yaml - -echo "========================================================================" - -echo "Disabling some pylint checks also checked by other tools" -sed -i -e '/ "unsubscriptable-object",/a \ # Checked by mypy\ - "no-member",' \ - -e '/ # Checked by flake8/a \ "f-string-without-interpolation",' \ - -e '/ "line-too-long",/a \ "missing-function-docstring",' \ - pyproject.toml - -echo "========================================================================" - -echo "Using symlink aliases in 'mkdocs.yml'" -sed -i "s|alias_type: redirect|alias_type: symlink|" mkdocs.yml - -echo "========================================================================" - -echo "Fixing credentials not being properly passed in '.github/workflows/ci.yaml'" -patch --merge -p1 <<'EOF' -diff --git a/.github/containers/test-installation/Dockerfile b/.github/containers/test-installation/Dockerfile -index 2494545..ac3de24 100644 ---- a/.github/containers/test-installation/Dockerfile -+++ b/.github/containers/test-installation/Dockerfile -@@ -14,5 +14,8 @@ RUN apt-get update -y && \ - python -m pip install --upgrade --no-cache-dir pip - - COPY dist dist --RUN pip install dist/*.whl && \ -- rm -rf dist -+# This git-credentials file is made available by the GitHub ci.yaml workflow -+COPY git-credentials /root/.git-credentials -+RUN git config --global credential.helper store && \ -+ pip install dist/*.whl && \ -+ rm -rf dist /root/.git-credentials -diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml -index 8062a61..67000f1 100644 ---- a/.github/workflows/ci.yaml -+++ b/.github/workflows/ci.yaml -@@ -41,6 +41,13 @@ jobs: - runs-on: ${{ matrix.os }} - - steps: -+ - name: Setup Git -+ uses: frequenz-floss/gh-action-setup-git@v0.x.x -+ # TODO(cookiecutter): Uncomment this for projects with private dependencies -+ # with: -+ # username: ${{ secrets.GIT_USER }} -+ # password: ${{ secrets.GIT_PASS }} -+ - - name: Print environment (debug) - run: env - -@@ -119,6 +126,13 @@ jobs: - runs-on: ${{ matrix.os }} - - steps: -+ - name: Setup Git -+ uses: frequenz-floss/gh-action-setup-git@v0.x.x -+ # TODO(cookiecutter): Uncomment this for projects with private dependencies -+ # with: -+ # username: ${{ secrets.GIT_USER }} -+ # password: ${{ secrets.GIT_PASS }} -+ - - name: Fetch sources - uses: actions/checkout@v4 - -@@ -220,6 +234,13 @@ jobs: - name: Build distribution packages - runs-on: ubuntu-20.04 - steps: -+ - name: Setup Git -+ uses: frequenz-floss/gh-action-setup-git@v0.x.x -+ # TODO(cookiecutter): Uncomment this for projects with private dependencies -+ # with: -+ # username: ${{ secrets.GIT_USER }} -+ # password: ${{ secrets.GIT_PASS }} -+ - - name: Fetch sources - uses: actions/checkout@v4 - with: -@@ -252,17 +273,31 @@ jobs: - needs: ["build"] - runs-on: ubuntu-20.04 - steps: -+ - name: Setup Git -+ uses: frequenz-floss/gh-action-setup-git@v0.x.x -+ # TODO(cookiecutter): Uncomment this for projects with private dependencies -+ # with: -+ # username: ${{ secrets.GIT_USER }} -+ # password: ${{ secrets.GIT_PASS }} -+ - - name: Fetch sources - uses: actions/checkout@v4 -+ - - name: Download package - uses: actions/download-artifact@v4 - with: - name: dist-packages - path: dist -+ -+ - name: Make Git credentials available to docker - run: | - touch ~/.git-credentials # Ensure the file exists -+ cp ~/.git-credentials git-credentials || true -+ - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 -+ - - name: Set up docker-buildx - uses: docker/setup-buildx-action@v3 -+ - - name: Test Installation - uses: docker/build-push-action@v6 - with: -@@ -277,14 +312,18 @@ jobs: - if: github.event_name != 'push' - runs-on: ubuntu-20.04 - steps: -+ - name: Setup Git -+ uses: frequenz-floss/gh-action-setup-git@v0.x.x -+ # TODO(cookiecutter): Uncomment this for projects with private dependencies -+ # with: -+ # username: ${{ secrets.GIT_USER }} -+ # password: ${{ secrets.GIT_PASS }} -+ - - name: Fetch sources - uses: actions/checkout@v4 - with: - submodules: true - -- - name: Setup Git user and e-mail -- uses: frequenz-floss/setup-git-user@v2 -- - - name: Set up Python - uses: actions/setup-python@v5 - with: -@@ -319,14 +358,18 @@ jobs: - permissions: - contents: write - steps: -+ - name: Setup Git -+ uses: frequenz-floss/gh-action-setup-git@v0.x.x -+ # TODO(cookiecutter): Uncomment this for projects with private dependencies -+ # with: -+ # username: ${{ secrets.GIT_USER }} -+ # password: ${{ secrets.GIT_PASS }} -+ - - name: Fetch sources - uses: actions/checkout@v4 - with: - submodules: true - -- - name: Setup Git user and e-mail -- uses: frequenz-floss/setup-git-user@v2 -- - - name: Set up Python - uses: actions/setup-python@v5 - with: -EOF -manual_step "Please make sure to remove or uncomment the options to the 'gh-action-setup-git' action in the '.github/workflows/ci.yaml'" -grep -n "TODO(cookiecutter)" -- .github/workflows/ci.yaml .github/containers/test-installation/Dockerfile - -echo "========================================================================" - -echo "Disabling new pydoclint's check-class-attributes check in " -sed -i "/^allow-init-docstring/a check-class-attributes = false" pyproject.toml - -echo "========================================================================" - -echo "Adding pull-requests read permission to the release-notes-check workflow" -patch --merge -p1 <<'EOF' -diff --git a/.github/workflows/release-notes-check.yml b/.github/workflows/release-notes-check.yml -index 1e35c1a..e97886b 100644 ---- a/.github/workflows/release-notes-check.yml -+++ b/.github/workflows/release-notes-check.yml -@@ -17,6 +17,8 @@ jobs: - check-release-notes: - name: Check release notes are updated - runs-on: ubuntu-latest -+ permissions: -+ pull-requests: read - steps: - - name: Check for a release notes update - if: github.event_name == 'pull_request' -EOF - -# Add a separation line like this one after each migration step. -echo "========================================================================" diff --git a/cookiecutter/{{cookiecutter.github_repo_name}}/.github/containers/test-installation/Dockerfile b/cookiecutter/{{cookiecutter.github_repo_name}}/.github/containers/test-installation/Dockerfile index 6c408565..9357144d 100644 --- a/cookiecutter/{{cookiecutter.github_repo_name}}/.github/containers/test-installation/Dockerfile +++ b/cookiecutter/{{cookiecutter.github_repo_name}}/.github/containers/test-installation/Dockerfile @@ -5,7 +5,7 @@ # This Dockerfile is used to test the installation of the python package in # multiple platforms in the CI. It is not used to build the package itself. -FROM --platform=${TARGETPLATFORM} python:3.11-slim +FROM python:3.11-slim RUN apt-get update -y && \ apt-get install --no-install-recommends -y \ diff --git a/cookiecutter/{{cookiecutter.github_repo_name}}/.github/dependabot.yml b/cookiecutter/{{cookiecutter.github_repo_name}}/.github/dependabot.yml index 9f90cb7b..cfeaac00 100644 --- a/cookiecutter/{{cookiecutter.github_repo_name}}/.github/dependabot.yml +++ b/cookiecutter/{{cookiecutter.github_repo_name}}/.github/dependabot.yml @@ -39,6 +39,14 @@ updates: labels: - "part:tooling" - "type:tech-debt" + groups: + compatible: + update-types: + - "minor" + - "patch" + artifacts: + patterns: + - "actions/*-artifact" {%- if cookiecutter.type == "api" %} - package-ecosystem: "gitsubmodule" diff --git a/cookiecutter/{{cookiecutter.github_repo_name}}/.github/labeler.yml b/cookiecutter/{{cookiecutter.github_repo_name}}/.github/labeler.yml index 525665e3..fc6510e7 100644 --- a/cookiecutter/{{cookiecutter.github_repo_name}}/.github/labeler.yml +++ b/cookiecutter/{{cookiecutter.github_repo_name}}/.github/labeler.yml @@ -26,7 +26,7 @@ # - changed-files: # - any-glob-to-any-file: # - "src/**/*.py" -# - all-glob-to-all-file: +# - all-globs-to-all-files: # - "!src/__init__.py" # # Please have in mind that that the part:xxx labels need to diff --git a/cookiecutter/{{cookiecutter.github_repo_name}}/.github/workflows/release-notes-check.yml b/cookiecutter/{{cookiecutter.github_repo_name}}/.github/workflows/release-notes-check.yml index 2b401084..e972fb06 100644 --- a/cookiecutter/{{cookiecutter.github_repo_name}}/.github/workflows/release-notes-check.yml +++ b/cookiecutter/{{cookiecutter.github_repo_name}}/.github/workflows/release-notes-check.yml @@ -24,7 +24,7 @@ jobs: if: github.event_name == 'pull_request' uses: brettcannon/check-for-changed-files@871d7b8b5917a4f6f06662e2262e8ffc51dff6d1 # v1.2.1 with: - # TODO(cookiecutter): Uncomment the following line for private repositories, otherwise remove it and remove it + # TODO(cookiecutter): Uncomment the following line for private repositories, otherwise remove it # token: {{'${{ secrets.github_token }}'}} file-pattern: "RELEASE_NOTES.md" {%- if cookiecutter.type == "api" %} diff --git a/cookiecutter/{{cookiecutter.github_repo_name}}/.gitmodules b/cookiecutter/{{cookiecutter.github_repo_name}}/.gitmodules index 1a4f870a..45ccf677 100644 --- a/cookiecutter/{{cookiecutter.github_repo_name}}/.gitmodules +++ b/cookiecutter/{{cookiecutter.github_repo_name}}/.gitmodules @@ -1,7 +1,4 @@ {% if cookiecutter.type == "api" -%} -[submodule "submodules/api-common-protos"] - path = submodules/api-common-protos - url = https://github.com/googleapis/api-common-protos.git [submodule "submodules/frequenz-api-common"] path = submodules/frequenz-api-common url = https://github.com/frequenz-floss/frequenz-api-common.git diff --git a/cookiecutter/{{cookiecutter.github_repo_name}}/mkdocs.yml b/cookiecutter/{{cookiecutter.github_repo_name}}/mkdocs.yml index 6120ff7d..4110b297 100644 --- a/cookiecutter/{{cookiecutter.github_repo_name}}/mkdocs.yml +++ b/cookiecutter/{{cookiecutter.github_repo_name}}/mkdocs.yml @@ -8,9 +8,9 @@ site_author: "{{cookiecutter.author_name}}" copyright: "Copyright © {{copyright_year}} {{cookiecutter.author_name}}" repo_name: "{{cookiecutter.github_repo_name}}" repo_url: "https://github.com/{{cookiecutter.github_org}}/{{cookiecutter.github_repo_name}}" -# TODO(cookiecutter): "main" is the GitHub repo default branch, you might want to update it +# TODO(cookiecutter): "v0.x.x" is the GitHub repo default branch, you might want to update it # if the project uses a different default branch. -edit_uri: "edit/main/docs/" +edit_uri: "edit/v0.x.x/docs/" strict: true # Treat warnings as errors # Build directories @@ -121,10 +121,10 @@ plugins: # See https://mkdocstrings.github.io/python/usage/#import for details - https://docs.python.org/3/objects.inv {%- if cookiecutter.type in ("actor", "app", "model") %} - - https://frequenz-floss.github.io/frequenz-channels-python/v0.16/objects.inv - - https://frequenz-floss.github.io/frequenz-sdk-python/v0.25/objects.inv + - https://frequenz-floss.github.io/frequenz-channels-python/v1/objects.inv + - https://frequenz-floss.github.io/frequenz-sdk-python/v1.0-pre/objects.inv {%- elif cookiecutter.type == "api" %} - - https://frequenz-floss.github.io/frequenz-api-common/v0.3/objects.inv + - https://frequenz-floss.github.io/frequenz-api-common/v0.6/objects.inv - https://grpc.github.io/grpc/python/objects.inv {%- endif %} - https://typing-extensions.readthedocs.io/en/stable/objects.inv diff --git a/cookiecutter/{{cookiecutter.github_repo_name}}/pyproject.toml b/cookiecutter/{{cookiecutter.github_repo_name}}/pyproject.toml index 97087f6f..2cdc06b1 100644 --- a/cookiecutter/{{cookiecutter.github_repo_name}}/pyproject.toml +++ b/cookiecutter/{{cookiecutter.github_repo_name}}/pyproject.toml @@ -3,9 +3,18 @@ [build-system] requires = [ - "setuptools == 70.1.1", + "setuptools == 75.5.0", "setuptools_scm[toml] == 8.1.0", - "frequenz-repo-config[{{cookiecutter.type}}] == 0.10.0", + "frequenz-repo-config[{{cookiecutter.type}}] == 0.11.0", +{%- if cookiecutter.type == "api" %} + # We need to pin the protobuf, grpcio and grpcio-tools dependencies to make + # sure the code is generated using the minimum supported versions, as older + # versions can't work with code that was generated with newer versions. + # https://protobuf.dev/support/cross-version-runtime-guarantee/#backwards + "protobuf == 5.28.0", + "grpcio-tools == 1.66.1", + "grpcio == 1.66.1", +{%- endif %} ] build-backend = "setuptools.build_meta" @@ -33,23 +42,37 @@ classifiers = [ ] requires-python = ">= 3.11, < 4" # TODO(cookiecutter): Remove and add more dependencies if appropriate -{%- if cookiecutter.type in ("app", "actor", "model") %} +{%- if cookiecutter.type in ("actor", "model") %} +dependencies = [ + "typing-extensions >= 4.12.2, < 5", + # Make sure to update the version for cross-referencing also in the + # mkdocs.yml file when changing the version here (look for the config key + # plugins.mkdocstrings.handlers.python.import) + "frequenz-sdk >= 1.0.0rc1300, < 1.0.0rc1400", +] +{%- elif cookiecutter.type == "app" %} dependencies = [ - "typing-extensions == 4.5.0", + "typing-extensions == 4.12.2", # Make sure to update the version for cross-referencing also in the # mkdocs.yml file when changing the version here (look for the config key # plugins.mkdocstrings.handlers.python.import) - "frequenz-sdk == 0.25.0", + "frequenz-sdk == 1.0.0rc1300", ] {%- elif cookiecutter.type == "api" %} dependencies = [ - "frequenz-api-common >= 0.5.0, < 0.6.0", - "googleapis-common-protos >= 1.56.2, < 2", - "grpcio >= 1.51.1, < 2", + "frequenz-api-common >= 0.6.2, < 0.7.0", + # We can't widen beyond the current value unless we bump the minimum + # requirements too because of protobuf cross-version runtime guarantees: + # https://protobuf.dev/support/cross-version-runtime-guarantee/#major + "protobuf >= 5.28.0, < 7", # Do not widen beyond 7! + # We couldn't find any document with a spec about the cross-version runtime + # guarantee for grpcio, so unless we find one in the future, we'll assume + # major version jumps are not compatible + "grpcio >= 1.66.1, < 2", # Do not widen beyond 2! ] {%- else %} dependencies = [ - "typing-extensions >= 4.5.0, < 5", + "typing-extensions >= 4.12.2, < 5", ] {%- endif %} dynamic = ["version"] @@ -61,37 +84,37 @@ email = "{{cookiecutter.author_email}}" # TODO(cookiecutter): Remove and add more optional dependencies if appropriate [project.optional-dependencies] dev-flake8 = [ - "flake8 == 7.1.0", + "flake8 == 7.1.1", "flake8-docstrings == 1.7.0", "flake8-pyproject == 1.2.3", # For reading the flake8 config from pyproject.toml - "pydoclint == 0.5.3", + "pydoclint == 0.5.9", "pydocstyle == 6.3.0", ] -dev-formatting = ["black == 24.4.2", "isort == 5.13.2"] +dev-formatting = ["black == 24.10.0", "isort == 5.13.2"] dev-mkdocs = [ - "Markdown == 3.6.0", - "black == 24.4.2", - "mike == 2.1.2", + "Markdown == 3.7", + "black == 24.10.0", + "mike == 2.1.3", "mkdocs-gen-files == 0.5.0", "mkdocs-literate-nav == 0.6.1", - "mkdocs-macros-plugin == 1.0.5", - "mkdocs-material == 9.5.27", - "mkdocstrings[python] == 0.25.1", - "mkdocstrings-python == 1.10.5", - "frequenz-repo-config[{{cookiecutter.type}}] == 0.10.0", + "mkdocs-macros-plugin == 1.3.7", + "mkdocs-material == 9.5.45", + "mkdocstrings[python] == 0.27.0", + "mkdocstrings-python == 1.12.2", + "frequenz-repo-config[{{cookiecutter.type}}] == 0.11.0", ] dev-mypy = [ "mypy == 1.9.0", {%- if cookiecutter.type == "api" %} "grpc-stubs == 1.53.0.2", {%- endif %} - "types-Markdown == 3.6.0.20240316", + "types-Markdown == 3.7.0.20240822", # For checking the noxfile, docs/ script, and tests "{{cookiecutter.pypi_package_name}}[dev-mkdocs,dev-noxfile,dev-pytest]", ] dev-noxfile = [ - "nox == 2024.4.15", - "frequenz-repo-config[{{cookiecutter.type}}] == 0.10.0", + "nox == 2024.10.9", + "frequenz-repo-config[{{cookiecutter.type}}] == 0.11.0", ] dev-pylint = [ # dev-pytest already defines a dependency to pylint because of the examples @@ -99,12 +122,12 @@ dev-pylint = [ "{{cookiecutter.pypi_package_name}}[dev-mkdocs,dev-noxfile,dev-pytest]", ] dev-pytest = [ - "pytest == 8.2.2", - "pylint == 3.2.5", # We need this to check for the examples - "frequenz-repo-config[extra-lint-examples] == 0.10.0", + "pytest == 8.3.3", + "pylint == 3.3.1", # We need this to check for the examples + "frequenz-repo-config[extra-lint-examples] == 0.11.0", {%- if cookiecutter.type != "api" %} "pytest-mock == 3.14.0", - "pytest-asyncio == 0.23.7", + "pytest-asyncio == 0.24.0", "async-solipsism == 0.6", {%- endif %} ] @@ -163,11 +186,11 @@ disable = [ # disabled because it conflicts with isort "wrong-import-order", "ungrouped-imports", - # pylint's unsubscriptable check is buggy and is not needed because - # it is a type-check, for which we already have mypy. + # Checked by mypy (and pylint is very flaky checking these) "unsubscriptable-object", - # Checked by mypy "no-member", + "no-name-in-module", + "possibly-used-before-assignment", # Checked by flake8 "f-string-without-interpolation", "line-too-long", @@ -182,6 +205,7 @@ disable = [ {%- if cookiecutter.type != "api" %} testpaths = ["tests", "src"] asyncio_mode = "auto" +asyncio_default_fixture_loop_scope = "function" required_plugins = ["pytest-asyncio", "pytest-mock"] {%- else %} testpaths = ["pytests"] diff --git a/docs/user-guide/start-a-new-project/configure-github.md b/docs/user-guide/start-a-new-project/configure-github.md index fa948cd2..b0d2c84c 100644 --- a/docs/user-guide/start-a-new-project/configure-github.md +++ b/docs/user-guide/start-a-new-project/configure-github.md @@ -98,10 +98,18 @@ Import the following gh-pages]({{config.repo_url}}/blob/{{ref_name}}/github-rulesets/Disallow removal and force-pushes of gh-pages.json) * [Protect released tags]({{config.repo_url}}/blob/{{ref_name}}/github-rulesets/Protect released tags.json) +* [Queue PRs for the default + branch]({{config.repo_url}}/blob/{{ref_name}}/github-rulesets/Queue PRs for the default branch.json) + +##### Python specific rulesets + +* [Protect version + branches]({{config.repo_url}}/blob/{{ref_name}}/github-rulesets/python/Protect version branches.json) + +##### Rust specific rulesets + * [Protect version - branches]({{config.repo_url}}/blob/{{ref_name}}/github-rulesets/Protect version branches.json) -* [Queue PRs for - v0.x.x]({{config.repo_url}}/blob/{{ref_name}}/github-rulesets/Queue PRs for v0.x.x.json) + branches]({{config.repo_url}}/blob/{{ref_name}}/github-rulesets/rust/Protect version branches.json) ### Code security and analysis diff --git a/docs/user-guide/update-an-existing-project.md b/docs/user-guide/update-an-existing-project.md index 6b1ce55a..43448ffa 100644 --- a/docs/user-guide/update-an-existing-project.md +++ b/docs/user-guide/update-an-existing-project.md @@ -22,8 +22,8 @@ The easiest way to run the migration script is to fetch it from GitHub and run it directly. ```sh -curl -sSL https://raw.githubusercontent.com/frequenz-floss/frequenz-repo-config-python/{{ ref_name }}/cookiecutter/migrate.sh \ - | sh +curl -sSL https://raw.githubusercontent.com/frequenz-floss/frequenz-repo-config-python/{{ ref_name }}/cookiecutter/migrate.py \ + | python3 ``` Make sure that the version (`{{ ref_name }}`) matches the diff --git a/github-rulesets/Queue PRs for the default branch.json b/github-rulesets/Queue PRs for the default branch.json new file mode 100644 index 00000000..cfa5efa9 --- /dev/null +++ b/github-rulesets/Queue PRs for the default branch.json @@ -0,0 +1,46 @@ +{ + "name": "Queue PRs for the default branch", + "target": "branch", + "source_type": "Repository", + "source": "frequenz-floss/frequenz-repo-config-python", + "enforcement": "active", + "conditions": { + "ref_name": { + "exclude": [], + "include": [ + "~DEFAULT_BRANCH" + ] + } + }, + "rules": [ + { + "type": "merge_queue", + "parameters": { + "merge_method": "MERGE", + "max_entries_to_build": 5, + "min_entries_to_merge": 1, + "max_entries_to_merge": 5, + "min_entries_to_merge_wait_minutes": 5, + "grouping_strategy": "ALLGREEN", + "check_response_timeout_minutes": 60 + } + } + ], + "bypass_actors": [ + { + "actor_id": 2, + "actor_type": "RepositoryRole", + "bypass_mode": "pull_request" + }, + { + "actor_id": 5, + "actor_type": "RepositoryRole", + "bypass_mode": "always" + }, + { + "actor_id": 1, + "actor_type": "OrganizationAdmin", + "bypass_mode": "always" + } + ] +} diff --git a/github-rulesets/Protect version branches.json b/github-rulesets/python/Protect version branches.json similarity index 100% rename from github-rulesets/Protect version branches.json rename to github-rulesets/python/Protect version branches.json diff --git a/github-rulesets/Queue PRs for v0.x.x.json b/github-rulesets/rust/Protect version branches.json similarity index 63% rename from github-rulesets/Queue PRs for v0.x.x.json rename to github-rulesets/rust/Protect version branches.json index 64f46661..75d6dc04 100644 --- a/github-rulesets/Queue PRs for v0.x.x.json +++ b/github-rulesets/rust/Protect version branches.json @@ -1,5 +1,5 @@ { - "name": "Queue PRs for v0.x.x", + "name": "Protect version branches", "target": "branch", "source_type": "Repository", "source": "frequenz-floss/frequenz-repo-config-python", @@ -8,7 +8,8 @@ "ref_name": { "exclude": [], "include": [ - "refs/heads/v0.x.x" + "~DEFAULT_BRANCH", + "refs/heads/v[0-9]*.[0-9x]*.x" ] } }, @@ -22,10 +23,10 @@ { "type": "pull_request", "parameters": { - "required_approving_review_count": 1, - "dismiss_stale_reviews_on_push": true, "require_code_owner_review": true, "require_last_push_approval": true, + "dismiss_stale_reviews_on_push": true, + "required_approving_review_count": 1, "required_review_thread_resolution": false } }, @@ -33,47 +34,24 @@ "type": "required_status_checks", "parameters": { "strict_required_status_checks_policy": false, + "do_not_enforce_on_create": false, "required_status_checks": [ { - "context": "Test with nox", - "integration_id": 15368 - }, - { - "context": "Test documentation website generation", - "integration_id": 15368 - }, - { - "context": "Test package installation in different architectures", - "integration_id": 15368 - }, - { - "context": "Cross-arch tests with nox", - "integration_id": 15368 + "context": "DCO" }, { "context": "Check release notes are updated", "integration_id": 15368 }, { - "context": "DCO" + "context": "test", + "integration_id": 15368 } ] } }, { "type": "deletion" - }, - { - "type": "merge_queue", - "parameters": { - "merge_method": "Merge commit", - "max_entries_to_build": 5, - "min_entries_to_merge": 1, - "max_entries_to_merge": 5, - "min_entries_to_merge_wait_minutes": 5, - "grouping_strategy_all_green": true, - "check_response_timeout_minutes": 60 - } } ], "bypass_actors": [ diff --git a/noxfile.py b/noxfile.py index f88d626a..6b221956 100644 --- a/noxfile.py +++ b/noxfile.py @@ -11,6 +11,7 @@ [ "cookiecutter/hooks", "cookiecutter/local_extensions.py", + "cookiecutter/migrate.py", ] ) nox.configure(config) diff --git a/pyproject.toml b/pyproject.toml index f64e2b03..c76e9b65 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,7 +2,7 @@ # Copyright © 2023 Frequenz Energy-as-a-Service GmbH [build-system] -requires = ["setuptools == 68.1.0", "setuptools_scm[toml] == 7.1.0"] +requires = ["setuptools == 75.5.0", "setuptools_scm[toml] == 8.1.0"] build-backend = "setuptools.build_meta" [project] @@ -56,7 +56,7 @@ actor = [] api = [ "grpcio-tools >= 1.47.0, < 2", "mypy-protobuf >= 3.0.0, < 4", - "setuptools >= 67.6.0, < 71", + "setuptools >= 67.6.0, < 76", ] app = [] lib = [] @@ -64,50 +64,50 @@ model = [] extra-lint-examples = [ "pylint >= 2.17.3, < 4", "pytest >= 7.3.0, < 9", - "sybil >= 6.1.1, < 7", + "sybil >= 6.1.1, < 10", ] dev-flake8 = [ - "flake8 == 7.1.0", + "flake8 == 7.1.1", "flake8-docstrings == 1.7.0", "flake8-pyproject == 1.2.3", # For reading the flake8 config from pyproject.toml - "pydoclint == 0.5.3", + "pydoclint == 0.5.9", "pydocstyle == 6.3.0", ] -dev-formatting = ["black == 24.4.2", "isort == 5.13.2"] +dev-formatting = ["black == 24.10.0", "isort == 5.13.2"] dev-mkdocs = [ - "black == 24.4.2", - "Markdown == 3.6.0", - "mike == 2.1.2", + "black == 24.10.0", + "Markdown == 3.7", + "mike == 2.1.3", "mkdocs-gen-files == 0.5.0", "mkdocs-literate-nav == 0.6.1", - "mkdocs-macros-plugin == 1.0.5", - "mkdocs-material == 9.5.27", - "mkdocstrings[python] == 0.25.1", - "mkdocstrings-python == 1.10.5", + "mkdocs-macros-plugin == 1.3.7", + "mkdocs-material == 9.5.45", + "mkdocstrings[python] == 0.27.0", + "mkdocstrings-python == 1.12.2", ] dev-mypy = [ - "mypy == 1.10.1", - "types-setuptools >= 67.6.0, < 71", # Should match the build dependency - "types-Markdown == 3.6.0.20240316", - "types-PyYAML == 6.0.12.20240311", + "mypy == 1.13.0", + "types-setuptools >= 67.6.0, < 76", # Should match the build dependency + "types-Markdown == 3.7.0.20240822", + "types-PyYAML == 6.0.12.20240917", "types-babel == 2.11.0.15", "types-colorama == 0.4.15.20240311", # For checking the noxfile, docs/ script, and tests "frequenz-repo-config[dev-mkdocs,dev-noxfile,dev-pytest]", ] -dev-noxfile = ["nox == 2024.4.15"] +dev-noxfile = ["nox == 2024.10.9"] dev-pylint = [ # dev-pytest already defines a dependency to pylint because of the examples # For checking the noxfile, docs/ script, and tests "frequenz-repo-config[dev-mkdocs,dev-noxfile,dev-pytest]", - "setuptools >= 67.6.0, < 71", # Should match the build dependency + "setuptools >= 67.6.0, < 76", # Should match the build dependency ] dev-pytest = [ - "pytest == 8.2.2", - "pylint == 3.2.5", # We need this to check for the examples + "pytest == 8.3.3", + "pylint == 3.3.1", # We need this to check for the examples "cookiecutter == 2.6.0", # For checking the cookiecutter scripts "jinja2 == 3.1.4", # For checking the cookiecutter scripts - "sybil >= 6.1.1, < 7", # Should be consistent with the extra-lint-examples dependency + "sybil >= 6.1.1, < 10", # Should be consistent with the extra-lint-examples dependency ] dev = [ "frequenz-repo-config[dev-mkdocs,dev-flake8,dev-formatting,dev-mkdocs,dev-mypy,dev-noxfile,dev-pylint,dev-pytest]", @@ -128,7 +128,13 @@ include = '\.pyi?$' [tool.isort] profile = "black" line_length = 88 -src_paths = ["benchmarks", "examples", "src", "tests"] +src_paths = [ + "benchmarks", + "examples", + "src", + "tests", + "cookiecutter/migrate.py", +] [tool.flake8] # We give some flexibility to go over 88, there are cases like long URLs or @@ -161,11 +167,15 @@ disable = [ # disabled because it conflicts with isort "wrong-import-order", "ungrouped-imports", - # pylint's unsubscriptable check is buggy and is not needed because - # it is a type-check, for which we already have mypy. + # Checked by mypy (and pylint is very flaky checking these) "unsubscriptable-object", + "no-member", + "no-name-in-module", + "possibly-used-before-assignment", # Checked by flake8 + "f-string-without-interpolation", "line-too-long", + "missing-function-docstring", "redefined-outer-name", "unnecessary-lambda-assignment", "unused-import", diff --git a/src/frequenz/repo/config/__init__.py b/src/frequenz/repo/config/__init__.py index 6fef01ee..fbbfeec8 100644 --- a/src/frequenz/repo/config/__init__.py +++ b/src/frequenz/repo/config/__init__.py @@ -340,8 +340,8 @@ # Glob pattern to use to find the proto files in the proto_path (default: "*.proto") proto_glob = "*.prt" # Default: "*.proto" # List of paths to pass to the protoc compiler as include paths (default: -# ["submodules/api-common-protos", "submodules/frequenz-api-common/proto"]) -include_paths = ["submodules/api-common-protos"] +# ["submodules/frequenz-api-common/proto"]) +include_paths = ["submodules/frequenz-api-common/proto"] # Path where to generate the Python files (default: "py") py_path = "generated" # Path where to generate the documentation files (default: "protobuf-reference") @@ -376,23 +376,18 @@ section plus the following: - `pytests/`: Directory containing the tests for the Python code. -- `submodules/api-common-protos`: Directory containing the Git submodule with the - `google/api-common-protos` repository. - `submodules/frequenz-api-common`: Directory containing the Git submodule with the `frequenz-floss/frequenz-api-common` repository. Normally Frequenz APIs use basic types from -[`google/api-common-protos`](https://github.com/googleapis/api-common-protos) and [`frequenz-floss/frequenz-api-common`](https://github.com/frequenz-floss/frequenz-api-common), so you need to make sure the proper submodules are added to your project: ```sh mkdir submodules -git submodule add https://github.com/googleapis/api-common-protos.git \ - submodules/api-common-protos git submodule add https://github.com/frequenz-floss/frequenz-api-common.git \ submodules/frequenz-api-common -git commit -m "Add api-common-protos and frequenz-api-common submodules" submodules +git commit -m "Add frequenz-api-common submodule" submodules ``` Then you need to add this package as a build dependency and a few extra @@ -435,13 +430,11 @@ ``` Finally you need to make sure to include the generated `*.pyi` files in the -source distribution, as well as the Google api-common-protos files, as it -is not handled automatically yet +source distribution, as it is not handled automatically yet ([#13](https://github.com/frequenz-floss/frequenz-repo-config-python/issues/13)). Make sure to include these lines in the `MANIFEST.in` file: ``` -recursive-include submodules/api-common-protos/google *.proto recursive-include submodules/frequenz-api-common/proto *.proto ``` diff --git a/src/frequenz/repo/config/github.py b/src/frequenz/repo/config/github.py index bf1dd6dc..1e7754cb 100644 --- a/src/frequenz/repo/config/github.py +++ b/src/frequenz/repo/config/github.py @@ -56,6 +56,7 @@ def format(self, record: logging.LogRecord) -> str: def abort( # pylint: disable=too-many-arguments message: str, + *, title: str | None = None, file: str | None = None, col: int | None = None, diff --git a/src/frequenz/repo/config/protobuf.py b/src/frequenz/repo/config/protobuf.py index 9eaa20ba..83d31c63 100644 --- a/src/frequenz/repo/config/protobuf.py +++ b/src/frequenz/repo/config/protobuf.py @@ -27,10 +27,7 @@ class ProtobufConfig: proto_glob: str = "*.proto" """The glob pattern to use to find the protobuf files.""" - include_paths: Sequence[str] = ( - "submodules/api-common-protos", - "submodules/frequenz-api-common/proto", - ) + include_paths: Sequence[str] = ("submodules/frequenz-api-common/proto",) """The paths to add to the include path when compiling the protobuf files.""" py_path: str = "py" diff --git a/src/frequenz/repo/config/pytest/examples.py b/src/frequenz/repo/config/pytest/examples.py index b79fbfe6..7038a7e2 100644 --- a/src/frequenz/repo/config/pytest/examples.py +++ b/src/frequenz/repo/config/pytest/examples.py @@ -228,8 +228,4 @@ def get_sybil_arguments() -> dict[str, Any]: return { "parsers": [MyPythonCodeBlockParser()], "patterns": ["*.py"], - # This is a hack because Sybil seems to have issues with `__init__.py` files. - # See https://github.com/frequenz-floss/frequenz-repo-config-python/issues/113 - # for details - "excludes": ["__init__.py"], } diff --git a/tests_golden/integration/test_cookiecutter_generation/actor/cookiecutter-stdout.txt b/tests_golden/integration/test_cookiecutter_generation/actor/cookiecutter-stdout.txt index 905ba377..f4aaaaa2 100644 --- a/tests_golden/integration/test_cookiecutter_generation/actor/cookiecutter-stdout.txt +++ b/tests_golden/integration/test_cookiecutter_generation/actor/cookiecutter-stdout.txt @@ -8,7 +8,7 @@ ./.github/workflows/ci.yaml: # TODO(cookiecutter): Uncomment this for projects with private dependencies ./.github/workflows/ci.yaml: # TODO(cookiecutter): Uncomment this for projects with private dependencies ./.github/workflows/ci.yaml: # TODO(cookiecutter): Uncomment this for projects with private dependencies -./.github/workflows/release-notes-check.yml: # TODO(cookiecutter): Uncomment the following line for private repositories, otherwise remove it and remove it +./.github/workflows/release-notes-check.yml: # TODO(cookiecutter): Uncomment the following line for private repositories, otherwise remove it ./CODEOWNERS:# TODO(cookiecutter): Add more specific code-owners, check if the default is correct ./CODEOWNERS:* TODO(cookiecutter): Add codeowners (like @{github_org}/some-team)# Temporary, should probably change ./README.md:TODO(cookiecutter): Improve the README file @@ -16,7 +16,7 @@ ./mkdocs.yml: # TODO(cookiecutter): You might want to add other external references here ./mkdocs.yml: # TODO(cookiecutter): You might want to change the logo, the file is located in "docs/" ./mkdocs.yml: # TODO(cookiecutter): You probably want to update the social links -./mkdocs.yml:# TODO(cookiecutter): "main" is the GitHub repo default branch, you might want to update it +./mkdocs.yml:# TODO(cookiecutter): "v0.x.x" is the GitHub repo default branch, you might want to update it ./pyproject.toml:# TODO(cookiecutter): Remove and add more classifiers if appropriate ./pyproject.toml:# TODO(cookiecutter): Remove and add more dependencies if appropriate ./pyproject.toml:# TODO(cookiecutter): Remove and add more optional dependencies if appropriate diff --git a/tests_golden/integration/test_cookiecutter_generation/actor/frequenz-actor-test/.github/containers/test-installation/Dockerfile b/tests_golden/integration/test_cookiecutter_generation/actor/frequenz-actor-test/.github/containers/test-installation/Dockerfile index 6ca61423..d5e23993 100644 --- a/tests_golden/integration/test_cookiecutter_generation/actor/frequenz-actor-test/.github/containers/test-installation/Dockerfile +++ b/tests_golden/integration/test_cookiecutter_generation/actor/frequenz-actor-test/.github/containers/test-installation/Dockerfile @@ -3,7 +3,7 @@ # This Dockerfile is used to test the installation of the python package in # multiple platforms in the CI. It is not used to build the package itself. -FROM --platform=${TARGETPLATFORM} python:3.11-slim +FROM python:3.11-slim RUN apt-get update -y && \ apt-get install --no-install-recommends -y \ diff --git a/tests_golden/integration/test_cookiecutter_generation/actor/frequenz-actor-test/.github/dependabot.yml b/tests_golden/integration/test_cookiecutter_generation/actor/frequenz-actor-test/.github/dependabot.yml index 8978cb3c..23cd21b1 100644 --- a/tests_golden/integration/test_cookiecutter_generation/actor/frequenz-actor-test/.github/dependabot.yml +++ b/tests_golden/integration/test_cookiecutter_generation/actor/frequenz-actor-test/.github/dependabot.yml @@ -39,3 +39,11 @@ updates: labels: - "part:tooling" - "type:tech-debt" + groups: + compatible: + update-types: + - "minor" + - "patch" + artifacts: + patterns: + - "actions/*-artifact" diff --git a/tests_golden/integration/test_cookiecutter_generation/actor/frequenz-actor-test/.github/labeler.yml b/tests_golden/integration/test_cookiecutter_generation/actor/frequenz-actor-test/.github/labeler.yml index 289715e0..b8fea2f2 100644 --- a/tests_golden/integration/test_cookiecutter_generation/actor/frequenz-actor-test/.github/labeler.yml +++ b/tests_golden/integration/test_cookiecutter_generation/actor/frequenz-actor-test/.github/labeler.yml @@ -26,7 +26,7 @@ # - changed-files: # - any-glob-to-any-file: # - "src/**/*.py" -# - all-glob-to-all-file: +# - all-globs-to-all-files: # - "!src/__init__.py" # # Please have in mind that that the part:xxx labels need to diff --git a/tests_golden/integration/test_cookiecutter_generation/actor/frequenz-actor-test/.github/workflows/release-notes-check.yml b/tests_golden/integration/test_cookiecutter_generation/actor/frequenz-actor-test/.github/workflows/release-notes-check.yml index 514a7a0e..9f7ee31b 100644 --- a/tests_golden/integration/test_cookiecutter_generation/actor/frequenz-actor-test/.github/workflows/release-notes-check.yml +++ b/tests_golden/integration/test_cookiecutter_generation/actor/frequenz-actor-test/.github/workflows/release-notes-check.yml @@ -24,7 +24,7 @@ jobs: if: github.event_name == 'pull_request' uses: brettcannon/check-for-changed-files@871d7b8b5917a4f6f06662e2262e8ffc51dff6d1 # v1.2.1 with: - # TODO(cookiecutter): Uncomment the following line for private repositories, otherwise remove it and remove it + # TODO(cookiecutter): Uncomment the following line for private repositories, otherwise remove it # token: ${{ secrets.github_token }} file-pattern: "RELEASE_NOTES.md" prereq-pattern: "src/**" diff --git a/tests_golden/integration/test_cookiecutter_generation/actor/frequenz-actor-test/mkdocs.yml b/tests_golden/integration/test_cookiecutter_generation/actor/frequenz-actor-test/mkdocs.yml index ae4f9231..b15eefcd 100644 --- a/tests_golden/integration/test_cookiecutter_generation/actor/frequenz-actor-test/mkdocs.yml +++ b/tests_golden/integration/test_cookiecutter_generation/actor/frequenz-actor-test/mkdocs.yml @@ -8,9 +8,9 @@ site_author: "Frequenz Energy-as-a-Service GmbH" copyright: "Copyright © 2023 Frequenz Energy-as-a-Service GmbH" repo_name: "frequenz-actor-test" repo_url: "https://github.com/frequenz-floss/frequenz-actor-test" -# TODO(cookiecutter): "main" is the GitHub repo default branch, you might want to update it +# TODO(cookiecutter): "v0.x.x" is the GitHub repo default branch, you might want to update it # if the project uses a different default branch. -edit_uri: "edit/main/docs/" +edit_uri: "edit/v0.x.x/docs/" strict: true # Treat warnings as errors # Build directories @@ -120,8 +120,8 @@ plugins: # TODO(cookiecutter): You might want to add other external references here # See https://mkdocstrings.github.io/python/usage/#import for details - https://docs.python.org/3/objects.inv - - https://frequenz-floss.github.io/frequenz-channels-python/v0.16/objects.inv - - https://frequenz-floss.github.io/frequenz-sdk-python/v0.25/objects.inv + - https://frequenz-floss.github.io/frequenz-channels-python/v1/objects.inv + - https://frequenz-floss.github.io/frequenz-sdk-python/v1.0-pre/objects.inv - https://typing-extensions.readthedocs.io/en/stable/objects.inv # Note this plugin must be loaded after mkdocstrings to be able to use macros # inside docstrings. See the comment in `docs/_scripts/macros.py` for more diff --git a/tests_golden/integration/test_cookiecutter_generation/actor/frequenz-actor-test/pyproject.toml b/tests_golden/integration/test_cookiecutter_generation/actor/frequenz-actor-test/pyproject.toml index c4e517a1..45a10a9c 100644 --- a/tests_golden/integration/test_cookiecutter_generation/actor/frequenz-actor-test/pyproject.toml +++ b/tests_golden/integration/test_cookiecutter_generation/actor/frequenz-actor-test/pyproject.toml @@ -3,9 +3,9 @@ [build-system] requires = [ - "setuptools == 70.1.1", + "setuptools == 75.5.0", "setuptools_scm[toml] == 8.1.0", - "frequenz-repo-config[actor] == 0.10.0", + "frequenz-repo-config[actor] == 0.11.0", ] build-backend = "setuptools.build_meta" @@ -28,11 +28,11 @@ classifiers = [ requires-python = ">= 3.11, < 4" # TODO(cookiecutter): Remove and add more dependencies if appropriate dependencies = [ - "typing-extensions == 4.5.0", + "typing-extensions >= 4.12.2, < 5", # Make sure to update the version for cross-referencing also in the # mkdocs.yml file when changing the version here (look for the config key # plugins.mkdocstrings.handlers.python.import) - "frequenz-sdk == 0.25.0", + "frequenz-sdk >= 1.0.0rc1300, < 1.0.0rc1400", ] dynamic = ["version"] @@ -43,34 +43,34 @@ email = "floss@frequenz.com" # TODO(cookiecutter): Remove and add more optional dependencies if appropriate [project.optional-dependencies] dev-flake8 = [ - "flake8 == 7.1.0", + "flake8 == 7.1.1", "flake8-docstrings == 1.7.0", "flake8-pyproject == 1.2.3", # For reading the flake8 config from pyproject.toml - "pydoclint == 0.5.3", + "pydoclint == 0.5.9", "pydocstyle == 6.3.0", ] -dev-formatting = ["black == 24.4.2", "isort == 5.13.2"] +dev-formatting = ["black == 24.10.0", "isort == 5.13.2"] dev-mkdocs = [ - "Markdown == 3.6.0", - "black == 24.4.2", - "mike == 2.1.2", + "Markdown == 3.7", + "black == 24.10.0", + "mike == 2.1.3", "mkdocs-gen-files == 0.5.0", "mkdocs-literate-nav == 0.6.1", - "mkdocs-macros-plugin == 1.0.5", - "mkdocs-material == 9.5.27", - "mkdocstrings[python] == 0.25.1", - "mkdocstrings-python == 1.10.5", - "frequenz-repo-config[actor] == 0.10.0", + "mkdocs-macros-plugin == 1.3.7", + "mkdocs-material == 9.5.45", + "mkdocstrings[python] == 0.27.0", + "mkdocstrings-python == 1.12.2", + "frequenz-repo-config[actor] == 0.11.0", ] dev-mypy = [ "mypy == 1.9.0", - "types-Markdown == 3.6.0.20240316", + "types-Markdown == 3.7.0.20240822", # For checking the noxfile, docs/ script, and tests "frequenz-actor-test[dev-mkdocs,dev-noxfile,dev-pytest]", ] dev-noxfile = [ - "nox == 2024.4.15", - "frequenz-repo-config[actor] == 0.10.0", + "nox == 2024.10.9", + "frequenz-repo-config[actor] == 0.11.0", ] dev-pylint = [ # dev-pytest already defines a dependency to pylint because of the examples @@ -78,11 +78,11 @@ dev-pylint = [ "frequenz-actor-test[dev-mkdocs,dev-noxfile,dev-pytest]", ] dev-pytest = [ - "pytest == 8.2.2", - "pylint == 3.2.5", # We need this to check for the examples - "frequenz-repo-config[extra-lint-examples] == 0.10.0", + "pytest == 8.3.3", + "pylint == 3.3.1", # We need this to check for the examples + "frequenz-repo-config[extra-lint-examples] == 0.11.0", "pytest-mock == 3.14.0", - "pytest-asyncio == 0.23.7", + "pytest-asyncio == 0.24.0", "async-solipsism == 0.6", ] dev = [ @@ -137,11 +137,11 @@ disable = [ # disabled because it conflicts with isort "wrong-import-order", "ungrouped-imports", - # pylint's unsubscriptable check is buggy and is not needed because - # it is a type-check, for which we already have mypy. + # Checked by mypy (and pylint is very flaky checking these) "unsubscriptable-object", - # Checked by mypy "no-member", + "no-name-in-module", + "possibly-used-before-assignment", # Checked by flake8 "f-string-without-interpolation", "line-too-long", @@ -155,6 +155,7 @@ disable = [ [tool.pytest.ini_options] testpaths = ["tests", "src"] asyncio_mode = "auto" +asyncio_default_fixture_loop_scope = "function" required_plugins = ["pytest-asyncio", "pytest-mock"] [tool.mypy] diff --git a/tests_golden/integration/test_cookiecutter_generation/api/cookiecutter-stdout.txt b/tests_golden/integration/test_cookiecutter_generation/api/cookiecutter-stdout.txt index 66f6e724..2ec694d7 100644 --- a/tests_golden/integration/test_cookiecutter_generation/api/cookiecutter-stdout.txt +++ b/tests_golden/integration/test_cookiecutter_generation/api/cookiecutter-stdout.txt @@ -9,14 +9,14 @@ ./.github/workflows/ci.yaml: # TODO(cookiecutter): Uncomment this for projects with private dependencies ./.github/workflows/ci.yaml: # TODO(cookiecutter): Uncomment this for projects with private dependencies ./.github/workflows/ci.yaml: # TODO(cookiecutter): Uncomment this for projects with private dependencies -./.github/workflows/release-notes-check.yml: # TODO(cookiecutter): Uncomment the following line for private repositories, otherwise remove it and remove it +./.github/workflows/release-notes-check.yml: # TODO(cookiecutter): Uncomment the following line for private repositories, otherwise remove it ./CODEOWNERS:# TODO(cookiecutter): Add more specific code-owners, check if the default is correct ./README.md:TODO(cookiecutter): Improve the README file ./docs/_scripts/macros.py: # TODO(cookiecutter): Add any other macros, variables and filters here. ./mkdocs.yml: # TODO(cookiecutter): You might want to add other external references here ./mkdocs.yml: # TODO(cookiecutter): You might want to change the logo, the file is located in "docs/" ./mkdocs.yml: # TODO(cookiecutter): You probably want to update the social links -./mkdocs.yml:# TODO(cookiecutter): "main" is the GitHub repo default branch, you might want to update it +./mkdocs.yml:# TODO(cookiecutter): "v0.x.x" is the GitHub repo default branch, you might want to update it ./proto/frequenz/api/test/test.proto:// TODO(cookiecutter): Add a more descriptive package description. ./proto/frequenz/api/test/test.proto:// TODO(cookiecutter): Remove this message. ./py/frequenz/api/test/__init__.py:TODO(cookiecutter): Add a more descriptive module description. diff --git a/tests_golden/integration/test_cookiecutter_generation/api/frequenz-api-test/.github/containers/test-installation/Dockerfile b/tests_golden/integration/test_cookiecutter_generation/api/frequenz-api-test/.github/containers/test-installation/Dockerfile index 6ca61423..d5e23993 100644 --- a/tests_golden/integration/test_cookiecutter_generation/api/frequenz-api-test/.github/containers/test-installation/Dockerfile +++ b/tests_golden/integration/test_cookiecutter_generation/api/frequenz-api-test/.github/containers/test-installation/Dockerfile @@ -3,7 +3,7 @@ # This Dockerfile is used to test the installation of the python package in # multiple platforms in the CI. It is not used to build the package itself. -FROM --platform=${TARGETPLATFORM} python:3.11-slim +FROM python:3.11-slim RUN apt-get update -y && \ apt-get install --no-install-recommends -y \ diff --git a/tests_golden/integration/test_cookiecutter_generation/api/frequenz-api-test/.github/dependabot.yml b/tests_golden/integration/test_cookiecutter_generation/api/frequenz-api-test/.github/dependabot.yml index 24b56348..d98b4f33 100644 --- a/tests_golden/integration/test_cookiecutter_generation/api/frequenz-api-test/.github/dependabot.yml +++ b/tests_golden/integration/test_cookiecutter_generation/api/frequenz-api-test/.github/dependabot.yml @@ -39,6 +39,14 @@ updates: labels: - "part:tooling" - "type:tech-debt" + groups: + compatible: + update-types: + - "minor" + - "patch" + artifacts: + patterns: + - "actions/*-artifact" - package-ecosystem: "gitsubmodule" directory: "/" diff --git a/tests_golden/integration/test_cookiecutter_generation/api/frequenz-api-test/.github/labeler.yml b/tests_golden/integration/test_cookiecutter_generation/api/frequenz-api-test/.github/labeler.yml index d3fc066d..5e3bde5f 100644 --- a/tests_golden/integration/test_cookiecutter_generation/api/frequenz-api-test/.github/labeler.yml +++ b/tests_golden/integration/test_cookiecutter_generation/api/frequenz-api-test/.github/labeler.yml @@ -26,7 +26,7 @@ # - changed-files: # - any-glob-to-any-file: # - "src/**/*.py" -# - all-glob-to-all-file: +# - all-globs-to-all-files: # - "!src/__init__.py" # # Please have in mind that that the part:xxx labels need to diff --git a/tests_golden/integration/test_cookiecutter_generation/api/frequenz-api-test/.github/workflows/release-notes-check.yml b/tests_golden/integration/test_cookiecutter_generation/api/frequenz-api-test/.github/workflows/release-notes-check.yml index f6f06c17..1d18e8e5 100644 --- a/tests_golden/integration/test_cookiecutter_generation/api/frequenz-api-test/.github/workflows/release-notes-check.yml +++ b/tests_golden/integration/test_cookiecutter_generation/api/frequenz-api-test/.github/workflows/release-notes-check.yml @@ -24,7 +24,7 @@ jobs: if: github.event_name == 'pull_request' uses: brettcannon/check-for-changed-files@871d7b8b5917a4f6f06662e2262e8ffc51dff6d1 # v1.2.1 with: - # TODO(cookiecutter): Uncomment the following line for private repositories, otherwise remove it and remove it + # TODO(cookiecutter): Uncomment the following line for private repositories, otherwise remove it # token: ${{ secrets.github_token }} file-pattern: "RELEASE_NOTES.md" prereq-pattern: "{proto,py}/**" diff --git a/tests_golden/integration/test_cookiecutter_generation/api/frequenz-api-test/.gitmodules b/tests_golden/integration/test_cookiecutter_generation/api/frequenz-api-test/.gitmodules index a9766dec..b193b535 100644 --- a/tests_golden/integration/test_cookiecutter_generation/api/frequenz-api-test/.gitmodules +++ b/tests_golden/integration/test_cookiecutter_generation/api/frequenz-api-test/.gitmodules @@ -1,6 +1,3 @@ -[submodule "submodules/api-common-protos"] - path = submodules/api-common-protos - url = https://github.com/googleapis/api-common-protos.git [submodule "submodules/frequenz-api-common"] path = submodules/frequenz-api-common url = https://github.com/frequenz-floss/frequenz-api-common.git diff --git a/tests_golden/integration/test_cookiecutter_generation/api/frequenz-api-test/mkdocs.yml b/tests_golden/integration/test_cookiecutter_generation/api/frequenz-api-test/mkdocs.yml index bf29caff..f02aa9d9 100644 --- a/tests_golden/integration/test_cookiecutter_generation/api/frequenz-api-test/mkdocs.yml +++ b/tests_golden/integration/test_cookiecutter_generation/api/frequenz-api-test/mkdocs.yml @@ -8,9 +8,9 @@ site_author: "Frequenz Energy-as-a-Service GmbH" copyright: "Copyright © 2023 Frequenz Energy-as-a-Service GmbH" repo_name: "frequenz-api-test" repo_url: "https://github.com/frequenz-floss/frequenz-api-test" -# TODO(cookiecutter): "main" is the GitHub repo default branch, you might want to update it +# TODO(cookiecutter): "v0.x.x" is the GitHub repo default branch, you might want to update it # if the project uses a different default branch. -edit_uri: "edit/main/docs/" +edit_uri: "edit/v0.x.x/docs/" strict: true # Treat warnings as errors # Build directories @@ -120,7 +120,7 @@ plugins: # TODO(cookiecutter): You might want to add other external references here # See https://mkdocstrings.github.io/python/usage/#import for details - https://docs.python.org/3/objects.inv - - https://frequenz-floss.github.io/frequenz-api-common/v0.3/objects.inv + - https://frequenz-floss.github.io/frequenz-api-common/v0.6/objects.inv - https://grpc.github.io/grpc/python/objects.inv - https://typing-extensions.readthedocs.io/en/stable/objects.inv # Note this plugin must be loaded after mkdocstrings to be able to use macros diff --git a/tests_golden/integration/test_cookiecutter_generation/api/frequenz-api-test/pyproject.toml b/tests_golden/integration/test_cookiecutter_generation/api/frequenz-api-test/pyproject.toml index 1752cb1e..b399b89f 100644 --- a/tests_golden/integration/test_cookiecutter_generation/api/frequenz-api-test/pyproject.toml +++ b/tests_golden/integration/test_cookiecutter_generation/api/frequenz-api-test/pyproject.toml @@ -3,9 +3,16 @@ [build-system] requires = [ - "setuptools == 70.1.1", + "setuptools == 75.5.0", "setuptools_scm[toml] == 8.1.0", - "frequenz-repo-config[api] == 0.10.0", + "frequenz-repo-config[api] == 0.11.0", + # We need to pin the protobuf, grpcio and grpcio-tools dependencies to make + # sure the code is generated using the minimum supported versions, as older + # versions can't work with code that was generated with newer versions. + # https://protobuf.dev/support/cross-version-runtime-guarantee/#backwards + "protobuf == 5.28.0", + "grpcio-tools == 1.66.1", + "grpcio == 1.66.1", ] build-backend = "setuptools.build_meta" @@ -28,9 +35,15 @@ classifiers = [ requires-python = ">= 3.11, < 4" # TODO(cookiecutter): Remove and add more dependencies if appropriate dependencies = [ - "frequenz-api-common >= 0.5.0, < 0.6.0", - "googleapis-common-protos >= 1.56.2, < 2", - "grpcio >= 1.51.1, < 2", + "frequenz-api-common >= 0.6.2, < 0.7.0", + # We can't widen beyond the current value unless we bump the minimum + # requirements too because of protobuf cross-version runtime guarantees: + # https://protobuf.dev/support/cross-version-runtime-guarantee/#major + "protobuf >= 5.28.0, < 7", # Do not widen beyond 7! + # We couldn't find any document with a spec about the cross-version runtime + # guarantee for grpcio, so unless we find one in the future, we'll assume + # major version jumps are not compatible + "grpcio >= 1.66.1, < 2", # Do not widen beyond 2! ] dynamic = ["version"] @@ -41,35 +54,35 @@ email = "floss@frequenz.com" # TODO(cookiecutter): Remove and add more optional dependencies if appropriate [project.optional-dependencies] dev-flake8 = [ - "flake8 == 7.1.0", + "flake8 == 7.1.1", "flake8-docstrings == 1.7.0", "flake8-pyproject == 1.2.3", # For reading the flake8 config from pyproject.toml - "pydoclint == 0.5.3", + "pydoclint == 0.5.9", "pydocstyle == 6.3.0", ] -dev-formatting = ["black == 24.4.2", "isort == 5.13.2"] +dev-formatting = ["black == 24.10.0", "isort == 5.13.2"] dev-mkdocs = [ - "Markdown == 3.6.0", - "black == 24.4.2", - "mike == 2.1.2", + "Markdown == 3.7", + "black == 24.10.0", + "mike == 2.1.3", "mkdocs-gen-files == 0.5.0", "mkdocs-literate-nav == 0.6.1", - "mkdocs-macros-plugin == 1.0.5", - "mkdocs-material == 9.5.27", - "mkdocstrings[python] == 0.25.1", - "mkdocstrings-python == 1.10.5", - "frequenz-repo-config[api] == 0.10.0", + "mkdocs-macros-plugin == 1.3.7", + "mkdocs-material == 9.5.45", + "mkdocstrings[python] == 0.27.0", + "mkdocstrings-python == 1.12.2", + "frequenz-repo-config[api] == 0.11.0", ] dev-mypy = [ "mypy == 1.9.0", "grpc-stubs == 1.53.0.2", - "types-Markdown == 3.6.0.20240316", + "types-Markdown == 3.7.0.20240822", # For checking the noxfile, docs/ script, and tests "frequenz-api-test[dev-mkdocs,dev-noxfile,dev-pytest]", ] dev-noxfile = [ - "nox == 2024.4.15", - "frequenz-repo-config[api] == 0.10.0", + "nox == 2024.10.9", + "frequenz-repo-config[api] == 0.11.0", ] dev-pylint = [ # dev-pytest already defines a dependency to pylint because of the examples @@ -77,9 +90,9 @@ dev-pylint = [ "frequenz-api-test[dev-mkdocs,dev-noxfile,dev-pytest]", ] dev-pytest = [ - "pytest == 8.2.2", - "pylint == 3.2.5", # We need this to check for the examples - "frequenz-repo-config[extra-lint-examples] == 0.10.0", + "pytest == 8.3.3", + "pylint == 3.3.1", # We need this to check for the examples + "frequenz-repo-config[extra-lint-examples] == 0.11.0", ] dev = [ "frequenz-api-test[dev-mkdocs,dev-flake8,dev-formatting,dev-mkdocs,dev-mypy,dev-noxfile,dev-pylint,dev-pytest]", @@ -132,11 +145,11 @@ disable = [ # disabled because it conflicts with isort "wrong-import-order", "ungrouped-imports", - # pylint's unsubscriptable check is buggy and is not needed because - # it is a type-check, for which we already have mypy. + # Checked by mypy (and pylint is very flaky checking these) "unsubscriptable-object", - # Checked by mypy "no-member", + "no-name-in-module", + "possibly-used-before-assignment", # Checked by flake8 "f-string-without-interpolation", "line-too-long", diff --git a/tests_golden/integration/test_cookiecutter_generation/app/cookiecutter-stdout.txt b/tests_golden/integration/test_cookiecutter_generation/app/cookiecutter-stdout.txt index 02261522..8a5abb01 100644 --- a/tests_golden/integration/test_cookiecutter_generation/app/cookiecutter-stdout.txt +++ b/tests_golden/integration/test_cookiecutter_generation/app/cookiecutter-stdout.txt @@ -8,14 +8,14 @@ ./.github/workflows/ci.yaml: # TODO(cookiecutter): Uncomment this for projects with private dependencies ./.github/workflows/ci.yaml: # TODO(cookiecutter): Uncomment this for projects with private dependencies ./.github/workflows/ci.yaml: # TODO(cookiecutter): Uncomment this for projects with private dependencies -./.github/workflows/release-notes-check.yml: # TODO(cookiecutter): Uncomment the following line for private repositories, otherwise remove it and remove it +./.github/workflows/release-notes-check.yml: # TODO(cookiecutter): Uncomment the following line for private repositories, otherwise remove it ./CODEOWNERS:# TODO(cookiecutter): Add more specific code-owners, check if the default is correct ./README.md:TODO(cookiecutter): Improve the README file ./docs/_scripts/macros.py: # TODO(cookiecutter): Add any other macros, variables and filters here. ./mkdocs.yml: # TODO(cookiecutter): You might want to add other external references here ./mkdocs.yml: # TODO(cookiecutter): You might want to change the logo, the file is located in "docs/" ./mkdocs.yml: # TODO(cookiecutter): You probably want to update the social links -./mkdocs.yml:# TODO(cookiecutter): "main" is the GitHub repo default branch, you might want to update it +./mkdocs.yml:# TODO(cookiecutter): "v0.x.x" is the GitHub repo default branch, you might want to update it ./pyproject.toml:# TODO(cookiecutter): Remove and add more classifiers if appropriate ./pyproject.toml:# TODO(cookiecutter): Remove and add more dependencies if appropriate ./pyproject.toml:# TODO(cookiecutter): Remove and add more optional dependencies if appropriate diff --git a/tests_golden/integration/test_cookiecutter_generation/app/frequenz-app-test/.github/containers/test-installation/Dockerfile b/tests_golden/integration/test_cookiecutter_generation/app/frequenz-app-test/.github/containers/test-installation/Dockerfile index 6ca61423..d5e23993 100644 --- a/tests_golden/integration/test_cookiecutter_generation/app/frequenz-app-test/.github/containers/test-installation/Dockerfile +++ b/tests_golden/integration/test_cookiecutter_generation/app/frequenz-app-test/.github/containers/test-installation/Dockerfile @@ -3,7 +3,7 @@ # This Dockerfile is used to test the installation of the python package in # multiple platforms in the CI. It is not used to build the package itself. -FROM --platform=${TARGETPLATFORM} python:3.11-slim +FROM python:3.11-slim RUN apt-get update -y && \ apt-get install --no-install-recommends -y \ diff --git a/tests_golden/integration/test_cookiecutter_generation/app/frequenz-app-test/.github/dependabot.yml b/tests_golden/integration/test_cookiecutter_generation/app/frequenz-app-test/.github/dependabot.yml index 8978cb3c..23cd21b1 100644 --- a/tests_golden/integration/test_cookiecutter_generation/app/frequenz-app-test/.github/dependabot.yml +++ b/tests_golden/integration/test_cookiecutter_generation/app/frequenz-app-test/.github/dependabot.yml @@ -39,3 +39,11 @@ updates: labels: - "part:tooling" - "type:tech-debt" + groups: + compatible: + update-types: + - "minor" + - "patch" + artifacts: + patterns: + - "actions/*-artifact" diff --git a/tests_golden/integration/test_cookiecutter_generation/app/frequenz-app-test/.github/labeler.yml b/tests_golden/integration/test_cookiecutter_generation/app/frequenz-app-test/.github/labeler.yml index d8efb7a2..099fc309 100644 --- a/tests_golden/integration/test_cookiecutter_generation/app/frequenz-app-test/.github/labeler.yml +++ b/tests_golden/integration/test_cookiecutter_generation/app/frequenz-app-test/.github/labeler.yml @@ -26,7 +26,7 @@ # - changed-files: # - any-glob-to-any-file: # - "src/**/*.py" -# - all-glob-to-all-file: +# - all-globs-to-all-files: # - "!src/__init__.py" # # Please have in mind that that the part:xxx labels need to diff --git a/tests_golden/integration/test_cookiecutter_generation/app/frequenz-app-test/.github/workflows/release-notes-check.yml b/tests_golden/integration/test_cookiecutter_generation/app/frequenz-app-test/.github/workflows/release-notes-check.yml index 514a7a0e..9f7ee31b 100644 --- a/tests_golden/integration/test_cookiecutter_generation/app/frequenz-app-test/.github/workflows/release-notes-check.yml +++ b/tests_golden/integration/test_cookiecutter_generation/app/frequenz-app-test/.github/workflows/release-notes-check.yml @@ -24,7 +24,7 @@ jobs: if: github.event_name == 'pull_request' uses: brettcannon/check-for-changed-files@871d7b8b5917a4f6f06662e2262e8ffc51dff6d1 # v1.2.1 with: - # TODO(cookiecutter): Uncomment the following line for private repositories, otherwise remove it and remove it + # TODO(cookiecutter): Uncomment the following line for private repositories, otherwise remove it # token: ${{ secrets.github_token }} file-pattern: "RELEASE_NOTES.md" prereq-pattern: "src/**" diff --git a/tests_golden/integration/test_cookiecutter_generation/app/frequenz-app-test/mkdocs.yml b/tests_golden/integration/test_cookiecutter_generation/app/frequenz-app-test/mkdocs.yml index 8ce71a0c..c5bebc0b 100644 --- a/tests_golden/integration/test_cookiecutter_generation/app/frequenz-app-test/mkdocs.yml +++ b/tests_golden/integration/test_cookiecutter_generation/app/frequenz-app-test/mkdocs.yml @@ -8,9 +8,9 @@ site_author: "Frequenz Energy-as-a-Service GmbH" copyright: "Copyright © 2023 Frequenz Energy-as-a-Service GmbH" repo_name: "frequenz-app-test" repo_url: "https://github.com/frequenz-floss/frequenz-app-test" -# TODO(cookiecutter): "main" is the GitHub repo default branch, you might want to update it +# TODO(cookiecutter): "v0.x.x" is the GitHub repo default branch, you might want to update it # if the project uses a different default branch. -edit_uri: "edit/main/docs/" +edit_uri: "edit/v0.x.x/docs/" strict: true # Treat warnings as errors # Build directories @@ -120,8 +120,8 @@ plugins: # TODO(cookiecutter): You might want to add other external references here # See https://mkdocstrings.github.io/python/usage/#import for details - https://docs.python.org/3/objects.inv - - https://frequenz-floss.github.io/frequenz-channels-python/v0.16/objects.inv - - https://frequenz-floss.github.io/frequenz-sdk-python/v0.25/objects.inv + - https://frequenz-floss.github.io/frequenz-channels-python/v1/objects.inv + - https://frequenz-floss.github.io/frequenz-sdk-python/v1.0-pre/objects.inv - https://typing-extensions.readthedocs.io/en/stable/objects.inv # Note this plugin must be loaded after mkdocstrings to be able to use macros # inside docstrings. See the comment in `docs/_scripts/macros.py` for more diff --git a/tests_golden/integration/test_cookiecutter_generation/app/frequenz-app-test/pyproject.toml b/tests_golden/integration/test_cookiecutter_generation/app/frequenz-app-test/pyproject.toml index 454088dc..6f21a230 100644 --- a/tests_golden/integration/test_cookiecutter_generation/app/frequenz-app-test/pyproject.toml +++ b/tests_golden/integration/test_cookiecutter_generation/app/frequenz-app-test/pyproject.toml @@ -3,9 +3,9 @@ [build-system] requires = [ - "setuptools == 70.1.1", + "setuptools == 75.5.0", "setuptools_scm[toml] == 8.1.0", - "frequenz-repo-config[app] == 0.10.0", + "frequenz-repo-config[app] == 0.11.0", ] build-backend = "setuptools.build_meta" @@ -27,11 +27,11 @@ classifiers = [ requires-python = ">= 3.11, < 4" # TODO(cookiecutter): Remove and add more dependencies if appropriate dependencies = [ - "typing-extensions == 4.5.0", + "typing-extensions == 4.12.2", # Make sure to update the version for cross-referencing also in the # mkdocs.yml file when changing the version here (look for the config key # plugins.mkdocstrings.handlers.python.import) - "frequenz-sdk == 0.25.0", + "frequenz-sdk == 1.0.0rc1300", ] dynamic = ["version"] @@ -42,34 +42,34 @@ email = "floss@frequenz.com" # TODO(cookiecutter): Remove and add more optional dependencies if appropriate [project.optional-dependencies] dev-flake8 = [ - "flake8 == 7.1.0", + "flake8 == 7.1.1", "flake8-docstrings == 1.7.0", "flake8-pyproject == 1.2.3", # For reading the flake8 config from pyproject.toml - "pydoclint == 0.5.3", + "pydoclint == 0.5.9", "pydocstyle == 6.3.0", ] -dev-formatting = ["black == 24.4.2", "isort == 5.13.2"] +dev-formatting = ["black == 24.10.0", "isort == 5.13.2"] dev-mkdocs = [ - "Markdown == 3.6.0", - "black == 24.4.2", - "mike == 2.1.2", + "Markdown == 3.7", + "black == 24.10.0", + "mike == 2.1.3", "mkdocs-gen-files == 0.5.0", "mkdocs-literate-nav == 0.6.1", - "mkdocs-macros-plugin == 1.0.5", - "mkdocs-material == 9.5.27", - "mkdocstrings[python] == 0.25.1", - "mkdocstrings-python == 1.10.5", - "frequenz-repo-config[app] == 0.10.0", + "mkdocs-macros-plugin == 1.3.7", + "mkdocs-material == 9.5.45", + "mkdocstrings[python] == 0.27.0", + "mkdocstrings-python == 1.12.2", + "frequenz-repo-config[app] == 0.11.0", ] dev-mypy = [ "mypy == 1.9.0", - "types-Markdown == 3.6.0.20240316", + "types-Markdown == 3.7.0.20240822", # For checking the noxfile, docs/ script, and tests "frequenz-app-test[dev-mkdocs,dev-noxfile,dev-pytest]", ] dev-noxfile = [ - "nox == 2024.4.15", - "frequenz-repo-config[app] == 0.10.0", + "nox == 2024.10.9", + "frequenz-repo-config[app] == 0.11.0", ] dev-pylint = [ # dev-pytest already defines a dependency to pylint because of the examples @@ -77,11 +77,11 @@ dev-pylint = [ "frequenz-app-test[dev-mkdocs,dev-noxfile,dev-pytest]", ] dev-pytest = [ - "pytest == 8.2.2", - "pylint == 3.2.5", # We need this to check for the examples - "frequenz-repo-config[extra-lint-examples] == 0.10.0", + "pytest == 8.3.3", + "pylint == 3.3.1", # We need this to check for the examples + "frequenz-repo-config[extra-lint-examples] == 0.11.0", "pytest-mock == 3.14.0", - "pytest-asyncio == 0.23.7", + "pytest-asyncio == 0.24.0", "async-solipsism == 0.6", ] dev = [ @@ -136,11 +136,11 @@ disable = [ # disabled because it conflicts with isort "wrong-import-order", "ungrouped-imports", - # pylint's unsubscriptable check is buggy and is not needed because - # it is a type-check, for which we already have mypy. + # Checked by mypy (and pylint is very flaky checking these) "unsubscriptable-object", - # Checked by mypy "no-member", + "no-name-in-module", + "possibly-used-before-assignment", # Checked by flake8 "f-string-without-interpolation", "line-too-long", @@ -154,6 +154,7 @@ disable = [ [tool.pytest.ini_options] testpaths = ["tests", "src"] asyncio_mode = "auto" +asyncio_default_fixture_loop_scope = "function" required_plugins = ["pytest-asyncio", "pytest-mock"] [tool.mypy] diff --git a/tests_golden/integration/test_cookiecutter_generation/lib/cookiecutter-stdout.txt b/tests_golden/integration/test_cookiecutter_generation/lib/cookiecutter-stdout.txt index 36196456..77bc53b5 100644 --- a/tests_golden/integration/test_cookiecutter_generation/lib/cookiecutter-stdout.txt +++ b/tests_golden/integration/test_cookiecutter_generation/lib/cookiecutter-stdout.txt @@ -8,14 +8,14 @@ ./.github/workflows/ci.yaml: # TODO(cookiecutter): Uncomment this for projects with private dependencies ./.github/workflows/ci.yaml: # TODO(cookiecutter): Uncomment this for projects with private dependencies ./.github/workflows/ci.yaml: # TODO(cookiecutter): Uncomment this for projects with private dependencies -./.github/workflows/release-notes-check.yml: # TODO(cookiecutter): Uncomment the following line for private repositories, otherwise remove it and remove it +./.github/workflows/release-notes-check.yml: # TODO(cookiecutter): Uncomment the following line for private repositories, otherwise remove it ./CODEOWNERS:# TODO(cookiecutter): Add more specific code-owners, check if the default is correct ./README.md:TODO(cookiecutter): Improve the README file ./docs/_scripts/macros.py: # TODO(cookiecutter): Add any other macros, variables and filters here. ./mkdocs.yml: # TODO(cookiecutter): You might want to add other external references here ./mkdocs.yml: # TODO(cookiecutter): You might want to change the logo, the file is located in "docs/" ./mkdocs.yml: # TODO(cookiecutter): You probably want to update the social links -./mkdocs.yml:# TODO(cookiecutter): "main" is the GitHub repo default branch, you might want to update it +./mkdocs.yml:# TODO(cookiecutter): "v0.x.x" is the GitHub repo default branch, you might want to update it ./pyproject.toml:# TODO(cookiecutter): Remove and add more classifiers if appropriate ./pyproject.toml:# TODO(cookiecutter): Remove and add more dependencies if appropriate ./pyproject.toml:# TODO(cookiecutter): Remove and add more optional dependencies if appropriate diff --git a/tests_golden/integration/test_cookiecutter_generation/lib/frequenz-test-python/.github/containers/test-installation/Dockerfile b/tests_golden/integration/test_cookiecutter_generation/lib/frequenz-test-python/.github/containers/test-installation/Dockerfile index 6ca61423..d5e23993 100644 --- a/tests_golden/integration/test_cookiecutter_generation/lib/frequenz-test-python/.github/containers/test-installation/Dockerfile +++ b/tests_golden/integration/test_cookiecutter_generation/lib/frequenz-test-python/.github/containers/test-installation/Dockerfile @@ -3,7 +3,7 @@ # This Dockerfile is used to test the installation of the python package in # multiple platforms in the CI. It is not used to build the package itself. -FROM --platform=${TARGETPLATFORM} python:3.11-slim +FROM python:3.11-slim RUN apt-get update -y && \ apt-get install --no-install-recommends -y \ diff --git a/tests_golden/integration/test_cookiecutter_generation/lib/frequenz-test-python/.github/dependabot.yml b/tests_golden/integration/test_cookiecutter_generation/lib/frequenz-test-python/.github/dependabot.yml index 8978cb3c..23cd21b1 100644 --- a/tests_golden/integration/test_cookiecutter_generation/lib/frequenz-test-python/.github/dependabot.yml +++ b/tests_golden/integration/test_cookiecutter_generation/lib/frequenz-test-python/.github/dependabot.yml @@ -39,3 +39,11 @@ updates: labels: - "part:tooling" - "type:tech-debt" + groups: + compatible: + update-types: + - "minor" + - "patch" + artifacts: + patterns: + - "actions/*-artifact" diff --git a/tests_golden/integration/test_cookiecutter_generation/lib/frequenz-test-python/.github/labeler.yml b/tests_golden/integration/test_cookiecutter_generation/lib/frequenz-test-python/.github/labeler.yml index 05748ddb..1812ab8e 100644 --- a/tests_golden/integration/test_cookiecutter_generation/lib/frequenz-test-python/.github/labeler.yml +++ b/tests_golden/integration/test_cookiecutter_generation/lib/frequenz-test-python/.github/labeler.yml @@ -26,7 +26,7 @@ # - changed-files: # - any-glob-to-any-file: # - "src/**/*.py" -# - all-glob-to-all-file: +# - all-globs-to-all-files: # - "!src/__init__.py" # # Please have in mind that that the part:xxx labels need to diff --git a/tests_golden/integration/test_cookiecutter_generation/lib/frequenz-test-python/.github/workflows/release-notes-check.yml b/tests_golden/integration/test_cookiecutter_generation/lib/frequenz-test-python/.github/workflows/release-notes-check.yml index 514a7a0e..9f7ee31b 100644 --- a/tests_golden/integration/test_cookiecutter_generation/lib/frequenz-test-python/.github/workflows/release-notes-check.yml +++ b/tests_golden/integration/test_cookiecutter_generation/lib/frequenz-test-python/.github/workflows/release-notes-check.yml @@ -24,7 +24,7 @@ jobs: if: github.event_name == 'pull_request' uses: brettcannon/check-for-changed-files@871d7b8b5917a4f6f06662e2262e8ffc51dff6d1 # v1.2.1 with: - # TODO(cookiecutter): Uncomment the following line for private repositories, otherwise remove it and remove it + # TODO(cookiecutter): Uncomment the following line for private repositories, otherwise remove it # token: ${{ secrets.github_token }} file-pattern: "RELEASE_NOTES.md" prereq-pattern: "src/**" diff --git a/tests_golden/integration/test_cookiecutter_generation/lib/frequenz-test-python/mkdocs.yml b/tests_golden/integration/test_cookiecutter_generation/lib/frequenz-test-python/mkdocs.yml index fc4666b5..7e268f79 100644 --- a/tests_golden/integration/test_cookiecutter_generation/lib/frequenz-test-python/mkdocs.yml +++ b/tests_golden/integration/test_cookiecutter_generation/lib/frequenz-test-python/mkdocs.yml @@ -8,9 +8,9 @@ site_author: "Frequenz Energy-as-a-Service GmbH" copyright: "Copyright © 2023 Frequenz Energy-as-a-Service GmbH" repo_name: "frequenz-test-python" repo_url: "https://github.com/frequenz-floss/frequenz-test-python" -# TODO(cookiecutter): "main" is the GitHub repo default branch, you might want to update it +# TODO(cookiecutter): "v0.x.x" is the GitHub repo default branch, you might want to update it # if the project uses a different default branch. -edit_uri: "edit/main/docs/" +edit_uri: "edit/v0.x.x/docs/" strict: true # Treat warnings as errors # Build directories diff --git a/tests_golden/integration/test_cookiecutter_generation/lib/frequenz-test-python/pyproject.toml b/tests_golden/integration/test_cookiecutter_generation/lib/frequenz-test-python/pyproject.toml index 85bfa251..a2c6979b 100644 --- a/tests_golden/integration/test_cookiecutter_generation/lib/frequenz-test-python/pyproject.toml +++ b/tests_golden/integration/test_cookiecutter_generation/lib/frequenz-test-python/pyproject.toml @@ -3,9 +3,9 @@ [build-system] requires = [ - "setuptools == 70.1.1", + "setuptools == 75.5.0", "setuptools_scm[toml] == 8.1.0", - "frequenz-repo-config[lib] == 0.10.0", + "frequenz-repo-config[lib] == 0.11.0", ] build-backend = "setuptools.build_meta" @@ -28,7 +28,7 @@ classifiers = [ requires-python = ">= 3.11, < 4" # TODO(cookiecutter): Remove and add more dependencies if appropriate dependencies = [ - "typing-extensions >= 4.5.0, < 5", + "typing-extensions >= 4.12.2, < 5", ] dynamic = ["version"] @@ -39,34 +39,34 @@ email = "floss@frequenz.com" # TODO(cookiecutter): Remove and add more optional dependencies if appropriate [project.optional-dependencies] dev-flake8 = [ - "flake8 == 7.1.0", + "flake8 == 7.1.1", "flake8-docstrings == 1.7.0", "flake8-pyproject == 1.2.3", # For reading the flake8 config from pyproject.toml - "pydoclint == 0.5.3", + "pydoclint == 0.5.9", "pydocstyle == 6.3.0", ] -dev-formatting = ["black == 24.4.2", "isort == 5.13.2"] +dev-formatting = ["black == 24.10.0", "isort == 5.13.2"] dev-mkdocs = [ - "Markdown == 3.6.0", - "black == 24.4.2", - "mike == 2.1.2", + "Markdown == 3.7", + "black == 24.10.0", + "mike == 2.1.3", "mkdocs-gen-files == 0.5.0", "mkdocs-literate-nav == 0.6.1", - "mkdocs-macros-plugin == 1.0.5", - "mkdocs-material == 9.5.27", - "mkdocstrings[python] == 0.25.1", - "mkdocstrings-python == 1.10.5", - "frequenz-repo-config[lib] == 0.10.0", + "mkdocs-macros-plugin == 1.3.7", + "mkdocs-material == 9.5.45", + "mkdocstrings[python] == 0.27.0", + "mkdocstrings-python == 1.12.2", + "frequenz-repo-config[lib] == 0.11.0", ] dev-mypy = [ "mypy == 1.9.0", - "types-Markdown == 3.6.0.20240316", + "types-Markdown == 3.7.0.20240822", # For checking the noxfile, docs/ script, and tests "frequenz-test[dev-mkdocs,dev-noxfile,dev-pytest]", ] dev-noxfile = [ - "nox == 2024.4.15", - "frequenz-repo-config[lib] == 0.10.0", + "nox == 2024.10.9", + "frequenz-repo-config[lib] == 0.11.0", ] dev-pylint = [ # dev-pytest already defines a dependency to pylint because of the examples @@ -74,11 +74,11 @@ dev-pylint = [ "frequenz-test[dev-mkdocs,dev-noxfile,dev-pytest]", ] dev-pytest = [ - "pytest == 8.2.2", - "pylint == 3.2.5", # We need this to check for the examples - "frequenz-repo-config[extra-lint-examples] == 0.10.0", + "pytest == 8.3.3", + "pylint == 3.3.1", # We need this to check for the examples + "frequenz-repo-config[extra-lint-examples] == 0.11.0", "pytest-mock == 3.14.0", - "pytest-asyncio == 0.23.7", + "pytest-asyncio == 0.24.0", "async-solipsism == 0.6", ] dev = [ @@ -133,11 +133,11 @@ disable = [ # disabled because it conflicts with isort "wrong-import-order", "ungrouped-imports", - # pylint's unsubscriptable check is buggy and is not needed because - # it is a type-check, for which we already have mypy. + # Checked by mypy (and pylint is very flaky checking these) "unsubscriptable-object", - # Checked by mypy "no-member", + "no-name-in-module", + "possibly-used-before-assignment", # Checked by flake8 "f-string-without-interpolation", "line-too-long", @@ -151,6 +151,7 @@ disable = [ [tool.pytest.ini_options] testpaths = ["tests", "src"] asyncio_mode = "auto" +asyncio_default_fixture_loop_scope = "function" required_plugins = ["pytest-asyncio", "pytest-mock"] [tool.mypy] diff --git a/tests_golden/integration/test_cookiecutter_generation/model/cookiecutter-stdout.txt b/tests_golden/integration/test_cookiecutter_generation/model/cookiecutter-stdout.txt index 0669ae6d..0ba3358d 100644 --- a/tests_golden/integration/test_cookiecutter_generation/model/cookiecutter-stdout.txt +++ b/tests_golden/integration/test_cookiecutter_generation/model/cookiecutter-stdout.txt @@ -8,14 +8,14 @@ ./.github/workflows/ci.yaml: # TODO(cookiecutter): Uncomment this for projects with private dependencies ./.github/workflows/ci.yaml: # TODO(cookiecutter): Uncomment this for projects with private dependencies ./.github/workflows/ci.yaml: # TODO(cookiecutter): Uncomment this for projects with private dependencies -./.github/workflows/release-notes-check.yml: # TODO(cookiecutter): Uncomment the following line for private repositories, otherwise remove it and remove it +./.github/workflows/release-notes-check.yml: # TODO(cookiecutter): Uncomment the following line for private repositories, otherwise remove it ./CODEOWNERS:# TODO(cookiecutter): Add more specific code-owners, check if the default is correct ./README.md:TODO(cookiecutter): Improve the README file ./docs/_scripts/macros.py: # TODO(cookiecutter): Add any other macros, variables and filters here. ./mkdocs.yml: # TODO(cookiecutter): You might want to add other external references here ./mkdocs.yml: # TODO(cookiecutter): You might want to change the logo, the file is located in "docs/" ./mkdocs.yml: # TODO(cookiecutter): You probably want to update the social links -./mkdocs.yml:# TODO(cookiecutter): "main" is the GitHub repo default branch, you might want to update it +./mkdocs.yml:# TODO(cookiecutter): "v0.x.x" is the GitHub repo default branch, you might want to update it ./pyproject.toml:# TODO(cookiecutter): Remove and add more classifiers if appropriate ./pyproject.toml:# TODO(cookiecutter): Remove and add more dependencies if appropriate ./pyproject.toml:# TODO(cookiecutter): Remove and add more optional dependencies if appropriate diff --git a/tests_golden/integration/test_cookiecutter_generation/model/frequenz-model-test/.github/containers/test-installation/Dockerfile b/tests_golden/integration/test_cookiecutter_generation/model/frequenz-model-test/.github/containers/test-installation/Dockerfile index 6ca61423..d5e23993 100644 --- a/tests_golden/integration/test_cookiecutter_generation/model/frequenz-model-test/.github/containers/test-installation/Dockerfile +++ b/tests_golden/integration/test_cookiecutter_generation/model/frequenz-model-test/.github/containers/test-installation/Dockerfile @@ -3,7 +3,7 @@ # This Dockerfile is used to test the installation of the python package in # multiple platforms in the CI. It is not used to build the package itself. -FROM --platform=${TARGETPLATFORM} python:3.11-slim +FROM python:3.11-slim RUN apt-get update -y && \ apt-get install --no-install-recommends -y \ diff --git a/tests_golden/integration/test_cookiecutter_generation/model/frequenz-model-test/.github/dependabot.yml b/tests_golden/integration/test_cookiecutter_generation/model/frequenz-model-test/.github/dependabot.yml index 8978cb3c..23cd21b1 100644 --- a/tests_golden/integration/test_cookiecutter_generation/model/frequenz-model-test/.github/dependabot.yml +++ b/tests_golden/integration/test_cookiecutter_generation/model/frequenz-model-test/.github/dependabot.yml @@ -39,3 +39,11 @@ updates: labels: - "part:tooling" - "type:tech-debt" + groups: + compatible: + update-types: + - "minor" + - "patch" + artifacts: + patterns: + - "actions/*-artifact" diff --git a/tests_golden/integration/test_cookiecutter_generation/model/frequenz-model-test/.github/labeler.yml b/tests_golden/integration/test_cookiecutter_generation/model/frequenz-model-test/.github/labeler.yml index b2041fa3..57166837 100644 --- a/tests_golden/integration/test_cookiecutter_generation/model/frequenz-model-test/.github/labeler.yml +++ b/tests_golden/integration/test_cookiecutter_generation/model/frequenz-model-test/.github/labeler.yml @@ -26,7 +26,7 @@ # - changed-files: # - any-glob-to-any-file: # - "src/**/*.py" -# - all-glob-to-all-file: +# - all-globs-to-all-files: # - "!src/__init__.py" # # Please have in mind that that the part:xxx labels need to diff --git a/tests_golden/integration/test_cookiecutter_generation/model/frequenz-model-test/.github/workflows/release-notes-check.yml b/tests_golden/integration/test_cookiecutter_generation/model/frequenz-model-test/.github/workflows/release-notes-check.yml index 514a7a0e..9f7ee31b 100644 --- a/tests_golden/integration/test_cookiecutter_generation/model/frequenz-model-test/.github/workflows/release-notes-check.yml +++ b/tests_golden/integration/test_cookiecutter_generation/model/frequenz-model-test/.github/workflows/release-notes-check.yml @@ -24,7 +24,7 @@ jobs: if: github.event_name == 'pull_request' uses: brettcannon/check-for-changed-files@871d7b8b5917a4f6f06662e2262e8ffc51dff6d1 # v1.2.1 with: - # TODO(cookiecutter): Uncomment the following line for private repositories, otherwise remove it and remove it + # TODO(cookiecutter): Uncomment the following line for private repositories, otherwise remove it # token: ${{ secrets.github_token }} file-pattern: "RELEASE_NOTES.md" prereq-pattern: "src/**" diff --git a/tests_golden/integration/test_cookiecutter_generation/model/frequenz-model-test/mkdocs.yml b/tests_golden/integration/test_cookiecutter_generation/model/frequenz-model-test/mkdocs.yml index 82aabe9b..d7d1a203 100644 --- a/tests_golden/integration/test_cookiecutter_generation/model/frequenz-model-test/mkdocs.yml +++ b/tests_golden/integration/test_cookiecutter_generation/model/frequenz-model-test/mkdocs.yml @@ -8,9 +8,9 @@ site_author: "Frequenz Energy-as-a-Service GmbH" copyright: "Copyright © 2023 Frequenz Energy-as-a-Service GmbH" repo_name: "frequenz-model-test" repo_url: "https://github.com/frequenz-floss/frequenz-model-test" -# TODO(cookiecutter): "main" is the GitHub repo default branch, you might want to update it +# TODO(cookiecutter): "v0.x.x" is the GitHub repo default branch, you might want to update it # if the project uses a different default branch. -edit_uri: "edit/main/docs/" +edit_uri: "edit/v0.x.x/docs/" strict: true # Treat warnings as errors # Build directories @@ -120,8 +120,8 @@ plugins: # TODO(cookiecutter): You might want to add other external references here # See https://mkdocstrings.github.io/python/usage/#import for details - https://docs.python.org/3/objects.inv - - https://frequenz-floss.github.io/frequenz-channels-python/v0.16/objects.inv - - https://frequenz-floss.github.io/frequenz-sdk-python/v0.25/objects.inv + - https://frequenz-floss.github.io/frequenz-channels-python/v1/objects.inv + - https://frequenz-floss.github.io/frequenz-sdk-python/v1.0-pre/objects.inv - https://typing-extensions.readthedocs.io/en/stable/objects.inv # Note this plugin must be loaded after mkdocstrings to be able to use macros # inside docstrings. See the comment in `docs/_scripts/macros.py` for more diff --git a/tests_golden/integration/test_cookiecutter_generation/model/frequenz-model-test/pyproject.toml b/tests_golden/integration/test_cookiecutter_generation/model/frequenz-model-test/pyproject.toml index b481d163..6e4410d0 100644 --- a/tests_golden/integration/test_cookiecutter_generation/model/frequenz-model-test/pyproject.toml +++ b/tests_golden/integration/test_cookiecutter_generation/model/frequenz-model-test/pyproject.toml @@ -3,9 +3,9 @@ [build-system] requires = [ - "setuptools == 70.1.1", + "setuptools == 75.5.0", "setuptools_scm[toml] == 8.1.0", - "frequenz-repo-config[model] == 0.10.0", + "frequenz-repo-config[model] == 0.11.0", ] build-backend = "setuptools.build_meta" @@ -28,11 +28,11 @@ classifiers = [ requires-python = ">= 3.11, < 4" # TODO(cookiecutter): Remove and add more dependencies if appropriate dependencies = [ - "typing-extensions == 4.5.0", + "typing-extensions >= 4.12.2, < 5", # Make sure to update the version for cross-referencing also in the # mkdocs.yml file when changing the version here (look for the config key # plugins.mkdocstrings.handlers.python.import) - "frequenz-sdk == 0.25.0", + "frequenz-sdk >= 1.0.0rc1300, < 1.0.0rc1400", ] dynamic = ["version"] @@ -43,34 +43,34 @@ email = "floss@frequenz.com" # TODO(cookiecutter): Remove and add more optional dependencies if appropriate [project.optional-dependencies] dev-flake8 = [ - "flake8 == 7.1.0", + "flake8 == 7.1.1", "flake8-docstrings == 1.7.0", "flake8-pyproject == 1.2.3", # For reading the flake8 config from pyproject.toml - "pydoclint == 0.5.3", + "pydoclint == 0.5.9", "pydocstyle == 6.3.0", ] -dev-formatting = ["black == 24.4.2", "isort == 5.13.2"] +dev-formatting = ["black == 24.10.0", "isort == 5.13.2"] dev-mkdocs = [ - "Markdown == 3.6.0", - "black == 24.4.2", - "mike == 2.1.2", + "Markdown == 3.7", + "black == 24.10.0", + "mike == 2.1.3", "mkdocs-gen-files == 0.5.0", "mkdocs-literate-nav == 0.6.1", - "mkdocs-macros-plugin == 1.0.5", - "mkdocs-material == 9.5.27", - "mkdocstrings[python] == 0.25.1", - "mkdocstrings-python == 1.10.5", - "frequenz-repo-config[model] == 0.10.0", + "mkdocs-macros-plugin == 1.3.7", + "mkdocs-material == 9.5.45", + "mkdocstrings[python] == 0.27.0", + "mkdocstrings-python == 1.12.2", + "frequenz-repo-config[model] == 0.11.0", ] dev-mypy = [ "mypy == 1.9.0", - "types-Markdown == 3.6.0.20240316", + "types-Markdown == 3.7.0.20240822", # For checking the noxfile, docs/ script, and tests "frequenz-model-test[dev-mkdocs,dev-noxfile,dev-pytest]", ] dev-noxfile = [ - "nox == 2024.4.15", - "frequenz-repo-config[model] == 0.10.0", + "nox == 2024.10.9", + "frequenz-repo-config[model] == 0.11.0", ] dev-pylint = [ # dev-pytest already defines a dependency to pylint because of the examples @@ -78,11 +78,11 @@ dev-pylint = [ "frequenz-model-test[dev-mkdocs,dev-noxfile,dev-pytest]", ] dev-pytest = [ - "pytest == 8.2.2", - "pylint == 3.2.5", # We need this to check for the examples - "frequenz-repo-config[extra-lint-examples] == 0.10.0", + "pytest == 8.3.3", + "pylint == 3.3.1", # We need this to check for the examples + "frequenz-repo-config[extra-lint-examples] == 0.11.0", "pytest-mock == 3.14.0", - "pytest-asyncio == 0.23.7", + "pytest-asyncio == 0.24.0", "async-solipsism == 0.6", ] dev = [ @@ -137,11 +137,11 @@ disable = [ # disabled because it conflicts with isort "wrong-import-order", "ungrouped-imports", - # pylint's unsubscriptable check is buggy and is not needed because - # it is a type-check, for which we already have mypy. + # Checked by mypy (and pylint is very flaky checking these) "unsubscriptable-object", - # Checked by mypy "no-member", + "no-name-in-module", + "possibly-used-before-assignment", # Checked by flake8 "f-string-without-interpolation", "line-too-long", @@ -155,6 +155,7 @@ disable = [ [tool.pytest.ini_options] testpaths = ["tests", "src"] asyncio_mode = "auto" +asyncio_default_fixture_loop_scope = "function" required_plugins = ["pytest-asyncio", "pytest-mock"] [tool.mypy]