Skip to content

PYTHON-5980 Add uv lock update action - #113

Merged
blink1073 merged 6 commits into
mongodb-labs:mainfrom
blink1073:PYTHON-5980
Aug 5, 2026
Merged

PYTHON-5980 Add uv lock update action#113
blink1073 merged 6 commits into
mongodb-labs:mainfrom
blink1073:PYTHON-5980

Conversation

@blink1073

@blink1073 blink1073 commented Aug 4, 2026

Copy link
Copy Markdown
Member

Adds a python/uv-lock-update composite action that refreshes a consuming repo's uv.lock and keeps a single open pull request with the result.

For repos that commit uv.lock and want routine dependency upgrades handled on a schedule rather than as individual Dependabot pull requests. The first consumer will be mongodb/mongo-python-driver#2977 (PYTHON-5980).

The caller checks out the repository and supplies uv. A GitHub App token is required outside dry runs. Later runs refresh the open pull request instead of opening another.

Also adds a test-python job to ci.yml. Usage is documented in the README.

Validation

Include 23 unit assertions that run in CI.

Exercised end to end tests against my fork of mongo-python-driver, with a real GitHub App and an out-of-date lock file:

  • Dry run: no branch pushed, no pull request opened, summary logged.
  • Live run: pull request opened with the expected base, label, and body, touching only uv.lock. CI ran on it on the PR, as expected.
  • Second run: refreshed the same pull request.
  • After closing it, a third run opened a new one.

Comment thread python/uv-lock-update/action.yml Outdated
Comment thread .github/workflows/ci.yml Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Adds a new composite GitHub Action to automate uv.lock upgrades in consumer repositories by maintaining a single “lock update” pull request that is created once and refreshed on subsequent runs, with documentation and CI coverage for the new logic.

Changes:

  • Introduces python/uv-lock-update composite action plus supporting shell/Python scripts to upgrade uv.lock and create/update a PR via gh.
  • Adds bash-based tests for the lock diffing and PR create/update decision logic, and runs them in CI.
  • Documents usage and operational behavior in README.md.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
README.md Documents the new python/uv-lock-update action and how to call it.
python/uv-lock-update/action.yml Defines inputs/steps for generating an app token, upgrading uv.lock, and creating/updating the PR.
python/uv-lock-update/update_lock.sh Generates a change summary, commits uv.lock, force-pushes the bot branch, and dispatches PR creation/update.
python/uv-lock-update/decide_pr_action.sh Uses gh to decide whether to create a PR or edit the existing open PR for the branch (with dry-run support).
python/uv-lock-update/diff_lock.py Diffs two uv.lock files and prints a markdown summary of package version changes.
python/uv-lock-update/test_diff_lock.sh Tests the lock diffing behavior across additions/removals/forks/unchanged packages.
python/uv-lock-update/test_decide_pr_action.sh Tests PR create vs update decisions using a fake gh shim and logged calls.
.github/workflows/ci.yml Adds a test-python job to run the new bash tests in CI.

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

Comment thread python/uv-lock-update/diff_lock.py Outdated
Adds a python/uv-lock-update composite action that runs uv lock --upgrade in a
consuming repository and maintains a single open pull request with the result.

The caller checks out the repository and supplies uv. A GitHub App token is
required outside dry runs, so the pull request the action opens triggers CI.
Later runs refresh that pull request rather than opening another.

Also adds a test-python job to ci.yml, the first automated test coverage for
the actions outside code-scanning-export.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated no new comments.

Suppressed comments (3)

python/uv-lock-update/update_lock.sh:39

  • The push embeds GH_TOKEN directly in the remote URL. If git push fails, the full URL can be echoed in error output, and the token may be exposed (even if usually masked). Prefer authenticating via an HTTP header so the token is not part of the URL.
# Authenticate the push inline rather than with `git remote set-url`, so the
# token is never written to the workspace .git/config.
if [ "$DRY_RUN" != "true" ]; then
  git push --force "https://x-access-token:${GH_TOKEN}@github.com/${GITHUB_REPOSITORY}.git" "$BRANCH"
fi

python/uv-lock-update/action.yml:68

  • GH_TOKEN is set via ${{ steps.app-token.outputs.token || github.token }}. Given the prior step explicitly rejects using github.token for non-dry runs, it’s safer (and clearer) to only use github.token when inputs.dry_run == 'true' and otherwise require the app token output, so a future edit can’t accidentally fall back to github.token for live runs.
        GH_TOKEN: ${{ steps.app-token.outputs.token || github.token }}

README.md:509

  • This action shells out to gh pr ... (see python/uv-lock-update/decide_pr_action.sh), so it also requires the GitHub CLI (gh) to be available on PATH. The README section currently only mentions uv.
The caller checks out the repository and puts `uv` on `PATH`. The cooldown on new
releases comes from `exclude-newer` in the consuming repo's `pyproject.toml`, not
from this action.

@blink1073

blink1073 commented Aug 5, 2026

Copy link
Copy Markdown
Member Author

Both token findings addressed in 49e2f16.

Token in the push URL. Credentials now come from a helper that reads GH_TOKEN from the environment, so the token is not in the remote URL, not in .git/config, and not in the command arguments either.

Implicit github.token fallback. It is now gated on the dry-run flag directly, so a live run gets the app token or an empty value that fails loudly.

@blink1073
blink1073 requested a review from aclark4life August 5, 2026 15:25
@blink1073
blink1073 marked this pull request as ready for review August 5, 2026 15:25
Comment thread python/uv-lock-update/update_lock.sh Outdated
@blink1073
blink1073 requested a review from aclark4life August 5, 2026 17:58
Comment thread python/uv-lock-update/decide_pr_action.sh Outdated
Comment thread README.md
Comment thread python/uv-lock-update/diff_lock.py Outdated
Comment thread python/uv-lock-update/update_lock.sh
@blink1073
blink1073 requested a review from aclark4life August 5, 2026 19:46

@aclark4life aclark4life left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM with optional nits!

  • In decide_pr_action.sh:14 we could add --owner to avoid the extremely unlikely scenario that someone else's PR is found before ours.
  • We could add a working_directory input and put working-directory: ${{ inputs.working_directory }} on each run step in action.yml for clarity
  • Replace git diff --quiet with if cmp -s "$OLD_LOCK" uv.lock; then… because otherwise we have different baselines for "did anything change"
    • action.yml:60 copies uv.lock to $OLD_LOCK before running the upgrade — that's the working-tree content at action start.
    • update_lock.sh:9 runs git diff --quiet uv.lock — that compares working tree against the index/HEAD.

@blink1073

Copy link
Copy Markdown
Member Author

I addressed the first and last, I think we can defer working-directory for if/when we need monorepo support.

@blink1073
blink1073 requested a review from aclark4life August 5, 2026 21:07

@aclark4life aclark4life left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM

@blink1073
blink1073 merged commit bc33fb6 into mongodb-labs:main Aug 5, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants