Skip to content

Commit

Permalink
🐛 Add missing sponsors as contributors
Browse files Browse the repository at this point in the history
  • Loading branch information
ebullient committed Jun 15, 2024
1 parent d90608d commit 4a885b2
Show file tree
Hide file tree
Showing 20 changed files with 538 additions and 113 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,15 @@
* The WebHook provides an id (read by GHType), GraphQL doesn't.
*/
public class DataActor extends DataCommonType {

static final String ACTOR_FIELDS_MIN = """
login
url
""";
static final String ACTOR_FIELDS = ACTOR_FIELDS_MIN + """
avatarUrl
""";

public final String login;
public final String url;
public final String avatarUrl;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,26 +12,18 @@
@TemplateData
public class DataCommonObject extends DataCommonType {

static final String ACTOR_FIELDS_MIN = """
login
url
""";
static final String ACTOR_FIELDS = ACTOR_FIELDS_MIN + """
avatarUrl
""";

static final String COMMON_OBJECT_MIN = """
id
author {
""" + ACTOR_FIELDS_MIN + """
""" + DataActor.ACTOR_FIELDS_MIN + """
}
url
""";

static final String COMMON_OBJECT_FIELDS = """
id
author {
""" + ACTOR_FIELDS + """
""" + DataActor.ACTOR_FIELDS + """
}
body
createdAt
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
public class DataLabel extends DataCommonType {

static final String LABEL_FIELDS = """
id
name
id
name
""";
static final String FIRST_10_LABELS = """
labels(first: 10) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public class DataReaction {

static final String REACTION_FIELDS = """
user {
""" + DataCommonObject.ACTOR_FIELDS_MIN + """
""" + DataActor.ACTOR_FIELDS_MIN + """
}
content
createdAt
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package org.commonhaus.automation.github.context;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import jakarta.json.JsonArray;
import jakarta.json.JsonObject;

import io.quarkus.logging.Log;
import io.smallrye.graphql.client.Response;

public class DataSponsorship extends DataCommonType {

public final boolean isActive;
public final Date createdAt;
public final DataActor sponsorable;
public final DataActor sponsorEntity;
public final DataTier tier;

DataSponsorship(JsonObject object) {
super(object);

// common with webhook
this.createdAt = JsonAttribute.createdAt.dateFrom(object);
this.sponsorable = JsonAttribute.sponsorable.actorFrom(object);
this.sponsorEntity = JsonAttribute.sponsorEntity.actorFrom(object);
this.tier = JsonAttribute.tier.tierFrom(object);

// graphql only
this.isActive = JsonAttribute.isActive.booleanFromOrFalse(object);
}

public String sponsorLogin() {
return sponsorEntity.login;
}

@Override
public String toString() {
return "DataSponsorship [isActive=" + isActive + ", sponsorable=" + sponsorable + ", sponsorEntity="
+ sponsorEntity + "]";
}

public static List<DataSponsorship> queryRecentSponsors(QueryContext qc, String login) {
if (qc.hasErrors()) {
Log.debugf("[%s] queryRecentSponsors for sponsorable %s; skipping modify (errors)", qc.getLogId(), login);
return null;
}
Log.debugf("[%s] queryRecentSponsors for sponsorable %s", qc.getLogId(), login);

Map<String, Object> variables = new HashMap<>();
variables.put("login", login);
Response response = qc.execQuerySync("""
query($login: String!) {
organization(login: $login) {
sponsorshipsAsMaintainer(first: 50, activeOnly: false, orderBy: {field: CREATED_AT, direction: DESC}) {
totalCount
nodes {
isActive
isOneTimePayment
isActive
isOneTimePayment
sponsorEntity {
... on User {
login
}
... on Organization {
login
}
}
}
pageInfo {
hasNextPage
endCursor
}
}
}
}
""", variables);
if (qc.hasErrors() || response == null) {
return List.of();
}

JsonObject organization = JsonAttribute.organization.jsonObjectFrom(response.getData());
JsonObject sponsorshipsAsMaintainer = JsonAttribute.sponsorshipsAsMaintainer.jsonObjectFrom(organization);
JsonArray nodes = JsonAttribute.nodes.jsonArrayFrom(sponsorshipsAsMaintainer);
if (nodes == null) {
return List.of();
}
return nodes.stream()
.map(JsonObject.class::cast)
.map(DataSponsorship::new)
.toList();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package org.commonhaus.automation.github.context;

import java.util.Date;

import jakarta.json.JsonObject;

public class DataTier extends DataCommonType {

static final String TIER_FIELDS = """
id
name
monthlyPriceInCents
monthlyPriceInDollars
isOneTime
isCustomAmount
""";

public final Date createdAt;
public final Integer monthlyPriceInCents;
public final Integer monthlyPriceInDollars;
public final String name;
public final boolean isOneTime;
public final boolean isCustomAmount;

DataTier(JsonObject object) {
super(object);
this.createdAt = JsonAttribute.createdAt.dateFrom(object);
this.monthlyPriceInCents = JsonAttribute.monthlyPriceInCents.integerFrom(object);
this.monthlyPriceInDollars = JsonAttribute.monthlyPriceInDollars.integerFrom(object);
this.name = JsonAttribute.name.stringFrom(object);
this.isOneTime = JsonAttribute.isOneTime.booleanFromOrFalse(object);
this.isCustomAmount = JsonAttribute.isCustomAmount.booleanFromOrFalse(object);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ public enum JsonAttribute {
company,
content,
createIssue,
createLabel,
createdAt("created_at"),
databaseId,
discussion,
Expand All @@ -78,13 +79,19 @@ public enum JsonAttribute {
hasNextPage,
id,
installation,
isActive,
isCustomAmount("is_custom_amount"),
isOneTime("is_one_time"),
issue,
issueComment,
label,
labelable,
labels,
lastEditedAt,
latestReviews,
login,
monthlyPriceInCents("monthly_price_in_cents"),
monthlyPriceInDollars("monthly_price_in_dollars"),
name,
node,
node_id,
Expand All @@ -102,8 +109,12 @@ public enum JsonAttribute {
repository,
reviewDecision,
search,
sponsorEntity("sponsor"),
sponsorable,
sponsorshipsAsMaintainer,
state,
submittedAt("submitted_at"),
tier,
title,
updateDiscussionComment,
updateIssue,
Expand All @@ -113,8 +124,6 @@ public enum JsonAttribute {
url("html_url"),
user,
viewer,
lastEditedAt,
createLabel,
;

/** Bridge between JSON-B parsed types and Jackson-created GH* types */
Expand Down Expand Up @@ -330,6 +339,14 @@ public List<DataLabel> labelsFrom(JsonObject object) {
.toList();
}

public DataTier tierFrom(JsonObject object) {
if (object == null) {
return null;
}
JsonObject field = jsonObjectFrom(object);
return field == null ? null : new DataTier(field);
}

/** Bridge to GH* type usually parsed using Jackson; may be incomplete */
public GHRepository repositoryFrom(JsonObject object) {
String value = stringFrom(object);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -690,12 +690,6 @@ public boolean isTeamMember(GHUser user, String teamFullName) {
return members != null && members.contains(user);
}

public boolean isCollaborator(GHUser user, String repoName) {
Set<String> collaborators = collaborators(repoName);
Log.debugf("%s members: %s", repoName, collaborators);
return collaborators != null && collaborators.contains(user.getLogin());
}

public TeamList getTeamList(String teamFullName) {
Set<GHUser> members = teamMembers(teamFullName);
TeamList teamList = new TeamList(teamFullName, members);
Expand Down Expand Up @@ -735,6 +729,27 @@ public Set<GHUser> teamMembers(String teamFullName) {
return members;
}

public void addTeamMember(GHUser user, String teamFullName) {
if (isDryRun()) {
Log.debugf("[%s] addTeamMember would add %s to %s", getLogId(), user.getLogin(), teamFullName);
return;
}
// this will trigger membership change events, which will come back around to update the cache.
TEAM_MEMBERS.invalidate(teamFullName);

String orgName = toOrganizationName(teamFullName);
String relativeName = toRelativeName(orgName, teamFullName);
GHOrganization org = getOrganization(orgName);
execGitHubSync((gh, dryRun) -> {
GHTeam ghTeam = org.getTeamByName(relativeName);
ghTeam.add(user);
return null;
});
if (hasErrors()) {
clearNotFound();
}
}

public Set<String> collaborators(String repoFullName) {
Set<String> collaborators = COLLABORATORS.get(repoFullName);
if (collaborators == null) {
Expand All @@ -748,30 +763,29 @@ public Set<String> collaborators(String repoFullName) {
clearNotFound();
return null;
}
Log.debugf("%s members: %s", repoFullName, collaborators);
COLLABORATORS.put(repoFullName, collaborators);
}
return collaborators;
}

public void addTeamMember(GHUser user, String teamFullName) {
public void addCollaborators(GHRepository repo, List<GHUser> user) {
if (isDryRun()) {
Log.debugf("[%s] addTeamMember would add %s to %s", getLogId(), user.getLogin(), teamFullName);
Log.debugf("[%s] addCollaborators would add %s to %s",
getLogId(),
user.stream().map(GHUser::getLogin).toList(),
repo.getFullName());
return;
}
// this will trigger membership change events, which will come back around to update
// the cache.
String orgName = toOrganizationName(teamFullName);
String relativeName = toRelativeName(orgName, teamFullName);
GHOrganization org = getOrganization(orgName);
execGitHubSync((gh, dryRun) -> {
GHTeam ghTeam = org.getTeamByName(relativeName);
ghTeam.add(user);
repo.addCollaborators(user);
return null;
});
if (hasErrors()) {
clearNotFound();
}
TEAM_MEMBERS.invalidate(teamFullName);
}

public boolean isCollaborator(GHUser user, String repoName) {
Set<String> collaborators = collaborators(repoName);
return collaborators != null && collaborators.contains(user.getLogin());
}

public String[] getErrorAddresses() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,6 @@ public Throwable connectionError() {
}

public SecurityIdentity identity() {
return identity();
return identity;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.commonhaus.automation.admin.config;

import io.quarkus.runtime.annotations.RegisterForReflection;

@RegisterForReflection
public record SponsorsConfig(
String sponsorable,
String repository,
Boolean dryRun) {
public Boolean dryRun() {
return dryRun != null && dryRun;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public static TeamManagementConfig getGroupManagementConfig(AdminConfigFile repo
return repoConfigFile.groupManagement();
}

public SponsorsConfig sponsors;
public final List<TeamSourceConfig> sources = new ArrayList<>();

TeamManagementConfig() {
Expand Down Expand Up @@ -84,5 +85,8 @@ public void setAccess(InstallationAccess access) {
});
}
});
if (sponsors != null && sponsors.repository() != null) {
access.addWrite(sponsors.repository());
}
}
}
Loading

0 comments on commit 4a885b2

Please sign in to comment.