summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorDaniel Silverstone <dsilvers@digital-scurf.org>2017-04-26 21:26:54 +0100
committerDaniel Silverstone <dsilvers@digital-scurf.org>2017-04-26 21:26:54 +0100
commit246d0c03f0bf498f9a2ed86c29433d1ee9e17055 (patch)
treea30be1574af91b17f41afa529f6f5ce49402d0e8 /doc
parentd2d522da024c59bd592d7c24d07b1272511766d4 (diff)
parent17f73b454311ef232c29e85d9eacde7941dd8097 (diff)
downloadgitano-246d0c03f0bf498f9a2ed86c29433d1ee9e17055.tar.gz
Merge remote-tracking branch 'origin/richardmaw/githookdoc'
(slight tweaks as per review)
Diffstat (limited to 'doc')
-rw-r--r--doc/admin/000.mdwn139
1 files changed, 138 insertions, 1 deletions
diff --git a/doc/admin/000.mdwn b/doc/admin/000.mdwn
index 770bac8..8f36ec9 100644
--- a/doc/admin/000.mdwn
+++ b/doc/admin/000.mdwn
@@ -419,7 +419,7 @@ follows:
* Otherwise, without the global prefix,
it is included from the per-project rules
- (`refs/gitano-admin` branch of the repository being operated on).
+ (`refs/gitano/admin` branch of the repository being operated on).
Include statements can be made conditional by adding a predicate after the path,
so you can split up your rules:
@@ -433,6 +433,143 @@ so you can split up your rules:
# Branches must not be tags
deny "Branches may only be commits" [ref prefix refs/heads/] [newtype exact commit]
+# Git Hook scripts
+
+Gitano administrators may create, or delegate creation of,
+[Lua][lua] scripts to take action or provide further authentication
+when content is pushed to a repository.
+
+These [Lua][lua] scripts are sandboxed using [Supple][supple],
+to make it safer to run user-defined code.
+
+## How to add a hook
+
+Hooks are stored in the `gitano-admin.git` repository
+and the `refs/gitano/admin` branch of each other repository,
+so that there can be traceability of who is responsible for each hook.
+
+Global hooks in `gitano-admin.git` are loaded
+from the `global-hooks` subdirectory.
+Per-repository hooks in the `refs/gitano/admin` branch
+are loaded from the `hooks` subdirectory.
+
+In both cases hooks are loaded from a file named after the hook
+as defined by [githooks(5)][] suffixed with `.lua`.
+
+Currently the only hooks that are supported are:
+
+1. pre-receive
+2. update
+3. post-receive
+
+So a global pre-receive hook would be in the file `global-hooks/pre-receive.lua`
+and a per-repository post-receive hook would be in `hooks/post-receive.lua`.
+
+## APIs available to hooks
+
+1. `log.$level(...)` to emit text at that log level.
+ $level can be one of:
+
+ 1. `state`
+ 2. `crit` or `critical`
+ 3. `err` or `error`
+ 4. `warn` or `warning`
+ 5. `chat`
+ 6. `info`
+ 7. `debug`
+ 8. `ddebug` or `deepdebug`
+
+2. `fetch(url, headers, body, content_type)` during post-receive hooks.
+
+3. A `repo` object as the first parameter to per-repository hooks,
+ with the following methods:
+
+ ------------------------------------ ----------------------------------------------------------------------------
+ `:get(sha1ish)` Get the contents of a git object from anything matching [gitrevisions(7)][].
+ `:get_config(confname)` Get the value confname from the repo config if it is a single value
+ `:get_config_list(confname)` Get the value confname from the repo config if it is a list value
+ `:check_signature(obj, keyringname)` Check whether `obj` is an object signed by a key in keyring `keyringname`.
+ ------------------------------------ ----------------------------------------------------------------------------
+
+ Objects returned from `get` are [gall][] objects.
+ Refer to [gall's API documentation][gall-api] for details.
+
+4. An `actor` table in the global environment,
+ containing the following indices:
+
+ -------- --------------------------------------------------------------
+ username Gitano username of user doing the push.
+ keytag Name of the ssh key the user is pushing with.
+ source "ssh", "http" or "git" depending on the protocol used to push.
+ realname Real name of user from user configuration.
+ email E-Mail of user from user configuration.
+ -------- --------------------------------------------------------------
+
+5. The `refname`, `oldsha` and `newsha` as the second to fourth parameters
+ during per-repository update hooks, as described in [githooks(5)][].
+
+ Checking whether the master ref is deleted would be accomplished by:
+
+ local _, refname, oldsha, newsha = ...
+ if refname == "refs/heads/master" and newsha == ("0"):rep(40) then
+ log.state("Master deleted")
+ end
+
+6. For pre-receive or post-receive per-repository hooks as the second parameter,
+ a table indexed by the `refnames` being modified
+ containing tables of the `oldsha` and `newsha` indexed
+ either at positional indices `1` and `2`,
+ or by name `oldsha` and `newsha`.
+ Checking whether the master ref is deleted would be accomplished by:
+
+ local _, updates = ...
+ if (updates["refs/heads/master"] or {}).newsha == ("0"):rep(40) then
+ log.state("Master deleted")
+ end
+
+7. Global hooks work the same as per-repository hooks,
+ except they are passed a callable function first, followed by the
+ positional parameters as described above. The callable will run the
+ per-repository hook when called,
+ so global hooks may either replace or augment per-repository hooks.
+
+ To unconditionally run some global hook code and then call a local hook
+ your global hook would be structured something like:
+
+ -- Example global-hooks/update.lua
+ local hookf, repo, refname, oldsha, newsha = ...
+ -- Do stuff with repo/refname/oldsha/newsha here
+ --
+ -- And finally (optionally) tail-chain through to the per-repo hook
+ return hookf(repo, refname, oldsha, newsha)
+
+ To unconditionally ignore update hooks and log why:
+
+ -- Example global-hooks/update.lua
+ local hookf, repo, refname, oldsha, newsha = ...
+ local treeish = repo:get("refs/gitano/admin").sha
+ if repo:get(treeish..":hooks/update.lua") then
+ log.state("Update hooks are disabled")
+ end
+
+ To provide a default if a hook is not defined:
+
+ -- Example global-hooks/update.lua
+ local hookf, repo, refname, oldsha, newsha = ...
+ local treeish = repo:get("refs/gitano/admin").sha
+ if repo:get(treeish..":hooks/update.lua") then
+ return hookf(repo, refname, oldsha, newsha)
+ end
+ -- Do stuff with repo/refname/oldsha/newsha here
+
+
+[lua]: https://www.lua.org/
+[supple]: https://www.gitano.org.uk/supple/
+[githooks(5)]: https://git-scm.com/docs/githooks
+[gitrevisions(7)]: https://git-scm.com/docs/gitrevisions
+[gall]: https://www.gitano.org.uk/gall/
+[gall-api]: file:///usr/share/doc/lua-gall-doc/html/index.html
+
# Backup and restore of a Gitano instance
When gitano-setup is run, the admin needs to specify a Unix user in