From 6e6b9877b32b44e84c0f3c3d412d688cf86761b0 Mon Sep 17 00:00:00 2001 From: DanConwayDev <114834599+DanConwayDev@users.noreply.github.com> Date: Thu, 16 Oct 2025 18:08:48 +0100 Subject: [PATCH] NIP-34: add PR and PR update events (#1966) --- 34.md | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++----- README.md | 5 +++ 2 files changed, 89 insertions(+), 8 deletions(-) diff --git a/34.md b/34.md index ab80a936..d35c0eb2 100644 --- a/34.md +++ b/34.md @@ -10,7 +10,7 @@ This NIP defines all the ways code collaboration using and adjacent to [`git`](h ## Repository announcements -Git repositories are hosted in Git-enabled servers, but their existence can be announced using Nostr events, as well as their willingness to receive patches, bug reports and comments in general. +Git repositories are hosted in Git-enabled servers, but their existence can be announced using Nostr events. By doing so the author asserts themselves as a maintainer and expresses a willingness to receive patches, bug reports and comments in general, unless `t` tag `personal-fork` is included. ```jsonc { @@ -25,6 +25,7 @@ Git repositories are hosted in Git-enabled servers, but their existence can be a ["relays", "", ...], // relays that this repository will monitor for patches and issues ["r", "", "euc"], ["maintainers", "", ...], + ["t","personal-fork"], // optionally indicate author isn't a maintainer ["t", ""], // hashtags labelling the repository ] } @@ -66,9 +67,13 @@ The `refs` tag can be optionally extended to enable clients to identify how many } ``` -## Patches +## Patches and Pull Requests (PRs) -Patches can be sent by anyone to any repository. Patches to a specific repository SHOULD be sent to the relays specified in that repository's announcement event's `"relays"` tag. Patch events SHOULD include an `a` tag pointing to that repository's announcement address. +Patches and PRs can be sent by anyone to any repository. Patches and PRs to a specific repository SHOULD be sent to the relays specified in that repository's announcement event's `"relays"` tag. Patch and PR events SHOULD include an `a` tag pointing to that repository's announcement address. + +Patches SHOULD be used if each event is under 60kb, otherwise PRs SHOULD be used. + +### Patches Patches in a patch set SHOULD include a [NIP-10](10.md) `e` `reply` tag pointing to the previous patch. @@ -103,9 +108,66 @@ The first patch revision in a patch revision SHOULD include a [NIP-10](10.md) `e The first patch in a series MAY be a cover letter in the format produced by `git format-patch`. +### Pull Requests + +The PR or PR update tip SHOULD be successfully pushed to `refs/nostr/<[PR|PR-Update]-event-id>` in all repositories listed in its `clone` tag before the event is signed. + +An attempt SHOULD be made to push this ref to all repositories listed in the repository's announcement event's `"clone"` tag, for which their is reason to believe the user might have write access. This includes each [grasp server](https://njump.me/naddr1qvzqqqrhnypzpgqgmmc409hm4xsdd74sf68a2uyf9pwel4g9mfdg8l5244t6x4jdqy28wumn8ghj7un9d3shjtnwva5hgtnyv4mqqpt8wfshxuqlnvh8x) which can be identified using this method: `clone` tag includes `[http|https]:////.git` and `relays` tag includes `[ws/wss]://`. + +Clients MAY fallback to creating a 'personal-fork' `repository announcement` listing other grasp servers, e.g. from the `User grasp list`, for the purpose of serving the specified commit(s). + +```jsonc +{ + "kind": 1618, + "content": "", + "tags": [ + ["a", "30617::"], + ["r", ""] // so clients can subscribe to all PRs sent to a local git repo + ["p", ""], + ["p", ""], // optionally send the PR to another user to bring it to their attention + + ["subject", ""], + ["t", ""], // optional + ["t", ""], // optional + + ["c", ""], // tip of the PR branch + ["clone", "", ...], // at least one git clone url where commit can be downloaded + ["branch-name", ""], // optional recommended branch name + + ["e", ""], // optionally indicate PR is a revision of an existing patch, which should be closed + ["merge-base", ""], // optional: the most recent common ancestor with the target branch + ] +} +``` + +### Pull Request Updates + +A PR Update changes the tip of a referenced PR event. + +```jsonc +{ + "kind": 1619, + "content": "", + "tags": [ + ["a", "30617::"], + ["r", ""] // so clients can subscribe to all PRs sent to a local git repo + ["p", ""], + ["p", ""], // optionally send the PR to another user to bring it to their attention + + // NIP-22 tags + ["E", ""], + ["P", ""], + + ["c", ""], // updated tip of PR + ["clone", "", ...], // at least one git clone url where commit can be downloaded + ["merge-base", ""], // optional: the most recent common ancestor with the target branch + ] +} +``` + ## Issues -Issues are Markdown text that is just human-readable conversational threads related to the repository: bug reports, feature requests, questions or comments of any kind. Like patches, these SHOULD be sent to the relays specified in that repository's announcement event's `"relays"` tag. +Issues are Markdown text that is just human-readable conversational threads related to the repository: bug reports, feature requests, questions or comments of any kind. Like patches, these SHOULD be sent to the relays specified in that repository's announcement event's `"relays"` tag. Issues may have a `subject` tag, which clients can utilize to display a header. Additionally, one or more `t` tags may be included to provide labels for the issue. @@ -125,11 +187,11 @@ Issues may have a `subject` tag, which clients can utilize to display a header. ## Replies -Replies to either a `kind:1621` (_issue_) or a `kind:1617` (_patch_) event should follow [NIP-22 comment](22.md). +Replies to either a `kind:1621` (_issue_), `kind:1617` (_patch_) or `kind:1618` (_pull request_) event should follow [NIP-22 comment](22.md). ## Status -Root Patches and Issues have a Status that defaults to 'Open' and can be set by issuing Status events. +Root Patches, PRs and Issues have a Status that defaults to 'Open' and can be set by issuing Status events. ```jsonc { @@ -139,7 +201,7 @@ Root Patches and Issues have a Status that defaults to 'Open' and can be set by "kind": 1633, // Draft "content": "", "tags": [ - ["e", "", "", "root"], + ["e", "", "", "root"], ["e", "", "", "reply"], // for when revisions applied ["p", ""], ["p", ""], @@ -165,8 +227,22 @@ The most recent Status event (by `created_at` date) from either the issue/patch The Status of a patch-revision is to either that of the root-patch, or `1632` (_Closed_) if the root-patch's Status is `1631` (_Applied/Merged_) and the patch-revision isn't tagged in the `1631` (_Applied/Merged_) event. +## User grasp list + +List of [grasp servers](https://njump.me/naddr1qvzqqqrhnypzpgqgmmc409hm4xsdd74sf68a2uyf9pwel4g9mfdg8l5244t6x4jdqy28wumn8ghj7un9d3shjtnwva5hgtnyv4mqqpt8wfshxuqlnvh8x) the user generally wishes to use for NIP-34 related activity. It is similar in function to the NIP-65 relay list and NIP-B7 blossom list. + +The event SHOULD include a list of `g` tags with grasp service websocket URLs in order of preference. + +```jsonc +{ + "kind": 10317, + "content": "", + "tags": [ + ["g", ""], // zero or more grasp sever urls + ] +} +``` ## Possible things to be added later -- "branch merge" kind (specifying a URL from where to fetch the branch to be merged) - inline file comments kind (we probably need one for patches and a different one for merged files) diff --git a/README.md b/README.md index f5194ded..445876e1 100644 --- a/README.md +++ b/README.md @@ -160,6 +160,8 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos | `1311` | Live Chat Message | [53](53.md) | | `1337` | Code Snippet | [C0](C0.md) | | `1617` | Patches | [34](34.md) | +| `1618` | Pull Requests | [34](34.md) | +| `1619` | Pull Request Updates | [34](34.md) | | `1621` | Issues | [34](34.md) | | `1622` | Git Replies (deprecated) | [34](34.md) | | `1630`-`1633` | Status | [34](34.md) | @@ -317,6 +319,7 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos | ----------------- | ------------------------------------ | ------------------------------- | -------------------------------------------------- | | `a` | coordinates to an event | relay URL | [01](01.md) | | `A` | root address | relay URL | [22](22.md) | +| `c` | commit id | | [34](34.md) | | `d` | identifier | -- | [01](01.md) | | `e` | event id (hex) | relay URL, marker, pubkey (hex) | [01](01.md), [10](10.md) | | `E` | root event id | relay URL | [22](22.md) | @@ -345,6 +348,7 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos | `alt` | summary | -- | [31](31.md) | | `amount` | millisatoshis, stringified | -- | [57](57.md) | | `bolt11` | `bolt11` invoice | -- | [57](57.md) | +| `branch-name` | branch name suggestion | -- | [34](34.md) | | `challenge` | challenge string | -- | [42](42.md) | | `client` | name, address | relay URL | [89](89.md) | | `clone` | git clone URL | -- | [34](34.md) | @@ -358,6 +362,7 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos | `expiration` | unix timestamp (string) | -- | [40](40.md) | | `file` | full path (string) | -- | [35](35.md) | | `goal` | event id (hex) | relay URL | [75](75.md) | +| `merge-base` | commit id | | [34](34.md) | | `HEAD` | `ref: refs/heads/` | | [34](34.md) | | `image` | image URL | dimensions in pixels | [23](23.md), [52](52.md), [58](58.md) | | `imeta` | inline metadata | -- | [92](92.md) |