Skip to content

Commit

Permalink
Add "last updated" information to community tab.
Browse files Browse the repository at this point in the history
  • Loading branch information
holly-cummins committed Nov 3, 2023
1 parent 9a0ad17 commit 4affb79
Show file tree
Hide file tree
Showing 7 changed files with 91 additions and 32 deletions.
5 changes: 4 additions & 1 deletion plugins/github-enricher/gatsby-node.js
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,9 @@ const fetchGitHubInfo = async (scmUrl, groupId, artifactId, labels) => {

// scmInfo.extensionPathInRepo may be undefined, but these methods will cope with that
scmInfo.sponsors = await findSponsor(coords.owner, project, scmInfo.extensionPathInRepo)
scmInfo.contributors = await getContributors(coords.owner, project, scmInfo.extensionPathInRepo)
const { contributors, lastUpdated } = await getContributors(coords.owner, project, scmInfo.extensionPathInRepo) ?? {}
scmInfo.contributors = contributors
scmInfo.lastUpdated = lastUpdated

scmInfo.owner = coords.owner

Expand Down Expand Up @@ -447,6 +449,7 @@ exports.createSchemaCustomization = ({ actions }) => {
companies: [String]
extensionYamlUrl: String
issues: String
lastUpdated: String
contributors: [ContributorInfo]
sponsors: [String]
socialImage: File @link(by: "url")
Expand Down
15 changes: 15 additions & 0 deletions plugins/github-enricher/gatsby-node.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
const { onCreateNode, onPreBootstrap, onPluginInit } = require("./gatsby-node")
const { createRemoteFileNode } = require("gatsby-source-filesystem")
const { queryGraphQl, getRawFileContents, queryRest } = require("./github-helper")
const { getContributors } = require("./sponsorFinder")

jest.mock("gatsby-source-filesystem")
jest.mock("./github-helper")
jest.mock("./sponsorFinder")

const contentDigest = "some content digest"
const createNode = jest.fn()
Expand Down Expand Up @@ -122,6 +124,7 @@ describe("the github data handler", () => {

beforeAll(async () => {
queryGraphQl.mockResolvedValue(response)
getContributors.mockResolvedValue({ contributors: [{ name: "someone" }], lastUpdated: Date.now() })
await onPreBootstrap({ cache, actions: {} })
})

Expand Down Expand Up @@ -209,6 +212,18 @@ describe("the github data handler", () => {
)
})

it("fills in last updated information", async () => {
expect(createNode).toHaveBeenCalledWith(
expect.objectContaining({ lastUpdated: expect.anything() })
)
})

it("fills in contributor information", async () => {
expect(createNode).toHaveBeenCalledWith(
expect.objectContaining({ contributors: expect.arrayContaining([expect.anything()]) })
)
})

it("does not populate a label", async () => {
expect(createNode).not.toHaveBeenCalledWith(
expect.objectContaining({ labels: expect.anything() })
Expand Down
33 changes: 17 additions & 16 deletions plugins/github-enricher/sponsorFinder.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,17 +103,17 @@ const getUserContributionsNoCache = async (org, project, inPath) => {
name
company
url
}
}
}
}
}
}
}
}
}
}
}
}`
}
}
}
}
}
}
}
}
}`

const body = await queryGraphQl(query)

Expand All @@ -136,17 +136,17 @@ const getUserContributionsNoCache = async (org, project, inPath) => {
return acc
}, []))

return collatedHistory
return { collatedHistory, lastUpdated: Date.now() }
}
}

}

const findSponsor = async (org, project, path) => {
// Cache the github response and aggregation, but not the calculation of sponsors, since we may change the algorithm for it
const collatedHistory = await getUserContributions(org, project, path)
const { collatedHistory } = await getUserContributions(org, project, path) ?? {}
// We don't want to persist the sponsor calculations across builds; we could cache it locally but it's probably not worth it
if (collatedHistory) {
// We don't want to persist the sponsor calculations across builds; we could cache it locally but it's probably not worth it
return findSponsorFromContributorList(collatedHistory)
}
}
Expand All @@ -156,11 +156,12 @@ const notBot = (user) => {
}

