Skip to content

Commit 78148da

Browse files
author
Danny McCormick
authored
Add auth support (#21)
* Updates * Update * Update * Update * Update * Yarn sometimes prefers npmrc, so use same token * Description * Update readme * Feedback * Add type * new toolkit and scoped registries * npmrc in RUNNER_TEMP * Dont always auth * Try exporting blank token * Get auth working for now pending runner changes * Fix string interpolation for auth token. * Don't export both userconfigs * Update authutil.js * Add single quotes for authString * Fix the registry string. * Use userconfig and append trailing slash * Keep in root of repo * Try just adding auth token * Remove auth token * Try changes again * Add tests * Npm and GPR samples * Add types
1 parent 0675b87 commit 78148da

File tree

391 files changed

+79848
-43
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

391 files changed

+79848
-43
lines changed

README.md

+41
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,47 @@ jobs:
3939
- run: npm test
4040
```
4141
42+
Publish to npmjs and GPR with npm:
43+
```yaml
44+
steps:
45+
- uses: actions/checkout@master
46+
- uses: actions/setup-node@v1
47+
with:
48+
version: '10.x'
49+
registry-url: 'https://registry.npmjs.org'
50+
- run: npm install
51+
- run: npm publish
52+
env:
53+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
54+
- uses: actions/setup-node@v1
55+
with:
56+
registry-url: 'https://npm.pkg.github.com'
57+
- run: npm publish
58+
env:
59+
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
60+
```
61+
62+
Publish to npmjs and GPR with yarn:
63+
```yaml
64+
steps:
65+
- uses: actions/checkout@master
66+
- uses: actions/setup-node@v1
67+
with:
68+
version: '10.x'
69+
registry-url: <registry url>
70+
- run: npm install -g yarn
71+
- run: yarn install
72+
- run: yarn publish
73+
env:
74+
NODE_AUTH_TOKEN: ${{ secrets.YARN_TOKEN }}
75+
- uses: actions/setup-node@v1
76+
with:
77+
registry-url: 'https://npm.pkg.github.com'
78+
- run: yarn publish
79+
env:
80+
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
81+
```
82+
4283
# License
4384
4485
The scripts and documentation in this project are released under the [MIT License](LICENSE)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`installer tests Appends trailing slash to registry 1`] = `
4+
"//registry.npmjs.org/:_authToken=\${NODE_AUTH_TOKEN}
5+
registry=https://registry.npmjs.org/"
6+
`;
7+
8+
exports[`installer tests Automatically configures GPR scope 1`] = `
9+
"npm.pkg.github.com/:_authToken=\${NODE_AUTH_TOKEN}
10+
@owner:registry=npm.pkg.github.com/"
11+
`;
12+
13+
exports[`installer tests Configures scoped npm registries 1`] = `
14+
"//registry.npmjs.org/:_authToken=\${NODE_AUTH_TOKEN}
15+
@myScope:registry=https://registry.npmjs.org/"
16+
`;
17+
18+
exports[`installer tests Sets up npmrc for npmjs 1`] = `
19+
"//registry.npmjs.org/:_authToken=\${NODE_AUTH_TOKEN}
20+
registry=https://registry.npmjs.org/"
21+
`;

__tests__/authutil.test.ts

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import io = require('@actions/io');
2+
import fs = require('fs');
3+
import path = require('path');
4+
5+
const tempDir = path.join(
6+
__dirname,
7+
'runner',
8+
path.join(
9+
Math.random()
10+
.toString(36)
11+
.substring(7)
12+
),
13+
'temp'
14+
);
15+
16+
const rcFile = path.join(tempDir, '.npmrc');
17+
18+
process.env['GITHUB_REPOSITORY'] = 'owner/repo';
19+
process.env['RUNNER_TEMP'] = tempDir;
20+
import * as auth from '../src/authutil';
21+
22+
describe('installer tests', () => {
23+
beforeAll(async () => {
24+
await io.rmRF(tempDir);
25+
await io.mkdirP(tempDir);
26+
}, 100000);
27+
28+
beforeEach(() => {
29+
if (fs.existsSync(rcFile)) {
30+
fs.unlinkSync(rcFile);
31+
}
32+
process.env['INPUT_SCOPE'] = '';
33+
});
34+
35+
it('Sets up npmrc for npmjs', async () => {
36+
await auth.configAuthentication('https://registry.npmjs.org/');
37+
expect(fs.existsSync(rcFile)).toBe(true);
38+
expect(fs.readFileSync(rcFile, {encoding: 'utf8'})).toMatchSnapshot();
39+
});
40+
41+
it('Appends trailing slash to registry', async () => {
42+
await auth.configAuthentication('https://registry.npmjs.org');
43+
44+
expect(fs.existsSync(rcFile)).toBe(true);
45+
expect(fs.readFileSync(rcFile, {encoding: 'utf8'})).toMatchSnapshot();
46+
});
47+
48+
it('Configures scoped npm registries', async () => {
49+
process.env['INPUT_SCOPE'] = 'myScope';
50+
await auth.configAuthentication('https://registry.npmjs.org');
51+
52+
expect(fs.existsSync(rcFile)).toBe(true);
53+
expect(fs.readFileSync(rcFile, {encoding: 'utf8'})).toMatchSnapshot();
54+
});
55+
56+
it('Automatically configures GPR scope', async () => {
57+
await auth.configAuthentication('npm.pkg.github.com');
58+
59+
expect(fs.existsSync(rcFile)).toBe(true);
60+
expect(fs.readFileSync(rcFile, {encoding: 'utf8'})).toMatchSnapshot();
61+
});
62+
});

__tests__/installer.test.ts

+2-11
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import os = require('os');
44
import path = require('path');
55

66
const toolDir = path.join(
7-
process.cwd(),
7+
__dirname,
88
'runner',
99
path.join(
1010
Math.random()
@@ -14,7 +14,7 @@ const toolDir = path.join(
1414
'tools'
1515
);
1616
const tempDir = path.join(
17-
process.cwd(),
17+
__dirname,
1818
'runner',
1919
path.join(
2020
Math.random()
@@ -36,15 +36,6 @@ describe('installer tests', () => {
3636
await io.rmRF(tempDir);
3737
}, 100000);
3838

39-
afterAll(async () => {
40-
try {
41-
await io.rmRF(toolDir);
42-
await io.rmRF(tempDir);
43-
} catch {
44-
console.log('Failed to remove test directories');
45-
}
46-
}, 100000);
47-
4839
it('Acquires version of node if no matching version is installed', async () => {
4940
await installer.getNode('10.16.0');
5041
const nodeDir = path.join(toolDir, 'node', '10.16.0', os.arch());

action.yml

+4
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ inputs:
55
version:
66
description: 'Version Spec of the version to use. Examples: 10.x, 10.15.1, >=10.15.0, lts'
77
default: '10.x'
8+
registry-url:
9+
description: 'Optional registry to set up for auth. Will set the registry in a project level .npmrc and .yarnrc file, and set up auth to read in from env.NODE_AUTH_TOKEN'
10+
scope:
11+
description: 'Optional scope for authenticating against scoped registries'
812
runs:
913
using: 'node12'
1014
main: 'lib/setup-node.js'

lib/authutil.js

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
"use strict";
2+
var __importStar = (this && this.__importStar) || function (mod) {
3+
if (mod && mod.__esModule) return mod;
4+
var result = {};
5+
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
6+
result["default"] = mod;
7+
return result;
8+
};
9+
Object.defineProperty(exports, "__esModule", { value: true });
10+
const fs = __importStar(require("fs"));
11+
const os = __importStar(require("os"));
12+
const path = __importStar(require("path"));
13+
const core = __importStar(require("@actions/core"));
14+
const github = __importStar(require("@actions/github"));
15+
function configAuthentication(registryUrl) {
16+
const npmrc = path.resolve(process.env['RUNNER_TEMP'] || process.cwd(), '.npmrc');
17+
if (!registryUrl.endsWith('/')) {
18+
registryUrl += '/';
19+
}
20+
writeRegistryToFile(registryUrl, npmrc);
21+
}
22+
exports.configAuthentication = configAuthentication;
23+
function writeRegistryToFile(registryUrl, fileLocation) {
24+
let scope = core.getInput('scope');
25+
if (!scope && registryUrl.indexOf('npm.pkg.github.com') > -1) {
26+
scope = github.context.repo.owner;
27+
}
28+
if (scope && scope[0] != '@') {
29+
scope = '@' + scope;
30+
}
31+
core.debug(`Setting auth in ${fileLocation}`);
32+
let newContents = '';
33+
if (fs.existsSync(fileLocation)) {
34+
const curContents = fs.readFileSync(fileLocation, 'utf8');
35+
curContents.split(os.EOL).forEach((line) => {
36+
// Add current contents unless they are setting the registry
37+
if (!line.toLowerCase().startsWith('registry')) {
38+
newContents += line + os.EOL;
39+
}
40+
});
41+
}
42+
// Remove http: or https: from front of registry.
43+
const authString = registryUrl.replace(/(^\w+:|^)/, '') + ':_authToken=${NODE_AUTH_TOKEN}';
44+
const registryString = scope
45+
? `${scope}:registry=${registryUrl}`
46+
: `registry=${registryUrl}`;
47+
newContents += `${authString}${os.EOL}${registryString}`;
48+
fs.writeFileSync(fileLocation, newContents);
49+
core.exportVariable('NPM_CONFIG_USERCONFIG', fileLocation);
50+
// Export empty node_auth_token so npm doesn't complain about not being able to find it
51+
core.exportVariable('NODE_AUTH_TOKEN', 'XXXXX-XXXXX-XXXXX-XXXXX');
52+
}

lib/setup-node.js

+5
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
1717
Object.defineProperty(exports, "__esModule", { value: true });
1818
const core = __importStar(require("@actions/core"));
1919
const installer = __importStar(require("./installer"));
20+
const auth = __importStar(require("./authutil"));
2021
const path = __importStar(require("path"));
2122
function run() {
2223
return __awaiter(this, void 0, void 0, function* () {
@@ -30,6 +31,10 @@ function run() {
3031
// TODO: installer doesn't support proxy
3132
yield installer.getNode(version);
3233
}
34+
const registryUrl = core.getInput('registry-url');
35+
if (registryUrl) {
36+
auth.configAuthentication(registryUrl);
37+
}
3338
// TODO: setup proxy from runner proxy config
3439
const matchersPath = path.join(__dirname, '..', '.github');
3540
console.log(`##[add-matcher]${path.join(matchersPath, 'tsc.json')}`);

node_modules/.bin/which

+15
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

node_modules/.bin/which.cmd

+7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

node_modules/@actions/github/README.md

+48
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

node_modules/@actions/github/lib/context.d.ts

+26
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

node_modules/@actions/github/lib/context.js

+38
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

node_modules/@actions/github/lib/context.js.map

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)