diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index dea4c33..77fad0d 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -4,7 +4,7 @@ on: push jobs: lint: - runs-on: ubuntu-latest + runs-on: blacksmith-2vcpu-ubuntu-2404-arm steps: - uses: actions/checkout@v6 - uses: actions/setup-node@v6 @@ -15,7 +15,7 @@ jobs: - run: npm run lint build: - runs-on: ubuntu-latest + runs-on: blacksmith-2vcpu-ubuntu-2404-arm env: MODE: production steps: @@ -29,7 +29,26 @@ jobs: test: name: test (Node.js ${{ matrix.node }}) - runs-on: ubuntu-latest + runs-on: blacksmith-4vcpu-ubuntu-2404 + strategy: + matrix: + node: [20, 22, 24] + fail-fast: false + steps: + - uses: actions/checkout@v6 + - uses: actions/setup-node@v6 + with: + node-version: ${{ matrix.node }} + cache: npm + - run: npm ci + - run: npm run unit + env: + E2E_PRISMIC_EMAIL: ${{ secrets.E2E_PRISMIC_EMAIL }} + E2E_PRISMIC_PASSWORD: ${{ secrets.E2E_PRISMIC_PASSWORD }} + + test-win32: + name: test windows (Node.js ${{ matrix.node }}) + runs-on: blacksmith-4vcpu-windows-2025 strategy: matrix: node: [20, 22, 24] @@ -48,7 +67,7 @@ jobs: types: name: "types (TypeScript ${{ matrix.typescript }})" - runs-on: ubuntu-latest + runs-on: blacksmith-2vcpu-ubuntu-2404-arm strategy: matrix: typescript: ["5.4", "5.6", "5.7", "5.8", "5.9"] diff --git a/src/adapters/index.ts b/src/adapters/index.ts index b4d2f15..d2c2aea 100644 --- a/src/adapters/index.ts +++ b/src/adapters/index.ts @@ -2,7 +2,7 @@ import type { CustomType, SharedSlice } from "@prismicio/types-internal/lib/cust import { pascalCase } from "change-case"; import { rm } from "node:fs/promises"; -import { fileURLToPath, pathToFileURL } from "node:url"; +import { pathToFileURL } from "node:url"; import { generateTypes } from "prismic-ts-codegen"; import { glob } from "tinyglobby"; @@ -79,9 +79,8 @@ export abstract class Adapter { const libraries = await this.getSliceLibraries(); for (const library of libraries) { - const modelGlob = new URL("*/model.json", library); const sliceModelPaths = Array.from( - await glob(fileURLToPath(modelGlob), { absolute: true }), + await glob("*/model.json", { absolute: true, cwd: library }), (path) => pathToFileURL(path), ); const slices = await Promise.all( @@ -139,9 +138,8 @@ export abstract class Adapter { const libraries = await this.getCustomTypeLibraries(); for (const library of libraries) { - const modelGlob = new URL("*/index.json", library); const customTypeModelPaths = Array.from( - await glob(fileURLToPath(modelGlob), { absolute: true }), + await glob("*/index.json", { absolute: true, cwd: library }), (path) => pathToFileURL(path), ); const customTypes = await Promise.all( diff --git a/src/lib/git.ts b/src/lib/git.ts index 804f7bb..0d53211 100644 --- a/src/lib/git.ts +++ b/src/lib/git.ts @@ -1,3 +1,4 @@ +import { realpath } from "node:fs/promises"; import { fileURLToPath, pathToFileURL } from "node:url"; import { x } from "tinyexec"; @@ -10,7 +11,7 @@ export async function getGitRoot(start: URL): Promise { throwOnError: true, }); const top = stdout.trim(); - return top ? appendTrailingSlash(pathToFileURL(top)) : undefined; + return top ? appendTrailingSlash(pathToFileURL(await realpath(top))) : undefined; } catch { return undefined; } diff --git a/src/project.ts b/src/project.ts index 0772b46..86b0ddd 100644 --- a/src/project.ts +++ b/src/project.ts @@ -1,6 +1,7 @@ import type { CustomType } from "@prismicio/types-internal/lib/customtypes"; -import { readFile, rm, writeFile } from "node:fs/promises"; +import { readFile, realpath, rm, writeFile } from "node:fs/promises"; +import { fileURLToPath, pathToFileURL } from "node:url"; import * as z from "zod/mini"; import { getVariantData } from "./clients/amplitude"; @@ -201,7 +202,7 @@ export async function findProjectRoot(): Promise { } } const projectRoot = new URL(".", configPath); - return projectRoot; + return appendTrailingSlash(pathToFileURL(await realpath(fileURLToPath(projectRoot)))); } export async function safeGetRepositoryName(): Promise { diff --git a/test/gen-setup.test.ts b/test/gen-setup.test.ts index b47b3a6..1fb6451 100644 --- a/test/gen-setup.test.ts +++ b/test/gen-setup.test.ts @@ -8,7 +8,7 @@ it("supports --help", async ({ expect, prismic }) => { expect(stdout).toContain("prismic gen setup [options]"); }); -it("generates setup files", async ({ expect, project, prismic }) => { +it("generates setup files", { timeout: 30_000 }, async ({ expect, project, prismic }) => { const { exitCode, stdout } = await prismic("gen", ["setup"]); expect(exitCode).toBe(0); expect(stdout).toContain("Generated setup files"); @@ -25,7 +25,7 @@ it("generates setup files", async ({ expect, project, prismic }) => { await expect(project).toHaveFile("package-lock.json"); }); -it("skips existing files", async ({ expect, project, prismic }) => { +it("skips existing files", { timeout: 30_000 }, async ({ expect, project, prismic }) => { const customContent = "// custom client file\n"; await writeFile(new URL("prismicio.js", project), customContent); diff --git a/test/init.test.ts b/test/init.test.ts index 1060916..85fb963 100644 --- a/test/init.test.ts +++ b/test/init.test.ts @@ -121,7 +121,7 @@ it("fails when Type Builder is not enabled", async ({ expect, project, prismic, expect(stderr).toContain("Type Builder"); }); -it("installs dependencies", async ({ expect, project, prismic, repo }) => { +it("installs dependencies", { timeout: 30_000 }, async ({ expect, project, prismic, repo }) => { await rm(new URL("prismic.config.json", project)); const { exitCode } = await prismic("init", ["--repo", repo]); diff --git a/test/it.ts b/test/it.ts index aef546a..8b912ae 100644 --- a/test/it.ts +++ b/test/it.ts @@ -35,7 +35,15 @@ export const it = test.extend({ home: async ({}, use) => { const dir = await mkdtemp(join(tmpdir(), "prismic-test-")); await use(pathToFileURL(dir + "/")); - await rm(dir, { recursive: true, force: true }); + try { + await rm(dir, { recursive: true, force: true }); + } catch { + // Noop on CI, retry once with delay locally + if (!process.env.CI) { + await new Promise((res) => setTimeout(res, 1000)); + await rm(dir, { recursive: true, force: true }); + } + } }, project: async ({ home, repo }, use) => { const projectPath = new URL("project/", home); diff --git a/test/pull.test.ts b/test/pull.test.ts index afc5276..c3eb567 100644 --- a/test/pull.test.ts +++ b/test/pull.test.ts @@ -1,4 +1,5 @@ import { writeFile, mkdir } from "node:fs/promises"; +import { sep } from "node:path"; import { fileURLToPath } from "node:url"; import { x } from "tinyexec"; @@ -252,7 +253,7 @@ it.sequential("blocks pull when local model files have uncommitted changes", asy const second = await prismic("pull", ["--repo", repo]); expect(second.exitCode).toBe(1); expect(second.stderr).toContain("uncommitted"); - expect(second.stderr).toContain(`customtypes/${customType.id}/index.json`); + expect(second.stderr).toContain(`customtypes/${customType.id}/index.json`.replaceAll("/", sep)); }); it.sequential("refuses to delete local models without --force when not tracked by git", async ({