Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exclude release author bots from authors list #4318

Merged
merged 1 commit into from
Feb 21, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 11 additions & 12 deletions Netkan/Sources/Github/GithubApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

using log4net;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

using CKAN.NetKAN.Services;

Expand Down Expand Up @@ -72,21 +71,21 @@ public IEnumerable<GithubRelease> GetAllReleases(GithubRef reference, bool? useP
break;
}
Log.Debug("Parsing JSON...");
var jsonReleases = JArray.Parse(json);
if (jsonReleases.Count < 1)
var ghReleases = JsonConvert.DeserializeObject<GithubRelease[]>(json)
?.Where(ghRel => ReleaseTypeMatches(usePrerelease, ghRel.PreRelease)
// Skip releases without assets
&& (reference.UseSourceArchive
|| (ghRel.Assets != null
&& ghRel.Assets.Any(reference.FilterMatches))))
// Insurance against GitHub returning them in the wrong order
.OrderByDescending(ghRel => ghRel.PublishedAt)
.ToArray()
?? Array.Empty<GithubRelease>();
if (ghReleases.Length < 1)
{
// That's all folks!
break;
}
var ghReleases = jsonReleases
.Select(rel => new GithubRelease(reference, rel))
.Where(ghRel => ReleaseTypeMatches(usePrerelease, ghRel.PreRelease)
// Skip releases without assets
&& ghRel.Assets != null
&& ghRel.Assets.Count != 0)
// Insurance against GitHub returning them in the wrong order
.OrderByDescending(ghRel => ghRel.PublishedAt)
.ToList();

foreach (var ghRel in ghReleases)
{
Expand Down
6 changes: 5 additions & 1 deletion Netkan/Sources/Github/GithubRef.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ internal sealed class GithubRef : RemoteRef
public string Account { get; private set; }
public string Project { get; private set; }
public string Repository { get; private set; }
public Regex? Filter { get; private set; }
public Regex Filter { get; private set; }
public Regex? VersionFromAsset { get; private set; }
public bool UseSourceArchive { get; private set; }

Expand Down Expand Up @@ -46,5 +46,9 @@ public GithubRef(RemoteRef remoteRef, bool useSourceArchive)
throw new Kraken(string.Format(@"Could not parse reference: ""{0}""", remoteRef));
}
}

public bool FilterMatches(GithubReleaseAsset asset)
=> asset.Name is string name && Filter.IsMatch(name);

}
}
65 changes: 21 additions & 44 deletions Netkan/Sources/Github/GithubRelease.cs
Original file line number Diff line number Diff line change
@@ -1,54 +1,31 @@
using System;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel;

using Newtonsoft.Json.Linq;
using Newtonsoft.Json;

using CKAN.Versioning;

namespace CKAN.NetKAN.Sources.Github
{
internal sealed class GithubRelease
public sealed class GithubRelease
{
public readonly string? Author;
public readonly ModuleVersion? Tag;
public readonly List<GithubReleaseAsset>? Assets;
public readonly bool PreRelease;
public readonly DateTime? PublishedAt;

public GithubRelease(GithubRef reference, JToken json)
{
PreRelease = (bool?)json["prerelease"] ?? false;
Tag = (string?)json["tag_name"] is string s ? new ModuleVersion(s) : null;
if (Tag == null)
{
throw new Kraken("GitHub release missing tag!");
}
Author = (string?)json["author"]?["login"];
PublishedAt = (DateTime?)json["published_at"];
Assets = reference.UseSourceArchive
&& (string?)json["zipball_url"] is string sourceZIP
? new List<GithubReleaseAsset> {
new GithubReleaseAsset(Tag.ToString(), new Uri(sourceZIP), PublishedAt),
}
: (JArray?)json["assets"] is JArray assets
&& reference.Filter != null
? assets.Select(asset => (string?)asset["name"] is string name
&& reference.Filter.IsMatch(name)
&& (string?)asset["browser_download_url"] is string url
&& (DateTime?)asset["updated_at"] is DateTime updated
? new GithubReleaseAsset(name, new Uri(url), updated)
: null)
.OfType<GithubReleaseAsset>()
.ToList()
: new List<GithubReleaseAsset>();
}

public GithubRelease(string author, ModuleVersion tag, List<GithubReleaseAsset> assets)
{
Author = author;
Tag = tag;
Assets = assets;
}
[JsonProperty("author")]
public GithubUser? Author { get; set; }

[JsonProperty("tag_name")]
public ModuleVersion? Tag { get; set; }

[JsonProperty("assets")]
public GithubReleaseAsset[]? Assets { get; set; }

[JsonProperty("zipball_url")]
public Uri? SourceArchive { get; set; }

[JsonProperty("published_at")]
public DateTime? PublishedAt { get; set; }

[JsonProperty("prerelease")]
[DefaultValue(false)]
public bool PreRelease { get; set; } = false;
}
}
21 changes: 12 additions & 9 deletions Netkan/Sources/Github/GithubReleaseAsset.cs
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
using System;

