From 4b1a4bb4846dfa5c7b245358b948fc6dd57891c0 Mon Sep 17 00:00:00 2001 From: Peter Evans <18365890+peter-evans@users.noreply.github.com> Date: Fri, 7 Apr 2023 09:16:46 +0900 Subject: [PATCH] feat: truncate short description exceeding the byte limit (#143) * feat: truncate short description exceeding the byte limit * fix tests --- __test__/readme-helper.unit.test.ts | 11 +----- __test__/utils.unit.test.ts | 10 +++++ dist/index.js | 57 +++++++++++++++++++---------- src/dockerhub-helper.ts | 4 +- src/main.ts | 19 +++++++--- src/readme-helper.ts | 12 +----- src/utils.ts | 14 +++++++ 7 files changed, 80 insertions(+), 47 deletions(-) create mode 100644 __test__/utils.unit.test.ts create mode 100644 src/utils.ts diff --git a/__test__/readme-helper.unit.test.ts b/__test__/readme-helper.unit.test.ts index 9bc4ef0..5b22616 100644 --- a/__test__/readme-helper.unit.test.ts +++ b/__test__/readme-helper.unit.test.ts @@ -1,4 +1,4 @@ -import {completeRelativeUrls, truncateToBytes} from '../src/readme-helper' +import {completeRelativeUrls} from '../src/readme-helper' describe('complete relative urls tests', () => { const GITHUB_SERVER_URL = process.env['GITHUB_SERVER_URL'] @@ -333,12 +333,3 @@ describe('complete relative urls tests', () => { ) }) }) - -describe('truncate to bytes tests', () => { - test('unicode aware truncation to a number of bytes', async () => { - expect(truncateToBytes('test string to be truncated', 10)).toEqual( - 'test strin' - ) - expect(truncateToBytes('😀😁😂🤣😃😄😅', 10)).toEqual('😀😁') - }) -}) diff --git a/__test__/utils.unit.test.ts b/__test__/utils.unit.test.ts new file mode 100644 index 0000000..dac6410 --- /dev/null +++ b/__test__/utils.unit.test.ts @@ -0,0 +1,10 @@ +import {truncateToBytes} from '../src/utils' + +describe('truncate to bytes tests', () => { + test('unicode aware truncation to a number of bytes', async () => { + expect(truncateToBytes('test string to be truncated', 10)).toEqual( + 'test strin' + ) + expect(truncateToBytes('😀😁😂🤣😃😄😅', 10)).toEqual('😀😁') + }) +}) diff --git a/dist/index.js b/dist/index.js index 2840a91..0135fc9 100644 --- a/dist/index.js +++ b/dist/index.js @@ -42,7 +42,6 @@ Object.defineProperty(exports, "__esModule", ({ value: true })); exports.updateRepositoryDescription = exports.getToken = void 0; const core = __importStar(__nccwpck_require__(2186)); const fetch = __importStar(__nccwpck_require__(467)); -const DESCRIPTION_MAX_CHARS = 100; function getToken(username, password) { return __awaiter(this, void 0, void 0, function* () { const body = { @@ -69,7 +68,7 @@ function updateRepositoryDescription(token, repository, description, fullDescrip full_description: fullDescription }; if (description) { - body['description'] = description.slice(0, DESCRIPTION_MAX_CHARS); + body['description'] = description; } yield fetch(`https://hub.docker.com/v2/repositories/${repository}`, { method: 'patch', @@ -238,12 +237,9 @@ const core = __importStar(__nccwpck_require__(2186)); const inputHelper = __importStar(__nccwpck_require__(5480)); const dockerhubHelper = __importStar(__nccwpck_require__(1812)); const readmeHelper = __importStar(__nccwpck_require__(3367)); +const utils = __importStar(__nccwpck_require__(918)); const util_1 = __nccwpck_require__(3837); -function getErrorMessage(error) { - if (error instanceof Error) - return error.message; - return String(error); -} +const SHORT_DESCRIPTION_MAX_BYTES = 100; function run() { return __awaiter(this, void 0, void 0, function* () { try { @@ -254,6 +250,11 @@ function run() { core.info('Reading description source file'); const readmeContent = yield readmeHelper.getReadmeContent(inputs.readmeFilepath, inputs.enableUrlCompletion, inputs.imageExtensions); core.debug(readmeContent); + // Truncate the short description if it is too long + const truncatedShortDescription = utils.truncateToBytes(inputs.shortDescription, SHORT_DESCRIPTION_MAX_BYTES); + if (truncatedShortDescription.length !== inputs.shortDescription.length) { + core.warning(`The short description exceeds DockerHub's limit and has been truncated to ${SHORT_DESCRIPTION_MAX_BYTES} bytes.`); + } // Acquire a token for the Docker Hub API core.info('Acquiring token'); const token = yield dockerhubHelper.getToken(inputs.username, inputs.password); @@ -264,7 +265,7 @@ function run() { } catch (error) { core.debug((0, util_1.inspect)(error)); - core.setFailed(getErrorMessage(error)); + core.setFailed(utils.getErrorMessage(error)); } }); } @@ -311,10 +312,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge }); }; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.completeRelativeUrls = exports.getReadmeContent = exports.truncateToBytes = exports.ENABLE_URL_COMPLETION_DEFAULT = exports.IMAGE_EXTENSIONS_DEFAULT = exports.README_FILEPATH_DEFAULT = void 0; +exports.completeRelativeUrls = exports.getReadmeContent = exports.ENABLE_URL_COMPLETION_DEFAULT = exports.IMAGE_EXTENSIONS_DEFAULT = exports.README_FILEPATH_DEFAULT = void 0; const core = __importStar(__nccwpck_require__(2186)); const fs = __importStar(__nccwpck_require__(7147)); -const unicodeSubstring = __nccwpck_require__(6986); +const utils = __importStar(__nccwpck_require__(918)); exports.README_FILEPATH_DEFAULT = './README.md'; exports.IMAGE_EXTENSIONS_DEFAULT = 'bmp,gif,jpg,jpeg,png,svg,webp'; exports.ENABLE_URL_COMPLETION_DEFAULT = false; @@ -323,14 +324,6 @@ const REPOSITORY_URL = `${process.env['GITHUB_SERVER_URL']}/${process.env['GITHU const BLOB_PREFIX = `${REPOSITORY_URL}/blob/${process.env['GITHUB_REF_NAME']}/`; const RAW_PREFIX = `${REPOSITORY_URL}/raw/${process.env['GITHUB_REF_NAME']}/`; const MAX_BYTES = 25000; -function truncateToBytes(s, n) { - let len = n; - while (Buffer.byteLength(s) > n) { - s = unicodeSubstring(s, 0, len--); - } - return s; -} -exports.truncateToBytes = truncateToBytes; function getReadmeContent(readmeFilepath, enableUrlCompletion, imageExtensions) { return __awaiter(this, void 0, void 0, function* () { // Fetch the readme content @@ -338,7 +331,7 @@ function getReadmeContent(readmeFilepath, enableUrlCompletion, imageExtensions) encoding: 'utf8' }); readmeContent = completeRelativeUrls(readmeContent, readmeFilepath, enableUrlCompletion, imageExtensions); - const truncatedReadmeContent = truncateToBytes(readmeContent, MAX_BYTES); + const truncatedReadmeContent = utils.truncateToBytes(readmeContent, MAX_BYTES); if (truncatedReadmeContent.length !== readmeContent.length) { core.warning(`The README content exceeds DockerHub's limit and has been truncated to ${MAX_BYTES} bytes.`); } @@ -446,6 +439,32 @@ function getRelativeUrlRules() { } +/***/ }), + +/***/ 918: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.truncateToBytes = exports.getErrorMessage = void 0; +const unicodeSubstring = __nccwpck_require__(6986); +function getErrorMessage(error) { + if (error instanceof Error) + return error.message; + return String(error); +} +exports.getErrorMessage = getErrorMessage; +function truncateToBytes(s, n) { + let len = n; + while (Buffer.byteLength(s) > n) { + s = unicodeSubstring(s, 0, len--); + } + return s; +} +exports.truncateToBytes = truncateToBytes; + + /***/ }), /***/ 7351: diff --git a/src/dockerhub-helper.ts b/src/dockerhub-helper.ts index fcea0b3..b2e8da0 100644 --- a/src/dockerhub-helper.ts +++ b/src/dockerhub-helper.ts @@ -1,8 +1,6 @@ import * as core from '@actions/core' import * as fetch from 'node-fetch' -const DESCRIPTION_MAX_CHARS = 100 - export async function getToken( username: string, password: string @@ -36,7 +34,7 @@ export async function updateRepositoryDescription( full_description: fullDescription } if (description) { - body['description'] = description.slice(0, DESCRIPTION_MAX_CHARS) + body['description'] = description } await fetch(`https://hub.docker.com/v2/repositories/${repository}`, { method: 'patch', diff --git a/src/main.ts b/src/main.ts index 17fc993..c384732 100644 --- a/src/main.ts +++ b/src/main.ts @@ -2,12 +2,10 @@ import * as core from '@actions/core' import * as inputHelper from './input-helper' import * as dockerhubHelper from './dockerhub-helper' import * as readmeHelper from './readme-helper' +import * as utils from './utils' import {inspect} from 'util' -function getErrorMessage(error: unknown) { - if (error instanceof Error) return error.message - return String(error) -} +const SHORT_DESCRIPTION_MAX_BYTES = 100 async function run(): Promise { try { @@ -25,6 +23,17 @@ async function run(): Promise { ) core.debug(readmeContent) + // Truncate the short description if it is too long + const truncatedShortDescription = utils.truncateToBytes( + inputs.shortDescription, + SHORT_DESCRIPTION_MAX_BYTES + ) + if (truncatedShortDescription.length !== inputs.shortDescription.length) { + core.warning( + `The short description exceeds DockerHub's limit and has been truncated to ${SHORT_DESCRIPTION_MAX_BYTES} bytes.` + ) + } + // Acquire a token for the Docker Hub API core.info('Acquiring token') const token = await dockerhubHelper.getToken( @@ -42,7 +51,7 @@ async function run(): Promise { core.info('Request successful') } catch (error) { core.debug(inspect(error)) - core.setFailed(getErrorMessage(error)) + core.setFailed(utils.getErrorMessage(error)) } } diff --git a/src/readme-helper.ts b/src/readme-helper.ts index 34ae5e9..90075c4 100644 --- a/src/readme-helper.ts +++ b/src/readme-helper.ts @@ -1,6 +1,6 @@ import * as core from '@actions/core' import * as fs from 'fs' -import unicodeSubstring = require('unicode-substring') +import * as utils from './utils' export const README_FILEPATH_DEFAULT = './README.md' export const IMAGE_EXTENSIONS_DEFAULT = 'bmp,gif,jpg,jpeg,png,svg,webp' @@ -28,14 +28,6 @@ type Rule = { absUrlPrefix: string } -export function truncateToBytes(s: string, n: number): string { - let len = n - while (Buffer.byteLength(s) > n) { - s = unicodeSubstring(s, 0, len--) - } - return s -} - export async function getReadmeContent( readmeFilepath: string, enableUrlCompletion: boolean, @@ -53,7 +45,7 @@ export async function getReadmeContent( imageExtensions ) - const truncatedReadmeContent = truncateToBytes(readmeContent, MAX_BYTES) + const truncatedReadmeContent = utils.truncateToBytes(readmeContent, MAX_BYTES) if (truncatedReadmeContent.length !== readmeContent.length) { core.warning( `The README content exceeds DockerHub's limit and has been truncated to ${MAX_BYTES} bytes.` diff --git a/src/utils.ts b/src/utils.ts new file mode 100644 index 0000000..e3eac07 --- /dev/null +++ b/src/utils.ts @@ -0,0 +1,14 @@ +import unicodeSubstring = require('unicode-substring') + +export function getErrorMessage(error: unknown) { + if (error instanceof Error) return error.message + return String(error) +} + +export function truncateToBytes(s: string, n: number): string { + let len = n + while (Buffer.byteLength(s) > n) { + s = unicodeSubstring(s, 0, len--) + } + return s +}