Skip to content

Commit

Permalink
Add method to upload Code Scanning Sarif Analysis results to GitHub (g…
Browse files Browse the repository at this point in the history
  • Loading branch information
ganeshkumarsv authored Nov 8, 2021
1 parent d3c6514 commit fdb62f6
Show file tree
Hide file tree
Showing 4 changed files with 224 additions and 0 deletions.
44 changes: 44 additions & 0 deletions github/code-scanning.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,26 @@ type AlertListOptions struct {
ListOptions
}

// SarifAnalysis specifies the results of a code scanning job.
//
// GitHub API docs: https://docs.github.com/en/rest/reference/code-scanning#upload-an-analysis-as-sarif-data
type SarifAnalysis struct {
CommitSHA *string `json:"commit_sha,omitempty"`
Ref *string `json:"ref,omitempty"`
Sarif *string `json:"sarif,omitempty"`
CheckoutURI *string `json:"checkout_uri,omitempty"`
StartedAt *Timestamp `json:"started_at,omitempty"`
ToolName *string `json:"tool_name,omitempty"`
}

// SarifID identifies a sarif analysis upload.
//
// GitHub API docs: https://docs.github.com/en/rest/reference/code-scanning#upload-an-analysis-as-sarif-data
type SarifID struct {
ID *string `json:"id,omitempty"`
URL *string `json:"url,omitempty"`
}

// ListAlertsForRepo lists code scanning alerts for a repository.
//
// Lists all open code scanning alerts for the default branch (usually master) and protected branches in a repository.
Expand Down Expand Up @@ -171,3 +191,27 @@ func (s *CodeScanningService) GetAlert(ctx context.Context, owner, repo string,

return a, resp, nil
}

// UploadSarif uploads the result of code scanning job to GitHub.
//
// For the parameter sarif, you must first compress your SARIF file using gzip and then translate the contents of the file into a Base64 encoding string.
// You must use an access token with the security_events scope to use this endpoint. GitHub Apps must have the security_events
// write permission to use this endpoint.
//
// GitHub API docs: https://docs.github.com/en/rest/reference/code-scanning#upload-an-analysis-as-sarif-data
func (s *CodeScanningService) UploadSarif(ctx context.Context, owner, repo string, sarif *SarifAnalysis) (*SarifID, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/code-scanning/sarifs", owner, repo)

req, err := s.client.NewRequest("POST", u, sarif)
if err != nil {
return nil, nil, err
}

sarifID := new(SarifID)
resp, err := s.client.Do(ctx, req, sarifID)
if err != nil {
return nil, resp, err
}

return sarifID, resp, nil
}
36 changes: 36 additions & 0 deletions github/code-scanning_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package github

import (
"context"
"encoding/json"
"fmt"
"net/http"
"testing"
Expand Down Expand Up @@ -53,6 +54,41 @@ func TestActionsService_Alert_ID(t *testing.T) {
}
}

func TestActionsService_UploadSarif(t *testing.T) {
client, mux, _, teardown := setup()
defer teardown()

mux.HandleFunc("/repos/o/r/code-scanning/sarifs", func(w http.ResponseWriter, r *http.Request) {
v := new(SarifAnalysis)
json.NewDecoder(r.Body).Decode(v)
testMethod(t, r, "POST")
want := &SarifAnalysis{CommitSHA: String("abc"), Ref: String("ref/head/main"), Sarif: String("abc"), CheckoutURI: String("uri"), StartedAt: &Timestamp{time.Date(2006, time.January, 02, 15, 04, 05, 0, time.UTC)}, ToolName: String("codeql-cli")}
if !cmp.Equal(v, want) {
t.Errorf("Request body = %+v, want %+v", v, want)
}

fmt.Fprint(w, `{"commit_sha":"abc","ref":"ref/head/main","sarif":"abc"}`)
})

ctx := context.Background()
sarifAnalysis := &SarifAnalysis{CommitSHA: String("abc"), Ref: String("ref/head/main"), Sarif: String("abc"), CheckoutURI: String("uri"), StartedAt: &Timestamp{time.Date(2006, time.January, 02, 15, 04, 05, 0, time.UTC)}, ToolName: String("codeql-cli")}
_, _, err := client.CodeScanning.UploadSarif(ctx, "o", "r", sarifAnalysis)
if err != nil {
t.Errorf("CodeScanning.UploadSarif returned error: %v", err)
}

const methodName = "UploadSarif"
testBadOptions(t, methodName, func() (err error) {
_, _, err = client.CodeScanning.UploadSarif(ctx, "\n", "\n", sarifAnalysis)
return err
})

testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
_, resp, err := client.CodeScanning.UploadSarif(ctx, "o", "r", sarifAnalysis)
return resp, err
})
}

func TestActionsService_ListAlertsForRepo(t *testing.T) {
client, mux, _, teardown := setup()
defer teardown()
Expand Down
64 changes: 64 additions & 0 deletions github/github-accessors.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

80 changes: 80 additions & 0 deletions github/github-accessors_test.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit fdb62f6

Please sign in to comment.