Skip to content

Commit

Permalink
ci(github): add check to validate exported types being correct
Browse files Browse the repository at this point in the history
Primary Changes
---------------
1. Added get-all-tgz-path.ts to get all tgz files path
2. Added run-attw-on-tgz.ts to run attw on each tgz filepath
3. Added are-the-types-wrong as part of the custom-checks mechanism

Fixes: hyperledger-cacti#3140

Signed-off-by: ruzell22 <ruzell.vince.aquino@accenture.com>
  • Loading branch information
ruzell22 authored and petermetz committed Nov 13, 2024
1 parent 5e3d9d7 commit 4424bf9
Show file tree
Hide file tree
Showing 6 changed files with 414 additions and 3 deletions.
1 change: 1 addition & 0 deletions .cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"approveformyorg",
"askar",
"Askar",
"attw",
"Authz",
"authzn",
"AWSSM",
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
"tools:fix-pkg-npm-scope": "TS_NODE_PROJECT=tools/tsconfig.json node --experimental-json-modules --trace-deprecation --experimental-modules --abort-on-uncaught-exception --loader ts-node/esm --experimental-specifier-resolution=node ./tools/custom-checks/check-pkg-npm-scope.ts",
"tools:sort-package-json": "TS_NODE_PROJECT=tools/tsconfig.json node --experimental-json-modules --trace-deprecation --experimental-modules --abort-on-uncaught-exception --loader ts-node/esm --experimental-specifier-resolution=node ./tools/sort-package-json.ts",
"tools:check-missing-node-deps": "TS_NODE_PROJECT=tools/tsconfig.json node --experimental-json-modules --trace-deprecation --experimental-modules --abort-on-uncaught-exception --loader ts-node/esm --experimental-specifier-resolution=node ./tools/custom-checks/check-missing-node-deps.ts",
"tools:are-the-types-wrong": "TS_NODE_PROJECT=./tools/tsconfig.json node --trace-deprecation --experimental-modules --abort-on-uncaught-exception --loader ts-node/esm --experimental-specifier-resolution=node ./tools/custom-checks/run-attw-on-tgz.ts",
"generate-api-server-config": "node ./tools/generate-api-server-config.js",
"sync-ts-config": "TS_NODE_PROJECT=tools/tsconfig.json node --experimental-json-modules --loader ts-node/esm ./tools/sync-npm-deps-to-tsc-projects.ts",
"start:api-server": "node ./packages/cactus-cmd-api-server/dist/lib/main/typescript/cmd/cactus-api.js --config-file=.config.json",
Expand Down Expand Up @@ -121,6 +122,7 @@
"zod": ">=3.22.3"
},
"devDependencies": {
"@arethetypeswrong/cli": "0.16.4",
"@babel/parser": "7.24.7",
"@babel/types": "7.24.7",
"@bufbuild/buf": "1.30.0",
Expand Down
76 changes: 76 additions & 0 deletions tools/custom-checks/get-all-tgz-path.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import path from "path";
import { fileURLToPath } from "url";
import { globby, Options as GlobbyOptions } from "globby";
import lernaCfg from "../../lerna.json" assert { type: "json" };

/**
* Interface for the response of the getAllTgzPath function.
* @property {Array<string>} relativePaths - An array of relative paths to the
* package directories.
*/

export interface IGetAllTgzPathResponse {
readonly relativePaths: Readonly<Array<string>>;
}

/**
* Asynchronous function to get all tgz filepaths in a Lerna monorepo.
* @returns {Promise<IGetAllTgzPathResponse>} A promise that resolves to an
* object containing the arrays of relative paths to the all tgz files.
*/

export async function getAllTgzPath(): Promise<IGetAllTgzPathResponse> {
const TAG = "[tools/get-all-tgz-path.ts]";
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const SCRIPT_DIR = __dirname;
const PROJECT_DIR = path.join(SCRIPT_DIR, "../../");

console.log(`${TAG} SCRIPT_DIR=${SCRIPT_DIR}`);
console.log(`${TAG} PROJECT_DIR=${PROJECT_DIR}`);

const globbyOpts: GlobbyOptions = {
cwd: PROJECT_DIR,
onlyFiles: true,
expandDirectories: false,
// ignore pattern is added temporarily so that the yarn custom-checks github action will pass. These packages
// are failing and needs to be fixed. Each issue ticket link is added above each ignore path. More details and
// links are in the description of the issue ticket.
ignore: [
"**/node_modules",
// link for issue ticket relating to this package: https://github.com/hyperledger-cacti/cacti/issues/3623
"weaver/core/drivers/fabric-driver/hyperledger-cacti-weaver-driver-fabric-*.tgz",
// link for issue ticket relating to this package: https://github.com/hyperledger-cacti/cacti/issues/3626
"weaver/core/identity-management/iin-agent/hyperledger-cacti-weaver-iin-agent-*.tgz",
// link for issue ticket relating to this package: https://github.com/hyperledger-cacti/cacti/issues/3627
"weaver/sdks/fabric/interoperation-node-sdk/hyperledger-cacti-weaver-sdk-fabric-*.tgz",
// link for issue ticket relating to this package: https://github.com/hyperledger-cacti/cacti/issues/3628
"packages/cacti-plugin-weaver-driver-fabric/src/main/typescript/hyperledger-cacti-weaver-driver-fabric-*.tgz",
// link for issue ticket relating to this package: https://github.com/hyperledger-cacti/cacti/issues/3629
"packages/cacti-plugin-copm-fabric/hyperledger-cacti-cacti-plugin-copm-fabric-*.tgz",
// link for issue ticket relating to this package: https://github.com/hyperledger-cacti/cacti/issues/3630
"packages/cacti-ledger-browser/hyperledger-cacti-ledger-browser-*.tgz",
// link for issue ticket relating to this package: https://github.com/hyperledger-cacti/cacti/issues/3631
"examples/cactus-example-cbdc-bridging-frontend/hyperledger-cacti-example-cbdc-bridging-frontend-*.tgz",
// link for issue ticket relating to this package: https://github.com/hyperledger-cacti/cacti/issues/3632
"examples/cactus-common-example-server/hyperledger-cactus-common-example-server-*.tgz",
// link for issue ticket relating to this package: https://github.com/hyperledger-cacti/cacti/issues/3633
"packages/cactus-verifier-client/hyperledger-cactus-verifier-client-*.tgz",
// link for issue ticket relating to this package: https://github.com/hyperledger-cacti/cacti/issues/3634
"packages/cactus-plugin-ledger-connector-polkadot/hyperledger-cactus-plugin-ledger-connector-polkadot-*.tgz",
// link for issue ticket relating to this package: https://github.com/hyperledger-cacti/cacti/issues/3635
"packages/cactus-common/hyperledger-cactus-common-*.tgz",
],
};

const tgzFilesPattern = lernaCfg.packages.map(
(pkg: string) => `${pkg}/**/hyperledger-*.tgz`,
);

const tgzFilesRelative = await globby(tgzFilesPattern, globbyOpts);
console.log("%s Found %s tgz files.", TAG, tgzFilesRelative.length);

return {
relativePaths: tgzFilesRelative,
};
}
105 changes: 105 additions & 0 deletions tools/custom-checks/run-attw-on-tgz.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import esMain from "es-main";
import { getAllTgzPath } from "./get-all-tgz-path";
import { exit } from "process";
import { rm } from "fs";
import { spawn } from "child_process";

// New function to stream subprocess output in real-time
function spawnPromise(
command: string,
args: string[],
options = {},
): Promise<string> {
return new Promise((resolve, reject) => {
const child = spawn(command, args, { shell: true, ...options });
let output = "";

// Append stdout and stderr to the output string
child.stdout.on("data", (data) => {
process.stdout.write(data);
output += data.toString();
});

child.stderr.on("data", (data) => {
process.stderr.write(data);
output += data.toString();
});

child.on("close", (code) => {
if (code === 0) {
resolve(output);
} else {
const error = new Error(`Process exited with code ${code}`);
(error as any).output = output;
reject(error);
}
});

child.on("error", (err) => reject(err));
});
}

async function cleanUpTgzFiles(): Promise<void> {
const TAG = "[tools/custom-checks/run-attw-on-tgz.ts]";
console.log(`${TAG} Cleaning up existing .tgz files...`);

const { relativePaths: tgzFilesRelative } = await getAllTgzPath();

for (const filePath of tgzFilesRelative) {
await rm(filePath, { recursive: true, force: true }, () => {});
console.log(`${TAG} Deleted ${filePath}`);
}
}

export async function runAttwOnTgz(): Promise<[boolean, string[]]> {
await cleanUpTgzFiles();

const TAG = "[tools/custom-checks/run-attw-on-tgz.ts]";
await execCommand("yarn lerna exec 'npm pack'", true);
console.log(`${TAG} Packaging .tgz files`);

console.log(`${TAG} Fetching .tgz file paths.`);
const { relativePaths: tgzFilesRelative } = await getAllTgzPath();

const attwFailedPackages: string[] = [];

for (const filePath of tgzFilesRelative) {
try {
const output = await execCommand("attw", filePath);
console.log(output);
} catch (error: any) {
attwFailedPackages.push(
`ERROR ${filePath}: ${error.message}\n${error.output || ""}`,
);
}
}

const success = attwFailedPackages.length === 0;
return [success, attwFailedPackages];
}

async function execCommand(
binaryName: string,
argument: string | boolean,
): Promise<string> {
let command;
if (typeof argument === "boolean") {
command = binaryName;
} else if (typeof argument === "string") {
command = `${binaryName} ./${argument}`;
} else {
throw new Error("Invalid arguments for execCommand");
}

return await spawnPromise(command, []);
}

if (esMain(import.meta)) {
const [success, attwFailedPackages] = await runAttwOnTgz();
if (!success) {
console.log("Types are wrong for these packages:");
console.log(attwFailedPackages);
exit(1);
}
exit(0);
}
7 changes: 7 additions & 0 deletions tools/custom-checks/run-custom-checks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
checkMissingNodeDeps,
} from "./check-missing-node-deps";
import { getAllPkgDirs } from "./get-all-pkg-dirs";
import { runAttwOnTgz } from "./run-attw-on-tgz";

export async function runCustomChecks(
argv: string[],
Expand Down Expand Up @@ -73,6 +74,12 @@ export async function runCustomChecks(
overallSuccess = overallSuccess && success;
}

{
const [success, errors] = await runAttwOnTgz();
overallErrors = overallErrors.concat(errors);
overallSuccess = overallSuccess && success;
}

if (!overallSuccess) {
overallErrors.forEach((it) => console.error(it));
} else {
Expand Down
Loading

0 comments on commit 4424bf9

Please sign in to comment.