A read-only clone of the dehub project, for until dehub.dev can be brought back online.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
dehub/docs/tut3.md

246 lines
8.0 KiB

# Tutorial 3: Commit Sign-Off
Commit sign-off is a common pattern in vanilla git projects, where a commit must
be approved by one or more people (besides the commit author themselves) in
order to be allowed into the primary branch.
dehub is able to accomplish this same pattern using only the access controls
which have already been covered in this tutorial series and a command which has
not: `dehub combine`. This tutorial will guide you through using `dehub combine`
to facilitate commit sign-off.
This tutorial assumes you have already completed [Tutorial 2](tut2.html), and
builds on top of the project which was started there.
## Step 0: Loosen the Previous Restrictions
In the [previous tutorial](tut2.html) you took an existing project, added a new
user `tot` to it, and then restricted `tot` to only be allowed to make commits
in a certain subset of branches which excluded the `main` branch.
As seen in that tutorial, `tot` is not able to create commits for the `main`
branch _at all_. In this tutorial we're going to open `main` back up to `tot`,
but only with a very important caveat: `tot`'s commits must be approved by
someone else.
In the `hello-world` project which was used for previous tutorials, with the
`main` branch checked out, go ahead and modify `.dehub/config.yml` to have the
following contents:
```
# contents of .dehub/config.yml
---
accounts:
- id: tut
signifiers:
- type: pgp_public_key_file
path: ".dehub/tut.asc"
- id: tot
signifiers:
- type: pgp_public_key_file
path: ".dehub/tot.asc"
access_controls:
- action: allow
filters:
- type: signature
account_ids:
- tot
- type: branch
pattern: tot/*
- action: deny
filters:
- type: branch
pattern: main
- type: not
filter:
type: signature
any_account: true
count: 2
```
and commit the changes:
```
git add .dehub/config.yml
dehub commit --as tut change --descr 'require commit sign-offs in main'
```
The primary change was to replace the old access control denying `tot` the
ability to commit to anything (outside of `tot/*` branches) with this one:
```
- action: deny
filters:
- type: branch
pattern: main
- type: not
filter:
type: signature
any_account: true
count: 2
```
There are two new things here. The first is the new fields on the `signature`
filter: `any_account` replaces the `account_ids` field, and refers to any
account which is defined in the `accounts` section; `count` declares how many
accounts must have a signature on the commit for the filter to match (if not
specified it defaults to 1).
The second new thing is the `not` filter: `not` wraps any other filter, and
reverses whether or not it matches. In this case, it's wrapping our `signature`
filter, such that this access control will match only if the commit _does not_
have signature credentials from 2 different accounts.
The total effect of this access control is to deny any commits to `main` which
have not been signed-off by 2 different accounts.
## Step 1: Some Changes to Merge
In the previous tutorial `tot` created a new script, `echo.sh`, in a new branch
called `tot/echo-script`. Check that branch out, rebase it on `main` (this will
help in later steps), and add another script to it:
```
git checkout tot/echo-script
git rebase main
echo 'echo "$@" | awk "{ print toupper(\$0) }"' > echo-upper.sh
git add echo-upper.sh
dehub commit --as tot change --descr 'echo-upper.sh'
```
Now the `tot/echo-script` branch contains two commits which aren't on `main`,
both of them signed by `tot`. What will happen next is that the branch's commits
will be combined into a single commit, be given accreditation by both `tut` and
`tot`, and added to the `main` branch.
## Step 2: Accreditation
First, `tot` will accredit both commits, and unify the two descriptions in the
process. To do this, you will create your first `credential` commit:
```
dehub commit --as tot credential --start HEAD^^ --descr 'add echo.sh and echo-upper.sh'
```
A `credential` commit, at its core, contains nothing except credentials for any
arbitrary fingerprint. To view the credential commit you just made
do: `git show`. You should see a commit message like:
```
Credential of AO3dn4Se61hq6OWy4Lm6m3MxdT2ru6TrIobuHaWJJidt
---
type: credential
commits:
- f085f13fa839ece122476601d970460ac249dc69 # these will be different
- 40a81ffb4f52dc4149570672f7f7fc053f12226a
change_description: add echo.sh and echo-upper.sh
fingerprint: AO3dn4Se61hq6OWy4Lm6m3MxdT2ru6TrIobuHaWJJidt
credentials:
- type: pgp_signature
pub_key_id: XXX
body: BIG LONG STRING
account: tot
```
You'll notice that the credential commit's fingerprint is different than either
of the two commits it accredits. This is the fingerprint is based on the
_combination_ of the two commits; it is based on the total of the file changes
and the description provided by the user. The two commits are enumerated in the
`commits` field of the payload, and the description provided by the user is
stored in the `change_description` field.
The combined commits have now been accredited by `tot`, but not `tut`, and so
they still lack a necessary credential. Have `tut` make a credential now:
```
dehub commit --as tut credential --rev HEAD
```
This form of the `credential` sub-command only accredits a single commit. When a
single commit is accredited and it itself is a credential commit then the new
commit which is created is merely a copy of the specified credential commit with
the caller's own credential appended to the `credentials` list. You can see this
with `git show`, which should look like:
```
Credential of AO3dn4Se61hq6OWy4Lm6m3MxdT2ru6TrIobuHaWJJidt
---
type: credential
commits:
- f085f13fa839ece122476601d970460ac249dc69 # these will be different
- 40a81ffb4f52dc4149570672f7f7fc053f12226a
change_description: add echo.sh and echo-upper.sh
fingerprint: AO3dn4Se61hq6OWy4Lm6m3MxdT2ru6TrIobuHaWJJidt
credentials:
- type: pgp_signature
pub_key_id: XXX
body: BIG LONG STRING
account: tot
- type: pgp_signature
pub_key_id: XXX
body: BIG LONG STRING
account: tut
```
There are now enough credentials to combine the commits in the `tot/echo-script`
branch into a single commit on the `main` branch.
## Step 3: Combination
At this point the `tot/echo-script` branch has the following elements in place:
* Two change commits, which we want to combine and bring over to `main`.
* A credential commit made by `tot` for the combined changes.
* A credential commit made by `tut` for the combined changes, which includes
`tot`'s credentials.
Combining the commits and placing them on `main` is done with a single command:
```
dehub combine --start HEAD^^^^ --end HEAD --onto main
```
This `combine` command combines all changes made within the given commit range,
the last change description found in that range (in this case it will be from
`tut`'s credential commit), and all credentials for that set of changes. The
command combines them into a single commit which it places on the `main` branch.
You can see the commit you've just created by doing:
```
git checkout main
git show
```
The commit should contain both of the new files, and the message should look
something like:
```
add echo.sh and echo-upper.sh
---
type: change
description: add echo.sh and echo-upper.sh
fingerprint: ALOcEuKJkgIdz27z0fjF1NEbK6Y9cEh2RH4/sL3uf3oa
credentials:
- type: pgp_signature
pub_key_id: XXX
body: BIG LONG BODY
account: tot
- type: pgp_signature
pub_key_id: XXX
body: BIG LONG BODY
account: tut
```
The commit is accredited by two different accounts, and so is allowed to be on
the `main` branch. This can be verified by doing `dehub verify`.
You now are able to require commit sign-off and create signed-off commits! The
access control settings surrounding commit sign-offs are entirely up to you and
your project's needs. You can require sign-off from specific accounts, any
accounts, only on specific files, only in certain branches, etc... all using the
same basic access control building blocks.