Skip to content

chore: modernize Python tooling and add CI - #12

Merged
gkrimer merged 7 commits into
mainfrom
chore/modernize-python-tooling
Jul 28, 2026
Merged

chore: modernize Python tooling and add CI#12
gkrimer merged 7 commits into
mainfrom
chore/modernize-python-tooling

Conversation

@gkrimer

@gkrimer gkrimer commented Apr 24, 2026

Copy link
Copy Markdown
Contributor

Setup tests and ci.

❯ ./smoke-test.sh
==> building sandbox consumer repo at /var/folders/8g/xz89xhb15v3dzkk8m2v9_rnm0000gn/T/tmp.1J8FP0qAFu
==> step 1: uv sync --frozen --no-dev (from action_path)
Using CPython 3.11.15
Creating virtual environment at: /var/folders/8g/xz89xhb15v3dzkk8m2v9_rnm0000gn/T/tmp.1J8FP0qAFu/.venv-action
Installed 17 packages in 31ms
...
==> step 2: uv run --frozen --no-dev python create_tag.py ...
DEBUG:git.util:sys.platform='darwin', git_executable='git'
DEBUG:git.cmd:Popen(['git', 'cat-file', '--batch-check'], cwd=/var/folders/8g/xz89xhb15v3dzkk8m2v9_rnm0000gn/T/tmp.1J8FP0qAFu, stdin=<valid stream>, shell=False, universal_newlines=False)
DEBUG:root:scanning all existing tags
DEBUG:git.cmd:Popen(['git', 'cat-file', '--batch'], cwd=/var/folders/8g/xz89xhb15v3dzkk8m2v9_rnm0000gn/T/tmp.1J8FP0qAFu, stdin=<valid stream>, shell=False, universal_newlines=False)
DEBUG:root:found last tag of v2.202604010000.1
DEBUG:git.cmd:Popen(['git', 'merge-base', 'v2.202604010000.1', '77e6d1e35ca802b38fbff97dfc42d064b571a397'], cwd=/var/folders/8g/xz89xhb15v3dzkk8m2v9_rnm0000gn/T/tmp.1J8FP0qAFu, stdin=None, shell=False, universal_newlines=False)
DEBUG:git.cmd:Popen(['git', 'rev-list', '3f6d9a5b98511f9e0177de69ac4016699e6287ba..77e6d1e35ca802b38fbff97dfc42d064b571a397', '--'], cwd=/var/folders/8g/xz89xhb15v3dzkk8m2v9_rnm0000gn/T/tmp.1J8FP0qAFu, stdin=None, shell=False, universal_newlines=False)
DEBUG:root:examining commit 77e6d1e35ca802b38fbff97dfc42d064b571a397
DEBUG:root:examining commit ac67b90e92ffb33d2690e59f7a226a0af8d44574
DEBUG:root:examining commit 3aa8ce489a80d2f227a0b4b645f98ff0060c4122
DEBUG:git.cmd:Popen(['git', 'tag', '-m', 'deployment of 77e6d1e35ca802b38fbff97dfc42d064b571a397 to production at 2026-04-24T18:44:05+00:00 (@1777056245) by @smoke-test\n\nchanges since v2.202604010000.1 (-95 days, 20:28:40 ago):\n\nFeatures:\n - add new endpoint (test@example.com)\n\nBug Fixes:\n - handle nil case (test@example.com)\n\nPerformance Improvements:\n - speed up parser (test@example.com)\n\nBREAKING CHANGES:\n - response shape changed (test@example.com)\n', 'v2.202604241844.4477349984', '77e6d1e35ca802b38fbff97dfc42d064b571a397'], cwd=/var/folders/8g/xz89xhb15v3dzkk8m2v9_rnm0000gn/T/tmp.1J8FP0qAFu, stdin=None, shell=False, universal_newlines=False)
tag_name=v2.202604241844.4477349984
release_body_path=release_notes-v2.202604241844.4477349984.txt
commit_authors=
==> asserting outputs
==> smoke test OK

