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
7 changes: 7 additions & 0 deletions .changeset/astro-manifest-warning.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@workflow/astro": patch
"@workflow/builders": patch
"@workflow/core": patch
---

Stop Astro and Vite from warning about generated workflow files during build and dev.
13 changes: 12 additions & 1 deletion packages/astro/src/builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ const WORKFLOW_ROUTES = [
},
];

/**
* Astro's router ignores files in the pages directory whose name starts with
* an underscore. Without it, Astro 5 warns about the manifest on every scan.
*/
const ASTRO_MANIFEST_FILE_NAME = '_manifest.json';

export class LocalBuilder extends BaseBuilder {
#pagesDir: string;

Expand Down Expand Up @@ -60,6 +66,9 @@ export class LocalBuilder extends BaseBuilder {

// Clean up stale V1 step route (may persist via Vercel build cache)
await rm(join(workflowGeneratedDir, 'step.js'), { force: true });
// Older versions wrote the manifest as `manifest.json`, which Astro 5
// warns about as an unsupported file type in the pages directory.
await rm(join(workflowGeneratedDir, 'manifest.json'), { force: true });

// Get workflow and step files to bundle
const inputFiles = await this.getInputFiles();
Expand Down Expand Up @@ -98,12 +107,14 @@ export const prerender = false;`

await this.buildWebhookRoute({ workflowGeneratedDir });

// Generate unified manifest
// Generate unified manifest. Prefixed with an underscore so Astro's
// router skips it instead of warning that `.json` is not a route type.
const workflowBundlePath = join(workflowGeneratedDir, 'flow.js');
const manifestJson = await this.createManifest({
workflowBundlePath,
manifestDir: workflowGeneratedDir,
manifest,
manifestFileName: ASTRO_MANIFEST_FILE_NAME,
});

// Expose manifest as a public HTTP route when WORKFLOW_PUBLIC_MANIFEST=1
Expand Down
26 changes: 25 additions & 1 deletion packages/builders/src/base-builder-logging.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs';
import {
existsSync,
mkdirSync,
mkdtempSync,
rmSync,
writeFileSync,
} from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
Expand All @@ -19,6 +25,7 @@ class TestBuilder extends BaseBuilder {
workflowBundlePath: string;
manifestDir: string;
manifest: WorkflowManifest;
manifestFileName?: string;
}): Promise<string | undefined> {
return this.createManifest(args);
}
Expand Down Expand Up @@ -133,4 +140,21 @@ describe('base builder logging', () => {
/^✓ Compiled workflows in \d+(?:ms|\.\d+s) \(2 steps, 1 workflow\)$/
);
});

it('writes the manifest under the requested file name', async () => {
const workflowBundlePath = join(testRoot, 'workflow.js');
const manifestDir = join(testRoot, 'src/pages/.well-known/workflow/v1');
writeFileSync(workflowBundlePath, '', 'utf-8');

const manifestJson = await createBuilder(testRoot).createTestManifest({
workflowBundlePath,
manifestDir,
manifest: { steps: {}, workflows: {} },
manifestFileName: '_manifest.json',
});

expect(manifestJson).toBeDefined();
expect(existsSync(join(manifestDir, '_manifest.json'))).toBe(true);
expect(existsSync(join(manifestDir, 'manifest.json'))).toBe(false);
});
});
4 changes: 3 additions & 1 deletion packages/builders/src/base-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2351,10 +2351,12 @@ export const OPTIONS = handler;`;
workflowBundlePath,
manifestDir,
manifest,
manifestFileName = 'manifest.json',
}: {
workflowBundlePath: string;
manifestDir: string;
manifest: WorkflowManifest;
manifestFileName?: string;
}): Promise<string | undefined> {
const buildStart = Date.now();
this.logCreateManifestInfo('Creating manifest...');
Expand All @@ -2379,7 +2381,7 @@ export const OPTIONS = handler;`;

await mkdir(manifestDir, { recursive: true });
await writeFileIfChanged(
join(manifestDir, 'manifest.json'),
join(manifestDir, manifestFileName),
manifestJson
);

Expand Down
2 changes: 1 addition & 1 deletion packages/core/e2e/manifest.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ const MANIFEST_LOCATIONS: Record<string, ManifestLocation> = {
nest: {
skipReason: 'Nest generates its manifest when the application starts',
},
astro: { path: 'src/pages/.well-known/workflow/v1/manifest.json' },
astro: { path: 'src/pages/.well-known/workflow/v1/_manifest.json' },
'tanstack-start': { path: 'node_modules/.nitro/workflow/manifest.json' },
};

Expand Down
1 change: 1 addition & 0 deletions packages/core/src/runtime/world.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ export const createWorld = async (): Promise<World> => {
} catch {
const resolvedPath = resolveModulePath(targetWorld);
mod = await import(
/* @vite-ignore */
/* webpackIgnore: true */
/* turbopackIgnore: true */
resolvedPath
Expand Down
Loading