Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/cool-stingrays-invent.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@trigger.dev/cli": patch
---

allow users to update trigger-dev packages to a specific version
9 changes: 6 additions & 3 deletions packages/cli/src/cli/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,13 @@ program

program
.command("update")
.description("Updates all @trigger.dev/* packages to their latest compatible versions")
.description(
"Updates all @trigger.dev/* packages to their latest compatible versions or the specified version"
)
.argument("[path]", "The path to the directory that contains the package.json file", ".")
.action(async (path) => {
await updateCommand(path);
.option("--to <version tag>", "The version to update to (ex: 2.1.4)", "latest")
.action(async (path, options) => {
await updateCommand(path, options);
});

program
Expand Down
67 changes: 54 additions & 13 deletions packages/cli/src/commands/update.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,24 @@ import { run, RunOptions } from "npm-check-updates";
import { installDependencies } from "../utils/installDependencies.js";
import { readJSONFileSync, writeJSONFile } from "../utils/fileSystem.js";
import { logger } from "../utils/logger.js";
import { z } from "zod";

export const UpdateCommandOptionsSchema = z.object({
to: z.string().optional(),
});

export type UpdateCommandOptions = z.infer<typeof UpdateCommandOptionsSchema>;

type NcuRunOptionTarget = "latest" | `@${string}`;

export async function updateCommand(projectPath: string, anyOptions: any) {
const parseRes = UpdateCommandOptionsSchema.safeParse(anyOptions);
if (!parseRes.success) {
logger.error(parseRes.error.message);
return;
}
const options = parseRes.data;

export async function updateCommand(projectPath: string) {
const triggerDevPackage = "@trigger.dev";
const packageJSONPath = path.join(projectPath, "package.json");
const packageData = readJSONFileSync(packageJSONPath);
Expand All @@ -27,12 +43,14 @@ export async function updateCommand(projectPath: string) {
};
});

const targetVersion = getTargetVersion(options.to);

// Use npm-check-updates to get updated dependency versions
const ncuOptions: RunOptions = {
packageData,
upgrade: true,
jsonUpgraded: true,
target: "latest",
target: targetVersion,
};

// Can either give a json like package.json or just with deps and their new versions
Expand Down Expand Up @@ -69,6 +87,39 @@ export async function updateCommand(projectPath: string) {
return;
}

let applyUpdates = targetVersion !== "latest";

if (targetVersion === "latest") {
applyUpdates = await hasUserConfirmed(packagesToUpdate, packageMaps, updatedDependencies);
}

if (applyUpdates) {
const newPackageJSON = packageData;
packagesToUpdate.forEach((packageName) => {
const tmp = packageMaps[packageName];
if (tmp) {
newPackageJSON[tmp.type][packageName] = updatedDependencies[packageName];
}
});
await writeJSONFile(packageJSONPath, newPackageJSON);
await installDependencies(projectPath);
}
}

// expects a version number, or latest.
// if version number is specified, prepend it with '@' for ncu.
function getTargetVersion(toVersion?: string): NcuRunOptionTarget {
if (!toVersion) {
return "latest";
}
return toVersion === "latest" ? "latest" : `@${toVersion}`;
}

async function hasUserConfirmed(
packagesToUpdate: string[],
packageMaps: { [x: string]: { type: string; version: string } },
updatedDependencies: { [x: string]: any }
): Promise<boolean> {
// Inform the user of the dependencies that can be updated
console.log("\nNewer versions found for the following packages:");
console.table(
Expand All @@ -86,15 +137,5 @@ export async function updateCommand(projectPath: string) {
message: "Do you want to update these packages in package.json and re-install dependencies?",
});

if (confirm) {
const newPackageJSON = packageData;
packagesToUpdate.forEach((packageName) => {
const tmp = packageMaps[packageName];
if (tmp) {
newPackageJSON[tmp.type][packageName] = updatedDependencies[packageName];
}
});
await writeJSONFile(packageJSONPath, newPackageJSON);
await installDependencies(projectPath);
}
return confirm;
}