better README, hooks ...

This commit is contained in:
Yann Esposito (Yogsototh) 2018-10-22 09:14:54 +02:00
parent 1e8bbcb006
commit cb940dc6e1
Signed by untrusted user who does not match committer: yogsototh
GPG key ID: 7B19A4C650D59646
4 changed files with 292 additions and 51 deletions

View file

@ -8,7 +8,7 @@ everything...
* Git Project Manager * Git Project Manager
Put a project management tool in git. Put a project management tool in your git repository.
In general each project in git also need a lot of meta data informations. In general each project in git also need a lot of meta data informations.
Most of them related to project management: Most of them related to project management:
@ -28,6 +28,180 @@ thousands of small commit related to project management.
An easy way to have best of both world is simply to create a branch An easy way to have best of both world is simply to create a branch
dedicated to project management only. dedicated to project management only.
** Installation
For now you should simply clone it, install stack and build it.
** Usage
*** Quick
#+BEGIN_SRC
> cd $HOME/my-git-repo
> gpm init
...
> gpm new-issue -i
...
> gpm serve start
...
> open http://localhost:1234
...
> cd /tmp; git clone git://localhost:9418/my-git-repo.git my-git-repo
...
> cd my-git-repo
> git checkout -b new-feature
> ... /hack/ ...
> git commit
> ...
#+END_SRC
*** Detailled
The easiest way would be to launch =gpm= or =gpm --help= to have the list of
commands.
#+BEGIN_SRC
Git Project Manager
Usage: gpm (init | new-issue | review | serve | hooks)
Available options:
-h,--help Show this help text
Available commands:
init Initialize gpm
new-issue Create a new Issue
review Review (use current branch by default)
serve Serve the git to the web
hooks Handle hooks for this git repository
#+END_SRC
*** Init
#+BEGIN_SRC
> gpm init --help
Usage: gpm init
Initialize gpm
Available options:
-h,--help Show this help text
#+END_SRC
*** New Issue
#+BEGIN_SRC
> gpm new-issue --help
Usage: gpm new-issue [-i|--interactive] [-p|--priority PRIORITY]
[-s|--status STATUS] [-t|--title TITLE]
[-c|--creator CREATOR] [-b|--branch BRANCH]
[-g|--tags TAGS] [-a|--assignee ASSIGNEE]
[-r|--reviewers REVIEWERS] [-d|--descr DESCR]
Create a new Issue
Available options:
-i,--interactive Interactive mode
-p,--priority PRIORITY Priority A,B,C
-s,--status STATUS The status of the issue (TODO, QUESTION, ...)
-t,--title TITLE The status title
-c,--creator CREATOR The user that created the issue
-b,--branch BRANCH The branch related to the issue
-g,--tags TAGS comma separated tags
-a,--assignee ASSIGNEE Assignee
-r,--reviewers REVIEWERS comma separated reviewers
-d,--descr DESCR Long issue description
-h,--help Show this help text
#+END_SRC
To edit an issue, manually change your branch to =gpm= and edit the =issues.org=
file.
*** Review
You can start a review, it will handle the task of creating a file where you can
annotate your comments. It will then create a file in
=reviews/<branch-name>-<reviewer>.org=.
The review process is quite open even if some helpers are provided.
#+BEGIN_SRC
> gpm review --help
Usage: gpm review (accept | feedback | question | request-change | reject |
start | end | show | retrieve)
Review (use current branch by default)
Available options:
-h,--help Show this help text
Available commands:
accept Accept the merge
feedback Provide a feedback
question Ask a question
request-change Request some Changes to merge
reject Reject the merge
start Start a new review
end End a review
show Show the review
retrieve Retrieve all the reviews for current branch
#+END_SRC
*** Serve
Expose a minimal read-only web interface of your repositories.
And serve the repository using =git= protocol.
- Web interface http://localhost:1234
- Git repository =git://localhost:9418/your-repo-name=
#+BEGIN_SRC
> gpm serve --help
Usage: gpm serve (start | stop | update | path)
Serve the git to the web
Available options:
-h,--help Show this help text
Available commands:
start Start to serve all gpm tracked repositories
stop Stop to serve all gpm tracked repositories
update Update the served git repository
path Show the path of the bare repository
#+END_SRC
*** Hooks
Synchronize hooks in all your repositories.
#+BEGIN_SRC
> gpm hooks --help
Usage: gpm hooks sync
Handle hooks for this git repository
Available options:
-h,--help Show this help text
Available commands:
sync Synchronize hooks from gpm branch
#+END_SRC
* Considerations
One of the goal of this project is to handle a lot of things handled by github
but with minimality. Everything used here is open source and really easy to use.
** No Push?
I tend to prefer pull request only, that is far easier not to handle identities
through web system. There is a manually provided hooks to only accepts push/pull
if all the commit are signed via a list of authorized GPG keys.
** Ops?
Managing the CI/CD through another 3rd party parallel branch is not simple.
Mainly part of the CI/CD script directly depends on some code change, and as so,
should be present in the dev branches. But also part of the code should be
independant. So the question on how to handle ops code is still open for me.
* About
** Project Management Format ** Project Management Format
As one goal is also to provide minimal friction I wouldn't advise to use As one goal is also to provide minimal friction I wouldn't advise to use
@ -146,54 +320,54 @@ Starting with only basic features (TODO / INPROGRESS / DONE)
Then, priority, multiple users, tags, many meta infos by task. Then, priority, multiple users, tags, many meta infos by task.
Task organized as tree of tasks and subtasks. Task organized as tree of tasks and subtasks.
* Why is this important? ** Why is this important?
It is very important to put all those meta-data about your project inside the It is very important to put all those meta-data about your project inside the
repository because: repository because:
- you are no more dependant on any 3rd party tool to manage your project - you are no more dependant on any 3rd party tool to manage your project
- you can easily change how you host your git project - you can easily change how you host your git project
- anyone with just a text editor can manage those tasks. - anyone with just a text editor can manage those tasks.
** After that
* After that A goal is to complete the =gpm= tool with a few other one all isolated but which
could all work together.
A goal is to complete the =gpm= tool with a few other one all isolated but which - hook handling (so all your team member can share nice hooks, for example,
could all work together.
- hook handling (so all your team member can share nice hooks, for example,
preformat commit messages, launch tests before publishing a pull request, preformat commit messages, launch tests before publishing a pull request,
etc...) etc...)
- minimal web interface to navigate your project files, commits, branches, etc... - minimal web interface to navigate your project management related files,
- identity handling so hand in hand with hook handle and web interface provide commits, branches, etc...
- identity handling so hand in hand with hook handle and web interface provide
the ability to manage how contributor can access your tool the ability to manage how contributor can access your tool
** Identfy users, allow access and trust them *** Identfy users, allow access and trust them
With this system it will be more about a pull from other than wait for them to push. With this system it will be more about a pull from other than wait for them to push.
The identity system should be decentralized and based on GPG keys. The identity system should be decentralized and based on GPG keys.
Mainly each user should sign their commit with their GPG key. Mainly each user should sign their commit with their GPG key.
Each user could then keep serving their local repo (see instaweb). Each user could then keep serving their local repo (see instaweb).
And more importantly, there will be "known" repositories, known packages and libraries. And more importantly, there will be "known" repositories, known packages and libraries.
It will be enough to sign all those activities and to publish them on some page automatically. It will be enough to sign all those activities and to publish them on some page automatically.
Or to search for the fingerprint of the GPG on the web via a search engine. Or to search for the fingerprint of the GPG on the web via a search engine.
You'll then see all the activities related to that key. You'll then see all the activities related to that key.
Typically: Typically:
- OSS contributions - OSS contributions
- web blog articles - web blog articles
- micro blog messages - micro blog messages
- comments - comments
- etc... - etc...
One great advantage of that, is that each user will be able to manage different One great advantage of that, is that each user will be able to manage different
GPG key pairs for dealing with different aspect of their lives. GPG key pairs for dealing with different aspect of their lives.
This solution won't need common consensus network à la bitcoin, or any This solution won't need common consensus network à la bitcoin, or any
decentralized smart contract system. And from my point of view, this is a lot decentralized smart contract system. And from my point of view, this is a lot
better. Because most of those decentralized system want you to adopt their better. Because most of those decentralized system want you to adopt their
centralized system, their software, their ecosystem. While just providing a centralized system, their software, their ecosystem. While just providing a
website with a list of links where the user could simply grab them and check all website with a list of links where the user could simply grab them and check all
link correspond to a signed activies is clearly totally open source compliant link correspond to a signed activies is clearly totally open source compliant
and does not require any software choice on any parties. This is yet again, just and does not require any software choice on any parties. This is yet again, just
a text file somewhere and a simple web service. With minimal tooling that could a text file somewhere and a simple web service. With minimal tooling that could
be coded in any language in not much time. be coded in any language in not much time.

