chore: convert core logger to global logger
parent
0440a33b65
commit
38285d014c
|
|
@ -55,6 +55,8 @@
|
|||
"no-continue": "off",
|
||||
// From experience, named exports are almost always desired. I got tired of this rule
|
||||
"import/prefer-default-export": "off",
|
||||
// Disable in favour of TS equivalent
|
||||
"no-unused-vars": "off",
|
||||
// Unused vars are useful to keep method signatures consistent and documented
|
||||
"@typescript-eslint/no-unused-vars": "off",
|
||||
// For this project only use kebab-case
|
||||
|
|
@ -65,9 +67,13 @@
|
|||
"unicorn/prevent-abbreviations": "off",
|
||||
// Allow disabling eslint per file
|
||||
"eslint-comments/no-use": "off",
|
||||
// Deno import style
|
||||
// Deno import style not supported (enable after upgrading)
|
||||
"import/extensions": "off",
|
||||
// Deno import style
|
||||
"import/no-unresolved": "off"
|
||||
// Deno import style not supported (enable after upgrading)
|
||||
"import/no-unresolved": "off",
|
||||
// App it not yet internationalised
|
||||
"i18n-text/no-en": "off",
|
||||
// Showing false positives (enable after upgrading)
|
||||
"no-shadow": "off"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,13 @@ export const createFormatter = ({
|
|||
showBrackets = true,
|
||||
depth = 3,
|
||||
} = {}): FormatterFunction => {
|
||||
const column = (value: string) => (showBrackets ? `[${value}]` : ` ${value}`);
|
||||
const column = (input: string, { width = 0, align = 'left' } = {}) => {
|
||||
const totalWidth = showBrackets ? width + 2 : width;
|
||||
const value = showBrackets ? `[${input}]` : ` ${input}`;
|
||||
const paddingOptions = { side: align === 'left' ? 'right' : 'left' };
|
||||
|
||||
return pad(value, totalWidth, paddingOptions);
|
||||
};
|
||||
|
||||
return ({ level, levelName, msg, args, loggerName }: LogRecord) => {
|
||||
let line = '';
|
||||
|
|
@ -31,7 +37,7 @@ export const createFormatter = ({
|
|||
|
||||
if (showLevelName) {
|
||||
const shortName = levelName.length <= 5 ? levelName : levelName.slice(0, 4);
|
||||
line += column(`${pad(shortName, 5, { side: 'left' })}`);
|
||||
line += column(shortName, { width: 5, align: 'right' });
|
||||
}
|
||||
|
||||
if (showLevel) {
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
/* eslint-disable no-unused-vars */
|
||||
export type Level = 'debug' | 'info' | 'warn' | 'error' | 'critical';
|
||||
let log: {
|
||||
debug: (msg: any, ...args: any[]) => void;
|
||||
info: (msg: any, ...args: any[]) => void;
|
||||
warning: (msg: any, ...args: any[]) => void;
|
||||
error: (msg: any, ...args: any[]) => void;
|
||||
};
|
||||
|
||||
declare global {
|
||||
const log: (level: Level, ...args: any[]) => void;
|
||||
|
||||
interface Window {
|
||||
log: any;
|
||||
}
|
||||
interface Window {
|
||||
log: any;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,8 @@ import PlatformSetup from './model/platform-setup.ts';
|
|||
async function runMain() {
|
||||
try {
|
||||
if (Cli.InitCliMode()) {
|
||||
log.debug('CloudBuilder CLI mode');
|
||||
// Todo - this is only here for testing the entire flow in deno and making sure I'm hitting the right path
|
||||
log.error('CloudBuilder CLI mode');
|
||||
await Cli.RunCli();
|
||||
|
||||
return;
|
||||
|
|
@ -28,7 +29,7 @@ async function runMain() {
|
|||
if (buildParameters.cloudRunnerCluster !== 'local') {
|
||||
await CloudRunner.run(buildParameters, baseImage.toString());
|
||||
} else {
|
||||
core.info('Building locally');
|
||||
log.info('Building locally');
|
||||
await PlatformSetup.setup(buildParameters, actionFolder);
|
||||
if (process.platform === 'darwin') {
|
||||
MacBuilder.run(actionFolder, workspace, buildParameters);
|
||||
|
|
@ -40,7 +41,7 @@ async function runMain() {
|
|||
// Set output
|
||||
await Output.setBuildVersion(buildParameters.buildVersion);
|
||||
} catch (error) {
|
||||
core.error(error);
|
||||
log.error(error);
|
||||
core.setFailed((error as Error).message);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ export default class AndroidVersioning {
|
|||
|
||||
static versionToVersionCode(version) {
|
||||
if (version === 'none') {
|
||||
core.info(`Versioning strategy is set to ${version}, so android version code should not be applied.`);
|
||||
log.info(`Versioning strategy is set to ${version}, so android version code should not be applied.`);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -19,7 +19,7 @@ export default class AndroidVersioning {
|
|||
const parsedVersion = semver.parse(version);
|
||||
|
||||
if (!parsedVersion) {
|
||||
core.warning(`Could not parse "${version}" to semver, defaulting android version code to 1`);
|
||||
log.warning(`Could not parse "${version}" to semver, defaulting android version code to 1`);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -33,7 +33,7 @@ export default class AndroidVersioning {
|
|||
`Generated versionCode ${versionCode} is dangerously close to the maximum allowed number 2100000000. Consider a different versioning scheme to be able to continue updating your application.`,
|
||||
);
|
||||
}
|
||||
core.info(`Using android versionCode ${versionCode}`);
|
||||
log.info(`Using android versionCode ${versionCode}`);
|
||||
|
||||
return versionCode;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ class Cache {
|
|||
return;
|
||||
}
|
||||
|
||||
core.warning(`
|
||||
log.warning(`
|
||||
Library folder does not exist.
|
||||
Consider setting up caching to speed up your workflow,
|
||||
if this is not your first build.
|
||||
|
|
|
|||
|
|
@ -68,8 +68,8 @@ export class Cli {
|
|||
|
||||
@CliFunction(`print-input`, `prints all input`)
|
||||
private static logInput() {
|
||||
core.info(`\n`);
|
||||
core.info(`INPUT:`);
|
||||
log.info(`\n`);
|
||||
log.info(`INPUT:`);
|
||||
const properties = Object.getOwnPropertyNames(Input);
|
||||
for (const element of properties) {
|
||||
if (
|
||||
|
|
@ -80,10 +80,10 @@ export class Cli {
|
|||
element !== 'cliOptions' &&
|
||||
element !== 'prototype'
|
||||
) {
|
||||
core.info(`${element} ${Input[element]}`);
|
||||
log.info(`${element} ${Input[element]}`);
|
||||
}
|
||||
}
|
||||
core.info(`\n`);
|
||||
log.info(`\n`);
|
||||
}
|
||||
|
||||
@CliFunction(`cli`, `runs a cloud runner build`)
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ export class AWSBaseStack {
|
|||
}
|
||||
CloudRunnerLogger.log('base stack is now ready');
|
||||
} catch (error) {
|
||||
core.error(JSON.stringify(await describeStack(), undefined, 4));
|
||||
log.error(JSON.stringify(await describeStack(), undefined, 4));
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import CloudRunner from '../../cloud-runner.ts';
|
|||
export class AWSError {
|
||||
static async handleStackCreationFailure(error: any, CF: aws.CloudFormation, taskDefStackName: string) {
|
||||
CloudRunnerLogger.log('aws error: ');
|
||||
core.error(JSON.stringify(error, undefined, 4));
|
||||
log.error(JSON.stringify(error, undefined, 4));
|
||||
if (CloudRunner.buildParameters.cloudRunnerIntegrationTests) {
|
||||
CloudRunnerLogger.log('Getting events and resources for task stack');
|
||||
const events = (await CF.describeStackEvents({ StackName: taskDefStackName }).promise()).StackEvents;
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ class AWSTaskRunner {
|
|||
);
|
||||
|
||||
core.setFailed(error);
|
||||
core.error(error);
|
||||
log.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -131,7 +131,7 @@ class Kubernetes implements ProviderInterface {
|
|||
return output;
|
||||
} catch (error) {
|
||||
CloudRunnerLogger.log('Running job failed');
|
||||
core.error(JSON.stringify(error, undefined, 4));
|
||||
log.error(JSON.stringify(error, undefined, 4));
|
||||
await this.cleanupTaskResources();
|
||||
throw error;
|
||||
}
|
||||
|
|
@ -151,7 +151,7 @@ class Kubernetes implements ProviderInterface {
|
|||
await new Promise((promise) => setTimeout(promise, 5000));
|
||||
} catch (error) {
|
||||
CloudRunnerLogger.log('Failed to cleanup, error:');
|
||||
core.error(JSON.stringify(error, undefined, 4));
|
||||
log.error(JSON.stringify(error, undefined, 4));
|
||||
CloudRunnerLogger.log('Abandoning cleanup, build error:');
|
||||
throw error;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,8 +37,8 @@ class KubernetesStorage {
|
|||
try {
|
||||
return (await kubeClient.readNamespacedPersistentVolumeClaim(name, namespace)).body.status?.phase;
|
||||
} catch (error) {
|
||||
core.error('Failed to get PVC phase');
|
||||
core.error(JSON.stringify(error, undefined, 4));
|
||||
log.error('Failed to get PVC phase');
|
||||
log.error(JSON.stringify(error, undefined, 4));
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
|
@ -57,9 +57,9 @@ class KubernetesStorage {
|
|||
},
|
||||
);
|
||||
} catch (error: any) {
|
||||
core.error('Failed to watch PVC');
|
||||
core.error(error.toString());
|
||||
core.error(
|
||||
log.error('Failed to watch PVC');
|
||||
log.error(error.toString());
|
||||
log.error(
|
||||
`PVC Body: ${JSON.stringify(
|
||||
(await kubeClient.readNamespacedPersistentVolumeClaim(name, namespace)).body,
|
||||
undefined,
|
||||
|
|
|
|||
|
|
@ -44,8 +44,8 @@ class KubernetesTaskRunner {
|
|||
throw resultError;
|
||||
}
|
||||
if (!didStreamAnyLogs) {
|
||||
core.error('Failed to stream any logs, listing namespace events, check for an error with the container');
|
||||
core.error(
|
||||
log.error('Failed to stream any logs, listing namespace events, check for an error with the container');
|
||||
log.error(
|
||||
JSON.stringify(
|
||||
{
|
||||
events: (await kubeClient.listNamespacedEvent(namespace)).body.items
|
||||
|
|
|
|||
|
|
@ -10,24 +10,24 @@ class CloudRunnerLogger {
|
|||
}
|
||||
|
||||
public static log(message: string) {
|
||||
core.info(message);
|
||||
log.info(message);
|
||||
}
|
||||
|
||||
public static logWarning(message: string) {
|
||||
core.warning(message);
|
||||
log.warning(message);
|
||||
}
|
||||
|
||||
public static logLine(message: string) {
|
||||
core.info(`${message}\n`);
|
||||
log.info(`${message}\n`);
|
||||
}
|
||||
|
||||
public static error(message: string) {
|
||||
core.error(message);
|
||||
log.error(message);
|
||||
}
|
||||
|
||||
public static logWithTime(message: string) {
|
||||
const newTimestamp = this.createTimestamp();
|
||||
core.info(
|
||||
log.info(
|
||||
`${message} (Since previous: ${this.calculateTimeDiff(
|
||||
newTimestamp,
|
||||
this.timestamp,
|
||||
|
|
|
|||
|
|
@ -9,19 +9,19 @@ export class FollowLogStreamService {
|
|||
CloudRunnerLogger.log('End of log transmission received');
|
||||
shouldReadLogs = false;
|
||||
} else if (message.includes('Rebuilding Library because the asset database could not be found!')) {
|
||||
core.warning('LIBRARY NOT FOUND!');
|
||||
log.warning('LIBRARY NOT FOUND!');
|
||||
core.setOutput('library-found', 'false');
|
||||
} else if (message.includes('Build succeeded')) {
|
||||
core.setOutput('build-result', 'success');
|
||||
} else if (message.includes('Build fail')) {
|
||||
core.setOutput('build-result', 'failed');
|
||||
core.setFailed('unity build failed');
|
||||
core.error('BUILD FAILED!');
|
||||
log.error('BUILD FAILED!');
|
||||
} else if (CloudRunner.buildParameters.cloudRunnerIntegrationTests && message.includes(': Listening for Jobs')) {
|
||||
core.setOutput('cloud runner stop watching', 'true');
|
||||
shouldReadLogs = false;
|
||||
shouldCleanup = false;
|
||||
core.warning('cloud runner stop watching');
|
||||
log.warning('cloud runner stop watching');
|
||||
}
|
||||
message = `[${CloudRunnerStatics.logPrefix}] ${message}`;
|
||||
if (CloudRunner.buildParameters.cloudRunnerIntegrationTests) {
|
||||
|
|
|
|||
|
|
@ -7,6 +7,6 @@ describe(`github cli`, () => {
|
|||
const token = await GithubCliReader.GetGitHubAuthToken();
|
||||
|
||||
// Todo - use expect(result).toStrictEqual(something)
|
||||
core.info(token);
|
||||
log.info(token);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ export class GithubCliReader {
|
|||
.replace(/ /g, '')
|
||||
.replace(/\n/g, '');
|
||||
} catch (error: any) {
|
||||
core.info(error || 'Failed to get github auth token from gh cli');
|
||||
log.info(error || 'Failed to get github auth token from gh cli');
|
||||
|
||||
return '';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,19 +20,19 @@ class System {
|
|||
|
||||
const showOutput = () => {
|
||||
if (debug !== '' && shouldLog) {
|
||||
core.debug(debug);
|
||||
log.debug(debug);
|
||||
}
|
||||
|
||||
if (result !== '' && shouldLog) {
|
||||
core.info(result);
|
||||
log.info(result);
|
||||
}
|
||||
|
||||
if (error !== '' && shouldLog) {
|
||||
core.warning(error);
|
||||
log.warning(error);
|
||||
}
|
||||
};
|
||||
|
||||
const throwContextualError = (message) => {
|
||||
const throwContextualError = (message: string) => {
|
||||
let commandAsString = command;
|
||||
if (Array.isArray(arguments_)) {
|
||||
commandAsString += ` ${arguments_.join(' ')}`;
|
||||
|
|
|
|||
|
|
@ -89,6 +89,8 @@ export default class Versioning {
|
|||
throw new ValidationError(`Versioning strategy should be one of ${Object.values(this.strategies).join(', ')}.`);
|
||||
}
|
||||
|
||||
log.info('Versioning strategy:', strategy);
|
||||
|
||||
let version;
|
||||
switch (strategy) {
|
||||
case this.strategies.None:
|
||||
|
|
@ -107,6 +109,8 @@ export default class Versioning {
|
|||
throw new NotImplementedException(`Strategy ${strategy} is not implemented.`);
|
||||
}
|
||||
|
||||
log.info('Version of this build:', version);
|
||||
|
||||
return version;
|
||||
}
|
||||
|
||||
|
|
@ -133,7 +137,7 @@ export default class Versioning {
|
|||
|
||||
if (!(await this.hasAnyVersionTags())) {
|
||||
const version = `0.0.${await this.getTotalNumberOfCommits()}`;
|
||||
core.info(`Generated version ${version} (no version tags found).`);
|
||||
log.info(`Generated version ${version} (no version tags found).`);
|
||||
|
||||
return version;
|
||||
}
|
||||
|
|
@ -146,13 +150,13 @@ export default class Versioning {
|
|||
const [major, minor, patch] = `${tag}.${commits}`.split('.');
|
||||
const threeDigitVersion = /^\d+$/.test(patch) ? `${major}.${minor}.${patch}` : `${major}.0.${minor}`;
|
||||
|
||||
core.info(`Found semantic version ${threeDigitVersion} for ${this.branch}@${hash}`);
|
||||
log.info(`Found semantic version ${threeDigitVersion} for ${this.branch}@${hash}`);
|
||||
|
||||
return `${threeDigitVersion}`;
|
||||
}
|
||||
|
||||
const version = `0.0.${await this.getTotalNumberOfCommits()}`;
|
||||
core.info(`Generated version ${version} (semantic version couldn't be determined).`);
|
||||
log.info(`Generated version ${version} (semantic version couldn't be determined).`);
|
||||
|
||||
return version;
|
||||
}
|
||||
|
|
@ -206,7 +210,7 @@ export default class Versioning {
|
|||
hash,
|
||||
};
|
||||
} catch {
|
||||
core.warning(
|
||||
log.warning(
|
||||
`Failed to parse git describe output or version can not be determined through: "${description}".`,
|
||||
);
|
||||
|
||||
|
|
@ -235,8 +239,10 @@ export default class Versioning {
|
|||
static async fetch() {
|
||||
try {
|
||||
await this.git(['fetch', '--unshallow']);
|
||||
} catch (error) {
|
||||
core.warning(`Fetch --unshallow caught: ${error}`);
|
||||
} catch {
|
||||
log.warning(
|
||||
`fetch --unshallow did not work, falling back to regular fetch (which probably just means it's not running on GH actions)`,
|
||||
);
|
||||
await this.git(['fetch']);
|
||||
}
|
||||
}
|
||||
|
|
@ -261,8 +267,8 @@ export default class Versioning {
|
|||
const isDirty = output !== '';
|
||||
|
||||
if (isDirty) {
|
||||
core.warning('Changes were made to the following files and folders:\n');
|
||||
core.warning(output);
|
||||
log.warning('Changes were made to the following files and folders:\n');
|
||||
log.warning(output);
|
||||
}
|
||||
|
||||
return isDirty;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { exec as originalExec } from 'https://deno.land/x/exec/mod.ts';
|
||||
import { exec as originalExec } from 'https://deno.land/x/exec@0.0.5/mod.ts';
|
||||
import { core } from './core.ts';
|
||||
|
||||
export enum OutputMode {
|
||||
|
|
@ -8,22 +8,34 @@ export enum OutputMode {
|
|||
Tee, // both dump and capture the output
|
||||
}
|
||||
|
||||
export interface IExecResponse {
|
||||
code: number;
|
||||
export interface ICommandResult {
|
||||
status?: {
|
||||
code: number;
|
||||
success: boolean;
|
||||
};
|
||||
output: string;
|
||||
}
|
||||
|
||||
export interface ISanitisedCommandResult {
|
||||
exitCode: number;
|
||||
success: boolean;
|
||||
output: string;
|
||||
}
|
||||
|
||||
interface IOptions {
|
||||
silent?: boolean;
|
||||
ignoreReturnCode?: boolean;
|
||||
output?: OutputMode;
|
||||
verbose?: boolean;
|
||||
continueOnError?: boolean;
|
||||
}
|
||||
|
||||
// Todo - change signature of exec inside the code instead of adapting the exec method
|
||||
const exec = async (command, args: string | string[] = [], ghActionsOptions: IOptions = {}): Promise<IExecResponse> => {
|
||||
core.info('Running command: ', command, args);
|
||||
|
||||
const exec = async (
|
||||
command: string,
|
||||
args: string | string[] = [],
|
||||
ghActionsOptions: IOptions = {},
|
||||
): Promise<ISanitisedCommandResult> => {
|
||||
const options = {
|
||||
output: OutputMode.Tee,
|
||||
verbose: false,
|
||||
|
|
@ -31,16 +43,20 @@ const exec = async (command, args: string | string[] = [], ghActionsOptions: IOp
|
|||
};
|
||||
|
||||
const { silent = false, ignoreReturnCode } = ghActionsOptions;
|
||||
if (silent) options.output = OutputMode.None;
|
||||
if (silent) options.output = OutputMode.Capture;
|
||||
if (ignoreReturnCode) options.continueOnError = true;
|
||||
|
||||
const result = await originalExec(`${command} ${args.join(' ')}`, options);
|
||||
core.info('result:', result);
|
||||
const argsString = typeof args === 'string' ? args : args.join(' ');
|
||||
log.debug('Command: ', command, argsString);
|
||||
|
||||
const { status = {}, output = '' } = result;
|
||||
const result: ICommandResult = await originalExec(`${command} ${argsString}`, options);
|
||||
|
||||
log.debug('Result:', result);
|
||||
|
||||
const { status, output = '' } = result;
|
||||
const { code: exitCode, success } = status;
|
||||
|
||||
return { exitCode, success, output };
|
||||
return { exitCode, success, output: output.trim() };
|
||||
};
|
||||
|
||||
export { exec };
|
||||
|
|
|
|||
Loading…
Reference in New Issue