Reduce test flakeyness (#517)
Some checks failed
All good? / all-good (push) Has been cancelled
Update pull request branches / Update pull request branches (push) Has been cancelled
Ensure Prisma migrations are in sync with the schema / check_prisma_migrations (22.x) (push) Has been cancelled
Docker Build and Push / Docker Build and Push Server (push) Has been cancelled
Docker Test / docker (push) Has been cancelled
Runs E2E API Tests / build (20.x) (push) Has been cancelled
Runs E2E API Tests / build (22.x) (push) Has been cancelled
Runs E2E API Tests / build (latest) (push) Has been cancelled
Lint & build / lint_and_build (20.x) (push) Has been cancelled
Lint & build / lint_and_build (22.x) (push) Has been cancelled
Mirror main branch to main-mirror-for-wdb / lint_and_build (push) Has been cancelled
Publish Docs / run (push) Has been cancelled
Dev Environment Test / test (push) Has been cancelled
Run setup tests / test (push) Has been cancelled
TOC Generator / TOC Generator (push) Has been cancelled

This commit is contained in:
Konsti Wohlwend 2025-03-07 13:34:50 -08:00 committed by GitHub
parent 63747df29e
commit b41681d1e4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
22 changed files with 68 additions and 64 deletions

46
.github/workflows/all-good.yaml vendored Normal file
View File

@ -0,0 +1,46 @@
name: All good?
on: push
jobs:
all-good:
runs-on: ubuntu-latest
env:
REPO: ${{ github.repository }}
COMMIT: ${{ github.sha }}
steps:
- name: Wait for 60 seconds
run: sleep 60
- name: Poll Checks API until complete
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
echo "Checking check runs for commit ${COMMIT} in repo ${REPO}..."
while true; do
response=$(curl -s -H "Authorization: Bearer ${GITHUB_TOKEN}" \
"https://api.github.com/repos/${REPO}/commits/${COMMIT}/check-runs")
total=$(echo "$response" | jq -r '.total_count')
if [ "$total" -eq 0 ]; then
echo "No check runs found for commit ${COMMIT}. Waiting..."
sleep 10
continue
fi
pending=$(echo "$response" | jq '[.check_runs[] | select(.status != "completed" and .name != "all-good")] | length')
if [ "$pending" -gt 0 ]; then
echo "$pending check run(s) still in progress. Waiting..."
sleep 10
continue
fi
failed=$(echo "$response" | jq '[.check_runs[] | select(.conclusion != "success" and .name != "all-good")] | length')
if [ "$failed" -eq 0 ]; then
echo "All check runs passed!"
exit 0
else
echo "Some check runs failed. Exiting with error."
exit 1
fi
done

View File

@ -8,6 +8,7 @@ jobs:
permissions:
contents: write
pull-requests: write
actions: write
name: Update pull request branches
runs-on: ubuntu-22.04
steps:

View File

@ -5,7 +5,7 @@ on: push
jobs:
build-server:
name: Docker Build and Push Server
runs-on: ubicloud-standard-16
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

View File

@ -4,7 +4,7 @@ on: push
jobs:
docker:
runs-on: ubicloud-standard-8
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

View File

@ -4,7 +4,7 @@ on: push
jobs:
build:
runs-on: depot-ubuntu-22.04-16
runs-on: ubicloud-standard-8
env:
NODE_ENV: test
STACK_ENABLE_HARDCODED_PASSKEY_CHALLENGE_FOR_TESTING: yes

View File

@ -4,7 +4,7 @@ on: push
jobs:
lint_and_build:
runs-on: ubicloud-standard-8
runs-on: ubuntu-latest
strategy:
matrix:

View File

@ -4,7 +4,7 @@ on: pull_request
jobs:
run:
runs-on: ubicloud-standard-8
runs-on: ubuntu-latest
permissions: write-all

View File

@ -7,7 +7,7 @@ on:
jobs:
run:
runs-on: ubicloud-standard-8
runs-on: ubuntu-latest
permissions: write-all

View File

@ -8,7 +8,6 @@ env:
jobs:
test:
runs-on: ubicloud-standard-8
timeout-minutes: 20
steps:
- uses: actions/checkout@v3

View File

@ -9,7 +9,6 @@ env:
jobs:
test:
runs-on: ubicloud-standard-8
timeout-minutes: 20
steps:
- uses: actions/checkout@v3

View File

@ -8,6 +8,7 @@ jobs:
runs-on: ubuntu-latest
permissions:
contents: write
actions: write
steps:
- uses: technote-space/toc-generator@v4
with:

View File

@ -20,10 +20,8 @@ if (getNodeEnvironment() !== 'production') {
export async function retryTransaction<T>(fn: (...args: Parameters<Parameters<typeof prismaClient.$transaction>[0]>) => Promise<T>): Promise<T> {
const isDev = getNodeEnvironment() === 'development';
// enable serializable isolation level for the first two attempts of 10% of all transactions
const enableSerializable = Math.random() < 0.1;
// disable serializable transactions for now, later we may re-add them
const enableSerializable = false as boolean;
return await traceSpan('Prisma transaction', async (span) => {
const res = await Result.retry(async (attemptIndex) => {
@ -41,7 +39,7 @@ export async function retryTransaction<T>(fn: (...args: Parameters<Parameters<ty
throw e;
}
}, {
isolationLevel: enableSerializable && attemptIndex < 2 ? Prisma.TransactionIsolationLevel.Serializable : undefined,
isolationLevel: enableSerializable && attemptIndex < 4 ? Prisma.TransactionIsolationLevel.Serializable : undefined,
});
} catch (e) {
// we don't want to retry as aggressively here, because the error may have been thrown after the transaction was already committed
@ -61,7 +59,9 @@ export async function retryTransaction<T>(fn: (...args: Parameters<Parameters<ty
}
return attemptRes;
});
}, 3);
}, 5, {
exponentialDelayBase: 250,
});
span.setAttribute("stack.prisma.transaction.success", res.status === "ok");
span.setAttribute("stack.prisma.transaction.attempts", res.attempts);

View File

@ -47,7 +47,7 @@ it("should return metrics data with users", async ({ expect }) => {
const response = await niceBackendFetch("/api/v1/internal/metrics", { accessType: 'admin' });
expect(response).toMatchSnapshot();
}, {
timeout: 60_000,
timeout: 120_000,
});
it("should not work for non-admins", async ({ expect }) => {

View File

@ -10,5 +10,5 @@ describe("`pnpm run lint`", () => {
});
});
expect(error, `Expected no error to be thrown!\n\n\n\nstdout: ${stdout}\n\n\n\nstderr: ${stderr}`).toBeNull();
}, 120_000);
}, 240_000);
});

