From d2b09047c54be8cf768c2d0f89a995f7923335dc Mon Sep 17 00:00:00 2001 From: pulpbot Date: Sun, 11 Oct 2026 11:40:02 +0000 Subject: [PATCH] Update cookiecutter --- .ci/scripts/check_changelog_snippets.py | 36 +++++++++++++++++++++++++ .ci/scripts/pr_labels.py | 2 +- .ci/scripts/release.sh | 2 +- .ci/scripts/validate_commit_message.py | 6 +++-- .github/workflows/build.yml | 10 +++++-- .github/workflows/codeql.yml | 9 ++++--- .github/workflows/collect_changes.yml | 12 +++++++-- .github/workflows/cookiecutter.yml | 32 +++++++++++++--------- .github/workflows/lint.yml | 6 +++++ .github/workflows/nightly.yml | 10 +++++-- .github/workflows/pr.yml | 8 +++++- .github/workflows/pr_checks.yml | 11 +++++--- .github/workflows/publish.yml | 21 +++++++-------- .github/workflows/release.yml | 12 +++++++-- .github/workflows/release_branch.yml | 16 ++++++++--- .github/workflows/test.yml | 6 +++++ Makefile | 3 +++ pyproject.toml | 2 +- 18 files changed, 158 insertions(+), 46 deletions(-) create mode 100755 .ci/scripts/check_changelog_snippets.py diff --git a/.ci/scripts/check_changelog_snippets.py b/.ci/scripts/check_changelog_snippets.py new file mode 100755 index 0000000..7c69b1b --- /dev/null +++ b/.ci/scripts/check_changelog_snippets.py @@ -0,0 +1,36 @@ +#!/bin/env python3 +# /// script +# requires-python = ">=3.11" +# dependencies = [ +# ] +# /// +import re +import sys +from pathlib import Path + +import tomllib + +EXCEPTIONS = [ + ".TEMPLATE.md", + ".gitkeep", + "pulp-glue-workflow", +] + + +def snippet_valid(path: Path, changelog_exts: list[str]) -> bool: + return (path.name in EXCEPTIONS) or ( + path.suffix in changelog_exts + and (path.stem.startswith("+") or re.fullmatch(r"\d*", path.stem)) + ) + + +if __name__ == "__main__": + with Path("pyproject.toml").open("rb") as fp: + pyproject_toml = tomllib.load(fp) + changelog_exts = [ + f".{item['directory']}" for item in pyproject_toml["tool"]["towncrier"]["type"] + ] + matches = Path("CHANGES").rglob("*") + invalid_snippets = ", ".join(f"'{s}'" for s in matches if not snippet_valid(s, changelog_exts)) + if invalid_snippets: + sys.exit(f"LINT: Invalid changelog entries: {invalid_snippets}.") diff --git a/.ci/scripts/pr_labels.py b/.ci/scripts/pr_labels.py index b2350b6..2144815 100755 --- a/.ci/scripts/pr_labels.py +++ b/.ci/scripts/pr_labels.py @@ -16,7 +16,7 @@ from git import Repo -def main(): +def main() -> None: assert len(sys.argv) == 3 with Path("pyproject.toml").open("rb") as fp: diff --git a/.ci/scripts/release.sh b/.ci/scripts/release.sh index a9c3644..41d2677 100755 --- a/.ci/scripts/release.sh +++ b/.ci/scripts/release.sh @@ -23,4 +23,4 @@ towncrier build --yes --version "${NEW_VERSION}" bump-my-version bump release --commit --message "Release {new_version}" --tag --tag-name "{new_version}" --tag-message "Release {new_version}" --allow-dirty bump-my-version bump patch --commit -git push origin "${BRANCH}" "${NEW_VERSION}" +git push --atomic origin "${BRANCH}" "${NEW_VERSION}" diff --git a/.ci/scripts/validate_commit_message.py b/.ci/scripts/validate_commit_message.py index 04fc613..651f68c 100644 --- a/.ci/scripts/validate_commit_message.py +++ b/.ci/scripts/validate_commit_message.py @@ -62,7 +62,9 @@ def check_changelog(issue: str) -> None: print(f"Checking commit message for {sha[0:7]}.") # validate the issue attached to the commit -issue_regex = r"(?:{keywords})[\s:]+#(\d+)".format(keywords=("|").join(KEYWORDS)) +issue_regex = r"(?:{keywords})[\s:]+#(\d+)".format( + keywords=("|").join(re.escape(k) for k in KEYWORDS) +) issues = re.findall(issue_regex, message, re.IGNORECASE) cherry_pick_regex = r"^\s*\(cherry picked from commit [0-9a-f]*\)\s*$" cherry_pick = re.search(cherry_pick_regex, message, re.MULTILINE) @@ -70,7 +72,7 @@ def check_changelog(issue: str) -> None: if issues: for issue in issues: if not cherry_pick: - check_status(issue) check_changelog(issue) + check_status(issue) print(f"Commit message for {sha[0:7]} passed.") diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d7c6a4b..6ee413f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -4,12 +4,18 @@ name: "Build" on: workflow_call: +defaults: + run: + working-directory: "pulp-cli-workflow" + jobs: build: runs-on: "ubuntu-latest" steps: - name: "Checkout" uses: "actions/checkout@v6" + with: + path: "pulp-cli-workflow" - name: "Set up Python" uses: "actions/setup-python@v6" with: @@ -22,14 +28,14 @@ jobs: - name: "Build wheels" run: | make build - touch .root + touch ../.root - name: "Upload wheels" uses: "actions/upload-artifact@v6" with: name: "pulp_cli_packages" path: | .root - dist/ + pulp-cli-workflow/dist/ if-no-files-found: "error" retention-days: 5 ... diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index facb1a8..ef13f56 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -2,11 +2,12 @@ name: "CodeQL" on: - push: - branches: - - "main" workflow_call: +defaults: + run: + working-directory: "pulp-cli-workflow" + jobs: analyze: name: "Analyze" @@ -19,6 +20,8 @@ jobs: steps: - name: "Checkout" uses: "actions/checkout@v6" + with: + path: "pulp-cli-workflow" - name: "Initialize CodeQL" uses: "github/codeql-action/init@v4" with: diff --git a/.github/workflows/collect_changes.yml b/.github/workflows/collect_changes.yml index 5e08242..bc6b50e 100644 --- a/.github/workflows/collect_changes.yml +++ b/.github/workflows/collect_changes.yml @@ -4,13 +4,21 @@ on: workflow_call: workflow_dispatch: +defaults: + run: + working-directory: "pulp-cli-workflow" + jobs: collect-changes: + permissions: + contents: "write" + pull-requests: "write" runs-on: "ubuntu-latest" steps: - name: "Checkout" uses: "actions/checkout@v6" with: + path: "pulp-cli-workflow" fetch-depth: 0 - name: "Set up Python" uses: "actions/setup-python@v6" @@ -32,16 +40,16 @@ jobs: uses: "peter-evans/create-pull-request@v8" id: "create_pr" with: - token: "${{ secrets.RELEASE_TOKEN }}" title: "Update Changelog" body: "" branch: "update_changes" delete-branch: true + path: "pulp-cli-workflow" - name: "Mark PR automerge" run: | gh pr merge --rebase --auto "${{ steps.create_pr.outputs.pull-request-number }}" if: "steps.create_pr.outputs.pull-request-number" env: - GH_TOKEN: "${{ secrets.RELEASE_TOKEN }}" + GH_TOKEN: "${{ secrets.GITHUB_TOKEN }}" continue-on-error: true ... diff --git a/.github/workflows/cookiecutter.yml b/.github/workflows/cookiecutter.yml index 3e08012..24475ce 100644 --- a/.github/workflows/cookiecutter.yml +++ b/.github/workflows/cookiecutter.yml @@ -11,16 +11,21 @@ defaults: jobs: update-ci: + permissions: + contents: "write" + pull-requests: "write" runs-on: "ubuntu-latest" steps: - uses: "actions/checkout@v6" with: repository: "pulp/pulp-cli" - path: "pulp-cli" - - uses: "actions/checkout@v6" + ref: "main" + path: "pulp-cli_cc" + - name: "Checkout" + uses: "actions/checkout@v6" with: - token: "${{ secrets.RELEASE_TOKEN }}" path: "pulp-cli-workflow" + token: "${{ secrets.RELEASE_TOKEN }}" - name: "Set up Python" uses: "actions/setup-python@v6" with: @@ -36,7 +41,7 @@ jobs: git config user.email pulp-infra@redhat.com - name: "Apply cookiecutter templates" run: | - uv run ../pulp-cli/cookiecutter/apply_templates.py + uv run ../pulp-cli_cc/cookiecutter/apply_templates.py if [ "$(git status --porcelain)" ] then git add . @@ -46,29 +51,33 @@ jobs: uses: "peter-evans/create-pull-request@v8" id: "create_pr" with: - token: "${{ secrets.RELEASE_TOKEN }}" title: "Update cookiecutter" body: "" branch: "update_cookiecutter" delete-branch: true path: "pulp-cli-workflow" + token: "${{ secrets.RELEASE_TOKEN }}" - name: "Mark PR automerge" run: | gh pr merge --rebase --auto "${{ steps.create_pr.outputs.pull-request-number }}" if: "steps.create_pr.outputs.pull-request-number" env: - GH_TOKEN: "${{ secrets.RELEASE_TOKEN }}" + GH_TOKEN: "${{ secrets.GITHUB_TOKEN }}" continue-on-error: true update-dependencies: + permissions: + contents: "write" + pull-requests: "write" runs-on: "ubuntu-latest" steps: - uses: "actions/checkout@v6" with: repository: "pulp/pulp-cli" - path: "pulp-cli" - - uses: "actions/checkout@v6" + branch: "main" + path: "pulp-cli_cc" + - name: "Checkout" + uses: "actions/checkout@v6" with: - token: "${{ secrets.RELEASE_TOKEN }}" path: "pulp-cli-workflow" - name: "Set up Python" uses: "actions/setup-python@v6" @@ -85,7 +94,7 @@ jobs: git config user.email pulp-infra@redhat.com - name: "Apply cookiecutter templates" run: | - uv run ../pulp-cli/cookiecutter/update_pulp_cli.py + uv run ../pulp-cli_cc/cookiecutter/update_pulp_cli.py if [ "$(git status --porcelain)" ] then git add . @@ -95,7 +104,6 @@ jobs: uses: "peter-evans/create-pull-request@v8" id: "create_pr" with: - token: "${{ secrets.RELEASE_TOKEN }}" title: "Update CLI and GLUE" body: "" branch: "update_cli" @@ -106,6 +114,6 @@ jobs: gh pr merge --rebase --auto "${{ steps.create_pr.outputs.pull-request-number }}" if: "steps.create_pr.outputs.pull-request-number" env: - GH_TOKEN: "${{ secrets.RELEASE_TOKEN }}" + GH_TOKEN: "${{ secrets.GITHUB_TOKEN }}" continue-on-error: true ... diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index fee95cd..7ccd989 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -4,6 +4,10 @@ name: "Lint" on: workflow_call: +defaults: + run: + working-directory: "pulp-cli-workflow" + jobs: lint: runs-on: "ubuntu-latest" @@ -16,6 +20,8 @@ jobs: steps: - name: "Checkout" uses: "actions/checkout@v6" + with: + path: "pulp-cli-workflow" - name: "Set up Python" uses: "actions/setup-python@v6" with: diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index cf39225..8ec5b26 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -1,5 +1,5 @@ --- -name: "pulp-cli Nightly" +name: "Nightly" on: schedule: @@ -14,8 +14,14 @@ jobs: - "build" uses: "./.github/workflows/test.yml" codeql: + permissions: + actions: "read" + contents: "read" + security-events: "write" uses: "./.github/workflows/codeql.yml" collect_changes: + permissions: + contents: "write" + pull-requests: "write" uses: "./.github/workflows/collect_changes.yml" - secrets: "inherit" ... diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 5617875..6489518 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -1,5 +1,5 @@ --- -name: "pulp-cli CI" +name: "Pull Request" on: pull_request: @@ -22,6 +22,10 @@ jobs: codeql: needs: - "lint" + permissions: + actions: "read" + contents: "read" + security-events: "write" uses: "./.github/workflows/codeql.yml" check-commits: runs-on: "ubuntu-latest" @@ -29,6 +33,7 @@ jobs: - name: "Checkout" uses: "actions/checkout@v6" with: + path: "pulp-cli-workflow" fetch-depth: 0 - name: "Set up Python" uses: "actions/setup-python@v6" @@ -53,6 +58,7 @@ jobs: fi done shell: "bash" + working-directory: "pulp-cli-workflow" ready-to-ship: # This is a dummy dependent task to have a single entry for the branch protection rules. runs-on: "ubuntu-latest" diff --git a/.github/workflows/pr_checks.yml b/.github/workflows/pr_checks.yml index c031756..29e84d8 100644 --- a/.github/workflows/pr_checks.yml +++ b/.github/workflows/pr_checks.yml @@ -1,5 +1,5 @@ --- -name: "Pulp CLI PR static checks" +name: "PR static checks" on: pull_request_target: types: ["opened", "synchronize", "reopened"] @@ -12,16 +12,21 @@ concurrency: group: "${{ github.event.pull_request.number }}-${{ github.workflow }}" cancel-in-progress: true +defaults: + run: + working-directory: "pulp-cli-workflow" + jobs: apply_labels: - runs-on: "ubuntu-latest" - name: "Label PR" permissions: pull-requests: "write" + runs-on: "ubuntu-latest" + name: "Label PR" steps: - name: "Checkout" uses: "actions/checkout@v6" with: + path: "pulp-cli-workflow" fetch-depth: 0 - name: "Set up Python" uses: "actions/setup-python@v6" diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 9256150..9524170 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -1,11 +1,15 @@ --- -name: "pulp-cli Publish" +name: "Publish" on: push: tags: - "[0-9]+.[0-9]+.[0-9]+" +defaults: + run: + working-directory: "pulp-cli-workflow" + jobs: build: uses: "./.github/workflows/build.yml" @@ -13,25 +17,20 @@ jobs: name: "Publish to PyPI" needs: "build" runs-on: "ubuntu-latest" + environment: + name: "pypi" + permissions: + id-token: "write" steps: - - name: "Checkout" - uses: "actions/checkout@v6" - name: "Download wheels" uses: "actions/download-artifact@v8" with: name: "pulp_cli_packages" - - name: "Set up Python" - uses: "actions/setup-python@v6" - with: - python-version: "3.14" - allow-prereleases: true - name: "Install uv" uses: "astral-sh/setup-uv@v7" with: - enable-cache: true + enable-cache: false - name: "Publish" - env: - UV_PUBLISH_TOKEN: "${{ secrets.PYPI_API_TOKEN }}" run: | uv publish ... diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index bda5708..35f4fab 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,16 +1,24 @@ --- -name: "pulp-cli Release" +name: "Tag Release" on: workflow_dispatch: +defaults: + run: + working-directory: "pulp-cli-workflow" + jobs: release: name: "Release" + permissions: + contents: "write" runs-on: "ubuntu-latest" steps: - - uses: "actions/checkout@v6" + - name: "Checkout" + uses: "actions/checkout@v6" with: + path: "pulp-cli-workflow" token: "${{ secrets.RELEASE_TOKEN }}" - name: "Set up Python" uses: "actions/setup-python@v6" diff --git a/.github/workflows/release_branch.yml b/.github/workflows/release_branch.yml index f20a5ef..799eb26 100644 --- a/.github/workflows/release_branch.yml +++ b/.github/workflows/release_branch.yml @@ -3,12 +3,22 @@ name: "Create Release Branch" on: workflow_dispatch: +defaults: + run: + working-directory: "pulp-cli-workflow" + jobs: create-release-branch: + permissions: + contents: "write" + issues: "write" + pull-requests: "write" runs-on: "ubuntu-latest" steps: - - uses: "actions/checkout@v6" + - name: "Checkout" + uses: "actions/checkout@v6" with: + path: "pulp-cli-workflow" token: "${{ secrets.RELEASE_TOKEN }}" - name: "Set up Python" uses: "actions/setup-python@v6" @@ -30,17 +40,17 @@ jobs: uses: "peter-evans/create-pull-request@v8" id: "create_pr" with: - token: "${{ secrets.RELEASE_TOKEN }}" title: "Bump dev-version" body: "" branch: "bump_version" delete-branch: true + path: "pulp-cli-workflow" - name: "Mark PR automerge" run: | gh pr merge --rebase --auto "${{ steps.create_pr.outputs.pull-request-number }}" if: "steps.create_pr.outputs.pull-request-number" env: - GH_TOKEN: "${{ secrets.RELEASE_TOKEN }}" + GH_TOKEN: "${{ secrets.GITHUB_TOKEN }}" continue-on-error: true - name: "Add Backport Label for new Branch" uses: "actions/github-script@v8" diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3ba1a05..98e033c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -4,6 +4,10 @@ name: "Test" on: workflow_call: +defaults: + run: + working-directory: "pulp-cli-workflow" + env: COLORTERM: "yes" TERM: "xterm-256color" @@ -30,6 +34,8 @@ jobs: steps: - name: "Checkout" uses: "actions/checkout@v6" + with: + path: "pulp-cli-workflow" - name: "Download wheels" uses: "actions/download-artifact@v8" with: diff --git a/Makefile b/Makefile index 9167725..284411e 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,6 @@ +# This file is managed by the cookiecutter templates. +# Do not edit manually GLUE_PLUGINS=$(notdir $(wildcard pulp-glue-workflow/src/pulp_glue/*)) CLI_PLUGINS=$(notdir $(wildcard src/pulpcore/cli/*)) @@ -36,6 +38,7 @@ _lint: ruff format --check --diff ruff check --output-format concise .ci/scripts/check_cli_dependencies.py + .ci/scripts/check_changelog_snippets.py .ci/scripts/check_click_for_mypy.py mypy cd pulp-glue-workflow; mypy diff --git a/pyproject.toml b/pyproject.toml index 8da1974..394119d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -229,7 +229,7 @@ dev = [ ] lint = [ {include-group = "test"}, - "mypy~=1.20.0", + "mypy~=2.4.0", "ruff~=0.16.0", "shellcheck-py~=0.11.0.1", "types-pygments",