|
|
|
@ -1,4 +1,5 @@
|
|
|
|
|
using Octokit; |
|
|
|
|
using Microsoft.Extensions.Logging; |
|
|
|
|
using Octokit; |
|
|
|
|
using StabilityMatrix.Core.Attributes; |
|
|
|
|
using StabilityMatrix.Core.Database; |
|
|
|
|
using StabilityMatrix.Core.Models.Database; |
|
|
|
@ -10,83 +11,85 @@ public class GithubApiCache : IGithubApiCache
|
|
|
|
|
{ |
|
|
|
|
private readonly ILiteDbContext dbContext; |
|
|
|
|
private readonly IGitHubClient githubApi; |
|
|
|
|
private readonly ILogger<IGithubApiCache> logger; |
|
|
|
|
private readonly TimeSpan cacheDuration = TimeSpan.FromMinutes(15); |
|
|
|
|
|
|
|
|
|
public GithubApiCache(ILiteDbContext dbContext, IGitHubClient githubApi) |
|
|
|
|
public GithubApiCache( |
|
|
|
|
ILiteDbContext dbContext, |
|
|
|
|
IGitHubClient githubApi, |
|
|
|
|
ILogger<IGithubApiCache> logger |
|
|
|
|
) |
|
|
|
|
{ |
|
|
|
|
this.dbContext = dbContext; |
|
|
|
|
this.githubApi = githubApi; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public async Task<Release?> GetLatestRelease(string username, string repository) |
|
|
|
|
{ |
|
|
|
|
var cacheKey = $"Releases-{username}-{repository}"; |
|
|
|
|
var latestRelease = await dbContext.GetGithubCacheEntry(cacheKey); |
|
|
|
|
if (latestRelease != null && !IsCacheExpired(latestRelease.LastUpdated)) |
|
|
|
|
{ |
|
|
|
|
return latestRelease.AllReleases.First(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var allReleases = await githubApi.Repository.Release.GetAll(username, repository); |
|
|
|
|
if (allReleases == null) |
|
|
|
|
{ |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var cacheEntry = new GithubCacheEntry |
|
|
|
|
{ |
|
|
|
|
CacheKey = cacheKey, |
|
|
|
|
AllReleases = allReleases.OrderByDescending(x => x.CreatedAt) |
|
|
|
|
}; |
|
|
|
|
await dbContext.UpsertGithubCacheEntry(cacheEntry); |
|
|
|
|
|
|
|
|
|
return cacheEntry.AllReleases.First(); |
|
|
|
|
this.logger = logger; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public async Task<IEnumerable<Release>> GetAllReleases(string username, string repository) |
|
|
|
|
{ |
|
|
|
|
var cacheKey = $"Releases-{username}-{repository}"; |
|
|
|
|
var cacheEntry = await dbContext.GetGithubCacheEntry(cacheKey); |
|
|
|
|
var cacheEntry = await dbContext.GetGithubCacheEntry(cacheKey).ConfigureAwait(false); |
|
|
|
|
if (cacheEntry != null && !IsCacheExpired(cacheEntry.LastUpdated)) |
|
|
|
|
{ |
|
|
|
|
return cacheEntry.AllReleases.OrderByDescending(x => x.CreatedAt); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var allReleases = await githubApi.Repository.Release.GetAll(username, repository); |
|
|
|
|
if (allReleases == null) |
|
|
|
|
try |
|
|
|
|
{ |
|
|
|
|
return new List<Release>().OrderByDescending(x => x.CreatedAt); |
|
|
|
|
} |
|
|
|
|
var allReleases = await githubApi.Repository.Release |
|
|
|
|
.GetAll(username, repository) |
|
|
|
|
.ConfigureAwait(false); |
|
|
|
|
if (allReleases == null) |
|
|
|
|
{ |
|
|
|
|
return new List<Release>(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var newCacheEntry = new GithubCacheEntry |
|
|
|
|
{ |
|
|
|
|
CacheKey = cacheKey, |
|
|
|
|
AllReleases = allReleases.OrderByDescending(x => x.CreatedAt) |
|
|
|
|
}; |
|
|
|
|
await dbContext.UpsertGithubCacheEntry(newCacheEntry); |
|
|
|
|
var newCacheEntry = new GithubCacheEntry |
|
|
|
|
{ |
|
|
|
|
CacheKey = cacheKey, |
|
|
|
|
AllReleases = allReleases.OrderByDescending(x => x.CreatedAt) |
|
|
|
|
}; |
|
|
|
|
await dbContext.UpsertGithubCacheEntry(newCacheEntry).ConfigureAwait(false); |
|
|
|
|
|
|
|
|
|
return newCacheEntry.AllReleases; |
|
|
|
|
return newCacheEntry.AllReleases; |
|
|
|
|
} |
|
|
|
|
catch (ApiException ex) |
|
|
|
|
{ |
|
|
|
|
logger.LogWarning(ex, "Failed to get releases from Github API."); |
|
|
|
|
return cacheEntry?.AllReleases.OrderByDescending(x => x.CreatedAt) |
|
|
|
|
?? Enumerable.Empty<Release>(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public async Task<IEnumerable<Branch>> GetAllBranches(string username, string repository) |
|
|
|
|
{ |
|
|
|
|
var cacheKey = $"Branches-{username}-{repository}"; |
|
|
|
|
var cacheEntry = await dbContext.GetGithubCacheEntry(cacheKey); |
|
|
|
|
var cacheEntry = await dbContext.GetGithubCacheEntry(cacheKey).ConfigureAwait(false); |
|
|
|
|
if (cacheEntry != null && !IsCacheExpired(cacheEntry.LastUpdated)) |
|
|
|
|
{ |
|
|
|
|
return cacheEntry.Branches; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var branches = await githubApi.Repository.Branch.GetAll(username, repository); |
|
|
|
|
if (branches == null) |
|
|
|
|
try |
|
|
|
|
{ |
|
|
|
|
return new List<Branch>(); |
|
|
|
|
} |
|
|
|
|
var branches = await githubApi.Repository.Branch |
|
|
|
|
.GetAll(username, repository) |
|
|
|
|
.ConfigureAwait(false); |
|
|
|
|
if (branches == null) |
|
|
|
|
{ |
|
|
|
|
return new List<Branch>(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var newCacheEntry = new GithubCacheEntry { CacheKey = cacheKey, Branches = branches }; |
|
|
|
|
await dbContext.UpsertGithubCacheEntry(newCacheEntry); |
|
|
|
|
var newCacheEntry = new GithubCacheEntry { CacheKey = cacheKey, Branches = branches }; |
|
|
|
|
await dbContext.UpsertGithubCacheEntry(newCacheEntry).ConfigureAwait(false); |
|
|
|
|
|
|
|
|
|
return newCacheEntry.Branches; |
|
|
|
|
return newCacheEntry.Branches; |
|
|
|
|
} |
|
|
|
|
catch (ApiException ex) |
|
|
|
|
{ |
|
|
|
|
logger.LogWarning(ex, "Failed to get branches from Github API."); |
|
|
|
|
return cacheEntry?.Branches ?? Enumerable.Empty<Branch>(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public async Task<IEnumerable<GitCommit>?> GetAllCommits( |
|
|
|
@ -98,37 +101,47 @@ public class GithubApiCache : IGithubApiCache
|
|
|
|
|
) |
|
|
|
|
{ |
|
|
|
|
var cacheKey = $"Commits-{username}-{repository}-{branch}-{page}-{perPage}"; |
|
|
|
|
var cacheEntry = await dbContext.GetGithubCacheEntry(cacheKey); |
|
|
|
|
var cacheEntry = await dbContext.GetGithubCacheEntry(cacheKey).ConfigureAwait(false); |
|
|
|
|
if (cacheEntry != null && !IsCacheExpired(cacheEntry.LastUpdated)) |
|
|
|
|
{ |
|
|
|
|
return cacheEntry.Commits; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var commits = await githubApi.Repository.Commit.GetAll( |
|
|
|
|
username, |
|
|
|
|
repository, |
|
|
|
|
new CommitRequest { Sha = branch }, |
|
|
|
|
new ApiOptions |
|
|
|
|
try |
|
|
|
|
{ |
|
|
|
|
var commits = await githubApi.Repository.Commit |
|
|
|
|
.GetAll( |
|
|
|
|
username, |
|
|
|
|
repository, |
|
|
|
|
new CommitRequest { Sha = branch }, |
|
|
|
|
new ApiOptions |
|
|
|
|
{ |
|
|
|
|
PageCount = page, |
|
|
|
|
PageSize = perPage, |
|
|
|
|
StartPage = page |
|
|
|
|
} |
|
|
|
|
) |
|
|
|
|
.ConfigureAwait(false); |
|
|
|
|
|
|
|
|
|
if (commits == null) |
|
|
|
|
{ |
|
|
|
|
PageCount = page, |
|
|
|
|
PageSize = perPage, |
|
|
|
|
StartPage = page |
|
|
|
|
return new List<GitCommit>(); |
|
|
|
|
} |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
if (commits == null) |
|
|
|
|
{ |
|
|
|
|
return new List<GitCommit>(); |
|
|
|
|
} |
|
|
|
|
var newCacheEntry = new GithubCacheEntry |
|
|
|
|
{ |
|
|
|
|
CacheKey = cacheKey, |
|
|
|
|
Commits = commits.Select(x => new GitCommit { Sha = x.Sha }) |
|
|
|
|
}; |
|
|
|
|
await dbContext.UpsertGithubCacheEntry(newCacheEntry).ConfigureAwait(false); |
|
|
|
|
|
|
|
|
|
var newCacheEntry = new GithubCacheEntry |
|
|
|
|
return newCacheEntry.Commits; |
|
|
|
|
} |
|
|
|
|
catch (ApiException ex) |
|
|
|
|
{ |
|
|
|
|
CacheKey = cacheKey, |
|
|
|
|
Commits = commits.Select(x => new GitCommit { Sha = x.Sha }) |
|
|
|
|
}; |
|
|
|
|
await dbContext.UpsertGithubCacheEntry(newCacheEntry); |
|
|
|
|
|
|
|
|
|
return newCacheEntry.Commits; |
|
|
|
|
logger.LogWarning(ex, "Failed to get commits from Github API."); |
|
|
|
|
return cacheEntry?.Commits ?? Enumerable.Empty<GitCommit>(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private bool IsCacheExpired(DateTimeOffset expiration) => |
|
|
|
|