View File

@ -10,5 +10,5 @@ describe("`pnpm run typecheck`", () => {
});
});
expect(error, `Expected no error to be thrown!\n\n\n\nstdout: ${stdout}\n\n\n\nstderr: ${stderr}`).toBeNull();
}, 120_000);
}, 240_000);
});

View File

@ -22,7 +22,7 @@
"clean": "rimraf dist && rimraf node_modules",
"lint": "eslint --ext .tsx,.ts .",
"build": "rimraf dist && pnpm run css && tsup-node",
"dev": "rimraf dist && concurrently -n \"build,codegen\" -k \"NODE_OPTIONS='--max_old_space_size=4096' tsup-node --watch\" \"pnpm run codegen:watch\"",
"dev": "rimraf dist && concurrently -n \"build,codegen\" -k \"tsup-node --watch\" \"pnpm run codegen:watch\"",
"codegen": "pnpm run css",
"codegen:watch": "pnpm run css:watch",
"css": "pnpm run css-tw && pnpm run css-sc",

View File

@ -82,7 +82,6 @@ import.meta.vitest?.test("groupBy", ({ expect }) => {
// Check the actual lengths of the words to ensure our test is correct
const words = ["apple", "banana", "cherry", "date", "elderberry"];
console.log("Word lengths:", words.map(w => `${w}: ${w.length}`));
const byLength = groupBy(words, (w) => w.length);
// Adjust expectations based on actual word lengths

View File

@ -57,47 +57,6 @@ export function logged<T extends object>(name: string, toLog: T, options: {} = {
});
return proxy;
}
import.meta.vitest?.test("logged", ({ expect }) => {
// Test with a simple object
const obj = {
value: 42,
method(x: number) { return x * 2; }
};
const loggedObj = logged("testObj", obj);
// Test property access
expect(loggedObj.value).toBe(42);
// Test method call
const result = loggedObj.method(21);
expect(result).toBe(42);
// Test property setting
loggedObj.value = 100;
expect(loggedObj.value).toBe(100);
// Test with a promise-returning method
const asyncObj = {
async asyncMethod(x: number) { return x * 3; }
};
const loggedAsyncObj = logged("asyncObj", asyncObj);
// Test async method
const promise = loggedAsyncObj.asyncMethod(7);
expect(promise instanceof Promise).toBe(true);
// Test error handling
const errorObj = {
throwError() { throw new Error("Test error"); }
};
const loggedErrorObj = logged("errorObj", errorObj);
// Test error throwing
expect(() => loggedErrorObj.throwError()).toThrow("Test error");
});
export function createLazyProxy<FactoryResult>(factory: () => FactoryResult): FactoryResult {
let cache: FactoryResult | undefined = undefined;

View File

@ -22,7 +22,7 @@
"clean": "rimraf dist && rimraf node_modules",
"lint": "eslint --ext .tsx,.ts .",
"build": "rimraf dist && pnpm run css && tsup-node",
"dev": "rimraf dist && concurrently -n \"build,codegen\" -k \"NODE_OPTIONS='--max_old_space_size=4096' tsup-node --watch\" \"pnpm run codegen:watch\"",
"dev": "rimraf dist && concurrently -n \"build,codegen\" -k \"tsup-node --watch\" \"pnpm run codegen:watch\"",
"codegen": "pnpm run css",
"codegen:watch": "pnpm run css:watch",
"css": "pnpm run css-tw && pnpm run css-sc",

View File

@ -34,7 +34,7 @@
"//": "IF_PLATFORM template react-like",
"build": "rimraf dist && pnpm run css && tsup-node",
"dev": "rimraf dist && concurrently -n \"build,codegen\" -k \"NODE_OPTIONS='--max_old_space_size=4096' tsup-node --watch\" \"pnpm run codegen:watch\"",
"dev": "rimraf dist && concurrently -n \"build,codegen\" -k \"tsup-node --watch\" \"pnpm run codegen:watch\"",
"codegen": "pnpm run css",
"codegen:watch": "pnpm run css:watch"
,"//": "ELSE_PLATFORM",

View File

@ -23,7 +23,7 @@
"clean": "rimraf dist && rimraf node_modules",
"lint": "eslint --ext .tsx,.ts .",
"build": "rimraf dist && pnpm run css && tsup-node",
"dev": "rimraf dist && concurrently -n \"build,codegen\" -k \"NODE_OPTIONS='--max_old_space_size=4096' tsup-node --watch\" \"pnpm run codegen:watch\"",
"dev": "rimraf dist && concurrently -n \"build,codegen\" -k \"tsup-node --watch\" \"pnpm run codegen:watch\"",
"codegen": "pnpm run css && pnpm run quetzal",
"codegen:watch": "concurrently -n \"css,quetzal\" -k \"pnpm run css:watch\" \"pnpm run quetzal:watch\"",
"css": "pnpm run css-tw && pnpm run css-sc",

View File

@ -13,7 +13,7 @@ const config: Options = {
sourcemap: true,
clean: false,
noExternal: [...customNoExternal],
dts: true,
dts: 'src/index.ts', // we only generate types for the barrel file because it drastically decreases the memory needed for tsup https://github.com/egoist/tsup/issues/920#issuecomment-2454732254
outDir: 'dist',
format: ['esm', 'cjs'],
legacyOutput: true,