@argos-ci/core 2.4.1 → 2.4.2-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 (2) hide show
  1. package/dist/index.mjs +162 -72
  2. package/package.json +8 -7
package/dist/index.mjs CHANGED
@@ -1,3 +1,4 @@
1
+ import { createClient } from '@argos-ci/api-client';
1
2
  import convict from 'convict';
2
3
  import { execSync } from 'node:child_process';
3
4
  import { existsSync, readFileSync, createReadStream } from 'node:fs';
@@ -13,52 +14,27 @@ import { readFile } from 'node:fs/promises';
13
14
  import { readVersionFromPackage, readMetadata, getPlaywrightTracePath } from '@argos-ci/util';
14
15
  import { createRequire } from 'node:module';
15
16
 
16
- const getPrNumber$2 = ({ env })=>{
17
- return env.BITRISE_PULL_REQUEST ? Number(env.BITRISE_PULL_REQUEST) : null;
18
- };
19
- const service$7 = {
20
- name: "Bitrise",
21
- key: "bitrise",
22
- detect: ({ env })=>Boolean(env.BITRISE_IO),
23
- config: ({ env })=>{
24
- return {
25
- commit: env.BITRISE_GIT_COMMIT || null,
26
- branch: env.BITRISE_GIT_BRANCH || null,
27
- owner: env.BITRISEIO_GIT_REPOSITORY_OWNER || null,
28
- repository: env.BITRISEIO_GIT_REPOSITORY_SLUG || null,
29
- jobId: null,
30
- runId: null,
31
- runAttempt: null,
32
- prNumber: getPrNumber$2({
33
- env
34
- }),
35
- prHeadCommit: null,
36
- nonce: env.BITRISEIO_PIPELINE_ID || null
37
- };
38
- }
39
- };
40
-
41
17
  /**
42
18
  * Check if the current directory is a git repository.
43
- */ const checkIsGitRepository = ()=>{
19
+ */ function checkIsGitRepository() {
44
20
  try {
45
21
  return execSync("git rev-parse --is-inside-work-tree").toString().trim() === "true";
46
22
  } catch {
47
23
  return false;
48
24
  }
49
- };
25
+ }
50
26
  /**
51
27
  * Returns the head commit.
52
- */ const head = ()=>{
28
+ */ function head() {
53
29
  try {
54
30
  return execSync("git rev-parse HEAD").toString().trim();
55
31
  } catch {
56
32
  return null;
57
33
  }
58
- };
34
+ }
59
35
  /**
60
36
  * Returns the current branch.
61
- */ const branch = ()=>{
37
+ */ function branch() {
62
38
  try {
63
39
  const headRef = execSync("git rev-parse --abbrev-ref HEAD").toString().trim();
64
40
  if (headRef === "HEAD") {
@@ -68,6 +44,57 @@ const service$7 = {
68
44
  } catch {
69
45
  return null;
70
46
  }
47
+ }
48
+ function getMergeBaseCommitShaWithDepth(input) {
49
+ const head = input.head || `HEAD`;
50
+ try {
51
+ execSync(`git fetch origin ${head} --depth ${input.depth}`);
52
+ execSync(`git fetch origin ${input.base}:${input.base} --depth ${input.depth}`);
53
+ const mergeBase = execSync(`git merge-base ${head} ${input.base}`).toString().trim();
54
+ return mergeBase || null;
55
+ } catch {
56
+ return null;
57
+ }
58
+ }
59
+ function getMergeBaseCommitSha$1(input) {
60
+ let depth = 50;
61
+ while(depth < 1000){
62
+ const mergeBase = getMergeBaseCommitShaWithDepth({
63
+ ...input,
64
+ depth
65
+ });
66
+ if (mergeBase) {
67
+ return mergeBase;
68
+ }
69
+ depth += 50;
70
+ }
71
+ return null;
72
+ }
73
+
74
+ const getPrNumber$2 = ({ env })=>{
75
+ return env.BITRISE_PULL_REQUEST ? Number(env.BITRISE_PULL_REQUEST) : null;
76
+ };
77
+ const service$7 = {
78
+ name: "Bitrise",
79
+ key: "bitrise",
80
+ detect: ({ env })=>Boolean(env.BITRISE_IO),
81
+ config: ({ env })=>{
82
+ return {
83
+ commit: env.BITRISE_GIT_COMMIT || null,
84
+ branch: env.BITRISE_GIT_BRANCH || null,
85
+ owner: env.BITRISEIO_GIT_REPOSITORY_OWNER || null,
86
+ repository: env.BITRISEIO_GIT_REPOSITORY_SLUG || null,
87
+ jobId: null,
88
+ runId: null,
89
+ runAttempt: null,
90
+ prNumber: getPrNumber$2({
91
+ env
92
+ }),
93
+ prHeadCommit: null,
94
+ nonce: env.BITRISEIO_PIPELINE_ID || null
95
+ };
96
+ },
97
+ getMergeBaseCommitSha: getMergeBaseCommitSha$1
71
98
  };
72
99
 
73
100
  const service$6 = {
@@ -88,7 +115,8 @@ const service$6 = {
88
115
  prHeadCommit: null,
89
116
  nonce: env.BUILDKITE_BUILD_ID || null
90
117
  };
91
- }
118
+ },
119
+ getMergeBaseCommitSha: getMergeBaseCommitSha$1
92
120
  };
93
121
 
94
122
  const service$5 = {
@@ -106,7 +134,8 @@ const service$5 = {
106
134
  prNumber: null,
107
135
  prHeadCommit: null,
108
136
  nonce: env.HEROKU_TEST_RUN_ID || null
109
- })
137
+ }),
138
+ getMergeBaseCommitSha: getMergeBaseCommitSha$1
110
139
  };
111
140
 
112
141
  const KEY = "@argos-ci/core";
@@ -179,34 +208,37 @@ To disable this warning, add \`DISABLE_GITHUB_TOKEN_WARNING: true\` as environme
179
208
  return null;
180
209
  }
181
210
  }
182
- const getBranch = ({ env })=>{
211
+ function getBranch(context, eventPayload) {
212
+ if (eventPayload?.pull_request?.head.ref) {
213
+ return eventPayload.pull_request.head.ref;
214
+ }
215
+ const { env } = context;
183
216
  if (env.GITHUB_HEAD_REF) {
184
217
  return env.GITHUB_HEAD_REF;
185
218
  }
186
- const branchRegex = /refs\/heads\/(.*)/;
187
219
  if (!env.GITHUB_REF) {
188
220
  return null;
189
221
  }
222
+ const branchRegex = /refs\/heads\/(.*)/;
190
223
  const matches = branchRegex.exec(env.GITHUB_REF);
191
224
  return matches?.[1] ?? null;
192
- };
193
- const getRepository$1 = ({ env })=>{
225
+ }
226
+ function getRepository$1({ env }) {
194
227
  if (!env.GITHUB_REPOSITORY) return null;
195
228
  return env.GITHUB_REPOSITORY.split("/")[1] || null;
196
- };
197
- const readEventPayload = ({ env })=>{
229
+ }
230
+ function readEventPayload({ env }) {
198
231
  if (!env.GITHUB_EVENT_PATH) return null;
199
232
  if (!existsSync(env.GITHUB_EVENT_PATH)) return null;
200
233
  return JSON.parse(readFileSync(env.GITHUB_EVENT_PATH, "utf-8"));
201
- };
234
+ }
202
235
  const service$4 = {
203
236
  name: "GitHub Actions",
204
237
  key: "github-actions",
205
- detect: ({ env })=>Boolean(env.GITHUB_ACTIONS),
206
- config: async ({ env })=>{
207
- const payload = readEventPayload({
208
- env
209
- });
238
+ detect: (context)=>Boolean(context.env.GITHUB_ACTIONS),
239
+ config: async (context)=>{
240
+ const { env } = context;
241
+ const payload = readEventPayload(context);
210
242
  const sha = process.env.GITHUB_SHA || null;
211
243
  if (!sha) {
212
244
  throw new Error(`GITHUB_SHA is missing`);
@@ -214,9 +246,7 @@ const service$4 = {
214
246
  const commonConfig = {
215
247
  commit: sha,
216
248
  owner: env.GITHUB_REPOSITORY_OWNER || null,
217
- repository: getRepository$1({
218
- env
219
- }),
249
+ repository: getRepository$1(context),
220
250
  jobId: env.GITHUB_JOB || null,
221
251
  runId: env.GITHUB_RUN_ID || null,
222
252
  runAttempt: env.GITHUB_RUN_ATTEMPT ? Number(env.GITHUB_RUN_ATTEMPT) : null,
@@ -226,9 +256,7 @@ const service$4 = {
226
256
  if (payload?.deployment) {
227
257
  debug("Deployment event detected");
228
258
  // Try to find a relevant pull request for the sha
229
- const pullRequest = await getPullRequestFromHeadSha({
230
- env
231
- }, sha);
259
+ const pullRequest = await getPullRequestFromHeadSha(context, sha);
232
260
  return {
233
261
  ...commonConfig,
234
262
  // If no pull request is found, we fallback to the deployment environment as branch name
@@ -240,12 +268,20 @@ const service$4 = {
240
268
  }
241
269
  return {
242
270
  ...commonConfig,
243
- branch: payload?.pull_request?.head.ref || getBranch({
244
- env
245
- }) || null,
271
+ branch: payload?.pull_request?.head.ref || getBranch(context, payload) || null,
246
272
  prNumber: payload?.pull_request?.number || null,
247
273
  prHeadCommit: payload?.pull_request?.head.sha ?? null
248
274
  };
275
+ },
276
+ getMergeBaseCommitSha: (input, ctx)=>{
277
+ const payload = readEventPayload(ctx);
278
+ const branch = getBranch(ctx, payload);
279
+ // Unshallow the repository to get the merge base commit
280
+ execSync(`git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"`);
281
+ return getMergeBaseCommitSha$1({
282
+ base: input.base,
283
+ head: branch
284
+ });
249
285
  }
