diff --git a/Octokit.Reactive/Clients/IObservableDependencyGraphClient.cs b/Octokit.Reactive/Clients/IObservableDependencyGraphClient.cs
new file mode 100644
index 0000000000..7a22d179f3
--- /dev/null
+++ b/Octokit.Reactive/Clients/IObservableDependencyGraphClient.cs
@@ -0,0 +1,22 @@
+namespace Octokit.Reactive
+{
+ ///
+ /// A client for GitHub's Dependency Graph API.
+ ///
+ ///
+ /// See the Git Dependency Graph API documentation for more information.
+ ///
+ public interface IObservableDependencyGraphClient
+ {
+ ///
+ /// Client for getting a dependency comparison between two commits.
+ ///
+ IObservableDependencyReviewClient DependencyReview { get; }
+
+ ///
+ /// Client for submitting dependency snapshots.
+ ///
+ IObservableDependencySubmissionClient DependencySubmission { get; }
+ }
+}
+
diff --git a/Octokit.Reactive/Clients/IObservableDependencyReviewClient.cs b/Octokit.Reactive/Clients/IObservableDependencyReviewClient.cs
new file mode 100644
index 0000000000..d87a4de001
--- /dev/null
+++ b/Octokit.Reactive/Clients/IObservableDependencyReviewClient.cs
@@ -0,0 +1,39 @@
+
+using System;
+
+namespace Octokit.Reactive
+{
+ ///
+ /// A client for GitHub's Dependency Review API.
+ ///
+ ///
+ /// See the Git Dependency Review API documentation for more information.
+ ///
+ public interface IObservableDependencyReviewClient
+ {
+ ///
+ /// Gets all s for the specified repository.
+ ///
+ ///
+ /// See the API documentation for more information.
+ ///
+ /// The owner of the repository
+ /// The name of the repository
+ /// The base revision
+ /// The head revision
+ /// Thrown when a general API error occurs.
+ IObservable GetAll(string owner, string name, string @base, string head);
+
+ ///
+ /// Gets all s for the specified repository.
+ ///
+ ///
+ /// See the API documentation for more information.
+ ///
+ /// The Id of the repository
+ /// The base revision
+ /// The head revision
+ /// Thrown when a general API error occurs.
+ IObservable GetAll(long repositoryId, string @base, string head);
+ }
+}
diff --git a/Octokit.Reactive/Clients/IObservableDependencySubmissionClient.cs b/Octokit.Reactive/Clients/IObservableDependencySubmissionClient.cs
new file mode 100644
index 0000000000..ed27fd853a
--- /dev/null
+++ b/Octokit.Reactive/Clients/IObservableDependencySubmissionClient.cs
@@ -0,0 +1,39 @@
+using System;
+
+namespace Octokit.Reactive
+{
+ ///
+ /// A client for GitHub's Dependency Submission API.
+ ///
+ ///
+ /// See the Dependency Submission API documentation for more details.
+ ///
+ public interface IObservableDependencySubmissionClient
+ {
+ ///
+ /// Creates a new dependency snapshot.
+ ///
+ ///
+ /// See the API documentation for more information.
+ ///
+ /// The repository's owner
+ /// The repository's name
+ /// The dependency snapshot to create
+ /// Thrown when a general API error occurs
+ /// A instance for the created snapshot
+ IObservable Create(string owner, string name, NewDependencySnapshot snapshot);
+
+ ///
+ /// Creates a new dependency snapshot.
+ ///
+ ///
+ /// See the API documentation for more information.
+ ///
+ /// The Id of the repository
+ /// The dependency snapshot to create
+ /// Thrown when a general API error occurs
+ /// A instance for the created snapshot
+ IObservable Create(long repositoryId, NewDependencySnapshot snapshot);
+ }
+}
+
diff --git a/Octokit.Reactive/Clients/ObservableDependencyGraphClient.cs b/Octokit.Reactive/Clients/ObservableDependencyGraphClient.cs
new file mode 100644
index 0000000000..0aadea0313
--- /dev/null
+++ b/Octokit.Reactive/Clients/ObservableDependencyGraphClient.cs
@@ -0,0 +1,29 @@
+namespace Octokit.Reactive
+{
+ ///
+ /// A client for GitHub's Dependency Graph API.
+ ///
+ ///
+ /// See the Git Dependency Graph API documentation for more information.
+ ///
+ public class ObservableDependencyGraphClient : IObservableDependencyGraphClient
+ {
+ public ObservableDependencyGraphClient(IGitHubClient client)
+ {
+ Ensure.ArgumentNotNull(client, nameof(client));
+
+ //DependencyReview = new ObservableDependencyReviewClient(client);
+ DependencySubmission = new ObservableDependencySubmissionClient(client);
+ }
+
+ ///
+ /// Client for getting a dependency comparison between two commits.
+ ///
+ public IObservableDependencyReviewClient DependencyReview { get; private set; }
+
+ ///
+ /// Client for submitting dependency snapshots.
+ ///
+ public IObservableDependencySubmissionClient DependencySubmission { get; private set; }
+ }
+}
diff --git a/Octokit.Reactive/Clients/ObservableDependencyReviewClient.cs b/Octokit.Reactive/Clients/ObservableDependencyReviewClient.cs
new file mode 100644
index 0000000000..c7bfcc1145
--- /dev/null
+++ b/Octokit.Reactive/Clients/ObservableDependencyReviewClient.cs
@@ -0,0 +1,63 @@
+using System;
+using System.Reactive.Linq;
+using System.Reactive.Threading.Tasks;
+
+namespace Octokit.Reactive
+{
+ ///
+ /// A client for GitHub's Dependency Review API.
+ ///
+ ///
+ /// See the Git Dependency Review API documentation for more information.
+ ///
+ public class ObservableDependencyReviewClient : IObservableDependencyReviewClient
+ {
+ readonly IDependencyReviewClient _client;
+
+ public ObservableDependencyReviewClient(IGitHubClient client)
+ {
+ Ensure.ArgumentNotNull(client, nameof(client));
+
+ _client = client.DependencyGraph.DependencyReview;
+ }
+
+ ///
+ /// Gets all s for the specified repository.
+ ///
+ ///
+ /// See the API documentation for more information.
+ ///
+ /// The owner of the repository
+ /// The name of the repository
+ /// The base revision
+ /// The head revision
+ /// Thrown when a general API error occurs.
+ public IObservable GetAll(string owner, string name, string @base, string head)
+ {
+ Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner));
+ Ensure.ArgumentNotNullOrEmptyString(name, nameof(name));
+ Ensure.ArgumentNotNullOrEmptyString(@base, nameof(@base));
+ Ensure.ArgumentNotNullOrEmptyString(head, nameof(head));
+
+ return _client.GetAll(owner, name, @base, head).ToObservable().SelectMany(x => x);
+ }
+
+ ///
+ /// Gets all s for the specified repository.
+ ///
+ ///
+ /// See the API documentation for more information.
+ ///
+ /// The Id of the repository
+ /// The base revision
+ /// The head revision
+ /// Thrown when a general API error occurs.
+ public IObservable GetAll(long repositoryId, string @base, string head)
+ {
+ Ensure.ArgumentNotNullOrEmptyString(@base, nameof(@base));
+ Ensure.ArgumentNotNullOrEmptyString(head, nameof(head));
+
+ return _client.GetAll(repositoryId, @base, head).ToObservable().SelectMany(x => x);
+ }
+ }
+}
diff --git a/Octokit.Reactive/Clients/ObservableDependencySubmissionClient.cs b/Octokit.Reactive/Clients/ObservableDependencySubmissionClient.cs
new file mode 100644
index 0000000000..23702457e6
--- /dev/null
+++ b/Octokit.Reactive/Clients/ObservableDependencySubmissionClient.cs
@@ -0,0 +1,60 @@
+using System;
+using System.Reactive.Threading.Tasks;
+
+namespace Octokit.Reactive
+{
+ ///
+ /// A client for GitHub's Dependency Submission API.
+ ///
+ ///
+ /// See the Dependency Submission API documentation for more details.
+ ///
+ public class ObservableDependencySubmissionClient : IObservableDependencySubmissionClient
+ {
+ readonly IDependencySubmissionClient _client;
+
+ public ObservableDependencySubmissionClient(IGitHubClient client)
+ {
+ Ensure.ArgumentNotNull(client, nameof(client));
+
+ _client = client.DependencyGraph.DependencySubmission;
+ }
+
+ ///
+ /// Creates a new dependency snapshot.
+ ///
+ ///
+ /// See the API documentation for more information.
+ ///
+ /// The repository's owner
+ /// The repository's name
+ /// The dependency snapshot to create
+ /// Thrown when a general API error occurs
+ /// A instance for the created snapshot
+ public IObservable Create(string owner, string name, NewDependencySnapshot snapshot)
+ {
+ Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner));
+ Ensure.ArgumentNotNullOrEmptyString(name, nameof(name));
+ Ensure.ArgumentNotNull(snapshot, nameof(snapshot));
+
+ return _client.Create(owner, name, snapshot).ToObservable();
+ }
+
+ ///
+ /// Creates a new dependency snapshot.
+ ///
+ ///
+ /// See the API documentation for more information.
+ ///
+ /// The Id of the repository
+ /// The dependency snapshot to create
+ /// Thrown when a general API error occurs
+ /// A instance for the created snapshot
+ public IObservable Create(long repositoryId, NewDependencySnapshot snapshot)
+ {
+ Ensure.ArgumentNotNull(snapshot, nameof(snapshot));
+
+ return _client.Create(repositoryId, snapshot).ToObservable();
+ }
+ }
+}
diff --git a/Octokit.Reactive/IObservableGitHubClient.cs b/Octokit.Reactive/IObservableGitHubClient.cs
index 68fb81a6a5..5fdb152a3d 100644
--- a/Octokit.Reactive/IObservableGitHubClient.cs
+++ b/Octokit.Reactive/IObservableGitHubClient.cs
@@ -44,5 +44,6 @@ public interface IObservableGitHubClient : IApiInfoProvider
IObservableActionsClient Actions { get; }
IObservableCodespacesClient Codespaces { get; }
IObservableCopilotClient Copilot { get; }
+ IObservableDependencyGraphClient DependencyGraph { get; }
}
}
diff --git a/Octokit.Reactive/ObservableGitHubClient.cs b/Octokit.Reactive/ObservableGitHubClient.cs
index 2713ad12ce..130e5aca52 100644
--- a/Octokit.Reactive/ObservableGitHubClient.cs
+++ b/Octokit.Reactive/ObservableGitHubClient.cs
@@ -59,6 +59,7 @@ public ObservableGitHubClient(IGitHubClient gitHubClient)
Actions = new ObservableActionsClient(gitHubClient);
Codespaces = new ObservableCodespacesClient(gitHubClient);
Copilot = new ObservableCopilotClient(gitHubClient);
+ DependencyGraph = new ObservableDependencyGraphClient(gitHubClient);
}
public IConnection Connection
@@ -108,7 +109,8 @@ public void SetRequestTimeout(TimeSpan timeout)
public IObservableActionsClient Actions { get; private set; }
public IObservableCodespacesClient Codespaces { get; private set; }
public IObservableCopilotClient Copilot { get; set; }
-
+ public IObservableDependencyGraphClient DependencyGraph { get; }
+
///
/// Gets the latest API Info - this will be null if no API calls have been made
///
diff --git a/Octokit.Tests.Integration/Clients/DependencyReviewClientTests.cs b/Octokit.Tests.Integration/Clients/DependencyReviewClientTests.cs
new file mode 100644
index 0000000000..b19f6f610d
--- /dev/null
+++ b/Octokit.Tests.Integration/Clients/DependencyReviewClientTests.cs
@@ -0,0 +1,55 @@
+using Octokit;
+using Octokit.Tests.Integration;
+using System.Linq;
+using System.Threading.Tasks;
+using Xunit;
+
+///
+/// Base and head must have different dependencies
+///
+public class DependencyReviewClientTests
+{
+
+ public class TheGetAllMethod
+ {
+ readonly IDependencyReviewClient _fixture;
+ readonly IGitHubClient _github;
+ readonly string _owner;
+ readonly string _repo;
+ readonly string _base;
+ readonly string _head;
+ readonly long _repoId;
+
+ public TheGetAllMethod()
+ {
+ _github = Helper.GetAuthenticatedClient();
+ _fixture = _github.DependencyGraph.DependencyReview;
+
+ _owner = "octokit";
+ _repo = "octokit.net";
+ _base = "main";
+ _head = "brave-new-codegen-world";
+ _repoId = _github.Repository.Get(_owner, _repo).Result.Id;
+ }
+
+ [IntegrationTest]
+ public async Task GetDependencyDiffs()
+ {
+ var diffs = await _fixture.GetAll(_owner, _repo, _base, _head);
+
+ Assert.NotEmpty(diffs);
+ Assert.NotNull(diffs);
+ Assert.IsType(diffs.First());
+ }
+
+ [IntegrationTest]
+ public async Task GetDependencyDiffsWithRepositoryId()
+ {
+ var diffs = await _fixture.GetAll(_repoId, _base, _head);
+
+ Assert.NotEmpty(diffs);
+ Assert.NotNull(diffs);
+ Assert.IsType(diffs.First());
+ }
+ }
+}
diff --git a/Octokit.Tests.Integration/Clients/DependencySubmissionClientTests.cs b/Octokit.Tests.Integration/Clients/DependencySubmissionClientTests.cs
new file mode 100644
index 0000000000..b86dcad1a6
--- /dev/null
+++ b/Octokit.Tests.Integration/Clients/DependencySubmissionClientTests.cs
@@ -0,0 +1,114 @@
+using Octokit;
+using Octokit.Tests.Integration;
+using Octokit.Tests.Integration.Helpers;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Threading.Tasks;
+using Xunit;
+
+public class DependencySubmissionClientTests
+{
+ public class TheCreateMethod
+ {
+ private readonly IDependencySubmissionClient _dependencySubmissionClient;
+ private readonly RepositoryContext _context;
+ private readonly NewDependencySnapshot _newDependencySnapshot;
+
+ public TheCreateMethod()
+ {
+ var github = Helper.GetAuthenticatedClient();
+
+ _dependencySubmissionClient = github.DependencyGraph.DependencySubmission;
+ _context = github.CreateRepositoryContextWithAutoInit("public-repo").Result;
+
+ var job = new NewDependencySnapshotJob("runid", "example-correlator");
+ var detector = new NewDependencySnapshotDetector("example-detector", "1.0.0", "https://github.com/example/detector");
+
+ var resolvedMetadata = new Dictionary
+ {
+ { "License", "MIT" }
+ };
+
+ var manifests = new Dictionary
+ {
+ {
+ "package-lock.json",
+ new NewDependencySnapshotManifest("package-lock.json")
+ {
+ File = new NewDependencySnapshotManifestFile
+ {
+ SourceLocation = "src/package-lock.json"
+ },
+ Resolved = new Dictionary
+ {
+ {
+ "@actions/core",
+ new NewDependencySnapshotResolvedDependency
+ {
+ PackageUrl = "pkg:/npm/%40actions/core@1.1.9",
+ Dependencies = new Collection { "@actions/http-client" },
+ Scope = ResolvedPackageKeyScope.Runtime,
+ Relationship = ResolvedPackageKeyRelationship.Indirect,
+ Metadata = resolvedMetadata
+ }
+ },
+ {
+ "@actions/http-client",
+ new NewDependencySnapshotResolvedDependency
+ {
+ PackageUrl = "pkg:/npm/%40actions/http-client@1.0.7",
+ Scope = ResolvedPackageKeyScope.Development,
+ Relationship = ResolvedPackageKeyRelationship.Direct
+ }
+ },
+ {
+ "tunnel",
+ new NewDependencySnapshotResolvedDependency
+ {
+ PackageUrl = "pkg:/npm/tunnel@0.0.6",
+ Dependencies = new Collection(),
+ Relationship = ResolvedPackageKeyRelationship.Direct,
+ }
+ }
+ }
+ }
+ }
+ };
+
+ var snapshotMetadata = new Dictionary
+ {
+ { "Author", "John Doe" },
+ { "Version", "1.0.0" },
+ { "License", "MIT" }
+ };
+
+ _newDependencySnapshot = new NewDependencySnapshot(
+ 1,
+ "ce587453ced02b1526dfb4cb910479d431683101",
+ "refs/heads/main",
+ "2022-06-14T20:25:00Z",
+ job,
+ detector)
+ {
+ Metadata = snapshotMetadata,
+ Manifests = manifests
+ };
+ }
+
+ [IntegrationTest]
+ public async Task CanCreateDependencySnapshot()
+ {
+ var submission = await _dependencySubmissionClient.Create(_context.RepositoryOwner, _context.RepositoryName, _newDependencySnapshot);
+
+ Assert.Equal(DependencySnapshotSubmissionResult.Accepted, submission.Result);
+ }
+
+ [IntegrationTest]
+ public async Task CanCreateDependencySnapshotWithRepositoryId()
+ {
+ var submission = await _dependencySubmissionClient.Create(_context.Repository.Id, _newDependencySnapshot);
+
+ Assert.Equal(DependencySnapshotSubmissionResult.Accepted, submission.Result);
+ }
+ }
+}
diff --git a/Octokit.Tests.Integration/Reactive/ObservableDependencyReviewClientTests.cs b/Octokit.Tests.Integration/Reactive/ObservableDependencyReviewClientTests.cs
new file mode 100644
index 0000000000..c64eda0cdd
--- /dev/null
+++ b/Octokit.Tests.Integration/Reactive/ObservableDependencyReviewClientTests.cs
@@ -0,0 +1,51 @@
+using Octokit;
+using Octokit.Reactive;
+using Octokit.Tests.Integration;
+using System.Linq;
+using System.Reactive.Linq;
+using System.Threading.Tasks;
+using Xunit;
+
+///
+/// Base and head must have different dependencies
+///
+public class ObservableDependencyReviewClientTests
+{
+ public class TheGetAllMethod
+ {
+ readonly ObservableDependencyReviewClient _DependencyReviewClient;
+ readonly string owner = "octokit";
+ readonly string repo = "octokit.net";
+ readonly string @base = "main";
+ readonly string head = "brave-new-codegen-world";
+ readonly long repoId;
+
+ public TheGetAllMethod()
+ {
+ var github = Helper.GetAuthenticatedClient();
+ _DependencyReviewClient = new ObservableDependencyReviewClient(github);
+
+ repoId = github.Repository.Get(owner, repo).Result.Id;
+ }
+
+ [IntegrationTest]
+ public async Task GetDependencyDiffs()
+ {
+ var diffs = await _DependencyReviewClient.GetAll(owner, repo, @base, head).ToList();
+
+ Assert.NotEmpty(diffs);
+ Assert.NotNull(diffs);
+ Assert.IsType(diffs.First());
+ }
+
+ [IntegrationTest]
+ public async Task GetDependencyDiffsWithRepositoryId()
+ {
+ var diffs = await _DependencyReviewClient.GetAll(repoId, @base, head).ToList();
+
+ Assert.NotEmpty(diffs);
+ Assert.NotNull(diffs);
+ Assert.IsType(diffs.First());
+ }
+ }
+}
diff --git a/Octokit.Tests.Integration/Reactive/ObservableDependencySubmissionClientTests.cs b/Octokit.Tests.Integration/Reactive/ObservableDependencySubmissionClientTests.cs
new file mode 100644
index 0000000000..63431e5dbb
--- /dev/null
+++ b/Octokit.Tests.Integration/Reactive/ObservableDependencySubmissionClientTests.cs
@@ -0,0 +1,115 @@
+using Octokit;
+using Octokit.Reactive;
+using Octokit.Tests.Integration;
+using Octokit.Tests.Integration.Helpers;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Reactive.Linq;
+using System.Threading.Tasks;
+using Xunit;
+
+public class ObservableDependencySubmissionClientTests
+{
+ public class TheCreateMethod
+ {
+ private readonly ObservableGitHubClient _client;
+ private readonly RepositoryContext _context;
+ private readonly NewDependencySnapshot _newDependencySnapshot;
+
+ public TheCreateMethod()
+ {
+ var github = Helper.GetAuthenticatedClient();
+ _client = new ObservableGitHubClient(github);
+ _context = github.CreateRepositoryContextWithAutoInit("public-repo").Result;
+
+ var job = new NewDependencySnapshotJob("runid", "example-correlator");
+ var detector = new NewDependencySnapshotDetector("example-detector", "1.0.0", "https://github.com/example/detector");
+
+ var resolvedMetadata = new Dictionary
+ {
+ { "License", "MIT" }
+ };
+
+ var manifests = new Dictionary
+ {
+ {
+ "package-lock.json",
+ new NewDependencySnapshotManifest("package-lock.json")
+ {
+ File = new NewDependencySnapshotManifestFile
+ {
+ SourceLocation = "src/package-lock.json"
+ },
+ Resolved = new Dictionary
+ {
+ {
+ "@actions/core",
+ new NewDependencySnapshotResolvedDependency
+ {
+ PackageUrl = "pkg:/npm/%40actions/core@1.1.9",
+ Dependencies = new Collection { "@actions/http-client" },
+ Scope = ResolvedPackageKeyScope.Runtime,
+ Relationship = ResolvedPackageKeyRelationship.Indirect,
+ Metadata = resolvedMetadata
+ }
+ },
+ {
+ "@actions/http-client",
+ new NewDependencySnapshotResolvedDependency
+ {
+ PackageUrl = "pkg:/npm/%40actions/http-client@1.0.7",
+ Scope = ResolvedPackageKeyScope.Development,
+ Relationship = ResolvedPackageKeyRelationship.Direct
+ }
+ },
+ {
+ "tunnel",
+ new NewDependencySnapshotResolvedDependency
+ {
+ PackageUrl = "pkg:/npm/tunnel@0.0.6",
+ Dependencies = new Collection(),
+ Relationship = ResolvedPackageKeyRelationship.Direct,
+ }
+ }
+ }
+ }
+ }
+ };
+
+ var snapshotMetadata = new Dictionary
+ {
+ { "Author", "John Doe" },
+ { "Version", "1.0.0" },
+ { "License", "MIT" }
+ };
+
+ _newDependencySnapshot = new NewDependencySnapshot(
+ 1,
+ "ce587453ced02b1526dfb4cb910479d431683101",
+ "refs/heads/main",
+ "2022-06-14T20:25:00Z",
+ job,
+ detector)
+ {
+ Metadata = snapshotMetadata,
+ Manifests = manifests
+ };
+ }
+
+ [IntegrationTest]
+ public async Task CanCreateDependencySnapshot()
+ {
+ var submission = await _client.DependencyGraph.DependencySubmission.Create(_context.RepositoryOwner, _context.RepositoryName, _newDependencySnapshot);
+
+ Assert.Equal(DependencySnapshotSubmissionResult.Accepted, submission.Result);
+ }
+
+ [IntegrationTest]
+ public async Task CanCreateDependencySnapshotWithRepositoryId()
+ {
+ var submission = await _client.DependencyGraph.DependencySubmission.Create(_context.Repository.Id, _newDependencySnapshot);
+
+ Assert.Equal(DependencySnapshotSubmissionResult.Accepted, submission.Result);
+ }
+ }
+}
diff --git a/Octokit.Tests/Clients/DependencyGraphClientTests.cs b/Octokit.Tests/Clients/DependencyGraphClientTests.cs
new file mode 100644
index 0000000000..fd76c1e6bb
--- /dev/null
+++ b/Octokit.Tests/Clients/DependencyGraphClientTests.cs
@@ -0,0 +1,17 @@
+using System;
+using Xunit;
+
+namespace Octokit
+{
+ public class DependencyGraphClientTests
+ {
+ public class TheCtor
+ {
+ [Fact]
+ public void EnsuresNonNullArguments()
+ {
+ Assert.Throws(() => new DependencyGraphClient(null));
+ }
+ }
+ }
+}
diff --git a/Octokit.Tests/Clients/DependencyReviewClientTests.cs b/Octokit.Tests/Clients/DependencyReviewClientTests.cs
new file mode 100644
index 0000000000..ef1331739c
--- /dev/null
+++ b/Octokit.Tests/Clients/DependencyReviewClientTests.cs
@@ -0,0 +1,74 @@
+using NSubstitute;
+using Octokit.Tests;
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Xunit;
+
+namespace Octokit
+{
+ public class DependencyReviewClientTests
+ {
+ public class TheGetAllMethod
+ {
+ [Fact]
+ public async Task RequestsCorrectUrl()
+ {
+ var connection = Substitute.For();
+ var client = new DependencyReviewClient(connection);
+
+ await client.GetAll("fake", "repo", "base", "head");
+
+ connection.Received().GetAll(Arg.Is(u => u.ToString() == "repos/fake/repo/dependency-graph/compare/base...head"));
+ }
+
+ [Fact]
+ public async Task RequestsCorrectUrlWithRepositoryId()
+ {
+ var connection = Substitute.For();
+ var client = new DependencyReviewClient(connection);
+
+ await client.GetAll(1, "base", "head");
+
+ connection.Received().GetAll(Arg.Is(u => u.ToString() == "repositories/1/dependency-graph/compare/base...head"));
+ }
+
+ [Fact]
+ public async Task EnsuresNonNullArguments()
+ {
+ var client = new DependencyReviewClient(Substitute.For());
+
+ await Assert.ThrowsAsync(() => client.GetAll(null, "name", "base", "head"));
+ await Assert.ThrowsAsync(() => client.GetAll("owner", null, "base", "head"));
+ await Assert.ThrowsAsync(() => client.GetAll("owner", "name", null, "head"));
+ await Assert.ThrowsAsync(() => client.GetAll("owner", "name", "base", null));
+
+ await Assert.ThrowsAsync(() => client.GetAll(1, null, "head"));
+ await Assert.ThrowsAsync(() => client.GetAll(1, "base", null));
+ }
+
+ [Fact]
+ public async Task EnsuresNonEmptyArguments()
+ {
+ var client = new DependencyReviewClient(Substitute.For());
+
+ await Assert.ThrowsAsync(() => client.GetAll("", "name", "base", "head"));
+ await Assert.ThrowsAsync(() => client.GetAll("owner", "", "base", "head"));
+ await Assert.ThrowsAsync(() => client.GetAll("owner", "name", "", "head"));
+ await Assert.ThrowsAsync(() => client.GetAll("owner", "name", "head", ""));
+
+ await Assert.ThrowsAsync(() => client.GetAll(1, "", "head"));
+ await Assert.ThrowsAsync(() => client.GetAll(1, "base", ""));
+ }
+ }
+
+ public class TheCtor
+ {
+ [Fact]
+ public void EnsuresNonNullArguments()
+ {
+ Assert.Throws(() => new DependencyReviewClient(null));
+ }
+ }
+ }
+}
diff --git a/Octokit.Tests/Clients/DependencySubmissionClientTests.cs b/Octokit.Tests/Clients/DependencySubmissionClientTests.cs
new file mode 100644
index 0000000000..9e3252214c
--- /dev/null
+++ b/Octokit.Tests/Clients/DependencySubmissionClientTests.cs
@@ -0,0 +1,73 @@
+using NSubstitute;
+using System;
+using System.Threading.Tasks;
+using Xunit;
+
+namespace Octokit
+{
+ public class DependencySubmissionClientTests
+ {
+ public class TheCreateMethod
+ {
+ private NewDependencySnapshot newDependencySnapshot = new NewDependencySnapshot(
+ 1,
+ "sha",
+ "ref",
+ "scanned",
+ new NewDependencySnapshotJob("runId", "jobCorrelator"),
+ new NewDependencySnapshotDetector("detectorName", "detectorVersion", "detectorUrl"));
+
+ [Fact]
+ public void PostsToTheCorrectUrl()
+ {
+ var connection = Substitute.For();
+ var client = new DependencySubmissionClient(connection);
+ var expectedUrl = "repos/owner/name/dependency-graph/snapshots";
+
+ client.Create("owner", "name", newDependencySnapshot);
+
+ connection.Received(1).Post(Arg.Is(u => u.ToString() == expectedUrl), Arg.Any());
+ }
+
+ [Fact]
+ public void PostsToTheCorrectUrlWithRepositoryId()
+ {
+ var connection = Substitute.For();
+ var client = new DependencySubmissionClient(connection);
+ var expectedUrl = "repositories/1/dependency-graph/snapshots";
+
+ client.Create(1, newDependencySnapshot);
+
+ connection.Received(1).Post(Arg.Is(u => u.ToString() == expectedUrl), Arg.Any());
+ }
+
+ [Fact]
+ public async Task EnsuresNonNullArguments()
+ {
+ var client = new DependencySubmissionClient(Substitute.For());
+
+ await Assert.ThrowsAsync(() => client.Create(null, "name", newDependencySnapshot));
+ await Assert.ThrowsAsync(() => client.Create("owner", null, newDependencySnapshot));
+ await Assert.ThrowsAsync(() => client.Create("owner", "name", null));
+ }
+
+ [Fact]
+ public async Task EnsuresNonEmptyArguments()
+ {
+ var client = new DependencySubmissionClient(Substitute.For());
+
+ await Assert.ThrowsAsync(() => client.Create("", "name", newDependencySnapshot));
+ await Assert.ThrowsAsync(() => client.Create("owner", "", newDependencySnapshot));
+ }
+ }
+
+ public class TheCtor
+ {
+ [Fact]
+ public void EnsuresNonNullArguments()
+ {
+ Assert.Throws(() => new DependencySubmissionClient(null));
+ }
+ }
+ }
+}
diff --git a/Octokit.Tests/Models/DependencyDiffTests.cs b/Octokit.Tests/Models/DependencyDiffTests.cs
new file mode 100644
index 0000000000..be46ef832a
--- /dev/null
+++ b/Octokit.Tests/Models/DependencyDiffTests.cs
@@ -0,0 +1,56 @@
+using Octokit.Internal;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Xunit;
+
+namespace Octokit
+{
+ public class DependencyDiffTests
+ {
+ [Fact]
+ public void CanDeserialize()
+ {
+ const string json = @"{
+ ""change_type"": ""removed"",
+ ""manifest"": ""Cargo.lock"",
+ ""ecosystem"": ""cargo"",
+ ""name"": ""libsqlite3-sys"",
+ ""version"": ""0.22.2"",
+ ""package_url"": ""pkg:cargo/libsqlite3-sys@0.22.2"",
+ ""license"": ""MIT"",
+ ""source_repository_url"": ""https://github.com/rusqlite/rusqlite"",
+ ""scope"": ""runtime"",
+ ""vulnerabilities"": [
+ {
+ ""severity"": ""high"",
+ ""advisory_ghsa_id"": ""GHSA-jw36-hf63-69r9"",
+ ""advisory_summary"": ""`libsqlite3-sys` via C SQLite improperly validates array index"",
+ ""advisory_url"": ""https://github.com/advisories/GHSA-jw36-hf63-69r9""
+ }
+ ]
+ }";
+
+ var actual = new SimpleJsonSerializer().Deserialize(json);
+
+ Assert.Equal("removed", actual.ChangeType);
+ Assert.Equal("Cargo.lock", actual.Manifest);
+ Assert.Equal("cargo", actual.Ecosystem);
+ Assert.Equal("libsqlite3-sys", actual.Name);
+ Assert.Equal("0.22.2", actual.Version);
+ Assert.Equal("pkg:cargo/libsqlite3-sys@0.22.2", actual.PackageUrl);
+ Assert.Equal("MIT", actual.License);
+ Assert.Equal("https://github.com/rusqlite/rusqlite", actual.SourceRepositoryUrl);
+ Assert.Equal("runtime", actual.Scope);
+ Assert.NotNull(actual.Vulnerabilities);
+ Assert.Single(actual.Vulnerabilities);
+ var vulnerability = actual.Vulnerabilities.First();
+ Assert.Equal("high", vulnerability.Severity);
+ Assert.Equal("GHSA-jw36-hf63-69r9", vulnerability.AdvisoryGhsaId);
+ Assert.Equal("`libsqlite3-sys` via C SQLite improperly validates array index", vulnerability.AdvisorySummary);
+ Assert.Equal("https://github.com/advisories/GHSA-jw36-hf63-69r9", vulnerability.AdvisoryUrl);
+ }
+ }
+}
diff --git a/Octokit.Tests/Models/DependencySnapshotSubmissionTests.cs b/Octokit.Tests/Models/DependencySnapshotSubmissionTests.cs
new file mode 100644
index 0000000000..cbcac0a502
--- /dev/null
+++ b/Octokit.Tests/Models/DependencySnapshotSubmissionTests.cs
@@ -0,0 +1,32 @@
+using Octokit.Internal;
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using Xunit;
+
+namespace Octokit
+{
+ public class DependencySnapshotSubmissionTests
+ {
+ [Fact]
+ public void CanDeserialize()
+ {
+ const string json = @"
+ {
+ ""id"": 12345,
+ ""created_at"": ""2018-05-04T01:14:52Z"",
+ ""message"": ""Dependency results for the repo have been successfully updated."",
+ ""result"": ""SUCCESS""
+ }";
+
+ var serializer = new SimpleJsonSerializer();
+
+ var actual = serializer.Deserialize(json);
+
+ Assert.Equal(12345, actual.Id);
+ Assert.Equal(DateTimeOffset.Parse("2018-05-04T01:14:52Z"), actual.CreatedAt);
+ Assert.Equal("Dependency results for the repo have been successfully updated.", actual.Message);
+ Assert.Equal("SUCCESS", actual.Result);
+ }
+ }
+}
diff --git a/Octokit.Tests/Reactive/ObservableDependencyGraphClientTests.cs b/Octokit.Tests/Reactive/ObservableDependencyGraphClientTests.cs
new file mode 100644
index 0000000000..8788b78dd2
--- /dev/null
+++ b/Octokit.Tests/Reactive/ObservableDependencyGraphClientTests.cs
@@ -0,0 +1,18 @@
+using Octokit.Reactive;
+using System;
+using Xunit;
+
+namespace Octokit.Tests.Reactive
+{
+ public class ObservableDependencyGraphClientTests
+ {
+ public class TheCtor
+ {
+ [Fact]
+ public void EnsuresNonNullArguments()
+ {
+ Assert.Throws(() => new ObservableDependencyGraphClient(null));
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Octokit.Tests/Reactive/ObservableDependencyReviewClientTests.cs b/Octokit.Tests/Reactive/ObservableDependencyReviewClientTests.cs
new file mode 100644
index 0000000000..fffc8958f9
--- /dev/null
+++ b/Octokit.Tests/Reactive/ObservableDependencyReviewClientTests.cs
@@ -0,0 +1,72 @@
+using NSubstitute;
+using Octokit.Reactive;
+using System;
+using System.Threading.Tasks;
+using Xunit;
+
+namespace Octokit.Tests.Reactive
+{
+ public class ObservableDependencyReviewClientTests
+ {
+ public class TheGetAllMethod
+ {
+ [Fact]
+ public async Task RequestsCorrectUrl()
+ {
+ var gitHubClient = Substitute.For();
+ var client = new ObservableDependencyReviewClient(gitHubClient);
+
+ client.GetAll("fake", "repo", "base", "head");
+
+ gitHubClient.Received().DependencyGraph.DependencyReview.GetAll("fake", "repo", "base", "head");
+ }
+
+ [Fact]
+ public void RequestsCorrectUrlWithRepositoryId()
+ {
+ var gitHubClient = Substitute.For();
+ var client = new ObservableDependencyReviewClient(gitHubClient);
+
+ client.GetAll(1, "base", "head");
+
+ gitHubClient.Received().DependencyGraph.DependencyReview.GetAll(1, "base", "head");
+ }
+
+ [Fact]
+ public void EnsuresNonNullArguments()
+ {
+ var client = new ObservableDependencyReviewClient(Substitute.For());
+
+ Assert.Throws(() => client.GetAll(null, "name", "base", "head"));
+ Assert.Throws(() => client.GetAll("owner", null, "base", "head"));
+ Assert.Throws(() => client.GetAll("owner", "name", null, "head"));
+ Assert.Throws(() => client.GetAll("owner", "name", "base", null));
+
+ Assert.Throws(() => client.GetAll(1, null, "head"));
+ Assert.Throws(() => client.GetAll(1, "base", null));
+ }
+
+ [Fact]
+ public void EnsuresNonEmptyArguments()
+ {
+ var client = new ObservableDependencyReviewClient(Substitute.For());
+
+ Assert.Throws(() => client.GetAll("", "name", "base", "head"));
+ Assert.Throws(() => client.GetAll("owner", "", "base", "head"));
+ Assert.Throws(() => client.GetAll("owner", "name", "", "head"));
+ Assert.Throws(() => client.GetAll("owner", "name", "base", ""));
+
+ Assert.Throws(() => client.GetAll(1, "", "head"));
+ Assert.Throws(() => client.GetAll(1, "base", ""));
+ }
+ }
+ public class TheCtor
+ {
+ [Fact]
+ public void EnsuresNonNullArguments()
+ {
+ Assert.Throws(() => new ObservableDependencyReviewClient(null));
+ }
+ }
+ }
+}
diff --git a/Octokit.Tests/Reactive/ObservableDependencySubmissionClientTests.cs b/Octokit.Tests/Reactive/ObservableDependencySubmissionClientTests.cs
new file mode 100644
index 0000000000..35eb5c45cd
--- /dev/null
+++ b/Octokit.Tests/Reactive/ObservableDependencySubmissionClientTests.cs
@@ -0,0 +1,71 @@
+using NSubstitute;
+using Octokit.Reactive;
+using System;
+using Xunit;
+
+namespace Octokit.Tests.Reactive
+{
+ public class ObservableDependencySubmissionClientTests
+ {
+ public class TheCreateMethod
+ {
+ private NewDependencySnapshot newDependencySnapshot = new NewDependencySnapshot(
+ 1,
+ "sha",
+ "ref",
+ "scanned",
+ new NewDependencySnapshotJob("runId", "jobCorrelator"),
+ new NewDependencySnapshotDetector("detectorName", "detectorVersion", "detectorUrl"));
+
+ [Fact]
+ public void PostsToTheCorrectUrl()
+ {
+ var gitHubClient = Substitute.For();
+ var client = new ObservableDependencySubmissionClient(gitHubClient);
+
+ client.Create("fake", "repo", newDependencySnapshot);
+
+ gitHubClient.DependencyGraph.DependencySubmission.Received().Create("fake", "repo", newDependencySnapshot);
+ }
+
+ [Fact]
+ public void PostsToTheCorrectUrlWithRepositoryId()
+ {
+ var gitHubClient = Substitute.For();
+ var client = new ObservableDependencySubmissionClient(gitHubClient);
+
+ client.Create(1, newDependencySnapshot);
+
+ gitHubClient.DependencyGraph.DependencySubmission.Received().Create(1, newDependencySnapshot);
+ }
+
+ [Fact]
+ public void EnsuresNonNullArguments()
+ {
+ var client = new ObservableDependencySubmissionClient(Substitute.For());
+
+ Assert.Throws(() => client.Create(null, "name", newDependencySnapshot));
+ Assert.Throws(() => client.Create("owner", null, newDependencySnapshot));
+ Assert.Throws(() => client.Create("owner", "name", null));
+ }
+
+ [Fact]
+ public void EnsuresNonEmptyArguments()
+ {
+ var client = new ObservableDependencySubmissionClient(Substitute.For());
+
+ Assert.Throws(() => client.Create("", "name", newDependencySnapshot));
+ Assert.Throws(() => client.Create("owner", "", newDependencySnapshot));
+ }
+ }
+
+ public class TheCtor
+ {
+ [Fact]
+ public void EnsuresNonNullArguments()
+ {
+ Assert.Throws(() => new ObservableDependencySubmissionClient(null));
+ }
+ }
+ }
+}
diff --git a/Octokit/Clients/DependencyGraphClient.cs b/Octokit/Clients/DependencyGraphClient.cs
new file mode 100644
index 0000000000..d36d78fa04
--- /dev/null
+++ b/Octokit/Clients/DependencyGraphClient.cs
@@ -0,0 +1,31 @@
+namespace Octokit
+{
+ ///
+ /// A client for GitHub's Dependency Graph API.
+ ///
+ ///
+ /// See the Git Dependency Graph API documentation for more information.
+ ///
+ public class DependencyGraphClient : IDependencyGraphClient
+ {
+ ///
+ /// Instantiates a new GitHub Dependency Graph API client.
+ ///
+ /// An API connection
+ public DependencyGraphClient(IApiConnection apiConnection)
+ {
+ DependencyReview = new DependencyReviewClient(apiConnection);
+ DependencySubmission = new DependencySubmissionClient(apiConnection);
+ }
+
+ ///
+ /// Client for getting a dependency comparison between two commits.
+ ///
+ public IDependencyReviewClient DependencyReview { get; private set; }
+
+ ///
+ /// Client for submitting dependency snapshots.
+ ///
+ public IDependencySubmissionClient DependencySubmission { get; private set; }
+ }
+}
\ No newline at end of file
diff --git a/Octokit/Clients/DependencyReviewClient.cs b/Octokit/Clients/DependencyReviewClient.cs
new file mode 100644
index 0000000000..caf52b4cec
--- /dev/null
+++ b/Octokit/Clients/DependencyReviewClient.cs
@@ -0,0 +1,66 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading.Tasks;
+using System.Xml.Linq;
+
+namespace Octokit
+{
+ ///
+ /// A client for GitHub's Dependency Review API.
+ ///
+ ///
+ /// See the Git Dependency Review API documentation for more information.
+ ///
+ public class DependencyReviewClient : ApiClient, IDependencyReviewClient
+ {
+ ///
+ /// Instantiate a new GitHub Dependency Review API client.
+ ///
+ /// An API connection
+ public DependencyReviewClient(IApiConnection apiConnection) : base(apiConnection)
+ {
+ }
+
+ ///
+ /// Gets all s for the specified repository.
+ ///
+ ///
+ /// See the API documentation for more information.
+ ///
+ /// The owner of the repository
+ /// The name of the repository
+ /// The base revision
+ /// The head revision
+ /// Thrown when a general API error occurs.
+ [ManualRoute("GET", "/repos/{owner}/{repo}/dependency-graph/compare/{base}...{head}")]
+ public Task> GetAll(string owner, string name, string @base, string head)
+ {
+ Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner));
+ Ensure.ArgumentNotNullOrEmptyString(name, nameof(name));
+ Ensure.ArgumentNotNullOrEmptyString(@base, nameof(@base));
+ Ensure.ArgumentNotNullOrEmptyString(head, nameof(head));
+
+ return ApiConnection.GetAll(ApiUrls.DependencyReview(owner, name, @base, head));
+ }
+
+ ///
+ /// Gets all s for the specified repository.
+ ///
+ ///
+ /// See the API documentation for more information.
+ ///
+ /// The Id of the repository
+ /// The base revision
+ /// The head revision
+ /// Thrown when a general API error occurs.
+ [ManualRoute("GET", "/repositories/{id}/dependency-graph/compare/{base}...{head}")]
+ public Task> GetAll(long repositoryId, string @base, string head)
+ {
+ Ensure.ArgumentNotNullOrEmptyString(@base, nameof(@base));
+ Ensure.ArgumentNotNullOrEmptyString(head, nameof(head));
+
+ return ApiConnection.GetAll(ApiUrls.DependencyReview(repositoryId, @base, head));
+ }
+ }
+}
diff --git a/Octokit/Clients/DependencySubmissionClient.cs b/Octokit/Clients/DependencySubmissionClient.cs
new file mode 100644
index 0000000000..968972e84a
--- /dev/null
+++ b/Octokit/Clients/DependencySubmissionClient.cs
@@ -0,0 +1,127 @@
+using System.Threading.Tasks;
+
+namespace Octokit
+{
+ ///
+ /// A client for GitHub's Dependency Submission API.
+ ///
+ ///
+ /// See the Dependency Submission API documentation for more details.
+ ///
+ public class DependencySubmissionClient : ApiClient, IDependencySubmissionClient
+ {
+ ///
+ /// Initializes a new GitHub Dependency Submission API client.
+ ///
+ /// An API connection
+ public DependencySubmissionClient(IApiConnection apiConnection) : base(apiConnection) { }
+
+ ///
+ /// Creates a new dependency snapshot.
+ ///
+ ///
+ /// See the API documentation for more information.
+ ///
+ /// The repository's owner
+ /// The repository's name
+ /// The dependency snapshot to create
+ /// Thrown when a general API error occurs
+ /// A instance for the created snapshot
+ [ManualRoute("POST", "/repos/{owner}/{repo}/dependency-graph/snapshots")]
+ public Task Create(string owner, string name, NewDependencySnapshot snapshot)
+ {
+ Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner));
+ Ensure.ArgumentNotNullOrEmptyString(name, nameof(name));
+ Ensure.ArgumentNotNull(snapshot, nameof(snapshot));
+
+ var newDependencySnapshotAsObject = ConvertToJsonObject(snapshot);
+
+ return ApiConnection.Post(ApiUrls.DependencySubmission(owner, name), newDependencySnapshotAsObject);
+ }
+
+ ///
+ /// Creates a new dependency snapshot.
+ ///
+ ///
+ /// See the API documentation for more information.
+ ///
+ /// The Id of the repository
+ /// The dependency snapshot to create
+ /// Thrown when a general API error occurs
+ /// A instance for the created snapshot
+ [ManualRoute("POST", "/repositories/{id}/dependency-graph/snapshots")]
+ public Task Create(long repositoryId, NewDependencySnapshot snapshot)
+ {
+ Ensure.ArgumentNotNull(snapshot, nameof(snapshot));
+
+ var newDependencySnapshotAsObject = ConvertToJsonObject(snapshot);
+
+ return ApiConnection.Post(ApiUrls.DependencySubmission(repositoryId), newDependencySnapshotAsObject);
+ }
+
+ ///
+ /// Dependency snapshots dictionaries such as Manifests need to be passed as JsonObject in order to be serialized correctly
+ ///
+ private JsonObject ConvertToJsonObject(NewDependencySnapshot snapshot)
+ {
+ var newSnapshotAsObject = new JsonObject();
+ newSnapshotAsObject.Add("version", snapshot.Version);
+ newSnapshotAsObject.Add("sha", snapshot.Sha);
+ newSnapshotAsObject.Add("ref", snapshot.Ref);
+ newSnapshotAsObject.Add("scanned", snapshot.Scanned);
+ newSnapshotAsObject.Add("job", snapshot.Job);
+ newSnapshotAsObject.Add("detector", snapshot.Detector);
+
+ if (snapshot.Metadata != null)
+ {
+ var metadataAsObject = new JsonObject();
+ foreach (var kvp in snapshot.Metadata)
+ {
+ metadataAsObject.Add(kvp.Key, kvp.Value);
+ }
+
+ newSnapshotAsObject.Add("metadata", metadataAsObject);
+ }
+
+ if (snapshot.Manifests != null)
+ {
+ var manifestsAsObject = new JsonObject();
+ foreach (var manifestKvp in snapshot.Manifests)
+ {
+ var manifest = manifestKvp.Value;
+
+ var manifestAsObject = new JsonObject();
+ manifestAsObject.Add("name", manifest.Name);
+
+ if (manifest.File.SourceLocation != null)
+ {
+ var manifestFileAsObject = new { SourceLocation = manifest.File.SourceLocation };
+ manifestAsObject.Add("file", manifestFileAsObject);
+ }
+
+ if (manifest.Metadata != null)
+ {
+ manifestAsObject.Add("metadata", manifest.Metadata);
+ }
+
+ if (manifest.Resolved != null)
+ {
+ var resolvedAsObject = new JsonObject();
+ foreach (var resolvedKvp in manifest.Resolved)
+ {
+ resolvedAsObject.Add(resolvedKvp.Key, resolvedKvp.Value);
+ }
+
+ manifestAsObject.Add("resolved", resolvedAsObject);
+ }
+
+ manifestsAsObject.Add(manifestKvp.Key, manifestAsObject);
+ }
+
+ newSnapshotAsObject.Add("manifests", manifestsAsObject);
+ }
+
+ return newSnapshotAsObject;
+ }
+ }
+}
diff --git a/Octokit/Clients/IDependencyGraphClient.cs b/Octokit/Clients/IDependencyGraphClient.cs
new file mode 100644
index 0000000000..4729ae8b28
--- /dev/null
+++ b/Octokit/Clients/IDependencyGraphClient.cs
@@ -0,0 +1,21 @@
+namespace Octokit
+{
+ ///
+ /// A client for GitHub's Dependency Graph API.
+ ///
+ ///
+ /// See the Git Dependency Graph API documentation for more information.
+ ///
+ public interface IDependencyGraphClient
+ {
+ ///
+ /// Client for getting a dependency comparison between two commits.
+ ///
+ IDependencyReviewClient DependencyReview { get; }
+
+ ///
+ /// Client for submitting dependency snapshots.
+ ///
+ IDependencySubmissionClient DependencySubmission { get; }
+ }
+}
diff --git a/Octokit/Clients/IDependencyReviewClient.cs b/Octokit/Clients/IDependencyReviewClient.cs
new file mode 100644
index 0000000000..9e6a6e63d7
--- /dev/null
+++ b/Octokit/Clients/IDependencyReviewClient.cs
@@ -0,0 +1,41 @@
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace Octokit
+{
+ ///
+ /// A client for GitHub's Dependency Review API.
+ ///
+ ///
+ /// See the Git Dependency Review API documentation for more information.
+ ///
+ public interface IDependencyReviewClient
+ {
+ ///
+ /// Gets all s for the specified repository.
+ ///
+ ///
+ /// See the API documentation for more information.
+ ///
+ /// The owner of the repository
+ /// The name of the repository
+ /// The base revision
+ /// The head revision
+ /// Thrown when a general API error occurs.
+ [ExcludeFromPaginationApiOptionsConventionTest("Pagination not supported by GitHub API.")]
+ Task> GetAll(string owner, string name, string @base, string head);
+
+ ///
+ /// Gets all s for the specified repository.
+ ///
+ ///
+ /// See the API documentation for more information.
+ ///
+ /// The Id of the repository
+ /// The base revision
+ /// The head revision
+ /// Thrown when a general API error occurs.
+ [ExcludeFromPaginationApiOptionsConventionTest("Pagination not supported by GitHub API.")]
+ Task> GetAll(long repositoryId, string @base, string head);
+ }
+}
diff --git a/Octokit/Clients/IDependencySubmissionClient.cs b/Octokit/Clients/IDependencySubmissionClient.cs
new file mode 100644
index 0000000000..4d51b87b76
--- /dev/null
+++ b/Octokit/Clients/IDependencySubmissionClient.cs
@@ -0,0 +1,38 @@
+using System.Threading.Tasks;
+
+namespace Octokit
+{
+ ///
+ /// A client for GitHub's Dependency Submission API.
+ ///
+ ///
+ /// See the Dependency Submission API documentation for more details.
+ ///
+ public interface IDependencySubmissionClient
+ {
+ ///
+ /// Creates a new dependency snapshot.
+ ///
+ ///
+ /// See the API documentation for more information.
+ ///
+ /// The repository's owner
+ /// The repository's name
+ /// The dependency snapshot to create
+ /// Thrown when a general API error occurs
+ /// A instance for the created snapshot
+ Task Create(string owner, string name, NewDependencySnapshot snapshot);
+
+ ///
+ /// Creates a new dependency snapshot.
+ ///
+ ///
+ /// See the API documentation for more information.
+ ///
+ /// The Id of the repository
+ /// The dependency snapshot to create
+ /// Thrown when a general API error occurs
+ /// A instance for the created snapshot
+ Task Create(long repositoryId, NewDependencySnapshot snapshot);
+ }
+}
diff --git a/Octokit/GitHubClient.cs b/Octokit/GitHubClient.cs
index d7b8bea36f..97f0474493 100644
--- a/Octokit/GitHubClient.cs
+++ b/Octokit/GitHubClient.cs
@@ -122,6 +122,7 @@ public GitHubClient(IConnection connection)
Actions = new ActionsClient(apiConnection);
Codespaces = new CodespacesClient(apiConnection);
Copilot = new CopilotClient(apiConnection);
+ DependencyGraph = new DependencyGraphClient(apiConnection);
}
///
@@ -396,12 +397,17 @@ public Uri BaseAddress
public IActionsClient Actions { get; private set; }
public ICodespacesClient Codespaces { get; private set; }
-
+
///
/// Access GitHub's Copilot for Business API
///
public ICopilotClient Copilot { get; private set; }
+ ///
+ /// Access GitHub's Dependency Graph API
+ ///
+ public IDependencyGraphClient DependencyGraph { get; private set; }
+
static Uri FixUpBaseUri(Uri uri)
{
Ensure.ArgumentNotNull(uri, nameof(uri));
diff --git a/Octokit/Helpers/ApiUrls.cs b/Octokit/Helpers/ApiUrls.cs
index 06849637ec..44eefc029e 100644
--- a/Octokit/Helpers/ApiUrls.cs
+++ b/Octokit/Helpers/ApiUrls.cs
@@ -922,7 +922,7 @@ public static Uri OrganizationMemberships(string org, string name)
{
return "orgs/{0}/memberships/{1}".FormatUri(org, name);
}
-
+
///
/// Returns the for the organization's invitations
///
@@ -2568,6 +2568,30 @@ public static Uri RepositoryVulnerabilityAlerts(string owner, string name)
return "repos/{0}/{1}/vulnerability-alerts".FormatUri(owner, name);
}
+ ///
+ /// Returns the for getting Dependency-Diffs between two revisions.
+ ///
+ /// The owner of the repository
+ /// The name of the repository
+ /// The base revision
+ /// The head revision
+ /// The for getting Dependency-Diffs between two revisions for the given repository.
+ public static Uri DependencyReview(string owner, string name, string @base, string head)
+ {
+ return "repos/{0}/{1}/dependency-graph/compare/{2}...{3}".FormatUri(owner, name, @base, head);
+ }
+
+ ///
+ /// Returns the for submitting a Dependency Snapshot for the given repository.
+ ///
+ /// The owner of the repository
+ /// The name of the repository
+ /// The for submitting a Dependency Snapshot for the given repository.
+ public static Uri DependencySubmission(string owner, string name)
+ {
+ return "repos/{0}/{1}/dependency-graph/snapshots".FormatUri(owner, name);
+ }
+
///
/// Returns the for the Deployments API for the given repository.
///
@@ -3244,6 +3268,28 @@ public static Uri CreateTag(long repositoryId)
return "repositories/{0}/git/tags".FormatUri(repositoryId);
}
+ ///
+ /// Returns the for getting Dependency-Diffs between two revisions.
+ ///
+ /// The Id of the repository
+ /// The base revision
+ /// The head revision
+ /// The for getting Dependency-Diffs between two revisions for the given repository.
+ public static Uri DependencyReview(long repositoryId, string @base, string head)
+ {
+ return "repositories/{0}/dependency-graph/compare/{1}...{2}".FormatUri(repositoryId, @base, head);
+ }
+
+ ///
+ /// Returns the for submitting a Dependency Snapshot for the given repository.
+ ///
+ /// The Id of the repository
+ /// The for submitting a Dependency Snapshot for the given repository.
+ public static Uri DependencySubmission(long repositoryId)
+ {
+ return "repositories/{0}/dependency-graph/snapshots".FormatUri(repositoryId);
+ }
+
///
/// Returns the for the Deployments API for the given repository.
///
@@ -5502,7 +5548,7 @@ public static Uri ActionsListOrganizationRunnerGroupRepositories(string org, lon
{
return "orgs/{0}/actions/runner-groups/{1}/repositories".FormatUri(org, runnerGroupId);
}
-
+
///
/// Returns the that handles adding or removing of copilot licenses for an organisation
///
@@ -5512,7 +5558,7 @@ public static Uri CopilotBillingLicense(string org)
{
return $"orgs/{org}/copilot/billing/selected_users".FormatUri(org);
}
-
+
///
/// Returns the that handles reading copilot billing settings for an organization
///
@@ -5522,7 +5568,7 @@ public static Uri CopilotBillingSettings(string org)
{
return $"orgs/{org}/copilot/billing".FormatUri(org);
}
-
+
///
/// Returns the that allows for searching across all licenses for an organisation
///
@@ -5532,7 +5578,7 @@ public static Uri CopilotAllocatedLicenses(string org)
{
return $"orgs/{org}/copilot/billing/seats".FormatUri(org);
}
-
+
public static Uri Codespaces()
{
return _currentUserAllCodespaces;
diff --git a/Octokit/IGitHubClient.cs b/Octokit/IGitHubClient.cs
index 3ff9f320c7..643aac636a 100644
--- a/Octokit/IGitHubClient.cs
+++ b/Octokit/IGitHubClient.cs
@@ -217,10 +217,15 @@ public interface IGitHubClient : IApiInfoProvider
IEmojisClient Emojis { get; }
ICodespacesClient Codespaces { get; }
-
+
///
/// Access to the GitHub Copilot for Business API
///
ICopilotClient Copilot { get; }
+
+ ///
+ /// Access GitHub's Dependency Graph API
+ ///
+ IDependencyGraphClient DependencyGraph { get; }
}
}
diff --git a/Octokit/Models/Request/NewDependencySnapshot.cs b/Octokit/Models/Request/NewDependencySnapshot.cs
new file mode 100644
index 0000000000..fc259203a4
--- /dev/null
+++ b/Octokit/Models/Request/NewDependencySnapshot.cs
@@ -0,0 +1,86 @@
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Globalization;
+
+namespace Octokit
+{
+ ///
+ /// Describes a new dependency snapshot to create via the method.
+ ///
+ [DebuggerDisplay("{DebuggerDisplay,nq}")]
+ public class NewDependencySnapshot
+ {
+ ///
+ /// Creates a new Dependency Snapshot.
+ ///
+ /// Required. The version of the repository snapshot submission.
+ /// Required. The commit SHA associated with this dependency snapshot. Maximum length: 40 characters.
+ /// Required. The repository branch that triggered this snapshot.
+ /// Required. The time at which the snapshot was scanned.
+ /// Required. The job associated with this dependency snapshot.
+ /// Required. A description of the detector used.
+ public NewDependencySnapshot(long version, string sha, string @ref, string scanned, NewDependencySnapshotJob job, NewDependencySnapshotDetector detector)
+ {
+ Ensure.ArgumentNotNullOrEmptyString(sha, nameof(sha));
+ Ensure.ArgumentNotNullOrEmptyString(@ref, nameof(@ref));
+ Ensure.ArgumentNotNullOrEmptyString(scanned, nameof(scanned));
+ Ensure.ArgumentNotNull(job, nameof(job));
+ Ensure.ArgumentNotNull(detector, nameof(detector));
+
+ Version = version;
+ Sha = sha;
+ Ref = @ref;
+ Scanned = scanned;
+ Job = job;
+ Detector = detector;
+ }
+
+ ///
+ /// Required. The version of the repository snapshot submission.
+ ///
+ public long Version { get; private set; }
+
+ ///
+ /// Required. The job associated with this dependency snapshot.
+ ///
+ public NewDependencySnapshotJob Job { get; private set; }
+
+ ///
+ /// Required. The commit SHA associated with this dependency snapshot. Maximum length: 40 characters.
+ ///
+ public string Sha { get; private set; }
+
+ ///
+ /// Required. The repository branch that triggered this snapshot.
+ ///
+ public string Ref { get; private set; }
+
+ ///
+ /// Required. A description of the detector used.
+ ///
+ public NewDependencySnapshotDetector Detector { get; private set; }
+
+ ///
+ /// Optional. User-defined metadata to store domain-specific information limited to 8 keys with scalar values.
+ ///
+ public IDictionary Metadata { get; set; }
+
+ ///
+ /// Optional. A collection of package manifests.
+ ///
+ public IDictionary Manifests { get; set; }
+
+ ///
+ /// Required. The time at which the snapshot was scanned.
+ ///
+ public string Scanned { get; private set; }
+
+ internal string DebuggerDisplay
+ {
+ get
+ {
+ return string.Format(CultureInfo.InvariantCulture, "Sha: {0}, Version: {1}", Sha, Version);
+ }
+ }
+ }
+}
diff --git a/Octokit/Models/Request/NewDependencySnapshotDetector.cs b/Octokit/Models/Request/NewDependencySnapshotDetector.cs
new file mode 100644
index 0000000000..00f562b6e6
--- /dev/null
+++ b/Octokit/Models/Request/NewDependencySnapshotDetector.cs
@@ -0,0 +1,45 @@
+using System.Diagnostics;
+using System.Globalization;
+
+namespace Octokit
+{
+ [DebuggerDisplay("{DebuggerDisplay,nq}")]
+ public class NewDependencySnapshotDetector
+ {
+ ///
+ /// Creates a new Dependency Snapshot Detector.
+ ///
+ /// Required. The name of the detector used.
+ /// Required. The version of the detector used.
+ /// Required. The url of the detector used.
+ public NewDependencySnapshotDetector(string name, string version, string url)
+ {
+ Name = name;
+ Version = version;
+ Url = url;
+ }
+
+ ///
+ /// Required. The name of the detector used.
+ ///
+ public string Name { get; private set; }
+
+ ///
+ /// Required. The version of the detector used.
+ ///
+ public string Version { get; private set; }
+
+ ///
+ /// Required. The url of the detector used.
+ ///
+ public string Url { get; private set; }
+
+ internal string DebuggerDisplay
+ {
+ get
+ {
+ return string.Format(CultureInfo.InvariantCulture, "Name: {0}, Version: {1}", Name, Version);
+ }
+ }
+ }
+}
diff --git a/Octokit/Models/Request/NewDependencySnapshotJob.cs b/Octokit/Models/Request/NewDependencySnapshotJob.cs
new file mode 100644
index 0000000000..9ee9163860
--- /dev/null
+++ b/Octokit/Models/Request/NewDependencySnapshotJob.cs
@@ -0,0 +1,45 @@
+using System.Diagnostics;
+using System.Globalization;
+
+namespace Octokit
+{
+ [DebuggerDisplay("{DebuggerDisplay,nq}")]
+ public class NewDependencySnapshotJob
+ {
+ ///
+ /// Creates a new Dependency Snapshot Job.
+ ///
+ /// Required. The external ID of the job.
+ /// Required. Correlator that is used to group snapshots submitted over time.
+ public NewDependencySnapshotJob(string id, string correlator)
+ {
+ Ensure.ArgumentNotNullOrEmptyString(correlator, nameof(correlator));
+
+ Id = id;
+ Correlator = correlator;
+ }
+
+ ///
+ /// Required. The external ID of the job.
+ ///
+ public string Id { get; private set; }
+
+ ///
+ /// Required. Correlator that is used to group snapshots submitted over time.
+ ///
+ public string Correlator { get; private set; }
+
+ ///
+ /// Optional. The URL for the job.
+ ///
+ public string HtmlUrl { get; set; }
+
+ internal string DebuggerDisplay
+ {
+ get
+ {
+ return string.Format(CultureInfo.InvariantCulture, "Id: {0}, HtmlUrl: {1}", Id, HtmlUrl);
+ }
+ }
+ }
+}
diff --git a/Octokit/Models/Request/NewDependencySnapshotManifest.cs b/Octokit/Models/Request/NewDependencySnapshotManifest.cs
new file mode 100644
index 0000000000..5fca4a4e72
--- /dev/null
+++ b/Octokit/Models/Request/NewDependencySnapshotManifest.cs
@@ -0,0 +1,49 @@
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Globalization;
+
+namespace Octokit
+{
+ [DebuggerDisplay("{DebuggerDisplay,nq}")]
+ public class NewDependencySnapshotManifest
+ {
+ ///
+ /// Creates a new Dependency Manifest Item.
+ ///
+ /// Required. The name of the manifest.
+ public NewDependencySnapshotManifest(string name)
+ {
+ Ensure.ArgumentNotNullOrEmptyString(name, nameof(name));
+
+ Name = name;
+ }
+
+ ///
+ /// Required. The name of the manifest.
+ ///
+ public string Name { get; private set; }
+
+ ///
+ /// Optional. The manifest file.
+ ///
+ public NewDependencySnapshotManifestFile File { get; set; }
+
+ ///
+ /// Optional. User-defined metadata to store domain-specific information limited to 8 keys with scalar values.
+ ///
+ public IDictionary Metadata { get; set; }
+
+ ///
+ /// Optional. A collection of resolved package dependencies.
+ ///
+ public IDictionary Resolved { get; set; }
+
+ internal string DebuggerDisplay
+ {
+ get
+ {
+ return string.Format(CultureInfo.InvariantCulture, "Name: {0}", Name);
+ }
+ }
+ }
+}
diff --git a/Octokit/Models/Request/NewDependencySnapshotManifestFile.cs b/Octokit/Models/Request/NewDependencySnapshotManifestFile.cs
new file mode 100644
index 0000000000..3f4ac22671
--- /dev/null
+++ b/Octokit/Models/Request/NewDependencySnapshotManifestFile.cs
@@ -0,0 +1,22 @@
+using System.Diagnostics;
+using System.Globalization;
+
+namespace Octokit
+{
+ [DebuggerDisplay("{DebuggerDisplay,nq}")]
+ public class NewDependencySnapshotManifestFile
+ {
+ ///
+ /// Optional. The path of the manifest file relative to the root of the Git repository.
+ ///
+ public string SourceLocation { get; set; }
+
+ internal string DebuggerDisplay
+ {
+ get
+ {
+ return string.Format(CultureInfo.InvariantCulture, "Source Location: {0}", SourceLocation);
+ }
+ }
+ }
+}
diff --git a/Octokit/Models/Request/NewDependencySnapshotResolvedDependency.cs b/Octokit/Models/Request/NewDependencySnapshotResolvedDependency.cs
new file mode 100644
index 0000000000..ab48314a7a
--- /dev/null
+++ b/Octokit/Models/Request/NewDependencySnapshotResolvedDependency.cs
@@ -0,0 +1,75 @@
+using Octokit.Internal;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Diagnostics;
+using System.Globalization;
+
+namespace Octokit
+{
+ [DebuggerDisplay("{DebuggerDisplay,nq}")]
+ public class NewDependencySnapshotResolvedDependency
+ {
+ ///
+ /// Optional. Package-url (PURL) of the dependency.
+ ///
+ public string PackageUrl { get; set; }
+
+ ///
+ /// Optional. User-defined metadata to store domain-specific information limited to 8 keys with scalar values..
+ ///
+ public IDictionary Metadata { get; set; }
+
+ ///
+ /// Optional. A notation of whether a dependency is requested directly by this manifest or is a dependency of another dependency.
+ ///
+ public ResolvedPackageKeyRelationship Relationship { get; set; }
+
+ ///
+ /// Optional. A notation of whether the dependency is required for the primary build artifact (runtime) or is only used for development.
+ ///
+ public ResolvedPackageKeyScope Scope { get; set; }
+
+ ///
+ /// Optional. Array of package-url (PURLs) of direct child dependencies.
+ ///
+ public Collection Dependencies { get; set; }
+
+ internal string DebuggerDisplay
+ {
+ get
+ {
+ return string.Format(CultureInfo.InvariantCulture, "Package Url: {0}", PackageUrl);
+ }
+ }
+ }
+
+ public enum ResolvedPackageKeyRelationship
+ {
+ ///
+ /// The dependency is requested directly by the manifest.
+ ///
+ [Parameter(Value = "direct")]
+ Direct,
+
+ ///
+ /// The dependency is a dependency of another dependency.
+ ///
+ [Parameter(Value = "indirect")]
+ Indirect,
+ }
+
+ public enum ResolvedPackageKeyScope
+ {
+ ///
+ /// The dependency is required for the primary build artifact.
+ ///
+ [Parameter(Value = "runtime")]
+ Runtime,
+
+ ///
+ /// The dependency is only used for development.
+ ///
+ [Parameter(Value = "development")]
+ Development,
+ }
+}
diff --git a/Octokit/Models/Response/ChangeType.cs b/Octokit/Models/Response/ChangeType.cs
new file mode 100644
index 0000000000..8daf475475
--- /dev/null
+++ b/Octokit/Models/Response/ChangeType.cs
@@ -0,0 +1,13 @@
+using Octokit.Internal;
+
+namespace Octokit
+{
+ public enum ChangeType
+ {
+ [Parameter(Value = "Added")]
+ Added,
+
+ [Parameter(Value = "Removed")]
+ Removed
+ }
+}
\ No newline at end of file
diff --git a/Octokit/Models/Response/DependencyDiff.cs b/Octokit/Models/Response/DependencyDiff.cs
new file mode 100644
index 0000000000..3521d55107
--- /dev/null
+++ b/Octokit/Models/Response/DependencyDiff.cs
@@ -0,0 +1,127 @@
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Globalization;
+
+namespace Octokit
+{
+ [DebuggerDisplay("{DebuggerDisplay,nq}")]
+ public class DependencyDiff
+ {
+ public DependencyDiff() { }
+
+ public DependencyDiff(ChangeType changeType, string manifest, string ecosystem, string name, string version, string packageUrl, string license, string sourceRepositoryUrl, IReadOnlyList vulnerabilities, Scope scope)
+ {
+ ChangeType = changeType;
+ Manifest = manifest;
+ Ecosystem = ecosystem;
+ Name = name;
+ Version = version;
+ PackageUrl = packageUrl;
+ License = license;
+ SourceRepositoryUrl = sourceRepositoryUrl;
+ Vulnerabilities = vulnerabilities;
+ Scope = scope;
+ }
+
+ ///
+ /// The type of the change.
+ ///
+ public StringEnum ChangeType { get; private set; }
+
+ ///
+ /// The package manifest of the dependency.
+ ///
+ public string Manifest { get; private set; }
+
+ ///
+ /// The package ecosystem of the dependency.
+ ///
+ public string Ecosystem { get; private set; }
+
+ ///
+ /// The package name of the dependency.
+ ///
+ public string Name { get; private set; }
+
+ ///
+ /// The package version of the dependency.
+ ///
+ public string Version { get; private set; }
+
+ ///
+ /// The package URL of the dependency.
+ ///
+ public string PackageUrl { get; private set; }
+
+ ///
+ /// The license of the dependency.
+ ///
+ public string License { get; private set; }
+
+ ///
+ /// The URL of the source repository of the dependency.
+ ///
+ public string SourceRepositoryUrl { get; private set; }
+
+ ///
+ /// A list of vulnerabilities for the dependency.
+ ///
+ public IReadOnlyList Vulnerabilities { get; private set; }
+
+ ///
+ /// The scope of the dependency.
+ ///
+ public StringEnum Scope { get; private set; }
+
+ internal string DebuggerDisplay
+ {
+ get
+ {
+ return string.Format(CultureInfo.InvariantCulture, "Name: {0}, Version: {1}", Name, Version);
+ }
+ }
+ }
+
+ [DebuggerDisplay("{DebuggerDisplay,nq}")]
+ public class DependencyVulnerability
+ {
+ public DependencyVulnerability() { }
+
+ public DependencyVulnerability(string severity, string advisoryGhsaId, string advisorySummary, string advisoryUrl)
+ {
+ Severity = severity;
+ AdvisoryGhsaId = advisoryGhsaId;
+ AdvisorySummary = advisorySummary;
+ AdvisoryUrl = advisoryUrl;
+ }
+
+ ///
+ /// The severity of the vulnerability.
+ ///
+ public string Severity { get; private set; }
+
+ ///
+ /// The GHSA Id of the advisory.
+ ///
+ public string AdvisoryGhsaId { get; private set; }
+
+ ///
+ /// "A summary of the advisory."
+ ///
+ public string AdvisorySummary { get; private set; }
+
+ ///
+ /// The URL of the advisory.
+ ///
+ public string AdvisoryUrl { get; private set; }
+
+ internal string DebuggerDisplay
+ {
+ get
+ {
+ return string.Format(CultureInfo.InvariantCulture, "Advisory URL: {0}", AdvisoryUrl);
+ }
+ }
+ }
+
+}
diff --git a/Octokit/Models/Response/DependencySnapshotSubmission.cs b/Octokit/Models/Response/DependencySnapshotSubmission.cs
new file mode 100644
index 0000000000..c40403b789
--- /dev/null
+++ b/Octokit/Models/Response/DependencySnapshotSubmission.cs
@@ -0,0 +1,70 @@
+using Octokit.Internal;
+using System;
+using System.Diagnostics;
+using System.Globalization;
+
+namespace Octokit
+{
+ [DebuggerDisplay("{DebuggerDisplay,nq}")]
+ public class DependencySnapshotSubmission
+ {
+ public DependencySnapshotSubmission() { }
+
+ public DependencySnapshotSubmission(long id, DateTimeOffset createdAt, DependencySnapshotSubmissionResult result, string message)
+ {
+ Id = id;
+ CreatedAt = createdAt;
+ Result = result;
+ Message = message;
+ }
+
+ ///
+ /// ID of the created snapshot.
+ ///
+ public long Id { get; private set; }
+
+ ///
+ /// The time at which the snapshot was created.
+ ///
+ public DateTimeOffset CreatedAt { get; private set; }
+
+ ///
+ /// The outcome of the dependency snapshot creation.
+ ///
+ public StringEnum Result { get; private set; }
+
+ ///
+ /// A message providing further details about the result, such as why the dependencies were not updated.
+ ///
+ public string Message { get; private set; }
+
+ internal string DebuggerDisplay
+ {
+ get
+ {
+ return string.Format(CultureInfo.InvariantCulture, "Id: {0} Created at: {1}", Id, CreatedAt);
+ }
+ }
+ }
+
+ public enum DependencySnapshotSubmissionResult
+ {
+ ///
+ /// The snapshot was successfully created and the repository's dependencies were updated.
+ ///
+ [Parameter(Value = "Success")]
+ Success,
+
+ ///
+ /// The snapshot was successfully created, but the repository's dependencies were not updated.
+ ///
+ [Parameter(Value = "Accepted")]
+ Accepted,
+
+ ///
+ /// The snapshot was malformed.
+ ///
+ [Parameter(Value = "Invalid")]
+ Invalid
+ }
+}
diff --git a/Octokit/Models/Response/Scope.cs b/Octokit/Models/Response/Scope.cs
new file mode 100644
index 0000000000..2d687b3849
--- /dev/null
+++ b/Octokit/Models/Response/Scope.cs
@@ -0,0 +1,25 @@
+using Octokit.Internal;
+
+namespace Octokit
+{
+ public enum Scope
+ {
+ ///
+ /// The scope of the dependency is not specified or cannot be determined.
+ ///
+ [Parameter(Value = "Unknown")]
+ Unknown,
+
+ ///
+ /// Dependency is utilized at runtime and in the development environment.
+ ///
+ [Parameter(Value = "Runtime")]
+ Runtime,
+
+ ///
+ /// Dependency is only utilized in the development environment.
+ ///
+ [Parameter(Value = "Development")]
+ Development,
+ }
+}