diff --git a/dist/index.js b/dist/index.js index 54e8b27..7e597bf 100644 --- a/dist/index.js +++ b/dist/index.js @@ -21,6 +21,9 @@ const tc = __nccwpck_require__(3472); const io = __nccwpck_require__(4994); const releases = __nccwpck_require__(5819); +// Constants +const CACHE_KEY = 'terraform'; + // arch in [arm, x32, x64...] (https://nodejs.org/api/os.html#os_os_arch) // return value in [amd64, 386, arm] function mapArch (arch) { @@ -40,7 +43,7 @@ function mapOS (os) { return mappings[os] || os; } -async function downloadCLI (url) { +async function downloadCLI (url, version) { core.debug(`Downloading Terraform CLI from ${url}`); const pathToCLIZip = await tc.downloadTool(url); @@ -63,7 +66,24 @@ async function downloadCLI (url) { throw new Error(`Unable to download Terraform from ${url}`); } - return pathToCLI; + // Cache for later + const cachedPath = await tc.cacheDir(pathToCLI, CACHE_KEY, version); + return cachedPath; +} + +async function checkWrapper (pathToCLI) { + const exeSuffix = os.platform().startsWith('win') ? '.exe' : ''; + const target = [pathToCLI, `terraform-bin${exeSuffix}`].join(path.sep); + + core.debug('Checking for existing wrapper'); + + const hasWrapper = io.which(target); + + if (hasWrapper) { + core.debug('Wrapper found, skipping creation.'); + } + + return hasWrapper; } async function installWrapper (pathToCLI) { @@ -93,9 +113,6 @@ async function installWrapper (pathToCLI) { core.error(`Unable to copy ${source} to ${target}.`); throw e; } - - // Export a new environment variable, so our wrapper can locate the binary - core.exportVariable('TERRAFORM_CLI_PATH', pathToCLI); } // Add credentials to CLI Configuration File @@ -157,14 +174,24 @@ async function run () { throw new Error(`Terraform version ${version} not available for ${platform} and ${arch}`); } - // Download requested version - const pathToCLI = await downloadCLI(build.url); + // Check cache for requested version, then download if not present + let pathToCLI = tc.find(CACHE_KEY, release.version, os.arch()); + + // Check to see if wrapper has been installed in a previous run + const hasWrapper = pathToCLI && checkWrapper(pathToCLI); + + if (!pathToCLI) { + pathToCLI = await downloadCLI(build.url, release.version); + } // Install our wrapper - if (wrapper) { + if (wrapper && !hasWrapper) { await installWrapper(pathToCLI); } + // Export a new environment variable, so our wrapper can locate the binary + core.exportVariable('TERRAFORM_CLI_PATH', pathToCLI); + // Add to path core.addPath(pathToCLI); diff --git a/lib/setup-terraform.js b/lib/setup-terraform.js index 87e7575..5658da7 100644 --- a/lib/setup-terraform.js +++ b/lib/setup-terraform.js @@ -15,6 +15,9 @@ const tc = require('@actions/tool-cache'); const io = require('@actions/io'); const releases = require('@hashicorp/js-releases'); +// Constants +const CACHE_KEY = 'terraform'; + // arch in [arm, x32, x64...] (https://nodejs.org/api/os.html#os_os_arch) // return value in [amd64, 386, arm] function mapArch (arch) { @@ -34,7 +37,7 @@ function mapOS (os) { return mappings[os] || os; } -async function downloadCLI (url) { +async function downloadCLI (url, version) { core.debug(`Downloading Terraform CLI from ${url}`); const pathToCLIZip = await tc.downloadTool(url); @@ -57,7 +60,24 @@ async function downloadCLI (url) { throw new Error(`Unable to download Terraform from ${url}`); } - return pathToCLI; + // Cache for later + const cachedPath = await tc.cacheDir(pathToCLI, CACHE_KEY, version); + return cachedPath; +} + +async function checkWrapper (pathToCLI) { + const exeSuffix = os.platform().startsWith('win') ? '.exe' : ''; + const target = [pathToCLI, `terraform-bin${exeSuffix}`].join(path.sep); + + core.debug('Checking for existing wrapper'); + + const hasWrapper = io.which(target); + + if (hasWrapper) { + core.debug('Wrapper found, skipping creation.'); + } + + return hasWrapper; } async function installWrapper (pathToCLI) { @@ -87,9 +107,6 @@ async function installWrapper (pathToCLI) { core.error(`Unable to copy ${source} to ${target}.`); throw e; } - - // Export a new environment variable, so our wrapper can locate the binary - core.exportVariable('TERRAFORM_CLI_PATH', pathToCLI); } // Add credentials to CLI Configuration File @@ -151,14 +168,24 @@ async function run () { throw new Error(`Terraform version ${version} not available for ${platform} and ${arch}`); } - // Download requested version - const pathToCLI = await downloadCLI(build.url); + // Check cache for requested version, then download if not present + let pathToCLI = tc.find(CACHE_KEY, release.version, os.arch()); + + // Check to see if wrapper has been installed in a previous run + const hasWrapper = pathToCLI && checkWrapper(pathToCLI); + + if (!pathToCLI) { + pathToCLI = await downloadCLI(build.url, release.version); + } // Install our wrapper - if (wrapper) { + if (wrapper && !hasWrapper) { await installWrapper(pathToCLI); } + // Export a new environment variable, so our wrapper can locate the binary + core.exportVariable('TERRAFORM_CLI_PATH', pathToCLI); + // Add to path core.addPath(pathToCLI); diff --git a/test/setup-terraform.test.js b/test/setup-terraform.test.js index 57cda0f..05f3715 100644 --- a/test/setup-terraform.test.js +++ b/test/setup-terraform.test.js @@ -571,6 +571,13 @@ describe('Setup Terraform', () => { .fn() .mockReturnValueOnce('file'); + tc.cacheDir = jest.fn() + .mockReturnValueOnce('file'); + + tc.find = jest + .fn() + .mockReturnValueOnce(null); + os.platform = jest .fn() .mockReturnValue('linux'); @@ -615,6 +622,13 @@ describe('Setup Terraform', () => { .fn() .mockReturnValueOnce('file'); + tc.cacheDir = jest.fn() + .mockReturnValueOnce('file'); + + tc.find = jest + .fn() + .mockReturnValueOnce(null); + os.platform = jest .fn() .mockReturnValue('win32');