pyproject-api 1.12.2__tar.gz → 1.12.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. pyproject_api-1.12.4/.github/SECURITY.md +51 -0
  2. pyproject_api-1.12.4/.github/THREAT_MODEL.md +101 -0
  3. pyproject_api-1.12.4/.github/workflows/check.yaml +59 -0
  4. pyproject_api-1.12.4/.github/workflows/codeql.yaml +22 -0
  5. {pyproject_api-1.12.2 → pyproject_api-1.12.4}/.github/workflows/news.yaml +3 -6
  6. {pyproject_api-1.12.2 → pyproject_api-1.12.4}/.github/workflows/prepare-release.yaml +1 -1
  7. pyproject_api-1.12.4/.github/workflows/release.yaml +56 -0
  8. pyproject_api-1.12.4/.github/workflows/scorecard.yaml +26 -0
  9. {pyproject_api-1.12.2 → pyproject_api-1.12.4}/.github/workflows/upgrade-release-tools.yaml +1 -1
  10. {pyproject_api-1.12.2 → pyproject_api-1.12.4}/.pre-commit-config.yaml +3 -3
  11. {pyproject_api-1.12.2 → pyproject_api-1.12.4}/PKG-INFO +7 -6
  12. pyproject_api-1.12.4/README.md +11 -0
  13. {pyproject_api-1.12.2 → pyproject_api-1.12.4}/docs/changelog.rst +18 -0
  14. {pyproject_api-1.12.2 → pyproject_api-1.12.4}/pylock.toml +204 -205
  15. {pyproject_api-1.12.2 → pyproject_api-1.12.4}/pyproject.toml +6 -5
  16. {pyproject_api-1.12.2 → pyproject_api-1.12.4}/src/pyproject_api/_frontend.py +9 -3
  17. {pyproject_api-1.12.2 → pyproject_api-1.12.4}/src/pyproject_api/_version.py +2 -2
  18. {pyproject_api-1.12.2 → pyproject_api-1.12.4}/tests/test_frontend.py +37 -0
  19. pyproject_api-1.12.2/.github/SECURITY.md +0 -9
  20. pyproject_api-1.12.2/.github/workflows/check.yaml +0 -83
  21. pyproject_api-1.12.2/.github/workflows/codeql.yaml +0 -41
  22. pyproject_api-1.12.2/.github/workflows/release.yaml +0 -118
  23. pyproject_api-1.12.2/README.md +0 -10
  24. {pyproject_api-1.12.2 → pyproject_api-1.12.4}/.github/FUNDING.yaml +0 -0
  25. {pyproject_api-1.12.2 → pyproject_api-1.12.4}/.github/dependabot.yaml +0 -0
  26. {pyproject_api-1.12.2 → pyproject_api-1.12.4}/.github/release.yaml +0 -0
  27. {pyproject_api-1.12.2 → pyproject_api-1.12.4}/.gitignore +0 -0
  28. {pyproject_api-1.12.2 → pyproject_api-1.12.4}/.readthedocs.yml +0 -0
  29. {pyproject_api-1.12.2 → pyproject_api-1.12.4}/CODE_OF_CONDUCT.md +0 -0
  30. {pyproject_api-1.12.2 → pyproject_api-1.12.4}/CONTRIBUTING.md +0 -0
  31. {pyproject_api-1.12.2 → pyproject_api-1.12.4}/LICENSE +0 -0
  32. {pyproject_api-1.12.2 → pyproject_api-1.12.4}/docs/api.rst +0 -0
  33. {pyproject_api-1.12.2 → pyproject_api-1.12.4}/docs/changelog.d/.gitkeep +0 -0
  34. {pyproject_api-1.12.2 → pyproject_api-1.12.4}/docs/changelog.d/template.jinja2 +0 -0
  35. {pyproject_api-1.12.2 → pyproject_api-1.12.4}/docs/conf.py +0 -0
  36. {pyproject_api-1.12.2 → pyproject_api-1.12.4}/docs/contributing.rst +0 -0
  37. {pyproject_api-1.12.2 → pyproject_api-1.12.4}/docs/index.rst +0 -0
  38. {pyproject_api-1.12.2 → pyproject_api-1.12.4}/src/pyproject_api/__init__.py +0 -0
  39. {pyproject_api-1.12.2 → pyproject_api-1.12.4}/src/pyproject_api/__main__.py +0 -0
  40. {pyproject_api-1.12.2 → pyproject_api-1.12.4}/src/pyproject_api/_backend.py +0 -0
  41. {pyproject_api-1.12.2 → pyproject_api-1.12.4}/src/pyproject_api/_backend.pyi +0 -0
  42. {pyproject_api-1.12.2 → pyproject_api-1.12.4}/src/pyproject_api/_util.py +0 -0
  43. {pyproject_api-1.12.2 → pyproject_api-1.12.4}/src/pyproject_api/_via_fresh_subprocess.py +0 -0
  44. {pyproject_api-1.12.2 → pyproject_api-1.12.4}/src/pyproject_api/py.typed +0 -0
  45. {pyproject_api-1.12.2 → pyproject_api-1.12.4}/tests/_build_sdist.py +0 -0
  46. {pyproject_api-1.12.2 → pyproject_api-1.12.4}/tests/demo_pkg_inline/build.py +0 -0
  47. {pyproject_api-1.12.2 → pyproject_api-1.12.4}/tests/demo_pkg_inline/pyproject.toml +0 -0
  48. {pyproject_api-1.12.2 → pyproject_api-1.12.4}/tests/test_backend.py +0 -0
  49. {pyproject_api-1.12.2 → pyproject_api-1.12.4}/tests/test_frontend_setuptools.py +0 -0
  50. {pyproject_api-1.12.2 → pyproject_api-1.12.4}/tests/test_main.py +0 -0
  51. {pyproject_api-1.12.2 → pyproject_api-1.12.4}/tests/test_util.py +0 -0
  52. {pyproject_api-1.12.2 → pyproject_api-1.12.4}/tests/test_version.py +0 -0
  53. {pyproject_api-1.12.2 → pyproject_api-1.12.4}/tox.toml +0 -0
@@ -0,0 +1,51 @@
1
+ # Security policy
2
+
3
+ pyproject-api is a Python library that drives a project's PEP 517 build backend from a separate process. This policy
4
+ says how to report a security problem and how we decide whether a report is one.
5
+
6
+ ## Reporting a vulnerability
7
+
8
+ **Do not open a public issue for a security problem.** Use
9
+ [GitHub's private vulnerability reporting](https://github.com/tox-dev/pyproject-api/security/advisories/new). If neither
10
+ works for you, email [gaborjbernat@gmail.com](mailto:gaborjbernat@gmail.com).
11
+
12
+ Include what the attacker controls and what they gain, the steps or a proof of concept, and the versions and platform
13
+ you tested. Write the report yourself; unreviewed tool or model output takes longer to triage.
14
+
15
+ ## What to expect
16
+
17
+ Volunteers maintain pyproject-api, with no on-call rotation. We aim to acknowledge a report within **5 working days**
18
+ and assess it within **15 working days**. Fixes are developed in a private fork attached to the draft advisory, ship in
19
+ a new release, and the advisory, with a CVE requested through GitHub, goes out with that release. The default embargo is
20
+ **90 days** from the report; we agree any change with the reporter. We credit reporters in the advisory under the name
21
+ they choose, or not at all. There is no bug bounty.
22
+
23
+ ## Supported versions
24
+
25
+ Only the latest release receives fixes. Confirm the problem reproduces on it before reporting.
26
+
27
+ ## Vulnerability or bug
28
+
29
+ A report is a vulnerability when an attacker who controls only an input that the [threat model](THREAT_MODEL.md) lists
30
+ as untrusted breaks a guarantee pyproject-api makes. A report that first needs control of something the threat model
31
+ trusts, such as the project being built and its build backend, is a bug: we fix it in the open and publish no advisory.
32
+ Classify by who supplies the dangerous input, not by how bad the outcome sounds.
33
+
34
+ **In scope**
35
+
36
+ - A `build-system.backend-path` entry that resolves outside the project being accepted as an import location.
37
+ - A frontend call writing a result or artifact outside the directory the caller named, including while extracting
38
+ `.dist-info` from a built wheel.
39
+ - Clearing a metadata directory deleting the project root, one of its ancestors, or anything reached through a symlink
40
+ inside it.
41
+ - A hook result naming a path outside its output directory, returned to the caller as the artifact or metadata path.
42
+ - Results of one backend call being read as another call's, for example through a predictable result file.
43
+
44
+ **Out of scope**
45
+
46
+ - Code a build backend runs: building a project runs its backend, so building untrusted source runs untrusted code, as
47
+ PEP 517 intends.
48
+ - What the backend writes into the artifacts it returns.
49
+ - The interpreter, environment and `requires` the caller provisions for the backend.
50
+
51
+ If you cannot tell which side a finding falls on, report it privately and we will decide.
@@ -0,0 +1,101 @@
1
+ # Threat model
2
+
3
+ This model says what pyproject-api trusts, where untrusted input enters, and which guarantees hold at each boundary, so
4
+ a report can be classified as a vulnerability or a bug. [SECURITY.md](SECURITY.md) covers reporting; if the two
5
+ disagree, SECURITY.md wins and we fix this file.
6
+
7
+ ## How pyproject-api works
8
+
9
+ A frontend such as tox points pyproject-api at a project folder. pyproject-api reads `[build-system]` from
10
+ `pyproject.toml`, checks that every `backend-path` entry stays inside the project, and starts the backend in a
11
+ subprocess of the interpreter the caller chose: `SubprocessFrontend` starts a fresh one per call, while other frontends,
12
+ such as tox's, can keep one alive across calls (`reuse_backend`). Each hook call (`build_wheel`,
13
+ `prepare_metadata_for_build_wheel` and so on) goes to the backend's stdin as JSON, and the backend writes its answer to
14
+ a temporary JSON file that the frontend reads back. Without a metadata hook, pyproject-api builds a wheel and extracts
15
+ its `.dist-info` into the caller's metadata directory.
16
+
17
+ ```mermaid
18
+ flowchart LR
19
+ fe["Frontend, e.g. tox<br/>(trusted)"] -->|project dir, python| api["pyproject-api"]
20
+ api -->|"reads [build-system]"| proj[("Project source")]
21
+ api -->|"spawn, JSON over stdin"| be["Backend subprocess<br/>runs project-chosen code"]
22
+ be -->|"result JSON in temp file,<br/>artifacts in output dir"| api
23
+ classDef trusted fill:#cfe4ff,stroke:#1f6feb,color:#0b1f3a;
24
+ classDef boundary fill:#ffe3a3,stroke:#d29200,color:#3a2c00;
25
+ class fe,api trusted;
26
+ class proj,be boundary;
27
+ ```
28
+
29
+ ## Compared with similar tools
30
+
31
+ We drew the boundary where comparable projects in other ecosystems draw theirs. The shared rule, stated by the
32
+ [Node.js threat model](https://github.com/nodejs/node/blob/main/SECURITY.md#the-nodejs-threat-model), is that a report
33
+ which first needs a trusted element compromised is out of scope; the first triage question, as
34
+ [DOMPurify](https://github.com/cure53/DOMPurify/blob/main/SECURITY.md#what-we-consider-a-vulnerability) puts it, is what
35
+ the attacker controls.
36
+
37
+ | Project | Language | Where it draws the line |
38
+ | ----------------------------------------------------------------------------------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
39
+ | [Cargo build scripts](https://doc.rust-lang.org/cargo/reference/build-scripts.html) | Rust | A package's `build.rs` runs with full rights during a build; building a crate means trusting it. |
40
+ | [Hatch](https://github.com/pypa/hatch/security/policy) | Python | Assumes the user has full control over the build environment. |
41
+ | [pnpm](https://github.com/pnpm/pnpm/security/policy) | JavaScript | Draws its boundary at filesystem permissions: the store, project, lockfile and configuration are trusted, and running it in a repository means trusting that repository. |
42
+
43
+ ## Trusted
44
+
45
+ An attacker who controls any of these already has what pyproject-api could give them:
46
+
47
+ - The frontend and the project folder, interpreter, environment and output directories it passes.
48
+ - The project's build backend and its `requires`; the backend runs with the user's rights.
49
+ - The filesystem and temporary directory.
50
+
51
+ ## Untrusted inputs
52
+
53
+ | Input | Comes from | What pyproject-api guarantees |
54
+ | -------------------------------------------- | ----------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
55
+ | `build-system.backend-path` | The project's `pyproject.toml` | Each entry must be relative and resolve inside the project; otherwise the call fails. |
56
+ | Backend stdout and stderr | The backend and anything it imports | Captured and returned to the caller as text; hook results come only from the result file. |
57
+ | Malformed `[build-system]` | The project's `pyproject.toml` | Wrong types raise a `ValueError` naming the key; a missing table falls back to the legacy setuptools backend, as PEP 517 specifies. |
58
+ | Members of a built wheel | The backend | Only members under a top-level `.dist-info` directory are extracted, through `zipfile`'s path sanitizing. |
59
+ | Entries inside a metadata directory to clear | Earlier builds, or the backend | Refused when it is the project root or one of its ancestors; symlinks inside it are unlinked, never followed. |
60
+
61
+ ## Threats and controls
62
+
63
+ | STRIDE | Threat | Control |
64
+ | ---------------------- | ----------------------------------------------------------------------- | ------------------------------------------------------------------ |
65
+ | Tampering | `backend-path = ["../other"]` loads a backend from outside the project. | Entries outside the project are rejected. |
66
+ | Spoofing | Backend output printed to stdout is taken as a hook's result. | Results travel through a per-call temporary JSON file, not stdout. |
67
+ | Elevation of privilege | A backend runs code during a build. | Accepted by design; PEP 517 builds run the project's code. |
68
+
69
+ ## Release chain
70
+
71
+ Releases run on the shared [tox-dev/github-workflows](https://github.com/tox-dev/github-workflows) pipeline. A release
72
+ App, not a person, pushes the release commit and tag; the build installs its tools from a hash-checked `pylock.toml`
73
+ resolved with a seven-day upload cooldown by default; PyPI receives the files through
74
+ [trusted publishing](https://docs.pypi.org/trusted-publishers/) with attestations, and the GitHub Release is immutable.
75
+ Every workflow pins third-party actions to a commit SHA.
76
+
77
+ ## Vulnerability or bug
78
+
79
+ | Report | Verdict | Why |
80
+ | -------------------------------------------------------------------- | ---------------------------------------------------- | ------------------------------------------------------------ |
81
+ | `backend-path` with `../` imports a module from the parent directory | Vulnerability | The in-tree guarantee of PEP 517 is broken. |
82
+ | Building a malicious sdist runs its `setup.py` | Not a vulnerability | The backend is trusted; build untrusted source in a sandbox. |
83
+ | A backend that prints JSON confuses `get_requires_for_build_wheel` | Bug, or vulnerability if the result file is bypassed | Results must come only from the result file. |
84
+
85
+ ## Severity
86
+
87
+ - **High:** a frontend call deletes or writes outside the directory the caller named, or clearing a metadata directory
88
+ removes the project or follows a symlink inside it.
89
+ - **Medium:** a `backend-path` outside the project is accepted, a hook's returned path escapes its directory, or one
90
+ call's result is read as another's.
91
+ - **Low:** a malformed backend response crashes or hangs the frontend instead of failing with an error.
92
+
93
+ ## Accepted risks
94
+
95
+ - Every hook call runs project code; isolation from the host is the caller's job.
96
+ - The backend subprocess inherits the environment the caller passes, secrets included.
97
+
98
+ ## Keeping this current
99
+
100
+ Revisit this model when pyproject-api gains a new input source, network access, a new way to run code, or a new place it
101
+ writes to, and whenever an advisory is published.
@@ -0,0 +1,59 @@
1
+ name: 🧪 check
2
+ on:
3
+ workflow_dispatch:
4
+ push:
5
+ branches: ["main"]
6
+ tags-ignore: ["**"]
7
+ pull_request:
8
+ types: [opened, synchronize, reopened]
9
+ schedule:
10
+ - cron: "0 8 * * *"
11
+ concurrency:
12
+ group: check-${{ github.ref }}
13
+ cancel-in-progress: true
14
+ permissions:
15
+ contents: read
16
+ jobs:
17
+ test:
18
+ name: 🧪 Test
19
+ uses: tox-dev/github-workflows/.github/workflows/check.yaml@bceb5c005e19823dc8835f536f53f172ae223927 # 6.5.0
20
+ permissions:
21
+ contents: read
22
+ with:
23
+ include: |
24
+ [
25
+ {"env": "3.15"},
26
+ {"env": "3.15t", "python": "3.15t"},
27
+ {"env": "3.14", "python": "3.14"},
28
+ {"env": "3.13", "python": "3.13"},
29
+ {"env": "3.12", "python": "3.12"},
30
+ {"env": "3.11", "python": "3.11"},
31
+ {"env": "type"},
32
+ {"env": "dev"},
33
+ {"env": "pkg_meta"},
34
+ {"env": "3.15", "os": "windows-2025-vs2026"},
35
+ {"env": "3.15t", "python": "3.15t", "os": "windows-2025-vs2026"},
36
+ {"env": "3.14", "python": "3.14", "os": "windows-2025-vs2026"},
37
+ {"env": "3.13", "python": "3.13", "os": "windows-2025-vs2026"},
38
+ {"env": "3.12", "python": "3.12", "os": "windows-2025-vs2026"},
39
+ {"env": "3.11", "python": "3.11", "os": "windows-2025-vs2026"},
40
+ {"env": "type", "os": "windows-2025-vs2026"},
41
+ {"env": "dev", "os": "windows-2025-vs2026"},
42
+ {"env": "pkg_meta", "os": "windows-2025-vs2026"},
43
+ {"env": "3.15", "os": "macos-26"},
44
+ {"env": "3.15t", "python": "3.15t", "os": "macos-26"},
45
+ {"env": "3.14", "python": "3.14", "os": "macos-26"},
46
+ {"env": "3.13", "python": "3.13", "os": "macos-26"},
47
+ {"env": "3.12", "python": "3.12", "os": "macos-26"},
48
+ {"env": "3.11", "python": "3.11", "os": "macos-26"}
49
+ ]
50
+ gate:
51
+ name: 🚦 ${{ github.event_name == 'pull_request' && 'Required checks pass' || 'Non-PR checks pass' }}
52
+ if: ${{ !cancelled() }} # codespell:ignore cancelled
53
+ needs: [test]
54
+ runs-on: ubuntu-26.04
55
+ steps:
56
+ - name: 🚦 Require all needed jobs to pass
57
+ uses: tox-dev/github-workflows/required-checks@bceb5c005e19823dc8835f536f53f172ae223927 # 6.5.0
58
+ with:
59
+ needs: ${{ toJSON(needs) }}
@@ -0,0 +1,22 @@
1
+ name: 🛡️ CodeQL
2
+ on:
3
+ workflow_dispatch:
4
+ push:
5
+ branches: ["main"]
6
+ pull_request:
7
+ schedule:
8
+ - cron: "0 9 * * 2"
9
+ concurrency:
10
+ group: codeql-${{ github.ref }}
11
+ cancel-in-progress: true
12
+ permissions: {}
13
+ jobs:
14
+ analyze:
15
+ name: 🛡️ Analyze
16
+ uses: tox-dev/github-workflows/.github/workflows/codeql.yaml@bceb5c005e19823dc8835f536f53f172ae223927 # 6.5.0
17
+ permissions:
18
+ contents: read
19
+ security-events: write
20
+ with:
21
+ languages: '["actions","python"]'
22
+ paths-ignore: '["tests"]'
@@ -2,9 +2,6 @@ name: 📝 Changelog
2
2
  on:
3
3
  pull_request:
4
4
  types: [opened, reopened, synchronize, labeled, unlabeled]
5
- concurrency:
6
- group: ${{ github.workflow }}-${{ github.event.pull_request.number }}
7
- cancel-in-progress: true
8
5
  permissions:
9
6
  contents: read
10
7
  pull-requests: read
@@ -19,15 +16,15 @@ jobs:
19
16
  fetch-depth: 0
20
17
  persist-credentials: false
21
18
  - name: 🐍 Install uv
22
- uses: astral-sh/setup-uv@07a047e608db84b3d8c06cd9a7c7dcc9c355c18e # v10.3.2
19
+ uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
23
20
  with:
24
21
  version: latest-known
25
22
  python-version: "3.15"
26
23
  enable-cache: false
27
24
  - name: 📦 Install locked release tools
28
- uses: tox-dev/github-workflows/install-locked-tools@57a765127aae73adf7d0e24a7fe0f067f2d3ea3e # 6.2.1
25
+ uses: tox-dev/github-workflows/install-locked-tools@bceb5c005e19823dc8835f536f53f172ae223927 # 6.5.0
29
26
  with:
30
27
  groups: release-news
31
28
  venv: ${{ runner.temp }}/release-tools
32
29
  - name: 🔍 Validate news fragments
33
- uses: tox-dev/github-workflows/validate-news@57a765127aae73adf7d0e24a7fe0f067f2d3ea3e # 6.2.1
30
+ uses: tox-dev/github-workflows/validate-news@bceb5c005e19823dc8835f536f53f172ae223927 # 6.5.0
@@ -16,7 +16,7 @@ permissions: {}
16
16
  jobs:
17
17
  prepare:
18
18
  name: 🏷️ Prepare Towncrier release
19
- uses: tox-dev/github-workflows/.github/workflows/prepare-towncrier-release.yaml@57a765127aae73adf7d0e24a7fe0f067f2d3ea3e # 6.2.1
19
+ uses: tox-dev/github-workflows/.github/workflows/prepare-towncrier-release.yaml@bceb5c005e19823dc8835f536f53f172ae223927 # 6.5.0
20
20
  permissions:
21
21
  contents: read
22
22
  pull-requests: read
@@ -0,0 +1,56 @@
1
+ name: 🚀 Release to PyPI
2
+ on:
3
+ push:
4
+ tags: ["*"]
5
+ permissions:
6
+ contents: read
7
+ concurrency:
8
+ group: release-${{ github.ref }}
9
+ cancel-in-progress: false
10
+ jobs:
11
+ build:
12
+ name: 🏗️ Build
13
+ uses: tox-dev/github-workflows/.github/workflows/validate-python-release.yaml@bceb5c005e19823dc8835f536f53f172ae223927 # 6.5.0
14
+ permissions:
15
+ contents: read
16
+ github-notes:
17
+ name: 📝 Render GitHub Release notes
18
+ uses: tox-dev/github-workflows/.github/workflows/release-notes.yaml@bceb5c005e19823dc8835f536f53f172ae223927 # 6.5.0
19
+ permissions:
20
+ contents: read
21
+ with:
22
+ tag: ${{ github.ref_name }}
23
+ changelog: docs/changelog.rst
24
+ artifact-url: https://pypi.org/project/pyproject-api/${{ github.ref_name }}/
25
+ release:
26
+ name: 🚀 Publish to PyPI
27
+ needs: [build, github-notes]
28
+ runs-on: ubuntu-26.04
29
+ environment:
30
+ name: release
31
+ url: https://pypi.org/project/pyproject-api/${{ github.ref_name }}
32
+ permissions:
33
+ id-token: write
34
+ steps:
35
+ - name: 📩 Download distributions
36
+ uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
37
+ with:
38
+ artifact-ids: ${{ needs.build.outputs.distributions-artifact-id }}
39
+ path: dist/
40
+ - name: 🚀 Publish to PyPI
41
+ uses: pypa/gh-action-pypi-publish@7245906fb61fa33a13554f9d5fb856fe61758086 # v1.14.3
42
+ with:
43
+ packages-dir: dist
44
+ attestations: true
45
+ github-release:
46
+ name: 🚀 Publish GitHub Release
47
+ needs: [build, release, github-notes]
48
+ uses: tox-dev/github-workflows/.github/workflows/github-release.yaml@bceb5c005e19823dc8835f536f53f172ae223927 # 6.5.0
49
+ permissions:
50
+ contents: write
51
+ with:
52
+ project: pyproject-api
53
+ version: ${{ github.ref_name }}
54
+ tag: ${{ github.ref_name }}
55
+ artifact-pattern: python-package-distributions
56
+ notes-artifact-id: ${{ needs.github-notes.outputs.artifact-id }}
@@ -0,0 +1,26 @@
1
+ name: 🛡️ scorecard
2
+ on:
3
+ branch_protection_rule:
4
+ schedule:
5
+ - cron: "30 7 * * 2"
6
+ push:
7
+ branches: ["main"]
8
+ workflow_dispatch:
9
+ concurrency:
10
+ group: ${{ github.workflow }}-${{ github.ref }}
11
+ cancel-in-progress: true
12
+ permissions: {}
13
+ jobs:
14
+ analysis:
15
+ name: 🛡️ Scorecard analysis
16
+ if: github.repository == 'tox-dev/pyproject-api'
17
+ permissions:
18
+ actions: read # read workflow runs for the Packaging check
19
+ checks: read # read check runs for the CI-Tests and SAST checks
20
+ contents: read # check out and scan the repository
21
+ id-token: write # authenticate the results published to the scorecard API
22
+ issues: read # read issue activity for the Maintained check
23
+ pull-requests: read # read reviews for the Code-Review check
24
+ security-events: write # upload the SARIF results to code scanning
25
+ statuses: read # read commit statuses for the CI-Tests check
26
+ uses: tox-dev/github-workflows/.github/workflows/scorecard.yaml@bceb5c005e19823dc8835f536f53f172ae223927 # 6.5.0
@@ -10,7 +10,7 @@ concurrency:
10
10
  jobs:
11
11
  upgrade:
12
12
  name: 🔀 Upgrade release tools
13
- uses: tox-dev/github-workflows/.github/workflows/upgrade-release-tools.yaml@57a765127aae73adf7d0e24a7fe0f067f2d3ea3e # 6.2.1
13
+ uses: tox-dev/github-workflows/.github/workflows/upgrade-release-tools.yaml@bceb5c005e19823dc8835f536f53f172ae223927 # 6.5.0
14
14
  permissions:
15
15
  contents: read
16
16
  secrets:
@@ -9,7 +9,7 @@ repos:
9
9
  - id: end-of-file-fixer
10
10
  - id: trailing-whitespace
11
11
  - repo: https://github.com/python-jsonschema/check-jsonschema
12
- rev: 0494aa7fa1314e98913a41227d8f0a515b2c1049 # frozen: 0.38.2
12
+ rev: a76b92851fc9eede9f9bc4073eb55202f34eb0df # frozen: 0.39.0
13
13
  hooks:
14
14
  - id: check-github-workflows
15
15
  args: ["--verbose"]
@@ -30,7 +30,7 @@ repos:
30
30
  hooks:
31
31
  - id: pyproject-fmt
32
32
  - repo: https://github.com/astral-sh/ruff-pre-commit
33
- rev: "38bfb07c0c64c304f47eb52090f8288150c77730" # frozen: v0.17.1
33
+ rev: "25bcf95026b96e2dd3c0aec3090c3d6ef6ca2e6c" # frozen: v0.17.3
34
34
  hooks:
35
35
  - id: ruff-format
36
36
  - id: ruff
@@ -44,7 +44,7 @@ repos:
44
44
  ^docs/changelog[.]rst$ # Only the generated release history.
45
45
  args: ["-l", "120", "--preserve-adornments"]
46
46
  additional_dependencies:
47
- - "sphinx==9.1.1"
47
+ - "sphinx==9.2.0"
48
48
  - repo: https://github.com/zizmorcore/zizmor-pre-commit
49
49
  rev: c92afdf2c6ca336aaa8f39e2bd8d48f62dbd8e1f # frozen: v1.31.1
50
50
  hooks:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: pyproject-api
3
- Version: 1.12.2
3
+ Version: 1.12.4
4
4
  Import-Name: pyproject_api
5
5
  Summary: API to interact with the python pyproject.toml based projects
6
6
  Project-URL: Changelog, https://github.com/tox-dev/pyproject-api/blob/main/docs/changelog.rst
@@ -29,13 +29,14 @@ Requires-Python: >=3.11
29
29
  Requires-Dist: packaging>=26.3
30
30
  Description-Content-Type: text/markdown
31
31
 
32
- # [`pyproject-api`][RTD]
32
+ # [`pyproject-api`][rtd]
33
33
 
34
34
  [![PyPI](https://img.shields.io/pypi/v/pyproject-api?style=flat-square)](https://pypi.org/project/pyproject-api/)
35
- [![Supported Python
36
- versions](https://img.shields.io/pypi/pyversions/pyproject-api.svg)](https://pypi.org/project/pyproject-api/)
35
+ [![Supported Python versions](https://img.shields.io/pypi/pyversions/pyproject-api.svg)](https://pypi.org/project/pyproject-api/)
37
36
  [![Downloads](https://static.pepy.tech/badge/pyproject-api/month)](https://pepy.tech/project/pyproject-api)
38
37
  [![check](https://github.com/tox-dev/pyproject-api/actions/workflows/check.yaml/badge.svg)](https://github.com/tox-dev/pyproject-api/actions/workflows/check.yaml)
39
- [![Documentation Status](https://readthedocs.org/projects/pyproject-api/badge/?version=latest)][RTD]
38
+ [![Documentation Status](https://readthedocs.org/projects/pyproject-api/badge/?version=latest)][rtd]
39
+ [![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/tox-dev/pyproject-api/badge)](https://scorecard.dev/viewer/?uri=github.com/tox-dev/pyproject-api)
40
+ [![OpenSSF Best Practices](https://www.bestpractices.dev/projects/16251/badge)](https://www.bestpractices.dev/projects/16251)
40
41
 
41
- [RTD]: https://pyproject-api.rtfd.io
42
+ [rtd]: https://pyproject-api.rtfd.io
@@ -0,0 +1,11 @@
1
+ # [`pyproject-api`][rtd]
2
+
3
+ [![PyPI](https://img.shields.io/pypi/v/pyproject-api?style=flat-square)](https://pypi.org/project/pyproject-api/)
4
+ [![Supported Python versions](https://img.shields.io/pypi/pyversions/pyproject-api.svg)](https://pypi.org/project/pyproject-api/)
5
+ [![Downloads](https://static.pepy.tech/badge/pyproject-api/month)](https://pepy.tech/project/pyproject-api)
6
+ [![check](https://github.com/tox-dev/pyproject-api/actions/workflows/check.yaml/badge.svg)](https://github.com/tox-dev/pyproject-api/actions/workflows/check.yaml)
7
+ [![Documentation Status](https://readthedocs.org/projects/pyproject-api/badge/?version=latest)][rtd]
8
+ [![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/tox-dev/pyproject-api/badge)](https://scorecard.dev/viewer/?uri=github.com/tox-dev/pyproject-api)
9
+ [![OpenSSF Best Practices](https://www.bestpractices.dev/projects/16251/badge)](https://www.bestpractices.dev/projects/16251)
10
+
11
+ [rtd]: https://pyproject-api.rtfd.io
@@ -5,6 +5,24 @@ Release History
5
5
 
6
6
  .. towncrier release notes start
7
7
 
8
+ .. _release-1-12-4:
9
+
10
+ v1.12.4 (2026-11-04)
11
+ --------------------
12
+
13
+ .. _release-1-12-3:
14
+
15
+ v1.12.3 (2026-11-02)
16
+ --------------------
17
+
18
+ .. _release-1-12-3-fixed:
19
+
20
+ Fixed
21
+ ^^^^^
22
+
23
+ - Clear stale files from reused ``.dist-info`` directories when building wheel or editable metadata (:pr:`345`) by
24
+ :user:`subotac` and :user:`gaborbernat`.
25
+
8
26
  .. _release-1-12-2:
9
27
 
10
28
  v1.12.2 (2026-10-28)