mirror of
https://github.com/logos-messaging/js-waku.git
synced 2026-01-03 22:33:07 +00:00
feat: introduce WSS checker CI (#2366)
* feat: introduce WSS checker CI * rename CI step * specify nodejs * try * remove not needed dep * use npx and fail on failure * run by dispatch only and improve naming * fix fail detection
This commit is contained in:
parent
fd2f5b7b8d
commit
e45736ff98
@ -116,7 +116,10 @@
|
||||
{
|
||||
"files": ["**/ci/*.js"],
|
||||
"rules": {
|
||||
"no-undef": "off"
|
||||
"no-undef": "off",
|
||||
"@typescript-eslint/explicit-member-accessibility": "off",
|
||||
"@typescript-eslint/no-floating-promises": "off",
|
||||
"import/no-extraneous-dependencies": "off"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
26
.github/workflows/fleet-checker.yml
vendored
Normal file
26
.github/workflows/fleet-checker.yml
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
NODE_JS: "20"
|
||||
|
||||
jobs:
|
||||
pre-release:
|
||||
name: fleet-checker
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name == 'workflow_dispatch'
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
repository: waku-org/js-waku
|
||||
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ env.NODE_JS }}
|
||||
registry-url: "https://registry.npmjs.org"
|
||||
|
||||
- run: npm install
|
||||
|
||||
- run: npm run build
|
||||
|
||||
- run: node --unhandled-rejections=none ./ci/wss-checker.js
|
||||
3
.github/workflows/pre-release.yml
vendored
3
.github/workflows/pre-release.yml
vendored
@ -1,6 +1,9 @@
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
NODE_JS: "20"
|
||||
|
||||
jobs:
|
||||
pre-release:
|
||||
name: pre-release
|
||||
|
||||
192
ci/wss-checker.js
Normal file
192
ci/wss-checker.js
Normal file
@ -0,0 +1,192 @@
|
||||
import cp from "child_process";
|
||||
import { promisify } from "util";
|
||||
|
||||
import { createLightNode } from "@waku/sdk";
|
||||
|
||||
const exec = promisify(cp.exec);
|
||||
|
||||
class Fleet {
|
||||
static async create() {
|
||||
const url = "https://fleets.status.im";
|
||||
|
||||
try {
|
||||
const response = await fetch(url);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! Status: ${response.status}`);
|
||||
}
|
||||
|
||||
const fleet = await response.json();
|
||||
|
||||
if (!Fleet.isRecordValid(fleet)) {
|
||||
throw Error("invalid_fleet_record");
|
||||
}
|
||||
|
||||
return new Fleet(fleet);
|
||||
} catch (error) {
|
||||
console.error(`Error fetching data from ${url}:`, error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
static isRecordValid(fleet) {
|
||||
let isValid = true;
|
||||
|
||||
if (!fleet.fleets) {
|
||||
console.error("No fleet records are present.");
|
||||
isValid = false;
|
||||
}
|
||||
|
||||
if (!fleet.fleets["waku.sandbox"]) {
|
||||
console.error("No waku.sandbox records are present.");
|
||||
isValid = false;
|
||||
} else if (!fleet.fleets["waku.sandbox"]["wss/p2p/waku"]) {
|
||||
console.error("No waku.sandbox WSS multi-addresses are present.");
|
||||
isValid = false;
|
||||
}
|
||||
|
||||
if (!fleet.fleets["waku.test"]) {
|
||||
console.error("No waku.test records are present.");
|
||||
isValid = false;
|
||||
} else if (!fleet.fleets["waku.test"]["wss/p2p/waku"]) {
|
||||
console.error("No waku.test WSS multi-addresses are present.");
|
||||
isValid = false;
|
||||
}
|
||||
|
||||
if (!isValid) {
|
||||
console.error(`Got ${JSON.stringify(fleet)}`);
|
||||
}
|
||||
|
||||
return isValid;
|
||||
}
|
||||
|
||||
constructor(fleet) {
|
||||
this.fleet = fleet;
|
||||
}
|
||||
|
||||
get sandbox() {
|
||||
return this.fleet.fleets["waku.sandbox"]["wss/p2p/waku"];
|
||||
}
|
||||
|
||||
get test() {
|
||||
return this.fleet.fleets["waku.test"]["wss/p2p/waku"];
|
||||
}
|
||||
}
|
||||
|
||||
class ConnectionChecker {
|
||||
static waku;
|
||||
static lock = false;
|
||||
|
||||
static async checkPlainWss(maddrs) {
|
||||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "1";
|
||||
|
||||
const results = await Promise.all(
|
||||
maddrs.map((v) => ConnectionChecker.dialPlainWss(v))
|
||||
);
|
||||
|
||||
console.log(
|
||||
"Raw WSS connection:\n",
|
||||
results.map(([addr, result]) => `${addr}:\t${result}`).join("\n")
|
||||
);
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
static async dialPlainWss(maddr) {
|
||||
const { domain, port } = ConnectionChecker.parseMaddr(maddr);
|
||||
return [
|
||||
maddr,
|
||||
await ConnectionChecker.spawn(`npx wscat -c wss://${domain}:${port}`)
|
||||
];
|
||||
}
|
||||
|
||||
static async checkWakuWss(maddrs) {
|
||||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
|
||||
|
||||
const waku = await createLightNode({
|
||||
defaultBootstrap: false,
|
||||
libp2p: {
|
||||
hideWebSocketInfo: true
|
||||
},
|
||||
networkConfig: {
|
||||
clusterId: 42,
|
||||
shards: [0]
|
||||
}
|
||||
});
|
||||
|
||||
const results = await Promise.all(
|
||||
maddrs.map((v) => ConnectionChecker.dialWaku(waku, v))
|
||||
);
|
||||
|
||||
console.log(
|
||||
"Libp2p WSS connection:\n",
|
||||
results.map(([addr, result]) => `${addr}:\t${result}`).join("\n")
|
||||
);
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
static async dialWaku(waku, maddr) {
|
||||
try {
|
||||
await waku.dial(maddr);
|
||||
return [maddr, "OK"];
|
||||
} catch (e) {
|
||||
return [maddr, "FAIL"];
|
||||
}
|
||||
}
|
||||
|
||||
static parseMaddr(multiaddr) {
|
||||
const regex = /\/dns4\/([^/]+)\/tcp\/(\d+)/;
|
||||
const match = multiaddr.match(regex);
|
||||
|
||||
if (!match) {
|
||||
throw new Error(
|
||||
"Invalid multiaddress format. Expected /dns4/domain/tcp/port pattern."
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
domain: match[1],
|
||||
port: parseInt(match[2], 10)
|
||||
};
|
||||
}
|
||||
|
||||
static async spawn(command) {
|
||||
try {
|
||||
console.info(`Spawning command: ${command}`);
|
||||
const { stderr } = await exec(command);
|
||||
return stderr || "OK";
|
||||
} catch (e) {
|
||||
return "FAIL";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function run() {
|
||||
const fleet = await Fleet.create();
|
||||
const sandbox = Object.values(fleet.sandbox);
|
||||
const test = Object.values(fleet.test);
|
||||
|
||||
let maddrs = [...sandbox, ...test];
|
||||
|
||||
const plainWssResult = await ConnectionChecker.checkPlainWss(maddrs);
|
||||
const wakuWssResult = await ConnectionChecker.checkWakuWss(maddrs);
|
||||
|
||||
const plainWssFail = plainWssResult.some(([_, status]) => status === "FAIL");
|
||||
const wakuWssFail = wakuWssResult.some(([_, status]) => status === "FAIL");
|
||||
|
||||
if (plainWssFail || wakuWssFail) {
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
(async () => {
|
||||
try {
|
||||
await run();
|
||||
} catch (error) {
|
||||
console.error("Unhandled error:", error);
|
||||
process.exit(1);
|
||||
}
|
||||
})();
|
||||
48
package-lock.json
generated
48
package-lock.json
generated
@ -23,9 +23,6 @@
|
||||
"packages/build-utils",
|
||||
"packages/react-native-polyfills"
|
||||
],
|
||||
"dependencies": {
|
||||
"@waku/utils": "^0.0.21"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@size-limit/preset-big-lib": "^11.0.2",
|
||||
"@typescript-eslint/eslint-plugin": "^6.6.0",
|
||||
@ -50,7 +47,8 @@
|
||||
"ts-loader": "^9.5.1",
|
||||
"ts-node": "^10.9.2",
|
||||
"typedoc": "^0.25.9",
|
||||
"typescript": "^5.3.3"
|
||||
"typescript": "^5.3.3",
|
||||
"wscat": "^6.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@ampproject/remapping": {
|
||||
@ -41704,6 +41702,48 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/wscat": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/wscat/-/wscat-6.0.1.tgz",
|
||||
"integrity": "sha512-a2xnAkRYBQ879s7BuUXJk4k/z22mk+a7l95aVK7GzY5d9DCb//i1PsbRT/Z80EJXHXbvp8VDBK38P0Xv+/ruJA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"commander": "^12.1.0",
|
||||
"https-proxy-agent": "^7.0.5",
|
||||
"read": "^4.0.0",
|
||||
"ws": "^8.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"wscat": "bin/wscat"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/wscat/node_modules/mute-stream": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-2.0.0.tgz",
|
||||
"integrity": "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": "^18.17.0 || >=20.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/wscat/node_modules/read": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/read/-/read-4.1.0.tgz",
|
||||
"integrity": "sha512-uRfX6K+f+R8OOrYScaM3ixPY4erg69f8DN6pgTvMcA9iRc8iDhwrA4m3Yu8YYKsXJgVvum+m8PkRboZwwuLzYA==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"mute-stream": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.17.0 || >=20.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/xcode": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/xcode/-/xcode-3.0.1.tgz",
|
||||
|
||||
@ -65,14 +65,12 @@
|
||||
"ts-loader": "^9.5.1",
|
||||
"ts-node": "^10.9.2",
|
||||
"typedoc": "^0.25.9",
|
||||
"typescript": "^5.3.3"
|
||||
"typescript": "^5.3.3",
|
||||
"wscat": "^6.0.1"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.{ts,js}": [
|
||||
"eslint --fix"
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@waku/utils": "^0.0.21"
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user