From 0666c7e592afd1767aaa229ef67d89b5bff3c56d Mon Sep 17 00:00:00 2001 From: sokari Date: Sun, 8 Dec 2024 16:04:24 +0100 Subject: [PATCH] feat: print URL to console in hyperlink --- README.md | 21 ++++++-- assets/clean-console-add.png | Bin 0 -> 48870 bytes start.sh | 2 +- worker/app/batch-processor.ts | 2 - worker/app/cloud-storage.ts | 6 +-- worker/app/util.ts | 12 +++-- worker/package-lock.json | 89 ++++++++++++++++++++++++++++++---- worker/package.json | 2 + worker/tsconfig.json | 2 +- 9 files changed, 113 insertions(+), 23 deletions(-) create mode 100644 assets/clean-console-add.png diff --git a/README.md b/README.md index ce52a07..64eb4f4 100644 --- a/README.md +++ b/README.md @@ -94,23 +94,31 @@ jobs: sokari/allure-docker-deploy:latest ``` +___ #### 2. Generate Allure results Add a step that outputs Allure result files to `/allure-results` path in the workflow. +___ + #### 3. Run the Workflow: Push your changes to the main branch and let GitHub Actions do the rest! +___ + #### 4. View Report information: Check the job summary in GitHub Actions for the report URL.
URL preview in GitHub Actions summary
+___ + #### 5. Get notified in Slack Add SLACK_TOKEN and SLACK_CHANNEL_ID as environment variable in the docker run command to receipt job completion notifications in Slack.
URL preview in GitHub Actions summary
+___ #### 6. View your test result files on the Firebase Developer console @@ -128,11 +136,15 @@ Tips 2. Configure `WEBSITE_EXPIRES` to manage the duration of hosted reports. 3. Mount `$GITHUB_STEP_SUMMARY` to display the test report URL in GitHub Actions job summaries. +___ + ### 2. For local test runs #### 1. Pull the Docker Image ```bash docker pull sokari/allure-docker-deploy:latest ``` +___ + #### 2. Run the Container ```shell docker run -d \ @@ -145,6 +157,8 @@ docker run -d \ -v /path/to/gcp-key.json:/credentials/key.json \ sokari/allure-docker-deploy ``` +___ + ##### 3. You can also use `docker-compose.yaml`: ```yaml services: @@ -164,11 +178,12 @@ services: WATCH_MODE: true TTL_SECS: 60 ``` +___ +#### 4. View test report URL in console +
Firebase CLI console output
-#### 4. Receive test report URL in console -
Firebase CLI console output
- +___ ## 🔑 **Key Features** * **Cloud Storage**: Automatically backs up test results to Google Cloud Storage. diff --git a/assets/clean-console-add.png b/assets/clean-console-add.png new file mode 100644 index 0000000000000000000000000000000000000000..d61899748f6ec4416f4e8cab174fd83a97975816 GIT binary patch literal 48870 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 Dof[] = []; if (websiteId) { diff --git a/worker/app/cloud-storage.ts b/worker/app/cloud-storage.ts index 20612a7..e0942d1 100644 --- a/worker/app/cloud-storage.ts +++ b/worker/app/cloud-storage.ts @@ -39,7 +39,7 @@ export class CloudStorage { destinationFilePath = path.basename(filePath); } try { - console.log(`Uploading ${destinationFilePath} to storage`) + // console.log(`Uploading ${destinationFilePath} to storage`) await CloudStorage.bucket.upload(filePath, { validation: !DEBUG, destination: `${storageHomeDir}/${destinationFilePath}`, @@ -58,7 +58,7 @@ export class CloudStorage { try { const [files] = await CloudStorage.bucket.getFiles({prefix: `${storageHomeDir}/`}); if (!files.length) { - console.log(`No files found in folder: ${storageHomeDir}/`); + console.log('No files to process from CloudStorage'); return; } await fs.mkdir(STAGING_PATH, {recursive: true}); // recursive, dont throw if exist @@ -69,10 +69,10 @@ export class CloudStorage { // Remove the preceding storageHomeDir path from the downloaded file const destination = path.join(STAGING_PATH, file.name.replace(`${storageHomeDir}/`, '')); await file.download({destination, validation: !DEBUG}); - console.log(`Downloaded ${file.name}`); })) } await Promise.all(downloadPromises); + console.log(`${files.length} files downloaded CloudStorage`); } catch (error) { console.error('Download error:', error); } diff --git a/worker/app/util.ts b/worker/app/util.ts index 8033cd3..a764962 100644 --- a/worker/app/util.ts +++ b/worker/app/util.ts @@ -2,15 +2,17 @@ import * as fsSync from 'fs' import * as fs from 'fs/promises' import * as path from "node:path"; import util from "node:util"; + const exec = util.promisify(require('child_process').exec) import {DEBUG, websiteId} from "../index"; import {StringBuilder} from "./string-builder"; import credential from "./credential"; - +import ansiEscapes from 'ansi-escapes'; +import chalk from "chalk"; export async function* getAllFilesStream(dir: string): AsyncGenerator { - const entries = await fs.readdir(dir, { withFileTypes: true }); + const entries = await fs.readdir(dir, {withFileTypes: true}); for (const entry of entries) { const fullPath = path.join(dir, entry.name); if (entry.isDirectory()) { @@ -30,7 +32,7 @@ export async function* getAllFilesStream(dir: string): AsyncGenerator { export function validateWebsiteExpires(expires: string): boolean { const length = expires.length - if(length < 2 || length > 3){ + if (length < 2 || length > 3) { return false; } @@ -143,7 +145,9 @@ export async function publishToFireBaseHosting(configParentDir: string): Promise if (match && match[2]) { const url = match[2] - console.log(`Allure test report URL: ${url}`) + + console.log('Allure test report URL') + console.log(ansiEscapes.link(chalk.blue(url), url)); return url as string } else { console.warn('Could not parse URL from hosting.') diff --git a/worker/package-lock.json b/worker/package-lock.json index 1267107..e284df8 100644 --- a/worker/package-lock.json +++ b/worker/package-lock.json @@ -8,7 +8,9 @@ "dependencies": { "@slack/web-api": "^7.8.0", "allure-commandline": "^2.32.0", + "ansi-escapes": "^7.0.0", "async-mutex": "^0.5.0", + "chalk": "^5.3.0", "chokidar": "^4.0.1", "firebase-admin": "^13.0.1", "p-limit": "^6.1.0" @@ -160,6 +162,36 @@ "regexp-match-indices": "1.0.2" } }, + "node_modules/@cucumber/cucumber/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@cucumber/cucumber/node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/@cucumber/cucumber/node_modules/glob": { "version": "10.4.5", "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", @@ -1806,6 +1838,21 @@ "allure": "bin/allure" } }, + "node_modules/ansi-escapes": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.0.0.tgz", + "integrity": "sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw==", + "license": "MIT", + "dependencies": { + "environment": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", @@ -2507,17 +2554,12 @@ } }, "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, "engines": { - "node": ">=10" + "node": "^12.17.0 || ^14.13 || >=16.0.0" }, "funding": { "url": "https://github.com/chalk/chalk?sponsor=1" @@ -3030,6 +3072,18 @@ "once": "^1.4.0" } }, + "node_modules/environment": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", + "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -3455,6 +3509,23 @@ "concat-map": "0.0.1" } }, + "node_modules/eslint/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, "node_modules/eslint/node_modules/eslint-visitor-keys": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", diff --git a/worker/package.json b/worker/package.json index 898393f..1e52033 100644 --- a/worker/package.json +++ b/worker/package.json @@ -14,7 +14,9 @@ "dependencies": { "@slack/web-api": "^7.8.0", "allure-commandline": "^2.32.0", + "ansi-escapes": "^7.0.0", "async-mutex": "^0.5.0", + "chalk": "^5.3.0", "chokidar": "^4.0.1", "firebase-admin": "^13.0.1", "p-limit": "^6.1.0" diff --git a/worker/tsconfig.json b/worker/tsconfig.json index 1fe239d..8b65470 100644 --- a/worker/tsconfig.json +++ b/worker/tsconfig.json @@ -6,7 +6,7 @@ "outDir": "lib", "sourceMap": true, "strict": true, - "target": "es2017", + "target": "es2020", "allowSyntheticDefaultImports": true, "esModuleInterop": true },