using Newtonsoft.Json;

namespace CKAN.NetKAN.Sources.Github
{
public sealed class GithubReleaseAsset
{
public string Name { get; }
public Uri Download { get; }
public DateTime? Updated { get; }
[JsonProperty("name")]
public string? Name { get; set; }

[JsonProperty("browser_download_url")]
public Uri? Download { get; set; }

[JsonProperty("updated_at")]
public DateTime? Updated { get; set; }

public GithubReleaseAsset(string name, Uri download, DateTime? updated)
{
Name = name;
Download = download;
Updated = updated;
}
[JsonProperty("uploader")]
public GithubUser? Uploader { get; set; }
}
}
9 changes: 8 additions & 1 deletion Netkan/Sources/Github/GithubRepo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,13 @@ public class GithubUser
public string? Login { get; set; }

[JsonProperty("type")]
public string? Type { get; set; }
public GithubUserType? Type { get; set; } = GithubUserType.User;
}

public enum GithubUserType
{
User,
Organization,
Bot,
}
}
47 changes: 32 additions & 15 deletions Netkan/Transformers/GithubTransformer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,27 @@ public IEnumerable<Metadata> Transform(Metadata metadata, TransformOptions? opts
releases = releases.Take(opts.Releases.Value);
}
bool returnedAny = false;
foreach (GithubRelease rel in releases)
foreach (var rel in releases)
{
if (ghRef.VersionFromAsset != null && rel.Assets != null)
if (ghRef.UseSourceArchive && rel.Tag != null)
{
returnedAny = true;
yield return TransformOne(metadata, metadata.Json(), ghRef, ghRepo, rel,
new GithubReleaseAsset()
{
Name = rel.Tag.ToString(),
Download = rel.SourceArchive,
Updated = rel.PublishedAt,
Uploader = rel.Author,
},
rel.Tag.ToString());
}
else if (ghRef.VersionFromAsset != null && rel.Assets != null)
{
Log.DebugFormat("Found version_from_asset regex, inflating all assets");
foreach (var asset in rel.Assets)
{
var match = ghRef.VersionFromAsset.Match(asset.Name);
var match = ghRef.VersionFromAsset.Match(asset.Name ?? "");
if (!match.Success)
{
continue;
Expand All @@ -92,13 +105,15 @@ public IEnumerable<Metadata> Transform(Metadata metadata, TransformOptions? opts
}
else if (rel.Assets != null && rel.Tag != null)
{
if (rel.Assets.Count > 1)
var assets = rel.Assets.Where(ghRef.FilterMatches).ToArray();
if (assets.Length > 1)
{
Log.WarnFormat("Multiple assets found for {0} {1} without `version_from_asset`",
metadata.Identifier, rel.Tag);
}
returnedAny = true;
yield return TransformOne(metadata, metadata.Json(), ghRef, ghRepo, rel, rel.Assets.First(), rel.Tag.ToString());
yield return TransformOne(metadata, metadata.Json(), ghRef, ghRepo, rel,
assets.First(), rel.Tag.ToString());
}
}
if (!returnedAny)
Expand Down Expand Up @@ -159,7 +174,10 @@ private Metadata TransformOne(Metadata metadata,
json.SafeAdd("version", version);
json.SafeAdd("author", () => GetAuthors(ghRepo, ghRelease));
json.Remove("$kref");
json.SafeAdd("download", ghAsset.Download.ToString());
if (ghAsset.Download is Uri url)
{
json.SafeAdd("download", url.ToString());
}
if (ghRef.UseSourceArchive)
{
// https://docs.github.com/en/rest/repos/contents#download-a-repository-archive-zip
Expand Down Expand Up @@ -241,17 +259,16 @@ public static void SetRepoResources(GithubRepo repo, JObject resources)
: _api.GetRepo(new GithubRef($"#/ckan/github/{r.ParentRepo.FullName}",
false)))
.Reverse()
.SelectMany(r => r.Owner?.Type switch
.Select(r => r.Owner)
.Append(release.Author)
.OfType<GithubUser>()
.SelectMany(u => u.Type switch
{
userType => Enumerable.Repeat(r.Owner.Login, 1),
orgType => _api.getOrgMembers(r.Owner)
.Select(u => u.Login),
_ => Enumerable.Empty<string>()
GithubUserType.User => Enumerable.Repeat(u.Login, 1),
GithubUserType.Organization => _api.getOrgMembers(u)
.Select(u => u.Login),
GithubUserType.Bot or _ => Enumerable.Empty<string>(),
})
.Append(release.Author)
.ToJValueOrJArray();

private const string userType = "User";
private const string orgType = "Organization";
}
}
Loading