Skip to content

feat: add PyPI resource and pyproject autodiscovery plugins#8155

Merged
olblak merged 2 commits into
updatecli:mainfrom
loispostula:push-ultwmqxxtlvu
Apr 3, 2026
Merged

feat: add PyPI resource and pyproject autodiscovery plugins#8155
olblak merged 2 commits into
updatecli:mainfrom
loispostula:push-ultwmqxxtlvu

Conversation

@loispostula

@loispostula loispostula commented Mar 25, 2026

Copy link
Copy Markdown
Contributor

Add Python ecosystem support to updatecli with two new plugins: a pypi resource and pyproject autodiscovery.

PyPI Resource (pkg/plugins/resources/pypi/)

Queries the PyPI JSON API for Python package versions.

  • Source: returns the latest version matching a version filter
  • Condition: checks whether a specific version exists
  • Changelog: extracts GitHub release notes from project_urls, falls back to PyPI release page links
  • Private registries: configurable URL + Bearer token
  • PEP 440 → semver normalization: converts Python pre-release versions (0.51b00.51.0-beta.0, 1.0a11.0.0-alpha.1, 2.0rc12.0.0-rc.1) so that semver version filtering works with the Python ecosystem
  • Yanked versions are excluded

Pyproject Autodiscovery (pkg/plugins/autodiscovery/pyproject/)

Discovers pyproject.toml files and generates updatecli manifests for dependency updates.

  • Detects package managers via lock files (uv supported, architecture ready for poetry/pdm)
  • Follows the npm multi-PM pattern with detectLockFileSupport()
  • Parses PEP 508 dependency strings (name, extras, version constraints, environment markers)
  • Handles [project.dependencies] and [project.optional-dependencies]
  • Generated manifests use pypi source + uv add shell target (updates pyproject.toml + uv.lock atomically)
  • Registered as pyproject with alias python/uv
  • Supports ignore/only matching rules, custom versionfilter, and custom indexurl

Example configuration

autodiscovery:
   scmid: default
   crawlers:
     pyproject:
       only:
         - packages:
             "requests": ""
       versionfilter:
         kind: semver
         pattern: minoronly

Test

go test ./pkg/plugins/resources/pypi/... ./pkg/plugins/autodiscovery/pyproject/... -v
  • e2e tests under e2e/updatecli.d/success.d/autodiscovery/pyproject/ using astral-sh/uv-fastapi-example

Additional Information

Checklist

Tradeoff

  • uv add does not support --dry-run, following the same approach as pnpm in the npm autodiscovery. The changedif: file/checksum mechanism handles idempotency.
  • PEP 440 → semver normalization is best-effort: covers a/b/rc pre-releases, .dev releases are excluded, .post releases map to build metadata. Calendar versioning (e.g., 2024.1) is padded to 3-part semver. User can avoid this by using only/ignore

Potential improvement

  • Add poetry/pdm support by extending detectLockFileSupport() and adding corresponding target templates
  • Add [dependency-groups] support (PEP 735)

@loispostula loispostula force-pushed the push-ultwmqxxtlvu branch 2 times, most recently from 34c38d7 to 0918799 Compare March 26, 2026 11:35
@loispostula loispostula added enhancement New feature or request autodiscovery All things related to the autodiscovery feature resource-pypi labels Mar 26, 2026
@olblak

olblak commented Mar 30, 2026

Copy link
Copy Markdown
Member

PEP 440 → semver normalization is best-effort: covers a/b/rc pre-releases, .dev releases are excluded, .post releases map to build metadata. Calendar versioning (e.g., 2024.1) is padded to 3-part semver. User can avoid this by using only/ignore

Should we leverage a library such as https://github.com/aquasecurity/go-pep440-version

@olblak

olblak commented Mar 30, 2026

Copy link
Copy Markdown
Member

That being said we are starting to have a lot of devependencies

@loispostula

Copy link
Copy Markdown
Contributor Author

@olblak now that #8245 has been merged, i've rebased this pr and incorporated the new versionfilter

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds Python ecosystem support to Updatecli by introducing a new pypi resource (PyPI JSON API-backed version discovery/conditions/changelogs) and a new pyproject autodiscovery crawler (pyproject.toml dependency discovery with uv/uv.lock support), plus CI/config updates to support running uv-based e2e coverage.

