@argos-ci/core 4.1.6 → 4.2.1-alpha.4

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 (3) hide show
  1. package/dist/index.d.ts +178 -147
  2. package/dist/index.js +182 -120
  3. package/package.json +5 -4
package/dist/index.d.ts CHANGED
@@ -1,123 +1,133 @@
1
- import * as _argos_ci_util from '@argos-ci/util';
2
1
  import { ArgosAPISchema } from '@argos-ci/api-client';
2
+ import { ScreenshotMetadata } from '@argos-ci/util';
3
3
 
4
- type BuildMetadata = ArgosAPISchema.components["schemas"]["BuildMetadata"];
5
- interface UploadParameters {
4
+ interface Config {
6
5
  /**
7
- * Globs matching image file paths to upload
6
+ * Base URL of the Argos API.
7
+ * Use this to target a self-hosted installation.
8
+ * @default "https://api.argos-ci.com/v2/"
8
9
  */
9
- files?: string[];
10
+ apiBaseUrl: string;
10
11
  /**
11
- * Root directory to look for image to upload
12
- * @default process.cwd()
12
+ * Git commit SHA.
13
13
  */
14
- root?: string;
14
+ commit: string;
15
15
  /**
16
- * Globs matching image file paths to ignore
17
- * @default ["**\/*.\{png,jpg,jpeg\}"]
16
+ * Git branch name of the build.
17
+ * @example "main", "develop", "release/1.0"
18
18
  */
19
- ignore?: string[];
19
+ branch: string;
20
20
  /**
21
- * Base URL of Argos API
22
- * @default "https://api.argos-ci.com/v2/"
21
+ * Argos repository access token.
23
22
  */
24
- apiBaseUrl?: string;
23
+ token: string | null;
25
24
  /**
26
- * Git commit
25
+ * Custom build name.
26
+ * Useful for multi-build setups on the same commit.
27
27
  */
28
- commit?: string;
28
+ buildName: string | null;
29
29
  /**
30
- * Git branch
30
+ * Whether this build is split across multiple parallel jobs.
31
+ * @default false
31
32
  */
32
- branch?: string;
33
+ parallel: boolean;
33
34
  /**
34
- * Argos repository token
35
+ * Unique identifier shared by all parallel jobs.
35
36
  */
36
- token?: string;
37
+ parallelNonce: string | null;
37
38
  /**
38
- * Pull-request number
39
+ * Index of the current parallel job.
40
+ * Must be between 1 and `parallelTotal`, or null if not set.
39
41
  */
40
- prNumber?: number;
42
+ parallelIndex: number | null;
41
43
  /**
42
- * Name of the build used to trigger multiple Argos builds on one commit
44
+ * Total number of parallel jobs.
45
+ * Use -1 if unknown, or null if not set.
43
46
  */
44
- buildName?: string;
47
+ parallelTotal: number | null;
45
48
  /**
46
- * Mode of comparison applied
47
- * @default "ci"
49
+ * Git branch used as the baseline for screenshot comparison.
48
50
  */
49
- mode?: "ci" | "monitoring";
51
+ referenceBranch: string | null;
50
52
  /**
51
- Parallel test suite mode
53
+ * Git commit SHA used as the baseline for screenshot comparison.
52
54
  */
53
- parallel?: {
54
- /** Unique build ID for this parallel build */
55
- nonce: string;
56
- /** The number of parallel nodes being ran */
57
- total: number;
58
- /** The index of the parallel node */
59
- index?: number;
60
- } | false;
55
+ referenceCommit: string | null;
61
56
  /**
62
- * Branch used as baseline for screenshot comparison
57
+ * Repository slug of the source repository.
58
+ * Example: "my-org/my-repo" or "my-user/my-repo".
59
+ * If from a fork, this refers to the fork repository.
63
60
  */
64
- referenceBranch?: string;
61
+ repository: string | null;
65
62
  /**
66
- * Commit used as baseline for screenshot comparison
63
+ * Repository slug of the original (base) repository.
64
+ * Example: "my-org/my-repo" or "my-user/my-repo".
65
+ * If from a fork, this refers to the base repository.
67
66
  */
68
- referenceCommit?: string;
67
+ originalRepository: string | null;
69
68
  /**
70
- * Sensitivity threshold between 0 and 1.
71
- * The higher the threshold, the less sensitive the diff will be.
72
- * @default 0.5
69
+ * CI job identifier (if provided by the CI environment).
73
70
  */
74
- threshold?: number;
71
+ jobId: string | null;
75
72
  /**
76
- * Build metadata.
73
+ * CI run identifier (if provided by the CI environment).
77
74
  */
78
- metadata?: BuildMetadata;
75
+ runId: string | null;
79
76
  /**
80
- * Preview URL configuration.
81
- * Accepts a base URL or a function that receives the URL and returns the preview URL.
77
+ * CI run attempt number (if provided by the CI environment).
82
78
  */
83
- previewUrl?: {
84
- baseUrl: string;
85
- } | ((url: string) => string);
79
+ runAttempt: number | null;
80
+ /**
81
+ * Pull request number associated with the build.
82
+ */
83
+ prNumber: number | null;
84
+ /**
85
+ * Pull request head commit SHA (if available).
86
+ */
87
+ prHeadCommit: string | null;
88
+ /**
89
+ * Pull request base branch (if available).
90
+ */
91
+ prBaseBranch: string | null;
92
+ /**
93
+ * Build mode to use.
94
+ * - "ci": Review visual changes introduced by a feature branch and prevent regressions.
95
+ * - "monitoring": Track visual changes outside the standard CI flow, either on a schedule or before a release.
96
+ * @see https://argos-ci.com/docs/build-modes
97
+ */
98
+ mode: "ci" | "monitoring" | null;
99
+ /**
100
+ * Name of the detected CI provider (if available).
101
+ * @example "github-actions", "gitlab-ci", "circleci"
102
+ */
103
+ ciProvider: string | null;
104
+ /**
105
+ * Diff sensitivity threshold between 0 and 1.
106
+ * Higher values make Argos less sensitive to differences.
107
+ */
108
+ threshold: number | null;
109
+ /**
110
+ * Base URL to use for preview links.
111
+ * @example "https://my-preview.example.com"
112
+ */
113
+ previewBaseUrl: string | null;
114
+ /**
115
+ * Skip this build.
116
+ * No screenshots are uploaded, and the commit status is marked as success.
117
+ */
118
+ skipped?: boolean;
86
119
  }
87
- /**
88
- * Upload screenshots to Argos.
89
- */
90
- declare function upload(params: UploadParameters): Promise<{
91
- build: {
92
- id: ArgosAPISchema.components["schemas"]["BuildId"];
93
- number: number;
94
- status: ("accepted" | "rejected") | ("no-changes" | "changes-detected") | ("expired" | "pending" | "progress" | "error" | "aborted");
95
- url: string;
96
- notification: {
97
- description: string;
98
- context: string;
99
- github: {
100
- state: "pending" | "success" | "error" | "failure";
101
- };
102
- gitlab: {
103
- state: "pending" | "running" | "success" | "failed" | "canceled";
104
- };
105
- } | null;
106
- };
107
- screenshots: {
108
- hash: string;
109
- optimizedPath: string;
110
- metadata: _argos_ci_util.ScreenshotMetadata | null;
111
- threshold: number | null;
112
- baseName: string | null;
113
- pwTrace: {
114
- path: string;
115
- hash: string;
116
- } | null;
117
- name: string;
118
- path: string;
119
- }[];
120
- }>;
120
+ declare function readConfig(options?: Partial<Config>): Promise<Config>;
121
+ declare function getConfigFromOptions({ parallel, ...options }: Omit<Partial<Config>, "parallel"> & {
122
+ parallel?: {
123
+ /** Unique build ID for this parallel build */
124
+ nonce: string;
125
+ /** The number of parallel nodes being ran */
126
+ total: number;
127
+ /** The index of the parallel node */
128
+ index?: number;
129
+ } | false | undefined;
130
+ }): Promise<Config>;
121
131
 
122
132
  interface components {
123
133
  schemas: {
@@ -136,6 +146,11 @@ interface components {
136
146
  name: string;
137
147
  baseName?: string | null;
138
148
  metadata?: {
149
+ /**
150
+ * @description Ignored. Can be set to get completions, validations and documentation in some editors.
151
+ * @example https://api.argos-ci.com/v2/screenshot-metadata.json
152
+ */
153
+ $schema?: string;
139
154
  /** @description The URL of the page that was screenshotted */
140
155
  url?: string | null;
141
156
  /** @description An URL to an accessible preview of the screenshot */
@@ -292,102 +307,118 @@ declare function finalize(params: FinalizeParameters): Promise<{
292
307
  builds: components["schemas"]["Build"][];
293
308
  }>;
294
309
 
295
- interface Config {
296
- /**
297
- * Argos API base URL (for self-hosted installations)
298
- */
299
- apiBaseUrl: string;
300
- /**
301
- * The commit SHA1 (40 characters)
302
- */
303
- commit: string;
304
- /**
305
- * The git branch name (e.g. "main", "master", "develop", "release/1.0" etc.)
306
- */
307
- branch: string;
308
- /**
309
- * The Argos repository token (40 characters)
310
- */
311
- token: string | null;
312
- /**
313
- * The name of the build (for multi-build setups)
314
- */
315
- buildName: string | null;
310
+ type BuildMetadata = ArgosAPISchema.components["schemas"]["BuildMetadata"];
311
+ interface UploadParameters {
316
312
  /**
317
- * Whether the current run is parallelized (split in multiple jobs) or not
313
+ * Globs that match image file paths to upload.
318
314
  */
319
- parallel: boolean;
315
+ files?: string[];
320
316
  /**
321
- * The parallelization nonce (identifier shared by all parallel jobs)
317
+ * Root directory used to resolve image paths.
318
+ * @default process.cwd()
322
319
  */
323
- parallelNonce: string | null;
320
+ root?: string;
324
321
  /**
325
- * The index of the current job (between 1 and parallelTotal inclusive, or null if not set)
322
+ * Globs that match image file paths to exclude from upload.
323
+ * @default ["**\/*.{png,jpg,jpeg}"]
326
324
  */
327
- parallelIndex: number | null;
325
+ ignore?: string[];
328
326
  /**
329
- * The total number of parallel jobs (or -1 if unknown, or null if not set)
327
+ * Base URL of the Argos API.
328
+ * @default "https://api.argos-ci.com/v2/"
330
329
  */
331
- parallelTotal: number | null;
330
+ apiBaseUrl?: string;
332
331
  /**
333
- * The reference git branch to compare against
332
+ * Git commit SHA of the build.
334
333
  */
335
- referenceBranch: string | null;
334
+ commit?: string;
336
335
  /**
337
- * The reference commit SHA1 to compare against
336
+ * Git branch name of the build.
338
337
  */
339
- referenceCommit: string | null;
338
+ branch?: string;
340
339
  /**
341
- * The git repository slug (e.g. "my-org/my-repo" or "my-user/my-repo")
342
- * If from a fork, this is the fork's repository.
340
+ * Argos repository access token.
343
341
  */
344
- repository: string | null;
342
+ token?: string;
345
343
  /**
346
- * The original git repository slug (e.g. "my-org/my-repo" or "my-user/my-repo")
347
- * If from a fork, this is the base repository.
344
+ * Pull request number associated with the build.
348
345
  */
349
- originalRepository: string | null;
346
+ prNumber?: number;
350
347
  /**
351
- * The CI job identifier (if available)
348
+ * Custom build name. Useful when triggering multiple Argos builds
349
+ * for the same commit.
352
350
  */
353
- jobId: string | null;
351
+ buildName?: string;
354
352
  /**
355
- * The CI run identifier (if available)
353
+ * Build mode to use.
354
+ * - "ci": Review the visual changes introduced by a feature branch and prevent regressions.
355
+ * - "monitoring": Track visual changes outside the standard CI flow, either on a schedule or before a release.
356
+ * @see https://argos-ci.com/docs/build-modes
357
+ * @default "ci"
356
358
  */
357
- runId: string | null;
359
+ mode?: "ci" | "monitoring";
358
360
  /**
359
- * The CI run attempt (if available)
361
+ * Parallel test suite configuration.
362
+ * @default false
360
363
  */
361
- runAttempt: number | null;
364
+ parallel?: {
365
+ /** Unique build identifier shared across parallel jobs. */
366
+ nonce: string;
367
+ /** Total number of parallel jobs, set to -1 to finalize manually. */
368
+ total: number;
369
+ /** Index of the current job (must start from 1). */
370
+ index?: number;
371
+ } | false;
362
372
  /**
363
- * The pull request number (if available)
373
+ * Branch used as the baseline for screenshot comparison.
364
374
  */
365
- prNumber: number | null;
375
+ referenceBranch?: string;
366
376
  /**
367
- * The pull request head commit SHA1 (if available)
377
+ * Commit SHA used as the baseline for screenshot comparison.
368
378
  */
369
- prHeadCommit: string | null;
379
+ referenceCommit?: string;
370
380
  /**
371
- * The pull request base branch (if available)
381
+ * Diff sensitivity threshold between 0 and 1.
382
+ * Higher values make Argos less sensitive to differences.
383
+ * @default 0.5
372
384
  */
373
- prBaseBranch: string | null;
385
+ threshold?: number;
374
386
  /**
375
- * The mode Argos is running in (ci or monitoring)
387
+ * Additional build metadata.
376
388
  */
377
- mode: "ci" | "monitoring" | null;
389
+ metadata?: BuildMetadata;
378
390
  /**
379
- * The CI provider name (if detected)
391
+ * Preview URL configuration.
392
+ * Can be a fixed base URL or a function to transform URLs dynamically.
380
393
  */
381
- ciProvider: string | null;
394
+ previewUrl?: {
395
+ baseUrl: string;
396
+ } | ((url: string) => string);
382
397
  /**
383
- * The threshold to use for this run (if any, between 0 and 1 inclusive, e.g. 0.1 for 10% or 0.0 for 0%)
398
+ * Mark this build as skipped.
399
+ * No screenshots are uploaded, and the commit status is marked as success.
384
400
  */
401
+ skipped?: boolean;
402
+ }
403
+ interface Screenshot {
404
+ hash: string;
405
+ optimizedPath: string;
406
+ metadata: ScreenshotMetadata | null;
385
407
  threshold: number | null;
386
- /**
387
- * The base URL to use for preview links (if any)
388
- */
389
- previewBaseUrl: string | null;
408
+ baseName: string | null;
409
+ pwTrace: {
410
+ path: string;
411
+ hash: string;
412
+ } | null;
413
+ name: string;
414
+ path: string;
390
415
  }
391
- declare function readConfig(options?: Partial<Config>): Promise<Config>;
416
+ /**
417
+ * Upload screenshots to Argos.
418
+ */
419
+ declare function upload(params: UploadParameters): Promise<{
420
+ build: ArgosAPISchema.components["schemas"]["Build"];
421
+ screenshots: Screenshot[];
422
+ }>;
392
423
 
393
- export { type Config, type FinalizeParameters, type UploadParameters, finalize, readConfig, upload };
424
+ export { type Config, type FinalizeParameters, type UploadParameters, finalize, getConfigFromOptions, readConfig, upload };
package/dist/index.js CHANGED
@@ -1,6 +1,3 @@
1
- // src/upload.ts
2
- import { createClient, throwAPIError } from "@argos-ci/api-client";
3
-
4
1
  // src/config.ts
5
2
  import convict from "convict";
6
3
 
@@ -344,6 +341,30 @@ function getPullRequestFromPayload(payload) {
344
341
  }
345
342
  return null;
346
343
  }
344
+ function getVercelDeploymentPayload(payload) {
345
+ if (!payload) {
346
+ return null;
347
+ }
348
+ if (process.env.GITHUB_EVENT_NAME !== "repository_dispatch") {
349
+ return null;
350
+ }
351
+ if (!("client_payload" in payload) || !("action" in payload)) {
352
+ return null;
353
+ }
354
+ if (payload.action !== "vercel.deployment.success") {
355
+ return null;
356
+ }
357
+ return payload;
358
+ }
359
+ function getSha(context, vercelPayload) {
360
+ if (vercelPayload) {
361
+ return vercelPayload.client_payload.git.sha;
362
+ }
363
+ if (!context.env.GITHUB_SHA) {
364
+ throw new Error(`GITHUB_SHA is missing`);
365
+ }
366
+ return context.env.GITHUB_SHA;
367
+ }
347
368
  var service4 = {
348
369
  name: "GitHub Actions",
349
370
  key: "github-actions",
@@ -351,10 +372,8 @@ var service4 = {
351
372
  config: async (context) => {
352
373
  const { env } = context;
353
374
  const payload = readEventPayload(context);
354
- const sha = process.env.GITHUB_SHA || null;
355
- if (!sha) {
356
- throw new Error(`GITHUB_SHA is missing`);
357
- }
375
+ const vercelPayload = getVercelDeploymentPayload(payload);
376
+ const sha = getSha(context, vercelPayload);
358
377
  const pullRequest = payload ? getPullRequestFromPayload(payload) : await getPullRequestFromHeadSha(context, sha);
359
378
  return {
360
379
  commit: sha,
@@ -364,7 +383,7 @@ var service4 = {
364
383
  runId: env.GITHUB_RUN_ID || null,
365
384
  runAttempt: env.GITHUB_RUN_ATTEMPT ? Number(env.GITHUB_RUN_ATTEMPT) : null,
366
385
  nonce: `${env.GITHUB_RUN_ID}-${env.GITHUB_RUN_ATTEMPT}`,
367
- branch: getBranchFromContext(context) || pullRequest?.head.ref || (payload ? getBranchFromPayload(payload) : null) || null,
386
+ branch: vercelPayload?.client_payload?.git?.ref || getBranchFromContext(context) || pullRequest?.head.ref || (payload ? getBranchFromPayload(payload) : null) || null,
368
387
  prNumber: pullRequest?.number || null,
369
388
  prHeadCommit: pullRequest?.head.sha ?? null,
370
389
  prBaseBranch: pullRequest?.base.ref ?? null
@@ -775,6 +794,11 @@ var schema = {
775
794
  format: String,
776
795
  default: null,
777
796
  nullable: true
797
+ },
798
+ skipped: {
799
+ env: "ARGOS_SKIPPED",
800
+ format: Boolean,
801
+ default: false
778
802
  }
779
803
  };
780
804
  function createConfig() {
@@ -815,7 +839,8 @@ async function readConfig(options = {}) {
815
839
  parallelIndex: options.parallelIndex ?? defaultConfig.parallelIndex ?? null,
816
840
  mode: options.mode || defaultConfig.mode || null,
817
841
  ciProvider: ciEnv?.key || null,
818
- previewBaseUrl: defaultConfig.previewBaseUrl || null
842
+ previewBaseUrl: defaultConfig.previewBaseUrl || null,
843
+ skipped: options.skipped ?? defaultConfig.skipped ?? false
819
844
  });
820
845
  if (!config.get("branch") || !config.get("commit")) {
821
846
  throw new Error(
@@ -825,6 +850,83 @@ async function readConfig(options = {}) {
825
850
  config.validate();
826
851
  return config.get();
827
852
  }
853
+ async function getConfigFromOptions({
854
+ parallel,
855
+ ...options
856
+ }) {
857
+ return readConfig({
858
+ ...options,
859
+ parallel: parallel !== void 0 ? Boolean(parallel) : void 0,
860
+ parallelNonce: parallel ? parallel.nonce : void 0,
861
+ parallelTotal: parallel ? parallel.total : void 0,
862
+ parallelIndex: parallel ? parallel.index : void 0
863
+ });
864
+ }
865
+
866
+ // src/finalize.ts
867
+ import { createClient, throwAPIError } from "@argos-ci/api-client";
868
+
869
+ // src/auth.ts
870
+ var base64Encode = (obj) => Buffer.from(JSON.stringify(obj), "utf8").toString("base64");
871
+ function getAuthToken(args) {
872
+ const {
873
+ token,
874
+ ciProvider,
875
+ originalRepository: repository,
876
+ jobId,
877
+ runId,
878
+ prNumber
879
+ } = args;
880
+ if (token) {
881
+ return token;
882
+ }
883
+ switch (ciProvider) {
884
+ case "github-actions": {
885
+ if (!repository || !jobId || !runId) {
886
+ throw new Error(
887
+ `Automatic GitHub Actions variables detection failed. Please add the 'ARGOS_TOKEN'`
888
+ );
889
+ }
890
+ const [owner, repo] = repository.split("/");
891
+ return `tokenless-github-${base64Encode({
892
+ owner,
893
+ repository: repo,
894
+ jobId,
895
+ runId,
896
+ prNumber: prNumber ?? void 0
897
+ })}`;
898
+ }
899
+ default:
900
+ throw new Error("Missing Argos repository token 'ARGOS_TOKEN'");
901
+ }
902
+ }
903
+
904
+ // src/finalize.ts
905
+ async function finalize(params) {
906
+ const config = await readConfig({
907
+ parallelNonce: params.parallel?.nonce
908
+ });
909
+ const authToken = getAuthToken(config);
910
+ const apiClient = createClient({
911
+ baseUrl: config.apiBaseUrl,
912
+ authToken
913
+ });
914
+ if (!config.parallelNonce) {
915
+ throw new Error("parallel.nonce is required to finalize the build");
916
+ }
917
+ const finalizeBuildsResult = await apiClient.POST("/builds/finalize", {
918
+ body: {
919
+ parallelNonce: config.parallelNonce
920
+ }
921
+ });
922
+ if (finalizeBuildsResult.error) {
923
+ throwAPIError(finalizeBuildsResult.error);
924
+ }
925
+ return finalizeBuildsResult.data;
926
+ }
927
+
928
+ // src/upload.ts
929
+ import { createClient as createClient2, throwAPIError as throwAPIError2 } from "@argos-ci/api-client";
828
930
 
829
931
  // src/discovery.ts
830
932
  import { resolve } from "path";
@@ -925,41 +1027,6 @@ var hashFile = async (filepath) => {
925
1027
  return hash.digest("hex");
926
1028
  };
927
1029
 
928
- // src/auth.ts
929
- var base64Encode = (obj) => Buffer.from(JSON.stringify(obj), "utf8").toString("base64");
930
- function getAuthToken(args) {
931
- const {
932
- token,
933
- ciProvider,
934
- originalRepository: repository,
935
- jobId,
936
- runId,
937
- prNumber
938
- } = args;
939
- if (token) {
940
- return token;
941
- }
942
- switch (ciProvider) {
943
- case "github-actions": {
944
- if (!repository || !jobId || !runId) {
945
- throw new Error(
946
- `Automatic GitHub Actions variables detection failed. Please add the 'ARGOS_TOKEN'`
947
- );
948
- }
949
- const [owner, repo] = repository.split("/");
950
- return `tokenless-github-${base64Encode({
951
- owner,
952
- repository: repo,
953
- jobId,
954
- runId,
955
- prNumber: prNumber ?? void 0
956
- })}`;
957
- }
958
- default:
959
- throw new Error("Missing Argos repository token 'ARGOS_TOKEN'");
960
- }
961
- }
962
-
963
1030
  // src/s3.ts
964
1031
  import { readFile } from "fs/promises";
965
1032
  async function uploadFile(input) {
@@ -992,7 +1059,10 @@ var chunk = (collection, size) => {
992
1059
  };
993
1060
 
994
1061
  // src/upload.ts
995
- import { getPlaywrightTracePath, readMetadata } from "@argos-ci/util";
1062
+ import {
1063
+ getPlaywrightTracePath,
1064
+ readMetadata
1065
+ } from "@argos-ci/util";
996
1066
 
997
1067
  // src/version.ts
998
1068
  import { readVersionFromPackage } from "@argos-ci/util";
@@ -1006,66 +1076,48 @@ async function getArgosCoreSDKIdentifier() {
1006
1076
 
1007
1077
  // src/upload.ts
1008
1078
  var CHUNK_SIZE = 10;
1009
- async function getConfigFromOptions({
1010
- parallel,
1011
- ...options
1012
- }) {
1013
- return readConfig({
1014
- ...options,
1015
- parallel: parallel !== void 0 ? Boolean(parallel) : void 0,
1016
- parallelNonce: parallel ? parallel.nonce : void 0,
1017
- parallelTotal: parallel ? parallel.total : void 0,
1018
- parallelIndex: parallel ? parallel.index : void 0
1019
- });
1020
- }
1021
- async function uploadFilesToS3(files) {
1022
- debug(`Split files in chunks of ${CHUNK_SIZE}`);
1023
- const chunks = chunk(files, CHUNK_SIZE);
1024
- debug(`Starting upload of ${chunks.length} chunks`);
1025
- for (let i = 0; i < chunks.length; i++) {
1026
- debug(`Uploading chunk ${i + 1}/${chunks.length}`);
1027
- const timeLabel = `Chunk ${i + 1}/${chunks.length}`;
1028
- debugTime(timeLabel);
1029
- const chunk2 = chunks[i];
1030
- if (!chunk2) {
1031
- throw new Error(`Invariant: chunk ${i} is empty`);
1032
- }
1033
- await Promise.all(
1034
- chunk2.map(async ({ url, path, contentType }) => {
1035
- await uploadFile({
1036
- url,
1037
- path,
1038
- contentType
1039
- });
1040
- })
1041
- );
1042
- debugTimeEnd(timeLabel);
1043
- }
1044
- }
1045
- function formatPreviewUrl(url, formatter) {
1046
- if (typeof formatter === "function") {
1047
- return formatter(url);
1048
- }
1049
- const urlObj = new URL(url);
1050
- return new URL(
1051
- urlObj.pathname + urlObj.search + urlObj.hash,
1052
- formatter.baseUrl
1053
- ).href;
1054
- }
1055
1079
  async function upload(params) {
1056
1080
  debug("Starting upload with params", params);
1057
1081
  const [config, argosSdk] = await Promise.all([
1058
1082
  getConfigFromOptions(params),
1059
1083
  getArgosCoreSDKIdentifier()
1060
1084
  ]);
1061
- const previewUrlFormatter = params.previewUrl ?? (config.previewBaseUrl ? { baseUrl: config.previewBaseUrl } : void 0);
1062
- const files = params.files ?? ["**/*.{png,jpg,jpeg}"];
1063
- debug("Using config and files", config, files);
1064
1085
  const authToken = getAuthToken(config);
1065
- const apiClient = createClient({
1086
+ const apiClient = createClient2({
1066
1087
  baseUrl: config.apiBaseUrl,
1067
1088
  authToken
1068
1089
  });
1090
+ if (config.skipped) {
1091
+ const createBuildResponse2 = await apiClient.POST("/builds", {
1092
+ body: {
1093
+ commit: config.commit,
1094
+ branch: config.branch,
1095
+ name: config.buildName,
1096
+ mode: config.mode,
1097
+ parallel: config.parallel,
1098
+ parallelNonce: config.parallelNonce,
1099
+ prNumber: config.prNumber,
1100
+ prHeadCommit: config.prHeadCommit,
1101
+ referenceBranch: config.referenceBranch,
1102
+ referenceCommit: config.referenceCommit,
1103
+ argosSdk,
1104
+ ciProvider: config.ciProvider,
1105
+ runId: config.runId,
1106
+ runAttempt: config.runAttempt,
1107
+ skipped: true,
1108
+ screenshotKeys: [],
1109
+ pwTraceKeys: [],
1110
+ parentCommits: []
1111
+ }
1112
+ });
1113
+ if (createBuildResponse2.error) {
1114
+ throwAPIError2(createBuildResponse2.error);
1115
+ }
1116
+ return { build: createBuildResponse2.data.build, screenshots: [] };
1117
+ }
1118
+ const previewUrlFormatter = params.previewUrl ?? (config.previewBaseUrl ? { baseUrl: config.previewBaseUrl } : void 0);
1119
+ const files = params.files ?? ["**/*.{png,jpg,jpeg}"];
1120
+ debug("Using config and files", config, files);
1069
1121
  const foundScreenshots = await discoverScreenshots(files, {
1070
1122
  root: params.root,
1071
1123
  ignore: params.ignore
@@ -1107,7 +1159,7 @@ async function upload(params) {
1107
1159
  debug("Fetch project");
1108
1160
  const projectResponse = await apiClient.GET("/project");
1109
1161
  if (projectResponse.error) {
1110
- throwAPIError(projectResponse.error);
1162
+ throwAPIError2(projectResponse.error);
1111
1163
  }
1112
1164
  debug("Project fetched", projectResponse.data);
1113
1165
  const { defaultBaseBranch, hasRemoteContentAccess } = projectResponse.data;
@@ -1178,7 +1230,7 @@ async function upload(params) {
1178
1230
  }
1179
1231
  });
1180
1232
  if (createBuildResponse.error) {
1181
- throwAPIError(createBuildResponse.error);
1233
+ throwAPIError2(createBuildResponse.error);
1182
1234
  }
1183
1235
  const result = createBuildResponse.data;
1184
1236
  debug("Got uploads url", result);
@@ -1232,37 +1284,47 @@ async function upload(params) {
1232
1284
  }
1233
1285
  });
1234
1286
  if (uploadBuildResponse.error) {
1235
- throwAPIError(uploadBuildResponse.error);
1287
+ throwAPIError2(uploadBuildResponse.error);
1236
1288
  }
1237
1289
  return { build: uploadBuildResponse.data.build, screenshots };
1238
1290
  }
1239
-
1240
- // src/finalize.ts
1241
- import { createClient as createClient2, throwAPIError as throwAPIError2 } from "@argos-ci/api-client";
1242
- async function finalize(params) {
1243
- const config = await readConfig({
1244
- parallelNonce: params.parallel?.nonce
1245
- });
1246
- const authToken = getAuthToken(config);
1247
- const apiClient = createClient2({
1248
- baseUrl: config.apiBaseUrl,
1249
- authToken
1250
- });
1251
- if (!config.parallelNonce) {
1252
- throw new Error("parallel.nonce is required to finalize the build");
1253
- }
1254
- const finalizeBuildsResult = await apiClient.POST("/builds/finalize", {
1255
- body: {
1256
- parallelNonce: config.parallelNonce
1291
+ async function uploadFilesToS3(files) {
1292
+ debug(`Split files in chunks of ${CHUNK_SIZE}`);
1293
+ const chunks = chunk(files, CHUNK_SIZE);
1294
+ debug(`Starting upload of ${chunks.length} chunks`);
1295
+ for (let i = 0; i < chunks.length; i++) {
1296
+ debug(`Uploading chunk ${i + 1}/${chunks.length}`);
1297
+ const timeLabel = `Chunk ${i + 1}/${chunks.length}`;
1298
+ debugTime(timeLabel);
1299
+ const chunk2 = chunks[i];
1300
+ if (!chunk2) {
1301
+ throw new Error(`Invariant: chunk ${i} is empty`);
1257
1302
  }
1258
- });
1259
- if (finalizeBuildsResult.error) {
1260
- throwAPIError2(finalizeBuildsResult.error);
1303
+ await Promise.all(
1304
+ chunk2.map(async ({ url, path, contentType }) => {
1305
+ await uploadFile({
1306
+ url,
1307
+ path,
1308
+ contentType
1309
+ });
1310
+ })
1311
+ );
1312
+ debugTimeEnd(timeLabel);
1261
1313
  }
1262
- return finalizeBuildsResult.data;
1314
+ }
1315
+ function formatPreviewUrl(url, formatter) {
1316
+ if (typeof formatter === "function") {
1317
+ return formatter(url);
1318
+ }
1319
+ const urlObj = new URL(url);
1320
+ return new URL(
1321
+ urlObj.pathname + urlObj.search + urlObj.hash,
1322
+ formatter.baseUrl
1323
+ ).href;
1263
1324
  }
1264
1325
  export {
1265
1326
  finalize,
1327
+ getConfigFromOptions,
1266
1328
  readConfig,
1267
1329
  upload
1268
1330
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@argos-ci/core",
3
3
  "description": "Node.js SDK for visual testing with Argos.",
4
- "version": "4.1.6",
4
+ "version": "4.2.1-alpha.4+d1894ac",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
7
7
  "exports": {
@@ -40,8 +40,8 @@
40
40
  "access": "public"
41
41
  },
42
42
  "dependencies": {
43
- "@argos-ci/api-client": "0.11.1",
44
- "@argos-ci/util": "3.1.0",
43
+ "@argos-ci/api-client": "0.12.1-alpha.4+d1894ac",
44
+ "@argos-ci/util": "3.1.2-alpha.4+d1894ac",
45
45
  "convict": "^6.2.4",
46
46
  "debug": "^4.4.3",
47
47
  "fast-glob": "^3.3.3",
@@ -53,6 +53,7 @@
53
53
  "@types/convict": "^6.1.6",
54
54
  "@types/debug": "^4.1.12",
55
55
  "@types/tmp": "^0.2.6",
56
+ "@vercel/repository-dispatch": "^0.1.0",
56
57
  "msw": "^2.11.3",
57
58
  "vitest": "catalog:"
58
59
  },
@@ -64,5 +65,5 @@
64
65
  "lint": "eslint .",
65
66
  "test": "vitest"
66
67
  },
67
- "gitHead": "00f28041a847158e437aaab5fc9e816f6b609021"
68
+ "gitHead": "d1894acc62fb886d4673c88cc7e8cc95e81db78b"
68
69
  }