@percy/env 1.12.0 → 1.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/dotenv.js CHANGED
@@ -1,61 +1,75 @@
1
- import fs from 'fs'; // Heavily inspired by dotenv-rails
2
- // https://github.com/bkeepers/dotenv
3
- // matches each valid line of a dotenv file
4
-
5
- const LINE_REG = new RegExp([// key with optional export
6
- '^\\s*(?:export\\s+)?(?<key>[\\w.]+)', // separator
7
- '(?:\\s*=\\s*?|:\\s+?)(?:', // single quoted value or
8
- '\\s*(?<squote>\')(?<sval>(?:\\\\\'|[^\'])*)\'|', // double quoted value or
9
- '\\s*(?<dquote>")(?<dval>(?:\\\\"|[^"])*)"|', // unquoted value
10
- '(?<uval>[^#\\r\\n]+))?', // optional comment
11
- '\\s*(?:#.*)?$'].join(''), 'gm'); // interpolate variable substitutions
1
+ import fs from 'fs';
12
2
 
13
- const INTERPOLATE_REG = /(.?)(\${?([a-zA-Z0-9_]+)?}?)/g; // expand newlines
3
+ // Heavily inspired by dotenv-rails
4
+ // https://github.com/bkeepers/dotenv
14
5
 
15
- const EXPAND_CRLF_REG = /\\(?:(r)|n)/g; // unescape characters
6
+ // matches each valid line of a dotenv file
7
+ const LINE_REG = new RegExp([
8
+ // key with optional export
9
+ '^\\s*(?:export\\s+)?(?<key>[\\w.]+)',
10
+ // separator
11
+ '(?:\\s*=\\s*?|:\\s+?)(?:',
12
+ // single quoted value or
13
+ '\\s*(?<squote>\')(?<sval>(?:\\\\\'|[^\'])*)\'|',
14
+ // double quoted value or
15
+ '\\s*(?<dquote>")(?<dval>(?:\\\\"|[^"])*)"|',
16
+ // unquoted value
17
+ '(?<uval>[^#\\r\\n]+))?',
18
+ // optional comment
19
+ '\\s*(?:#.*)?$'].join(''), 'gm');
16
20
 
21
+ // interpolate variable substitutions
22
+ const INTERPOLATE_REG = /(.?)(\${?([a-zA-Z0-9_]+)?}?)/g;
23
+ // expand newlines
24
+ const EXPAND_CRLF_REG = /\\(?:(r)|n)/g;
25
+ // unescape characters
17
26
  const UNESC_CHAR_REG = /\\([^$])/g;
18
27
  export function load() {
19
28
  // don't load dotenv files when disabled
20
29
  if (process.env.PERCY_DISABLE_DOTENV) return;
21
30
  let {
22
31
  NODE_ENV
23
- } = process.env; // dotenv filepaths ordered by priority
32
+ } = process.env;
24
33
 
25
- let paths = [NODE_ENV && `.env.${NODE_ENV}.local`, NODE_ENV !== 'test' && '.env.local', NODE_ENV && `.env.${NODE_ENV}`, '.env']; // load each dotenv file synchronously
34
+ // dotenv filepaths ordered by priority
35
+ let paths = [NODE_ENV && `.env.${NODE_ENV}.local`, NODE_ENV !== 'test' && '.env.local', NODE_ENV && `.env.${NODE_ENV}`, '.env'];
26
36
 
37
+ // load each dotenv file synchronously
27
38
  for (let path of paths) {
28
39
  try {
29
40
  let src = fs.readFileSync(path, {
30
41
  encoding: 'utf-8'
31
- }); // iterate over each matching line
42
+ });
32
43
 
44
+ // iterate over each matching line
33
45
  for (let {
34
46
  groups: match
35
47
  } of src.matchAll(LINE_REG)) {
36
- let value = match.sval ?? match.dval ?? match.uval ?? ''; // if double quoted, expand newlines
48
+ let value = match.sval ?? match.dval ?? match.uval ?? '';
37
49
 
50
+ // if double quoted, expand newlines
38
51
  if (match.dquote) {
39
52
  value = value.replace(EXPAND_CRLF_REG, (_, r) => r ? '\r' : '\n');
40
- } // unescape characters
41
-
53
+ }
42
54
 
43
- value = value.replace(UNESC_CHAR_REG, '$1'); // if not single quoted, interpolate substitutions
55
+ // unescape characters
56
+ value = value.replace(UNESC_CHAR_REG, '$1');
44
57
 
58
+ // if not single quoted, interpolate substitutions
45
59
  if (!match.squote) {
46
60
  value = value.replace(INTERPOLATE_REG, (_, pre, ref, key) => {
47
61
  if (pre === '\\') return ref; // escaped reference
48
-
49
62
  return pre + (process.env[key] ?? '');
50
63
  });
51
- } // set process.env if not already
52
-
64
+ }
53
65
 
66
+ // set process.env if not already
54
67
  if (!Object.prototype.hasOwnProperty.call(process.env, match.key)) {
55
68
  process.env[match.key] = value;
56
69
  }
57
70
  }
58
- } catch (e) {// silent error
71
+ } catch (e) {
72
+ // silent error
59
73
  }
60
74
  }
61
75
  }
@@ -2,9 +2,9 @@ import { getCommitData, getJenkinsSha, github } from './utils.js';
2
2
  export class PercyEnv {
3
3
  constructor(vars = process.env) {
4
4
  this.vars = vars;
5
- } // used for getter switch statements
6
-
5
+ }
7
6
 
7
+ // used for getter switch statements
8
8
  get ci() {
9
9
  if (this.vars.TRAVIS_BUILD_ID) {
10
10
  return 'travis';
@@ -43,301 +43,230 @@ export class PercyEnv {
43
43
  } else {
44
44
  return null;
45
45
  }
46
- } // environment info reported in user-agents
47
-
46
+ }
48
47
 
48
+ // environment info reported in user-agents
49
49
  get info() {
50
50
  switch (this.ci) {
51
51
  case 'github':
52
52
  return this.vars.PERCY_GITHUB_ACTION ? `github/${this.vars.PERCY_GITHUB_ACTION}` : this.ci;
53
-
54
53
  case 'gitlab':
55
54
  return `gitlab/${this.vars.CI_SERVER_VERSION}`;
56
-
57
55
  case 'semaphore':
58
56
  return this.vars.SEMAPHORE_GIT_SHA ? 'semaphore/2.0' : 'semaphore';
59
-
60
57
  default:
61
58
  return this.ci;
62
59
  }
63
- } // current commit sha
64
-
60
+ }
65
61
 
62
+ // current commit sha
66
63
  get commit() {
67
64
  if (this.vars.PERCY_COMMIT) {
68
65
  return this.vars.PERCY_COMMIT;
69
66
  }
70
-
71
67
  let commit = (() => {
72
68
  var _github$pull_request;
73
-
74
69
  switch (this.ci) {
75
70
  case 'travis':
76
71
  return this.vars.TRAVIS_COMMIT;
77
-
78
72
  case 'jenkins-prb':
79
73
  return this.vars.ghprbActualCommit || this.vars.GIT_COMMIT;
80
-
81
74
  case 'jenkins':
82
75
  return getJenkinsSha() || this.vars.GIT_COMMIT;
83
-
84
76
  case 'circle':
85
77
  return this.vars.CIRCLE_SHA1;
86
-
87
78
  case 'codeship':
88
79
  return this.vars.CI_COMMIT_ID;
89
-
90
80
  case 'drone':
91
81
  return this.vars.DRONE_COMMIT;
92
-
93
82
  case 'semaphore':
94
83
  return this.vars.REVISION || this.vars.SEMAPHORE_GIT_PR_SHA || this.vars.SEMAPHORE_GIT_SHA;
95
-
96
84
  case 'buildkite':
97
85
  return this.vars.BUILDKITE_COMMIT !== 'HEAD' && this.vars.BUILDKITE_COMMIT;
98
-
99
86
  case 'heroku':
100
87
  return this.vars.HEROKU_TEST_RUN_COMMIT_VERSION;
101
-
102
88
  case 'gitlab':
103
89
  return this.vars.CI_COMMIT_SHA;
104
-
105
90
  case 'azure':
106
91
  return this.vars.SYSTEM_PULLREQUEST_SOURCECOMMITID || this.vars.BUILD_SOURCEVERSION;
107
-
108
92
  case 'appveyor':
109
93
  return this.vars.APPVEYOR_PULL_REQUEST_HEAD_COMMIT || this.vars.APPVEYOR_REPO_COMMIT;
110
-
111
94
  case 'probo':
112
95
  case 'netlify':
113
96
  return this.vars.COMMIT_REF;
114
-
115
97
  case 'bitbucket':
116
98
  return this.vars.BITBUCKET_COMMIT;
117
-
118
99
  case 'github':
119
100
  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;
120
101
  }
121
102
  })();
122
-
123
103
  return commit || null;
124
- } // current branch name
125
-
104
+ }
126
105
 
