fix(docker): install pnpm via npm instead of corepack shim (GRO-1983) #125
+7
-9
@@ -1,7 +1,10 @@
|
|||||||
FROM node:22-alpine AS base
|
FROM node:22-alpine AS base
|
||||||
RUN corepack enable && corepack install -g pnpm@9.15.4
|
# Install pnpm as a real binary via npm (not corepack shim) so runtime
|
||||||
ENV COREPACK_ENABLE_DOWNLOAD_PROMPT=0
|
# invocations of `pnpm` work without DNS access to registry.npmjs.org.
|
||||||
ENV COREPACK_ENABLE_STRICT=0
|
# The corepack shim delegates to corepack, which re-validates against
|
||||||
|
# npmjs.org on first use — that fails in air-gapped UAT seed/migrate/reset
|
||||||
|
# Jobs. GRO-1983 / GRO-1889 / GRO-1909.
|
||||||
|
RUN npm install -g pnpm@9.15.4
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
# Install deps
|
# Install deps
|
||||||
@@ -22,9 +25,7 @@ RUN pnpm --filter @groombook/types build && \
|
|||||||
|
|
||||||
# Runtime
|
# Runtime
|
||||||
FROM node:22-alpine AS runner
|
FROM node:22-alpine AS runner
|
||||||
RUN corepack enable && corepack install -g pnpm@9.15.4
|
RUN npm install -g pnpm@9.15.4
|
||||||
ENV COREPACK_ENABLE_DOWNLOAD_PROMPT=0
|
|
||||||
ENV COREPACK_ENABLE_STRICT=0
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
ENV NODE_ENV=production
|
ENV NODE_ENV=production
|
||||||
|
|
||||||
@@ -53,7 +54,4 @@ CMD ["pnpm", "--filter", "@groombook/db", "seed"]
|
|||||||
|
|
||||||
# Reset stage — drops all tables, re-runs migrations, and re-seeds
|
# Reset stage — drops all tables, re-runs migrations, and re-seeds
|
||||||
FROM builder AS reset
|
FROM builder AS reset
|
||||||
RUN corepack enable && corepack install -g pnpm@9.15.4
|
|
||||||
ENV COREPACK_ENABLE_DOWNLOAD_PROMPT=0
|
|
||||||
ENV COREPACK_ENABLE_STRICT=0
|
|
||||||
CMD ["pnpm", "--filter", "@groombook/db", "reset"]
|
CMD ["pnpm", "--filter", "@groombook/db", "reset"]
|
||||||
|
|||||||
+20
-14
@@ -1106,14 +1106,17 @@ async function seed() {
|
|||||||
temperamentScore: randInt(1, 5),
|
temperamentScore: randInt(1, 5),
|
||||||
temperamentFlags: pickN(temperamentFlagPool, randInt(1, 3)),
|
temperamentFlags: pickN(temperamentFlagPool, randInt(1, 3)),
|
||||||
medicalAlerts: (() => {
|
medicalAlerts: (() => {
|
||||||
// ~30% of pets get alerts; TestCooper/TestRocky get deterministic types
|
// TestCooper always has a behavioral alert; TestRocky always has a skin alert.
|
||||||
|
// All other UAT test pets follow the 30% random distribution.
|
||||||
|
// Deterministic alerts on 2 of 507 pets (~0.4%) do not meaningfully shift
|
||||||
|
// the overall distribution from the 25-35% target band.
|
||||||
|
if (uc.petName === "TestCooper") {
|
||||||
|
return pickN(medicalAlertPool.filter((a) => a.type === "behavioral"), 1).map((a) => ({ ...a, id: uuid() }));
|
||||||
|
}
|
||||||
|
if (uc.petName === "TestRocky") {
|
||||||
|
return pickN(medicalAlertPool.filter((a) => a.type === "skin"), 1).map((a) => ({ ...a, id: uuid() }));
|
||||||
|
}
|
||||||
if (rand() < 0.3) {
|
if (rand() < 0.3) {
|
||||||
if (uc.petName === "TestCooper") {
|
|
||||||
return pickN(medicalAlertPool.filter((a) => a.type === "behavioral"), 1).map((a) => ({ ...a, id: uuid() }));
|
|
||||||
}
|
|
||||||
if (uc.petName === "TestRocky") {
|
|
||||||
return pickN(medicalAlertPool.filter((a) => a.type === "skin"), 1).map((a) => ({ ...a, id: uuid() }));
|
|
||||||
}
|
|
||||||
const count = rand() < 0.7 ? 1 : 2;
|
const count = rand() < 0.7 ? 1 : 2;
|
||||||
return pickN(medicalAlertPool, count).map((a) => ({ ...a, id: uuid() }));
|
return pickN(medicalAlertPool, count).map((a) => ({ ...a, id: uuid() }));
|
||||||
}
|
}
|
||||||
@@ -1136,14 +1139,17 @@ async function seed() {
|
|||||||
temperamentScore: randInt(1, 5),
|
temperamentScore: randInt(1, 5),
|
||||||
temperamentFlags: pickN(temperamentFlagPool, randInt(1, 3)),
|
temperamentFlags: pickN(temperamentFlagPool, randInt(1, 3)),
|
||||||
medicalAlerts: (() => {
|
medicalAlerts: (() => {
|
||||||
// ~30% of pets get alerts; TestCooper/TestRocky get deterministic types
|
// TestCooper always has a behavioral alert; TestRocky always has a skin alert.
|
||||||
|
// All other UAT test pets follow the 30% random distribution.
|
||||||
|
// Deterministic alerts on 2 of 507 pets (~0.4%) do not meaningfully shift
|
||||||
|
// the overall distribution from the 25-35% target band.
|
||||||
|
if (uc.petName === "TestCooper") {
|
||||||
|
return pickN(medicalAlertPool.filter((a) => a.type === "behavioral"), 1).map((a) => ({ ...a, id: uuid() }));
|
||||||
|
}
|
||||||
|
if (uc.petName === "TestRocky") {
|
||||||
|
return pickN(medicalAlertPool.filter((a) => a.type === "skin"), 1).map((a) => ({ ...a, id: uuid() }));
|
||||||
|
}
|
||||||
if (rand() < 0.3) {
|
if (rand() < 0.3) {
|
||||||
if (uc.petName === "TestCooper") {
|
|
||||||
return pickN(medicalAlertPool.filter((a) => a.type === "behavioral"), 1).map((a) => ({ ...a, id: uuid() }));
|
|
||||||
}
|
|
||||||
if (uc.petName === "TestRocky") {
|
|
||||||
return pickN(medicalAlertPool.filter((a) => a.type === "skin"), 1).map((a) => ({ ...a, id: uuid() }));
|
|
||||||
}
|
|
||||||
const count = rand() < 0.7 ? 1 : 2;
|
const count = rand() < 0.7 ? 1 : 2;
|
||||||
return pickN(medicalAlertPool, count).map((a) => ({ ...a, id: uuid() }));
|
return pickN(medicalAlertPool, count).map((a) => ({ ...a, id: uuid() }));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user