Skip to content

Commit

Permalink
fix: Remove Slackbot data
Browse files Browse the repository at this point in the history
  • Loading branch information
cybersokari committed Dec 8, 2024
1 parent 7e77856 commit fd2bed4
Show file tree
Hide file tree
Showing 7 changed files with 89 additions and 66 deletions.
2 changes: 1 addition & 1 deletion docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ services:
WEBSITE_EXPIRES: 12h
KEEP_HISTORY: true # Default is true when STORAGE_BUCKET is provided
KEEP_RETRIES: true # Default is false
WATCH_MODE: true
WATCH_MODE: false
TTL_SECS: 6
volumes:
- ./worker:/app #Devs only. This overrides the /app dir
Expand Down
4 changes: 2 additions & 2 deletions worker/app/counter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@ class Counter {
startTimer(): void {
this.startTime = Date.now();
}
getElapsedSeconds(): number {
getElapsedSeconds(): string {
if (!this.startTime) {
throw "Timer has not been started.";
}
const elapsed = Date.now() - this.startTime;
return elapsed / 1000
return (elapsed / 1000).toFixed()
}
}

Expand Down
15 changes: 5 additions & 10 deletions worker/app/credential.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import fs from "fs/promises";
* Handles loading and accessing Google Cloud credentials.
* Implements a Singleton pattern to ensure only one instance is created.
*/
class Credential {
export class Credential {
private _projectId: string | null = null; // Holds the project ID
private static instance: Credential; // Singleton instance
private data: any; // Parsed credentials data
Expand Down Expand Up @@ -35,15 +35,10 @@ class Credential {
* Sets the project ID for later use.
*/
public async create() {
try {
this.data = JSON.parse(
await fs.readFile(process.env.GOOGLE_APPLICATION_CREDENTIALS!, 'utf8')
);
this._projectId = this.data.project_id;
} catch (error) {
console.error('Failed to get project_id from Google credentials:', error);
throw error;
}
this.data = JSON.parse(
await fs.readFile(process.env.GOOGLE_APPLICATION_CREDENTIALS!, 'utf8')
);
this._projectId = this.data.project_id;
}
}

Expand Down
41 changes: 30 additions & 11 deletions worker/app/notifier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import {cloudStorage, keepHistory, keepRetires, STORAGE_BUCKET, websiteId} from
import {WebClient} from '@slack/web-api';
import {StringBuilder} from "./string-builder";
import * as fs from "node:fs";
import ansiEscapes from "ansi-escapes";
import chalk from "chalk";
import credential from "./credential";

type SlackCredentials = {
Expand All @@ -17,7 +19,15 @@ type SlackCredentials = {
* Handles notifications related to report generation and file processing.
* Supports Slack notifications, GitHub summary updates, and general stats logging.
*/
class Notifier {
export class Notifier {

get dashboardUrl(){
return new StringBuilder().
append("https://console.firebase.google.com/project")
.append(`/${(credential.projectId)}`)
.append(`/storage/${STORAGE_BUCKET}/files`)
.toString()
}

/**
* Sends a message to a Slack channel with details about the report.
Expand All @@ -43,7 +53,7 @@ class Notifier {
"elements": [
{
"type": "mrkdwn",
"text": ":file_folder: *Files uploaded:* 54"
"text": `:file_folder: *Files uploaded:* ${counter.filesUploaded}`
}
]
},
Expand All @@ -52,7 +62,7 @@ class Notifier {
"elements": [
{
"type": "mrkdwn",
"text": ":mag: *Files processed:* 49"
"text": `:mag: *Files processed:* ${counter.filesProcessed}`
}
]
},)
Expand All @@ -62,7 +72,7 @@ class Notifier {
"elements": [
{
"type": "mrkdwn",
"text": ":stopwatch: *Duration:* 11.206 seconds"
"text": `:stopwatch: *Duration:* ${counter.getElapsedSeconds()} seconds`
}
]
})
Expand All @@ -83,8 +93,6 @@ class Notifier {
})
}
if(cloudStorage){

const firebaseDashboardUrl = `https://console.firebase.google.com/project/${credential.projectId}/storage/${STORAGE_BUCKET}/files`
blocks.push({
"type": "actions",
"elements": [
Expand All @@ -95,7 +103,7 @@ class Notifier {
"text": "View files in storage",
"emoji": true
},
"url": firebaseDashboardUrl
"url": this.dashboardUrl
}
]
})
Expand Down Expand Up @@ -129,7 +137,7 @@ class Notifier {
* Includes the report link, processing stats, and duration.
* @param data - Contains the report URL and file path for summary
*/
public async printGithubSummary(data: { mountedFilePath: string, url: string | undefined }): Promise<void> {
public async printGithubSummary(data: { mountedFilePath: string, url: string | undefined}): Promise<void> {
const lineBreak = '</br>'
const builder = new StringBuilder()
builder.append(`**Your Allure report is ready 📈**}`)
Expand All @@ -139,8 +147,7 @@ class Notifier {
.append(lineBreak).append(lineBreak)
}
if (cloudStorage) {
const firebaseDashboardUrl = `https://console.firebase.google.com/project/${credential.projectId}/storage/${STORAGE_BUCKET}/files`
builder.append(`**[View files](${firebaseDashboardUrl})**`)
builder.append(`**[View files](${this.dashboardUrl})**`)
.append(lineBreak).append(lineBreak)

builder.append(`📂 Files uploaded: ${counter.filesUploaded}`)
Expand Down Expand Up @@ -179,6 +186,18 @@ class Notifier {
console.log('STORAGE_BUCKET is not provided, KEEP_HISTORY and KEEP_RETRIES disabled');
}
}

printSummaryToConsole(data: {url: string | null}): void {
if(data.url){
console.log('Allure test report URL')
console.log(ansiEscapes.link(chalk.blue(data.url), data.url));
}
if(cloudStorage){
const dashboardUrl = this.dashboardUrl
console.log('View files in Storage')
console.log(ansiEscapes.link(chalk.blue(dashboardUrl), dashboardUrl));
}
}
}

export default new Notifier();

7 changes: 6 additions & 1 deletion worker/app/report-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import * as fs from 'fs/promises'
import counter from "./counter";
import pLimit from 'p-limit';
import {publishToFireBaseHosting} from "./util";
import {Notifier} from "./notifier";

/**
* ReportBuilder Class
Expand All @@ -16,6 +17,7 @@ import {publishToFireBaseHosting} from "./util";
class ReportBuilder {
private timeOut: NodeJS.Timeout | undefined
private readonly ttl: number
private notifier = new Notifier()

constructor() {
this.ttl = Number.parseInt(process.env.TTL_SECS ?? '45')
Expand All @@ -29,7 +31,10 @@ class ReportBuilder {
clearTimeout(this.timeOut)
this.timeOut = setTimeout(async () => {
const path = await this.generate()
await publishToFireBaseHosting(path)
const url = await publishToFireBaseHosting(path)
if (url) {
this.notifier.printSummaryToConsole({url: url})
}
}, this.ttl * 1000)
}

Expand Down
17 changes: 6 additions & 11 deletions worker/app/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,9 @@ 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 {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<string> {
Expand Down Expand Up @@ -89,11 +87,11 @@ export async function changePermissionsRecursively(dirPath: string, mode: fsSync
* @param configParentDir - Directory containing the hosting configuration
* @returns {Promise<string | undefined>} - The URL of the deployed site, if successful
*/
export async function publishToFireBaseHosting(configParentDir: string): Promise<string| undefined> {
if (DEBUG) {
console.warn('DEBUG=true: Skipping live deployment')
return
}
export async function publishToFireBaseHosting(configParentDir: string): Promise<string | undefined> {
// if (DEBUG) {
// console.warn('DEBUG=true: Skipping live deployment')
// return
// }
const hosting = {
"hosting": {
"public": ".",
Expand Down Expand Up @@ -145,9 +143,6 @@ export async function publishToFireBaseHosting(configParentDir: string): Promise

if (match && match[2]) {
const url = match[2]

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.')
Expand Down
69 changes: 39 additions & 30 deletions worker/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import {
import ReportBuilder from "./app/report-builder";
import {CloudStorage} from "./app/cloud-storage";
import counter from "./app/counter";
import notifier from "./app/notifier";
import credential from "./app/credential";
import {BatchProcessor} from "./app/batch-processor";
import {Notifier} from "./app/notifier";

export const DEBUG = process.env.FIREBASE_STORAGE_EMULATOR_HOST !== undefined || false;
export const MOUNTED_PATH = '/allure-results'
Expand All @@ -22,7 +22,6 @@ export const keepRetires = process.env.KEEP_RETRIES?.toLowerCase() === 'true'
export const watchMode = process.env.WATCH_MODE?.toLowerCase() === 'true' || false;
export const fileProcessingConcurrency = watchMode ? 5 : 10


/**
* Entry Point
*
Expand All @@ -37,57 +36,67 @@ export function main(): void {
console.warn('WEBSITE_ID or STORAGE_BUCKET is required');
return
}
// Create it now, so that project_id will be available for
// Site deployment and messaging.
void credential.create()

if (watchMode) {
const processor = new BatchProcessor()
chokidar.watch('/allure-results', {
ignored: '^(?!.*\\.(json|png|jpeg|jpg|gif|properties|log|webm)$).*$',
persistent: true,
awaitWriteFinish: true,
usePolling: true,
depth: 2, // Limit recursive depth
}).on('add', (filePath: string) => {
processor.add(filePath);
});
console.log("Watching for file additions...");
} else {
(async () => {

(async () => {
// credential must be initialized before starting app
try {
await credential.create()
} catch (error) {
console.error('Failed to process Google credentials: Are you sure you have the correct file?', error);
return
}
if (watchMode) {
const processor = new BatchProcessor()
chokidar.watch('/allure-results', {
ignored: '^(?!.*\\.(json|png|jpeg|jpg|gif|properties|log|webm)$).*$',
persistent: true,
awaitWriteFinish: true,
usePolling: true,
depth: 2, // Limit recursive depth
}).on('add', (filePath: string) => {
processor.add(filePath);
});
console.log("Watching for file additions...");
} else {
let url
if(websiteId){
if (websiteId) {
// Stage files, generateAndHost then upload history if enabled
await Promise.all([
ReportBuilder.stageFiles(getAllFilesStream(MOUNTED_PATH)),
cloudStorage?.stageRemoteFiles({concurrency: fileProcessingConcurrency})
])
const path = await ReportBuilder.generate()
url = await publishToFireBaseHosting(path)
if(keepHistory){
if (keepHistory) {
await cloudStorage?.uploadHistory()
}
}

if (cloudStorage && keepRetires) {
await cloudStorage.uploadResults()
}

const summaryPath = process.env.GITHUB_STEP_SUMMARY
const promises = []
if(summaryPath){
promises.push(notifier.printGithubSummary({mountedFilePath: summaryPath, url: url}))
const notifier = new Notifier()
if (summaryPath) {
promises.push(notifier.printGithubSummary({
mountedFilePath: summaryPath,
url: url
}))
}
const token = process.env.SLACK_TOKEN;
const conversationId = process.env.SLACK_CHANNEL_ID;
if(conversationId && token){
promises.push(notifier.SendSlackMsg({conversationId: conversationId, token: token, url: url}))
if (conversationId && token) {
promises.push(notifier.SendSlackMsg({
conversationId: conversationId,
token: token, url: url
}))
}
await Promise.all(promises)
}

})()

})()
}
notifier.printStats()
}

if (require.main === module) {
Expand Down

0 comments on commit fd2bed4

Please sign in to comment.