add folding of builds when there are more than 3 commits

Signed-off-by: Jakub Sokołowski <jakub@status.im>
This commit is contained in:
Jakub Sokołowski 2019-01-15 22:56:56 +01:00
parent 080139a2df
commit 63d39fcb87
No known key found for this signature in database
GPG Key ID: 4EF064D0E6D63020
4 changed files with 88 additions and 12 deletions

View File

@ -2,8 +2,8 @@ const log = require('loglevel')
const Handlebars = require('handlebars') const Handlebars = require('handlebars')
const template = require('./template') const template = require('./template')
/* in theory the jenkins build comment should be the first one */ /* how many builds to show without folding */
const PER_PAGE = 100 const VIS_BUILDS = 3
const COMMENT_REGEX = /\#\#\# Jenkins Builds\n/ const COMMENT_REGEX = /\#\#\# Jenkins Builds\n/
/* loop helper compares commits of build and previous build */ /* loop helper compares commits of build and previous build */
@ -23,6 +23,21 @@ const dateHelper = (data) => {
) )
} }
/* adds archive attribute to builds to mark for folding in template */
const extractArchiveBuilds = (builds) => {
/* get unique commits */
const commits = [...new Set(builds.map(b=>b.commit))]
/* if there's not too many don't archive any */
if (commits.length < VIS_BUILDS) {
return {visible: builds, archived: []}
}
/* split builds into visible and archived */
const archivedCommits = commits.slice(0, -(VIS_BUILDS-1))
const archived = builds.filter(b => archivedCommits.includes(b.commit))
const visible = builds.slice(archived.length)
return {visible, archived}
}
class Comments { class Comments {
constructor(client, owner, repo, builds) { constructor(client, owner, repo, builds) {
this.gh = client this.gh = client
@ -33,8 +48,11 @@ class Comments {
Handlebars.registerHelper('date', dateHelper) Handlebars.registerHelper('date', dateHelper)
/* add helper for checking change in commit */ /* add helper for checking change in commit */
Handlebars.registerHelper('commitChanged', commitHelper) Handlebars.registerHelper('commitChanged', commitHelper)
/* add partis */
Object.keys(template.partials).forEach(k=>
Handlebars.registerPartial(k, template.partials[k])
)
/* setup templating for comments */ /* setup templating for comments */
Handlebars.registerPartial('build', template.build)
this.template = Handlebars.compile(template.main); this.template = Handlebars.compile(template.main);
} }
@ -43,7 +61,9 @@ class Comments {
if (builds.length == 0) { if (builds.length == 0) {
throw Error('No builds exist for this PR') throw Error('No builds exist for this PR')
} }
return this.template({builds}) /* split to be able to fold if there are too many builds */
const {visible, archived} = extractArchiveBuilds(builds)
return this.template({visible, archived})
} }
async postComment (pr) { async postComment (pr) {

View File

@ -1,19 +1,30 @@
const main = ` const main = `
### Jenkins Builds ### Jenkins Builds
{{#if archived.length }}
<details>
<summary>Click to see older builds</summary>
{{> buildsTable archived }}
</details>
{{/if}}
{{> buildsTable visible }}
`
const buildsTable = `
| :grey_question: | Commit | :hash: | Finished (UTC) | Duration | Platform | Result | | :grey_question: | Commit | :hash: | Finished (UTC) | Duration | Platform | Result |
|-|-|-|-|-|-|-| |-|-|-|-|-|-|-|
{{#each builds}} {{#each this}}
{{#commitChanged ../builds @index}} {{#commitChanged ../this @index}}
| | | | | | | | | | | | | | | |
{{/commitChanged}} {{/commitChanged}}
{{> build }} {{> buildRow }}
{{/each}} {{/each}}
` `.trim()
const build = ` const buildRow = `
{{#if this.success}} {{#if this.success}}
| :heavy_check_mark: | {{ this.commit }} | [{{ this.id }}]({{ this.url }}) | {{date this.meta.created }} | {{ this.duration }} | \`{{ this.platform }}\` | [:package: package]({{ this.pkg_url }}) | | :heavy_check_mark: | {{ this.commit }} | [{{ this.id }}]({{ this.url }}) | {{date this.meta.created }} | {{ this.duration }} | \`{{ this.platform }}\` | [:package: package]({{ this.pkg_url }}) |
{{else}} {{else}}
| :x: | {{ this.commit }} | [{{ this.id }}]({{ this.url }}) | {{date this.meta.created }} | {{ this.duration }} | \`{{ this.platform }}\` | [:page_facing_up: build log]({{ this.url }}consoleText) | | :x: | {{ this.commit }} | [{{ this.id }}]({{ this.url }}) | {{date this.meta.created }} | {{ this.duration }} | \`{{ this.platform }}\` | [:page_facing_up: build log]({{ this.url }}consoleText) |
{{/if}} {{/if}}
`.trim() `.trim()
module.exports = { main, build } module.exports = { main, partials: {buildRow, buildsTable} }

View File

@ -17,6 +17,25 @@ const COMMENT = `
| :x: | COMMIT-2 | [ID-2](URL-2) | 2018-12-20 08:45:28 | DURATION-2 | \`PLATFORM-2\` | [:page_facing_up: build log](URL-2consoleText) | | :x: | COMMIT-2 | [ID-2](URL-2) | 2018-12-20 08:45:28 | DURATION-2 | \`PLATFORM-2\` | [:page_facing_up: build log](URL-2consoleText) |
` `
const COMMENT_FOLDED = `
### Jenkins Builds
<details>
<summary>Click to see older builds</summary>
| :grey_question: | Commit | :hash: | Finished (UTC) | Duration | Platform | Result |
|-|-|-|-|-|-|-|
| :heavy_check_mark: | COMMIT-1 | [ID-1](URL-1) | 2018-12-20 08:26:33 | DURATION-1 | \`PLATFORM-1\` | [:package: package](PKG_URL-1) |
| | | | | | | |
| :x: | COMMIT-2 | [ID-2](URL-2) | 2018-12-20 08:45:28 | DURATION-2 | \`PLATFORM-2\` | [:page_facing_up: build log](URL-2consoleText) |
</details>
| :grey_question: | Commit | :hash: | Finished (UTC) | Duration | Platform | Result |
|-|-|-|-|-|-|-|
| :heavy_check_mark: | COMMIT-3 | [ID-3](URL-3) | 2018-12-20 08:26:32 | DURATION-3 | \`PLATFORM-3\` | [:package: package](PKG_URL-3) |
| | | | | | | |
| :x: | COMMIT-4 | [ID-4](URL-4) | 2018-12-20 08:45:23 | DURATION-4 | \`PLATFORM-4\` | [:page_facing_up: build log](URL-4consoleText) |
`
describe('Comments', () => { describe('Comments', () => {
beforeEach(() => { beforeEach(() => {
client = { client = {
@ -26,7 +45,7 @@ describe('Comments', () => {
}, },
} }
builds = sinon.createStubInstance(Builds, { builds = sinon.createStubInstance(Builds, {
getBuilds: sample.BUILDS, getBuilds: sample.BUILDS.slice(0, 2),
}) })
comments = new Comments(client, 'owner', 'repo', builds) comments = new Comments(client, 'owner', 'repo', builds)
}) })
@ -37,10 +56,16 @@ describe('Comments', () => {
expect(comments.renderComment('PR-ID')).rejectedWith('No builds exist for this PR') expect(comments.renderComment('PR-ID')).rejectedWith('No builds exist for this PR')
}) })
it('should render correctly', async () => { it('should render less than 3 comments fully', async () => {
let body = await comments.renderComment('PR-ID') let body = await comments.renderComment('PR-ID')
expect(body).to.eq(COMMENT) expect(body).to.eq(COMMENT)
}) })
it('should render more than 3 comments folded', async () => {
builds.getBuilds.returns(sample.BUILDS)
let body = await comments.renderComment('PR-ID')
expect(body).to.eq(COMMENT_FOLDED)
})
}) })
describe('postComment', () => { describe('postComment', () => {

View File

@ -30,6 +30,26 @@ const BUILDS = [
pkg_url: 'PKG_URL-2', pkg_url: 'PKG_URL-2',
meta: { created: 1545295528896 }, meta: { created: 1545295528896 },
}, },
{
id: 'ID-3',
commit: 'COMMIT-3',
success: true,
platform: 'PLATFORM-3',
duration: 'DURATION-3',
url: 'URL-3',
pkg_url: 'PKG_URL-3',
meta: { created: 1545294392930 },
},
{
id: 'ID-4',
commit: 'COMMIT-4',
success: false,
platform: 'PLATFORM-4',
duration: 'DURATION-4',
url: 'URL-4',
pkg_url: 'PKG_URL-4',
meta: { created: 1545295523333 },
},
] ]
const COMMENTS = [ const COMMENTS = [