Skip to content

Commit c7df4e9

Browse files
committed
feat(scripts/ci): achieve near-feature-parity with original CI workflow
1 parent b555045 commit c7df4e9

2 files changed

Lines changed: 91 additions & 9 deletions

File tree

scripts/ci/main.ts

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,41 @@
1-
import { notice } from '@actions/core';
2-
import { bold } from '@std/fmt/colors';
1+
import { permissionArgs, runCommands } from '@encode/ci/lib';
32

43
export async function main(): Promise<void> {
5-
const ci = Deno.env.get('CI');
6-
7-
if (ci) {
8-
console.log("We're in a CI environment!", { ci });
9-
} else {
10-
console.log(`We are ${bold('not')} in a CI environment!`);
11-
}
4+
await runCommands([
5+
{
6+
name: 'Biome checks',
7+
args: [
8+
Deno.execPath(),
9+
{
10+
args: ['run', ...permissionArgs('biome'), 'npm:@biomejs/biome', 'ci'],
11+
stderr: 'piped',
12+
stdout: 'piped',
13+
},
14+
],
15+
},
16+
{
17+
name: 'Deno checks',
18+
args: [
19+
Deno.execPath(),
20+
{
21+
args: ['check'],
22+
stderr: 'piped',
23+
stdout: 'piped',
24+
},
25+
],
26+
},
27+
{
28+
name: 'Tests',
29+
args: [
30+
Deno.execPath(),
31+
{
32+
args: ['test', ...permissionArgs(), '--coverage', '--shuffle'],
33+
stderr: 'piped',
34+
stdout: 'piped',
35+
},
36+
],
37+
},
38+
]);
1239
}
1340

1441
if (import.meta.main) {

scripts/ci/mod.ts

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import { error } from '@actions/core';
2+
import { bold, red } from '@std/fmt/colors';
3+
4+
export interface CommandParams {
5+
name: string;
6+
args: ConstructorParameters<typeof Deno.Command>;
7+
}
8+
9+
export async function runCommands(
10+
commandParams: Iterable<CommandParams, void, undefined>,
11+
): Promise<void> {
12+
const processes = Array.from(commandParams, ({ name, args }) => {
13+
return { name, process: new Deno.Command(...args).spawn() };
14+
});
15+
16+
for (const [idx, { name, process }] of processes.entries()) {
17+
await Promise.all([
18+
process.stderr.pipeTo(Deno.stderr.writable, { preventClose: true, preventAbort: true }),
19+
process.stdout.pipeTo(Deno.stdout.writable, { preventClose: true, preventAbort: true }),
20+
]);
21+
22+
if (!(await process.status).success) {
23+
console.log('\n');
24+
25+
annotateError({ title: 'CI', message: `${name} failed!` });
26+
}
27+
28+
if (idx !== processes.length - 1) {
29+
console.log(`\n${bold('-'.repeat(Deno.consoleSize().columns))}\n\n`);
30+
}
31+
}
32+
}
33+
34+
export function isCI() {
35+
return Deno.env.get('CI') === 'true';
36+
}
37+
38+
export function permissionArgs(permissionSetName?: string): string[] {
39+
return [permissionSetName ? `-P=${permissionSetName}` : '-P', '--no-prompt'];
40+
}
41+
42+
interface Annotation {
43+
title: string;
44+
message: string;
45+
}
46+
47+
function annotateError(annotation: Annotation): void {
48+
const { title, message } = annotation;
49+
50+
if (isCI()) {
51+
error(red(message), { title });
52+
} else {
53+
console.error(`${bold(`${title}:`)} ${red(message)}`);
54+
}
55+
}

0 commit comments

Comments
 (0)