250
286
  };
251
287
 
@@ -276,7 +312,8 @@ const service$3 = {
276
312
  prHeadCommit: null,
277
313
  nonce: env.CIRCLE_WORKFLOW_ID || env.CIRCLE_BUILD_NUM || null
278
314
  };
279
- }
315
+ },
316
+ getMergeBaseCommitSha: getMergeBaseCommitSha$1
280
317
  };
281
318
 
282
319
  const getOwner = ({ env })=>{
@@ -309,7 +346,8 @@ const service$2 = {
309
346
  prHeadCommit: null,
310
347
  nonce: env.TRAVIS_BUILD_ID || null
311
348
  };
312
- }
349
+ },
350
+ getMergeBaseCommitSha: getMergeBaseCommitSha$1
313
351
  };
314
352
 
315
353
  const service$1 = {
@@ -329,7 +367,8 @@ const service$1 = {
329
367
  prHeadCommit: null,
330
368
  nonce: env.CI_PIPELINE_ID || null
331
369
  };
332
- }
370
+ },
371
+ getMergeBaseCommitSha: getMergeBaseCommitSha$1
333
372
  };
334
373
 
335
374
  const service = {
@@ -349,7 +388,8 @@ const service = {
349
388
  prHeadCommit: null,
350
389
  nonce: null
351
390
  };
352
- }
391
+ },
392
+ getMergeBaseCommitSha: getMergeBaseCommitSha$1
353
393
  };
354
394
 
355
395
  // List of services ordered by usage
@@ -364,18 +404,38 @@ const services = [
364
404
  service$7,
365
405
  service
366
406
  ];
