Skip to content

Instantly share code, notes, and snippets.

@motorcityadam
Created October 31, 2019 21:01
Show Gist options
  • Save motorcityadam/d892b6c31a9783b1ceccec494f711dbf to your computer and use it in GitHub Desktop.
Save motorcityadam/d892b6c31a9783b1ceccec494f711dbf to your computer and use it in GitHub Desktop.
Preinstall script to fix npm proxy issues with Yarn and GitHub Package Registry
// Copyright (c) Alliedstrand Corporation. All rights reserved.
//
// Licensed under the MIT License.
'use strict';
/**
* @file Extract the GitHub Personal Access Token for GitHub Package Registry
* access.
*
* @note This script should be placed in the root of the repository and added
* to the "preinstall" script in the `package.json` file. For example,
* "preinstall": "node preinstall.js --owner=OWNER"
*/
const fs = require('fs');
const os = require('os');
const path = require('path');
const readline = require('readline');
const ownerCLOption = '--owner=';
if (process.argv.length <= 2 || process.argv[2].indexOf(ownerCLOption) !== 0) {
console.error('Usage: ' + __filename + ` ${ownerCLOption}GITHUB_OWNER`);
process.exit(-1);
}
const githubOwner = process.argv[2].split(ownerCLOption)[1];
const npmrcFilename = '.npmrc';
const userHomeDirpath = os.homedir();
const userNpmrcFilepath = path.join(userHomeDirpath, npmrcFilename);
const yarnrcFilename = '.yarnrc';
console.info(`INFO: Creating ${yarnrcFilename}...`);
const repoRootFilepath = process.cwd();
const yarnrcFilepath = path.join(repoRootFilepath, yarnrcFilename);
const githubDocLink =
'See https://help.github.com/en/github/managing-packages-with-github-package-registry/configuring-npm-for-use-with-github-package-registry';
const githubRegUrlPrefix = '//npm.pkg.github.com/:_authToken=';
const githubOwnerRegUrlPrefix = `//npm.pkg.github.com/${githubOwner}/:_authToken=`;
if (!fs.existsSync(userNpmrcFilepath)) {
console.error(
`Cannot find ${npmrcFilename} file in ${userHomeDirpath}. Did you run 'npm login' for the GitHub Package Registry.`
);
console.error(githubDocLink);
process.exit(-1);
}
const npmrcReadInterface = readline.createInterface({
input: fs.createReadStream(userNpmrcFilepath),
});
/**
* Extract Github Personal Access Token from the user `.npmrc` file.
* @returns {string | undefined} GitHub token if present. Otherwise,`undefined`.
*/
async function getGithubToken() {
let token = undefined;
for await (const line of npmrcReadInterface) {
if (line.indexOf(githubRegUrlPrefix) === 0) {
token = line.split(githubRegUrlPrefix)[1];
}
}
return token;
}
getGithubToken().then(function(githubToken) {
if (githubToken) {
const yarnrcContents = `${githubRegUrlPrefix}${githubToken}
${githubOwnerRegUrlPrefix}${githubToken}`;
fs.writeFileSync(yarnrcFilepath, yarnrcContents);
} else {
console.error(
`Cannot find the npm registry URL for the GitHub Package Registry. Did you run 'npm login' for the GitHub Package Registry.`
);
console.error(githubDocLink);
process.exit(-1);
}
});
console.log(`SUCCESS: Created ${yarnrcFilename}...`);
@motorcityadam
Copy link
Author

This script will generate a .yarnrc file in your repository root directory which you should probably add to the .gitignore file as it will be generated before each yarn install and will contain a GitHub user-specific Personal Access Token which you may not wish to check into Git.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment