Skip to content

Commit

Permalink
ci(deploy): detect changes caused by dependency versions
Browse files Browse the repository at this point in the history
TL;DR: When comparing compiled scripts, we'll compile them in a
child process and make sure that the dependencies are installed
according to the lock file.
  • Loading branch information
ROpdebee committed Oct 23, 2022
1 parent da8315d commit ee3840c
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 7 deletions.
2 changes: 1 addition & 1 deletion .github/actions/setup/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ inputs:
node-version:
description: Node version to install, defaults to v16
required: false
default: '16'
default: '18'
runs:
using: composite
steps:
Expand Down
7 changes: 5 additions & 2 deletions build/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,8 @@ import { getVersionForToday } from './versions';

// Don't use await at the top level, this is incompatible with node and
// CommonJS modules.
buildUserscripts(getVersionForToday()).
catch(console.error);
buildUserscripts(getVersionForToday())
.catch((err) => {
console.error(err);
throw err;
});
4 changes: 4 additions & 0 deletions build/check-scripts-unchanged.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import fs from 'node:fs/promises';

import { buildUserscript } from './rollup';
import { getPreviousReleaseVersion, userscriptHasChanged } from './versions';

if (!process.env.GITHUB_ACTIONS) {
Expand All @@ -22,6 +23,9 @@ async function checkUserscriptsChanged(): Promise<void> {

// Check against the main branch.
if (await userscriptHasChanged(scriptName, 'main')) {
// Build it again into the dist repo so that the changes can be
// displayed.
await buildUserscript(scriptName, previousVersion, distRepo);
throw new Error(`Userscript ${scriptName} would be changed`);
}
}
Expand Down
31 changes: 27 additions & 4 deletions build/versions.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { exec } from 'node:child_process';
import fs from 'node:fs/promises';
import path from 'node:path';
import { promisify } from 'node:util';

import simpleGit from 'simple-git';

import { buildUserscript } from './rollup';

export function getVersionForToday(): string {
const today = new Date();
return `${today.getUTCFullYear()}.${today.getUTCMonth() + 1}.${today.getUTCDate()}`;
Expand Down Expand Up @@ -58,7 +58,26 @@ export async function getPreviousReleaseVersion(userscriptName: string, buildDir

async function buildTempUserscript(scriptName: string): Promise<string> {
const outputDir = await fs.mkdtemp(scriptName);
await buildUserscript(scriptName, '0.0.0', outputDir);

// Need to run this in its own process because we may need to change the
// versions of dependencies and ensure the node process uses the correct
// version. We also can't just change the `build.ts` script to accept
// arguments because we may need to compare to a version in which the script
// hadn't been changed yet.
const builderSource = `
import { buildUserscript } from "build/rollup";
buildUserscript("${scriptName}", "0.0.0", "${path.resolve(outputDir)}")
.catch((err) => {
console.error(err);
throw err;
});
`;
await fs.writeFile('isolatedBuilder.ts', builderSource);
const command = 'npm i --no-audit --production=false && npx ts-node -r tsconfig-paths/register isolatedBuilder.ts';
const { stderr, stdout } = await promisify(exec)(command);
if (stderr) console.error(stderr);
if (stdout) console.log(stdout);

const content = fs.readFile(path.join(outputDir, `${scriptName}.user.js`), 'utf8');
await fs.rm(outputDir, { recursive: true });
return content;
Expand All @@ -68,7 +87,9 @@ export async function userscriptHasChanged(scriptName: string, compareToRef: str
// We'll check whether the userscript has changed by building both the
// latest code as well as the code at `baseRef`, then diffing them.
// If there's a diff, we assume it needs a new release.
const currentVersion = await buildTempUserscript(scriptName);

// Build previous version before current version so that the current
// dependency versions are installed after everything is finished.

// Temporarily check out the base ref
const repo = simpleGit();
Expand All @@ -80,5 +101,7 @@ export async function userscriptHasChanged(scriptName: string, compareToRef: str
await repo.checkout('-');
}

const currentVersion = await buildTempUserscript(scriptName);

return currentVersion !== previousVersion;
}

0 comments on commit ee3840c

Please sign in to comment.