Skip to content

Commit 0f8350d

Browse files
authored
chore: update deno.lock and freeze install during build (RocketChat#40038)
1 parent 5052af2 commit 0f8350d

File tree

2 files changed

+139
-75
lines changed

2 files changed

+139
-75
lines changed

packages/apps-engine/deno-runtime/deno.lock

Lines changed: 69 additions & 69 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/apps-engine/scripts/deno-cache.js

Lines changed: 70 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,85 @@
11
const childProcess = require('child_process');
2+
const fs = require('fs');
23
const path = require('path');
34

5+
const SHELL_ERR_CMD_NOT_FOUND = 127;
6+
const { CI } = process.env;
7+
8+
/**
9+
* Matches 'deno 2.3.1' or 'Deno 2.7.11-alpha3.24' or even 'some deno and-anything in between 1.43.5' (as long as everything is in the same line)
10+
* and extracts the correct version string from those ('2.3.1', '2.7.11' and '1.43.5' respectively).
11+
*
12+
* Doesn't match 'denoing 2.3.1' or 'deno2.3.1' or 'mydeno 2.7.11alpha3.24' or 'deno\n1.43.5'
13+
*
14+
* The expression gets a bit complicated because the word boundary assertion (\b) identifies the dash (-) as a valid word boundary,
15+
* but that is not the case for use, as we don't want to match "make-deno" for instance. So, for correctness, we use a negative lookbehind
16+
* assertion ("(?<!)") BEFORE words to make sure our match is not preceded by a word character (\w), a dash (-) or a dot (.), e.g. it won't
17+
* match "mydeno", "my-deno", "my.deno", etc. The negative lookbehind also allows us to match "deno" in the start of the input, something that
18+
* simply using the expression itself wouldn't match. In most other cases, these would be replaced by simply "\b"
19+
*
20+
* The exact expression tries find the first line to match a sequence as follows:
21+
* - A character "D" or "d" that is not preceded by a word character, dash or dot (negative lookbehind)
22+
* - Followed by the literal sequence "eno"
23+
* - Followed by any character that is not a word character, dash or dot
24+
* - Followed by a sequence of zero or more occurrences of any character (non multi line)
25+
* - Followed by a sequence of one or more numbers, then a dot, then one or more numbers, then a dot, then one or more numbers ("version" capture group)
26+
* that is NOT preceded by a word character, a dash, or dot (negative lookbehind)
27+
* - Followed by a word boundary (here we're less picky with the "\b" assertion, as we're out of the capture group)
28+
*/
29+
const extractDenoVersion = (input) => /(?<![\w-.])[Dd]eno[^\w-.].*(?<![\w-.])(?<version>\d+\.\d+\.\d+)\b/.exec(input)?.groups?.version;
30+
431
try {
5-
childProcess.execSync('deno info');
32+
const toolVersionsPath = path.resolve(__dirname, '..', '..', '..', '.tool-versions');
33+
const denoToolVersion = extractDenoVersion(fs.readFileSync(toolVersionsPath).toString());
34+
35+
if (!denoToolVersion) {
36+
throw new Error(`Invalid Deno version in ${toolVersionsPath}, aborting...`);
37+
}
38+
39+
const installedVersion = extractDenoVersion(childProcess.execSync('deno --version').toString());
40+
41+
if (!installedVersion) {
42+
throw new Error(
43+
`Couldn't determine version of installed Deno. Try validating the version with 'deno --version' and make sure it is a valid Deno installation`,
44+
);
45+
}
46+
47+
if (installedVersion !== denoToolVersion) {
48+
const message = `Incorrect Deno version. Required '${denoToolVersion}', found '${installedVersion}'.${CI ? '' : " The server will likely work, but it may cause your deno.lock to change - do not commit it. Make sure your Deno version matches the required one so you don't see this message again."}`;
49+
50+
if (CI) {
51+
throw new Error(message);
52+
}
53+
54+
// We don't need to fail if a dev environment doesn't have a matching Deno version, just the warning is enough
55+
console.warn(message);
56+
}
657
} catch (e) {
7-
console.error(
8-
'Could not execute "deno" in the system. It is now a requirement for the Apps-Engine framework, and Rocket.Chat apps will not work without it.\n',
9-
'Make sure to install Deno and run the installation process for the Apps-Engine again. More info on https://docs.deno.com/runtime/manual/getting_started/installation',
10-
);
58+
if (e.status === SHELL_ERR_CMD_NOT_FOUND) {
59+
console.error(
60+
new Error(
61+
[
62+
'Could not execute "deno" in the system. It is now a requirement for the Apps-Engine framework, and Rocket.Chat apps will not work without it.',
63+
'Make sure to install Deno and run the installation process for the Apps-Engine again. More info on https://docs.deno.com/runtime/manual/getting_started/installation',
64+
].join('\n'),
65+
{ cause: e },
66+
),
67+
);
68+
} else {
69+
console.error(e);
70+
}
71+
1172
process.exit(1);
1273
}
1374

1475
const rootPath = path.join(__dirname, '..');
1576
const denoRuntimePath = path.join(rootPath, 'deno-runtime');
1677
const DENO_DIR = process.env.DENO_DIR ?? path.join(rootPath, '.deno-cache');
1778

18-
childProcess.execSync('deno cache main.ts', {
79+
// In CI envs, break if lockfile changes; in dev envs, it's alright
80+
const commandLine = CI ? 'deno install --frozen --entrypoint main.ts' : 'deno install --entrypoint main.ts';
81+
82+
childProcess.execSync(commandLine, {
1983
cwd: denoRuntimePath,
2084
env: {
2185
...process.env,

0 commit comments

Comments
 (0)