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
30 changes: 30 additions & 0 deletions .github/workflows/preview.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Preview

# Builds the per-package preview container (npm artifact + smoke test of the
# exact files pi loads) and pushes it to GHCR on main.
on:
pull_request:
push:
branches: [main]

permissions:
contents: read
packages: write

jobs:
preview:
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@v7
- name: Build preview image
run: docker build -f preview/Dockerfile -t ghcr.io/groeponline/pi-tools-preview:sha-${GITHUB_SHA} .
- name: Run preview smoke
run: docker run --rm ghcr.io/groeponline/pi-tools-preview:sha-${GITHUB_SHA}
- name: Push preview image (main only)
if: github.ref == 'refs/heads/main'
run: |
echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin
docker tag ghcr.io/groeponline/pi-tools-preview:sha-${GITHUB_SHA} ghcr.io/groeponline/pi-tools-preview:main
docker push ghcr.io/groeponline/pi-tools-preview:sha-${GITHUB_SHA}
docker push ghcr.io/groeponline/pi-tools-preview:main
10 changes: 10 additions & 0 deletions packages/pi-tools/src/tgrep.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,17 @@ async function defaultExec(
stdout?: string;
stderr?: string;
message?: string;
killed?: boolean;
};
// execFile reports a budget timeout as killed:true with code null, so it
// would otherwise fall through to the generic failure below. User aborts
// are already handled above; a kill here means the time budget ran out.
if (execError.killed) {
const budget = opts.timeoutMs ?? TGREP_TIME_BUDGET_MS;
throw new Error(
`tgrep timed out after ${budget}ms; narrow with fileType/glob or raise tgrepTimeBudgetMs`,
);
}
if (execError.code === "ERR_CHILD_PROCESS_STDIO_MAXBUFFER")
return { exit: 0, stdout: execError.stdout ?? "", stderr: execError.stderr ?? "" };
if (typeof execError.code === "number")
Expand Down
9 changes: 9 additions & 0 deletions packages/pi-tools/test/tgrep.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,15 @@ describe("runTgrep", () => {
await expect(running).rejects.toThrow("Operation aborted");
});

test("maps a time-budget timeout to a narrowing hint", async () => {
await expect(
runTgrep(process.execPath, ["-e", "setTimeout(() => {}, 30000)"], {
cwd: "/tmp",
timeoutMs: 100,
}),
).rejects.toThrow("timed out after 100ms");
});

test("forwards a custom time budget to the executor", async () => {
let seen: number | undefined;
await runTgrep(
Expand Down
20 changes: 20 additions & 0 deletions preview/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Preview image for @groeponline/pi-tools.
# Packs the npm artifact and smoke-tests the exact files pi loads,
# inside a clean container. (Build context is the repo root; only the
# packages/pi-tools subpackage is packed.)
#
# docker build -f preview/Dockerfile -t ghcr.io/groeponline/pi-tools-preview:local .
# docker run --rm ghcr.io/groeponline/pi-tools-preview:local
FROM node:22 AS build
WORKDIR /src/packages/pi-tools
COPY packages/pi-tools/package.json ./
RUN npm install --ignore-scripts --no-audit --no-fund
COPY packages/pi-tools/ ./
RUN mkdir -p /out && npm pack --pack-destination /out

FROM node:22-slim AS preview
WORKDIR /preview
COPY --from=build /out/*.tgz ./pkg.tgz
COPY preview/smoke.sh ./smoke.sh
RUN npm install ./pkg.tgz --prefix ./pkg --no-audit --no-fund && sh ./smoke.sh ./pkg
CMD ["sh", "./smoke.sh", "./pkg"]
9 changes: 9 additions & 0 deletions preview/smoke.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/bin/sh
# Smoke-test the installed preview package: the exact entries pi loads must
# exist in the shipped artifact.
set -eu
PREFIX="${1:-./pkg}"
PKG="$PREFIX/node_modules/@groeponline/pi-tools"
fail() { echo "preview FAIL: $1" >&2; exit 1; }
test -f "$PKG/src/index.ts" || fail "missing pi extension entry src/index.ts"
echo "preview OK: @groeponline/pi-tools (src/index.ts present)"
Loading