cli: test canonical tags
Add a test to exercise adding canonical reference rules and pushing new canonical tags. A change in `rad id` was required to allow adding a new payload to the document, i.e. one that does not already exist. Adding rules is also documented in the man page for `rad id`.
This commit is contained in:
parent
ff365e2d8b
commit
8201225166
|
|
@ -0,0 +1,213 @@
|
|||
In this example, we will show how we can make other references become canonical.
|
||||
To illustrate, we will use Git tags as an example. The storage of the repository
|
||||
should look something like this by the end of the example:
|
||||
|
||||
~~~
|
||||
storage/z6cFWeWpnZNHh9rUW8phgA3b5yGt/refs
|
||||
├── heads
|
||||
│ └── main
|
||||
├── namespaces
|
||||
│ ├── z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
|
||||
│ │ └── refs
|
||||
│ │ ├── cobs
|
||||
│ │ │ └── xyz.radicle.id
|
||||
│ │ │ └── 865c48204bd7bb7f088b8db90ffdccb48cfa0a50
|
||||
│ │ ├── heads
|
||||
│ │ │ └── master
|
||||
│ │ ├── tags
|
||||
│ │ │ ├── v1.0-hotfix
|
||||
│ │ │ └── v1.0
|
||||
│ │ └── rad
|
||||
│ │ ├── id
|
||||
│ │ └── sigrefs
|
||||
│ └── z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk
|
||||
│ └── refs
|
||||
│ ├── heads
|
||||
│ │ └── master
|
||||
│ ├── tags
|
||||
│ │ ├── v1.0-hotfix
|
||||
│ │ └── v1.0
|
||||
│ └── rad
|
||||
│ ├── id
|
||||
│ └── sigrefs
|
||||
├── rad
|
||||
│ └── id
|
||||
└── tags
|
||||
├── v1.0-hotfix
|
||||
└── v1.0
|
||||
~~~
|
||||
|
||||
Noting that there are tags under `refs/tags` now.
|
||||
|
||||
To start, Alice will add a new payload to the repository identity. The
|
||||
identifier for this payload is `xyz.radicle.crefs`. It contains a single field
|
||||
with the key `rules`, and the value for this key is an array of rules. In this
|
||||
case, we will have two rules: one for `refs/tags/*` and one for `refs/tags/qa/*`
|
||||
(see RIP-0004 for more information on the rules).
|
||||
|
||||
``` ~alice
|
||||
$ rad id update --title "Add canonical reference rules" --payload xyz.radicle.crefs rules '{ "refs/tags/*": { "threshold": 1, "allow": "delegates" }, "refs/tags/qa/*": { "threshold": 1, "allow": "delegates" }}'
|
||||
✓ Identity revision [..] created
|
||||
╭────────────────────────────────────────────────────────────────────────╮
|
||||
│ Title Add canonical reference rules │
|
||||
│ Revision c3349f07bfe6a82bbeb2989d2de4a918408f9831 │
|
||||
│ Blob 85fa09e2de93b825d5231778dbb34143004a4bca │
|
||||
│ Author did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi │
|
||||
│ State accepted │
|
||||
│ Quorum yes │
|
||||
├────────────────────────────────────────────────────────────────────────┤
|
||||
│ ✓ did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi alice (you) │
|
||||
╰────────────────────────────────────────────────────────────────────────╯
|
||||
|
||||
@@ -1,13 +1,25 @@
|
||||
{
|
||||
"payload": {
|
||||
+ "xyz.radicle.crefs": {
|
||||
+ "rules": {
|
||||
+ "refs/tags/*": {
|
||||
+ "allow": "delegates",
|
||||
+ "threshold": 1
|
||||
+ },
|
||||
+ "refs/tags/qa/*": {
|
||||
+ "allow": "delegates",
|
||||
+ "threshold": 1
|
||||
+ }
|
||||
+ }
|
||||
+ },
|
||||
"xyz.radicle.project": {
|
||||
"defaultBranch": "master",
|
||||
"description": "Radicle Heartwood Protocol & Stack",
|
||||
"name": "heartwood"
|
||||
}
|
||||
},
|
||||
"delegates": [
|
||||
"did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
|
||||
],
|
||||
"threshold": 1
|
||||
}
|
||||
```
|
||||
|
||||
Now, Alice will create a tag and push it:
|
||||
|
||||
``` ~alice
|
||||
$ git tag v1.0-hotfix
|
||||
```
|
||||
|
||||
``` ~alice (stderr)
|
||||
$ git push rad --tags
|
||||
✓ Canonical reference refs/tags/v1.0-hotfix updated to f2de534b5e81d7c6e2dcaf58c3dd91573c0a0354
|
||||
✓ Synced with 1 seed(s)
|
||||
To rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
|
||||
* [new tag] v1.0-hotfix -> v1.0-hotfix
|
||||
```
|
||||
|
||||
Notice that the output included a message about a canonical reference being
|
||||
updated:
|
||||
|
||||
~~~
|
||||
✓ Canonical reference refs/tags/v1.0-hotfix updated to f2de534b5e81d7c6e2dcaf58c3dd91573c0a0354
|
||||
~~~
|
||||
|
||||
On the other side, Bob performs a fetch and now has the tags locally:
|
||||
|
||||
``` ~bob (stderr)
|
||||
$ cd heartwood
|
||||
$ git fetch rad
|
||||
From rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji
|
||||
* [new tag] v1.0-hotfix -> rad/tags/v1.0-hotfix
|
||||
* [new tag] v1.0-hotfix -> v1.0-hotfix
|
||||
```
|
||||
|
||||
In the next portion of this example, we want to show that using a `threshold` of
|
||||
`2` requires both delegates. To do this, Bob creates a `master` reference, Alice
|
||||
adds him as a remote, and adds him to the identity delegates, as well as setting
|
||||
the `threshold` to `2` for the `refs/tags/*` rule:
|
||||
|
||||
``` ~bob
|
||||
$ rad remote add z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi --name alice
|
||||
✓ Follow policy updated for z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi (alice)
|
||||
Fetching rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji from the network, found 1 potential seed(s).
|
||||
✓ Target met: 1 seed(s)
|
||||
✓ Remote alice added
|
||||
✓ Remote-tracking branch alice/master created for z6MknSL…StBU8Vi
|
||||
$ git push rad master
|
||||
```
|
||||
|
||||
``` ~alice
|
||||
$ rad remote add z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk --name bob
|
||||
✓ Follow policy updated for z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk (bob)
|
||||
Fetching rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji from the network, found 1 potential seed(s).
|
||||
✓ Target met: 1 seed(s)
|
||||
✓ Remote bob added
|
||||
✓ Remote-tracking branch bob/master created for z6Mkt67…v4N1tRk
|
||||
$ rad id update --title "Add Bob" --delegate did:key:z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk --no-confirm -q
|
||||
27ab0d77a95581c59ca9d30e679ceb06a9f758db
|
||||
$ rad id update --title "Update canonical reference rules" --payload xyz.radicle.crefs rules '{ "refs/tags/*": { "threshold": 2, "allow": "delegates" }, "refs/tags/qa/*": { "threshold": 1, "allow": "delegates" } }' -q
|
||||
dace164ba43fa51802697ec28d0b1965a9d7808b
|
||||
```
|
||||
|
||||
**Note:** here we have to specify all the rules again to update the `threshold`.
|
||||
In reality, you can use `rad id update --edit` and edit the payload in your
|
||||
editor instead.
|
||||
|
||||
``` ~bob
|
||||
$ rad sync -f
|
||||
Fetching rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji from the network, found 1 potential seed(s).
|
||||
✓ Target met: 1 seed(s)
|
||||
🌱 Fetched from z6MknSL…StBU8Vi
|
||||
$ rad id accept dace164ba43fa51802697ec28d0b1965a9d7808b -q
|
||||
```
|
||||
|
||||
When Bob creates a new tag and pushes it, we see that there's a warning that
|
||||
no quorum was found for the new tag:
|
||||
|
||||
``` ~bob (stderr)
|
||||
$ git tag v2.0
|
||||
$ git push rad --tags
|
||||
warn: could not determine commit for canonical reference 'refs/tags/v2.0', no commit with at least 2 vote(s) found (threshold not met)
|
||||
warn: it is recommended to find a commit to agree upon
|
||||
✓ Synced with 1 seed(s)
|
||||
To rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk
|
||||
* [new tag] v1.0-hotfix -> v1.0-hotfix
|
||||
* [new tag] v2.0 -> v2.0
|
||||
```
|
||||
|
||||
Alice can then fetch and checkout the new tag, create one on her side, and push
|
||||
it:
|
||||
|
||||
``` ~alice (stderr)
|
||||
$ git fetch bob
|
||||
From rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk
|
||||
* [new tag] v1.0-hotfix -> bob/tags/v1.0-hotfix
|
||||
* [new tag] v2.0 -> bob/tags/v2.0
|
||||
```
|
||||
|
||||
``` ~alice
|
||||
$ git checkout bob/tags/v2.0
|
||||
$ git tag v2.0
|
||||
```
|
||||
|
||||
``` ~alice (stderr)
|
||||
$ git push rad --tags
|
||||
✓ Canonical reference refs/tags/v2.0 updated to f2de534b5e81d7c6e2dcaf58c3dd91573c0a0354
|
||||
✓ Synced with 1 seed(s)
|
||||
To rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
|
||||
* [new tag] v2.0 -> v2.0
|
||||
```
|
||||
|
||||
Now that Bob has also pushed this tag, we can see that the tag was made
|
||||
canonical.
|
||||
|
||||
For the final portion of the example, we will show that both delegates aren't
|
||||
required for pushing tags that match the rule `refs/tags/qa/*`. To show this,
|
||||
Bob will create a tag and push it, and we should see that the canonical
|
||||
reference is created:
|
||||
|
||||
``` ~bob (stderr)
|
||||
$ git tag qa/v2.1
|
||||
$ git push rad --tags
|
||||
✓ Canonical reference refs/tags/qa/v2.1 updated to f2de534b5e81d7c6e2dcaf58c3dd91573c0a0354
|
||||
✓ Synced with 1 seed(s)
|
||||
To rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk
|
||||
* [new tag] qa/v2.1 -> qa/v2.1
|
||||
```
|
||||
|
|
@ -2517,6 +2517,48 @@ fn git_tag() {
|
|||
.unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn git_push_canonical_tags() {
|
||||
let mut environment = Environment::new();
|
||||
let alice = environment.node("alice");
|
||||
let bob = environment.node("bob");
|
||||
|
||||
let rid = RepoId::from_str("z42hL2jL4XNk6K8oHQaSWfMgCL7ji").unwrap();
|
||||
|
||||
fixtures::repository(environment.work(&alice));
|
||||
|
||||
test(
|
||||
"examples/rad-init.md",
|
||||
environment.work(&alice),
|
||||
Some(&alice.home),
|
||||
[],
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let alice = alice.spawn();
|
||||
let mut bob = bob.spawn();
|
||||
|
||||
bob.connect(&alice).converge([&alice]);
|
||||
bob.clone(rid, environment.work(&bob)).unwrap();
|
||||
formula(
|
||||
&environment.tempdir(),
|
||||
"examples/git/git-push-canonical-tags.md",
|
||||
)
|
||||
.unwrap()
|
||||
.home(
|
||||
"alice",
|
||||
environment.work(&alice),
|
||||
[("RAD_HOME", alice.home.path().display())],
|
||||
)
|
||||
.home(
|
||||
"bob",
|
||||
environment.work(&bob),
|
||||
[("RAD_HOME", bob.home.path().display())],
|
||||
)
|
||||
.run()
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rad_workflow() {
|
||||
let mut environment = Environment::new();
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ rad-id - Manage changes to a Radicle repository's identity.
|
|||
*rad id* _edit_ <revision-id> [--title <string>] [--description <string>] [<option>...] +
|
||||
*rad id* _show_ <revision-id> [<option>...] +
|
||||
*rad id* _accept_ | _reject_ <revision-id> [<option>...] +
|
||||
*rad id* _redact_ <revision-id> [<option>...]
|
||||
*rad id* _redact_ <revision-id> [<option>...] +
|
||||
|
||||
== Description
|
||||
|
||||
|
|
@ -176,3 +176,49 @@ To remove a delegate and update the threshold, use the *--rescind* option:
|
|||
As with adding a delegate, this change will require approval from the remaining
|
||||
delegates. Make sure you set an appropriate new threshold when removing
|
||||
delegates!
|
||||
|
||||
=== Adding Canonical References Rules
|
||||
|
||||
To update the canonical reference rules of the project, use the `--payload
|
||||
xyz.radicle.crefs` option while updating, `rules` as the key, and the rules
|
||||
object as the value. Here is an example below:
|
||||
|
||||
$ rad id update --title "Update canonical reference rules" \
|
||||
--payload xyz.radicle.crefs rules '{
|
||||
"refs/heads/master": { "threshold": 1, "allow": "delegates" },
|
||||
"refs/tags/*": { "threshold": 2, "allow": "delegates" },
|
||||
"refs/tags/qa/*": { "threshold": 1, "allow": "delegates" }
|
||||
}'
|
||||
|
||||
Alternatively, you can use the `--edit` option for the `update` command and edit
|
||||
the payload directly. Here is an example of what that may look like:
|
||||
|
||||
{
|
||||
"payload": {
|
||||
"xyz.radicle.crefs": {
|
||||
"rules": {
|
||||
"refs/heads/master": {
|
||||
"allow": "delegates",
|
||||
"threshold": 1
|
||||
},
|
||||
"refs/tags/*": {
|
||||
"allow": "delegates",
|
||||
"threshold": 1
|
||||
},
|
||||
"refs/tags/qa/*": {
|
||||
"allow": "delegates",
|
||||
"threshold": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
"xyz.radicle.project": {
|
||||
"defaultBranch": "master",
|
||||
"description": "Radicle Heartwood Protocol & Stack",
|
||||
"name": "heartwood"
|
||||
}
|
||||
},
|
||||
"delegates": [
|
||||
"did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
|
||||
],
|
||||
"threshold": 1
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue