-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for Dependency Graph Snapshots endpoint (#2856)
- Loading branch information
Showing
4 changed files
with
558 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
// Copyright 2023 The go-github AUTHORS. All rights reserved. | ||
// | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file. | ||
|
||
package github | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
) | ||
|
||
// DependencyGraphSnapshotResolvedDependency represents a resolved dependency in a dependency graph snapshot. | ||
// | ||
// GitHub API docs: https://docs.github.com/rest/dependency-graph/dependency-submission#create-a-snapshot-of-dependencies-for-a-repository | ||
type DependencyGraphSnapshotResolvedDependency struct { | ||
PackageURL *string `json:"package_url,omitempty"` | ||
// Represents whether the dependency is requested directly by the manifest or is a dependency of another dependency. | ||
// Can have the following values: | ||
// - "direct": indicates that the dependency is requested directly by the manifest. | ||
// - "indirect": indicates that the dependency is a dependency of another dependency. | ||
Relationship *string `json:"relationship,omitempty"` | ||
// Represents whether the dependency is required for the primary build artifact or is only used for development. | ||
// Can have the following values: | ||
// - "runtime": indicates that the dependency is required for the primary build artifact. | ||
// - "development": indicates that the dependency is only used for development. | ||
Scope *string `json:"scope,omitempty"` | ||
Dependencies []string `json:"dependencies,omitempty"` | ||
} | ||
|
||
// DependencyGraphSnapshotJob represents the job that created the snapshot. | ||
// | ||
// GitHub API docs: https://docs.github.com/rest/dependency-graph/dependency-submission#create-a-snapshot-of-dependencies-for-a-repository | ||
type DependencyGraphSnapshotJob struct { | ||
Correlator *string `json:"correlator,omitempty"` | ||
ID *string `json:"id,omitempty"` | ||
HTMLURL *string `json:"html_url,omitempty"` | ||
} | ||
|
||
// DependencyGraphSnapshotDetector represents a description of the detector used. | ||
// | ||
// GitHub API docs: https://docs.github.com/rest/dependency-graph/dependency-submission#create-a-snapshot-of-dependencies-for-a-repository | ||
type DependencyGraphSnapshotDetector struct { | ||
Name *string `json:"name,omitempty"` | ||
Version *string `json:"version,omitempty"` | ||
URL *string `json:"url,omitempty"` | ||
} | ||
|
||
// DependencyGraphSnapshotManifestFile represents the file declaring the repository's dependencies. | ||
// | ||
// GitHub API docs: https://docs.github.com/rest/dependency-graph/dependency-submission#create-a-snapshot-of-dependencies-for-a-repository | ||
type DependencyGraphSnapshotManifestFile struct { | ||
SourceLocation *string `json:"source_location,omitempty"` | ||
} | ||
|
||
// DependencyGraphSnapshotManifest represents a collection of related dependencies declared in a file or representing a logical group of dependencies. | ||
// | ||
// GitHub API docs: https://docs.github.com/rest/dependency-graph/dependency-submission#create-a-snapshot-of-dependencies-for-a-repository | ||
type DependencyGraphSnapshotManifest struct { | ||
Name *string `json:"name,omitempty"` | ||
File *DependencyGraphSnapshotManifestFile `json:"file,omitempty"` | ||
Resolved map[string]*DependencyGraphSnapshotResolvedDependency `json:"resolved,omitempty"` | ||
} | ||
|
||
// DependencyGraphSnapshot represent a snapshot of a repository's dependencies. | ||
// | ||
// GitHub API docs: https://docs.github.com/rest/dependency-graph/dependency-submission#create-a-snapshot-of-dependencies-for-a-repository | ||
type DependencyGraphSnapshot struct { | ||
Version int `json:"version"` | ||
Sha *string `json:"sha,omitempty"` | ||
Ref *string `json:"ref,omitempty"` | ||
Job *DependencyGraphSnapshotJob `json:"job,omitempty"` | ||
Detector *DependencyGraphSnapshotDetector `json:"detector,omitempty"` | ||
Scanned *Timestamp `json:"scanned,omitempty"` | ||
Manifests map[string]*DependencyGraphSnapshotManifest `json:"manifests,omitempty"` | ||
} | ||
|
||
// DependencyGraphSnapshotCreationData represents the dependency snapshot's creation result. | ||
// | ||
// GitHub API docs: https://docs.github.com/rest/dependency-graph/dependency-submission#create-a-snapshot-of-dependencies-for-a-repository | ||
type DependencyGraphSnapshotCreationData struct { | ||
ID int64 `json:"id"` | ||
CreatedAt *Timestamp `json:"created_at,omitempty"` | ||
Message *string `json:"message,omitempty"` | ||
// Represents the snapshot creation result. | ||
// Can have the following values: | ||
// - "SUCCESS": indicates that the snapshot was successfully created and the repository's dependencies were updated. | ||
// - "ACCEPTED": indicates that the snapshot was successfully created, but the repository's dependencies were not updated. | ||
// - "INVALID": indicates that the snapshot was malformed. | ||
Result *string `json:"result,omitempty"` | ||
} | ||
|
||
// CreateSnapshot creates a new snapshot of a repository's dependencies. | ||
// | ||
// GitHub API docs: https://docs.github.com/rest/dependency-graph/dependency-submission#create-a-snapshot-of-dependencies-for-a-repository | ||
// | ||
//meta:operation POST /repos/{owner}/{repo}/dependency-graph/snapshots | ||
func (s *DependencyGraphService) CreateSnapshot(ctx context.Context, owner, repo string, dependencyGraphSnapshot *DependencyGraphSnapshot) (*DependencyGraphSnapshotCreationData, *Response, error) { | ||
url := fmt.Sprintf("repos/%v/%v/dependency-graph/snapshots", owner, repo) | ||
|
||
req, err := s.client.NewRequest("POST", url, dependencyGraphSnapshot) | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
|
||
var snapshotCreationData *DependencyGraphSnapshotCreationData | ||
resp, err := s.client.Do(ctx, req, &snapshotCreationData) | ||
if err != nil { | ||
return nil, resp, err | ||
} | ||
|
||
return snapshotCreationData, resp, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
// Copyright 2023 The go-github AUTHORS. All rights reserved. | ||
// | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file. | ||
|
||
package github | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"net/http" | ||
"testing" | ||
"time" | ||
|
||
"github.com/google/go-cmp/cmp" | ||
) | ||
|
||
func TestDependencyGraphService_CreateSnapshot(t *testing.T) { | ||
client, mux, _, teardown := setup() | ||
defer teardown() | ||
|
||
mux.HandleFunc("/repos/o/r/dependency-graph/snapshots", func(w http.ResponseWriter, r *http.Request) { | ||
testMethod(t, r, "POST") | ||
testBody(t, r, `{"version":0,"sha":"ce587453ced02b1526dfb4cb910479d431683101","ref":"refs/heads/main","job":{"correlator":"yourworkflowname_youractionname","id":"yourrunid","html_url":"https://example.com"},"detector":{"name":"octo-detector","version":"0.0.1","url":"https://github.com/octo-org/octo-repo"},"scanned":"2022-06-14T20:25:00Z","manifests":{"package-lock.json":{"name":"package-lock.json","file":{"source_location":"src/package-lock.json"},"resolved":{"@actions/core":{"package_url":"pkg:/npm/%40actions/[email protected]","relationship":"direct","scope":"runtime","dependencies":["@actions/http-client"]},"@actions/http-client":{"package_url":"pkg:/npm/%40actions/[email protected]","relationship":"indirect","scope":"runtime","dependencies":["tunnel"]},"tunnel":{"package_url":"pkg:/npm/[email protected]","relationship":"indirect","scope":"runtime"}}}}}`+"\n") | ||
fmt.Fprint(w, `{"id":12345,"created_at":"2022-06-14T20:25:01Z","message":"Dependency results for the repo have been successfully updated.","result":"SUCCESS"}`) | ||
}) | ||
|
||
ctx := context.Background() | ||
snapshot := &DependencyGraphSnapshot{ | ||
Version: 0, | ||
Sha: String("ce587453ced02b1526dfb4cb910479d431683101"), | ||
Ref: String("refs/heads/main"), | ||
Job: &DependencyGraphSnapshotJob{ | ||
Correlator: String("yourworkflowname_youractionname"), | ||
ID: String("yourrunid"), | ||
HTMLURL: String("https://example.com"), | ||
}, | ||
Detector: &DependencyGraphSnapshotDetector{ | ||
Name: String("octo-detector"), | ||
Version: String("0.0.1"), | ||
URL: String("https://github.com/octo-org/octo-repo"), | ||
}, | ||
Scanned: &Timestamp{time.Date(2022, time.June, 14, 20, 25, 00, 0, time.UTC)}, | ||
Manifests: map[string]*DependencyGraphSnapshotManifest{ | ||
"package-lock.json": { | ||
Name: String("package-lock.json"), | ||
File: &DependencyGraphSnapshotManifestFile{SourceLocation: String("src/package-lock.json")}, | ||
Resolved: map[string]*DependencyGraphSnapshotResolvedDependency{ | ||
"@actions/core": { | ||
PackageURL: String("pkg:/npm/%40actions/[email protected]"), | ||
Relationship: String("direct"), | ||
Scope: String("runtime"), | ||
Dependencies: []string{"@actions/http-client"}, | ||
}, | ||
"@actions/http-client": { | ||
PackageURL: String("pkg:/npm/%40actions/[email protected]"), | ||
Relationship: String("indirect"), | ||
Scope: String("runtime"), | ||
Dependencies: []string{"tunnel"}, | ||
}, | ||
"tunnel": { | ||
PackageURL: String("pkg:/npm/[email protected]"), | ||
Relationship: String("indirect"), | ||
Scope: String("runtime"), | ||
}, | ||
}, | ||
}, | ||
}, | ||
} | ||
|
||
snapshotCreationData, _, err := client.DependencyGraph.CreateSnapshot(ctx, "o", "r", snapshot) | ||
if err != nil { | ||
t.Errorf("DependencyGraph.CreateSnapshot returned error: %v", err) | ||
} | ||
|
||
want := &DependencyGraphSnapshotCreationData{ | ||
ID: 12345, | ||
CreatedAt: &Timestamp{time.Date(2022, time.June, 14, 20, 25, 01, 0, time.UTC)}, | ||
Message: String("Dependency results for the repo have been successfully updated."), | ||
Result: String("SUCCESS"), | ||
} | ||
if !cmp.Equal(snapshotCreationData, want) { | ||
t.Errorf("DependencyGraph.CreateSnapshot returned %+v, want %+v", snapshotCreationData, want) | ||
} | ||
|
||
const methodName = "CreateSnapshot" | ||
testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { | ||
got, resp, err := client.DependencyGraph.CreateSnapshot(ctx, "o", "r", snapshot) | ||
if got != nil { | ||
t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) | ||
} | ||
return resp, err | ||
}) | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Oops, something went wrong.