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

Add ProjectsV2Item event payload #1502

Merged
merged 1 commit into from Aug 18, 2022
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
22 changes: 22 additions & 0 deletions src/main/java/org/kohsuke/github/GHEventPayload.java
Expand Up @@ -1630,4 +1630,26 @@ public Date getStarredAt() {
return GitHubClient.parseDate(starredAt);
}
}

/**
* A project v2 item was archived, converted, created, edited, restored, deleted, or reordered.
*
* @see <a href=
* "https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#projects_v2_item">star
* event</a>
*/
public static class ProjectsV2Item extends GHEventPayload {

private GHProjectsV2Item projectsV2Item;
private GHProjectsV2ItemChanges changes;

@SuppressFBWarnings(value = { "EI_EXPOSE_REP" }, justification = "Expected")
public GHProjectsV2Item getProjectsV2Item() {
return projectsV2Item;
}

public GHProjectsV2ItemChanges getChanges() {
return changes;
}
}
}
59 changes: 59 additions & 0 deletions src/main/java/org/kohsuke/github/GHProjectsV2Item.java
@@ -0,0 +1,59 @@
package org.kohsuke.github;

import org.kohsuke.github.internal.EnumUtils;

import java.io.IOException;
import java.net.URL;
import java.util.Date;

/**
* A Projects V2 item in the organization.
* <p>
* Projects V2 are not attached to a repository but to an organization, even if it is possible to create shortcuts at
* the repository level.
* <p>
* This event exposes the GraphQL object (more or less - the ids are handled differently for instance) directly. The new
* Projects V2 API is only available through GraphQL so for now you cannot execute any actions on this object.
*
* @author Guillaume Smet
* @see <a href=
* "https://docs.github.com/en/issues/planning-and-tracking-with-projects/automating-your-project/using-the-api-to-manage-projects">The
* GraphQL API for Projects V2</a>
*/
public class GHProjectsV2Item extends GHObject {

private String projectNodeId;
private String contentNodeId;
private String contentType;

private GHUser creator;
private String archivedAt;

public String getProjectNodeId() {
return projectNodeId;
}

public String getContentNodeId() {
return contentNodeId;
}

public ContentType getContentType() {
return EnumUtils.getEnumOrDefault(ContentType.class, contentType, ContentType.UNKNOWN);
}

public GHUser getCreator() throws IOException {
return root().intern(creator);
}

public Date getArchivedAt() {
return GitHubClient.parseDate(archivedAt);
}

public URL getHtmlUrl() {
throw new IllegalStateException(getClass().getName() + " does not offer a HTML URL.");
}

public enum ContentType {
ISSUE, DRAFTISSUE, PULLREQUEST, UNKNOWN;
}
}
80 changes: 80 additions & 0 deletions src/main/java/org/kohsuke/github/GHProjectsV2ItemChanges.java
@@ -0,0 +1,80 @@
package org.kohsuke.github;

import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import org.kohsuke.github.internal.EnumUtils;

import java.util.Date;

/**
* An object to track changes in projects_v2_item payloads.
* <p>
* Note that this is best effort only as nothing is documented in the GitHub documentation.
*/
@SuppressFBWarnings(value = { "UWF_UNWRITTEN_FIELD" }, justification = "JSON API")
public class GHProjectsV2ItemChanges {

private FieldValue fieldValue;

private FromToDate archivedAt;

private FromTo previousProjectsV2ItemNodeId;

public FieldValue getFieldValue() {
return fieldValue;
}

public FromToDate getArchivedAt() {
return archivedAt;
}

public FromTo getPreviousProjectsV2ItemNodeId() {
return previousProjectsV2ItemNodeId;
}

public static class FieldValue {

private String fieldNodeId;
private String fieldType;

public String getFieldNodeId() {
return fieldNodeId;
}

public FieldType getFieldType() {
return EnumUtils.getEnumOrDefault(FieldType.class, fieldType, FieldType.UNKNOWN);
}
}

public static class FromTo {

private String from;
private String to;

public String getFrom() {
return from;
}

public String getTo() {
return to;
}
}

public static class FromToDate {

private String from;
private String to;

public Date getFrom() {
return GitHubClient.parseDate(from);
}

public Date getTo() {
return GitHubClient.parseDate(to);
}
}

public enum FieldType {

TEXT, NUMBER, DATE, SINGLE_SELECT, ITERATION, UNKNOWN;
}
}
100 changes: 100 additions & 0 deletions src/test/java/org/kohsuke/github/GHEventPayloadTest.java
Expand Up @@ -4,6 +4,8 @@
import org.junit.Test;
import org.kohsuke.github.GHCheckRun.Conclusion;
import org.kohsuke.github.GHCheckRun.Status;
import org.kohsuke.github.GHProjectsV2Item.ContentType;
import org.kohsuke.github.GHProjectsV2ItemChanges.FieldType;