106
+ // current branch name
127
107
  get branch() {
128
108
  if (this.vars.PERCY_BRANCH) {
129
109
  return this.vars.PERCY_BRANCH;
130
110
  }
131
-
132
111
  let branch = (() => {
133
112
  var _github$pull_request2;
134
-
135
113
  switch (this.ci) {
136
114
  case 'travis':
137
115
  return this.pullRequest && this.vars.TRAVIS_PULL_REQUEST_BRANCH || this.vars.TRAVIS_BRANCH;
138
-
139
116
  case 'jenkins-prb':
140
117
  return this.vars.ghprbSourceBranch;
141
-
142
118
  case 'jenkins':
143
119
  return this.vars.CHANGE_BRANCH || this.vars.GIT_BRANCH;
144
-
145
120
  case 'circle':
146
121
  return this.vars.CIRCLE_BRANCH;
147
-
148
122
  case 'codeship':
149
123
  return this.vars.CI_BRANCH;
150
-
151
124
  case 'drone':
152
125
  return this.vars.DRONE_BRANCH;
153
-
154
126
  case 'semaphore':
155
127
  return this.vars.BRANCH_NAME || this.vars.SEMAPHORE_GIT_PR_BRANCH || this.vars.SEMAPHORE_GIT_BRANCH;
156
-
157
128
  case 'buildkite':
158
129
  return this.vars.BUILDKITE_BRANCH;
159
-
160
130
  case 'heroku':
161
131
  return this.vars.HEROKU_TEST_RUN_BRANCH;
162
-
163
132
  case 'gitlab':
164
133
  return this.vars.CI_COMMIT_REF_NAME;
165
-
166
134
  case 'azure':
167
135
  return this.vars.SYSTEM_PULLREQUEST_SOURCEBRANCH || this.vars.BUILD_SOURCEBRANCHNAME;
168
-
169
136
  case 'appveyor':
170
137
  return this.vars.APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH || this.vars.APPVEYOR_REPO_BRANCH;
171
-
172
138
  case 'probo':
173
139
  return this.vars.BRANCH_NAME;
174
-
175
140
  case 'bitbucket':
176
141
  return this.vars.BITBUCKET_BRANCH;
177
-
178
142
  case 'github':
179
143
  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;
180
-
181
144
  case 'netlify':
182
145
  return this.vars.HEAD;
183
146
  }
184
147
  })();
185
-
186
148
  return (branch === null || branch === void 0 ? void 0 : branch.replace(/^refs\/\w+?\//, '')) || null;
187
- } // pull request number
188
-
149
+ }
189
150
 
151
+ // pull request number
190
152
  get pullRequest() {
191
153
  if (this.vars.PERCY_PULL_REQUEST) {
192
154
  return this.vars.PERCY_PULL_REQUEST;
193
155
  }
194
-
195
156
  let pr = (() => {
196
157
  var _this$vars$CI_PULL_RE, _this$vars$PULL_REQUE, _github$pull_request3;
197
-
198
158
  switch (this.ci) {
199
159
  case 'travis':
200
160
  return this.vars.TRAVIS_PULL_REQUEST !== 'false' && this.vars.TRAVIS_PULL_REQUEST;
201
-
202
161
  case 'jenkins-prb':
203
162
  return this.vars.ghprbPullId;
204
-
205
163
  case 'jenkins':
206
164
  return this.vars.CHANGE_ID;
207
-
208
165
  case 'circle':
209
166
  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];
210
-
211
167
  case 'drone':
212
168
  return this.vars.CI_PULL_REQUEST;
213
-
214
169
  case 'semaphore':
215
170
  return this.vars.PULL_REQUEST_NUMBER || this.vars.SEMAPHORE_GIT_PR_NUMBER;
216
-
217
171
  case 'buildkite':
218
172
  return this.vars.BUILDKITE_PULL_REQUEST !== 'false' && this.vars.BUILDKITE_PULL_REQUEST;
219
-
220
173
  case 'heroku':
221
174
  return this.vars.HEROKU_PR_NUMBER;
222
-
223
175
  case 'gitlab':
224
176
  return this.vars.CI_MERGE_REQUEST_IID;
225
-
226
177
  case 'azure':
227
178
  return this.vars.SYSTEM_PULLREQUEST_PULLREQUESTID || this.vars.SYSTEM_PULLREQUEST_PULLREQUESTNUMBER;
228
-
229
179
  case 'appveyor':
230
180
  return this.vars.APPVEYOR_PULL_REQUEST_NUMBER;
231
-
232
181
  case 'probo':
233
182
  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];
234
-
235
183
  case 'bitbucket':
236
184
  return this.vars.BITBUCKET_PR_ID;
237
-
238
185
  case 'netlify':
239
186
  return this.vars.PULL_REQUEST !== 'false' && this.vars.REVIEW_ID;
240
-
241
187
  case 'github':
242
188
  return (_github$pull_request3 = github(this.vars).pull_request) === null || _github$pull_request3 === void 0 ? void 0 : _github$pull_request3.number;
243
189
  }
244
190
  })();
245
-
246
191
  return pr || null;
247
- } // parallel total & nonce
248
-
192
+ }
249
193
 
194
+ // parallel total & nonce
250
195
  get parallel() {
251
196
  let total = parseInt(this.vars.PERCY_PARALLEL_TOTAL, 10);
252
- if (!Number.isInteger(total)) total = null; // no nonce if no total
197
+ if (!Number.isInteger(total)) total = null;
253
198
 
199
+ // no nonce if no total
254
200
  let nonce = total && (() => {
255
201
  var _this$vars$BUILD_TAG;
256
-
257
202
  if (this.vars.PERCY_PARALLEL_NONCE) {
258
203
  return this.vars.PERCY_PARALLEL_NONCE;
259
204
  }
260
-
261
205
  switch (this.ci) {
262
206
  case 'travis':
263
207
  return this.vars.TRAVIS_BUILD_NUMBER;
264
-
265
208
  case 'jenkins-prb':
266
209
  return this.vars.BUILD_NUMBER;
267
-
268
210
  case 'jenkins':
269
211
  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);
270
-
271
212
  case 'circle':
272
213
  return this.vars.CIRCLE_WORKFLOW_ID || this.vars.CIRCLE_BUILD_NUM;
273
-
274
214
  case 'codeship':
275
215
  return this.vars.CI_BUILD_NUMBER || this.vars.CI_BUILD_ID;
276
-
277
216
  case 'drone':
278
217
  return this.vars.DRONE_BUILD_NUMBER;
279
-
280
218
  case 'semaphore':
281
219
  return this.vars.SEMAPHORE_WORKFLOW_ID || `${this.vars.SEMAPHORE_BRANCH_ID}/${this.vars.SEMAPHORE_BUILD_NUMBER}`;
282
-
283
220
  case 'buildkite':
284
221
  return this.vars.BUILDKITE_BUILD_ID;
285
-
286
222
  case 'heroku':
287
223
  return this.vars.HEROKU_TEST_RUN_ID;
288
-
289
224
  case 'gitlab':
290
225
  return this.vars.CI_PIPELINE_ID;
291
-
292
226
  case 'azure':
293
227
  return this.vars.BUILD_BUILDID;
294
-
295
228
  case 'appveyor':
296
229
  return this.vars.APPVEYOR_BUILD_ID;
297
-
298
230
  case 'probo':
299
231
  return this.vars.BUILD_ID;
300
-
301
232
  case 'bitbucket':
302
233
  return this.vars.BITBUCKET_BUILD_NUMBER;
303
-
304
234
  case 'github':
305
235
  return this.vars.GITHUB_RUN_ID;
306
236
  }
307
237
  })();
308
-
309
238
  return {
310
239
  total: total || null,
311
240
  nonce: nonce || null
312
241
  };
313
- } // git information for the current commit
314
-
242
+ }
315
243
 
244
+ // git information for the current commit
316
245
  get git() {
317
246
  return getCommitData(this.commit, this.branch, this.vars);
318
- } // manually set build commit and branch targets
319
-
247
+ }
320
248
 
249
+ // manually set build commit and branch targets
321
250
  get target() {
322
251
  return {
323
252
  commit: this.vars.PERCY_TARGET_COMMIT || null,
324
253
  branch: this.vars.PERCY_TARGET_BRANCH || null
325
254
  };
326
- } // build marked as partial
327
-
255
+ }
328
256
 
