-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
/
index.js
153 lines (106 loc) · 5.04 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/** @file Runs all smoke tests and may add extra smoke-test dependencies to `yarn.lock`. */
// @ts-check
import Zip from 'adm-zip';
import { execa } from 'execa';
import { polyfill } from '@astropub/webapi';
import { fileURLToPath } from 'node:url';
import { promises as fs } from 'node:fs';
polyfill(globalThis, { exclude: 'window document' });
/* Configuration
/* -------------------------------------------------------------------------- */
/** URL directory containing this current script. */
const scriptDir = new URL('./', import.meta.url);
/** URL directory containing the entire project. */
const rootDir = new URL('../../', import.meta.url);
/** URL directory containing the example subdirectories. */
const exampleDir = new URL('examples/', rootDir);
/** URL directory containing the Astro package. */
const astroDir = new URL('packages/astro/', rootDir);
/** GitHub configuration for the external "docs" Astro project. */
const docGithubConfig = { org: 'withastro', name: 'docs', branch: 'main' };
/** GitHub configuration for the external "astro.build" Astro project. */
const wwwGithubConfig = { org: 'withastro', name: 'astro.build', branch: 'main' };
/* Application
/* -------------------------------------------------------------------------- */
/** Runs all smoke tests. */
async function run() {
console.log('');
const directories = await getChildDirectories(exampleDir);
// TODO Skipped the docs-main test since it is failing at the moment.
directories.push(/*await downloadGithubZip(docGithubConfig), */ await downloadGithubZip(wwwGithubConfig));
console.log('🤖', 'Preparing', 'yarn');
await execa('yarn', [], { cwd: fileURLToPath(rootDir), stdout: 'inherit', stderr: 'inherit' });
for (const directory of directories) {
console.log('🤖', 'Testing', directory.pathname.split('/').at(-1));
try {
await execa('yarn', ['build'], { cwd: fileURLToPath(directory), stdout: 'inherit', stderr: 'inherit' });
} catch (err) {
console.log(err);
process.exit(1);
}
// Run with the static build too
if(directory.pathname.includes('astro.build')) {
// astro.build uses the static build, so rerunning with the flag actually negates it.
continue;
}
try {
await execa('yarn', ['build', '--', '--experimental-static-build'], { cwd: fileURLToPath(directory), stdout: 'inherit', stderr: 'inherit' });
} catch (err) {
console.log(err);
process.exit(1);
}
console.log();
}
}
/* Functionality
/* -------------------------------------------------------------------------- */
/** Returns the URL to the ZIP of the given GitHub project. */
const getGithubZipURL = (/** @type {GithubOpts} */ opts) => `https://github.com/${opts.org}/${opts.name}/archive/refs/heads/${opts.branch}.zip`;
/** Returns the awaited ZIP Buffer from the given GitHub project. */
const fetchGithubZip = (/** @type {GithubOpts} */ opts) =>
fetch(getGithubZipURL(opts))
.then((response) => response.arrayBuffer())
.then((arrayBuffer) => Buffer.from(arrayBuffer));
/** Downloads a ZIP from the given GitHub project. */
const downloadGithubZip = async (/** @type {GithubOpts} */ opts) => {
/** Expected directory when the zip is downloaded. */
const githubDir = new URL(`${opts.name}-${opts.branch}`, scriptDir);
console.log('🤖', 'Downloading', `${opts.org}/${opts.name}#${opts.branch}`);
const buffer = await fetchGithubZip(opts);
console.log('🤖', 'Extracting', `${opts.org}/${opts.name}#${opts.branch}`);
new Zip(buffer).extractAllTo(fileURLToPath(scriptDir), true);
console.log('🤖', 'Preparing', `${opts.org}/${opts.name}#${opts.branch}`);
const astroPackage = await readDirectoryPackage(astroDir);
const githubPackage = await readDirectoryPackage(githubDir);
if ('astro' in Object(githubPackage.dependencies)) {
githubPackage.dependencies['astro'] = astroPackage.version;
}
if ('astro' in Object(githubPackage.devDependencies)) {
githubPackage.devDependencies['astro'] = astroPackage.version;
}
if ('astro' in Object(githubPackage.peerDependencies)) {
githubPackage.peerDependencies['astro'] = astroPackage.version;
}
await writeDirectoryPackage(githubDir, githubPackage);
return githubDir;
};
/** Returns the parsed package.json of the given directory. */
const readDirectoryPackage = async (/** @type {URL} */ dir) => JSON.parse(await fs.readFile(new URL('package.json', dir + '/'), 'utf-8'));
/** Returns upon completion of writing a package.json to the given directory. */
const writeDirectoryPackage = async (/** @type {URL} */ dir, /** @type {any} */ data) =>
await fs.writeFile(new URL('package.json', dir + '/'), JSON.stringify(data, null, ' ') + '\n');
/** Returns all child directories of the given directory. */
const getChildDirectories = async (/** @type {URL} */ dir) => {
/** @type {URL[]} */
const dirs = [];
for await (const dirent of await fs.opendir(dir)) {
if (dirent.isDirectory()) {
dirs.push(new URL(dirent.name, dir));
}
}
return dirs;
};
/* Execution
/* -------------------------------------------------------------------------- */
run();
/** @typedef {{ org: string, name: string, branch: string }} GithubOpts */