import java.io.IOException;
import java.text.SimpleDateFormat;
Expand Down Expand Up @@ -1152,4 +1154,102 @@ public void starred() throws Exception {
assertThat(starPayload.getSender().getLogin(), is("gsmet"));
assertThat(starPayload.getStarredAt().getTime(), is(1654017876000L));
}

@Test
public void projectsv2item_created() throws Exception {
final GHEventPayload.ProjectsV2Item projectsV2ItemPayload = GitHub.offline()
.parseEventPayload(payload.asReader(), GHEventPayload.ProjectsV2Item.class);

assertThat(projectsV2ItemPayload.getAction(), is("created"));

assertThat(projectsV2ItemPayload.getProjectsV2Item().getId(), is(8083254L));
assertThat(projectsV2ItemPayload.getProjectsV2Item().getNodeId(), is("PVTI_lADOBNft-M4AEjBWzgB7VzY"));
assertThat(projectsV2ItemPayload.getProjectsV2Item().getProjectNodeId(), is("PVT_kwDOBNft-M4AEjBW"));
assertThat(projectsV2ItemPayload.getProjectsV2Item().getContentNodeId(), is("I_kwDOFOkjw85Ozz26"));
assertThat(projectsV2ItemPayload.getProjectsV2Item().getContentType(), is(ContentType.ISSUE));
assertThat(projectsV2ItemPayload.getProjectsV2Item().getCreator().getLogin(), is("gsmet"));
assertThat(projectsV2ItemPayload.getProjectsV2Item().getCreator().getNodeId(), is("MDQ6VXNlcjEyNzk3NDk="));
assertThat(projectsV2ItemPayload.getProjectsV2Item().getCreatedAt().getTime(), is(1659532028000L));
assertThat(projectsV2ItemPayload.getProjectsV2Item().getUpdatedAt().getTime(), is(1659532028000L));
assertThat(projectsV2ItemPayload.getProjectsV2Item().getArchivedAt(), is(nullValue()));

assertThat(projectsV2ItemPayload.getOrganization().getLogin(), is("gsmet-bot-playground"));
assertThat(projectsV2ItemPayload.getOrganization().getId(), is(81260024L));
assertThat(projectsV2ItemPayload.getOrganization().getNodeId(), is("MDEyOk9yZ2FuaXphdGlvbjgxMjYwMDI0"));

assertThat(projectsV2ItemPayload.getSender().getLogin(), is("gsmet"));
assertThat(projectsV2ItemPayload.getSender().getId(), is(1279749L));
assertThat(projectsV2ItemPayload.getSender().getNodeId(), is("MDQ6VXNlcjEyNzk3NDk="));

assertThat(projectsV2ItemPayload.getInstallation().getId(), is(16779846L));
assertThat(projectsV2ItemPayload.getInstallation().getNodeId(),
is("MDIzOkludGVncmF0aW9uSW5zdGFsbGF0aW9uMTY3Nzk4NDY="));
}

