Skip to content

Automatically add DCO signoff with commit hooks#2283

Merged
htuch merged 7 commits intoenvoyproxy:masterfrom
hausdorff:dco-hooks
Dec 31, 2017
Merged

Automatically add DCO signoff with commit hooks#2283
htuch merged 7 commits intoenvoyproxy:masterfrom
hausdorff:dco-hooks

Conversation

@hausdorff
Copy link
Copy Markdown
Contributor

@hausdorff hausdorff commented Dec 29, 2017

Fixes #2281. DCO signoff is mandatory for all contributors. Currently
this is enforced via CI.

This commit smoothes this process somewhat by introducing:

  1. A git commit hook, which will check the commit message for a
    signoff, and if not present, add one to the bottom of the message.
  2. A script, support/bootstrap, which will symlink these commit
    hooks into the Envoy root .git directory, to minimize the effort
    it takes to use them.

Signed-off-by: Alex Clemmer [email protected]

Fixes envoyproxy#2281. DCO signoff is mandatory for all contributors. Currently
this is enforced via CI.

This commit smoothes this process somewhat by introducing:

  1. A git commit hook, which will check the commit message for a
     signoff, and if not present, add one to the bottom of the message.
  2. A script, `support/bootstrap`, which will symlink these commit
     hooks into the Envoy root `.git` directory, to minimize the effort
     it takes to use them.

Signed-off-by: Alex Clemmer <[email protected]>
@mattklein123
Copy link
Copy Markdown
Member

Sweet! Can we potentially merge https://github.com/envoyproxy/envoy/blob/master/tools/pre-commit.sh into this commit also? That one sets up a hook to check format, but it has never been well documented (I use it locally).

@hausdorff
Copy link
Copy Markdown
Contributor Author

@mattklein123 Done. Two more things:

  1. Are there any other places we should be documenting this?
  2. I notice that some of the mac OS X tests are failing but because I am not changing any "real" code I'm guessing they're just flaky. So first of all, are they? And second of all is there a way for normals to re-trigger a build in such a case?

@hausdorff
Copy link
Copy Markdown
Contributor Author

Oh I've noticed that moving the commit hook causes it to not work. Oops. That's what I get for copy+paste'ing. Let me fix that.

@hausdorff
Copy link
Copy Markdown
Contributor Author

Ok that should be fixed. I went ahead and just rebased the commit because it looks like no one had gotten around to reviewing it.

An undocumented pre-commit hook that runs the format checker on all
changed files exists in `tools/pre-commit.sh`. We're transitioning to a
model where commit hooks are installed with `support/bootstrap`, so this
commit will:

  1. Move this file to `support/hooks`
  2. Cause `support/bootstrap` to actually install it.

Signed-off-by: Alex Clemmer <[email protected]>
Copy link
Copy Markdown
Member

@mattklein123 mattklein123 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is really awesome. Thank you. Just a few doc comments. I will defer to @htuch on the script review as he is a bash master.

# Support tools

A collection of helper scripts meant to be used by the Envoy developers. For
example, scripts executed as post-commit hooks would go here.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be worth it to add a little more text here of which things are installed and roughly what they do? I might mention that when the check format script is installed the developer can use the -n flag with git commit to avoid checking if they don't want to temporarily. Some people might get annoyed if they don't know this.

Also, perhaps we should link to here from the top level developer guide? https://github.com/envoyproxy/envoy/blob/master/DEVELOPER.md or even https://github.com/envoyproxy/envoy#contributing?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mattklein123 Sounds good, let's do all of those things. I'll take another pass later today.

@hausdorff
Copy link
Copy Markdown
Contributor Author

@mattklein123 ok, I believe all of those comments should be addressed.

Copy link
Copy Markdown
Member

@htuch htuch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is awesome. A few design/flow related comments, I think any improvement here is a good direction.

so:

