@argos-ci/cli 0.4.0 → 0.4.1

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.
Files changed (2) hide show
  1. package/dist/index.mjs +63 -53
  2. package/package.json +3 -3
package/dist/index.mjs CHANGED
@@ -5,6 +5,7 @@ import { program } from 'commander';
5
5
  import convict from 'convict';
6
6
  import envCi from 'env-ci';
7
7
  import { execSync } from 'child_process';
8
+ import createDebug from 'debug';
8
9
  import glob from 'fast-glob';
9
10
  import { promisify } from 'node:util';
10
11
  import sharp from 'sharp';
@@ -12,7 +13,6 @@ import tmp from 'tmp';
12
13
  import { createReadStream } from 'node:fs';
13
14
  import { createHash } from 'node:crypto';
14
15
  import axios from 'axios';
15
- import createDebug from 'debug';
16
16
  import ora from 'ora';
17
17
 
18
18
  const mustBeApiBaseUrl = (value)=>{
@@ -44,14 +44,13 @@ const schema = {
44
44
  },
45
45
  commit: {
46
46
  env: "ARGOS_COMMIT",
47
- default: "",
47
+ default: null,
48
48
  format: mustBeCommit
49
49
  },
50
50
  branch: {
51
51
  env: "ARGOS_BRANCH",
52
52
  default: null,
53
- format: String,
54
- nullable: true
53
+ format: String
55
54
  },
56
55
  token: {
57
56
  env: "ARGOS_TOKEN",
@@ -64,6 +63,12 @@ const schema = {
64
63
  format: String,
65
64
  nullable: true
66
65
  },
66
+ prNumber: {
67
+ env: "ARGOS_PR_NUMBER",
68
+ format: Number,
69
+ default: null,
70
+ nullable: true
71
+ },
67
72
  parallel: {
68
73
  env: "ARGOS_PARALLEL",
69
74
  default: false,
@@ -96,11 +101,6 @@ const schema = {
96
101
  default: null,
97
102
  nullable: true
98
103
  },
99
- prNumber: {
100
- format: Number,
101
- default: null,
102
- nullable: true
103
- },
104
104
  owner: {
105
105
  format: String,
106
106
  default: null,
@@ -118,26 +118,14 @@ const createConfig = ()=>{
118
118
  });
119
119
  };
120
120
 
121
- /**
122
- * Omit undefined properties from an object.
123
- */ const omitUndefined = (obj)=>{
124
- const result = {};
125
- Object.keys(obj).forEach((key)=>{
126
- if (obj[key] !== undefined) {
127
- result[key] = obj[key];
128
- }
129
- });
130
- return result;
131
- };
132
-
133
121
  const service$4 = {
122
+ name: "Buildkite",
134
123
  detect: ({ env })=>Boolean(env.BUILDKITE),
135
124
  config: ({ env })=>{
136
125
  const ciProps = envCiDetection({
137
126
  env
138
127
  });
139
128
  return {
140
- name: "Buildkite",
141
129
  commit: ciProps?.commit || null,
142
130
  branch: env.BUILDKITE_BRANCH || null,
143
131
  owner: env.BUILDKITE_ORGANIZATION_SLUG || null,
@@ -150,9 +138,9 @@ const service$4 = {
150
138
  };
151
139
 
152
140
  const service$3 = {
141
+ name: "Heroku",
153
142
  detect: ({ env })=>Boolean(env.HEROKU_TEST_RUN_ID),
154
143
  config: ({ env })=>({
155
- name: "Heroku",
156
144
  commit: env.HEROKU_TEST_RUN_COMMIT_VERSION || null,
157
145
  branch: env.HEROKU_TEST_RUN_BRANCH || null,
158
146
  owner: null,
@@ -220,9 +208,9 @@ const getPrNumber$1 = ({ env })=>{
220
208
  return null;
221
209
  };
222
210
  const service$2 = {
211
+ name: "GitHub Actions",
223
212
  detect: ({ env })=>Boolean(env.GITHUB_ACTIONS),
224
213
  config: ({ env })=>({
225
- name: "GitHub Actions",
226
214
  commit: getSha({
227
215
  env
228
216
  }),
@@ -250,13 +238,13 @@ const getPrNumber = ({ env })=>{
250
238
  return null;
251
239
  };
252
240
  const service$1 = {
241
+ name: "CircleCI",
253
242
  detect: ({ env })=>Boolean(env.CIRCLECI),
254
243
  config: ({ env })=>{
255
244
  const ciProps = envCiDetection({
256
245
  env
257
246
  });
258
247
  return {
259
- name: "CircleCI",
260
248
  commit: ciProps?.commit || null,
261
249
  branch: ciProps?.branch || null,
262
250
  owner: ciProps?.owner || null,
@@ -271,13 +259,13 @@ const service$1 = {
271
259
  };
272
260
 
273
261
  const service = {
262
+ name: "Travis CI",
274
263
  detect: ({ env })=>Boolean(env.TRAVIS),
275
264
  config: ({ env })=>{
276
265
  const ciProps = envCiDetection({
277
266
  env
278
267
  });
279
268
  return {
280
- name: "Travis CI",
281
269
  commit: ciProps?.commit || null,
282
270
  branch: ciProps?.branch || null,
283
271
  owner: ciProps?.owner || null,
@@ -289,6 +277,8 @@ const service = {
289
277
  }
290
278
  };
291
279
 
280
+ const debug = createDebug("@argos-ci/core");
281
+
292
282
  const services = [
293
283
  service$3,
294
284
  service$2,
@@ -322,12 +312,25 @@ const getCiEnvironment = ({ env =process.env } = {})=>{
322
312
  const ctx = {
323
313
  env
324
314
  };
315
+ debug("Detecting CI environment", {
316
+ env
317
+ });
325
318
  const service = services.find((service)=>service.detect(ctx));
326
319
  // Internal service matched
327
320
  if (service) {
328
- return service.config(ctx);
321
+ debug("Internal service matched", service.name);
322
+ const variables = service.config(ctx);
323
+ const ciEnvironment = {
324
+ name: service.name,
325
+ ...variables
326
+ };
327
+ debug("CI environment", ciEnvironment);
328
+ return ciEnvironment;
329
329
  }
330
- return envCiDetection(ctx);
330
+ debug("Falling back on env-ci");
331
+ const ciEnvironment1 = envCiDetection(ctx);
332
+ debug("CI environment", ciEnvironment1);
333
+ return ciEnvironment1;
331
334
  };
332
335
 
333
336
  const discoverScreenshots = async (patterns, { root =process.cwd() , ignore } = {})=>{
@@ -398,11 +401,20 @@ const createArgosApiClient = (options)=>{
398
401
  });
399
402
  const call = async (method, path, data)=>{
400
403
  try {
404
+ debug("Sending request", {
405
+ method,
406
+ path,
407
+ data
408
+ });
401
409
  const response = await axiosInstance.request({
402
410
  method,
403
411
  url: path,
404
412
  data
405
413
  });
414
+ debug("Getting response", {
415
+ status: response.status,
416
+ data: response.data
417
+ });
406
418
  return response.data;
407
419
  } catch (error) {
408
420
  if (error?.response?.data?.error?.message) {
@@ -437,45 +449,42 @@ const upload$1 = async (input)=>{
437
449
  });
438
450
  };
439
451
 
440
- const debug = createDebug("@argos-ci/core");
441
-
442
452
  const getConfigFromOptions = (options)=>{
443
453
  const config = createConfig();
444
454
  const ciEnv = getCiEnvironment();
445
- if (ciEnv) {
446
- config.load(omitUndefined({
447
- commit: ciEnv.commit,
448
- branch: ciEnv.branch,
449
- ciService: ciEnv.name,
450
- owner: ciEnv.owner,
451
- repository: ciEnv.repository,
452
- jobId: ciEnv.jobId,
453
- runId: ciEnv.runId,
454
- prNumber: ciEnv.prNumber
455
- }));
455
+ config.load({
456
+ apiBaseUrl: config.get("apiBaseUrl") ?? options.apiBaseUrl,
457
+ commit: config.get("commit") ?? options.commit ?? ciEnv?.commit ?? null,
458
+ branch: config.get("branch") ?? options.branch ?? ciEnv?.branch ?? null,
459
+ token: config.get("token") ?? options.token ?? null,
460
+ buildName: config.get("buildName") ?? options.buildName ?? null,
461
+ prNumber: config.get("prNumber") ?? options.prNumber ?? ciEnv?.prNumber ?? null,
462
+ ciService: ciEnv?.name ?? null,
463
+ owner: ciEnv?.owner ?? null,
464
+ repository: ciEnv?.repository ?? null,
465
+ jobId: ciEnv?.jobId ?? null,
466
+ runId: ciEnv?.runId ?? null
467
+ });
468
+ if (options.parallel) {
469
+ config.load({
470
+ parallel: Boolean(options.parallel),
471
+ parallelNonce: options.parallel ? options.parallel.nonce : null,
472
+ parallelTotal: options.parallel ? options.parallel.total : null
473
+ });
456
474
  }
457
- config.load(omitUndefined({
458
- apiBaseUrl: options.apiBaseUrl,
459
- commit: options.commit,
460
- branch: options.branch,
461
- token: options.token,
462
- prNumber: options.prNumber,
463
- buildName: options.buildName,
464
- parallel: Boolean(options.parallel),
465
- parallelNonce: options.parallel ? options.parallel.nonce : null,
466
- parallelTotal: options.parallel ? options.parallel.total : null
467
- }));
468
475
  config.validate();
469
476
  return config.get();
470
477
  };
471
478
  /**
472
479
  * Upload screenshots to argos-ci.com.
473
480
  */ const upload = async (params)=>{
481
+ debug("Starting upload with params", params);
474
482
  // Read config
475
483
  const config = getConfigFromOptions(params);
476
484
  const files = params.files ?? [
477
485
  "**/*.{png,jpg,jpeg}"
478
486
  ];
487
+ debug("Using config and files", config, files);
479
488
  const apiClient = createArgosApiClient({
480
489
  baseUrl: config.apiBaseUrl,
481
490
  bearerToken: getBearerToken(config)
@@ -485,6 +494,7 @@ const getConfigFromOptions = (options)=>{
485
494
  root: params.root,
486
495
  ignore: params.ignore
487
496
  });
497
+ debug("Found screenshots", foundScreenshots);
488
498
  // Optimize & compute hashes
489
499
  const screenshots = await Promise.all(foundScreenshots.map(async (screenshot)=>{
490
500
  const optimizedPath = await optimizeScreenshot(screenshot.path);
@@ -540,7 +550,7 @@ const __dirname = fileURLToPath(new URL(".", import.meta.url));
540
550
  const rawPkg = await readFile(resolve(__dirname, "..", "package.json"), "utf8");
541
551
  const pkg = JSON.parse(rawPkg);
542
552
  program.name(pkg.name).description("Interact with and upload screenshots to argos-ci.com via command line.").version(pkg.version);
543
- program.command("upload").argument("<directory>", "Directory to upload").description("Upload screenshots to argos-ci.com").option("-f, --files <patterns...>", "One or more globs matching image file paths to upload", "**/*.{png,jpg,jpeg}").option("-i, --ignore <patterns...>", 'One or more globs matching image file paths to ignore (ex: "**/*.png **/diff.jpg")').option("--token <token>", "Repository token").option("--pull-request <number>", "Pull-request number").option("--build-name <string>", "Name of the build, in case you want to run multiple Argos builds in a single CI job").option("--parallel", "Enable parallel mode. Run multiple Argos builds and combine them at the end").option("--parallel-total <number>", "The number of parallel nodes being ran").option("--parallel-nonce <string>", "A unique ID for this parallel build").action(async (directory, options)=>{
553
+ program.command("upload").argument("<directory>", "Directory to upload").description("Upload screenshots to argos-ci.com").option("-f, --files <patterns...>", "One or more globs matching image file paths to upload", "**/*.{png,jpg,jpeg}").option("-i, --ignore <patterns...>", 'One or more globs matching image file paths to ignore (ex: "**/*.png **/diff.jpg")').option("--token <token>", "Repository token").option("--build-name <string>", "Name of the build, in case you want to run multiple Argos builds in a single CI job").option("--parallel", "Enable parallel mode. Run multiple Argos builds and combine them at the end").option("--parallel-total <number>", "The number of parallel nodes being ran").option("--parallel-nonce <string>", "A unique ID for this parallel build").action(async (directory, options)=>{
544
554
  const spinner = ora("Uploading screenshots").start();
545
555
  try {
546
556
  const result = await upload({
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@argos-ci/cli",
3
3
  "description": "Visual testing solution to avoid visual regression. Argos CLI is used to interact with and upload screenshots to argos-ci.com via command line.",
4
- "version": "0.4.0",
4
+ "version": "0.4.1",
5
5
  "bin": {
6
6
  "argos": "./bin/argos-cli.js"
7
7
  },
@@ -40,7 +40,7 @@
40
40
  "access": "public"
41
41
  },
42
42
  "dependencies": {
43
- "@argos-ci/core": "^0.7.0",
43
+ "@argos-ci/core": "^0.7.1",
44
44
  "commander": "^9.4.1",
45
45
  "ora": "^6.1.2",
46
46
  "update-notifier": "^6.0.2"
@@ -49,5 +49,5 @@
49
49
  "rollup": "^2.79.1",
50
50
  "rollup-plugin-swc3": "^0.6.0"
51
51
  },
52
- "gitHead": "a7603beaf95ec4be8be9405450a445bfe94a6a12"
52
+ "gitHead": "0ae6b18c7728deb14beb7ffee85e9faf104c4365"
53
53
  }