Adjust CI checks (#7851)
This commit is contained in:
parent
fcd0367a10
commit
d8b98782d4
10
jest-ci.config.cjs
Normal file
10
jest-ci.config.cjs
Normal file
@ -0,0 +1,10 @@
|
||||
// Copyright 2017-2022 @polkadot/apps authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
const config = require('@polkadot/dev/config/jest.cjs');
|
||||
|
||||
module.exports = {
|
||||
...config,
|
||||
moduleNameMapper: {},
|
||||
testTimeout: 2 * 60 * 1000
|
||||
};
|
||||
@ -15,6 +15,7 @@
|
||||
"url": "https://github.com/polkadot-js/apps.git"
|
||||
},
|
||||
"sideEffects": false,
|
||||
"type": "module",
|
||||
"version": "0.116.2-93-x",
|
||||
"workspaces": [
|
||||
"packages/*"
|
||||
@ -36,8 +37,8 @@
|
||||
"build:release:www": "yarn polkadot-ci-ghact-build && yarn build:release:ghpages && yarn build:release:ipfs",
|
||||
"build:robohash": "node scripts/robohash.cjs",
|
||||
"build:www": "rm -rf packages/apps/build && mkdir -p packages/apps/build && yarn run build:i18n && cd packages/apps && yarn webpack --config webpack.config.cjs",
|
||||
"ci:chainEndpoints": "NODE_OPTIONS=--max_old_space_size=8192 polkadot-dev-run-test --runInBand packages/apps-config/src/ci/chainEndpoints",
|
||||
"ci:chainTypes": "NODE_OPTIONS=--max_old_space_size=8192 polkadot-dev-run-test --runInBand packages/apps-config/src/ci/chainTypes",
|
||||
"ci:chainEndpoints": "NODE_OPTIONS=--experimental-vm-modules polkadot-dev-run-test --config ./jest-ci.config.cjs --runInBand --detectOpenHandles packages/apps-config/src/ci/chainEndpoints",
|
||||
"ci:chainTypes": "NODE_OPTIONS=--experimental-vm-modules polkadot-dev-run-test --config ./jest-ci.config.cjs --runInBand --detectOpenHandles packages/apps-config/src/ci/chainTypes",
|
||||
"clean": "polkadot-dev-clean-build",
|
||||
"clean:electronBuild": "cd packages/apps-electron && polkadot-dev-clean-build",
|
||||
"clean:electronRelease": "cd packages/apps-electron && rm -rf release",
|
||||
|
||||
@ -1,9 +1,13 @@
|
||||
// Copyright 2017-2022 @polkadot/apps-config authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { checkEndpoints } from './util';
|
||||
import { checkEndpoints } from './runner';
|
||||
|
||||
describe('--SLOW--: check configured chain endpoints', (): void => {
|
||||
beforeAll((): void => {
|
||||
jest.setTimeout(2 * 60 * 1000);
|
||||
});
|
||||
|
||||
checkEndpoints('./.github/chain-endpoints.md', [
|
||||
'No DNS entry for',
|
||||
'Timeout connecting to',
|
||||
|
||||
@ -1,9 +1,13 @@
|
||||
// Copyright 2017-2022 @polkadot/apps-config authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { checkEndpoints } from './util';
|
||||
import { checkEndpoints } from './runner';
|
||||
|
||||
describe.skip('--SLOW--: check configured chain types', (): void => {
|
||||
beforeAll((): void => {
|
||||
jest.setTimeout(2 * 60 * 1000);
|
||||
});
|
||||
|
||||
checkEndpoints('./.github/chain-types.md', [
|
||||
'Unknown types'
|
||||
]);
|
||||
|
||||
88
packages/apps-config/src/ci/check.ts
Normal file
88
packages/apps-config/src/ci/check.ts
Normal file
@ -0,0 +1,88 @@
|
||||
// Copyright 2017-2022 @polkadot/apps-config authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import fs from 'fs';
|
||||
|
||||
import { ApiPromise, WsProvider } from '@polkadot/api';
|
||||
import { assert, isError } from '@polkadot/util';
|
||||
|
||||
import { typesBundle, typesChain } from '../api';
|
||||
import { fetchJson } from './fetch';
|
||||
|
||||
interface DnsResponse {
|
||||
Answer?: { name: string }[];
|
||||
Question: { name: string }[];
|
||||
}
|
||||
|
||||
const TICK = '`';
|
||||
|
||||
export function checkEndpoint (issueFile: string, failures: string[]): (name: string, ws: string) => Promise<boolean> {
|
||||
return async (name: string, ws: string): Promise<boolean> => {
|
||||
const [,, hostWithPort] = ws.split('/');
|
||||
const [host] = hostWithPort.split(':');
|
||||
const json = await fetchJson<DnsResponse>(`https://dns.google/resolve?name=${host}`);
|
||||
|
||||
let provider: WsProvider | null = null;
|
||||
let api: ApiPromise | null = null;
|
||||
let timerId: NodeJS.Timeout | null = null;
|
||||
|
||||
try {
|
||||
assert(json.Answer, `No DNS entry for ${host}`);
|
||||
|
||||
provider = new WsProvider(ws, false);
|
||||
api = new ApiPromise({
|
||||
provider,
|
||||
throwOnConnect: true,
|
||||
throwOnUnknown: false,
|
||||
typesBundle,
|
||||
typesChain
|
||||
});
|
||||
|
||||
setTimeout((): void => {
|
||||
provider &&
|
||||
provider
|
||||
.connect()
|
||||
.catch(() => undefined);
|
||||
}, 1000);
|
||||
|
||||
await Promise.race([
|
||||
// eslint-disable-next-line promise/param-names
|
||||
new Promise((_, reject): void => {
|
||||
timerId = setTimeout((): void => {
|
||||
timerId = null;
|
||||
reject(new Error(`Timeout connecting to ${ws}`));
|
||||
}, 30_000);
|
||||
}),
|
||||
api.isReadyOrError
|
||||
.then((a) => a.rpc.chain.getBlock())
|
||||
.then((b) => console.log(b.toHuman()))
|
||||
]);
|
||||
} catch (error) {
|
||||
if (isError(error) && failures.some((f) => (error as Error).message.includes(f))) {
|
||||
process.env.CI_LOG && fs.appendFileSync(issueFile, `\n${TICK}${name} @ ${ws} ${error.message}${TICK}\n`);
|
||||
|
||||
throw error;
|
||||
}
|
||||
|
||||
console.error(JSON.stringify(error));
|
||||
} finally {
|
||||
if (timerId) {
|
||||
clearTimeout(timerId);
|
||||
}
|
||||
|
||||
if (provider) {
|
||||
try {
|
||||
if (api) {
|
||||
await api.disconnect();
|
||||
} else {
|
||||
await provider.disconnect();
|
||||
}
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Promise.resolve(true);
|
||||
};
|
||||
}
|
||||
38
packages/apps-config/src/ci/fetch.ts
Normal file
38
packages/apps-config/src/ci/fetch.ts
Normal file
@ -0,0 +1,38 @@
|
||||
// Copyright 2017-2022 @polkadot/apps authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { fetch } from '@polkadot/x-fetch';
|
||||
|
||||
// a fetch with a 2s timeout
|
||||
async function fetchWithTimeout (url: string, timeout = 2000): Promise<Response> {
|
||||
const controller = new AbortController();
|
||||
let isAborted = false;
|
||||
const id = setTimeout((): void => {
|
||||
console.log(`Timeout on ${url}`);
|
||||
|
||||
isAborted = true;
|
||||
controller.abort();
|
||||
}, timeout);
|
||||
|
||||
try {
|
||||
const response = await fetch(url, { signal: controller.signal });
|
||||
|
||||
clearTimeout(id);
|
||||
|
||||
return response;
|
||||
} catch (error) {
|
||||
if (!isAborted) {
|
||||
clearTimeout(id);
|
||||
}
|
||||
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
export function fetchJson <T> (url: string, timeout = 2000): Promise<T> {
|
||||
return fetchWithTimeout(url, timeout).then<T>((r) => r.json());
|
||||
}
|
||||
|
||||
export function fetchText (url: string, timeout = 2000): Promise<string> {
|
||||
return fetchWithTimeout(url, timeout).then((r) => r.text());
|
||||
}
|
||||
37
packages/apps-config/src/ci/runner.ts
Normal file
37
packages/apps-config/src/ci/runner.ts
Normal file
@ -0,0 +1,37 @@
|
||||
// Copyright 2017-2022 @polkadot/apps-config authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { isString } from '@polkadot/util';
|
||||
|
||||
import { createWsEndpoints } from '../endpoints';
|
||||
import { checkEndpoint } from './check';
|
||||
|
||||
interface Endpoint {
|
||||
name: string;
|
||||
ws: string;
|
||||
}
|
||||
|
||||
export function checkEndpoints (issueFile: string, failures: string[]): void {
|
||||
const checker = checkEndpoint(issueFile, failures);
|
||||
|
||||
it.each(
|
||||
createWsEndpoints()
|
||||
.filter(({ isDisabled, isUnreachable, value }) =>
|
||||
!isDisabled &&
|
||||
!isUnreachable &&
|
||||
value &&
|
||||
isString(value) &&
|
||||
!value.includes('127.0.0.1') &&
|
||||
!value.startsWith('light://')
|
||||
)
|
||||
.map(({ text, value }): Partial<Endpoint> => ({
|
||||
name: text as string,
|
||||
ws: value
|
||||
}))
|
||||
.filter((v): v is Endpoint => !!v.ws)
|
||||
)('%name @ %$ws', ({ name, ws }): Promise<void> => {
|
||||
console.error(`>>> ${name} @ ${ws}`);
|
||||
|
||||
return checker(name, ws).then((r) => expect(r).toBe(true));
|
||||
});
|
||||
}
|
||||
@ -1,112 +0,0 @@
|
||||
// Copyright 2017-2022 @polkadot/apps-config authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import fs from 'fs';
|
||||
|
||||
import { ApiPromise, WsProvider } from '@polkadot/api';
|
||||
import { assert, isError, isString } from '@polkadot/util';
|
||||
import { fetch } from '@polkadot/x-fetch';
|
||||
|
||||
import { typesBundle, typesChain } from '../api';
|
||||
import { createWsEndpoints } from '../endpoints';
|
||||
|
||||
interface Endpoint {
|
||||
name: string;
|
||||
ws: string;
|
||||
}
|
||||
|
||||
interface DnsResponse {
|
||||
Answer?: { name: string }[];
|
||||
Question: { name: string }[];
|
||||
}
|
||||
|
||||
const TICK = '`';
|
||||
|
||||
export function checkEndpoints (issueFile: string, failures: string[]): void {
|
||||
createWsEndpoints()
|
||||
.filter(({ isDisabled, isUnreachable, value }) =>
|
||||
!isDisabled &&
|
||||
!isUnreachable &&
|
||||
value &&
|
||||
isString(value) &&
|
||||
!value.includes('127.0.0.1') &&
|
||||
!value.startsWith('light://')
|
||||
)
|
||||
.map(({ text, value }): Partial<Endpoint> => ({
|
||||
name: text as string,
|
||||
ws: value
|
||||
}))
|
||||
.filter((v): v is Endpoint => !!v.ws)
|
||||
.forEach(({ name, ws }) =>
|
||||
it(`${name} @ ${ws}`, async (): Promise<void> => {
|
||||
console.error(`>>> ${name} @ ${ws}`);
|
||||
|
||||
const [,, hostWithPort] = ws.split('/');
|
||||
const [host] = hostWithPort.split(':');
|
||||
|
||||
const response = await fetch(`https://dns.google/resolve?name=${host}`);
|
||||
const json = await response.json() as DnsResponse;
|
||||
|
||||
let provider: WsProvider | null = null;
|
||||
let api: ApiPromise | null = null;
|
||||
let timerId: NodeJS.Timeout | null = null;
|
||||
|
||||
try {
|
||||
assert(json.Answer, `No DNS entry for ${host}`);
|
||||
|
||||
provider = new WsProvider(ws, false);
|
||||
api = new ApiPromise({
|
||||
provider,
|
||||
throwOnConnect: true,
|
||||
throwOnUnknown: false,
|
||||
typesBundle,
|
||||
typesChain
|
||||
});
|
||||
|
||||
setTimeout((): void => {
|
||||
provider &&
|
||||
provider
|
||||
.connect()
|
||||
.catch(() => undefined);
|
||||
}, 1000);
|
||||
|
||||
await Promise.race([
|
||||
// eslint-disable-next-line promise/param-names
|
||||
new Promise((_, reject): void => {
|
||||
timerId = setTimeout((): void => {
|
||||
timerId = null;
|
||||
reject(new Error(`Timeout connecting to ${ws}`));
|
||||
}, 30_000);
|
||||
}),
|
||||
api.isReadyOrError
|
||||
.then((a) => a.rpc.chain.getBlock())
|
||||
.then((b) => console.log(b.toHuman()))
|
||||
]);
|
||||
} catch (error) {
|
||||
if (isError(error) && failures.some((f) => (error as Error).message.includes(f))) {
|
||||
process.env.CI_LOG && fs.appendFileSync(issueFile, `\n${TICK}${name} @ ${ws} ${error.message}${TICK}\n`);
|
||||
|
||||
throw error;
|
||||
}
|
||||
|
||||
console.error(JSON.stringify(error));
|
||||
} finally {
|
||||
if (timerId) {
|
||||
clearTimeout(timerId);
|
||||
}
|
||||
|
||||
if (provider) {
|
||||
try {
|
||||
if (api) {
|
||||
await api.disconnect();
|
||||
} else {
|
||||
await provider.disconnect();
|
||||
}
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user