Changes:

  • Add pypi resource plugin (source/condition/changelog) and register it in the resource factory.
  • Add pyproject autodiscovery crawler (uv lock detection, PEP 508 parsing, only/ignore rules, manifest template generation) and register it with alias python/uv.
  • Add uv installation to CI and add an Updatecli policy to keep the workflow uv version pinned/up to date; add e2e autodiscovery configs.

Reviewed changes

Copilot reviewed 29 out of 33 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
updatecli/updatecli.d/uv.yaml Updatecli policy to bump setup-uv version in GitHub workflows
pkg/plugins/resources/pypi/main.go Implements PyPI JSON API fetch + version filtering/normalization + report config
pkg/plugins/resources/pypi/source.go pypi source implementation
pkg/plugins/resources/pypi/source_test.go Source unit tests (filtering, yanked handling, auth cases)
pkg/plugins/resources/pypi/condition.go pypi condition implementation (version existence)
pkg/plugins/resources/pypi/condition_test.go Condition unit tests
pkg/plugins/resources/pypi/changelog.go Changelog extraction (GitHub releases fallback to PyPI links)
pkg/plugins/resources/pypi/changelog_test.go Changelog unit tests
pkg/plugins/resources/pypi/target.go Explicitly marks target as unsupported
pkg/plugins/resources/pypi/main_test.go New() constructor validation tests
pkg/plugins/resources/pypi/test_utils.go HTTP mock utilities + fixture JSON payloads
pkg/plugins/autodiscovery/pyproject/main.go Crawler spec/config + initialization (defaults, rootdir handling, uv presence)
pkg/plugins/autodiscovery/pyproject/dependencies.go TOML parsing + dependency discovery + manifest generation
pkg/plugins/autodiscovery/pyproject/manifestTemplate.go Template used to generate Updatecli manifests for discovered deps
pkg/plugins/autodiscovery/pyproject/utils.go File walking, uv/lock detection, PEP 508 parsing helpers
pkg/plugins/autodiscovery/pyproject/utils_test.go Unit tests for PEP 508 parsing
pkg/plugins/autodiscovery/pyproject/matchingRule.go Only/Ignore matching rules (path + package constraints)
pkg/plugins/autodiscovery/pyproject/matchingRule_test.go Unit tests for matching rules logic
pkg/plugins/autodiscovery/pyproject/main_test.go End-to-end-ish manifest generation tests from testdata projects
pkg/plugins/autodiscovery/pyproject/testdata/simple_project/pyproject.toml Test fixture: basic deps
pkg/plugins/autodiscovery/pyproject/testdata/simple_project/uv.lock Test fixture: uv lock presence
pkg/plugins/autodiscovery/pyproject/testdata/optional_deps/pyproject.toml Test fixture: optional-dependencies groups
pkg/plugins/autodiscovery/pyproject/testdata/optional_deps/uv.lock Test fixture: uv lock presence
pkg/plugins/autodiscovery/pyproject/testdata/no_version/pyproject.toml Test fixture: dependency without constraint
pkg/plugins/autodiscovery/pyproject/testdata/no_version/uv.lock Test fixture: uv lock presence
pkg/plugins/autodiscovery/pyproject/testdata/no_lockfile/pyproject.toml Test fixture: source-only mode (no uv.lock)
pkg/plugins/autodiscovery/pyproject/testdata/markers/pyproject.toml Test fixture: env markers in deps
pkg/plugins/autodiscovery/pyproject/testdata/markers/uv.lock Test fixture: uv lock presence
pkg/core/pipeline/resource/main.go Registers new pypi resource kind
pkg/core/pipeline/autodiscovery/main.go Registers new pyproject crawler + alias python/uv
e2e/updatecli.d/success.d/autodiscovery/pyproject/pyproject.yaml e2e config for pyproject autodiscovery (only rule)
e2e/updatecli.d/success.d/autodiscovery/pyproject/pyproject.versionfilter.yaml e2e config for pyproject autodiscovery with versionfilter override
.github/workflows/go.yaml Installs uv in CI to support pyproject/uv e2e coverage

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread pkg/plugins/resources/pypi/main.go Outdated
Comment thread pkg/plugins/resources/pypi/main.go Outdated
Comment thread pkg/plugins/resources/pypi/condition.go
Comment thread pkg/plugins/resources/pypi/main.go Outdated
Comment thread pkg/plugins/autodiscovery/pyproject/utils.go
@olblak

olblak commented Apr 1, 2026

Copy link
Copy Markdown
Member

@loispostula Thanks for the pullrequest, that's a big beast 😄 could you review copilot message?
Feel free to ignore nit pick comment

