diff --git a/.github/workflows/pr-checks.yml b/.github/workflows/pr-checks.yml index ac61475d6..d835d15ed 100644 --- a/.github/workflows/pr-checks.yml +++ b/.github/workflows/pr-checks.yml @@ -55,7 +55,7 @@ jobs: npm ci - name: Verify compiled JS up to date - run: .github/workflows/script/check-js.sh + run: npx tsx pr-checks/check-js.ts - name: Run unit tests if: always() diff --git a/.github/workflows/script/check-js.sh b/.github/workflows/script/check-js.sh deleted file mode 100755 index 57638dcf2..000000000 --- a/.github/workflows/script/check-js.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/bash -set -eu - -# Sanity check that repo is clean to start with -if [ ! -z "$(git status --porcelain)" ]; then - # If we get a fail here then this workflow needs attention... - >&2 echo "Failed: Repo should be clean before testing!" - exit 1 -fi -# Wipe the lib directory in case there are extra unnecessary files in there -rm -rf lib -# Generate the JavaScript files -npm run-script build -# Check that repo is still clean -if [ ! -z "$(git status --porcelain)" ]; then - # If we get a fail here then the PR needs attention - >&2 echo "Failed: JavaScript files are not up to date. Run 'rm -rf lib && npm run-script build' to update" - git status - - echo "### Transpiled JS diff" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo '```diff' >> $GITHUB_STEP_SUMMARY - git diff --output="$RUNNER_TEMP/js.diff" - cat "$RUNNER_TEMP/js.diff" >> $GITHUB_STEP_SUMMARY - echo '```' >> $GITHUB_STEP_SUMMARY - - # Reset bundled files to allow other checks to test for changes - git checkout lib - - # Fail this check - exit 1 -fi -echo "Success: JavaScript files are up to date" diff --git a/pr-checks/check-js.ts b/pr-checks/check-js.ts new file mode 100755 index 000000000..835bb0056 --- /dev/null +++ b/pr-checks/check-js.ts @@ -0,0 +1,67 @@ +#!/usr/bin/env npx tsx + +import * as fs from "node:fs"; +import * as path from "node:path"; + +import * as core from "@actions/core"; + +import { runCommand, runGit } from "./command"; +import { LIB_ROOT, PR_CHECKS_DIR, REPO_ROOT } from "./config"; +import { getErrorMessage } from "./util"; + +function main() { + // Sanity check that repo is clean to start with + try { + runGit(["diff", "--exit-code"], { allowNonZeroExitCode: false }); + console.info("Repository is clean."); + } catch (err) { + // If we get a fail here then this workflow needs attention... + console.error(getErrorMessage(err)); + console.error("Failed: Repo should be clean before testing!"); + return -1; + } + + // Wipe the lib directory in case there are extra unnecessary files in there + console.info(`Removing ${LIB_ROOT}...`); + fs.rmSync(LIB_ROOT, { recursive: true, force: true }); + + // Generate the JavaScript files + runCommand("npm", ["run", "build"], { execOptions: { shell: true } }); + + // Check that repo is still clean + try { + runGit(["diff", "--exit-code"], { allowNonZeroExitCode: false }); + console.info("Repository is clean."); + } catch (err) { + // If we get a fail here then the PR needs attention + console.error(getErrorMessage(err)); + console.error("Failed: JavaScript files are not up to date."); + console.error("Run 'rm -rf lib && npm run build' to update."); + + const diffFile = path.join( + process.env["RUNNER_TEMP"] ?? PR_CHECKS_DIR, + "js.diff", + ); + runCommand("git", ["status"]); + runCommand("git", ["diff", `--output=${diffFile}`], { + execOptions: { cwd: REPO_ROOT }, + }); + + core.summary.addHeading("Transpiled JS diff", 3); + core.summary.addCodeBlock(fs.readFileSync(diffFile, "utf-8"), "diff"); + + fs.rmSync(diffFile); + + // Reset bundled files to allow other checks to test for changes + runCommand("git", ["checkout", "lib"]); + + return 1; + } + + console.info("Success: JavaScript files are up to date"); + return 0; +} + +if (require.main === module) { + process.exit(main()); +} diff --git a/pr-checks/config.ts b/pr-checks/config.ts index 9cd23e48d..40ca7037a 100644 --- a/pr-checks/config.ts +++ b/pr-checks/config.ts @@ -24,6 +24,9 @@ export const BUNDLE_METADATA_FILE = path.join(REPO_ROOT, "meta.json"); /** The `src` directory. */ export const SOURCE_ROOT = path.join(REPO_ROOT, "src"); +/** The `src` directory. */ +export const LIB_ROOT = path.join(REPO_ROOT, "lib"); + /** The path to `defaults.json`. */ export const DEFAULTS_FILE = path.join(SOURCE_ROOT, "defaults.json");