diff options
| author | 2023-04-28 01:36:44 +0800 | |
|---|---|---|
| committer | 2023-04-28 01:36:44 +0800 | |
| commit | dd84b9d64fb98746a230cd24233ff50a562c39c9 (patch) | |
| tree | b583261ef00b3afe72ec4d6dacb31e57779a6faf /packages/turbo-ignore/src/ignore.ts | |
| parent | 0b46fcd72ac34382387b2bcf9095233efbcc52f4 (diff) | |
| download | HydroRoll-dd84b9d64fb98746a230cd24233ff50a562c39c9.tar.gz HydroRoll-dd84b9d64fb98746a230cd24233ff50a562c39c9.zip | |
Diffstat (limited to 'packages/turbo-ignore/src/ignore.ts')
| -rw-r--r-- | packages/turbo-ignore/src/ignore.ts | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/packages/turbo-ignore/src/ignore.ts b/packages/turbo-ignore/src/ignore.ts new file mode 100644 index 0000000..a6f8f2e --- /dev/null +++ b/packages/turbo-ignore/src/ignore.ts @@ -0,0 +1,125 @@ +import { exec } from "child_process"; +import path from "path"; +import { getTurboRoot } from "@turbo/utils"; +import { getComparison } from "./getComparison"; +import { getTask } from "./getTask"; +import { getWorkspace } from "./getWorkspace"; +import { info, warn, error } from "./logger"; +import { shouldWarn } from "./errors"; +import { TurboIgnoreArgs } from "./types"; +import { checkCommit } from "./checkCommit"; + +function ignoreBuild() { + console.log("⏭ Ignoring the change"); + return process.exit(0); +} + +function continueBuild() { + console.log("✓ Proceeding with deployment"); + return process.exit(1); +} + +export default function turboIgnore({ args }: { args: TurboIgnoreArgs }) { + info( + `Using Turborepo to determine if this project is affected by the commit...\n` + ); + + // set default directory + args.directory = args.directory + ? path.resolve(args.directory) + : process.cwd(); + + // check for TURBO_FORCE and bail early if it's set + if (process.env.TURBO_FORCE === "true") { + info("`TURBO_FORCE` detected"); + return continueBuild(); + } + + // find the monorepo root + const root = getTurboRoot(args.directory); + if (!root) { + error("Monorepo root not found. turbo-ignore inferencing failed"); + return continueBuild(); + } + + // Find the workspace from the command-line args, or the package.json at the current directory + const workspace = getWorkspace(args); + if (!workspace) { + return continueBuild(); + } + + // Identify which task to execute from the command-line args + let task = getTask(args); + + // check the commit message + const parsedCommit = checkCommit({ workspace }); + if (parsedCommit.result === "skip") { + info(parsedCommit.reason); + return ignoreBuild(); + } + if (parsedCommit.result === "deploy") { + info(parsedCommit.reason); + return continueBuild(); + } + if (parsedCommit.result === "conflict") { + info(parsedCommit.reason); + } + + // Get the start of the comparison (previous deployment when available, or previous commit by default) + const comparison = getComparison({ workspace, fallback: args.fallback }); + if (!comparison) { + // This is either the first deploy of the project, or the first deploy for the branch, either way - build it. + return continueBuild(); + } + + // Build, and execute the command + const command = `npx turbo run ${task} --filter=${workspace}...[${comparison.ref}] --dry=json`; + info(`Analyzing results of \`${command}\``); + exec( + command, + { + cwd: root, + }, + (err, stdout) => { + if (err) { + const { level, code, message } = shouldWarn({ err: err.message }); + if (level === "warn") { + warn(message); + } else { + error(`${code}: ${err}`); + } + return continueBuild(); + } + + try { + const parsed = JSON.parse(stdout); + if (parsed == null) { + error(`Failed to parse JSON output from \`${command}\`.`); + return continueBuild(); + } + const { packages } = parsed; + if (packages && packages.length > 0) { + if (packages.length === 1) { + info(`This commit affects "${workspace}"`); + } else { + // subtract 1 because the first package is the workspace itself + info( + `This commit affects "${workspace}" and ${packages.length - 1} ${ + packages.length - 1 === 1 ? "dependency" : "dependencies" + } (${packages.slice(1).join(", ")})` + ); + } + + return continueBuild(); + } else { + info(`This project and its dependencies are not affected`); + return ignoreBuild(); + } + } catch (e) { + error(`Failed to parse JSON output from \`${command}\`.`); + error(e); + return continueBuild(); + } + } + ); +} |