Add Python ecosystem support to updatecli with two new plugins:

- pypi resource: queries PyPI JSON API for package versions,
  with PEP 440 to semver normalization (a/b/rc pre-releases),
  private registry support (Bearer token), and yanked version filtering.

- pyproject autodiscovery: discovers pyproject.toml + uv.lock pairs,
  parses PEP 508 dependencies, generates manifests using pypi source
  and uv add shell target. Named pyproject (alias python/uv) for
  multi-PM extensibility following the npm pattern.

Signed-off-by: Loïs Postula <lois@postu.la>
@loispostula loispostula force-pushed the push-ultwmqxxtlvu branch 2 times, most recently from 3f57dc8 to 24ad585 Compare April 1, 2026 21:32
@olblak olblak merged commit ab9569c into updatecli:main Apr 3, 2026
7 checks passed
olblak pushed a commit to LeC-D/updatecli that referenced this pull request Apr 5, 2026
…i#8155)

* feat: add PyPI resource and pyproject autodiscovery plugins

Add Python ecosystem support to updatecli with two new plugins:

- pypi resource: queries PyPI JSON API for package versions,
  with PEP 440 to semver normalization (a/b/rc pre-releases),
  private registry support (Bearer token), and yanked version filtering.

- pyproject autodiscovery: discovers pyproject.toml + uv.lock pairs,
  parses PEP 508 dependencies, generates manifests using pypi source
  and uv add shell target. Named pyproject (alias python/uv) for
  multi-PM extensibility following the npm pattern.

Signed-off-by: Loïs Postula <lois@postu.la>

* fix: cursor comments

---------

Signed-off-by: Loïs Postula <lois@postu.la>
olblak added a commit that referenced this pull request Apr 5, 2026
* feat(github): add client-side pull request merge option (#2312)

Add a new 'clientsidemerge' option to the GitHub action spec that allows
updatecli to merge a pull request directly via the GitHub GraphQL API
(mergePullRequest mutation), bypassing the need for server-side auto-merge
which requires a paid plan or a public repository.

When 'clientsidemerge: true' is set, updatecli will attempt to merge
the pull request immediately after it is created or updated. The merge
will fail if the PR is not in a mergeable state (e.g. has conflicts or
failing required checks).

The merge method is controlled by the existing 'mergemethod' field and
defaults to GitHub's default ('MERGE') if not specified. The
'usetitleforautomerge' flag is also respected to set a custom commit
headline for squash and rebase merges.

Fixes #2312

* feat(github): restructure merge spec and deprecate automerge field

- Replace ClientSideMerge bool with nested Merge.Strategy/After fields
- Deprecate AutoMerge bool -> *bool with migration warning to merge.strategy: auto
- Add merge.after support to delay client-side merge by a configured duration
- Minimize mutationMergePullRequest response struct (Copilot suggestion)
- Guard nil rateLimit before calling Pause() in MergePullRequest
- Add CreatedAt field to PullRequestApi

* feat: add PyPI resource and pyproject autodiscovery plugins (#8155)

* feat: add PyPI resource and pyproject autodiscovery plugins

Add Python ecosystem support to updatecli with two new plugins:

- pypi resource: queries PyPI JSON API for package versions,
  with PEP 440 to semver normalization (a/b/rc pre-releases),
  private registry support (Bearer token), and yanked version filtering.

- pyproject autodiscovery: discovers pyproject.toml + uv.lock pairs,
  parses PEP 508 dependencies, generates manifests using pypi source
  and uv add shell target. Named pyproject (alias python/uv) for
  multi-PM extensibility following the npm pattern.

Signed-off-by: Loïs Postula <lois@postu.la>

* fix: cursor comments

---------

Signed-off-by: Loïs Postula <lois@postu.la>

* fix: various fixes and improvements

* use constants for merge client strategy
* add closing pullrequest in cleanAction
* set default value to 24h for auto merge client
* correctly fallback from automerge setting to either manual or auto

Signed-off-by: Olblak <me@olblak.com>

* fix: ignore gosec

Signed-off-by: Olblak <me@olblak.com>

---------

Signed-off-by: Loïs Postula <lois@postu.la>
Signed-off-by: Olblak <me@olblak.com>
Co-authored-by: Olivier Vernin <olivier@vernin.me>
Co-authored-by: Loïs Postula <lois@postu.la>
Co-authored-by: Olblak <me@olblak.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

autodiscovery All things related to the autodiscovery feature enhancement New feature or request resource-pypi

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants