Improve the update CLI command and fix missing tsconfig.json error (#1315)

* Fixes for CLI update command, and make the hide the "whoami" command output when running in dev

* Fix an issue where a missing tsconfig.json file would throw an error on dev/deploy

* Don’t show latest CLI warning when using a prerelease

* Only print CLI update required message when update is embedded

* Strip out TRIGGER\_ keys when using syncEnvVars, to prevent deploy errors
This commit is contained in:
Eric Allam
2024-09-18 11:07:09 +01:00
committed by GitHub
parent 56a5b58849
commit 3d53d4c086
11 changed files with 98 additions and 38 deletions
+6
View File
@@ -0,0 +1,6 @@
---
"trigger.dev": patch
"@trigger.dev/core": patch
---
Fix an issue where a missing tsconfig.json file would throw an error on dev/deploy
+5
View File
@@ -0,0 +1,5 @@
---
"trigger.dev": patch
---
Fixes for CLI update command, and make the hide the "whoami" command output when running in dev.
+5
View File
@@ -0,0 +1,5 @@
---
"@trigger.dev/build": patch
---
Strip out TRIGGER\_ keys when using syncEnvVars, to prevent deploy errors
@@ -63,6 +63,8 @@ const UNSYNCABLE_ENV_VARS = [
"_", "_",
]; ];
const UNSYNCABLE_ENV_VARS_PREFIXES = ["TRIGGER_"];
export type SyncEnvVarsFunction = (params: SyncEnvVarsParams) => SyncEnvVarsResult; export type SyncEnvVarsFunction = (params: SyncEnvVarsParams) => SyncEnvVarsResult;
export type SyncEnvVarsOptions = { export type SyncEnvVarsOptions = {
@@ -98,6 +100,11 @@ export function syncEnvVars(fn: SyncEnvVarsFunction, options?: SyncEnvVarsOption
return acc; return acc;
} }
// Strip out any TRIGGER_ prefix env vars
if (UNSYNCABLE_ENV_VARS_PREFIXES.some((prefix) => key.startsWith(prefix))) {
return acc;
}
acc[key] = value; acc[key] = value;
return acc; return acc;
}, },
+1
View File
@@ -51,6 +51,7 @@ export async function devCommand(options: DevCommandOptions) {
const authorization = await login({ const authorization = await login({
embedded: true, embedded: true,
silent: true,
defaultApiUrl: options.apiUrl, defaultApiUrl: options.apiUrl,
profile: options.profile, profile: options.profile,
}); });
+9 -2
View File
@@ -59,12 +59,18 @@ export type LoginOptions = {
defaultApiUrl?: string; defaultApiUrl?: string;
embedded?: boolean; embedded?: boolean;
profile?: string; profile?: string;
silent?: boolean;
}; };
export async function login(options?: LoginOptions): Promise<LoginResult> { export async function login(options?: LoginOptions): Promise<LoginResult> {
return await tracer.startActiveSpan("login", async (span) => { return await tracer.startActiveSpan("login", async (span) => {
try { try {
const opts = { defaultApiUrl: "https://api.trigger.dev", embedded: false, ...options }; const opts = {
defaultApiUrl: "https://api.trigger.dev",
embedded: false,
silent: false,
...options,
};
span.setAttributes({ span.setAttributes({
"cli.config.apiUrl": opts.defaultApiUrl, "cli.config.apiUrl": opts.defaultApiUrl,
@@ -111,7 +117,8 @@ export async function login(options?: LoginOptions): Promise<LoginResult> {
skipTelemetry: !span.isRecording(), skipTelemetry: !span.isRecording(),
logLevel: logger.loggerLevel, logLevel: logger.loggerLevel,
}, },
true true,
opts.silent
); );
if (!whoAmIResult.success) { if (!whoAmIResult.success) {
+39 -24
View File
@@ -43,7 +43,7 @@ export function configureUpdateCommand(program: Command) {
const triggerPackageFilter = /^@trigger\.dev/; const triggerPackageFilter = /^@trigger\.dev/;
export async function updateCommand(dir: string, options: UpdateCommandOptions) { export async function updateCommand(dir: string, options: UpdateCommandOptions) {
await updateTriggerPackages(dir, options); await updateTriggerPackages(dir, options, false);
} }
export async function updateTriggerPackages( export async function updateTriggerPackages(
@@ -74,7 +74,7 @@ export async function updateTriggerPackages(
const newCliVersion = await updateCheck(); const newCliVersion = await updateCheck();
if (newCliVersion) { if (newCliVersion && !cliVersion.startsWith("0.0.0")) {
prettyWarning( prettyWarning(
"You're not running the latest CLI version, please consider updating ASAP", "You're not running the latest CLI version, please consider updating ASAP",
`Current: ${cliVersion}\nLatest: ${newCliVersion}`, `Current: ${cliVersion}\nLatest: ${newCliVersion}`,
@@ -127,24 +127,30 @@ export async function updateTriggerPackages(
if (mismatches.length === 0) { if (mismatches.length === 0) {
if (!embedded) { if (!embedded) {
outro(`Nothing to do${newCliVersion ? " ..but you should really update your CLI!" : ""}`); outro(`Nothing to update${newCliVersion ? " ..but you should really update your CLI!" : ""}`);
return hasOutput; return hasOutput;
} }
return hasOutput; return hasOutput;
} }
if (isDowngrade) { if (embedded) {
prettyError("Some of the installed @trigger.dev packages are newer than your CLI version"); if (isDowngrade) {
} else { prettyError("Some of the installed @trigger.dev packages are newer than your CLI version");
prettyWarning( } else {
"Mismatch between your CLI version and installed packages", if (embedded) {
"We recommend pinned versions for guaranteed compatibility" prettyWarning(
); "Mismatch between your CLI version and installed packages",
"We recommend pinned versions for guaranteed compatibility"
);
}
}
} }
if (!hasTTY) { if (!hasTTY) {
// Running in CI with version mismatch detected // Running in CI with version mismatch detected
outro("Deploy failed"); if (embedded) {
outro("Deploy failed");
}
console.log( console.log(
`ERROR: Version mismatch detected while running in CI. This won't end well. Aborting. `ERROR: Version mismatch detected while running in CI. This won't end well. Aborting.
@@ -162,8 +168,7 @@ export async function updateTriggerPackages(
} }
// WARNING: We can only start accepting user input once we know this is a TTY, otherwise, the process will exit with an error in CI // WARNING: We can only start accepting user input once we know this is a TTY, otherwise, the process will exit with an error in CI
if (isDowngrade && embedded) {
if (isDowngrade) {
printUpdateTable("Versions", mismatches, cliVersion, "installed", "CLI"); printUpdateTable("Versions", mismatches, cliVersion, "installed", "CLI");
outro("CLI update required!"); outro("CLI update required!");
@@ -187,14 +192,20 @@ export async function updateTriggerPackages(
if (!userWantsToUpdate) { if (!userWantsToUpdate) {
if (requireUpdate) { if (requireUpdate) {
outro("You shall not pass!"); if (embedded) {
outro("You shall not pass!");
logger.log( logger.log(
`${chalkError( `${chalkError(
"X Error:" "X Error:"
)} Update required: Version mismatches are a common source of bugs and errors. Please update or use \`--skip-update-check\` at your own risk.\n` )} Update required: Version mismatches are a common source of bugs and errors. Please update or use \`--skip-update-check\` at your own risk.\n`
); );
process.exit(1); process.exit(1);
} else {
outro("No updates applied");
process.exit(0);
}
} }
if (!embedded) { if (!embedded) {
@@ -205,7 +216,7 @@ export async function updateTriggerPackages(
} }
const installSpinner = spinner(); const installSpinner = spinner();
installSpinner.start("Writing new package.json file"); installSpinner.start("Updating dependencies in package.json");
// Backup package.json // Backup package.json
const packageJsonBackupPath = `${packageJsonPath}.bak`; const packageJsonBackupPath = `${packageJsonPath}.bak`;
@@ -235,12 +246,16 @@ export async function updateTriggerPackages(
const packageManager = await detectPackageManager(projectPath); const packageManager = await detectPackageManager(projectPath);
try { try {
installSpinner.message(`Installing new package versions with ${packageManager}`); installSpinner.message(
`Installing new package versions${packageManager ? ` with ${packageManager.name}` : ""}`
);
await installDependencies({ cwd: projectPath }); await installDependencies({ cwd: projectPath, silent: true });
} catch (error) { } catch (error) {
installSpinner.stop( installSpinner.stop(
`Failed to install new package versions${packageManager ? ` with ${packageManager}` : ""}` `Failed to install new package versions${
packageManager ? ` with ${packageManager.name}` : ""
}`
); );
// Remove exit handler in case of failure // Remove exit handler in case of failure
+14 -9
View File
@@ -51,27 +51,32 @@ export async function whoAmICommand(options: unknown) {
export async function whoAmI( export async function whoAmI(
options?: WhoamiCommandOptions, options?: WhoamiCommandOptions,
embedded: boolean = false embedded: boolean = false,
silent: boolean = false
): Promise<WhoAmIResult> { ): Promise<WhoAmIResult> {
if (!embedded) { if (!embedded) {
intro(`Displaying your account details [${options?.profile ?? "default"}]`); intro(`Displaying your account details [${options?.profile ?? "default"}]`);
} }
const loadingSpinner = spinner(); const loadingSpinner = spinner();
loadingSpinner.start("Checking your account details");
if (!silent) {
loadingSpinner.start("Checking your account details");
}
const authentication = await isLoggedIn(options?.profile); const authentication = await isLoggedIn(options?.profile);
if (!authentication.ok) { if (!authentication.ok) {
if (authentication.error === "fetch failed") { if (authentication.error === "fetch failed") {
loadingSpinner.stop("Fetch failed. Platform down?"); !silent && loadingSpinner.stop("Fetch failed. Platform down?");
} else { } else {
if (embedded) { if (embedded) {
loadingSpinner.stop( !silent &&
`Failed to check account details. You may want to run \`trigger.dev logout --profile ${ loadingSpinner.stop(
options?.profile ?? "default" `Failed to check account details. You may want to run \`trigger.dev logout --profile ${
}\` and try again.` options?.profile ?? "default"
); }\` and try again.`
);
} else { } else {
loadingSpinner.stop( loadingSpinner.stop(
`You must login first. Use \`trigger.dev login --profile ${ `You must login first. Use \`trigger.dev login --profile ${
@@ -110,7 +115,7 @@ URL: ${chalkLink(authentication.auth.apiUrl)}
`Account details [${authentication.profile}]` `Account details [${authentication.profile}]`
); );
} else { } else {
loadingSpinner.stop(`Retrieved your account details for ${userData.data.email}`); !silent && loadingSpinner.stop(`Retrieved your account details for ${userData.data.email}`);
} }
return userData; return userData;
+10 -2
View File
@@ -138,7 +138,7 @@ async function resolveConfig(
warn = true warn = true
): Promise<ResolvedConfig> { ): Promise<ResolvedConfig> {
const packageJsonPath = await resolvePackageJSON(cwd); const packageJsonPath = await resolvePackageJSON(cwd);
const tsconfigPath = await resolveTSConfig(cwd); const tsconfigPath = await safeResolveTsConfig(cwd);
const lockfilePath = await resolveLockfile(cwd); const lockfilePath = await resolveLockfile(cwd);
const workspaceDir = await findWorkspaceDir(cwd); const workspaceDir = await findWorkspaceDir(cwd);
@@ -179,7 +179,7 @@ async function resolveConfig(
conditions: [], conditions: [],
}, },
} }
); ) as ResolvedConfig; // TODO: For some reason, without this, there is a weird type error complaining about tsconfigPath being string | nullish, which can't be assigned to string | undefined
return { return {
...mergedConfig, ...mergedConfig,
@@ -188,6 +188,14 @@ async function resolveConfig(
}; };
} }
async function safeResolveTsConfig(cwd: string) {
try {
return await resolveTSConfig(cwd);
} catch {
return undefined;
}
}
const IGNORED_DIRS = ["node_modules", ".git", "dist", "out", "build"]; const IGNORED_DIRS = ["node_modules", ".git", "dist", "out", "build"];
async function autoDetectDirs(workingDir: string): Promise<string[]> { async function autoDetectDirs(workingDir: string): Promise<string[]> {
+1 -1
View File
@@ -31,7 +31,7 @@ export async function resolveFileSources(
} }
await resolveConfigSource(sources, resolvedConfig.workingDir, resolvedConfig.configFile); await resolveConfigSource(sources, resolvedConfig.workingDir, resolvedConfig.configFile);
await resolveConfigSource(sources, resolvedConfig.workingDir, resolvedConfig.tsconfig); await resolveConfigSource(sources, resolvedConfig.workingDir, resolvedConfig.tsconfigPath);
await resolveConfigSource(sources, resolvedConfig.workingDir, resolvedConfig.packageJsonPath); await resolveConfigSource(sources, resolvedConfig.workingDir, resolvedConfig.packageJsonPath);
return sources; return sources;
@@ -24,6 +24,7 @@ export type ResolvedConfig = Prettify<
packageJsonPath: string; packageJsonPath: string;
lockfilePath: string; lockfilePath: string;
configFile?: string; configFile?: string;
tsconfigPath?: string;
resolveEnvVars?: ResolveEnvironmentVariablesFunction; resolveEnvVars?: ResolveEnvironmentVariablesFunction;
instrumentedPackageNames?: string[]; instrumentedPackageNames?: string[];
} }