View file

@ -21,11 +21,11 @@ where
import Protolude hiding (ask, die, stdout, (%)) import Protolude hiding (ask, die, stdout, (%))
import Turtle import Turtle
import GPM.Helpers (debug_, getGPMDataDir, getGitUser, green)
import qualified Data.Char as Char import qualified Data.Char as Char
import Data.FileEmbed (embedStringFile) import Data.FileEmbed (embedStringFile)
import qualified Data.Text as Text import qualified Data.Text as Text
import GPM.Helpers (debug_, getGPMDataDir, getGitUser, green,
green)
import qualified System.Directory as Directory import qualified System.Directory as Directory
import Text.Mustache import Text.Mustache

View file

@ -1,4 +1,5 @@
{-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE TemplateHaskell #-}
{-| {-|
module : GPM.Serve module : GPM.Serve
Description : GPM review related commands Description : GPM review related commands
@ -23,6 +24,7 @@ import GPM.Helpers (debug, debug_, getGPMDataDir,
-- | External Lib Imports -- | External Lib Imports
import qualified Data.Text as Text import qualified Data.Text as Text
import Data.FileEmbed (embedStringFile)
-- | Retrieve a public dir to serve git repositories -- | Retrieve a public dir to serve git repositories
getPublicDir :: IO Turtle.FilePath getPublicDir :: IO Turtle.FilePath
@ -66,9 +68,11 @@ init = do
debug_ (format ("git clone --mirror "%fp%" "%fp) debug_ (format ("git clone --mirror "%fp%" "%fp)
repoRoot repoRoot
publicProjectDir) publicProjectDir)
inDir publicProjectDir $ do inDir (publicProjectDir </> "hooks") $ do
mv ("hooks" </> "post-update.sample") ("hooks" </> "post-update") mv "post-update.sample" "post-update"
_ <- chmod executable ("hooks" </> "post-update") _ <- chmod executable "post-update"
writeFile "pre-receive-hooks" $(embedStringFile "templates/pre-receive-hooks")
_ <- chmod executable "pre-receive-hooks"
debug_ "git update-server-info" debug_ "git update-server-info"
-- | Serve command -- | Serve command
@ -121,11 +125,10 @@ handleProjectDir = getPublicDir >>= putText . format fp
dirServe :: Turtle.FilePath -> IO () dirServe :: Turtle.FilePath -> IO ()
dirServe pubdir = do dirServe pubdir = do
gpmDataDir <- getGPMDataDir gpmDataDir <- getGPMDataDir
let pidfiledir = gpmDataDir </> "procs"
debug_ $ debug_ $
format ("git daemon --detach --pid-file="%fp format ("git daemon --detach --pid-file="%fp
%" --reuseaddr --export-all --base-path="%fp%" "%fp) %" --reuseaddr --export-all --base-path="%fp%" "%fp)
(pidfiledir </> "gitServePID") (gpmDataDir </> "git-daemon-pid")
pubdir pubdir
pubdir pubdir
@ -133,7 +136,7 @@ dirStopServe :: IO ()
dirStopServe = do dirStopServe = do
gpmDataDir <- getGPMDataDir gpmDataDir <- getGPMDataDir
inDir gpmDataDir $ do inDir gpmDataDir $ do
pidtxt <- readTextFile (gpmDataDir </>"procs" </> "gitServePID") pidtxt <- readTextFile (gpmDataDir </> "git-daemon-pid")
if Text.null pidtxt if Text.null pidtxt
then putErrText "git daemon doesn't appear to be running" then putErrText "git daemon doesn't appear to be running"
else debug_ ("kill " <> pidtxt) else debug_ ("kill " <> pidtxt)

View file

@ -0,0 +1,64 @@
!/usr/bin/env bash
#
# Pre-receive hook that will block any unsigned commits and tags when pushed.
# It will also only accept a list of predefined GPG keys fingerprints (your team)
#
# More details on GPG commit and tag signing can be found on
#
# https://help.github.com/articles/signing-commits-using-gpg/
#
# Use your authorized fingerprints!
authorized_keys_fingerprints=(
"0000000000000000000000000000000000000000"
"0000000000000000000000000000000000000001"
)
function join_by { local IFS="$1"; shift; echo "$*"; }
fingerprints_regex="($(join_by '|' ${authorized_keys_fingerprints[@]}))"
zero_commit="0000000000000000000000000000000000000000"
# we have to change the home directory of GPG
# as in the default environment, /root/.gnupg is not writeable
export GNUPGHOME=/tmp/
# Do not traverse over commits that are already in the repository
# (e.g. in a different branch)
# This prevents funny errors if pre-receive hooks got enabled after some
# commits got already in and then somebody tries to create a new branch
# If this is unwanted behavior, just set the variable to empty
excludeExisting="--not --all"
while read oldrev newrev refname; do
# echo "payload"
echo $refname $oldrev $newrev
# branch or tag get deleted
if [ "$newrev" = "$zero_commit" ]; then
continue
fi
# Check for new branch or tag
if [ "$oldrev" = "$zero_commit" ]; then
span=`git rev-list $newrev $excludeExisting`
else
span=`git rev-list $oldrev..$newrev $excludeExisting`
fi
for COMMIT in $span;
do
signed=$(git verify-commit --raw $COMMIT 2>&1 | grep -E "VALIDSIG $authorized_keys_fingerprints ")
if test -n "$signed"; then
echo Commit $COMMIT was signed by a GPG key: $signed
else
echo Commit $COMMIT was not signed by a GPG key, rejecting push
exit 1
fi
done
done
exit 0