Repository: actions/toolkit (ts)

Issue:
cache: Sets global MSYS env var, interfering with MSYS2 on Windows runners
The recent >=3.1.x updates introduced a change overwriting globally the "MSYS" env var: https://github.com/actions/toolkit/blob/6c1f9eaae833355a0b212b66c5f2e3ac366de185/packages/cache/src/internal/tar.ts#L17

This env vars is used for configuring MSYS2 behavior and setting it overrides config provided by the user, or changes the default behavior.

It would be nice if this env var was only set for what it is needed and not globally.

@Phantsure

Pull request description:
Don't set the MSYS env var globally
b2d865f18051b21447 introduced a call to exportVariable() to export the MSYS env var, which configures the symlink strategy for MSYS2/cygwin binaries it calls.

By setting the env var globally, this also changes the behaviour of other MSYS2 using tools in a CI job, and also overrides MSYS configuration set by the user, which I think was not intended.

To avoid this leakage set the MSYS env var only for the commands which @actions/cache calls.

Fixes #1312

Patch:
diff --git a/packages/cache/src/internal/tar.ts b/packages/cache/src/internal/tar.ts
index 8c6337e..adf6106 100644
--- a/packages/cache/src/internal/tar.ts
+++ b/packages/cache/src/internal/tar.ts
@@ -1,5 +1,4 @@
 import {exec} from '@actions/exec'
-import {exportVariable} from '@actions/core'
 import * as io from '@actions/io'
 import {existsSync, writeFileSync} from 'fs'
 import * as path from 'path'
@@ -14,7 +13,6 @@ import {
 } from './constants'
 
 const IS_WINDOWS = process.platform === 'win32'
-exportVariable('MSYS', 'winsymlinks:nativestrict')
 
 // Returns tar path and type: BSD or GNU
 async function getTarPath(): Promise<ArchiveTool> {
@@ -250,7 +248,10 @@ async function getCompressionProgram(
 async function execCommands(commands: string[], cwd?: string): Promise<void> {
   for (const command of commands) {
     try {
-      await exec(command, undefined, {cwd})
+      await exec(command, undefined, {
+        cwd,
+        env: {...(process.env as object), MSYS: 'winsymlinks:nativestrict'}
+      })
     } catch (error) {
       throw new Error(
         `${command.split(' ')[0]} failed with error: ${error?.message}`


Test patch:
diff --git a/packages/cache/__tests__/tar.test.ts b/packages/cache/__tests__/tar.test.ts
index 7ae7760..4145d9a 100644
--- a/packages/cache/__tests__/tar.test.ts
+++ b/packages/cache/__tests__/tar.test.ts
@@ -1,5 +1,4 @@
 import * as exec from '@actions/exec'
-import {exportVariable} from '@actions/core'
 import * as io from '@actions/io'
 import * as path from 'path'
 import {
@@ -15,8 +14,6 @@ import * as utils from '../src/internal/cacheUtils'
 // eslint-disable-next-line @typescript-eslint/no-require-imports
 import fs = require('fs')
 
-exportVariable('MSYS', 'winsymlinks:nativestrict')
-
 jest.mock('@actions/exec')
 jest.mock('@actions/io')
 
@@ -25,6 +22,8 @@ const IS_MAC = process.platform === 'darwin'
 
 const defaultTarPath = IS_MAC ? 'gtar' : 'tar'
 
+const defaultEnv = {MSYS: 'winsymlinks:nativestrict'}
+
 function getTempDir(): string {
   return path.join(__dirname, '_temp', 'tar')
 }
@@ -78,7 +77,10 @@ test('zstd extract tar', async () => {
       ])
       .join(' '),
     undefined,
-    {cwd: undefined}
+    {
+      cwd: undefined,
+      env: expect.objectContaining(defaultEnv)
+    }
   )
 })
 
@@ -107,7 +109,10 @@ test('zstd extract tar with windows BSDtar', async () => {
         archivePath.replace(new RegExp(`\\${path.sep}`, 'g'), '/')
       ].join(' '),
       undefined,
-      {cwd: undefined}
+      {
+        cwd: undefined,
+        env: expect.objectContaining(defaultEnv)
+      }
     )
 
     expect(execMock).toHaveBeenNthCalledWith(
@@ -121,7 +126,10 @@ test('zstd extract tar with windows BSDtar', async () => {
         workspace?.replace(/\\/g, '/')
       ].join(' '),
       undefined,
-      {cwd: undefined}
+      {
+        cwd: undefined,
+        env: expect.objectContaining(defaultEnv)
+      }
     )
   }
 })
@@ -153,7 +161,10 @@ test('gzip extract tar', async () => {
       .concat(['-z'])
       .join(' '),
     undefined,
-    {cwd: undefined}
+    {
+      cwd: undefined,
+      env: expect.objectContaining(defaultEnv)
+    }
   )
 })
 
@@ -182,7 +193,10 @@ test('gzip extract GNU tar on windows with GNUtar in path', async () => {
         '-z'
       ].join(' '),
       undefined,
-      {cwd: undefined}
+      {
+        cwd: undefined,
+        env: expect.objectContaining(defaultEnv)
+      }
     )
   }
 })
@@ -224,7 +238,8 @@ test('zstd create tar', async () => {
       .join(' '),
     undefined, // args
     {
-      cwd: archiveFolder
+      cwd: archiveFolder,
+      env: expect.objectContaining(defaultEnv)
     }
   )
 })
@@ -269,7 +284,8 @@ test('zstd create tar with windows BSDtar', async () => {
       ].join(' '),
       undefined, // args
       {
-        cwd: archiveFolder
+        cwd: archiveFolder,
+        env: expect.objectContaining(defaultEnv)
       }
     )
 
@@ -282,7 +298,8 @@ test('zstd create tar with windows BSDtar', async () => {
       ].join(' '),
       undefined, // args
       {
-        cwd: archiveFolder
+        cwd: archiveFolder,
+        env: expect.objectContaining(defaultEnv)
       }
     )
   }
@@ -322,7 +339,8 @@ test('gzip create tar', async () => {
       .join(' '),
     undefined, // args
     {
-      cwd: archiveFolder
+      cwd: archiveFolder,
+      env: expect.objectContaining(defaultEnv)
     }
   )
 })
@@ -353,7 +371,10 @@ test('zstd list tar', async () => {
       ])
       .join(' '),
     undefined,
-    {cwd: undefined}
+    {
+      cwd: undefined,
+      env: expect.objectContaining(defaultEnv)
+    }
   )
 })
 
@@ -378,7 +399,10 @@ test('zstd list tar with windows BSDtar', async () => {
         archivePath.replace(new RegExp(`\\${path.sep}`, 'g'), '/')
       ].join(' '),
       undefined,
-      {cwd: undefined}
+      {
+        cwd: undefined,
+        env: expect.objectContaining(defaultEnv)
+      }
     )
 
     expect(execMock).toHaveBeenNthCalledWith(
@@ -390,7 +414,10 @@ test('zstd list tar with windows BSDtar', async () => {
         '-P'
       ].join(' '),
       undefined,
-      {cwd: undefined}
+      {
+        cwd: undefined,
+        env: expect.objectContaining(defaultEnv)
+      }
     )
   }
 })
@@ -418,7 +445,10 @@ test('zstdWithoutLong list tar', async () => {
       .concat(['--use-compress-program', IS_WINDOWS ? '"zstd -d"' : 'unzstd'])
       .join(' '),
     undefined,
-    {cwd: undefined}
+    {
+      cwd: undefined,
+      env: expect.objectContaining(defaultEnv)
+    }
   )
 })
 
@@ -444,6 +474,9 @@ test('gzip list tar', async () => {
       .concat(['-z'])
       .join(' '),
     undefined,
-    {cwd: undefined}
+    {
+      cwd: undefined,
+      env: expect.objectContaining(defaultEnv)
+    }
   )
 })