Skip to content
Closed
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/fix-dotted-keys-logging.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@trigger.dev/core": patch
---

Fix issue where logging objects with keys containing dots resulted in incorrect nested object structure in logs (#1510)
60 changes: 29 additions & 31 deletions apps/webapp/app/components/runs/v3/RunFilters.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -635,7 +635,7 @@ function TasksDropdown({
<SelectProvider value={values("tasks")} setValue={handleChange} virtualFocus={true}>
{trigger}
<SelectPopover
className="min-w-0 max-w-[min(360px,var(--popover-available-width))]"
className="min-w-0 max-w-[min(500px,var(--popover-available-width))]"
hideOnEscape={() => {
if (onClose) {
onClose();
Expand All @@ -655,7 +655,7 @@ function TasksDropdown({
<TaskTriggerSourceIcon source={item.triggerSource} className="size-4 flex-none" />
}
>
<MiddleTruncate text={item.slug}/>
<MiddleTruncate text={item.slug} />
</SelectItem>
))}
</SelectList>
Expand Down Expand Up @@ -896,10 +896,10 @@ function TagsDropdown({
<SelectList>
{filtered.length > 0
? filtered.map((tag, index) => (
<SelectItem key={tag} value={tag}>
{tag}
</SelectItem>
))
<SelectItem key={tag} value={tag}>
{tag}
</SelectItem>
))
: null}
{filtered.length === 0 && fetcher.state !== "loading" && (
<SelectItem disabled>No tags found</SelectItem>
Expand Down Expand Up @@ -981,8 +981,7 @@ function QueuesDropdown({
searchParams.set("query", s);
}
fetcher.load(
`/resources/orgs/${organization.slug}/projects/${project.slug}/env/${
environment.slug
`/resources/orgs/${organization.slug}/projects/${project.slug}/env/${environment.slug
}/queues?${searchParams.toString()}`
);
},
Expand Down Expand Up @@ -1054,20 +1053,20 @@ function QueuesDropdown({
<SelectList>
{filtered.length > 0
? filtered.map((queue) => (
<SelectItem
key={queue.value}
value={queue.value}
icon={
queue.type === "task" ? (
<TaskIcon className="size-4 shrink-0 text-blue-500" />
) : (
<RectangleStackIcon className="size-4 shrink-0 text-purple-500" />
)
}
>
{queue.name}
</SelectItem>
))
<SelectItem
key={queue.value}
value={queue.value}
icon={
queue.type === "task" ? (
<TaskIcon className="size-4 shrink-0 text-blue-500" />
) : (
<RectangleStackIcon className="size-4 shrink-0 text-purple-500" />
)
}
>
{queue.name}
</SelectItem>
))
: null}
{filtered.length === 0 && fetcher.state !== "loading" && (
<SelectItem disabled>No queues found</SelectItem>
Expand Down Expand Up @@ -1243,8 +1242,7 @@ function VersionsDropdown({
searchParams.set("query", s);
}
fetcher.load(
`/resources/orgs/${organization.slug}/projects/${project.slug}/env/${
environment.slug
`/resources/orgs/${organization.slug}/projects/${project.slug}/env/${environment.slug
}/versions?${searchParams.toString()}`
);
},
Expand Down Expand Up @@ -1305,13 +1303,13 @@ function VersionsDropdown({
<SelectList>
{filtered.length > 0
? filtered.map((version) => (
<SelectItem key={version.version} value={version.version}>
<span className="flex items-center gap-2">
<span className="grow truncate">{version.version}</span>
{version.isCurrent ? <Badge variant="extra-small">Current</Badge> : null}
</span>
</SelectItem>
))
<SelectItem key={version.version} value={version.version}>
<span className="flex items-center gap-2">
<span className="grow truncate">{version.version}</span>
{version.isCurrent ? <Badge variant="extra-small">Current</Badge> : null}
</span>
</SelectItem>
))
: null}
{filtered.length === 0 && fetcher.state !== "loading" && (
<SelectItem disabled>No versions found</SelectItem>
Expand Down
4 changes: 2 additions & 2 deletions apps/webapp/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
"@codemirror/view": "6.7.2",
"@conform-to/react": "0.9.2",
"@conform-to/zod": "0.9.2",
"@depot/cli": "0.0.1-cli.2.80.0",
"@depot/cli": "0.0.1-cli.2.101.3",
"@depot/sdk-node": "^1.0.0",
"@electric-sql/react": "^0.3.5",
"@headlessui/react": "^1.7.8",
Expand Down Expand Up @@ -298,4 +298,4 @@
"engines": {
"node": ">=18.19.0 || >=20.6.0"
}
}
}
4 changes: 2 additions & 2 deletions packages/cli-v3/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@
},
"dependencies": {
"@clack/prompts": "0.11.0",
"@depot/cli": "0.0.1-cli.2.80.0",
"@depot/cli": "0.0.1-cli.2.101.3",
"@modelcontextprotocol/sdk": "^1.25.2",
"@opentelemetry/api": "1.9.0",
"@opentelemetry/api-logs": "0.203.0",
Expand Down Expand Up @@ -159,4 +159,4 @@
}
}
}
}
}
47 changes: 34 additions & 13 deletions packages/cli-v3/src/build/buildWorker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ import {
resolvePluginsForContext,
} from "./extensions.js";
import { createExternalsBuildExtension } from "./externals.js";
import { join, relative, sep } from "node:path";
import { join, relative, sep, basename } from "node:path";
import { generateContainerfile } from "../deploy/buildImage.js";
import { writeFile } from "node:fs/promises";
import fsModule from "node:fs/promises";
import { buildManifestToJSON } from "../utilities/buildManifest.js";
import { readPackageJSON } from "pkg-types";
import { writeJSONFile } from "../utilities/fileSystem.js";
Expand Down Expand Up @@ -53,16 +54,16 @@ export async function buildWorker(options: BuildWorkerOptions) {
const buildContext = createBuildContext(options.target, resolvedConfig, {
logger: options.plain
? {
debug: (...args) => console.log(...args),
log: (...args) => console.log(...args),
warn: (...args) => console.log(...args),
progress: (message) => console.log(message),
spinner: (message) => {
const $spinner = spinner({ plain: true });
$spinner.start(message);
return $spinner;
},
}
debug: (...args) => console.log(...args),
log: (...args) => console.log(...args),
warn: (...args) => console.log(...args),
progress: (message) => console.log(message),
spinner: (message) => {
const $spinner = spinner({ plain: true });
$spinner.start(message);
return $spinner;
},
}
: undefined,
});
buildContext.prependExtension(externalsExtension);
Expand Down Expand Up @@ -196,6 +197,7 @@ async function writeDeployFiles({
join(outputPath, "package.json"),
{
...packageJson,
version: "0.0.0", // Strip version for better docker caching
name: packageJson.name ?? "trigger-project",
dependencies: {
...dependencies,
Expand All @@ -208,8 +210,13 @@ async function writeDeployFiles({
true
);

if (resolvedConfig.lockfilePath) {
const lockfileName = basename(resolvedConfig.lockfilePath);
await fsModule.copyFile(resolvedConfig.lockfilePath, join(outputPath, lockfileName));
}

await writeJSONFile(join(outputPath, "build.json"), buildManifestToJSON(buildManifest));
await writeContainerfile(outputPath, buildManifest);
await writeContainerfile(outputPath, buildManifest, resolvedConfig.lockfilePath);
}

async function readProjectPackageJson(packageJsonPath: string) {
Expand All @@ -218,17 +225,31 @@ async function readProjectPackageJson(packageJsonPath: string) {
return packageJson;
}

async function writeContainerfile(outputPath: string, buildManifest: BuildManifest) {
async function writeContainerfile(
outputPath: string,
buildManifest: BuildManifest,
lockfilePath?: string
) {
if (!buildManifest.runControllerEntryPoint || !buildManifest.indexControllerEntryPoint) {
throw new Error("Something went wrong with the build. Aborting deployment. [code 7789]");
}

const packageManager = lockfilePath
? lockfilePath.endsWith("pnpm-lock.yaml")
? ("pnpm" as const)
: lockfilePath.endsWith("yarn.lock")
? ("yarn" as const)
: ("npm" as const)
: undefined;

const containerfile = await generateContainerfile({
runtime: buildManifest.runtime,
entrypoint: buildManifest.runControllerEntryPoint,
build: buildManifest.build,
image: buildManifest.image,
indexScript: buildManifest.indexControllerEntryPoint,
packageManager,
lockfile: lockfilePath ? basename(lockfilePath) : undefined,
});

const containerfilePath = join(outputPath, "Containerfile");
Expand Down
132 changes: 132 additions & 0 deletions packages/cli-v3/src/build/bundle.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import { expect, test, vi, describe, beforeEach, afterEach } from "vitest";
import { bundleWorker } from "./bundle.js";
import * as esbuild from "esbuild";
import { copyFile, mkdir } from "node:fs/promises";
import { shims } from "./packageModules.js";
import { join } from "node:path";

vi.mock("esbuild", () => ({
build: vi.fn(),
context: vi.fn(() => ({
watch: vi.fn(),
dispose: vi.fn(),
})),
}));

vi.mock("node:fs/promises", () => ({
copyFile: vi.fn(),
mkdir: vi.fn(),
writeFile: vi.fn(),
readdir: vi.fn(() => []),
readFile: vi.fn(),
}));

vi.mock("../utilities/fileSystem.js", () => ({
createFile: vi.fn(),
createFileWithStore: vi.fn(),
}));

vi.mock("./entryPoints.js", () => ({
createEntryPointManager: vi.fn(() => ({
entryPoints: ["src/trigger/task.ts"],
patterns: [],
stop: vi.fn(),
})),
}));

vi.mock("./plugins.js", () => ({
buildPlugins: vi.fn(() => []),
SdkVersionExtractor: vi.fn(() => ({
plugin: { name: "sdk-version" },
})),
}));

vi.mock("./manifests.js", () => ({
copyManifestToDir: vi.fn(),
}));

vi.mock("../utilities/sourceFiles.js", () => ({
resolveFileSources: vi.fn(),
}));

vi.mock("../utilities/logger.js", () => ({
logger: {
debug: vi.fn(),
info: vi.fn(),
error: vi.fn(),
warn: vi.fn(),
},
}));

vi.mock("../utilities/cliOutput.js", () => ({
cliLink: vi.fn(),
prettyError: vi.fn(),
}));

vi.mock("../cli/common.js", () => ({
SkipLoggingError: class extends Error { },
}));

describe("bundleWorker with Yarn PnP support", () => {
beforeEach(() => {
vi.clearAllMocks();
});

test("should copy shims to .trigger/shims and use them in inject", async () => {
const workingDir = "/project";
const options = {
target: "deploy" as const,
destination: "/dist",
cwd: workingDir,
resolvedConfig: {
workingDir,
dirs: ["src/trigger"],
build: {
jsx: { automatic: true }
}
} as any,
};

vi.mocked(esbuild.build).mockResolvedValue({
outputFiles: [],
metafile: {
outputs: {
"dist/index.mjs": {
entryPoint: "src/entryPoints/managed-run-worker.js",
},
"dist/controller.mjs": {
entryPoint: "src/entryPoints/managed-run-controller.js",
},
"dist/index-worker.mjs": {
entryPoint: "src/entryPoints/managed-index-worker.js",
},
"dist/index-controller.mjs": {
entryPoint: "src/entryPoints/managed-index-controller.js",
},
"dist/config.mjs": {
entryPoint: "trigger.config.ts",
}
}
},
errors: [],
warnings: [],
} as any);

await bundleWorker(options);

// Verify mkdir was called for .trigger/shims
expect(mkdir).toHaveBeenCalledWith(join(workingDir, ".trigger", "shims"), { recursive: true });

// Verify copyFile was called for each shim
for (const shim of shims) {
expect(copyFile).toHaveBeenCalledWith(shim, expect.stringContaining(join(".trigger", "shims")));
}

// Verify esbuild.build was called with local shim paths in inject
expect(esbuild.build).toHaveBeenCalledWith(
expect.objectContaining({
inject: expect.arrayContaining([expect.stringContaining(join(".trigger", "shims"))]),
})
);
});
});
Loading