From 7d99d406f7712edbd51d8870bb8b9147fe446afd Mon Sep 17 00:00:00 2001 From: Ryan Kienstra Date: Wed, 5 Jan 2022 20:39:22 -0600 Subject: [PATCH 01/18] Improve message when no dynamic jobs created Sometimes there will be no dynamic jobs, like if there's no diff against main. So show a more helpful message, instead of Success! You can now run the dynamic config jobs --- src/utils/runJob.ts | 5 ++++- src/utils/showMainTerminalHelperMessages.ts | 14 ++++++++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/utils/runJob.ts b/src/utils/runJob.ts index 4b6c79dc..a3919164 100644 --- a/src/utils/runJob.ts +++ b/src/utils/runJob.ts @@ -98,11 +98,14 @@ export default async function runJob( // @todo: maybe don't have a volume at all if there's no persist_to_workspace or attach_workspace. terminal.sendText( `${getBinaryPath()} local execute --job ${jobName} --config ${ - isJobInDynamicConfig ? dynamicConfigFilePath : processFilePath + isJobInDynamicConfig && fs.existsSync(dynamicConfigFilePath) + ? dynamicConfigFilePath + : processFilePath } -v ${volume} --debug` ); const helperMessagesProcess = showMainTerminalHelperMessages( + context, jobProvider, job, doesJobCreateDynamicConfig(jobInConfig) diff --git a/src/utils/showMainTerminalHelperMessages.ts b/src/utils/showMainTerminalHelperMessages.ts index 2b8b1853..c9f9246e 100644 --- a/src/utils/showMainTerminalHelperMessages.ts +++ b/src/utils/showMainTerminalHelperMessages.ts @@ -3,9 +3,13 @@ import * as vscode from 'vscode'; import Job from '../classes/Job'; import JobProvider from '../classes/JobProvider'; import { GET_PICARD_CONTAINER_FUNCTION } from '../constants'; +import getConfigFilePath from './getConfigFilePath'; +import getConfigFromPath from './getConfigFromPath'; +import getDynamicConfigFilePath from './getDynamicConfigFilePath'; import getSpawnOptions from './getSpawnOptions'; export default function showMainTerminalHelperMessages( + context: vscode.ExtensionContext, jobProvider: JobProvider, job: Job | undefined, doesJobCreateDynamicConfig: boolean @@ -25,7 +29,7 @@ export default function showMainTerminalHelperMessages( getSpawnOptions() ); - process.stdout.on('data', (data) => { + process.stdout.on('data', async (data) => { const output = data?.toString(); if (!output?.length) { return; @@ -38,8 +42,14 @@ export default function showMainTerminalHelperMessages( if (doesJobCreateDynamicConfig) { jobProvider.refresh(); + const config = getConfigFromPath( + getDynamicConfigFilePath(await getConfigFilePath(context)) + ); + vscode.window.showInformationMessage( - 'Success, you can now run the dynamic config jobs' + config?.jobs + ? `Success! You can now run the dynamic config jobs` + : `The step succeeded, but it didn't create any dynamic job` ); } else { jobProvider.refresh(job); From 9732c831271eae2b313da230eb6bf4c502742faa Mon Sep 17 00:00:00 2001 From: Ryan Kienstra Date: Wed, 5 Jan 2022 21:10:17 -0600 Subject: [PATCH 02/18] Make the 'Try again' button delete the dynamic config if there is onw When there's an error in the generated dynamic config, sometimes the only way to fix it is to delete that config. Then, the user can rerun the setup job. Maybe LCI should do that for them, but that might be overstepping. --- src/classes/JobProvider.ts | 3 ++- src/constants/index.ts | 1 + src/extension.ts | 13 +++++++++++++ src/utils/showMainTerminalHelperMessages.ts | 4 ++-- 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/classes/JobProvider.ts b/src/classes/JobProvider.ts index 4ace0cf5..6b7563d4 100644 --- a/src/classes/JobProvider.ts +++ b/src/classes/JobProvider.ts @@ -18,6 +18,7 @@ import { ENTER_LICENSE_COMMAND, GET_LICENSE_COMMAND, JOB_TREE_VIEW_ID, + PROCESS_TRY_AGAIN_COMMAND, TRIAL_STARTED_TIMESTAMP, } from '../constants'; @@ -183,7 +184,7 @@ export default class JobProvider return [ new Warning('Error processing the CircleCI config:'), new vscode.TreeItem(this.getJobErrorMessage()), - new Command('Try Again', `${JOB_TREE_VIEW_ID}.refresh`), + new Command('Try Again', PROCESS_TRY_AGAIN_COMMAND), ]; default: return []; diff --git a/src/constants/index.ts b/src/constants/index.ts index e553141c..43a75060 100644 --- a/src/constants/index.ts +++ b/src/constants/index.ts @@ -5,6 +5,7 @@ export const LICENSE_ERROR = 'localCiLicenseKeyError'; export const GET_LICENSE_COMMAND = 'local-ci.license.get'; export const ENTER_LICENSE_COMMAND = 'local-ci.license.enter'; export const EXIT_JOB_COMMAND = 'local-ci.job.exit'; +export const PROCESS_TRY_AGAIN_COMMAND = 'local-ci.process-error.try-again'; export const GET_RUNNING_CONTAINER_FUNCTION = `get_running_container() { IMAGE=$1 diff --git a/src/extension.ts b/src/extension.ts index 30ab5826..c7e1731a 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -18,6 +18,7 @@ import { HELP_URL, HOST_TMP_DIRECTORY, JOB_TREE_VIEW_ID, + PROCESS_TRY_AGAIN_COMMAND, RUN_JOB_COMMAND, SELECTED_CONFIG_PATH, TELEMETRY_KEY, @@ -30,6 +31,7 @@ import getCheckoutJobs from './utils/getCheckoutJobs'; import getConfig from './utils/getConfig'; import getConfigFilePath from './utils/getConfigFilePath'; import getDebuggingTerminalName from './utils/getDebuggingTerminalName'; +import getDynamicConfigFilePath from './utils/getDynamicConfigFilePath'; import getFinalTerminalName from './utils/getFinalTerminalName'; import getRepoBasename from './utils/getRepoBasename'; import getStarterConfig from './utils/getStarterConfig'; @@ -79,6 +81,17 @@ export function activate(context: vscode.ExtensionContext): void { vscode.commands.registerCommand(`${JOB_TREE_VIEW_ID}.refresh`, () => jobProvider.refresh() ), + vscode.commands.registerCommand(PROCESS_TRY_AGAIN_COMMAND, async () => { + // There might have been a problem with the dynamic config file, so remove it. + const dynamicConfig = getDynamicConfigFilePath( + await getConfigFilePath(context) + ); + if (fs.existsSync(dynamicConfig)) { + fs.rmSync(dynamicConfig); + } + + jobProvider.refresh(); + }), vscode.commands.registerCommand(`${JOB_TREE_VIEW_ID}.enterToken`, () => { const terminal = vscode.window.createTerminal({ name: 'Enter CircleCI® API Token', diff --git a/src/utils/showMainTerminalHelperMessages.ts b/src/utils/showMainTerminalHelperMessages.ts index c9f9246e..82fb239d 100644 --- a/src/utils/showMainTerminalHelperMessages.ts +++ b/src/utils/showMainTerminalHelperMessages.ts @@ -42,12 +42,12 @@ export default function showMainTerminalHelperMessages( if (doesJobCreateDynamicConfig) { jobProvider.refresh(); - const config = getConfigFromPath( + const dynamicConfig = getConfigFromPath( getDynamicConfigFilePath(await getConfigFilePath(context)) ); vscode.window.showInformationMessage( - config?.jobs + dynamicConfig?.jobs ? `Success! You can now run the dynamic config jobs` : `The step succeeded, but it didn't create any dynamic job` ); From 2111086f439c00d66e7af5c8588144357c1dbf66 Mon Sep 17 00:00:00 2001 From: Ryan Kienstra Date: Thu, 6 Jan 2022 10:36:02 -0600 Subject: [PATCH 03/18] Revert change to runJob() There would still be a problem running a job in a config that doesn't exist, but that probably isn't the place to fix it. --- src/utils/runJob.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/utils/runJob.ts b/src/utils/runJob.ts index a3919164..4b6c79dc 100644 --- a/src/utils/runJob.ts +++ b/src/utils/runJob.ts @@ -98,14 +98,11 @@ export default async function runJob( // @todo: maybe don't have a volume at all if there's no persist_to_workspace or attach_workspace. terminal.sendText( `${getBinaryPath()} local execute --job ${jobName} --config ${ - isJobInDynamicConfig && fs.existsSync(dynamicConfigFilePath) - ? dynamicConfigFilePath - : processFilePath + isJobInDynamicConfig ? dynamicConfigFilePath : processFilePath } -v ${volume} --debug` ); const helperMessagesProcess = showMainTerminalHelperMessages( - context, jobProvider, job, doesJobCreateDynamicConfig(jobInConfig) From 48b9937546a26309ad0b490a84ba218a9d6d3562 Mon Sep 17 00:00:00 2001 From: Ryan Kienstra Date: Thu, 6 Jan 2022 11:09:54 -0600 Subject: [PATCH 04/18] Add a missing argument to showMainTerminalHelperMessages() --- src/utils/runJob.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/utils/runJob.ts b/src/utils/runJob.ts index 4b6c79dc..b2aecddf 100644 --- a/src/utils/runJob.ts +++ b/src/utils/runJob.ts @@ -103,6 +103,7 @@ export default async function runJob( ); const helperMessagesProcess = showMainTerminalHelperMessages( + context, jobProvider, job, doesJobCreateDynamicConfig(jobInConfig) From ad76af0656303d17de90a83c79a5ddec9579f583 Mon Sep 17 00:00:00 2001 From: Ryan Kienstra Date: Thu, 6 Jan 2022 11:16:58 -0600 Subject: [PATCH 05/18] Add a period to the end of a sentence --- src/utils/showMainTerminalHelperMessages.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/showMainTerminalHelperMessages.ts b/src/utils/showMainTerminalHelperMessages.ts index 82fb239d..2b1e026f 100644 --- a/src/utils/showMainTerminalHelperMessages.ts +++ b/src/utils/showMainTerminalHelperMessages.ts @@ -48,7 +48,7 @@ export default function showMainTerminalHelperMessages( vscode.window.showInformationMessage( dynamicConfig?.jobs - ? `Success! You can now run the dynamic config jobs` + ? `Success! You can now run the dynamic config jobs.` : `The step succeeded, but it didn't create any dynamic job` ); } else { From 15d9f5f674d3e154d13d62e63cd9e3a053dcc5d0 Mon Sep 17 00:00:00 2001 From: Ryan Kienstra Date: Thu, 6 Jan 2022 11:43:22 -0600 Subject: [PATCH 06/18] Add a message to fix a build --- src/utils/showMainTerminalHelperMessages.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/utils/showMainTerminalHelperMessages.ts b/src/utils/showMainTerminalHelperMessages.ts index 2b1e026f..25ec9790 100644 --- a/src/utils/showMainTerminalHelperMessages.ts +++ b/src/utils/showMainTerminalHelperMessages.ts @@ -7,6 +7,7 @@ import getConfigFilePath from './getConfigFilePath'; import getConfigFromPath from './getConfigFromPath'; import getDynamicConfigFilePath from './getDynamicConfigFilePath'; import getSpawnOptions from './getSpawnOptions'; +import isMac from './isMac'; export default function showMainTerminalHelperMessages( context: vscode.ExtensionContext, @@ -59,6 +60,12 @@ export default function showMainTerminalHelperMessages( if (output?.includes('Task failed')) { job?.setIsFailure(); jobProvider.refresh(job); + + if (output?.includes('error looking up cgroup')) { + vscode.window.showErrorMessage( + 'You can probably fix this failed build with rm ~/.circleci/build_agent_settings.json' + ); + } } if (output?.includes(memoryMessage)) { From f15b5b1f9aeec451725853634e949d59ae9cd278 Mon Sep 17 00:00:00 2001 From: Ryan Kienstra Date: Thu, 6 Jan 2022 11:43:44 -0600 Subject: [PATCH 07/18] Add a message to fix a build --- src/utils/showMainTerminalHelperMessages.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/utils/showMainTerminalHelperMessages.ts b/src/utils/showMainTerminalHelperMessages.ts index 25ec9790..0bd86bbc 100644 --- a/src/utils/showMainTerminalHelperMessages.ts +++ b/src/utils/showMainTerminalHelperMessages.ts @@ -7,7 +7,6 @@ import getConfigFilePath from './getConfigFilePath'; import getConfigFromPath from './getConfigFromPath'; import getDynamicConfigFilePath from './getDynamicConfigFilePath'; import getSpawnOptions from './getSpawnOptions'; -import isMac from './isMac'; export default function showMainTerminalHelperMessages( context: vscode.ExtensionContext, From 8acbc5a45e452e43277fddf8e7f3271f8ecabc09 Mon Sep 17 00:00:00 2001 From: Ryan Kienstra Date: Thu, 6 Jan 2022 11:50:04 -0600 Subject: [PATCH 08/18] Update the error message to include to run it on local machine --- src/utils/showMainTerminalHelperMessages.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/utils/showMainTerminalHelperMessages.ts b/src/utils/showMainTerminalHelperMessages.ts index 0bd86bbc..e06fc297 100644 --- a/src/utils/showMainTerminalHelperMessages.ts +++ b/src/utils/showMainTerminalHelperMessages.ts @@ -37,6 +37,7 @@ export default function showMainTerminalHelperMessages( // This should be the final 'Success!' message when a job succeeds. // There can be lot of other 'Success!' messages that might trigger this incorrectly. + // @todo: look for a less brittle way to detect success. if (output?.includes(`[32mSuccess!`)) { job?.setIsSuccess(); @@ -62,7 +63,7 @@ export default function showMainTerminalHelperMessages( if (output?.includes('error looking up cgroup')) { vscode.window.showErrorMessage( - 'You can probably fix this failed build with rm ~/.circleci/build_agent_settings.json' + 'You can probably fix this failed build by running this on your local machine: rm ~/.circleci/build_agent_settings.json' ); } } From c2c9b8ffcec4660ac607fd67bceeda64fd418f7e Mon Sep 17 00:00:00 2001 From: Ryan Kienstra Date: Thu, 6 Jan 2022 11:51:13 -0600 Subject: [PATCH 09/18] Change template literals to simple ' --- src/utils/showMainTerminalHelperMessages.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/showMainTerminalHelperMessages.ts b/src/utils/showMainTerminalHelperMessages.ts index e06fc297..6a3e9947 100644 --- a/src/utils/showMainTerminalHelperMessages.ts +++ b/src/utils/showMainTerminalHelperMessages.ts @@ -70,7 +70,7 @@ export default function showMainTerminalHelperMessages( if (output?.includes(memoryMessage)) { vscode.window.showInformationMessage( - `This may have failed from a lack of Docker memory. You can increase it via Docker Desktop > Preferences > Resources > Advanced > Memory` + 'This may have failed from a lack of Docker memory. You can increase it via Docker Desktop > Preferences > Resources > Advanced > Memory' ); } }); From 57ce33c1dd85d338c034752da3df88f558f066d9 Mon Sep 17 00:00:00 2001 From: Ryan Kienstra Date: Thu, 6 Jan 2022 17:25:22 -0600 Subject: [PATCH 10/18] Use a more helpful error message for not being online --- src/classes/JobProvider.ts | 9 +++++++-- src/utils/prepareConfig.ts | 8 +++++--- src/utils/showMainTerminalHelperMessages.ts | 5 ++--- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/classes/JobProvider.ts b/src/classes/JobProvider.ts index 6b7563d4..b5d8b374 100644 --- a/src/classes/JobProvider.ts +++ b/src/classes/JobProvider.ts @@ -157,11 +157,16 @@ export default class JobProvider } getErrorTreeItems(): vscode.TreeItem[] { + const errorMessage = this.getJobErrorMessage(); + const internetMessage = errorMessage?.includes('connection refused') + ? 'Is your machine connected to the internet? ' + : ''; + switch (this.jobErrorType) { case JobError.dockerNotRunning: return [ new Warning('Error: is Docker running?'), - new vscode.TreeItem(`${this.getJobErrorMessage()}`), + new vscode.TreeItem(errorMessage), new Command('Try Again', `${JOB_TREE_VIEW_ID}.refresh`), ]; case JobError.licenseKey: @@ -183,7 +188,7 @@ export default class JobProvider case JobError.processFile: return [ new Warning('Error processing the CircleCI config:'), - new vscode.TreeItem(this.getJobErrorMessage()), + new vscode.TreeItem(`${internetMessage}${errorMessage}`), new Command('Try Again', PROCESS_TRY_AGAIN_COMMAND), ]; default: diff --git a/src/utils/prepareConfig.ts b/src/utils/prepareConfig.ts index 9a5da79a..793e5f25 100644 --- a/src/utils/prepareConfig.ts +++ b/src/utils/prepareConfig.ts @@ -46,10 +46,12 @@ export default function prepareConfig( } catch (e) { processError = (e as ErrorWithMessage)?.message; if (!suppressMessage) { + const message = (e as ErrorWithMessage)?.message; + const internetMessage = message?.includes('connection refused') + ? 'Is your machine connected to the internet? ' + : ''; vscode.window.showErrorMessage( - `There was an error processing the CircleCI config: ${ - (e as ErrorWithMessage)?.message - }` + `${internetMessage}There was an error processing the CircleCI config: ${message}` ); } diff --git a/src/utils/showMainTerminalHelperMessages.ts b/src/utils/showMainTerminalHelperMessages.ts index 6a3e9947..92674bea 100644 --- a/src/utils/showMainTerminalHelperMessages.ts +++ b/src/utils/showMainTerminalHelperMessages.ts @@ -15,7 +15,6 @@ export default function showMainTerminalHelperMessages( doesJobCreateDynamicConfig: boolean ): cp.ChildProcessWithoutNullStreams { const memoryMessage = 'Exited with code exit status 127'; - const process = cp.spawn( '/bin/sh', [ @@ -37,7 +36,7 @@ export default function showMainTerminalHelperMessages( // This should be the final 'Success!' message when a job succeeds. // There can be lot of other 'Success!' messages that might trigger this incorrectly. - // @todo: look for a less brittle way to detect success. + // @todo: look for a more reliable way to detect success. if (output?.includes(`[32mSuccess!`)) { job?.setIsSuccess(); @@ -63,7 +62,7 @@ export default function showMainTerminalHelperMessages( if (output?.includes('error looking up cgroup')) { vscode.window.showErrorMessage( - 'You can probably fix this failed build by running this on your local machine: rm ~/.circleci/build_agent_settings.json' + 'You can probably fix this failed job by running this on your local machine: rm ~/.circleci/build_agent_settings.json' ); } } From 650dfd5d05ae9b2929e582f8e24e58561b7d835e Mon Sep 17 00:00:00 2001 From: Ryan Kienstra Date: Thu, 6 Jan 2022 21:00:30 -0600 Subject: [PATCH 11/18] Stop committing the images when the job succeeds or fails There's no need to keep committing, as the job isn't running anymore. --- ...erMessages.ts => handleSuccessAndFailure.ts} | 5 ++++- src/utils/runJob.ts | 17 ++++++++++------- src/utils/uncommittedWarning.ts | 2 +- 3 files changed, 15 insertions(+), 9 deletions(-) rename src/utils/{showMainTerminalHelperMessages.ts => handleSuccessAndFailure.ts} (94%) diff --git a/src/utils/showMainTerminalHelperMessages.ts b/src/utils/handleSuccessAndFailure.ts similarity index 94% rename from src/utils/showMainTerminalHelperMessages.ts rename to src/utils/handleSuccessAndFailure.ts index 92674bea..fbd099f7 100644 --- a/src/utils/showMainTerminalHelperMessages.ts +++ b/src/utils/handleSuccessAndFailure.ts @@ -8,10 +8,11 @@ import getConfigFromPath from './getConfigFromPath'; import getDynamicConfigFilePath from './getDynamicConfigFilePath'; import getSpawnOptions from './getSpawnOptions'; -export default function showMainTerminalHelperMessages( +export default function handleSuccessAndFailure( context: vscode.ExtensionContext, jobProvider: JobProvider, job: Job | undefined, + commitProcess: cp.ChildProcess, doesJobCreateDynamicConfig: boolean ): cp.ChildProcessWithoutNullStreams { const memoryMessage = 'Exited with code exit status 127'; @@ -39,6 +40,7 @@ export default function showMainTerminalHelperMessages( // @todo: look for a more reliable way to detect success. if (output?.includes(`[32mSuccess!`)) { job?.setIsSuccess(); + commitProcess.kill(); if (doesJobCreateDynamicConfig) { jobProvider.refresh(); @@ -59,6 +61,7 @@ export default function showMainTerminalHelperMessages( if (output?.includes('Task failed')) { job?.setIsFailure(); jobProvider.refresh(job); + commitProcess.kill(); if (output?.includes('error looking up cgroup')) { vscode.window.showErrorMessage( diff --git a/src/utils/runJob.ts b/src/utils/runJob.ts index b2aecddf..2ad3a992 100644 --- a/src/utils/runJob.ts +++ b/src/utils/runJob.ts @@ -15,7 +15,7 @@ import getLatestCommittedImage from './getLatestCommittedImage'; import getLocalVolumePath from './getLocalVolumePath'; import getProcessFilePath from './getProcessFilePath'; import getTerminalName from './getTerminalName'; -import showMainTerminalHelperMessages from './showMainTerminalHelperMessages'; +import handleSuccessAndFailure from './handleSuccessAndFailure'; import showFinalTerminalHelperMessages from './showFinalTerminalHelperMessages'; import JobClass from '../classes/Job'; import { @@ -102,16 +102,18 @@ export default async function runJob( } -v ${volume} --debug` ); - const helperMessagesProcess = showMainTerminalHelperMessages( + const committedImageRepo = `${COMMITTED_IMAGE_NAMESPACE}/${jobName}`; + + const jobImage = getImageFromJob(jobInConfig); + const commitProcess = commitContainer(jobImage, committedImageRepo); + + const helperMessagesProcess = handleSuccessAndFailure( context, jobProvider, job, + commitProcess, doesJobCreateDynamicConfig(jobInConfig) ); - const committedImageRepo = `${COMMITTED_IMAGE_NAMESPACE}/${jobName}`; - - const jobImage = getImageFromJob(jobInConfig); - const commitProcess = commitContainer(jobImage, committedImageRepo); const debuggingTerminal = vscode.window.createTerminal({ name: getDebuggingTerminalName(jobName), @@ -138,6 +140,8 @@ export default async function runJob( let finalTerminal: vscode.Terminal; vscode.window.onDidCloseTerminal(async (closedTerminal) => { + commitProcess.kill(); + if ( closedTerminal.name !== debuggingTerminal.name || !closedTerminal?.exitStatus?.code @@ -145,7 +149,6 @@ export default async function runJob( return; } - commitProcess.kill(); if (finalTerminal || areTerminalsClosed(terminal, debuggingTerminal)) { return; } diff --git a/src/utils/uncommittedWarning.ts b/src/utils/uncommittedWarning.ts index 12dfc6b7..660bafdc 100644 --- a/src/utils/uncommittedWarning.ts +++ b/src/utils/uncommittedWarning.ts @@ -30,7 +30,7 @@ export default function uncommittedWarning( .filter( (line: string) => !!line?.trim() && - !line.includes('.circleci/config.yml') && + !line.startsWith('.circleci/config.yml') && !line.includes('.vscode/') ) .join(', '); From 3dbae2abb738bece97d083d10dfb36c8bcfed626 Mon Sep 17 00:00:00 2001 From: Ryan Kienstra Date: Thu, 6 Jan 2022 21:10:25 -0600 Subject: [PATCH 12/18] Correct an error from .startsWith() The data can start with M, like: M .circleci/config.yml so .startsWith('.circleci/config.yml') will be false. --- src/utils/uncommittedWarning.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/uncommittedWarning.ts b/src/utils/uncommittedWarning.ts index 660bafdc..51372e64 100644 --- a/src/utils/uncommittedWarning.ts +++ b/src/utils/uncommittedWarning.ts @@ -30,7 +30,7 @@ export default function uncommittedWarning( .filter( (line: string) => !!line?.trim() && - !line.startsWith('.circleci/config.yml') && + !line.match(/\s\.circleci\/config\.yml/) && !line.includes('.vscode/') ) .join(', '); From 9403ff99d6ca31f767c0cec3009810c3a68070b2 Mon Sep 17 00:00:00 2001 From: Ryan Kienstra Date: Thu, 6 Jan 2022 21:15:58 -0600 Subject: [PATCH 13/18] Add a comment about why the config.yml is in the conditional --- src/utils/uncommittedWarning.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/uncommittedWarning.ts b/src/utils/uncommittedWarning.ts index 51372e64..4886b830 100644 --- a/src/utils/uncommittedWarning.ts +++ b/src/utils/uncommittedWarning.ts @@ -30,7 +30,7 @@ export default function uncommittedWarning( .filter( (line: string) => !!line?.trim() && - !line.match(/\s\.circleci\/config\.yml/) && + !line.match(/\s\.circleci\/config\.yml/) && // The file should not start with .circleci/config.yml, as edits to that will appear in Local CI. !line.includes('.vscode/') ) .join(', '); From 1a6763b4b8f27f1ebf2ccdfb4260c5c07bf71a15 Mon Sep 17 00:00:00 2001 From: Ryan Kienstra Date: Fri, 7 Jan 2022 20:55:50 -0600 Subject: [PATCH 14/18] Prevent killing the process when any terminal closes There could be a non-Local CI terminal that closes, and that shouldn't trigger killing the commitProcess. --- src/utils/handleSuccessAndFailure.ts | 34 +++++++++++++++++++++++++--- src/utils/runJob.ts | 15 +++++++++--- 2 files changed, 43 insertions(+), 6 deletions(-) diff --git a/src/utils/handleSuccessAndFailure.ts b/src/utils/handleSuccessAndFailure.ts index fbd099f7..ec970007 100644 --- a/src/utils/handleSuccessAndFailure.ts +++ b/src/utils/handleSuccessAndFailure.ts @@ -15,7 +15,6 @@ export default function handleSuccessAndFailure( commitProcess: cp.ChildProcess, doesJobCreateDynamicConfig: boolean ): cp.ChildProcessWithoutNullStreams { - const memoryMessage = 'Exited with code exit status 127'; const process = cp.spawn( '/bin/sh', [ @@ -64,13 +63,42 @@ export default function handleSuccessAndFailure( commitProcess.kill(); if (output?.includes('error looking up cgroup')) { + const moreInformationText = 'More information'; vscode.window.showErrorMessage( - 'You can probably fix this failed job by running this on your local machine: rm ~/.circleci/build_agent_settings.json' + 'You can probably fix this failed job by running this on your local machine: rm ~/.circleci/build_agent_settings.json', + { detail: 'Possible solution' }, + moreInformationText + ).then((clicked) => { + if (clicked === moreInformationText) { + vscode.env.openExternal(vscode.Uri.parse('https://github.com/CircleCI-Public/circleci-cli/issues/589#issuecomment-1005865018')); + } + }); + } + + if (output?.includes('mkdir /host_mnt/private/tmp/local-ci/volume: no such file or directory')) { + vscode.window.showErrorMessage( + `Restarting Docker Desktop should fix that error 'no such file or directory' error, though that's not fun`, + { detail: 'Possible solution' }, ); } + + } + + if (output?.includes('compinit: insecure directories')) { + const possibleSolutionText = 'See a possible solution'; + vscode.window.showInformationMessage( + `Here's a possible solution to the compinit error:`, + { detail: 'Possible solution' }, + possibleSolutionText + ) + .then((clicked) => { + if (clicked === possibleSolutionText) { + vscode.env.openExternal(vscode.Uri.parse('https://github.com/zsh-users/zsh-completions/issues/680#issuecomment-864906013')); + } + }); } - if (output?.includes(memoryMessage)) { + if (output?.includes('Exited with code exit status 127')) { vscode.window.showInformationMessage( 'This may have failed from a lack of Docker memory. You can increase it via Docker Desktop > Preferences > Resources > Advanced > Memory' ); diff --git a/src/utils/runJob.ts b/src/utils/runJob.ts index 2ad3a992..c8ac9852 100644 --- a/src/utils/runJob.ts +++ b/src/utils/runJob.ts @@ -139,9 +139,19 @@ export default async function runJob( debuggingTerminal.sendText('cd ~/'); let finalTerminal: vscode.Terminal; - vscode.window.onDidCloseTerminal(async (closedTerminal) => { - commitProcess.kill(); + vscode.window.onDidCloseTerminal((closedTerminal) => { + const terminalNames = [ + getTerminalName(jobName), + debuggingTerminal.name, + finalTerminal?.name, + ]; + + if (terminalNames.includes(closedTerminal.name)) { + commitProcess.kill(); + } + }); + vscode.window.onDidCloseTerminal(async (closedTerminal) => { if ( closedTerminal.name !== debuggingTerminal.name || !closedTerminal?.exitStatus?.code @@ -186,7 +196,6 @@ export default async function runJob( vscode.window.onDidCloseTerminal(() => { if (areTerminalsClosed(terminal, debuggingTerminal, finalTerminal)) { - commitProcess.kill(); helperMessagesProcess.kill(); cleanUpCommittedImages(committedImageRepo); } From c649e5a867c26fa4fd5156bb79601918905deafa Mon Sep 17 00:00:00 2001 From: Ryan Kienstra Date: Fri, 7 Jan 2022 21:06:08 -0600 Subject: [PATCH 15/18] Fix several linting issues --- src/utils/handleSuccessAndFailure.ts | 58 +++++++++++++++++----------- 1 file changed, 36 insertions(+), 22 deletions(-) diff --git a/src/utils/handleSuccessAndFailure.ts b/src/utils/handleSuccessAndFailure.ts index ec970007..b9f0eac6 100644 --- a/src/utils/handleSuccessAndFailure.ts +++ b/src/utils/handleSuccessAndFailure.ts @@ -64,38 +64,52 @@ export default function handleSuccessAndFailure( if (output?.includes('error looking up cgroup')) { const moreInformationText = 'More information'; - vscode.window.showErrorMessage( - 'You can probably fix this failed job by running this on your local machine: rm ~/.circleci/build_agent_settings.json', - { detail: 'Possible solution' }, - moreInformationText - ).then((clicked) => { - if (clicked === moreInformationText) { - vscode.env.openExternal(vscode.Uri.parse('https://github.com/CircleCI-Public/circleci-cli/issues/589#issuecomment-1005865018')); - } - }); + vscode.window + .showErrorMessage( + 'You can probably fix this failed job by running this on your local machine: rm ~/.circleci/build_agent_settings.json', + { detail: 'Possible solution' }, + moreInformationText + ) + .then((clicked) => { + if (clicked === moreInformationText) { + vscode.env.openExternal( + vscode.Uri.parse( + 'https://github.com/CircleCI-Public/circleci-cli/issues/589#issuecomment-1005865018' + ) + ); + } + }); } - if (output?.includes('mkdir /host_mnt/private/tmp/local-ci/volume: no such file or directory')) { + if ( + output?.includes( + 'mkdir /host_mnt/private/tmp/local-ci/volume: no such file or directory' + ) + ) { vscode.window.showErrorMessage( `Restarting Docker Desktop should fix that error 'no such file or directory' error, though that's not fun`, - { detail: 'Possible solution' }, + { detail: 'Possible solution' } ); } - } if (output?.includes('compinit: insecure directories')) { const possibleSolutionText = 'See a possible solution'; - vscode.window.showInformationMessage( - `Here's a possible solution to the compinit error:`, - { detail: 'Possible solution' }, - possibleSolutionText - ) - .then((clicked) => { - if (clicked === possibleSolutionText) { - vscode.env.openExternal(vscode.Uri.parse('https://github.com/zsh-users/zsh-completions/issues/680#issuecomment-864906013')); - } - }); + vscode.window + .showInformationMessage( + `Here's a possible solution to the compinit error:`, + { detail: 'Possible solution' }, + possibleSolutionText + ) + .then((clicked) => { + if (clicked === possibleSolutionText) { + vscode.env.openExternal( + vscode.Uri.parse( + 'https://github.com/zsh-users/zsh-completions/issues/680#issuecomment-864906013' + ) + ); + } + }); } if (output?.includes('Exited with code exit status 127')) { From 2e18759d735d0a578bf42b51d8f892de3711b635 Mon Sep 17 00:00:00 2001 From: Ryan Kienstra Date: Fri, 7 Jan 2022 21:18:09 -0600 Subject: [PATCH 16/18] Store the job name in a const There could have been a bug where job.getName() no longer returned a name. --- src/utils/handleSuccessAndFailure.ts | 5 +++-- src/utils/prepareConfig.ts | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/utils/handleSuccessAndFailure.ts b/src/utils/handleSuccessAndFailure.ts index b9f0eac6..5ff8afeb 100644 --- a/src/utils/handleSuccessAndFailure.ts +++ b/src/utils/handleSuccessAndFailure.ts @@ -15,15 +15,16 @@ export default function handleSuccessAndFailure( commitProcess: cp.ChildProcess, doesJobCreateDynamicConfig: boolean ): cp.ChildProcessWithoutNullStreams { + const jobName = job?.getJobName(); const process = cp.spawn( '/bin/sh', [ '-c', `${GET_PICARD_CONTAINER_FUNCTION} - until [[ -n $(get_picard_container ${job?.getJobName()}) ]]; do + until [[ -n $(get_picard_container ${jobName}) ]]; do sleep 2 done - docker logs --follow $(get_picard_container ${job?.getJobName()})`, + docker logs --follow $(get_picard_container ${jobName})`, ], getSpawnOptions() ); diff --git a/src/utils/prepareConfig.ts b/src/utils/prepareConfig.ts index 793e5f25..29045465 100644 --- a/src/utils/prepareConfig.ts +++ b/src/utils/prepareConfig.ts @@ -47,11 +47,11 @@ export default function prepareConfig( processError = (e as ErrorWithMessage)?.message; if (!suppressMessage) { const message = (e as ErrorWithMessage)?.message; - const internetMessage = message?.includes('connection refused') + const internetErrorMessage = message?.includes('connection refused') ? 'Is your machine connected to the internet? ' : ''; vscode.window.showErrorMessage( - `${internetMessage}There was an error processing the CircleCI config: ${message}` + `${internetErrorMessage}There was an error processing the CircleCI config: ${message}` ); } From bd9b369cc07399d4f2dca55557b0f855f0279949 Mon Sep 17 00:00:00 2001 From: Ryan Kienstra Date: Fri, 7 Jan 2022 21:38:30 -0600 Subject: [PATCH 17/18] Refactor the internet error message logic Instead of the hack of ending the message with ' ' before concatenation. --- src/classes/JobProvider.ts | 14 ++++++++++---- src/utils/prepareConfig.ts | 12 ++++++++---- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/classes/JobProvider.ts b/src/classes/JobProvider.ts index b5d8b374..3a102b24 100644 --- a/src/classes/JobProvider.ts +++ b/src/classes/JobProvider.ts @@ -158,9 +158,6 @@ export default class JobProvider getErrorTreeItems(): vscode.TreeItem[] { const errorMessage = this.getJobErrorMessage(); - const internetMessage = errorMessage?.includes('connection refused') - ? 'Is your machine connected to the internet? ' - : ''; switch (this.jobErrorType) { case JobError.dockerNotRunning: @@ -188,7 +185,16 @@ export default class JobProvider case JobError.processFile: return [ new Warning('Error processing the CircleCI config:'), - new vscode.TreeItem(`${internetMessage}${errorMessage}`), + new vscode.TreeItem( + [ + errorMessage?.includes('connection refused') + ? 'Is your machine connected to the internet?' + : '', + errorMessage, + ] + .filter((message) => !!message) + .join(' ') + ), new Command('Try Again', PROCESS_TRY_AGAIN_COMMAND), ]; default: diff --git a/src/utils/prepareConfig.ts b/src/utils/prepareConfig.ts index 29045465..7df50a08 100644 --- a/src/utils/prepareConfig.ts +++ b/src/utils/prepareConfig.ts @@ -47,11 +47,15 @@ export default function prepareConfig( processError = (e as ErrorWithMessage)?.message; if (!suppressMessage) { const message = (e as ErrorWithMessage)?.message; - const internetErrorMessage = message?.includes('connection refused') - ? 'Is your machine connected to the internet? ' - : ''; vscode.window.showErrorMessage( - `${internetErrorMessage}There was an error processing the CircleCI config: ${message}` + [ + message?.includes('connection refused') + ? 'Is your machine connected to the internet? ' + : '', + `There was an error processing the CircleCI config: ${message}`, + ] + .filter((message) => !!message) + .join(' ') ); } From 6a89e15dd7bd330786e405a43042cd66933a02f9 Mon Sep 17 00:00:00 2001 From: Ryan Kienstra Date: Fri, 7 Jan 2022 21:57:18 -0600 Subject: [PATCH 18/18] Bump version to 1.4.3, add CHANGELOG --- CHANGELOG.md | 8 ++++++++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 647b7da0..832abd48 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Change Log +## 1.4.3 - 7 January 2022 + +### Added +- Add several helper notices, like for internet connection. [#73](https://github.com/getlocalci/local-ci/pull/73/) + +### Fixed +- Stop committing images when the job succeeds or fails. [#73](https://github.com/getlocalci/local-ci/pull/73/) + ## 1.4.2 - 4 January 2022 ### Added diff --git a/package-lock.json b/package-lock.json index 14c347c8..2ce42cc8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "local-ci", - "version": "1.4.2", + "version": "1.4.3", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "local-ci", - "version": "1.4.2", + "version": "1.4.3", "hasInstallScript": true, "license": "GPL-2.0-or-later", "os": [ diff --git a/package.json b/package.json index 7a1da0ef..0b9572df 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "local-ci", "displayName": "Local CI", "description": "Debug CircleCI® workflows locally, with Bash access during and after. Free preview, then paid.", - "version": "1.4.2", + "version": "1.4.3", "publisher": "LocalCI", "contributors": [ "Ryan Kienstra"