Skip to content

Commit fdb62f6

Browse files
Add method to upload Code Scanning Sarif Analysis results to GitHub (#2165)
1 parent d3c6514 commit fdb62f6

File tree

4 files changed

+224
-0
lines changed

4 files changed

+224
-0
lines changed

github/code-scanning.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,26 @@ type AlertListOptions struct {
119119
ListOptions
120120
}
121121

122+
// SarifAnalysis specifies the results of a code scanning job.
123+
//
124+
// GitHub API docs: https://docs.github.com/en/rest/reference/code-scanning#upload-an-analysis-as-sarif-data
125+
type SarifAnalysis struct {
126+
CommitSHA *string `json:"commit_sha,omitempty"`
127+
Ref *string `json:"ref,omitempty"`
128+
Sarif *string `json:"sarif,omitempty"`
129+
CheckoutURI *string `json:"checkout_uri,omitempty"`
130+
StartedAt *Timestamp `json:"started_at,omitempty"`
131+
ToolName *string `json:"tool_name,omitempty"`
132+
}
133+
134+
// SarifID identifies a sarif analysis upload.
135+
//
136+
// GitHub API docs: https://docs.github.com/en/rest/reference/code-scanning#upload-an-analysis-as-sarif-data
137+
type SarifID struct {
138+
ID *string `json:"id,omitempty"`
139+
URL *string `json:"url,omitempty"`
140+
}
141+
122142
// ListAlertsForRepo lists code scanning alerts for a repository.
123143
//
124144
// Lists all open code scanning alerts for the default branch (usually master) and protected branches in a repository.
@@ -171,3 +191,27 @@ func (s *CodeScanningService) GetAlert(ctx context.Context, owner, repo string,
171191

172192
return a, resp, nil
173193
}
194+
195+
// UploadSarif uploads the result of code scanning job to GitHub.
196+
//
197+
// 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.
198+
// You must use an access token with the security_events scope to use this endpoint. GitHub Apps must have the security_events
199+
// write permission to use this endpoint.
200+
//
201+
// GitHub API docs: https://docs.github.com/en/rest/reference/code-scanning#upload-an-analysis-as-sarif-data
202+
func (s *CodeScanningService) UploadSarif(ctx context.Context, owner, repo string, sarif *SarifAnalysis) (*SarifID, *Response, error) {
203+
u := fmt.Sprintf("repos/%v/%v/code-scanning/sarifs", owner, repo)
204+
205+
req, err := s.client.NewRequest("POST", u, sarif)
206+
if err != nil {
207+
return nil, nil, err
208+
}
209+
210+
sarifID := new(SarifID)
211+
resp, err := s.client.Do(ctx, req, sarifID)
212+
if err != nil {
213+
return nil, resp, err
214+
}
215+
216+
return sarifID, resp, nil
217+
}

github/code-scanning_test.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ package github
77

88
import (
99
"context"
10+
"encoding/json"
1011
"fmt"
1112
"net/http"
1213
"testing"
@@ -53,6 +54,41 @@ func TestActionsService_Alert_ID(t *testing.T) {
5354
}
5455
}
5556

57+
func TestActionsService_UploadSarif(t *testing.T) {
58+
client, mux, _, teardown := setup()
59+
defer teardown()
60+
61+
mux.HandleFunc("/repos/o/r/code-scanning/sarifs", func(w http.ResponseWriter, r *http.Request) {
62+
v := new(SarifAnalysis)
63+
json.NewDecoder(r.Body).Decode(v)
64+
testMethod(t, r, "POST")
65+
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")}
66+
if !cmp.Equal(v, want) {
67+
t.Errorf("Request body = %+v, want %+v", v, want)
68+
}
69+
70+
fmt.Fprint(w, `{"commit_sha":"abc","ref":"ref/head/main","sarif":"abc"}`)
71+
})
72+
73+
ctx := context.Background()
74+
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")}
75+
_, _, err := client.CodeScanning.UploadSarif(ctx, "o", "r", sarifAnalysis)
76+
if err != nil {
77+
t.Errorf("CodeScanning.UploadSarif returned error: %v", err)
78+
}
79+
80+
const methodName = "UploadSarif"
81+
testBadOptions(t, methodName, func() (err error) {
82+
_, _, err = client.CodeScanning.UploadSarif(ctx, "\n", "\n", sarifAnalysis)
83+
return err
84+
})
85+
86+
testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
87+
_, resp, err := client.CodeScanning.UploadSarif(ctx, "o", "r", sarifAnalysis)
88+
return resp, err
89+
})
90+
}
91+
5692
func TestActionsService_ListAlertsForRepo(t *testing.T) {
5793
client, mux, _, teardown := setup()
5894
defer teardown()

github/github-accessors.go

Lines changed: 64 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

github/github-accessors_test.go

Lines changed: 80 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)