@gkrimer
gkrimer requested a review from a team as a code owner April 24, 2026 23:07
@gkrimer
gkrimer requested a review from instrumentl707 April 24, 2026 23:07
@gkrimer
gkrimer marked this pull request as draft April 24, 2026 23:07
gkrimer and others added 2 commits May 13, 2026 17:07
Replaces pip + requirements.txt + setup-python with uv + pyproject.toml +
astral-sh/setup-uv. Adds ruff (lint + format), pyright (type check), pytest,
and a smoke test that exercises the action end-to-end against a throwaway
consumer repo. All of the above run in a new CI workflow on every PR — the
SyntaxError that reached prod today would have been caught three ways
(py_compile, ruff parse, pyright).

- action.yml: setup-python/pip -> setup-uv + uv sync --frozen + uv run
- create-tag -> create_tag.py (preserves git history via rename)
- pyproject.toml replaces requirements.txt; uv.lock pins the full graph
- create_tag.py: small incidental fixes for bugbear B020 (shadowed loop var)
  and two pyright findings (None guard on tag dates, direct GitCommandError
  import)
- smoke-test.sh reproduces a real invocation locally and in CI

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Empty test file caused `pytest` to exit 5 (no tests collected), failing CI.
Four small parser tests give pytest something real to collect and start a
suite future logic changes can extend.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@gkrimer
gkrimer force-pushed the chore/modernize-python-tooling branch from c24c8bd to 6e2f22b Compare May 14, 2026 03:50
@gkrimer
gkrimer marked this pull request as ready for review May 14, 2026 04:03
@gkrimer
gkrimer requested a review from celinefb May 14, 2026 04:03
Comment thread create_tag.py Outdated
@celinefb
celinefb self-requested a review May 18, 2026 18:52

@celinefb celinefb 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.

rename commit into change_commit and it should be good

@gkrimer

gkrimer commented May 26, 2026

Copy link
Copy Markdown
Contributor Author

Hey @celinefb thank you for reviewing! Unfortunately I lost context on this PR. I'll try to come back to it later this week or next (or anyone is free to take it over) to validate and get prepped for what to look for in #deployments should things stop working once this is merged. Wanted to explain the delay.

@instrumentl707

Copy link
Copy Markdown

Hey @celinefb thank you for reviewing! Unfortunately I lost context on this PR. I'll try to come back to it later this week or next (or anyone is free to take it over) to validate and get prepped for what to look for in #deployments should things stop working once this is merged. Wanted to explain the delay.

Putting this into "draft" so it stops appearing in reviewer's feeds.

@instrumentl707
instrumentl707 marked this pull request as draft July 21, 2026 14:32
@gkrimer

gkrimer commented Jul 24, 2026

Copy link
Copy Markdown
Contributor Author

Hey @celinefb thank you for reviewing! Unfortunately I lost context on this PR. I'll try to come back to it later this week or next (or anyone is free to take it over) to validate and get prepped for what to look for in #deployments should things stop working once this is merged. Wanted to explain the delay.

Putting this into "draft" so it stops appearing in reviewer's feeds.

Thanks!

Review asked to rename `commit` -> `change_commit` on the `iter_commits` range.
Applying it literally raises `UnboundLocalError`: the range expression is
evaluated once, before the loop variable is bound. Renamed the *parameter* to
`head_commit` instead, which removes the ambiguity the review flagged, and added
tests that pin the range's upper bound so this can't silently regress.

- create_tag.py: enumerate_changes(..., commit) -> head_commit, plus a comment
  explaining why the range is not the loop variable
- create_tag_test.py: 5 enumerate_changes tests against a real throwaway repo
  (range bound, max_commits, non-conventional skip, no merge base); parser stubs
  now use create_autospec(git.Commit) instead of SimpleNamespace so attribute
  typos fail
