Skip to content

Commit 6a8123b

Browse files
authored
Simplify CI (#6769)
* Simplify Test flow * S * .. * More * Lets go * Go * Lets go * Lets go * Fix import * .. * Concurrency * Try again * .. * Lets go * Force exit
1 parent b1146e6 commit 6a8123b

File tree

22 files changed

+530
-459
lines changed

22 files changed

+530
-459
lines changed

.changeset/sharp-carrots-hunt.md

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
'@graphql-tools/executor-urql-exchange': patch
3+
'@graphql-tools/executor-apollo-link': patch
4+
'@graphql-tools/utils': patch
5+
---
6+
7+
Improvements for `fakePromise` so it can be used without params to create a `void` Promise

.github/workflows/pr.yml

+3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ on:
44
branches:
55
- master
66

7+
concurrency:
8+
group: ${{ github.workflow }}-${{ github.ref }}
9+
710
jobs:
811
dependencies:
912
uses: the-guild-org/shared-config/.github/workflows/changesets-dependencies.yaml@main

.github/workflows/release.yml

+3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ on:
44
branches:
55
- master
66

7+
concurrency:
8+
group: ${{ github.workflow }}-${{ github.ref }}
9+
710
jobs:
811
stable:
912
permissions:

.github/workflows/tests.yml

+20-63
Original file line numberDiff line numberDiff line change
@@ -5,44 +5,20 @@ env:
55
NODE_OPTIONS: '--max-old-space-size=8192'
66
CI: true
77

8+
concurrency:
9+
group: ${{ github.workflow }}-${{ github.ref }}
10+
cancel-in-progress: true
11+
812
on:
913
push:
1014
branches:
1115
- master
1216
pull_request:
1317

1418
jobs:
15-
prettier-check:
16-
name: 🧹 Prettier Check
17-
runs-on: ubuntu-latest
18-
steps:
19-
- name: Checkout Master
20-
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
21-
22-
- name: Setup env
23-
uses: the-guild-org/shared-config/setup@main
24-
with:
25-
nodeVersion: 22
26-
27-
- name: Prettier Check
28-
run: yarn prettier:check
29-
lint:
30-
name: Lint
31-
uses: the-guild-org/shared-config/.github/workflows/lint.yml@main
32-
with:
33-
script: yarn ci:lint
34-
secrets:
35-
githubToken: ${{ secrets.GITHUB_TOKEN }}
36-
37-
build:
38-
name: Type Check on GraphQL v${{matrix.graphql_version}}
19+
typecheck-15:
20+
name: Type Check on GraphQL v15
3921
runs-on: ubuntu-latest
40-
strategy:
41-
fail-fast: false
42-
matrix:
43-
graphql_version:
44-
- 15
45-
- 16
4622
steps:
4723
- name: Checkout Master
4824
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
@@ -52,25 +28,27 @@ jobs:
5228
with:
5329
nodeVersion: 22
5430

55-
- name: Use GraphQL v${{matrix.graphql_version}}
56-
run: node ./scripts/match-graphql.js ${{matrix.graphql_version}}
31+
- name: Use GraphQL v15
32+
run: node ./scripts/match-graphql.js 15
5733
- name: Install Dependencies using Yarn
5834
run: yarn install --ignore-engines && git checkout yarn.lock
5935
- name: Type Check
6036
run: yarn ts:check
61-
test_esm:
62-
name: ESM Test
37+
check:
38+
name: Full Check on GraphQL v16
6339
runs-on: ubuntu-latest
6440
steps:
6541
- name: Checkout Master
6642
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
67-
6843
- name: Setup env
6944
uses: the-guild-org/shared-config/setup@main
7045
with:
7146
nodeVersion: 22
72-
73-
- name: Build Packages
47+
- name: Prettier
48+
run: yarn prettier:check
49+
- name: Lint
50+
run: yarn lint
51+
- name: Build
7452
run: yarn build
7553
- name: Test ESM and CJS integrity
7654
run: yarn bob check
@@ -83,7 +61,7 @@ jobs:
8361
fail-fast: false
8462
matrix:
8563
os: [ubuntu-latest] # remove windows to speed up the tests
86-
node-version: [18, 20, 22]
64+
node-version: [18, 20, 22, 23]
8765
graphql_version:
8866
- 15
8967
- 16
@@ -113,34 +91,13 @@ jobs:
11391
hashFiles('yarn.lock') }}
11492
restore-keys: |
11593
${{ runner.os }}-${{matrix.node-version}}-${{matrix.graphql_version}}-jest-
116-
- name: Test
117-
if: ${{ matrix.node-version >= 20 }}
94+
- name: Build
95+
run: yarn build
96+
- name: Unit Tests
11897
run: yarn test --ci
119-
- name: Test
120-
if: ${{ matrix.node-version < 20 }}
98+
- name: Leak Tests
12199
uses: nick-fields/retry@v3
122100
with:
123101
timeout_minutes: 10
124102
max_attempts: 5
125103
command: yarn test:leaks --ci
126-
127-
test_browser:
128-
name: Browser Test
129-
runs-on: ubuntu-latest
130-
steps:
131-
- name: Checkout Master
132-
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
133-
- name: Setup env
134-
uses: the-guild-org/shared-config/setup@main
135-
with:
136-
nodeVersion: 22
137-
- name: Setup Chrome
138-
uses: browser-actions/setup-chrome@v1
139-
- name: Build Packages
140-
run: yarn build
141-
- name: Test
142-
uses: nick-fields/retry@v3
143-
with:
144-
timeout_minutes: 10
145-
max_attempts: 5
146-
command: TEST_BROWSER=true yarn jest --no-watchman --ci browser

.github/workflows/website.yml

+3
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ on:
66
- master
77
pull_request:
88

9+
concurrency:
10+
group: ${{ github.workflow }}-${{ github.ref }}
11+
912
jobs:
1013
deployment:
1114
runs-on: ubuntu-latest

jest.config.js

+1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ externalToolsPackages.forEach(mod => {
3636
});
3737

3838
module.exports = {
39+
displayName: process.env.LEAK_TEST ? 'Leak Test' : 'Unit Test',
3940
testEnvironment: 'node',
4041
rootDir: ROOT_DIR,
4142
prettierPath: null, // disable prettier for inline snapshots

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
"prettier:check": "prettier --cache --ignore-path .prettierignore --check .",
4141
"release": "changeset publish",
4242
"test": "jest --no-watchman",
43-
"test:leaks": "cross-env \"LEAK_TEST=1\" jest --no-watchman --detectOpenHandles --detectLeaks --logHeapUsage",
43+
"test:leaks": "cross-env \"LEAK_TEST=1\" jest --no-watchman --detectOpenHandles --detectLeaks --forceExit",
4444
"ts:check": "tsc --noEmit"
4545
},
4646
"devDependencies": {

packages/executor/src/execution/__tests__/simplePubSub-test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { SimplePubSub } from './simplePubSub.js';
1+
import { SimplePubSub } from '../../../../testing/simplePubSub.js';
22

33
describe('SimplePubSub', () => {
44
it('subscribe async-iterator mock', async () => {

packages/executor/src/execution/__tests__/subscribe.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ import { ExecutionResult, isAsyncIterable, isPromise, MaybePromise } from '@grap
1212
import { expectJSON } from '../../__testUtils__/expectJSON.js';
1313
import { resolveOnNextTick } from '../../__testUtils__/resolveOnNextTick.js';
1414
import { assertAsyncIterable } from '../../../../loaders/url/tests/test-utils.js';
15+
import { SimplePubSub } from '../../../../testing/simplePubSub.js';
1516
import { ExecutionArgs, subscribe } from '../execute.js';
1617
import { normalizedExecutor } from '../normalizedExecutor.js';
17-
import { SimplePubSub } from './simplePubSub.js';
1818

1919
interface Email {
2020
from: string;

packages/executors/apollo-link/src/index.ts

+23-20
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import * as apolloImport from '@apollo/client';
2-
import { ExecutionRequest, Executor, isAsyncIterable } from '@graphql-tools/utils';
2+
import { Executor, fakePromise, isAsyncIterable } from '@graphql-tools/utils';
33

44
const apollo: typeof apolloImport = (apolloImport as any)?.default ?? apolloImport;
55

@@ -8,34 +8,37 @@ function createApolloRequestHandler(executor: Executor): apolloImport.RequestHan
88
operation: apolloImport.Operation,
99
): apolloImport.Observable<apolloImport.FetchResult> {
1010
return new apollo.Observable(observer => {
11-
Promise.resolve().then(async () => {
12-
const executionRequest: ExecutionRequest = {
13-
document: operation.query,
14-
variables: operation.variables,
15-
operationName: operation.operationName,
16-
extensions: operation.extensions,
17-
context: operation.getContext(),
18-
};
19-
try {
20-
const results = await executor(executionRequest);
11+
fakePromise()
12+
.then(() =>
13+
executor({
14+
document: operation.query,
15+
variables: operation.variables,
16+
operationName: operation.operationName,
17+
extensions: operation.extensions,
18+
context: operation.getContext(),
19+
}),
20+
)
21+
.then(results => {
2122
if (isAsyncIterable(results)) {
22-
for await (const result of results) {
23-
if (observer.closed) {
24-
return;
23+
return fakePromise().then(async () => {
24+
for await (const result of results) {
25+
if (observer.closed) {
26+
return;
27+
}
28+
observer.next(result);
2529
}
26-
observer.next(result);
27-
}
28-
observer.complete();
30+
observer.complete();
31+
});
2932
} else if (!observer.closed) {
3033
observer.next(results);
3134
observer.complete();
3235
}
33-
} catch (e) {
36+
})
37+
.catch(e => {
3438
if (!observer.closed) {
3539
observer.error(e);
3640
}
37-
}
38-
});
41+
});
3942
});
4043
};
4144
}

packages/executors/apollo-link/tests/browser-apollo-link.spec.ts renamed to packages/executors/apollo-link/tests/apollo-link.spec.ts

+13-8
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
1+
import { setTimeout } from 'timers/promises';
12
import { parse } from 'graphql';
23
import { createSchema, createYoga } from 'graphql-yoga';
34
import { ApolloClient, FetchResult, InMemoryCache } from '@apollo/client/core';
45
import { buildHTTPExecutor } from '@graphql-tools/executor-http';
6+
import { testIf } from '../../../testing/utils.js';
57
import { ExecutorLink } from '../src/index.js';
68

79
describe('Apollo Link', () => {
8-
if (!process.env['TEST_BROWSER']) {
9-
it('skips', () => {});
10-
return;
11-
}
1210
const yoga = createYoga({
1311
logging: false,
1412
maskedErrors: false,
@@ -36,7 +34,7 @@ describe('Apollo Link', () => {
3634
time: {
3735
async *subscribe() {
3836
while (true) {
39-
await new Promise(resolve => setTimeout(resolve, 1000));
37+
await setTimeout(300);
4038
yield new Date().toISOString();
4139
}
4240
},
@@ -58,6 +56,13 @@ describe('Apollo Link', () => {
5856
cache: new InMemoryCache(),
5957
});
6058

59+
beforeEach(() => {});
60+
61+
afterAll(() => {
62+
client.stop();
63+
return client.clearStore();
64+
});
65+
6166
it('should handle queries correctly', async () => {
6267
const result = await client.query({
6368
query: parse(/* GraphQL */ `
@@ -72,7 +77,7 @@ describe('Apollo Link', () => {
7277
hello: 'Hello Apollo Client!',
7378
});
7479
});
75-
it('should handle subscriptions correctly', async () => {
80+
testIf(!process.env['LEAK_TEST'])('should handle subscriptions correctly', async () => {
7681
expect.assertions(5);
7782
const observable = client.subscribe({
7883
query: parse(/* GraphQL */ `
@@ -83,15 +88,15 @@ describe('Apollo Link', () => {
8388
});
8489
const collectedValues: string[] = [];
8590
let i = 0;
86-
await new Promise<void>(resolve => {
91+
await new Promise<void>((resolve, reject) => {
8792
const subscription = observable.subscribe((result: FetchResult) => {
8893
collectedValues.push(result.data?.['time']);
8994
i++;
9095
if (i > 2) {
9196
subscription.unsubscribe();
9297
resolve();
9398
}
94-
});
99+
}, reject);
95100
});
96101
expect(collectedValues.length).toBe(3);
97102
expect(i).toBe(3);

packages/executors/urql-exchange/src/index.ts

+19-15
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { OperationTypeNode } from 'graphql';
22
import { filter, make, merge, mergeMap, pipe, share, Source, takeUntil } from 'wonka';
3-
import { ExecutionRequest, Executor, isAsyncIterable } from '@graphql-tools/utils';
3+
import { ExecutionRequest, Executor, fakePromise, isAsyncIterable } from '@graphql-tools/utils';
44
import {
55
AnyVariables,
66
Exchange,
@@ -37,31 +37,35 @@ export function executorExchange(executor: Executor): Exchange {
3737
};
3838
return make<OperationResult<TData>>(observer => {
3939
let ended = false;
40-
Promise.resolve(executor(executionRequest))
41-
.then(async result => {
40+
fakePromise()
41+
.then(() => executor(executionRequest))
42+
.then(result => {
4243
if (ended || !result) {
4344
return;
4445
}
4546
if (!isAsyncIterable(result)) {
4647
observer.next(makeResult(operation, result as ExecutionResult));
48+
observer.complete();
4749
} else {
4850
let prevResult: OperationResult<TData, AnyVariables> | null = null;
4951

50-
for await (const value of result) {
51-
if (value) {
52-
if (prevResult && value.incremental) {
53-
prevResult = mergeResultPatch(prevResult, value as ExecutionResult);
54-
} else {
55-
prevResult = makeResult(operation, value as ExecutionResult);
52+
return fakePromise().then(async () => {
53+
for await (const value of result) {
54+
if (value) {
55+
if (prevResult && value.incremental) {
56+
prevResult = mergeResultPatch(prevResult, value as ExecutionResult);
57+
} else {
58+
prevResult = makeResult(operation, value as ExecutionResult);
59+
}
60+
observer.next(prevResult);
61+
}
62+
if (ended) {
63+
break;
5664
}
57-
observer.next(prevResult);
58-
}
59-
if (ended) {
60-
break;
6165
}
62-
}
66+
observer.complete();
67+
});
6368
}
64-
observer.complete();
6569
})
6670
.catch(error => {
6771
observer.next(makeErrorResult(operation, error));

0 commit comments

Comments
 (0)