hook: get push options and pass them #340

closed
opened by ptr.pet targeting master from [deleted fork]: push-options
Changed files
+37 -3
hook
knotserver
nix
modules
+10
hook/hook.go
··· 36 36 Usage: "endpoint for the internal API", 37 37 Value: "http://localhost:5444", 38 38 }, 39 + &cli.StringSliceFlag{ 40 + Name: "push-option", 41 + Usage: "any push option from git", 42 + }, 39 43 }, 40 44 Commands: []*cli.Command{ 41 45 { ··· 52 56 userDid := cmd.String("user-did") 53 57 userHandle := cmd.String("user-handle") 54 58 endpoint := cmd.String("internal-api") 59 + pushOptions := cmd.StringSlice("push-option") 55 60 56 61 payloadReader := bufio.NewReader(os.Stdin) 57 62 payload, _ := payloadReader.ReadString('\n') ··· 67 72 req.Header.Set("X-Git-Dir", gitDir) 68 73 req.Header.Set("X-Git-User-Did", userDid) 69 74 req.Header.Set("X-Git-User-Handle", userHandle) 75 + if pushOptions != nil { 76 + for _, option := range pushOptions { 77 + req.Header.Add("X-Git-Push-Option", option) 78 + } 79 + } 70 80 71 81 resp, err := client.Do(req) 72 82 if err != nil {
+6 -1
hook/setup.go
··· 133 133 134 134 hookContent := fmt.Sprintf(`#!/usr/bin/env bash 135 135 # AUTO GENERATED BY KNOT, DO NOT MODIFY 136 - %s hook -git-dir "$GIT_DIR" -user-did "$GIT_USER_DID" -user-handle "$GIT_USER_HANDLE" -internal-api "%s" post-recieve 136 + push_options=() 137 + for ((i=0; i<GIT_PUSH_OPTION_COUNT; i++)); do 138 + option_var="GIT_PUSH_OPTION_$i" 139 + push_options+=(-push-option "${!option_var}") 140 + done 141 + %s hook -git-dir "$GIT_DIR" -user-did "$GIT_USER_DID" -user-handle "$GIT_USER_HANDLE" -internal-api "%s" "${push_options[@]}" post-recieve 137 142 `, executablePath, config.internalApi) 138 143 139 144 return os.WriteFile(hookPath, []byte(hookContent), 0755)
+19 -2
knotserver/internal.go
··· 64 64 return 65 65 } 66 66 67 + type PushOptions struct { 68 + skipCi bool 69 + } 70 + 67 71 func (h *InternalHandle) PostReceiveHook(w http.ResponseWriter, r *http.Request) { 68 72 l := h.l.With("handler", "PostReceiveHook") 69 73 ··· 90 94 // non-fatal 91 95 } 92 96 97 + // extract any push options 98 + pushOptionsRaw := r.Header.Values("X-Git-Push-Option") 99 + pushOptions := PushOptions{} 100 + for _, option := range pushOptionsRaw { 101 + if option == "skip-ci" || option == "ci-skip" { 102 + pushOptions.skipCi = true 103 + } 104 + } 105 + 93 106 for _, line := range lines { 94 107 err := h.insertRefUpdate(line, gitUserDid, repoDid, repoName) 95 108 if err != nil { ··· 97 110 // non-fatal 98 111 } 99 112 100 - err = h.triggerPipeline(line, gitUserDid, repoDid, repoName) 113 + err = h.triggerPipeline(line, gitUserDid, repoDid, repoName, pushOptions) 101 114 if err != nil { 102 115 l.Error("failed to trigger pipeline", "err", err, "line", line, "did", gitUserDid, "repo", gitRelativeDir) 103 116 // non-fatal ··· 148 161 return h.db.InsertEvent(event, h.n) 149 162 } 150 163 151 - func (h *InternalHandle) triggerPipeline(line git.PostReceiveLine, gitUserDid, repoDid, repoName string) error { 164 + func (h *InternalHandle) triggerPipeline(line git.PostReceiveLine, gitUserDid, repoDid, repoName string, pushOptions PushOptions) error { 165 + if pushOptions.skipCi { 166 + return nil 167 + } 168 + 152 169 didSlashRepo, err := securejoin.SecureJoin(repoDid, repoName) 153 170 if err != nil { 154 171 return err
+2
nix/modules/knot.nix
··· 113 113 [user] 114 114 name = Git User 115 115 email = git@example.com 116 + [receive] 117 + advertisePushOptions = true 116 118 EOF 117 119 chown -R ${cfg.gitUser}:${cfg.gitUser} "${cfg.stateDir}" 118 120 '';