- action.yml: `uv run` re-syncs with dev deps by default, defeating the earlier
  `uv sync --no-dev`; pass `--frozen --no-dev` so ruff/pyright/pytest stay out of
  the deploy path
- pyproject.toml: drop `reportMissingImports = false` -- it hid unresolvable
  imports, which ruff and py_compile do not catch either
- .tool-versions: pin nodejs; pyright is a node binary and could not run locally
- smoke-test.sh: sync into a throwaway UV_PROJECT_ENVIRONMENT so --no-dev stops
  pruning the working .venv
- ci.yml: permissions: contents: read

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@gkrimer
gkrimer marked this pull request as ready for review July 27, 2026 21:33
@gkrimer
gkrimer requested a review from celinefb July 27, 2026 21:40
@gkrimer

gkrimer commented Jul 27, 2026

Copy link
Copy Markdown
Contributor Author

Hey @celinefb thank you for reviewing! Unfortunately I lost context on this PR. I'll try to come back to it later this week or next (or anyone is free to take it over) to validate and get prepped for what to look for in #deployments should things stop working once this is merged. Wanted to explain the delay.

Putting this into "draft" so it stops appearing in reviewer's feeds.

Thanks!

Should be good to go now.

gkrimer and others added 2 commits July 27, 2026 15:22
Both actions targeted the deprecated node20 runtime, so the runner was
force-upgrading them to node24 and warning on every run:

  Node.js 20 is deprecated. The following actions target Node.js 20 but
  are being forced to run on Node.js 24: actions/checkout@v4,
  astral-sh/setup-uv@v5

setup-uv v7 is `using: "node24"` and keeps both inputs this action relies
on (`enable-cache`, `cache-dependency-glob`). Chose v7 over v9 because
ai-service already runs @v7 successfully.

Note action.yml is consumer-facing: the bump ships to every repo using
auto-deploy-to-gke at @main.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…CVEs

All five are in the runtime (--no-dev) set, so they ship to every repo
consuming this action at @main. 10 advisories cleared:

  gitpython    3.1.47 -> 3.1.57  GHSA-3rp5-jjmw-4wv2 (high, config injection)
                                 GHSA-rwj8-pgh3-r573 (high, env exfiltration)
  urllib3      2.6.3  -> 2.7.0   CVE-2026-44432, CVE-2026-44431 (high)
  pyjwt        2.12.1 -> 2.13.0  CVE-2026-48526 (high), -48523, -48525, -48524
  cryptography 47.0.0 -> 49.0.0  GHSA-537c-gmf6-5ccf (high, bundled OpenSSL)
  idna         3.13   -> 3.18    CVE-2026-45409 (medium)

The GitPython pair matters most here: it is the core dependency of
create_tag.py, and the env-exfiltration advisory applies to a step whose
environment holds a GitHub App token with contents: write.

Lockfile-only; pyproject.toml requires-python >=3.11 unchanged, no
packages added or removed, no dev-group churn.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@gkrimer
gkrimer dismissed celinefb’s stale review July 27, 2026 22:59

Claude called it.

@gkrimer

gkrimer commented Jul 27, 2026

Copy link
Copy Markdown
Contributor Author

rename commit into change_commit and it should be good

Done

--frozen installs from uv.lock without ever reading pyproject.toml, so a
dependency edit that was never re-locked passes CI silently:

  # with an unlocked dep added to pyproject.toml
  uv lock --check      exit=1  The lockfile at `uv.lock` needs to be updated
  uv sync --frozen     exit=0  Audited 25 packages

--locked performs that check and then installs, so drift fails loudly.
Matches data-platform's .github/actions/setup, which already uses
`uv sync --locked --all-extras --dev`.

action.yml keeps --frozen deliberately: it runs on a consumer's runner at
deploy time and must never re-resolve. CI is the gate; the action is not.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@gkrimer
gkrimer merged commit 8429360 into main Jul 28, 2026
1 check passed
@gkrimer
gkrimer deleted the chore/modernize-python-tooling branch July 28, 2026 00:19
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