@Test
public void projectsv2item_edited() throws Exception {
final GHEventPayload.ProjectsV2Item projectsV2ItemPayload = GitHub.offline()
.parseEventPayload(payload.asReader(), GHEventPayload.ProjectsV2Item.class);

assertThat(projectsV2ItemPayload.getAction(), is("edited"));

assertThat(projectsV2ItemPayload.getProjectsV2Item().getId(), is(8083254L));
assertThat(projectsV2ItemPayload.getProjectsV2Item().getCreatedAt().getTime(), is(1659532028000L));
assertThat(projectsV2ItemPayload.getProjectsV2Item().getUpdatedAt().getTime(), is(1659532033000L));
assertThat(projectsV2ItemPayload.getProjectsV2Item().getArchivedAt(), is(nullValue()));

assertThat(projectsV2ItemPayload.getChanges().getFieldValue().getFieldNodeId(),
is("PVTF_lADOBNft-M4AEjBWzgCnp5Q"));
assertThat(projectsV2ItemPayload.getChanges().getFieldValue().getFieldType(), is(FieldType.SINGLE_SELECT));
}

@Test
public void projectsv2item_archived() throws Exception {
final GHEventPayload.ProjectsV2Item projectsV2ItemPayload = GitHub.offline()
.parseEventPayload(payload.asReader(), GHEventPayload.ProjectsV2Item.class);

assertThat(projectsV2ItemPayload.getAction(), is("archived"));

assertThat(projectsV2ItemPayload.getProjectsV2Item().getId(), is(8083794L));
assertThat(projectsV2ItemPayload.getProjectsV2Item().getCreatedAt().getTime(), is(1659532431000L));
assertThat(projectsV2ItemPayload.getProjectsV2Item().getUpdatedAt().getTime(), is(1660086629000L));
assertThat(projectsV2ItemPayload.getProjectsV2Item().getArchivedAt().getTime(), is(1660086629000L));

assertThat(projectsV2ItemPayload.getChanges().getArchivedAt().getFrom(), is(nullValue()));
assertThat(projectsV2ItemPayload.getChanges().getArchivedAt().getTo().getTime(), is(1660086629000L));
}

@Test
public void projectsv2item_restored() throws Exception {
final GHEventPayload.ProjectsV2Item projectsV2ItemPayload = GitHub.offline()
.parseEventPayload(payload.asReader(), GHEventPayload.ProjectsV2Item.class);

assertThat(projectsV2ItemPayload.getAction(), is("restored"));

assertThat(projectsV2ItemPayload.getProjectsV2Item().getId(), is(8083254L));
assertThat(projectsV2ItemPayload.getProjectsV2Item().getCreatedAt().getTime(), is(1659532028000L));
assertThat(projectsV2ItemPayload.getProjectsV2Item().getUpdatedAt().getTime(), is(1659532419000L));
assertThat(projectsV2ItemPayload.getProjectsV2Item().getArchivedAt(), is(nullValue()));

assertThat(projectsV2ItemPayload.getChanges().getArchivedAt().getFrom().getTime(), is(1659532142000L));
assertThat(projectsV2ItemPayload.getChanges().getArchivedAt().getTo(), is(nullValue()));
}

