hook: get push options and pass them #340

closed
opened by ptr.pet targeting master from ptr.pet/core: push-options
Changed files
+37 -3
hook
knotserver
nix
modules
+10
hook/hook.go
···
Usage: "endpoint for the internal API",
Value: "http://localhost:5444",
},
+
&cli.StringSliceFlag{
+
Name: "push-option",
+
Usage: "any push option from git",
+
},
},
Commands: []*cli.Command{
{
···
userDid := cmd.String("user-did")
userHandle := cmd.String("user-handle")
endpoint := cmd.String("internal-api")
+
pushOptions := cmd.StringSlice("push-option")
payloadReader := bufio.NewReader(os.Stdin)
payload, _ := payloadReader.ReadString('\n')
···
req.Header.Set("X-Git-Dir", gitDir)
req.Header.Set("X-Git-User-Did", userDid)
req.Header.Set("X-Git-User-Handle", userHandle)
+
if pushOptions != nil {
+
for _, option := range pushOptions {
+
req.Header.Add("X-Git-Push-Option", option)
+
}
+
}
resp, err := client.Do(req)
if err != nil {
+6 -1
hook/setup.go
···
hookContent := fmt.Sprintf(`#!/usr/bin/env bash
# AUTO GENERATED BY KNOT, DO NOT MODIFY
-
%s hook -git-dir "$GIT_DIR" -user-did "$GIT_USER_DID" -user-handle "$GIT_USER_HANDLE" -internal-api "%s" post-recieve
+
push_options=()
+
for ((i=0; i<GIT_PUSH_OPTION_COUNT; i++)); do
+
option_var="GIT_PUSH_OPTION_$i"
+
push_options+=(-push-option "${!option_var}")
+
done
+
%s hook -git-dir "$GIT_DIR" -user-did "$GIT_USER_DID" -user-handle "$GIT_USER_HANDLE" -internal-api "%s" "${push_options[@]}" post-recieve
`, executablePath, config.internalApi)
return os.WriteFile(hookPath, []byte(hookContent), 0755)
+19 -2
knotserver/internal.go
···
return
}
+
type PushOptions struct {
+
skipCi bool
+
}
+
func (h *InternalHandle) PostReceiveHook(w http.ResponseWriter, r *http.Request) {
l := h.l.With("handler", "PostReceiveHook")
···
// non-fatal
}
+
// extract any push options
+
pushOptionsRaw := r.Header.Values("X-Git-Push-Option")
+
pushOptions := PushOptions{}
+
for _, option := range pushOptionsRaw {
+
if option == "skip-ci" || option == "ci-skip" {
+
pushOptions.skipCi = true
+
}
+
}
+
for _, line := range lines {
err := h.insertRefUpdate(line, gitUserDid, repoDid, repoName)
if err != nil {
···
// non-fatal
}
-
err = h.triggerPipeline(line, gitUserDid, repoDid, repoName)
+
err = h.triggerPipeline(line, gitUserDid, repoDid, repoName, pushOptions)
if err != nil {
l.Error("failed to trigger pipeline", "err", err, "line", line, "did", gitUserDid, "repo", gitRelativeDir)
// non-fatal
···
return h.db.InsertEvent(event, h.n)
}
-
func (h *InternalHandle) triggerPipeline(line git.PostReceiveLine, gitUserDid, repoDid, repoName string) error {
+
func (h *InternalHandle) triggerPipeline(line git.PostReceiveLine, gitUserDid, repoDid, repoName string, pushOptions PushOptions) error {
+
if pushOptions.skipCi {
+
return nil
+
}
+
didSlashRepo, err := securejoin.SecureJoin(repoDid, repoName)
if err != nil {
return err
+2
nix/modules/knot.nix
···
[user]
name = Git User
email = git@example.com
+
[receive]
+
advertisePushOptions = true
EOF
chown -R ${cfg.gitUser}:${cfg.gitUser} "${cfg.stateDir}"
'';