From 53234c232f116b171616ec07048ae0d8a16176b3 Mon Sep 17 00:00:00 2001
From: Sayak Mukhopadhyay <mukhopadhyaysayak@gmail.com>
Date: Mon, 26 Dec 2022 22:32:49 +0530
Subject: [PATCH] feat: add logic to enable corepack on passing optional input

---
 action.yml       |  3 +++
 src/installer.ts | 19 +++++++++++++++++++
 src/main.ts      |  3 +++
 3 files changed, 25 insertions(+)

diff --git a/action.yml b/action.yml
index b22de1ef..0b124b32 100644
--- a/action.yml
+++ b/action.yml
@@ -25,6 +25,9 @@ inputs:
     description: 'Used to specify a package manager for caching in the default directory. Supported values: npm, yarn, pnpm.'
   cache-dependency-path:
     description: 'Used to specify the path to a dependency file: package-lock.json, yarn.lock, etc. Supports wildcards or a list of file names for caching multiple dependencies.'
+  corepack:
+    description: 'Used to specify whether to enable Corepack. Set to true to enable all package managers or set it to one or more package manager names (separate package manager names by a space. Supported package manager names: npm, yarn, pnpm.'
+    default: 'false'
 # TODO: add input to control forcing to pull from cloud or dist. 
 #       escape valve for someone having issues or needing the absolute latest which isn't cached yet
 outputs:
diff --git a/src/installer.ts b/src/installer.ts
index 1b5659b6..79bd2af5 100644
--- a/src/installer.ts
+++ b/src/installer.ts
@@ -4,6 +4,7 @@ import * as core from '@actions/core';
 import * as hc from '@actions/http-client';
 import * as io from '@actions/io';
 import * as tc from '@actions/tool-cache';
+import * as exec from '@actions/exec';
 import * as path from 'path';
 import * as semver from 'semver';
 import fs from 'fs';
@@ -604,3 +605,21 @@ export function parseNodeVersionFile(contents: string): string {
 function isLatestSyntax(versionSpec): boolean {
   return ['current', 'latest', 'node'].includes(versionSpec);
 }
+
+export async function enableCorepack(input: string): Promise<void> {
+  let corepackArgs = ['enable'];
+  if (input.length > 0 && input !== 'false') {
+    if (input !== 'true') {
+      const packageManagers = input.split(' ');
+      if (!packageManagers.every(pm => ['npm', 'yarn', 'pnpm'].includes(pm))) {
+        throw new Error(
+          `One or more of the specified package managers [ ${input} ] are not supported by corepack`
+        );
+      }
+      corepackArgs.push(...packageManagers);
+    }
+    await exec.getExecOutput('corepack', corepackArgs, {
+      ignoreReturnCode: true
+    });
+  }
+}
diff --git a/src/main.ts b/src/main.ts
index 2a846b06..f29ccc7d 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -49,6 +49,9 @@ export async function run() {
       auth.configAuthentication(registryUrl, alwaysAuth);
     }
 
+    const corepack = core.getInput('corepack') || 'false';
+    await installer.enableCorepack(corepack);
+
     if (cache && isCacheFeatureAvailable()) {
       const cacheDependencyPath = core.getInput('cache-dependency-path');
       await restoreCache(cache, cacheDependencyPath);