-
Notifications
You must be signed in to change notification settings - Fork 105
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
Create a tool to find inactive reviewers and approvers for a repository. #359
Comments
/cc |
@dhiller Thank you! |
Now I can see some use cases here:
So I've come up with a GraphQL query as an example: query UserActivityInRepo($username: String!) {
issuesCreated: search(first: 5, type: ISSUE, query: "repo:kubevirt/community author:alonakaplan is:issue created:>=2023-11-27") {
issueCount
nodes {
... on Issue {
number
title
repository {
name
}
author {
login
}
createdAt
}
}
}
issuesCommented: search(first: 5, type: ISSUE, query: "repo:kubevirt/community is:issue commenter:alonakaplan created:>=2023-11-27") {
issueCount
nodes {
... on Issue {
number
title
repository {
name
}
author {
login
}
comments(first:100, orderBy: {field: UPDATED_AT, direction: ASC} ) {
nodes {
author {
login
}
createdAt
}
}
}
}
}
prsCreated: search(type: ISSUE, first: 5, query: "repo:kubevirt/community author:alonakaplan is:pr created:>=2023-11-27") {
issueCount
nodes {
... on PullRequest {
number
title
author {
login
}
createdAt
}
}
}
prsReviewed: search(type: ISSUE, first: 5, query: "repo:repo:kubevirt/community reviewer:alonakaplan is:pr updated:>=2023-11-27") {
issueCount
nodes {
... on PullRequest {
title
number
createdAt
reviews(author: $username) {
totalCount
}
}
}
}
prsCommented: search(last: 100, type: ISSUE, query: "repo:kubevirt/community is:pr updated:>=2023-11-27 commenter:alonakaplan") {
issueCount
nodes {
... on PullRequest {
number
title
repository {
name
}
author {
login
}
comments(first:100, orderBy: {field: UPDATED_AT, direction: ASC} ) {
nodes {
author {
login
}
createdAt
}
}
}
}
}
commitsByUser: repository(owner: "kubevirt", name: "community") {
defaultBranchRef {
target {
... on Commit {
history(author: {emails: "[email protected]"}, since: "2023-11-27T00:00:00Z") {
totalCount
nodes {
commitUrl
associatedPullRequests(first: 5) {
nodes {
number
title
}
}
}
}
}
}
}
}
} This yields {
"data": {
"issuesCreated": {
"issueCount": 0,
"nodes": []
},
"issuesCommented": {
"issueCount": 0,
"nodes": []
},
"prsCreated": {
"issueCount": 2,
"nodes": [
{
"number": 281,
"title": "network binding plugin: DownwardAPI for device info",
"author": {
"login": "AlonaKaplan"
},
"createdAt": "2024-03-31T11:32:13Z"
},
{
"number": 271,
"title": "sig-network charter",
"author": {
"login": "AlonaKaplan"
},
"createdAt": "2024-03-10T12:03:56Z"
}
]
},
"prsReviewed": {
"issueCount": 0,
"nodes": []
},
"prsCommented": {
"issueCount": 9,
"nodes": [
{
"number": 281,
"title": "network binding plugin: DownwardAPI for device info",
"repository": {
"name": "community"
},
"author": {
"login": "AlonaKaplan"
},
"comments": {
"nodes": [
{
"author": {
"login": "kubevirt-bot"
},
"createdAt": "2024-03-31T11:32:15Z"
},
{
"author": {
"login": "EdDev"
},
"createdAt": "2024-04-01T19:36:15Z"
},
{
"author": {
"login": "EdDev"
},
"createdAt": "2024-04-03T08:45:46Z"
},
{
"author": {
"login": "alaypatel07"
},
"createdAt": "2024-04-05T17:57:46Z"
},
{
"author": {
"login": "AlonaKaplan"
},
"createdAt": "2024-04-07T18:36:44Z"
},
{
"author": {
"login": "alaypatel07"
},
"createdAt": "2024-04-07T18:53:39Z"
},
{
"author": {
"login": "AlonaKaplan"
},
"createdAt": "2024-04-07T20:24:30Z"
},
{
"author": {
"login": "EdDev"
},
"createdAt": "2024-04-08T03:36:40Z"
},
{
"author": {
"login": "EdDev"
},
"createdAt": "2024-04-08T06:26:58Z"
},
{
"author": {
"login": "alaypatel07"
},
"createdAt": "2024-04-08T12:43:01Z"
},
{
"author": {
"login": "AlonaKaplan"
},
"createdAt": "2024-04-11T07:22:09Z"
},
{
"author": {
"login": "alaypatel07"
},
"createdAt": "2024-04-11T13:04:48Z"
},
{
"author": {
"login": "alaypatel07"
},
"createdAt": "2024-04-16T14:09:58Z"
},
{
"author": {
"login": "AlonaKaplan"
},
"createdAt": "2024-04-17T10:41:42Z"
},
{
"author": {
"login": "kubevirt-bot"
},
"createdAt": "2024-04-17T10:41:50Z"
}
]
}
},
{
"number": 280,
"title": "design-proposal: Network binding plugin",
"repository": {
"name": "community"
},
"author": {
"login": "EdDev"
},
"comments": {
"nodes": [
{
"author": {
"login": "EdDev"
},
"createdAt": "2024-03-28T08:51:49Z"
},
{
"author": {
"login": "AlonaKaplan"
},
"createdAt": "2024-03-28T12:46:09Z"
},
{
"author": {
"login": "kubevirt-bot"
},
"createdAt": "2024-03-28T12:46:13Z"
},
{
"author": {
"login": "ormergi"
},
"createdAt": "2024-03-28T16:45:06Z"
}
]
}
},
{
"number": 279,
"title": "ipam: integrate w/ k8s multi-network defacto standard persistent IPs",
"repository": {
"name": "community"
},
"author": {
"login": "maiqueb"
},
"comments": {
"nodes": [
{
"author": {
"login": "maiqueb"
},
"createdAt": "2024-03-19T12:53:16Z"
},
{
"author": {
"login": "EdDev"
},
"createdAt": "2024-03-20T05:32:10Z"
},
{
"author": {
"login": "maiqueb"
},
"createdAt": "2024-03-22T11:31:34Z"
},
{
"author": {
"login": "AlonaKaplan"
},
"createdAt": "2024-04-18T10:23:06Z"
},
{
"author": {
"login": "kubevirt-bot"
},
"createdAt": "2024-04-18T10:23:12Z"
},
{
"author": {
"login": "oshoval"
},
"createdAt": "2024-04-18T10:32:13Z"
}
]
}
},
{
"number": 271,
"title": "sig-network charter",
"repository": {
"name": "community"
},
"author": {
"login": "AlonaKaplan"
},
"comments": {
"nodes": [
{
"author": {
"login": "kubevirt-bot"
},
"createdAt": "2024-03-10T12:03:58Z"
},
{
"author": {
"login": "fabiand"
},
"createdAt": "2024-04-10T08:07:17Z"
},
{
"author": {
"login": "fabiand"
},
"createdAt": "2024-04-10T08:12:57Z"
},
{
"author": {
"login": "AlonaKaplan"
},
"createdAt": "2024-04-10T09:36:13Z"
},
{
"author": {
"login": "AlonaKaplan"
},
"createdAt": "2024-04-10T09:36:57Z"
},
{
"author": {
"login": "kubevirt-bot"
},
"createdAt": "2024-04-10T09:37:04Z"
}
]
}
},
{
"number": 249,
"title": "Passt network interface API and implementation replacement",
"repository": {
"name": "community"
},
"author": {
"login": "ormergi"
},
"comments": {
"nodes": [
{
"author": {
"login": "kubevirt-bot"
},
"createdAt": "2023-11-09T17:18:47Z"
},
{
"author": {
"login": "ormergi"
},
"createdAt": "2023-11-09T17:36:01Z"
},
{
"author": {
"login": "AlonaKaplan"
},
"createdAt": "2023-11-22T09:59:05Z"
},
{
"author": {
"login": "ormergi"
},
"createdAt": "2023-11-26T12:37:52Z"
},
{
"author": {
"login": "AlonaKaplan"
},
"createdAt": "2023-11-28T08:09:50Z"
},
{
"author": {
"login": "kubevirt-bot"
},
"createdAt": "2023-11-28T08:09:58Z"
}
]
}
},
{
"number": 242,
"title": "Proposal for VM rollout strategy",
"repository": {
"name": "community"
},
"author": {
"login": "vladikr"
},
"comments": {
"nodes": [
{
"author": {
"login": "vladikr"
},
"createdAt": "2023-08-31T16:50:20Z"
},
{
"author": {
"login": "iholder101"
},
"createdAt": "2023-09-14T11:33:32Z"
},
{
"author": {
"login": "fabiand"
},
"createdAt": "2023-09-21T10:33:37Z"
},
{
"author": {
"login": "vladikr"
},
"createdAt": "2023-11-30T03:36:52Z"
},
{
"author": {
"login": "acardace"
},
"createdAt": "2023-12-08T11:52:53Z"
},
{
"author": {
"login": "enp0s3"
},
"createdAt": "2023-12-08T13:51:07Z"
},
{
"author": {
"login": "enp0s3"
},
"createdAt": "2023-12-08T14:12:44Z"
},
{
"author": {
"login": "fabiand"
},
"createdAt": "2023-12-08T15:01:29Z"
},
{
"author": {
"login": "fabiand"
},
"createdAt": "2023-12-08T15:02:56Z"
},
{
"author": {
"login": "acardace"
},
"createdAt": "2023-12-11T08:37:30Z"
},
{
"author": {
"login": "dankenigsberg"
},
"createdAt": "2023-12-20T15:26:07Z"
},
{
"author": {
"login": "jean-edouard"
},
"createdAt": "2023-12-20T20:27:35Z"
},
{
"author": {
"login": "xpivarc"
},
"createdAt": "2023-12-20T20:38:36Z"
},
{
"author": {
"login": "fabiand"
},
"createdAt": "2023-12-21T07:49:05Z"
},
{
"author": {
"login": "fabiand"
},
"createdAt": "2023-12-22T08:35:06Z"
},
{
"author": {
"login": "fabiand"
},
"createdAt": "2023-12-22T10:44:58Z"
},
{
"author": {
"login": "fabiand"
},
"createdAt": "2023-12-22T10:45:04Z"
},
{
"author": {
"login": "kubevirt-bot"
},
"createdAt": "2023-12-22T10:45:04Z"
}
]
}
},
{
"number": 228,
"title": "vDPA interface design proposal",
"repository": {
"name": "community"
},
"author": {
"login": "makoto126"
},
"comments": {
"nodes": [
{
"author": {
"login": "kubevirt-bot"
},
"createdAt": "2023-07-19T09:43:56Z"
},
{
"author": {
"login": "kubevirt-bot"
},
"createdAt": "2023-10-31T10:24:28Z"
},
{
"author": {
"login": "kubevirt-bot"
},
"createdAt": "2023-11-30T10:31:24Z"
},
{
"author": {
"login": "kubevirt-bot"
},
"createdAt": "2023-12-30T10:41:49Z"
},
{
"author": {
"login": "kubevirt-bot"
},
"createdAt": "2023-12-30T10:41:52Z"
},
{
"author": {
"login": "aburdenthehand"
},
"createdAt": "2024-01-03T14:37:15Z"
},
{
"author": {
"login": "makoto126"
},
"createdAt": "2024-01-04T01:58:59Z"
},
{
"author": {
"login": "aburdenthehand"
},
"createdAt": "2024-01-04T09:57:09Z"
},
{
"author": {
"login": "kubevirt-bot"
},
"createdAt": "2024-01-04T09:57:13Z"
},
{
"author": {
"login": "kubevirt-bot"
},
"createdAt": "2024-01-04T09:57:17Z"
},
{
"author": {
"login": "aburdenthehand"
},
"createdAt": "2024-02-21T15:09:01Z"
},
{
"author": {
"login": "AlonaKaplan"
},
"createdAt": "2024-03-13T14:23:05Z"
},
{
"author": {
"login": "lmilleri"
},
"createdAt": "2024-03-14T11:33:08Z"
},
{
"author": {
"login": "EdDev"
},
"createdAt": "2024-04-02T17:50:30Z"
},
{
"author": {
"login": "kubevirt-bot"
},
"createdAt": "2024-07-01T18:20:53Z"
},
{
"author": {
"login": "kubevirt-bot"
},
"createdAt": "2024-07-31T19:04:47Z"
},
{
"author": {
"login": "kubevirt-bot"
},
"createdAt": "2024-08-30T20:02:52Z"
},
{
"author": {
"login": "kubevirt-bot"
},
"createdAt": "2024-08-30T20:02:56Z"
}
]
}
},
{
"number": 220,
"title": "design-proposals: Network interface resources requests",
"repository": {
"name": "community"
},
"author": {
"login": "EdDev"
},
"comments": {
"nodes": [
{
"author": {
"login": "kubevirt-bot"
},
"createdAt": "2023-05-07T10:02:15Z"
},
{
"author": {
"login": "EdDev"
},
"createdAt": "2023-05-07T10:05:02Z"
},
{
"author": {
"login": "maiqueb"
},
"createdAt": "2023-05-08T15:04:25Z"
},
{
"author": {
"login": "andreabolognani"
},
"createdAt": "2023-05-08T15:11:33Z"
},
{
"author": {
"login": "EdDev"
},
"createdAt": "2023-05-09T07:22:23Z"
},
{
"author": {
"login": "EdDev"
},
"createdAt": "2023-05-11T10:10:17Z"
},
{
"author": {
"login": "EdDev"
},
"createdAt": "2023-05-11T10:18:57Z"
},
{
"author": {
"login": "EdDev"
},
"createdAt": "2023-05-16T12:15:14Z"
},
{
"author": {
"login": "EdDev"
},
"createdAt": "2023-05-17T05:28:33Z"
},
{
"author": {
"login": "EdDev"
},
"createdAt": "2023-05-18T17:49:30Z"
},
{
"author": {
"login": "AlonaKaplan"
},
"createdAt": "2023-05-18T18:05:54Z"
},
{
"author": {
"login": "kubevirt-bot"
},
"createdAt": "2023-08-17T08:06:59Z"
},
{
"author": {
"login": "kubevirt-bot"
},
"createdAt": "2023-09-16T08:17:13Z"
},
{
"author": {
"login": "kubevirt-bot"
},
"createdAt": "2023-10-16T09:12:11Z"
},
{
"author": {
"login": "kubevirt-bot"
},
"createdAt": "2023-10-16T09:12:14Z"
},
{
"author": {
"login": "aburdenthehand"
},
"createdAt": "2023-11-30T13:11:09Z"
}
]
}
},
{
"number": 182,
"title": "proposal: Live migration for bridged pod network",
"repository": {
"name": "community"
},
"author": {
"login": "kvaps"
},
"comments": {
"nodes": [
{
"author": {
"login": "kvaps"
},
"createdAt": "2022-07-06T13:53:53Z"
},
{
"author": {
"login": "maiqueb"
},
"createdAt": "2022-07-06T13:55:25Z"
},
{
"author": {
"login": "AlonaKaplan"
},
"createdAt": "2022-07-27T10:54:56Z"
},
{
"author": {
"login": "maiqueb"
},
"createdAt": "2022-07-27T11:01:00Z"
},
{
"author": {
"login": "kvaps"
},
"createdAt": "2022-07-27T11:37:09Z"
},
{
"author": {
"login": "AlonaKaplan"
},
"createdAt": "2022-07-27T12:23:47Z"
},
{
"author": {
"login": "AlonaKaplan"
},
"createdAt": "2022-07-27T13:32:27Z"
},
{
"author": {
"login": "kvaps"
},
"createdAt": "2022-07-27T13:45:55Z"
},
{
"author": {
"login": "EdDev"
},
"createdAt": "2022-07-27T13:59:15Z"
},
{
"author": {
"login": "rthallisey"
},
"createdAt": "2022-08-17T14:05:38Z"
},
{
"author": {
"login": "kvaps"
},
"createdAt": "2022-08-18T16:36:55Z"
},
{
"author": {
"login": "kvaps"
},
"createdAt": "2022-09-14T09:36:24Z"
},
{
"author": {
"login": "davidvossel"
},
"createdAt": "2022-09-16T20:55:32Z"
},
{
"author": {
"login": "maiqueb"
},
"createdAt": "2022-09-19T09:45:10Z"
},
{
"author": {
"login": "AlonaKaplan"
},
"createdAt": "2022-09-19T11:58:19Z"
},
{
"author": {
"login": "kubevirt-bot"
},
"createdAt": "2022-12-18T12:55:33Z"
},
{
"author": {
"login": "rthallisey"
},
"createdAt": "2022-12-19T11:53:39Z"
},
{
"author": {
"login": "kvaps"
},
"createdAt": "2022-12-27T16:57:56Z"
},
{
"author": {
"login": "kubevirt-bot"
},
"createdAt": "2023-03-02T08:49:28Z"
},
{
"author": {
"login": "xagent003"
},
"createdAt": "2023-03-15T19:23:38Z"
},
{
"author": {
"login": "xuzhenglun"
},
"createdAt": "2023-04-18T08:31:00Z"
},
{
"author": {
"login": "kubevirt-bot"
},
"createdAt": "2023-07-17T09:29:02Z"
},
{
"author": {
"login": "kvaps"
},
"createdAt": "2023-07-26T12:00:53Z"
},
{
"author": {
"login": "kvaps"
},
"createdAt": "2023-07-26T12:01:53Z"
},
{
"author": {
"login": "kubevirt-bot"
},
"createdAt": "2023-10-24T12:21:24Z"
},
{
"author": {
"login": "rthallisey"
},
"createdAt": "2023-10-24T12:50:15Z"
},
{
"author": {
"login": "kubevirt-bot"
},
"createdAt": "2024-01-22T13:07:00Z"
},
{
"author": {
"login": "aburdenthehand"
},
"createdAt": "2024-02-21T11:17:34Z"
},
{
"author": {
"login": "kvaps"
},
"createdAt": "2024-02-21T11:27:49Z"
},
{
"author": {
"login": "kvaps"
},
"createdAt": "2024-03-13T15:13:14Z"
},
{
"author": {
"login": "kubevirt-bot"
},
"createdAt": "2024-03-13T15:13:18Z"
}
]
}
}
]
},
"commitsByUser": {
"defaultBranchRef": {
"target": {
"history": {
"totalCount": 2,
"nodes": [
{
"commitUrl": "https://github.com/kubevirt/community/commit/b35512b93a1195673d1155b774c6c36599079c47",
"associatedPullRequests": {
"nodes": [
{
"number": 281,
"title": "network binding plugin: DownwardAPI for device info"
}
]
}
},
{
"commitUrl": "https://github.com/kubevirt/community/commit/a125f5fb6437698ad3647764a59082ae579f0d0e",
"associatedPullRequests": {
"nodes": [
{
"number": 271,
"title": "sig-network charter"
}
]
}
}
]
}
}
}
}
}
} While there will be some iteration necessary, the information we need should all be there in one query - currently per user, but it seems we could query for all users at once. |
I've created a similar query for org activity, which will allow us to check inactive org members without relying on devstats (the latter process is manual since we need to export the data from the dashboard and there's no way to scrape it to my understanding) query UserActivityInOrg($username: String!) {
organization(login: "kubevirt") {
id
}
userContributionsInOrg: user(login: $username) {
contributionsCollection(organizationID: "O_kgDOAR1Znw", from: "2023-11-27T00:00:00Z") {
hasAnyContributions
totalCommitContributions
totalIssueContributions
totalPullRequestContributions
totalPullRequestReviewContributions
issueContributions(first: 1, orderBy: {direction: DESC}) {
totalCount
nodes {
issue {
url
}
occurredAt
}
}
pullRequestContributions(first: 1, orderBy: {direction: DESC}) {
totalCount
nodes {
pullRequest {
url
}
occurredAt
}
}
pullRequestReviewContributions(first: 1, orderBy: {direction: DESC}) {
totalCount
nodes {
pullRequestReview {
repository {
nameWithOwner
}
pullRequest {
url
}
createdAt
state
}
}
}
commitContributionsByRepository(maxRepositories: 10) {
contributions(first: 10, orderBy: {field: OCCURRED_AT, direction: DESC}) {
nodes {
repository {
nameWithOwner
}
user {
name
}
occurredAt
}
}
}
}
}
} which yields {
"data": {
"organization": {
"id": "MDEyOk9yZ2FuaXphdGlvbjE4NzAwNzAz"
},
"userContributionsInOrg": {
"contributionsCollection": {
"hasAnyContributions": true,
"totalCommitContributions": 41,
"totalIssueContributions": 0,
"totalPullRequestContributions": 17,
"totalPullRequestReviewContributions": 42,
"issueContributions": {
"totalCount": 0,
"nodes": []
},
"pullRequestContributions": {
"totalCount": 17,
"nodes": [
{
"pullRequest": {
"url": "https://github.com/kubevirt/kubevirt/pull/11796"
},
"occurredAt": "2024-04-25T14:12:43Z"
}
]
},
"pullRequestReviewContributions": {
"totalCount": 42,
"nodes": [
{
"pullRequestReview": {
"repository": {
"nameWithOwner": "kubevirt/kubevirt"
},
"pullRequest": {
"url": "https://github.com/kubevirt/kubevirt/pull/11410"
},
"createdAt": "2024-05-12T13:36:38Z",
"state": "COMMENTED"
}
}
]
},
"commitContributionsByRepository": [
{
"contributions": {
"nodes": [
{
"repository": {
"nameWithOwner": "kubevirt/kubevirt"
},
"user": {
"name": "Alona Paz"
},
"occurredAt": "2024-04-25T07:00:00Z"
},
{
"repository": {
"nameWithOwner": "kubevirt/kubevirt"
},
"user": {
"name": "Alona Paz"
},
"occurredAt": "2024-04-03T07:00:00Z"
},
{
"repository": {
"nameWithOwner": "kubevirt/kubevirt"
},
"user": {
"name": "Alona Paz"
},
"occurredAt": "2024-03-28T07:00:00Z"
},
{
"repository": {
"nameWithOwner": "kubevirt/kubevirt"
},
"user": {
"name": "Alona Paz"
},
"occurredAt": "2024-03-26T07:00:00Z"
},
{
"repository": {
"nameWithOwner": "kubevirt/kubevirt"
},
"user": {
"name": "Alona Paz"
},
"occurredAt": "2024-03-25T07:00:00Z"
},
{
"repository": {
"nameWithOwner": "kubevirt/kubevirt"
},
"user": {
"name": "Alona Paz"
},
"occurredAt": "2024-02-26T08:00:00Z"
},
{
"repository": {
"nameWithOwner": "kubevirt/kubevirt"
},
"user": {
"name": "Alona Paz"
},
"occurredAt": "2024-02-13T08:00:00Z"
},
{
"repository": {
"nameWithOwner": "kubevirt/kubevirt"
},
"user": {
"name": "Alona Paz"
},
"occurredAt": "2024-02-12T08:00:00Z"
},
{
"repository": {
"nameWithOwner": "kubevirt/kubevirt"
},
"user": {
"name": "Alona Paz"
},
"occurredAt": "2024-02-11T08:00:00Z"
},
{
"repository": {
"nameWithOwner": "kubevirt/kubevirt"
},
"user": {
"name": "Alona Paz"
},
"occurredAt": "2024-01-29T08:00:00Z"
}
]
}
},
{
"contributions": {
"nodes": [
{
"repository": {
"nameWithOwner": "kubevirt/community"
},
"user": {
"name": "Alona Paz"
},
"occurredAt": "2024-04-17T07:00:00Z"
},
{
"repository": {
"nameWithOwner": "kubevirt/community"
},
"user": {
"name": "Alona Paz"
},
"occurredAt": "2024-04-10T07:00:00Z"
}
]
}
},
{
"contributions": {
"nodes": [
{
"repository": {
"nameWithOwner": "kubevirt/user-guide"
},
"user": {
"name": "Alona Paz"
},
"occurredAt": "2024-02-13T08:00:00Z"
}
]
}
}
]
}
}
}
} |
The basic idea is to create a golang tool using GitHub GraphQL 1 which should yield better performance and be more maintainable, since the number of people with go skills is greater.
Running this with a target repository directory should yield a yaml file which can then be used as an input for other automation.
This idea is stemming from an original conversation in a PR changing OWNERS files, where it was asked for proof to support the action.
Originally posted by @vladikr in #329 (comment)
The text was updated successfully, but these errors were encountered: