@percy/env
Advanced tools
Comparing version 1.12.0 to 1.13.0
@@ -1,17 +0,26 @@ | ||
import fs from 'fs'; // Heavily inspired by dotenv-rails | ||
import fs from 'fs'; | ||
// Heavily inspired by dotenv-rails | ||
// https://github.com/bkeepers/dotenv | ||
// matches each valid line of a dotenv file | ||
const LINE_REG = new RegExp([ | ||
// key with optional export | ||
'^\\s*(?:export\\s+)?(?<key>[\\w.]+)', | ||
// separator | ||
'(?:\\s*=\\s*?|:\\s+?)(?:', | ||
// single quoted value or | ||
'\\s*(?<squote>\')(?<sval>(?:\\\\\'|[^\'])*)\'|', | ||
// double quoted value or | ||
'\\s*(?<dquote>")(?<dval>(?:\\\\"|[^"])*)"|', | ||
// unquoted value | ||
'(?<uval>[^#\\r\\n]+))?', | ||
// optional comment | ||
'\\s*(?:#.*)?$'].join(''), 'gm'); | ||
const LINE_REG = new RegExp([// key with optional export | ||
'^\\s*(?:export\\s+)?(?<key>[\\w.]+)', // separator | ||
'(?:\\s*=\\s*?|:\\s+?)(?:', // single quoted value or | ||
'\\s*(?<squote>\')(?<sval>(?:\\\\\'|[^\'])*)\'|', // double quoted value or | ||
'\\s*(?<dquote>")(?<dval>(?:\\\\"|[^"])*)"|', // unquoted value | ||
'(?<uval>[^#\\r\\n]+))?', // optional comment | ||
'\\s*(?:#.*)?$'].join(''), 'gm'); // interpolate variable substitutions | ||
const INTERPOLATE_REG = /(.?)(\${?([a-zA-Z0-9_]+)?}?)/g; // expand newlines | ||
const EXPAND_CRLF_REG = /\\(?:(r)|n)/g; // unescape characters | ||
// interpolate variable substitutions | ||
const INTERPOLATE_REG = /(.?)(\${?([a-zA-Z0-9_]+)?}?)/g; | ||
// expand newlines | ||
const EXPAND_CRLF_REG = /\\(?:(r)|n)/g; | ||
// unescape characters | ||
const UNESC_CHAR_REG = /\\([^$])/g; | ||
@@ -23,6 +32,8 @@ export function load() { | ||
NODE_ENV | ||
} = process.env; // dotenv filepaths ordered by priority | ||
} = process.env; | ||
let paths = [NODE_ENV && `.env.${NODE_ENV}.local`, NODE_ENV !== 'test' && '.env.local', NODE_ENV && `.env.${NODE_ENV}`, '.env']; // load each dotenv file synchronously | ||
// dotenv filepaths ordered by priority | ||
let paths = [NODE_ENV && `.env.${NODE_ENV}.local`, NODE_ENV !== 'test' && '.env.local', NODE_ENV && `.env.${NODE_ENV}`, '.env']; | ||
// load each dotenv file synchronously | ||
for (let path of paths) { | ||
@@ -32,25 +43,27 @@ try { | ||
encoding: 'utf-8' | ||
}); // iterate over each matching line | ||
}); | ||
// iterate over each matching line | ||
for (let { | ||
groups: match | ||
} of src.matchAll(LINE_REG)) { | ||
let value = match.sval ?? match.dval ?? match.uval ?? ''; // if double quoted, expand newlines | ||
let value = match.sval ?? match.dval ?? match.uval ?? ''; | ||
// if double quoted, expand newlines | ||
if (match.dquote) { | ||
value = value.replace(EXPAND_CRLF_REG, (_, r) => r ? '\r' : '\n'); | ||
} // unescape characters | ||
} | ||
// unescape characters | ||
value = value.replace(UNESC_CHAR_REG, '$1'); | ||
value = value.replace(UNESC_CHAR_REG, '$1'); // if not single quoted, interpolate substitutions | ||
// if not single quoted, interpolate substitutions | ||
if (!match.squote) { | ||
value = value.replace(INTERPOLATE_REG, (_, pre, ref, key) => { | ||
if (pre === '\\') return ref; // escaped reference | ||
return pre + (process.env[key] ?? ''); | ||
}); | ||
} // set process.env if not already | ||
} | ||
// set process.env if not already | ||
if (!Object.prototype.hasOwnProperty.call(process.env, match.key)) { | ||
@@ -60,3 +73,4 @@ process.env[match.key] = value; | ||
} | ||
} catch (e) {// silent error | ||
} catch (e) { | ||
// silent error | ||
} | ||
@@ -63,0 +77,0 @@ } |
@@ -5,5 +5,5 @@ import { getCommitData, getJenkinsSha, github } from './utils.js'; | ||
this.vars = vars; | ||
} // used for getter switch statements | ||
} | ||
// used for getter switch statements | ||
get ci() { | ||
@@ -47,5 +47,5 @@ if (this.vars.TRAVIS_BUILD_ID) { | ||
} | ||
} // environment info reported in user-agents | ||
} | ||
// environment info reported in user-agents | ||
get info() { | ||
@@ -55,15 +55,12 @@ switch (this.ci) { | ||
return this.vars.PERCY_GITHUB_ACTION ? `github/${this.vars.PERCY_GITHUB_ACTION}` : this.ci; | ||
case 'gitlab': | ||
return `gitlab/${this.vars.CI_SERVER_VERSION}`; | ||
case 'semaphore': | ||
return this.vars.SEMAPHORE_GIT_SHA ? 'semaphore/2.0' : 'semaphore'; | ||
default: | ||
return this.ci; | ||
} | ||
} // current commit sha | ||
} | ||
// current commit sha | ||
get commit() { | ||
@@ -73,50 +70,34 @@ if (this.vars.PERCY_COMMIT) { | ||
} | ||
let commit = (() => { | ||
var _github$pull_request; | ||
switch (this.ci) { | ||
case 'travis': | ||
return this.vars.TRAVIS_COMMIT; | ||
case 'jenkins-prb': | ||
return this.vars.ghprbActualCommit || this.vars.GIT_COMMIT; | ||
case 'jenkins': | ||
return getJenkinsSha() || this.vars.GIT_COMMIT; | ||
case 'circle': | ||
return this.vars.CIRCLE_SHA1; | ||
case 'codeship': | ||
return this.vars.CI_COMMIT_ID; | ||
case 'drone': | ||
return this.vars.DRONE_COMMIT; | ||
case 'semaphore': | ||
return this.vars.REVISION || this.vars.SEMAPHORE_GIT_PR_SHA || this.vars.SEMAPHORE_GIT_SHA; | ||
case 'buildkite': | ||
return this.vars.BUILDKITE_COMMIT !== 'HEAD' && this.vars.BUILDKITE_COMMIT; | ||
case 'heroku': | ||
return this.vars.HEROKU_TEST_RUN_COMMIT_VERSION; | ||
case 'gitlab': | ||
return this.vars.CI_COMMIT_SHA; | ||
case 'azure': | ||
return this.vars.SYSTEM_PULLREQUEST_SOURCECOMMITID || this.vars.BUILD_SOURCEVERSION; | ||
case 'appveyor': | ||
return this.vars.APPVEYOR_PULL_REQUEST_HEAD_COMMIT || this.vars.APPVEYOR_REPO_COMMIT; | ||
case 'probo': | ||
case 'netlify': | ||
return this.vars.COMMIT_REF; | ||
case 'bitbucket': | ||
return this.vars.BITBUCKET_COMMIT; | ||
case 'github': | ||
@@ -126,7 +107,6 @@ return ((_github$pull_request = github(this.vars).pull_request) === null || _github$pull_request === void 0 ? void 0 : _github$pull_request.head.sha) || this.vars.GITHUB_SHA; | ||
})(); | ||
return commit || null; | ||
} // current branch name | ||
} | ||
// current branch name | ||
get branch() { | ||
@@ -136,52 +116,35 @@ if (this.vars.PERCY_BRANCH) { | ||
} | ||
let branch = (() => { | ||
var _github$pull_request2; | ||
switch (this.ci) { | ||
case 'travis': | ||
return this.pullRequest && this.vars.TRAVIS_PULL_REQUEST_BRANCH || this.vars.TRAVIS_BRANCH; | ||
case 'jenkins-prb': | ||
return this.vars.ghprbSourceBranch; | ||
case 'jenkins': | ||
return this.vars.CHANGE_BRANCH || this.vars.GIT_BRANCH; | ||
case 'circle': | ||
return this.vars.CIRCLE_BRANCH; | ||
case 'codeship': | ||
return this.vars.CI_BRANCH; | ||
case 'drone': | ||
return this.vars.DRONE_BRANCH; | ||
case 'semaphore': | ||
return this.vars.BRANCH_NAME || this.vars.SEMAPHORE_GIT_PR_BRANCH || this.vars.SEMAPHORE_GIT_BRANCH; | ||
case 'buildkite': | ||
return this.vars.BUILDKITE_BRANCH; | ||
case 'heroku': | ||
return this.vars.HEROKU_TEST_RUN_BRANCH; | ||
case 'gitlab': | ||
return this.vars.CI_COMMIT_REF_NAME; | ||
case 'azure': | ||
return this.vars.SYSTEM_PULLREQUEST_SOURCEBRANCH || this.vars.BUILD_SOURCEBRANCHNAME; | ||
case 'appveyor': | ||
return this.vars.APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH || this.vars.APPVEYOR_REPO_BRANCH; | ||
case 'probo': | ||
return this.vars.BRANCH_NAME; | ||
case 'bitbucket': | ||
return this.vars.BITBUCKET_BRANCH; | ||
case 'github': | ||
return ((_github$pull_request2 = github(this.vars).pull_request) === null || _github$pull_request2 === void 0 ? void 0 : _github$pull_request2.head.ref) || this.vars.GITHUB_REF; | ||
case 'netlify': | ||
@@ -191,7 +154,6 @@ return this.vars.HEAD; | ||
})(); | ||
return (branch === null || branch === void 0 ? void 0 : branch.replace(/^refs\/\w+?\//, '')) || null; | ||
} // pull request number | ||
} | ||
// pull request number | ||
get pullRequest() { | ||
@@ -201,49 +163,33 @@ if (this.vars.PERCY_PULL_REQUEST) { | ||
} | ||
let pr = (() => { | ||
var _this$vars$CI_PULL_RE, _this$vars$PULL_REQUE, _github$pull_request3; | ||
switch (this.ci) { | ||
case 'travis': | ||
return this.vars.TRAVIS_PULL_REQUEST !== 'false' && this.vars.TRAVIS_PULL_REQUEST; | ||
case 'jenkins-prb': | ||
return this.vars.ghprbPullId; | ||
case 'jenkins': | ||
return this.vars.CHANGE_ID; | ||
case 'circle': | ||
return (_this$vars$CI_PULL_RE = this.vars.CI_PULL_REQUESTS) === null || _this$vars$CI_PULL_RE === void 0 ? void 0 : _this$vars$CI_PULL_RE.split('/').slice(-1)[0]; | ||
case 'drone': | ||
return this.vars.CI_PULL_REQUEST; | ||
case 'semaphore': | ||
return this.vars.PULL_REQUEST_NUMBER || this.vars.SEMAPHORE_GIT_PR_NUMBER; | ||
case 'buildkite': | ||
return this.vars.BUILDKITE_PULL_REQUEST !== 'false' && this.vars.BUILDKITE_PULL_REQUEST; | ||
case 'heroku': | ||
return this.vars.HEROKU_PR_NUMBER; | ||
case 'gitlab': | ||
return this.vars.CI_MERGE_REQUEST_IID; | ||
case 'azure': | ||
return this.vars.SYSTEM_PULLREQUEST_PULLREQUESTID || this.vars.SYSTEM_PULLREQUEST_PULLREQUESTNUMBER; | ||
case 'appveyor': | ||
return this.vars.APPVEYOR_PULL_REQUEST_NUMBER; | ||
case 'probo': | ||
return (_this$vars$PULL_REQUE = this.vars.PULL_REQUEST_LINK) === null || _this$vars$PULL_REQUE === void 0 ? void 0 : _this$vars$PULL_REQUE.split('/').slice(-1)[0]; | ||
case 'bitbucket': | ||
return this.vars.BITBUCKET_PR_ID; | ||
case 'netlify': | ||
return this.vars.PULL_REQUEST !== 'false' && this.vars.REVIEW_ID; | ||
case 'github': | ||
@@ -253,61 +199,45 @@ return (_github$pull_request3 = github(this.vars).pull_request) === null || _github$pull_request3 === void 0 ? void 0 : _github$pull_request3.number; | ||
})(); | ||
return pr || null; | ||
} // parallel total & nonce | ||
} | ||
// parallel total & nonce | ||
get parallel() { | ||
let total = parseInt(this.vars.PERCY_PARALLEL_TOTAL, 10); | ||
if (!Number.isInteger(total)) total = null; // no nonce if no total | ||
if (!Number.isInteger(total)) total = null; | ||
// no nonce if no total | ||
let nonce = total && (() => { | ||
var _this$vars$BUILD_TAG; | ||
if (this.vars.PERCY_PARALLEL_NONCE) { | ||
return this.vars.PERCY_PARALLEL_NONCE; | ||
} | ||
switch (this.ci) { | ||
case 'travis': | ||
return this.vars.TRAVIS_BUILD_NUMBER; | ||
case 'jenkins-prb': | ||
return this.vars.BUILD_NUMBER; | ||
case 'jenkins': | ||
return (_this$vars$BUILD_TAG = this.vars.BUILD_TAG) === null || _this$vars$BUILD_TAG === void 0 ? void 0 : _this$vars$BUILD_TAG.split('').reverse().join('').substring(0, 60); | ||
case 'circle': | ||
return this.vars.CIRCLE_WORKFLOW_ID || this.vars.CIRCLE_BUILD_NUM; | ||
case 'codeship': | ||
return this.vars.CI_BUILD_NUMBER || this.vars.CI_BUILD_ID; | ||
case 'drone': | ||
return this.vars.DRONE_BUILD_NUMBER; | ||
case 'semaphore': | ||
return this.vars.SEMAPHORE_WORKFLOW_ID || `${this.vars.SEMAPHORE_BRANCH_ID}/${this.vars.SEMAPHORE_BUILD_NUMBER}`; | ||
case 'buildkite': | ||
return this.vars.BUILDKITE_BUILD_ID; | ||
case 'heroku': | ||
return this.vars.HEROKU_TEST_RUN_ID; | ||
case 'gitlab': | ||
return this.vars.CI_PIPELINE_ID; | ||
case 'azure': | ||
return this.vars.BUILD_BUILDID; | ||
case 'appveyor': | ||
return this.vars.APPVEYOR_BUILD_ID; | ||
case 'probo': | ||
return this.vars.BUILD_ID; | ||
case 'bitbucket': | ||
return this.vars.BITBUCKET_BUILD_NUMBER; | ||
case 'github': | ||
@@ -317,3 +247,2 @@ return this.vars.GITHUB_RUN_ID; | ||
})(); | ||
return { | ||
@@ -323,10 +252,10 @@ total: total || null, | ||
}; | ||
} // git information for the current commit | ||
} | ||
// git information for the current commit | ||
get git() { | ||
return getCommitData(this.commit, this.branch, this.vars); | ||
} // manually set build commit and branch targets | ||
} | ||
// manually set build commit and branch targets | ||
get target() { | ||
@@ -337,17 +266,17 @@ return { | ||
}; | ||
} // build marked as partial | ||
} | ||
// build marked as partial | ||
get partial() { | ||
let partial = this.vars.PERCY_PARTIAL_BUILD; | ||
return !!partial && partial !== '0'; | ||
} // percy token | ||
} | ||
// percy token | ||
get token() { | ||
return this.vars.PERCY_TOKEN || null; | ||
} | ||
} | ||
} // cache getters on initial call so subsequent calls are not re-computed | ||
// cache getters on initial call so subsequent calls are not re-computed | ||
Object.defineProperties(PercyEnv.prototype, Object.entries(Object.getOwnPropertyDescriptors(PercyEnv.prototype)).reduce((proto, [key, { | ||
@@ -365,5 +294,4 @@ get, | ||
} | ||
}) | ||
}), {})); | ||
export default PercyEnv; |
import fs from 'fs'; | ||
import cp from 'child_process'; | ||
const GIT_COMMIT_FORMAT = ['COMMIT_SHA:%H', 'AUTHOR_NAME:%an', 'AUTHOR_EMAIL:%ae', 'COMMITTER_NAME:%cn', 'COMMITTER_EMAIL:%ce', 'COMMITTED_DATE:%ai', // order is important, this must come last because the regex is a multiline match. | ||
const GIT_COMMIT_FORMAT = ['COMMIT_SHA:%H', 'AUTHOR_NAME:%an', 'AUTHOR_EMAIL:%ae', 'COMMITTER_NAME:%cn', 'COMMITTER_EMAIL:%ce', 'COMMITTED_DATE:%ai', | ||
// order is important, this must come last because the regex is a multiline match. | ||
'COMMIT_MESSAGE:%B'].join('%n'); // git show format uses %n for newlines. | ||
@@ -15,13 +16,13 @@ | ||
} | ||
} // get raw commit data | ||
} | ||
// get raw commit data | ||
export function getCommitData(sha, branch, vars = {}) { | ||
let raw = git(`show ${sha || 'HEAD'} --quiet --format=${GIT_COMMIT_FORMAT}`); // prioritize PERCY_GIT_* vars and fallback to GIT_* vars | ||
let raw = git(`show ${sha || 'HEAD'} --quiet --format=${GIT_COMMIT_FORMAT}`); | ||
// prioritize PERCY_GIT_* vars and fallback to GIT_* vars | ||
let get = key => { | ||
var _raw$match; | ||
return vars[`PERCY_GIT_${key}`] || ((_raw$match = raw.match(new RegExp(`^${key}:(.*)$`, 'm'))) === null || _raw$match === void 0 ? void 0 : _raw$match[1]) || vars[`GIT_${key}`] || null; | ||
}; | ||
return { | ||
@@ -37,9 +38,11 @@ sha: (sha === null || sha === void 0 ? void 0 : sha.length) === 40 ? sha : get('COMMIT_SHA'), | ||
}; | ||
} // the sha needed from Jenkins merge commits is the parent sha | ||
} | ||
// the sha needed from Jenkins merge commits is the parent sha | ||
export function getJenkinsSha() { | ||
let data = getCommitData(); | ||
return data.authorName === 'Jenkins' && data.authorEmail === 'nobody@nowhere' && data.message.match(/^Merge commit [^\s]+ into HEAD$/) && git('rev-parse HEAD^'); | ||
} // github actions are triggered by webhook events which are saved to the filesystem | ||
} | ||
// github actions are triggered by webhook events which are saved to the filesystem | ||
export function github({ | ||
@@ -53,4 +56,3 @@ GITHUB_EVENT_PATH | ||
} | ||
return github.payload || (github.payload = {}); | ||
} |
{ | ||
"name": "@percy/env", | ||
"version": "1.12.0", | ||
"version": "1.13.0", | ||
"license": "MIT", | ||
@@ -33,3 +33,3 @@ "repository": { | ||
}, | ||
"gitHead": "4303b74df91f60e36065141289d2ef2277d1d6fc" | ||
"gitHead": "d2e812d14aa446fa580ffa75144a6280627b5a27" | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
405
18961