GitHub Hooks

We’re converging to the three simplest solutions. :slight_smile:

Just cut & pasting what you said on the review would be of great help.


Can you show on Tim’s repo how that won’t work?


Tim’s repo is using "status checks” and not only protected branch.

Yep, I think the main benefit (so far) over just protected branches
would be that we can also guarantee sane timestamps on master, which
should mean we can reconstruct the llvm-project umbrella uniquely when
its script goes down or something else weird happens.

I think that's a useful ability to have, and can't really think of a
way to do it if you can't trust a commit's time (commit-date here, not
author-date). I'm not sure how theoretical that issue is though.

It would also alter the usual git workflow, which is unfortunate.
You'd have to explicitly run "git llvm-verify" before pushing to
master (or "git llvm-push", or whatever).


Actually, now that I think about it, you wouldn't necessarily get a
perfect *re*construction (the umbrella would be triggered by a push so
could still have a different order if each push is picked up
immediately and one commit-date lags).

What you would get is a better (not perfect) guarantee of each
umbrella commit having a sane state, after script downtime. That's
seems less persuasive to me.


What about linear history? Does not this require the "status checks”?

Ah, that too probably. I was confusing that with fast-forward-only,
which I think is what protected branches without status give you.


Just thought I'd send my current progress so that effort isn't wasted
over night if others are thinking along similar lines. I'm attaching
an extremely rough-and-ready verifier here. I'm expecting lots more
bells and whistles would be needed, more user-friendly error
reporting, and more verification steps (at the moment it checks a
linear history only).

To use it:

1. Generate a GitHub OAuth token for "repo:status" and "git config
llvm.token $TOK" with it.
2. Similarly config llvm.user to your GitHub username
3. Add "llvm" as a remote, pointing to the protected repository (in my
test-case, usually

Routine use:
3. Work on your feature branch (not the protected one, or at least a
fork of it otherwise step 4 will fail)
4. git push the feature to your fork.
5. Run "python --branch master" in the git dir[1]
6. Run "git push llvm HEAD:master".


[1] In the usual case, the branch can be inferred (you'll be
developing on a fork of $thing, and want to push to $thing). But when
you don't have 2 GitHub accounts to test with it gets more
complicated. Simplest workaround is "--branch master". (2.91 KB)

Not to derail a large portion of this thread by just pointing out how easy
what you want to do is, but ...

So, there's been a bit of a misunderstanding about the hooks that are
supported in GitHub, and after talking to the GitHub staff, I'd like
to clarify what they are and how we can use them.

  1. Pre-commit hooks, avoiding forced pushes / re-order

GitHub doesn't support server hooks due to security concerns.

But there is an alternative:

About protected branches - GitHub Docs

I don't know how we'd check for non-ff-merges with this, and I'd
appreciate if someone with better GitHub knowledge could chime in. But
they *do* stop pushes from going in, which is what we want. Maybe we
would need a web-service (see 2) to get this working.

They do stop pushes, because you can require status checks.

You don't need a web service. Anyone with push access can create a status,
or you can also
grant oauth scope of repo:status to just grant status creation access
without push access to code itself.

All you have to do to create a status is post to a specific URL (and
include your access tokens, blah blah blah). You can use the context field
to say what service created the status, etc. There are libraries for all
of it.
For example, Google's CLA bot uses to do it's work.
There are libraries for every language you can think of, AFAIK (

In any case, all you would have to is post a status of state failed to the
ref for the pull request, and it will reflect in the pull request.

In this case, what that means is "have thing" (cron job, whatever), post
state pending on every new request that comes in.
As it figures out whether they are linear history or not, post state

You can then mark whatever status checks you want as required for a given
branch (it'll give you a dropdown of status types it finds in the past

it will not allow push or merge until the required statuses are green.

The interface also allows you to check "Require branches to be up-to-date
before merging".


Also note that github already blocks non-ff pushes unless you force (and you can’t force a protected branch without being an admin, and you can even disable admins force-pushing), so …

Perhaps Travis CI could be used. They support triggering builds using an API [1].

[1] Triggering builds with API V3 - Travis CI

I think this is great for builds and tests, but only for the environments that Travis CI supports. If we want to do cross-platform pre-commit testing then we're still going to need to update the build-bots somehow to be "trigger-able" if that's the intent. If the intent is to do it post-commit, it's not as valuable IMO.

Note that the open-source package for Travis CI ends up running on very limited hardware [1].


[1] Redirecting…

I was thinking on the hook to make sure that the history is linear, no force pushing and so on. Not ideal to use Travis CI for this but it could work.