feat(JavaScript): Add the workflow file for CI check (#1296)
* feat(JavaScript): Add the workflow file for CI check * Apply suggestions from code review Co-authored-by: krahets <krahets@163.com> * Test failure * Update javascript.yml * Test success --------- Co-authored-by: Yudong Jin <krahets@163.com>pull/1303/head
parent
a7f4340e55
commit
1a99dd420f
@ -0,0 +1,27 @@
|
|||||||
|
name: JavaScript
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: ['main']
|
||||||
|
paths: ['codes/javascript/**/*.js']
|
||||||
|
pull_request:
|
||||||
|
branches: ['main']
|
||||||
|
paths: ['codes/javascript/**/*.js']
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: 20.x
|
||||||
|
- uses: denoland/setup-deno@v1
|
||||||
|
with:
|
||||||
|
deno-version: v1.x
|
||||||
|
- name: Run JavaScript Code
|
||||||
|
run: deno run -A codes/javascript/test_all.js
|
@ -0,0 +1,63 @@
|
|||||||
|
import { bold, brightRed } from 'jsr:@std/fmt/colors';
|
||||||
|
import { expandGlob } from 'jsr:@std/fs';
|
||||||
|
import { relative, resolve } from 'jsr:@std/path';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {import('jsr:@std/fs').WalkEntry} WalkEntry
|
||||||
|
* @type {WalkEntry[]}
|
||||||
|
*/
|
||||||
|
const entries = [];
|
||||||
|
|
||||||
|
for await (const entry of expandGlob(
|
||||||
|
resolve(import.meta.dirname, './chapter_*/*.js')
|
||||||
|
)) {
|
||||||
|
entries.push(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @type {{ status: Promise<Deno.CommandStatus>; stderr: ReadableStream<Uint8Array>; }[]} */
|
||||||
|
const processes = [];
|
||||||
|
|
||||||
|
for (const file of entries) {
|
||||||
|
const execute = new Deno.Command('node', {
|
||||||
|
args: [relative(import.meta.dirname, file.path)],
|
||||||
|
cwd: import.meta.dirname,
|
||||||
|
stdin: 'piped',
|
||||||
|
stdout: 'piped',
|
||||||
|
stderr: 'piped',
|
||||||
|
});
|
||||||
|
|
||||||
|
const process = execute.spawn();
|
||||||
|
processes.push({ status: process.status, stderr: process.stderr });
|
||||||
|
}
|
||||||
|
|
||||||
|
const results = await Promise.all(
|
||||||
|
processes.map(async (item) => {
|
||||||
|
const status = await item.status;
|
||||||
|
return { status, stderr: item.stderr };
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
/** @type {ReadableStream<Uint8Array>[]} */
|
||||||
|
const errors = [];
|
||||||
|
|
||||||
|
for (const result of results) {
|
||||||
|
if (!result.status.success) {
|
||||||
|
errors.push(result.stderr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`Tested ${entries.length} files`);
|
||||||
|
console.log(`Found exception in ${errors.length} files`);
|
||||||
|
|
||||||
|
if (errors.length) {
|
||||||
|
console.log();
|
||||||
|
|
||||||
|
for (const error of errors) {
|
||||||
|
const reader = error.getReader();
|
||||||
|
const { value } = await reader.read();
|
||||||
|
const decoder = new TextDecoder();
|
||||||
|
console.log(`${bold(brightRed('error'))}: ${decoder.decode(value)}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error('Test failed');
|
||||||
|
}
|
Loading…
Reference in new issue