diff --git a/__tests__/__snapshots__/authutil.test.ts.snap b/__tests__/__snapshots__/authutil.test.ts.snap new file mode 100644 index 0000000..99174a6 --- /dev/null +++ b/__tests__/__snapshots__/authutil.test.ts.snap @@ -0,0 +1,21 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`installer tests Appends trailing slash to registry 1`] = ` +"//registry.npmjs.org/:_authToken=\${NODE_AUTH_TOKEN} +registry=https://registry.npmjs.org/" +`; + +exports[`installer tests Automatically configures GPR scope 1`] = ` +"npm.pkg.github.com/:_authToken=\${NODE_AUTH_TOKEN} +@owner:registry=npm.pkg.github.com/" +`; + +exports[`installer tests Configures scoped npm registries 1`] = ` +"//registry.npmjs.org/:_authToken=\${NODE_AUTH_TOKEN} +@myScope:registry=https://registry.npmjs.org/" +`; + +exports[`installer tests Sets up npmrc for npmjs 1`] = ` +"//registry.npmjs.org/:_authToken=\${NODE_AUTH_TOKEN} +registry=https://registry.npmjs.org/" +`; diff --git a/__tests__/authutil.test.ts b/__tests__/authutil.test.ts new file mode 100644 index 0000000..3dab907 --- /dev/null +++ b/__tests__/authutil.test.ts @@ -0,0 +1,62 @@ +import io = require('@actions/io'); +import fs = require('fs'); +import path = require('path'); + +const tempDir = path.join( + __dirname, + 'runner', + path.join( + Math.random() + .toString(36) + .substring(7) + ), + 'temp' +); + +const rcFile = path.join(tempDir, '.npmrc'); + +process.env['GITHUB_REPOSITORY'] = 'owner/repo'; +process.env['RUNNER_TEMP'] = tempDir; +import * as auth from '../src/authutil'; + +describe('installer tests', () => { + beforeAll(async () => { + await io.rmRF(tempDir); + await io.mkdirP(tempDir); + }, 100000); + + beforeEach(() => { + if (fs.existsSync(rcFile)) { + fs.unlinkSync(rcFile); + } + process.env['INPUT_SCOPE'] = ''; + }); + + it('Sets up npmrc for npmjs', async () => { + await auth.configAuthentication('https://registry.npmjs.org/'); + expect(fs.existsSync(rcFile)).toBe(true); + expect(fs.readFileSync(rcFile, {encoding: 'utf8'})).toMatchSnapshot(); + }); + + it('Appends trailing slash to registry', async () => { + await auth.configAuthentication('https://registry.npmjs.org'); + + expect(fs.existsSync(rcFile)).toBe(true); + expect(fs.readFileSync(rcFile, {encoding: 'utf8'})).toMatchSnapshot(); + }); + + it('Configures scoped npm registries', async () => { + process.env['INPUT_SCOPE'] = 'myScope'; + await auth.configAuthentication('https://registry.npmjs.org'); + + expect(fs.existsSync(rcFile)).toBe(true); + expect(fs.readFileSync(rcFile, {encoding: 'utf8'})).toMatchSnapshot(); + }); + + it('Automatically configures GPR scope', async () => { + await auth.configAuthentication('npm.pkg.github.com'); + + expect(fs.existsSync(rcFile)).toBe(true); + expect(fs.readFileSync(rcFile, {encoding: 'utf8'})).toMatchSnapshot(); + }); +}); diff --git a/__tests__/installer.test.ts b/__tests__/installer.test.ts index e2aa653..e0ada32 100644 --- a/__tests__/installer.test.ts +++ b/__tests__/installer.test.ts @@ -4,7 +4,7 @@ import os = require('os'); import path = require('path'); const toolDir = path.join( - process.cwd(), + __dirname, 'runner', path.join( Math.random() @@ -14,7 +14,7 @@ const toolDir = path.join( 'tools' ); const tempDir = path.join( - process.cwd(), + __dirname, 'runner', path.join( Math.random() @@ -36,15 +36,6 @@ describe('installer tests', () => { await io.rmRF(tempDir); }, 100000); - afterAll(async () => { - try { - await io.rmRF(toolDir); - await io.rmRF(tempDir); - } catch { - console.log('Failed to remove test directories'); - } - }, 100000); - it('Acquires version of node if no matching version is installed', async () => { await installer.getNode('10.16.0'); const nodeDir = path.join(toolDir, 'node', '10.16.0', os.arch()); diff --git a/lib/authutil.js b/lib/authutil.js index c45f351..b9fe8cb 100644 --- a/lib/authutil.js +++ b/lib/authutil.js @@ -13,11 +13,10 @@ const path = __importStar(require("path")); const core = __importStar(require("@actions/core")); const github = __importStar(require("@actions/github")); function configAuthentication(registryUrl) { - // const npmrc: string = path.resolve( - // process.env['RUNNER_TEMP'] || process.cwd(), - // '.npmrc' - // ); - const npmrc = path.resolve(process.cwd(), '.npmrc'); + const npmrc = path.resolve(process.env['RUNNER_TEMP'] || process.cwd(), '.npmrc'); + if (!registryUrl.endsWith('/')) { + registryUrl += '/'; + } writeRegistryToFile(registryUrl, npmrc); } exports.configAuthentication = configAuthentication; @@ -31,23 +30,15 @@ function writeRegistryToFile(registryUrl, fileLocation) { } core.debug(`Setting auth in ${fileLocation}`); let newContents = ''; - if (fs.existsSync(fileLocation)) { - const curContents = fs.readFileSync(fileLocation, 'utf8'); - curContents.split(os.EOL).forEach((line) => { - // Add current contents unless they are setting the registry - if (!line.toLowerCase().startsWith('registry')) { - newContents += line + os.EOL; - } - }); - } + // Remove http: or https: from front of registry. const authString = registryUrl.replace(/(^\w+:|^)/, '') + ':_authToken=${NODE_AUTH_TOKEN}'; const registryString = scope ? `${scope}:registry=${registryUrl}` : `registry=${registryUrl}`; - newContents += `${registryString}${os.EOL}${authString}`; + newContents += `${authString}${os.EOL}${registryString}`; fs.writeFileSync(fileLocation, newContents); core.exportVariable('NPM_CONFIG_USERCONFIG', fileLocation); // Export empty node_auth_token so npm doesn't complain about not being able to find it - // core.exportVariable('NODE_AUTH_TOKEN', 'XXXXX-XXXXX-XXXXX-XXXXX'); + core.exportVariable('NODE_AUTH_TOKEN', 'XXXXX-XXXXX-XXXXX-XXXXX'); } diff --git a/src/authutil.ts b/src/authutil.ts index d95c2fe..9285bb9 100644 --- a/src/authutil.ts +++ b/src/authutil.ts @@ -5,11 +5,13 @@ import * as core from '@actions/core'; import * as github from '@actions/github'; export function configAuthentication(registryUrl: string) { - // const npmrc: string = path.resolve( - // process.env['RUNNER_TEMP'] || process.cwd(), - // '.npmrc' - // ); - const npmrc: string = path.resolve(process.cwd(), '.npmrc'); + const npmrc: string = path.resolve( + process.env['RUNNER_TEMP'] || process.cwd(), + '.npmrc' + ); + if (!registryUrl.endsWith('/')) { + registryUrl += '/'; + } writeRegistryToFile(registryUrl, npmrc); } @@ -36,13 +38,13 @@ function writeRegistryToFile(registryUrl: string, fileLocation: string) { } // Remove http: or https: from front of registry. const authString = - registryUrl.replace(/(^\w+:|^)/, '') + `:_authToken=${NODE_AUTH_TOKEN}`; + registryUrl.replace(/(^\w+:|^)/, '') + ':_authToken=${NODE_AUTH_TOKEN}'; const registryString = scope ? `${scope}:registry=${registryUrl}` : `registry=${registryUrl}`; - newContents += `${registryString}${os.EOL}${authString}`; + newContents += `${authString}${os.EOL}${registryString}`; fs.writeFileSync(fileLocation, newContents); -// core.exportVariable('NPM_CONFIG_USERCONFIG', fileLocation); + core.exportVariable('NPM_CONFIG_USERCONFIG', fileLocation); // Export empty node_auth_token so npm doesn't complain about not being able to find it - // core.exportVariable('NODE_AUTH_TOKEN', 'XXXXX-XXXXX-XXXXX-XXXXX'); + core.exportVariable('NODE_AUTH_TOKEN', 'XXXXX-XXXXX-XXXXX-XXXXX'); }