```bash
git commit --no-verify
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before getting into too much review depth, I'm wondering if we really want this to be opt-out on commit vs. push. My common workflow (and I'm sure is the case for many devs) is that we commit early-and-often locally, without caring about format or DCO (which happens via my git aliases anyway). I later squash down in a rebase and then push. I rather that any additional latency is added on the remote push rather than the local commit.

Of course, these are just my preferences and I don't need to actually use these hooks, but I think they may be shared by others as well.

# copying project-standard git commit hooks that do things like ensure DCO
# signoff is present during commit.

# Best-effort check that we're in the envoy root directory.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't you figure out the exact root using git rev-parse --show-toplevel?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not 100% sure that works in all the corner cases, but it looks like it works for submodules, which does seem to be a case we care about, so I'm ok doing this.

# Try to find the `.git` directory, even if it's not in Envoy project root (as
# it wouldn't be if, say, this were in a submodule). The "blessed" but fairly
# new way to do this is to use `--git-common-dir`.
dotGitDir=`git rev-parse --git-common-dir`
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We tend to prefer $(some subshell) style in Envoy.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

dotGitDir=`git rev-parse --git-common-dir`
if test ! -d "${_gitdir}"; then
# If `--git-common-dir` is not available, fall back to older way of doing it.
dotGitDir=`git rev-parse --git-dir`
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer DOT_GIT_DIR style in Envoy scripts.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

fi

hooksDir="${dotGitDir}/hooks"
hooksDirRelpath=`relpath "${hooksDir}" "${PWD}"`
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need relative path here? Can't we just symlink from the absolute path?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not an expert in how this works -- my understanding is that if the repostitory is mv'd, the absolute path strategy would fail. Am I wrong?

Either way, in general it just seems nicer to me to have a symlink between two things whose relative path is well-defined, vs. having that knowledge depend on the directory they could sit in.

@@ -0,0 +1,23 @@
#!/usr/bin/env bash
#
# A git commit hook that will automatically append a DCO signoff to the bottom
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we just enforce that a DCO is present? This would allow flows where the user automatically appends DCO (which I have already) but ensures that there are no mistakes made (trust but verify).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Handled in the discussion below.)

@hausdorff
Copy link
Copy Markdown
Contributor Author

hausdorff commented Dec 30, 2017

@htuch Ok, so, to recap, it sounds like we have two main questions:

  1. When should the formatting checks happen? (Options are: pre-commit, post-commit, and pre-push.)
  2. Should DCO signoff line be added automatically, or should we just error out and tell them that they don't have the signoff line?

For the first, I think you're right that it's more annoying to run as a pre-commit hook, but I suspect that making it a pre-push hook is noticably more complex. (i.e., it's not yet clear to me whether there's an easy way to deal with all the cases of push simply). So what I will offer to you is: if you believe it is worth this extra complexity, both in terms of our time commitment on this PR and in terms of the technical risk, we can do it that way.

For the second, I actually prefer to have it just auto-append if missing, but I'm only about a 6/10 in my conviction this is the way to go, so if you feel strongly about it we can do it your way. My rationale was, firstly, in general I prefer to solve the problem if we can, rather than haranguing people to solve it themselves. But secondly, I wrote this code to work well with other popular workflows I know about: specifically, I wrote it to be compatible with --signoff. Do you see a place where this would be incompatible with another common workflow?

@htuch
Copy link
Copy Markdown
Member

htuch commented Dec 30, 2017

  1. Can you elaborate on why it is much more complex to do this on push vs. commit? My understanding (from some quick searching) is that git has pre-push hooks. Can't they just validate some reasonable suffix of commit history (e.g. last 50 commits) have DCO? Anything that comes from upstream should have DCO, any local changes must have had them added.

  2. Since it's compatible with --signoff I think what you have there is good, so no worries.

BTW, I think this whole PR is a really useful contribution and don't want perfect to get in the way of good, so please only do what is low hanging fruit.

@hausdorff
Copy link
Copy Markdown
Contributor Author

  1. Ah, I was actually talking about the case of running the format checker as pre-push, could be expensive if we validate too many commits. But this case is purely hypothetical at this point, I'm only cautious because we got it wrong on Mesos and it made the push workflow painful. So let me investigate and come back with a real recommendation.

@htuch
Copy link
Copy Markdown
Member

htuch commented Dec 30, 2017

The format check doesn't happen on a per-commit basis. It just looks at the entire state of the tree when you run it, without looking at version control history, so I don't think you have a per-commit validation worry there.

Copy link
Copy Markdown
Member

@htuch htuch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great, thanks for polishing this up.

for i in $(git diff --name-only $RANGE --diff-filter=ACMR 2>&1); do
echo " Checking format for $i"
"$SCRIPT_DIR"/check_format.py check $i
if [[ $? -ne 0 ]]; then
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can just run set +e, that will catch other badness.

do
if [ "$LOCAL_SHA" = $DUMMY_SHA ]
then
# Branch deleted. Do nothing.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you use two space indents? That's what we've been doing in general across most languages and shell scripts in the Envoy code base. Thanks.

@hausdorff
Copy link
Copy Markdown
Contributor Author

@htuch Alright, we're really starting to strain my knowledge of bash, so if it looks like we're doing something dumb, we probably are.

I am pretty sure pre-push won't behave perfectly in all the weird corner cases, but I think we're starting to get close to something that will work for, like, maybe 95% of cases.

htuch
htuch previously approved these changes Dec 30, 2017
Copy link
Copy Markdown
Member

@htuch htuch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM modulo two space indents.

@hausdorff
Copy link
Copy Markdown
Contributor Author

@htuch I actually fixed that as you typed that message. I think we're good now.

Signed-off-by: Alex Clemmer <[email protected]>
Copy link
Copy Markdown
Member

@mattklein123 mattklein123 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sweet, thanks! Will let @htuch merge assuming everything is satisfactory.

Copy link
Copy Markdown
Member

@htuch htuch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rad.

@htuch htuch merged commit a38facb into envoyproxy:master Dec 31, 2017
jpsim pushed a commit that referenced this pull request Nov 28, 2022
jpsim pushed a commit that referenced this pull request Nov 29, 2022
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.

3 participants