From 20be8d311c0e15cc43b91c9ebf5437610f98ba7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Soko=C5=82owski?= Date: Mon, 22 Jul 2024 19:14:42 +0200 Subject: [PATCH] x MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jakub SokoĊ‚owski --- README.md | 16 ++++++++-------- src/builds.js | 2 +- src/schema.js | 11 ++++++----- src/template.js | 14 +++++++------- test/comments.js | 44 ++++++++++++++++++++++---------------------- test/sample.js | 6 +++++- test/schema.js | 31 ++++++++++++++++++++++++++----- 7 files changed, 75 insertions(+), 49 deletions(-) diff --git a/README.md b/README.md index 73e9cdb..237cf3a 100644 --- a/README.md +++ b/README.md @@ -8,14 +8,14 @@ The problem this solves is posting comments in a PR from multiple builds without --- ### Jenkins Builds -| :grey_question: | Commit | :hash: | Finished (UTC) | Duration | Platform | Result | -|-|-|-|-|-|-|-| -| :x: | a088572b | [#3](https://example.org) | 2018-12-21 12:13:18 | ~12 min | `android` | [:page_facing_up:`log`](https://example.org) | -| :heavy_check_mark: | a088572b | [#3](https://example.org) | 2018-12-21 12:13:53 | ~12 min | `ios` | [:package:`api`](https://example.org) | -| :heavy_check_mark: | a088572b | [#3](https://example.org) | 2018-12-21 12:13:34 | ~12 min | `android` | [:package:`apk`](https://example.org) [:calling:](https://chart.apis.google.com/chart?cht=qr&chs=400x400&chld=L%7C%0A0&chl=https%3A%2F%2Fexample.org) | -| :heavy_check_mark: | a088572b | [#3](https://example.org) | 2018-12-21 12:14:44 | ~12 min | `windows` | [:package:`exe`](https://example.org) | -| :interrobang: | a088572b | [#3](https://example.org) | 2018-12-21 12:15:37 | ~13 min | `macos` | [:page_facing_up:`log`](https://example.org) | -| :heavy_multiplication_x: | a088572b | [#3](https://example.org) | 2018-12-21 12:16:40 | ~12 min | `linux` | [:package:`pkg`](https://unknown.example.org/path/package) | +| :grey_question: | Commit | :hash: | Finished (UTC) | Duration | Platform | Arch | Result | +|-|-|-|-|-|-|-|-| +| :x: | a088572b | [#3](https://example.org) | 2018-12-21 12:13:18 | ~12 min | `android` | `universal` | [:page_facing_up:`log`](https://example.org) | +| :heavy_check_mark: | a088572b | [#3](https://example.org) | 2018-12-21 12:13:53 | ~12 min | `ios` | `arm64` | [:package:`api`](https://example.org) | +| :heavy_check_mark: | a088572b | [#3](https://example.org) | 2018-12-21 12:13:34 | ~12 min | `android` | `i386` | [:package:`apk`](https://example.org) [:calling:](https://chart.apis.google.com/chart?cht=qr&chs=400x400&chld=L%7C%0A0&chl=https%3A%2F%2Fexample.org) | +| :heavy_check_mark: | a088572b | [#3](https://example.org) | 2018-12-21 12:14:44 | ~12 min | `windows` | `x86_64` | [:package:`exe`](https://example.org) | +| :interrobang: | a088572b | [#3](https://example.org) | 2018-12-21 12:15:37 | ~13 min | `macos` | `aarch64` | [:page_facing_up:`log`](https://example.org) | +| :heavy_multiplication_x: | a088572b | [#3](https://example.org) | 2018-12-21 12:16:40 | ~12 min | `linux` | `x86_64` | [:package:`pkg`](https://unknown.example.org/path/package) | --- # API diff --git a/src/builds.js b/src/builds.js index 543f58d..ff90a82 100644 --- a/src/builds.js +++ b/src/builds.js @@ -71,7 +71,7 @@ class Builds { } async addBuild ({repo, pr, build}) { - log.info(`Storing build for ${repo}/PR-${pr}: #${build.id} for ${build.platform}`) + log.info(`Storing build for ${repo}/PR-${pr}: #${build.id} for ${build.platform}/${build.arch}`) return await this.builds.insert({repo, pr, ...build}) } diff --git a/src/schema.js b/src/schema.js index 1264ec2..c613c36 100644 --- a/src/schema.js +++ b/src/schema.js @@ -1,13 +1,14 @@ const Joi = require('joi') const schema = Joi.object().keys({ - id: Joi.alternatives().try(Joi.number().positive(), Joi.string()).required(), - commit: Joi.string().regex(/^[a-zA-Z0-9]{6,40}$/).required(), - success: Joi.boolean().required(), + id: Joi.alternatives().try(Joi.number().positive(), Joi.string()).required(), + commit: Joi.string().regex(/^[a-zA-Z0-9]{6,40}$/).required(), + success: Joi.boolean().required(), platform: Joi.string().max(20).required(), + arch: Joi.string().max(20).regex(/^[a-zA-Z0-9_]/).optional().default('unknown'), duration: Joi.string().max(20).required(), - url: Joi.string().uri().required(), - pkg_url: Joi.string().uri().allow(null), + url: Joi.string().uri().required(), + pkg_url: Joi.string().uri().allow(null), }) module.exports = schema diff --git a/src/template.js b/src/template.js index 0fc93e7..c50ab8a 100644 --- a/src/template.js +++ b/src/template.js @@ -11,11 +11,11 @@ const main = ` {{> buildsTable visible }} ` const buildsTable = ` -| :grey_question: | Commit | :hash: | Finished (UTC) | Duration | Platform | Result | -|-|-|-|-|-|-|-| +| :grey_question: | Commit | :hash: | Finished (UTC) | Duration | Platform | Arch | Result | +|-|-|-|-|-|-|-|-| {{#each this}} {{#commitChanged ../this @index}} -| | | | | | | | +| | | | | | | | | {{/commitChanged}} {{> buildRow }} {{/each}} @@ -23,15 +23,15 @@ const buildsTable = ` const buildRow = ` {{#if this.success }} {{#if this.pkg_url }} -| :heavy_check_mark: | {{ this.commit }} | [{{ this.id }}]({{ this.url }}) | {{formatDate this.meta.created }} | {{ shortenDuration this.duration }} | \`{{ this.platform }}\` | [{{ fileIcon this.pkg_url }}\`{{ fileExt this.pkg_url }}\`]({{ this.pkg_url }}) {{ genQRCodeUrl this.pkg_url }}| +| :heavy_check_mark: | {{ this.commit }} | [{{ this.id }}]({{ this.url }}) | {{formatDate this.meta.created }} | {{ shortenDuration this.duration }} | \`{{ this.platform }}\` | \`{{ this.arch }}\` | [{{ fileIcon this.pkg_url }}\`{{ fileExt this.pkg_url }}\`]({{ this.pkg_url }}) {{ genQRCodeUrl this.pkg_url }}| {{else}} -| :interrobang: | {{ this.commit }} | [{{ this.id }}]({{ this.url }}) | {{formatDate this.meta.created }} | {{ shortenDuration this.duration }} | \`{{ this.platform }}\` | [{{ fileIcon "log" }}\`log\`]({{ this.url }}consoleText) | +| :interrobang: | {{ this.commit }} | [{{ this.id }}]({{ this.url }}) | {{formatDate this.meta.created }} | {{ shortenDuration this.duration }} | \`{{ this.platform }}\` | \`{{ this.arch }}\` | [{{ fileIcon "log" }}\`log\`]({{ this.url }}consoleText) | {{/if}} {{else}} {{#if this.pkg_url }} -| :heavy_multiplication_x: | {{ this.commit }} | [{{ this.id }}]({{ this.url }}) | {{formatDate this.meta.created }} | {{ shortenDuration this.duration }} | \`{{ this.platform }}\` | [{{ fileIcon this.pkg_url }}\`{{ fileExt this.pkg_url }}\`]({{ this.pkg_url }}) {{ genQRCodeUrl this.pkg_url }}| +| :heavy_multiplication_x: | {{ this.commit }} | [{{ this.id }}]({{ this.url }}) | {{formatDate this.meta.created }} | {{ shortenDuration this.duration }} | \`{{ this.platform }}\` | \`{{ this.arch }}\` | [{{ fileIcon this.pkg_url }}\`{{ fileExt this.pkg_url }}\`]({{ this.pkg_url }}) {{ genQRCodeUrl this.pkg_url }}| {{else}} -| :x: | {{ this.commit }} | [{{ this.id }}]({{ this.url }}) | {{formatDate this.meta.created }} | {{ shortenDuration this.duration }} | \`{{ this.platform }}\` | [{{ fileIcon "log" }}\`log\`]({{ this.url }}consoleText) | +| :x: | {{ this.commit }} | [{{ this.id }}]({{ this.url }}) | {{formatDate this.meta.created }} | {{ shortenDuration this.duration }} | \`{{ this.platform }}\` | \`{{ this.arch }}\` | [{{ fileIcon "log" }}\`log\`]({{ this.url }}consoleText) | {{/if}} {{/if}} `.trim() diff --git a/test/comments.js b/test/comments.js index 73a4aa8..258dcd6 100644 --- a/test/comments.js +++ b/test/comments.js @@ -10,10 +10,10 @@ let comments, client, builds /* expected comment based on given builds */ const COMMENT = ` ### Jenkins Builds -| :grey_question: | Commit | :hash: | Finished (UTC) | Duration | Platform | Result | -|-|-|-|-|-|-|-| -| :heavy_check_mark: | COMMIT-0 | [ID-1](URL-1/) | 2018-12-20 08:25:56 | DURATION-1 | \`PLATFORM-1\` | [:robot:\`apk\`](https://example.org/StatusIm-123-456-abc-pr.apk) [:calling:](https://chart.apis.google.com/chart?cht=qr&chs=400x400&chld=L%7C%0A1&chl=https%3A%2F%2Fexample.org%2FStatusIm-123-456-abc-pr.apk)| -| :heavy_check_mark: | COMMIT-0 | [ID-2](URL-2/) | 2018-12-20 08:26:53 | DURATION-2 | \`PLATFORM-2\` | [:cd:\`exe\`](https://example.org/StatusIm-123-456-abc-pr.exe) | +| :grey_question: | Commit | :hash: | Finished (UTC) | Duration | Platform | Arch | Result | +|-|-|-|-|-|-|-|-| +| :heavy_check_mark: | COMMIT-0 | [ID-1](URL-1/) | 2018-12-20 08:25:56 | DURATION-1 | \`macos\` | \`x86_64\` | [:robot:\`apk\`](https://example.org/StatusIm-123-456-abc-pr.apk) [:calling:](https://chart.apis.google.com/chart?cht=qr&chs=400x400&chld=L%7C%0A1&chl=https%3A%2F%2Fexample.org%2FStatusIm-123-456-abc-pr.apk)| +| :heavy_check_mark: | COMMIT-0 | [ID-2](URL-2/) | 2018-12-20 08:26:53 | DURATION-2 | \`windows\` | \`aarch64\` | [:cd:\`exe\`](https://example.org/StatusIm-123-456-abc-pr.exe) | ` const COMMENT_FOLDED = ` @@ -21,26 +21,26 @@ const COMMENT_FOLDED = `
Click to see older builds (7) -| :grey_question: | Commit | :hash: | Finished (UTC) | Duration | Platform | Result | -|-|-|-|-|-|-|-| -| :heavy_check_mark: | COMMIT-0 | [ID-1](URL-1/) | 2018-12-20 08:25:56 | DURATION-1 | \`PLATFORM-1\` | [:robot:\`apk\`](https://example.org/StatusIm-123-456-abc-pr.apk) [:calling:](https://chart.apis.google.com/chart?cht=qr&chs=400x400&chld=L%7C%0A1&chl=https%3A%2F%2Fexample.org%2FStatusIm-123-456-abc-pr.apk)| -| :heavy_check_mark: | COMMIT-0 | [ID-2](URL-2/) | 2018-12-20 08:26:53 | DURATION-2 | \`PLATFORM-2\` | [:cd:\`exe\`](https://example.org/StatusIm-123-456-abc-pr.exe) | -| :x: | COMMIT-0 | [ID-3](URL-3/) | 2018-12-20 08:27:50 | DURATION-3 | \`PLATFORM-3\` | [:page_facing_up:\`log\`](URL-3/consoleText) | -| | | | | | | | -| :heavy_check_mark: | COMMIT-1 | [ID-4](URL-4/) | 2018-12-20 08:28:47 | DURATION-4 | \`PLATFORM-4\` | [:package:\`App\`](https://example.org/StatusIm-123-456-abc-pr.AppImage) | -| :heavy_check_mark: | COMMIT-1 | [ID-5](URL-5/) | 2018-12-20 08:29:43 | DURATION-5 | \`PLATFORM-5\` | [:iphone:\`ipa\`](https://i.diawi.com/ABCDxyz1) [:calling:](https://chart.apis.google.com/chart?cht=qr&chs=400x400&chld=L%7C%0A1&chl=https%3A%2F%2Fi.diawi.com%2FABCDxyz1)| -| :heavy_multiplication_x: | COMMIT-1 | [ID-6](URL-6/) | 2018-12-20 08:30:40 | DURATION-6 | \`PLATFORM-6\` | [:package:\`pkg\`](https://unknown.example.org/path/package) | -| :interrobang: | COMMIT-1 | [ID-7](URL-7/) | 2018-12-20 08:31:37 | DURATION-7 | \`PLATFORM-7\` | [:page_facing_up:\`log\`](URL-7/consoleText) | +| :grey_question: | Commit | :hash: | Finished (UTC) | Duration | Platform | Arch | Result | +|-|-|-|-|-|-|-|-| +| :heavy_check_mark: | COMMIT-0 | [ID-1](URL-1/) | 2018-12-20 08:25:56 | DURATION-1 | \`macos\` | \`x86_64\` | [:robot:\`apk\`](https://example.org/StatusIm-123-456-abc-pr.apk) [:calling:](https://chart.apis.google.com/chart?cht=qr&chs=400x400&chld=L%7C%0A1&chl=https%3A%2F%2Fexample.org%2FStatusIm-123-456-abc-pr.apk)| +| :heavy_check_mark: | COMMIT-0 | [ID-2](URL-2/) | 2018-12-20 08:26:53 | DURATION-2 | \`windows\` | \`aarch64\` | [:cd:\`exe\`](https://example.org/StatusIm-123-456-abc-pr.exe) | +| :x: | COMMIT-0 | [ID-3](URL-3/) | 2018-12-20 08:27:50 | DURATION-3 | \`android\` | \`arm64\` | [:page_facing_up:\`log\`](URL-3/consoleText) | +| | | | | | | | | +| :heavy_check_mark: | COMMIT-1 | [ID-4](URL-4/) | 2018-12-20 08:28:47 | DURATION-4 | \`ios\` | \`i386\` | [:package:\`App\`](https://example.org/StatusIm-123-456-abc-pr.AppImage) | +| :heavy_check_mark: | COMMIT-1 | [ID-5](URL-5/) | 2018-12-20 08:29:43 | DURATION-5 | \`linux\` | \`x86_64\` | [:iphone:\`ipa\`](https://i.diawi.com/ABCDxyz1) [:calling:](https://chart.apis.google.com/chart?cht=qr&chs=400x400&chld=L%7C%0A1&chl=https%3A%2F%2Fi.diawi.com%2FABCDxyz1)| +| :heavy_multiplication_x: | COMMIT-1 | [ID-6](URL-6/) | 2018-12-20 08:30:40 | DURATION-6 | \`macos\` | \`aarch64\` | [:package:\`pkg\`](https://unknown.example.org/path/package) | +| :interrobang: | COMMIT-1 | [ID-7](URL-7/) | 2018-12-20 08:31:37 | DURATION-7 | \`windows\` | \`arm64\` | [:page_facing_up:\`log\`](URL-7/consoleText) |
-| :grey_question: | Commit | :hash: | Finished (UTC) | Duration | Platform | Result | -|-|-|-|-|-|-|-| -| :heavy_check_mark: | COMMIT-2 | [ID-8](URL-8/) | 2018-12-20 08:32:34 | DURATION-8 | \`PLATFORM-8\` | [:package:\`tgz\`](https://example.org/StatusIm-123-456-abc-pr.tar.gz) | -| :heavy_multiplication_x: | COMMIT-2 | [ID-9](URL-9/) | 2018-12-20 08:33:31 | DURATION-9 | \`PLATFORM-9\` | [:robot:\`apk\`](https://example.org/StatusIm-123-456-abc-pr.apk) [:calling:](https://chart.apis.google.com/chart?cht=qr&chs=400x400&chld=L%7C%0A1&chl=https%3A%2F%2Fexample.org%2FStatusIm-123-456-abc-pr.apk)| -| :heavy_check_mark: | COMMIT-2 | [ID-10](URL-10/) | 2018-12-20 08:34:27 | DURATION-10 | \`PLATFORM-10\` | [:cd:\`exe\`](https://example.org/StatusIm-123-456-abc-pr.exe) | -| :interrobang: | COMMIT-2 | [ID-11](URL-11/) | 2018-12-20 08:35:24 | DURATION-11 | \`PLATFORM-11\` | [:page_facing_up:\`log\`](URL-11/consoleText) | -| | | | | | | | -| :heavy_multiplication_x: | COMMIT-3 | [ID-12](URL-12/) | 2018-12-20 08:36:21 | DURATION-12 | \`PLATFORM-12\` | [:package:\`App\`](https://example.org/StatusIm-123-456-abc-pr.AppImage) | +| :grey_question: | Commit | :hash: | Finished (UTC) | Duration | Platform | Arch | Result | +|-|-|-|-|-|-|-|-| +| :heavy_check_mark: | COMMIT-2 | [ID-8](URL-8/) | 2018-12-20 08:32:34 | DURATION-8 | \`android\` | \`i386\` | [:package:\`tgz\`](https://example.org/StatusIm-123-456-abc-pr.tar.gz) | +| :heavy_multiplication_x: | COMMIT-2 | [ID-9](URL-9/) | 2018-12-20 08:33:31 | DURATION-9 | \`ios\` | \`x86_64\` | [:robot:\`apk\`](https://example.org/StatusIm-123-456-abc-pr.apk) [:calling:](https://chart.apis.google.com/chart?cht=qr&chs=400x400&chld=L%7C%0A1&chl=https%3A%2F%2Fexample.org%2FStatusIm-123-456-abc-pr.apk)| +| :heavy_check_mark: | COMMIT-2 | [ID-10](URL-10/) | 2018-12-20 08:34:27 | DURATION-10 | \`linux\` | \`aarch64\` | [:cd:\`exe\`](https://example.org/StatusIm-123-456-abc-pr.exe) | +| :interrobang: | COMMIT-2 | [ID-11](URL-11/) | 2018-12-20 08:35:24 | DURATION-11 | \`macos\` | \`arm64\` | [:page_facing_up:\`log\`](URL-11/consoleText) | +| | | | | | | | | +| :heavy_multiplication_x: | COMMIT-3 | [ID-12](URL-12/) | 2018-12-20 08:36:21 | DURATION-12 | \`windows\` | \`i386\` | [:package:\`App\`](https://example.org/StatusIm-123-456-abc-pr.AppImage) | ` describe('Comments', () => { diff --git a/test/sample.js b/test/sample.js index b12321a..ffbb64a 100644 --- a/test/sample.js +++ b/test/sample.js @@ -20,11 +20,15 @@ const BUILD = { pkg_url: 'https://example.com/some/pkg/StatusIm-123-456-789.apk', } +const archs = [ 'i386', 'x86_64', 'aarch64', 'arm64' ] +const platforms = [ 'linux', 'macos', 'windows', 'android', 'ios' ] + const getBuild = (idx) => ({ id: `ID-${idx}`, commit: `COMMIT-${Math.floor(idx/4)}`, success: (idx%3) ? true : false, - platform: `PLATFORM-${idx}`, + platform: platforms[idx%platforms.length], + arch: archs[idx%archs.length], duration: `DURATION-${idx} 12 sec`, url: `URL-${idx}/`, pkg_url: PKG_URLS[(idx-1)%PKG_URLS.length], diff --git a/test/schema.js b/test/schema.js index e2d2a04..b08456b 100644 --- a/test/schema.js +++ b/test/schema.js @@ -16,13 +16,13 @@ describe('Schema', () => { describe('id', () => { it('can be a string', () => { let rval = schema.validate(build) - expect(rval.value).to.eql(build) + expect(rval.value).to.eql({ ...build, arch: 'unknown' }) }) it('can be a number', () => { build.id = 123 let rval = schema.validate(build) - expect(rval.value).to.eql(build) + expect(rval.value).to.eql({ ...build, arch: 'unknown' }) }) it('can\'t be null', () => { @@ -37,7 +37,7 @@ describe('Schema', () => { describe('commit', () => { it('has to be a commit', () => { let rval = schema.validate(build) - expect(rval.value).to.eql(build) + expect(rval.value).to.eql({ ...build, arch: 'unknown' }) }) it('can\'t be a null', () => { @@ -57,16 +57,37 @@ describe('Schema', () => { }) }) + describe('arch', () => { + it('defaults to "unknown"', () => { + let rval = schema.validate(build) + expect(rval.value).to.eql({ ...build, arch: 'unknown' }) + }) + + it('can be x86_64', () => { + build.arch = 'x86_64' + let rval = schema.validate(build) + expect(rval.value).to.eql(build) + }) + + it('can\'t have special chars', () => { + build.arch = '-+=' + let rval = schema.validate(build) + expect(rval.error.message).to.eq( + '"arch" with value "-+=" fails to match the required pattern: /^[a-zA-Z0-9_]/' + ) + }) + }) + describe('pkg_url', () => { it('has to be a URL', () => { let rval = schema.validate(build) - expect(rval.value).to.eql(build) + expect(rval.value).to.eql({ ...build, arch: 'unknown' }) }) it('can be a null', () => { build.pkg_url = null let rval = schema.validate(build) - expect(rval.value).to.eql(build) + expect(rval.value).to.eql({ ...build, arch: 'unknown' }) }) it('can\'t be a number', () => {