257
+ // build marked as partial
329
258
  get partial() {
330
259
  let partial = this.vars.PERCY_PARTIAL_BUILD;
331
260
  return !!partial && partial !== '0';
332
- } // percy token
333
-
261
+ }
334
262
 
263
+ // percy token
335
264
  get token() {
336
265
  return this.vars.PERCY_TOKEN || null;
337
266
  }
267
+ }
338
268
 
339
- } // cache getters on initial call so subsequent calls are not re-computed
340
-
269
+ // cache getters on initial call so subsequent calls are not re-computed
341
270
  Object.defineProperties(PercyEnv.prototype, Object.entries(Object.getOwnPropertyDescriptors(PercyEnv.prototype)).reduce((proto, [key, {
342
271
  get,
343
272
  ...descr
@@ -350,7 +279,6 @@ Object.defineProperties(PercyEnv.prototype, Object.entries(Object.getOwnProperty
350
279
  });
351
280
  return value;
352
281
  }
353
-
354
282
  })
355
283
  }), {}));
356
284
  export default PercyEnv;
package/dist/utils.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import fs from 'fs';
2
2
  import cp from 'child_process';
3
- 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.
3
+ const GIT_COMMIT_FORMAT = ['COMMIT_SHA:%H', 'AUTHOR_NAME:%an', 'AUTHOR_EMAIL:%ae', 'COMMITTER_NAME:%cn', 'COMMITTER_EMAIL:%ce', 'COMMITTED_DATE:%ai',
4
+ // order is important, this must come last because the regex is a multiline match.
4
5
  'COMMIT_MESSAGE:%B'].join('%n'); // git show format uses %n for newlines.
5
6
 
6
7
  export function git(args) {
@@ -12,17 +13,17 @@ export function git(args) {
12
13
  } catch (e) {
13
14
  return '';
14
15
  }
15
- } // get raw commit data
16
+ }
16
17
 
18
+ // get raw commit data
17
19
  export function getCommitData(sha, branch, vars = {}) {
18
- let raw = git(`show ${sha || 'HEAD'} --quiet --format=${GIT_COMMIT_FORMAT}`); // prioritize PERCY_GIT_* vars and fallback to GIT_* vars
20
+ let raw = git(`show ${sha || 'HEAD'} --quiet --format=${GIT_COMMIT_FORMAT}`);
19
21
 
22
+ // prioritize PERCY_GIT_* vars and fallback to GIT_* vars
20
23
  let get = key => {
21
24
  var _raw$match;
22
-
23
25
  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;
24
26
  };
25
-
26
27
  return {
27
28
  sha: (sha === null || sha === void 0 ? void 0 : sha.length) === 40 ? sha : get('COMMIT_SHA'),
28
29
  branch: branch || git('rev-parse --abbrev-ref HEAD') || null,
@@ -33,13 +34,15 @@ export function getCommitData(sha, branch, vars = {}) {
33
34
  committerName: get('COMMITTER_NAME'),
34
35
  committerEmail: get('COMMITTER_EMAIL')
35
36
  };
36
- } // the sha needed from Jenkins merge commits is the parent sha
37
+ }
37
38
 
39
+ // the sha needed from Jenkins merge commits is the parent sha
38
40
  export function getJenkinsSha() {
39
41
  let data = getCommitData();
40
42
  return data.authorName === 'Jenkins' && data.authorEmail === 'nobody@nowhere' && data.message.match(/^Merge commit [^\s]+ into HEAD$/) && git('rev-parse HEAD^');
41
- } // github actions are triggered by webhook events which are saved to the filesystem
43
+ }
42
44
 
45
+ // github actions are triggered by webhook events which are saved to the filesystem
43
46
  export function github({
44
47
  GITHUB_EVENT_PATH
45
48
  }) {
@@ -48,6 +51,5 @@ export function github({
48
51
  github.payload = JSON.parse(fs.readFileSync(GITHUB_EVENT_PATH));
49
52
  } catch {}
50
53
  }
51
-
52
54
  return github.payload || (github.payload = {});
53
55
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@percy/env",
3
- "version": "1.12.0",
3
+ "version": "1.13.0",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -30,5 +30,5 @@
30
30
  "test": "node ../../scripts/test",
31
31
  "test:coverage": "yarn test --coverage"
32
32
  },
33
- "gitHead": "4303b74df91f60e36065141289d2ef2277d1d6fc"
33
+ "gitHead": "d2e812d14aa446fa580ffa75144a6280627b5a27"
34
34
  }