@Test
public void projectsv2item_reordered() throws Exception {
final GHEventPayload.ProjectsV2Item projectsV2ItemPayload = GitHub.offline()
.parseEventPayload(payload.asReader(), GHEventPayload.ProjectsV2Item.class);

assertThat(projectsV2ItemPayload.getAction(), is("reordered"));

assertThat(projectsV2ItemPayload.getProjectsV2Item().getId(), is(8083794L));
assertThat(projectsV2ItemPayload.getProjectsV2Item().getCreatedAt().getTime(), is(1659532431000L));
assertThat(projectsV2ItemPayload.getProjectsV2Item().getUpdatedAt().getTime(), is(1659532439000L));
assertThat(projectsV2ItemPayload.getProjectsV2Item().getArchivedAt(), is(nullValue()));

assertThat(projectsV2ItemPayload.getChanges().getPreviousProjectsV2ItemNodeId().getFrom(),
is("PVTI_lADOBNft-M4AEjBWzgB7VzY"));
assertThat(projectsV2ItemPayload.getChanges().getPreviousProjectsV2ItemNodeId().getTo(),
is("PVTI_lADOBNft-M4AEjBWzgB7VzY"));
}
}
@@ -0,0 +1,77 @@
{
"action": "archived",
"projects_v2_item": {
"id": 8083794,
"node_id": "PVTI_lADOBNft-M4AEjBWzgB7WVI",
"project_node_id": "PVT_kwDOBNft-M4AEjBW",
"content_node_id": "I_kwDOFOkjw85OzN4w",
"content_type": "Issue",
"creator": {
"login": "gsmet",
"id": 1279749,
"node_id": "MDQ6VXNlcjEyNzk3NDk=",
"avatar_url": "https://avatars.githubusercontent.com/u/1279749?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/gsmet",
"html_url": "https://github.com/gsmet",
"followers_url": "https://api.github.com/users/gsmet/followers",
"following_url": "https://api.github.com/users/gsmet/following{/other_user}",
"gists_url": "https://api.github.com/users/gsmet/gists{/gist_id}",
"starred_url": "https://api.github.com/users/gsmet/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/gsmet/subscriptions",
"organizations_url": "https://api.github.com/users/gsmet/orgs",
"repos_url": "https://api.github.com/users/gsmet/repos",
"events_url": "https://api.github.com/users/gsmet/events{/privacy}",
"received_events_url": "https://api.github.com/users/gsmet/received_events",
"type": "User",
"site_admin": false
},
"created_at": "2022-08-03T13:13:51Z",
"updated_at": "2022-08-09T23:10:29Z",
"archived_at": "2022-08-09T23:10:29Z"
},
"changes": {
"archived_at": {
"from": null,
"to": "2022-08-10T01:10:29+02:00"
}
},
"organization": {
"login": "gsmet-bot-playground",
"id": 81260024,
"node_id": "MDEyOk9yZ2FuaXphdGlvbjgxMjYwMDI0",
"url": "https://api.github.com/orgs/gsmet-bot-playground",
"repos_url": "https://api.github.com/orgs/gsmet-bot-playground/repos",
"events_url": "https://api.github.com/orgs/gsmet-bot-playground/events",
"hooks_url": "https://api.github.com/orgs/gsmet-bot-playground/hooks",
"issues_url": "https://api.github.com/orgs/gsmet-bot-playground/issues",
"members_url": "https://api.github.com/orgs/gsmet-bot-playground/members{/member}",
"public_members_url": "https://api.github.com/orgs/gsmet-bot-playground/public_members{/member}",
"avatar_url": "https://avatars.githubusercontent.com/u/81260024?v=4",
"description": null
},
"sender": {
"login": "gsmet",
"id": 1279749,
"node_id": "MDQ6VXNlcjEyNzk3NDk=",
"avatar_url": "https://avatars.githubusercontent.com/u/1279749?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/gsmet",
"html_url": "https://github.com/gsmet",
"followers_url": "https://api.github.com/users/gsmet/followers",
"following_url": "https://api.github.com/users/gsmet/following{/other_user}",
"gists_url": "https://api.github.com/users/gsmet/gists{/gist_id}",
"starred_url": "https://api.github.com/users/gsmet/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/gsmet/subscriptions",
"organizations_url": "https://api.github.com/users/gsmet/orgs",
"repos_url": "https://api.github.com/users/gsmet/repos",
"events_url": "https://api.github.com/users/gsmet/events{/privacy}",
"received_events_url": "https://api.github.com/users/gsmet/received_events",
"type": "User",
"site_admin": false
},
"installation": {
"id": 16779846,
"node_id": "MDIzOkludGVncmF0aW9uSW5zdGFsbGF0aW9uMTY3Nzk4NDY="
}
}