367
- async function getCiEnvironment({ env = process.env } = {}) {
368
- const ctx = {
369
- env
407
+ /**
408
+ * Create the context for the CI service detection.
409
+ */ function createContext() {
410
+ return {
411
+ env: process.env
370
412
  };
371
- debug("Detecting CI environment", {
372
- env
373
- });
374
- const service = services.find((service)=>service.detect(ctx));
413
+ }
414
+ /**
415
+ * Get the CI service that is currently running.
416
+ */ function getCiService(context) {
417
+ return services.find((service)=>service.detect(context));
418
+ }
419
+ /**
420
+ * Get the merge base commit.
421
+ */ function getMergeBaseCommitSha(input) {
422
+ const context = createContext();
423
+ const service = getCiService(context);
424
+ if (!service) {
425
+ return null;
426
+ }
427
+ return service.getMergeBaseCommitSha(input, context);
428
+ }
429
+ /**
430
+ * Get the CI environment.
431
+ */ async function getCiEnvironment() {
432
+ const context = createContext();
433
+ debug("Detecting CI environment", context);
434
+ const service = getCiService(context);
375
435
  // Service matched
376
436
  if (service) {
377
437
  debug("Internal service matched", service.name);
378
- const variables = await service.config(ctx);
438
+ const variables = await service.config(context);
379
439
  const ciEnvironment = {
380
440
  name: service.name,
381
441
  key: service.key,
@@ -642,7 +702,7 @@ function getBearerToken({ token, ciProvider, owner, repository, jobId, runId, pr
642
702
  throw new Error("Missing Argos repository token 'ARGOS_TOKEN'");
643
703
  }
644
704
  }
645
- const createArgosApiClient = (options)=>{
705
+ const createArgosLegacyAPIClient = (options)=>{
646
706
  const axiosInstance = axios.create({
647
707
  baseURL: options.baseUrl,
648
708
  headers: {
@@ -771,9 +831,14 @@ async function uploadFilesToS3(files) {
771
831
  "**/*.{png,jpg,jpeg}"
772
832
  ];
773
833
  debug("Using config and files", config, files);
774
- const apiClient = createArgosApiClient({
834
+ const authToken = getBearerToken(config);
835
+ const apiClient = createClient({
836
+ baseUrl: config.apiBaseUrl,
837
+ authToken: authToken
838
+ });
839
+ const legacyApiClient = createArgosLegacyAPIClient({
775
840
  baseUrl: config.apiBaseUrl,
776
- bearerToken: getBearerToken(config)
841
+ bearerToken: authToken
777
842
  });
778
843
  // Collect screenshots
779
844
  const foundScreenshots = await discoverScreenshots(files, {
@@ -810,6 +875,31 @@ async function uploadFilesToS3(files) {
810
875
  } : null
811
876
  };
812
877
  }));
878
+ debug("Fetch project");
879
+ const { data: project, error } = await apiClient.GET("/project");
880
+ if (error) {
881
+ throw new Error(error.error);
882
+ }
883
+ const { defaultBaseBranch, hasRemoteContentAccess } = project;
884
+ const referenceBranch = config.referenceBranch || defaultBaseBranch;
885
+ const referenceCommit = (()=>{
886
+ if (config.referenceCommit) {
887
+ debug("Found reference commit in config", config.referenceCommit);
888
+ return config.referenceCommit;
889
+ }
890
+ if (hasRemoteContentAccess) {
891
+ return null;
892
+ }
893
+ const sha = getMergeBaseCommitSha({
894
+ base: referenceBranch
895
+ });
896
+ if (sha) {
897
+ debug("Found reference commit from git", sha);
898
+ } else {
899
+ debug("No reference commit found in git");
900
+ }
901
+ return sha;
902
+ })();
813
903
  // Create build
814
904
  debug("Creating build");
815
905
  const [pwTraceKeys, screenshotKeys] = screenshots.reduce(([pwTraceKeys, screenshotKeys], screenshot)=>{
@@ -827,7 +917,7 @@ async function uploadFilesToS3(files) {
827
917
  [],
828
918
  []
829
919
  ]);
830
- const result = await apiClient.createBuild({
920
+ const result = await legacyApiClient.createBuild({
831
921
  commit: config.commit,
832
922
  branch: config.branch,
833
923
  name: config.buildName,
@@ -838,8 +928,8 @@ async function uploadFilesToS3(files) {
838
928
  pwTraceKeys,
839
929
  prNumber: config.prNumber,
840
930
  prHeadCommit: config.prHeadCommit,
841
- referenceBranch: config.referenceBranch,
842
- referenceCommit: config.referenceCommit,
931
+ referenceBranch,
932
+ referenceCommit,
843
933
  argosSdk,
844
934
  ciProvider: config.ciProvider,
845
935
  runId: config.runId,
@@ -873,7 +963,7 @@ async function uploadFilesToS3(files) {
873
963
  await uploadFilesToS3(uploadFiles);
874
964
  // Update build
875
965
  debug("Updating build");
876
- await apiClient.updateBuild({
966
+ await legacyApiClient.updateBuild({
877
967
  buildId: result.build.id,
878
968
  screenshots: screenshots.map((screenshot)=>({
879
969
  key: screenshot.hash,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@argos-ci/core",
3
3
  "description": "Visual testing solution to avoid visual regression. The core component of Argos SDK that handles build creation.",
4
- "version": "2.4.1",
4
+ "version": "2.4.2-alpha.4+4b6e8a3",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
7
7
  "types": "./dist/index.d.ts",
@@ -40,24 +40,25 @@
40
40
  "access": "public"
41
41
  },
42
42
  "dependencies": {
43
- "@argos-ci/util": "2.1.0",
44
- "axios": "^1.6.8",
43
+ "@argos-ci/api-client": "0.1.1-alpha.32+4b6e8a3",
44
+ "@argos-ci/util": "2.1.1-alpha.12+4b6e8a3",
45
+ "axios": "^1.7.4",
45
46
  "convict": "^6.2.4",
46
- "debug": "^4.3.4",
47
+ "debug": "^4.3.6",
47
48
  "fast-glob": "^3.3.2",
48
- "sharp": "^0.33.3",
49
+ "sharp": "^0.33.5",
49
50
  "tmp": "^0.2.3"
50
51
  },
51
52
  "devDependencies": {
52
53
  "@types/convict": "^6.1.6",
53
54
  "@types/debug": "^4.1.12",
54
55
  "@types/tmp": "^0.2.6",
55
- "msw": "^2.2.13"
56
+ "msw": "^2.3.5"
56
57
  },
57
58
  "scripts": {
58
59
  "prebuild": "rm -rf dist",
59
60
  "build": "rollup -c",
60
61
  "e2e": "node ./e2e/upload.cjs && node ./e2e/upload.mjs"
61
62
  },
62
- "gitHead": "8fbd0bb85ba9df1e8ca39d46acfe9903264d0b51"
63
+ "gitHead": "4b6e8a36627d466e65859396ec6cfee717ba7c7b"
63
64
  }