Repository navigation
Add a snippet-based release note approach #3034
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| # SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. | ||
| # | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| name: Fetch release history | ||
|
|
||
| description: >- | ||
| Complete a shallow checkout with the git history needed to build release | ||
| notes (see cuda_python/docs/exts/release_notes.py): the history of the | ||
| checked-out commit and of every tag. No branches are fetched, which also | ||
| leaves out the large gh-pages branch that holds only built docs. | ||
|
|
||
| runs: | ||
| using: composite | ||
| steps: | ||
| - name: Fetch the checked-out commit's history and all tags | ||
| shell: bash --noprofile --norc -xeuo pipefail {0} | ||
| run: | | ||
| # Run after actions/checkout with its default fetch-depth of 1. | ||
| # Release notes are read from the history reachable from release tags | ||
| # (patch tags may sit on maintenance branches) and from the commit being | ||
| # built, so no branch names are needed. | ||
| refspecs=("$(git rev-parse HEAD)" '+refs/tags/*:refs/tags/*') | ||
| if [[ "$(git rev-parse --is-shallow-repository)" == "true" ]]; then | ||
| git fetch --unshallow --no-tags origin "${refspecs[@]}" | ||
| else | ||
| git fetch --no-tags origin "${refspecs[@]}" | ||
| fi |
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -28,7 +28,12 @@ Thank you for your interest in contributing to CUDA Python! Based on the type of | |||||||||||
| - [Enabling git symlinks](#enabling-git-symlinks) | ||||||||||||
| - [Type stubs for cuda.core](#type-stubs-for-cudacore) | ||||||||||||
| - [Pre-commit](#pre-commit) | ||||||||||||
| - [Release notes](#release-notes) | ||||||||||||
| - [Writing a release note](#writing-a-release-note) | ||||||||||||
| - [Known issues](#known-issues) | ||||||||||||
| - [How release notes are assembled](#how-release-notes-are-assembled) | ||||||||||||
| - [Pixi lockfiles](#pixi-lockfiles) | ||||||||||||
| - [Secret Scanning](#secret-scanning) | ||||||||||||
| - [Signing Your Work](#signing-your-work) | ||||||||||||
| - [Code signing](#code-signing) | ||||||||||||
| - [Developer Certificate of Origin (DCO)](#developer-certificate-of-origin-dco) | ||||||||||||
|
|
@@ -235,6 +240,106 @@ between commits, leaving stale headers or out-of-date stubs in the history. | |||||||||||
| If the hook isn't installed, `pre-commit run` will print a visible warning | ||||||||||||
| reminding you to run `pre-commit install`. | ||||||||||||
|
|
||||||||||||
| ## Release notes | ||||||||||||
|
|
||||||||||||
| Release notes are one small reStructuredText file per change, kept next to the code in the | ||||||||||||
| PR that makes the change. (The design is inspired by | ||||||||||||
| [reno](https://docs.openstack.org/reno/latest/), but behaves quite differently.) | ||||||||||||
| All four packages work this way: `cuda-bindings` and | ||||||||||||
| `cuda-python` (13.5.0 and later), `cuda-core` (1.3.0 and later) and | ||||||||||||
| `cuda-pathfinder` (1.9.0 and later), with notes in | ||||||||||||
| `<package>/releasenotes/`. Earlier releases keep their hand-written pages | ||||||||||||
| under `<package>/docs/source/release/`. | ||||||||||||
|
|
||||||||||||
| ### Writing a release note | ||||||||||||
|
|
||||||||||||
| Every pull request that changes the sources of one of these packages needs a | ||||||||||||
| release note for it, or an edit to an existing one (a PR touching multiple | ||||||||||||
| packages needs one for each). Changes to docs, tests, examples, and CI do not | ||||||||||||
| need one. A CI check enforces this. If a PR touches the sources but truly needs | ||||||||||||
| no note, a maintainer can apply the `skip-release-note` label. | ||||||||||||
|
|
||||||||||||
| Create a note with the `add_note.py` script. It can be run from any directory, | ||||||||||||
| and takes the package, the type of note and a few words describing the change: | ||||||||||||
|
|
||||||||||||
| ```bash | ||||||||||||
| python toolshed/add_note.py cuda-core fix "Fix the thing" [--edit] | ||||||||||||
| ``` | ||||||||||||
|
|
||||||||||||
| The package is one of `cuda-bindings`, `cuda-core`, `cuda-pathfinder` and | ||||||||||||
| `cuda-python` (the `cuda-` prefix is optional). The type is one of the values in | ||||||||||||
| the table below. The new file is created in `<package>/releasenotes/` and named | ||||||||||||
| `<type>-<short-description>-<hash>.rst`. `--edit` opens it in `$VISUAL` or | ||||||||||||
| `$EDITOR`. | ||||||||||||
|
|
||||||||||||
| Edit the new file and replace the `TODO` text. A note is reStructuredText, | ||||||||||||
| written for users of the package, and has exactly one type, which is the start | ||||||||||||
| of its file name. A change that needs two kinds of entry, such as a bug fix that | ||||||||||||
| is also a breaking change, gets two notes. A pre-commit hook checks the notes | ||||||||||||
| for obvious mistakes, such as an unknown type or leftover `TODO` text. | ||||||||||||
|
|
||||||||||||
| | Type | Use for | | ||||||||||||
| |---|---| | ||||||||||||
| | `feature` | New functionality, including experimental APIs (say so in the text) | | ||||||||||||
| | `upgrade` | Changes users may need to act on, including behavior changes | | ||||||||||||
| | `deprecation` | Newly deprecated functionality | | ||||||||||||
| | `critical` | Critical issues users must know about | | ||||||||||||
| | `security` | Security issues | | ||||||||||||
| | `fix` | Bug fixes | | ||||||||||||
| | `issue` | Known issues (see below) | | ||||||||||||
| | `other` | Anything else | | ||||||||||||
| | `prelude` | An introduction to a release's notes. Useful to highlight important themes in a release. | | ||||||||||||
|
|
||||||||||||
| Some details: | ||||||||||||
|
|
||||||||||||
| * You do not need to add a link to the pull request: one is added automatically, | ||||||||||||
| taken from the `(#N)` in the squash-merge commit that introduced the note. | ||||||||||||
| * To name the pull request(s) yourself instead, write `(#1234)` or | ||||||||||||
| `(#1234, #1235)` anywhere in a note, usually at the end. Each marker is | ||||||||||||
| replaced with links, and the automatic lookup is skipped for that note. This | ||||||||||||
| is rarely needed. It is for a note whose file is added by a different PR than | ||||||||||||
| the one that made the change, for example a note written afterwards or notes | ||||||||||||
| moved in from another place. The marker can go anywhere in ordinary text. A | ||||||||||||
| `(#N)` inside backquoted text, such as an inline literal, is left alone, so | ||||||||||||
| it can be used in an example. Do not put a marker inside a literal block, or | ||||||||||||
| the rows of a table or other directive content, where the link text could | ||||||||||||
| break the markup. | ||||||||||||
| * Do not rename or move a note after it is merged. | ||||||||||||
| * Which releases list a note is decided from git, so a note shows up in a local | ||||||||||||
| docs build only once it is committed. | ||||||||||||
| * You can fix a note that is already part of a release (a typo, or a clearer | ||||||||||||
| wording). The docs are published from `main`, and every page shows a note's | ||||||||||||
| current text, so the fix appears on the pages of the releases that list it | ||||||||||||
| the next time the docs are published. Editing a note never moves it to | ||||||||||||
| another release. | ||||||||||||
|
|
||||||||||||
| ### Known issues | ||||||||||||
|
|
||||||||||||
| Unlike the other types, which appear only on the release that first contains | ||||||||||||
| them, known issues are listed on **every** release until they are resolved. To | ||||||||||||
| record one, add a note of type `issue`. To resolve it, delete that note in the | ||||||||||||
| PR that fixes the problem, and describe the fix in a new `fix` note. The pages of releases that were already | ||||||||||||
| tagged keep listing the issue, with the text it had when its note was deleted. | ||||||||||||
|
|
||||||||||||
| ### How release notes are assembled | ||||||||||||
|
|
||||||||||||
| The docs build generates a page for every release from the notes in git, | ||||||||||||
| with a final "In development" page for notes that are not in any release yet. | ||||||||||||
| Only plain `vX.Y.Z` tags count as releases. Pre-release tags (`rc`, `a`, `b`) | ||||||||||||
| are ignored, and their notes roll into the final release. | ||||||||||||
|
Comment on lines
+328
to
+329
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win suggestion: Fix the tag format in the release-tag rule. Line 328 says only plain --- "a/CONTRIBUTING.md"
+++ "b/CONTRIBUTING.md"
@@ -325,7 +325,8 @@
The docs build generates a page for every release from the notes in git,
with a final "In development" page for notes that are not in any release yet.
-Only plain `vX.Y.Z` tags count as releases. Pre-release tags (`rc`, `a`, `b`)
+Only plain `<prefix>X.Y.Z` release tags count (`v` for `cuda-bindings` and
+`cuda-python`, `cuda-core-v` and `cuda-pathfinder-v` for the others). Pre-release tags (`rc`, `a`, `b`)
are ignored, and their notes roll into the final release.
* A minor release (`X.Y.0`) lists the notes added since the previous minor📝 Committable suggestion
Suggested change
|
||||||||||||
|
|
||||||||||||
| * A minor release (`X.Y.0`) lists the notes added since the previous minor | ||||||||||||
| release. | ||||||||||||
| * A patch release lists the notes added since the previous release of the same | ||||||||||||
| `X.Y` line. | ||||||||||||
| * A note that is backported appears on the patch release page and again on the | ||||||||||||
| page of the next minor release that contains it. This is intentional. | ||||||||||||
|
|
||||||||||||
| Building the docs needs the history of the checked-out commit and of every release | ||||||||||||
| tag (no branches), and the build fails on a shallow clone rather than produce incomplete | ||||||||||||
| pages. In CI, the `.github/actions/fetch-release-history` action does this. The | ||||||||||||
| rules are documented in `cuda_python/docs/exts/release_notes.py`. | ||||||||||||
|
|
||||||||||||
| ## Pixi lockfiles | ||||||||||||
|
|
||||||||||||
| The repository checks in a `pixi.lock` next to each `pixi.toml`. Those lockfiles | ||||||||||||
|
|
||||||||||||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
🔎 Supported by static analysis
🏁 Script executed:
Repository: NVIDIA/cuda-python
Length of output: 34102
🏁 Script executed:
Repository: NVIDIA/cuda-python
Length of output: 12970
🏁 Script executed:
Repository: NVIDIA/cuda-python
Length of output: 13451
important: Keep release-history fetching independent of the checked-out release tag.
Each workflow checks out the release tag before it invokes
./.github/actions/fetch-release-history. Tags created before this PR do not containaction.yml, so the release can stop withCan't find 'action.yml'before the release-note check. This affects the configured maintenance-branch backport flow and oldercuda-pathfinder1.8.x tags.Inline the fetch command in all three workflows:
Apply this change to
.github/workflows/release.yml,.github/workflows/build-docs.yml, and.github/workflows/release-cuda-pathfinder.yml.🧰 Tools
🪛 zizmor (1.30.1)
[warning] 162-167: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false
(artipacked)
[warning] 5-285: overly broad permissions (excessive-permissions): default permissions used due to no permissions: block
(excessive-permissions)
[warning] 158-181: overly broad permissions (excessive-permissions): default permissions used due to no permissions: block
(excessive-permissions)
[warning] 169-169: use GitHub's dedicated self-repository syntax (self-repository): use '$/...' instead of './...'
(self-repository)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I follow. The action should be available from every commit it is called from. Can you describe the scenario in which this would fail?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mdboom important: The workflow definition and the checked-out files can come from different commits.
The failure scenario is:
main.main, withgit-tagset to a tag created before this PR.actions/checkoutchecks out that tag because the step setsref: ${{ inputs.git-tag }}../.github/actions/fetch-release-history.GitHub resolves a
./action from the checked-out workspace, not from the commit that supplied the workflow definition. If the selected tag lacks.github/actions/fetch-release-history/action.yml, the action cannot load.The action is available in the commit that defines the workflow, as you describe. The preceding checkout replaces the workspace with a different commit.
If releases only target tags that contain this action, this failure does not occur. My concern is running the updated workflow against older tags or maintenance-branch tags that do not contain it.
You are interacting with an AI system.