Skip to content

Release body is the notes file verbatim; mypy CI gate (#56, #30) - #57

Merged
craigmcchesney merged 4 commits into
mainfrom
plan/56-30-release-body-and-mypy
Sep 24, 2026
Merged

craigmcchesney merged 4 commits into
mainfrom
plan/56-30-release-body-and-mypy

Conversation

@craigmcchesney

@craigmcchesney craigmcchesney commented Sep 24, 2026 •

Copy link
Copy Markdown
Collaborator

Closes #56
Closes #30

Plan: plan/tickets/56/plan.md. It covers both tickets, and its closing "Implementation notes" section lists where the implementation departs from it.

#56: the release body is the notes file, verbatim

The ticket's diagnosis was that the release already existed when the workflow ran. That turned out to be wrong (see the plan's Background). What actually happened: the workflow published the full body, and a later gh release edit --notes-file republished the notes file alone. That dropped the verification section the workflow had appended.

This PR removes the appending, so the file and the page are the same content:

  • release.yml
    • Stages doc/release-notes/<tag>.md as dist/RELEASE_NOTES.md and publishes it as body_path with nothing added. The assembly step is removed.
    • Drops generate_release_notes. A republish from the file would silently lose GitHub's commit list, so each notes file carries a hand-written Full Changelog link instead.
    • Adds a step after publishing that diffs the live body against the file. A dry run against rel-1.16.0 matched, and a one-line change made it fail.
  • .dev/tools/check-release-notes.py (new) checks each notes file:
    • It has a ## Verifying these artifacts section.
    • Its --cert-identity names that file's own tag. A stale tag, copied from the previous release, makes sigstore verify reject every genuine artifact. I confirmed this against the rel-1.16.0 downloads.
    • Each sigstore verify identity command names the wheel, the sdist and SHA256SUMS.
    • It has a **Full Changelog** compare link that ends at the file's own tag and starts at an earlier one.
    • Each run starts with a self-test against known-bad notes, like the cookbook checker's canary, so a rule that stops matching fails loudly.
    • It runs in CI's quality job and again at tag time.
  • README.env (new): a reference for the release artifacts and how to verify them, following the Java repos' README.env. Its commands were run successfully against the rel-1.16.0 downloads.
  • rel-1.16.0.md: backports the verification section the live page carries, widened to verify all three files (the page's version named the wheel only), plus a README.env pointer and the rel-1.15.0...rel-1.16.0 Full Changelog link. The page is republished from the file after merge (see below).
  • CLAUDE.md / README.md: document the new notes-file contract and the rule against hand-editing release pages. The republish command is gh release edit <tag> --notes-file ….

#30: mypy src/ is clean and gated in CI

  • [tool.mypy]: the generated gRPC package is excluded, and imports into it are not followed. grpc is allowed to be missing, scoped to that module only. There is no python_version, because numpy's stubs need 3.12 syntax.
  • [dev] extra: adds types-PyYAML, types-protobuf and pandas-stubs.
  • Type fixes:
    • TimestampInput gets an explicit TypeAlias annotation.
    • timestamp_list() takes a Sequence.
    • MldpClient.annotation / .query are typed X | None.
    • data_frame_image_descriptors() uses a private _image_descriptor() helper that never returns None.
  • Cookbook checker: its preamble narrows client.annotation / .query once. I tried disabling union-attr instead, but that also hid misspelled names, and the checker's self-test caught it.
  • ci.yml: the quality job adds mypy src/ and the release-notes check, and is renamed "Lint, type-check, and docs". main has no required status checks.
  • Deferred to Generate typed Python stubs (.pyi) in generate-python-stubs.yml dp-grpc#158: typed protobuf stubs, after which the gRPC exclusion can be removed and a py.typed marker added.

Verification

  • All pass locally:
    • mypy src/ reports Success.
    • The cookbook checker reports OK: 107 snippets.
    • check-release-notes.py passes on the real notes file and fails on a copy with the wrong tag.
    • ruff lint and format are clean.
    • All 725 unit tests pass.
    • The SHA-pin check is clean.
    • The release-notes checker's self-test fails when a rule is deliberately broken, and the checker rejects the previous rel-1.16.0.md (wheel-only verify, no changelog link) and a copy with a stale changelog tag.
  • The workflow_dispatch rehearsal of release.yml on this branch passed, covering build and sign (run 36059755066). The publish step and the compare step after it run only on a tag push, so they first run for real at rel-1.17.0. Before that, the compare logic was dry-run against the live rel-1.16.0 body.

After merge

Republish rel-1.16.0 from the updated file, so the page gains the Full Changelog link and the three-file verify command:

gh release edit rel-1.16.0 --notes-file doc/release-notes/rel-1.16.0.md

This PR must merge before the rel-1.17.0 tag is pushed.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Bqq8uGF2zNbHW9FU3vfj7Q

craigmcchesney and others added 3 commits September 24, 2026 15:01
…y CI gate

Triage found #56's root cause was wrong: the workflow created the rel-1.16.0 release
(release created_at is the tagged commit's date, not the release's), and the body was
replaced afterwards by a notes-file edit.  The plan makes the notes file the whole
release body, as the Java repos do, and checks it at PR time and after publishing.

For #30, a trialled mypy config brings `mypy src/` from 426 errors to the 3 real
ones; the typed-stub half moved to osprey-dcs/dp-grpc#158.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Bqq8uGF2zNbHW9FU3vfj7Q
…errors (#30)

- [tool.mypy]: exclude the generated grpc package and skip following imports into it
  (both needed), ignore_missing_imports scoped to grpc; no python_version, since numpy's
  stubs need 3.12 syntax.  types-PyYAML, types-protobuf, pandas-stubs join [dev].
- TimestampInput gets an explicit TypeAlias; timestamp_list() takes a Sequence.
- MldpClient.annotation / .query are typed X | None, which they are.
- data_frame_image_descriptors() uses a private _image_descriptor(), non-optional by
  construction, instead of image_descriptor_dict()'s None arm.
- Cookbook checker preamble narrows client.annotation/.query once.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Bqq8uGF2zNbHW9FU3vfj7Q
…r publishing (#56, #30)

- release.yml: stage doc/release-notes/<tag>.md as the body with nothing appended; drop
  generate_release_notes; diff the published body against the file after publishing.
- .dev/tools/check-release-notes.py: every notes file needs a verification section whose
  --cert-identity names its own tag.  Runs in CI's quality job and at tag time.
- ci.yml quality job: add mypy src/ and the release-notes check.
- README.env: release artifacts and verification reference, as in the Java repos.
- rel-1.16.0.md: backport the verification section the live page carries.
- CLAUDE.md / README.md: the new release-notes contract, the no-hand-edits rule, mypy.
- Plan: implementation notes.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Bqq8uGF2zNbHW9FU3vfj7Q
Copilot AI lite review requested due to automatic review settings September 24, 2026 21:10

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.

Copilot review overview

🟡 Changes recommended

The missing changelog link and incomplete verification-command enforcement leave release-contract issues unresolved.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 1 High severity · 1 Medium severity

Open (2)
What changed in this PR

Updates release publishing so notes are verbatim and adds a gated mypy src/ check with supporting documentation and validation tooling.

Changes:

  • Reworks release workflow publication and body verification.
  • Adds release-note and artifact verification checks.
  • Adds mypy configuration, dependencies, and typing fixes.
  • Updates CI and project documentation.
File Description
src/​dp_python_lib/​client/​time_conversions.py Makes the timestamp union an explicit type alias.
src/​dp_python_lib/​client/​mldp_client.py Types optional sub-clients accurately.
src/​dp_python_lib/​client/​data_frame.py Broadens timestamp inputs to Sequence.
src/​dp_python_lib/​client/​data_frame_conversions.py Adds non-optional image descriptor handling.
README.md Updates CI and release documentation.
README.env Documents artifact verification.
pyproject.toml Adds mypy configuration and typing dependencies.
plan/​tickets/​56/​plan.md Records design and implementation decisions.
doc/​release-notes/​rel-1.16.0.md Adds release verification and installation instructions.
CLAUDE.md Documents release and typing conventions.
.github/​workflows/​release.yml Publishes notes verbatim and verifies the live body.
.github/​workflows/​ci.yml Adds mypy and release-note checks.
.dev/​tools/​check-release-notes.py Validates release-note identity and verification content.
.dev/​tools/​check-cookbook-snippets.py Narrows optional client types for mypy.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread doc/release-notes/rel-1.16.0.md
Comment thread .dev/tools/check-release-notes.py Outdated
…d files (#56)

Review follow-up on PR #57.  rel-1.16.0.md lacked the Full Changelog line the plan (Q2)
and CLAUDE.md require, and its backported verify command named the wheel only, although
CLAUDE.md and README.env both say wheel, sdist, and SHA256SUMS.  The checker accepted both.

- rel-1.16.0.md: verify all three files, point to README.env, add the
  rel-1.15.0...rel-1.16.0 Full Changelog link.
- check-release-notes.py: every sigstore verify command must name the wheel, sdist, and
  SHA256SUMS; a Full Changelog compare link must end at the file's own tag and start at an
  earlier one.  A self-test against known-bad samples runs first, so a rule that stops
  matching fails loudly.
- CLAUDE.md, plan: record the rules.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Bqq8uGF2zNbHW9FU3vfj7Q
@craigmcchesney
craigmcchesney merged commit ccf04d8 into main Sep 24, 2026
6 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.

Release body is missing the verification and install instructions (rel-1.16.0) Add mypy to CI: fix real type errors and generate typed protobuf stubs

2 participants