Skip to content

Commit

Permalink
cogito: add support for configuring Github API endpoint
Browse files Browse the repository at this point in the history
- adds support for Github Enterprise API endpoints
  • Loading branch information
aliculPix4D committed Oct 19, 2023
1 parent 3d091a4 commit 17a3d8c
Show file tree
Hide file tree
Showing 11 changed files with 81 additions and 130 deletions.
5 changes: 2 additions & 3 deletions cmd/cogito/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import (
"github.com/hashicorp/go-hclog"

"github.com/Pix4D/cogito/cogito"
"github.com/Pix4D/cogito/github"
"github.com/Pix4D/cogito/sets"
)

Expand Down Expand Up @@ -56,8 +55,8 @@ func mainErr(in io.Reader, out io.Writer, logOut io.Writer, args []string) error
case "in":
return cogito.Get(log, input, out, args[1:])
case "out":
putter := cogito.NewPutter(github.API, log)
return cogito.Put(input, out, args[1:], putter)
putter := cogito.NewPutter(log)
return cogito.Put(log, input, out, args[1:], putter)
default:
return fmt.Errorf("cli wiring error; please report")
}
Expand Down
11 changes: 8 additions & 3 deletions cmd/cogito/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ func TestRunPutSuccess(t *testing.T) {
chatReply := googlechat.MessageReply{}
var gchatUrl *url.URL
googleChatSpy := testhelp.SpyHttpServer(&chatMsg, chatReply, &gchatUrl, http.StatusOK)
gitHubSpyDomain, err := url.Parse(gitHubSpy.URL)
if err != nil {
t.Fatalf("error parsing SpyHttpServer URL: %s", err)
}

in := bytes.NewReader(testhelp.ToJSON(t, cogito.PutRequest{
Source: cogito.Source{
Owner: "the-owner",
Expand All @@ -81,9 +86,9 @@ func TestRunPutSuccess(t *testing.T) {
var out bytes.Buffer
var logOut bytes.Buffer
inputDir := testhelp.MakeGitRepoFromTestdata(t, "../../cogito/testdata/one-repo/a-repo",
testhelp.HttpsRemote("the-owner", "the-repo"), "dummySHA", wantGitRef)
testhelp.HttpsRemote(gitHubSpyDomain.Host, "the-owner", "the-repo"), "dummySHA", wantGitRef)

err := mainErr(in, &out, &logOut, []string{"out", inputDir})
err = mainErr(in, &out, &logOut, []string{"out", inputDir})

assert.NilError(t, err, "\nout: %s\nlogOut: %s", out.String(), logOut.String())
//
Expand Down Expand Up @@ -115,7 +120,7 @@ func TestRunPutSuccessIntegration(t *testing.T) {
var out bytes.Buffer
var logOut bytes.Buffer
inputDir := testhelp.MakeGitRepoFromTestdata(t, "../../cogito/testdata/one-repo/a-repo",
testhelp.HttpsRemote(gitHubCfg.Owner, gitHubCfg.Repo), gitHubCfg.SHA,
testhelp.HttpsRemote("github.com", gitHubCfg.Owner, gitHubCfg.Repo), gitHubCfg.SHA,
"ref: refs/heads/a-branch-FIXME")
t.Setenv("BUILD_JOB_NAME", "TestRunPutSuccessIntegration")
t.Setenv("ATC_EXTERNAL_URL", "https://cogito.invalid")
Expand Down
4 changes: 1 addition & 3 deletions cogito/ghcommitsink.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ const (
// GitHubCommitStatusSink is an implementation of [Sinker] for the Cogito resource.
type GitHubCommitStatusSink struct {
Log hclog.Logger
GhAPI string
GitRef string
Request PutRequest
}
Expand All @@ -42,7 +41,7 @@ func (sink GitHubCommitStatusSink) Send() error {
context := ghMakeContext(sink.Request)

target := &github.Target{
Server: sink.GhAPI,
Server: sink.Request.Source.GithubApiEndpoint,
Retry: retry.Retry{
FirstDelay: retryFirstDelay,
BackoffLimit: retryBackoffLimit,
Expand All @@ -58,7 +57,6 @@ func (sink GitHubCommitStatusSink) Send() error {
"state", ghState, "owner", sink.Request.Source.Owner,
"repo", sink.Request.Source.Repo, "git-ref", sink.GitRef,
"context", context, "buildURL", buildURL, "description", description)

if err := commitStatus.Add(sink.GitRef, ghState, buildURL, description); err != nil {
return err
}
Expand Down
4 changes: 2 additions & 2 deletions cogito/ghcommitsink_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ func TestSinkGitHubCommitStatusSendSuccess(t *testing.T) {
ts := testhelp.SpyHttpServer(&ghReq, nil, &URL, http.StatusCreated)
sink := cogito.GitHubCommitStatusSink{
Log: hclog.NewNullLogger(),
GhAPI: ts.URL,
GitRef: wantGitRef,
Request: cogito.PutRequest{
Source: cogito.Source{GithubApiEndpoint: ts.URL},
Params: cogito.PutParams{State: wantState},
Env: cogito.Environment{BuildJobName: jobName},
},
Expand All @@ -50,9 +50,9 @@ func TestSinkGitHubCommitStatusSendFailure(t *testing.T) {
defer ts.Close()
sink := cogito.GitHubCommitStatusSink{
Log: hclog.NewNullLogger(),
GhAPI: ts.URL,
GitRef: "deadbeefdeadbeef",
Request: cogito.PutRequest{
Source: cogito.Source{GithubApiEndpoint: ts.URL},
Params: cogito.PutParams{State: cogito.StatePending},
},
}
Expand Down
12 changes: 9 additions & 3 deletions cogito/protocol.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"os"
"strings"

"github.com/Pix4D/cogito/github"
"github.com/Pix4D/cogito/sets"
)

Expand Down Expand Up @@ -165,14 +166,14 @@ type Source struct {
//
// Optional
//
GithubApiEndpoint string `json:"github_api_endpoint"`
GChatWebHook string `json:"gchat_webhook"` // SENSITIVE
LogLevel string `json:"log_level"`
LogUrl string `json:"log_url"` // DEPRECATED
ContextPrefix string `json:"context_prefix"`
ChatAppendSummary bool `json:"chat_append_summary"`
ChatNotifyOnStates []BuildState `json:"chat_notify_on_states"`
Sinks []string `json:"sinks"`
GithubApiEndpoint string `json:"github_api_endpoint"`
}

// String renders Source, redacting the sensitive fields.
Expand All @@ -181,15 +182,15 @@ func (src Source) String() string {

fmt.Fprintf(&bld, "owner: %s\n", src.Owner)
fmt.Fprintf(&bld, "repo: %s\n", src.Repo)
fmt.Fprintf(&bld, "github_api_endpoint: %s\n", src.GithubApiEndpoint)
fmt.Fprintf(&bld, "access_token: %s\n", redact(src.AccessToken))
fmt.Fprintf(&bld, "gchat_webhook: %s\n", redact(src.GChatWebHook))
fmt.Fprintf(&bld, "log_level: %s\n", src.LogLevel)
fmt.Fprintf(&bld, "context_prefix: %s\n", src.ContextPrefix)
fmt.Fprintf(&bld, "chat_append_summary: %t\n", src.ChatAppendSummary)
fmt.Fprintf(&bld, "chat_notify_on_states: %s\n", src.ChatNotifyOnStates)
// Last one: no newline.
fmt.Fprintf(&bld, "sinks: %s\n", src.Sinks)
fmt.Fprintf(&bld, "github_api_endpoint: %s", src.GithubApiEndpoint)
fmt.Fprintf(&bld, "sinks: %s", src.Sinks)

return bld.String()
}
Expand Down Expand Up @@ -257,7 +258,9 @@ func (src *Source) Validate() error {
return fmt.Errorf("source: missing keys: %s", strings.Join(mandatory, ", "))
}

//
// Validate optional fields.
//
if src.GithubApiEndpoint != "" {
u, err := url.ParseRequestURI(src.GithubApiEndpoint)
if err != nil || u.Host == "" {
Expand All @@ -274,6 +277,9 @@ func (src *Source) Validate() error {
if len(src.ChatNotifyOnStates) == 0 {
src.ChatNotifyOnStates = defaultNotifyStates
}
if len(src.GithubApiEndpoint) == 0 {
src.GithubApiEndpoint = github.API
}

return nil
}
Expand Down
9 changes: 5 additions & 4 deletions cogito/protocol_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ func TestSourcePrintLogRedaction(t *testing.T) {
source := cogito.Source{
Owner: "the-owner",
Repo: "the-repo",
GithubApiEndpoint: "dummy-api",
AccessToken: "sensitive-the-access-token",
GChatWebHook: "sensitive-gchat-webhook",
LogLevel: "debug",
Expand All @@ -224,14 +225,14 @@ func TestSourcePrintLogRedaction(t *testing.T) {
t.Run("fmt.Print redacts fields", func(t *testing.T) {
want := `owner: the-owner
repo: the-repo
github_api_endpoint: dummy-api
access_token: ***REDACTED***
gchat_webhook: ***REDACTED***
log_level: debug
context_prefix: the-prefix
chat_append_summary: true
chat_notify_on_states: [success failure]
sinks: []
github_api_endpoint: `
sinks: []`

have := fmt.Sprint(source)

Expand All @@ -244,14 +245,14 @@ github_api_endpoint: `
}
want := `owner: the-owner
repo:
github_api_endpoint:
access_token:
gchat_webhook:
log_level:
context_prefix:
chat_append_summary: false
chat_notify_on_states: []
sinks: []
github_api_endpoint: `
sinks: []`

have := fmt.Sprint(input)

Expand Down
4 changes: 3 additions & 1 deletion cogito/put.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"fmt"
"io"
"strings"

"github.com/hashicorp/go-hclog"
)

// Putter represents the put step of a Concourse resource.
Expand Down Expand Up @@ -38,7 +40,7 @@ type Sinker interface {
// Additionally, the script may emit metadata as a list of key-value pairs. This data is
// intended for public consumption and will make it upstream, intended to be shown on the
// build's page.
func Put(input []byte, out io.Writer, args []string, putter Putter) error {
func Put(log hclog.Logger, input []byte, out io.Writer, args []string, putter Putter) error {
if err := putter.LoadConfiguration(input, args); err != nil {
return fmt.Errorf("put: %s", err)
}
Expand Down
Loading

0 comments on commit 17a3d8c

Please sign in to comment.