const getContributors = async (org, project, path) => {
const collatedHistory = await getUserContributions(org, project, path)
return collatedHistory?.map(user => {
const { collatedHistory, lastUpdated } = await getUserContributions(org, project, path) ?? {}
const contributors = collatedHistory?.map(user => {
const { name, login, contributions, url } = user
return { name: name || login, login, contributions, url }
}).filter(notBot)
return { contributors, lastUpdated }
}

const findSponsorFromContributorList = async (userContributions) => {
Expand Down Expand Up @@ -297,7 +298,7 @@ const saveSponsorCache = async () => {
await companyCache.persist()
console.log("Persisted", companyCache.size(), "cached companies.")
await repoContributorCache.persist()
console.log("Persisted contributor information for", repoContributorCache.size(), "cached repositories.")
console.log("Persisted contributor information for", repoContributorCache.size(), "cached repositories and paths within those repositories.")
}

module.exports = {
Expand Down
14 changes: 12 additions & 2 deletions plugins/github-enricher/sponsorFinder.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -477,13 +477,23 @@ describe("the github sponsor finder", () => {
setMinimumContributionCount(1)
const contributors = await getContributors("someorg", "someproject")
expect(queryGraphQl).toHaveBeenCalled()
expect(contributors).toHaveLength(3)
expect(contributors[0]).toStrictEqual({
expect(contributors.contributors).toHaveLength(3)
expect(contributors.contributors[0]).toStrictEqual({
"name": "Doctor Fluffy",
login: "someonebouncy",
contributions: 5,
url: "http://profile"
})
})
})

it("returns last updated information", async () => {
const contributors = await getContributors("someorg", "someproject")

expect(contributors).toHaveProperty("lastUpdated")

const now = Date.now()
expect(contributors.lastUpdated / now).toBeCloseTo(1)

})
})
37 changes: 24 additions & 13 deletions src/templates/extension-detail.js
Original file line number Diff line number Diff line change
Expand Up @@ -248,19 +248,29 @@ const ExtensionDetailTemplate = ({

{metadata?.sourceControl?.contributors && metadata?.sourceControl?.contributors.length > 0 && (
<TabPanel>
<DocumentationSection>
<DocumentationHeading>Recent Contributors</DocumentationHeading>

{!extensionRootUrl && (
<p>Commits to this extension's repository in the past six months (including merge commits).</p>)}
{extensionRootUrl && (
<p>Commits to <a href={extensionRootUrl}>this extension's source code</a> in the past six months
(including merge commits).</p>)}

<ChartHolder>
<ContributionsChart contributors={metadata.sourceControl.contributors} />
</ChartHolder>
</DocumentationSection>
<DocumentationHeading>Recent Contributors</DocumentationHeading>

{!extensionRootUrl && (
<p>Commits to this extension's repository in the past six months (including merge commits).</p>)}
{extensionRootUrl && (
<p>Commits to <a href={extensionRootUrl}>this extension's source code</a> in the past six months
(including merge commits).</p>)}

<ChartHolder>
<ContributionsChart contributors={metadata.sourceControl.contributors} />
</ChartHolder>

{metadata?.sourceControl?.lastUpdated && (
<p><i>Commit statistics last
updated {new Date(+metadata?.sourceControl?.lastUpdated).toLocaleDateString("en-us", {
weekday: "long",
year: "numeric",
month: "short",
day: "numeric",
hour: "numeric",
minute: "numeric"
})}.</i></p>
)}
</TabPanel>)
}
</Tabs>
Expand Down Expand Up @@ -477,6 +487,7 @@ export const pageQuery = graphql`
issues
issuesUrl
sponsors
lastUpdated
contributors {
name
contributions
Expand Down
12 changes: 12 additions & 0 deletions src/templates/extension-detail.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ describe("extension detail page", () => {
project: "jproject",
issues: 839,
sponsors: ["Automatically Calculated Sponsor"],
lastUpdated: "1698924315702",
contributors: [{ name: "Alice", contributions: 6 }, { name: "Bob", contributions: 2 }],
ownerImage: {
childImageSharp: {
Expand Down Expand Up @@ -197,6 +198,17 @@ describe("extension detail page", () => {
expect(screen.getByText("Recent Contributors")).toBeTruthy()
})

it("has last updated information on the community tab", async () => {
const tab = screen.getAllByText("Community")[1] // get the last element, which should be second
await user.click(tab)
const year = new Date().getFullYear()
const lastUpdated = screen.getByText(/last updated/i)
expect(lastUpdated).toBeTruthy()

expect(lastUpdated.innerHTML).toMatch(" " + year)

})

// With the resizable container, we can't see inside the chart at all, sadly
xit("renders a committers chart", async () => {
// The committers chart is an svg, not an image, but we can find it by title
Expand Down
7 changes: 7 additions & 0 deletions test-integration/detail-page.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,11 @@ describe("an extension details page", () => {
page.waitForXPath(`//*[text()="Issues"]`)
).resolves.toBeTruthy()
})

it("should show a community tab", async () => {
await expect(
page.waitForXPath(`//*[text()="Community"]`)
).resolves.toBeTruthy()
})

})

0 comments on commit 4affb79

Please sign in to comment.