From 13edeccf5ad6a77aba420b62c7144c4a12867907 Mon Sep 17 00:00:00 2001 From: Alaeddin <15094821+BSalaeddin@users.noreply.github.com> Date: Sat, 25 Jul 2026 00:36:55 +0100 Subject: [PATCH 1/3] ci: enable core e2e jobs against snapvisor prod --- .github/workflows/ci.yml | 7 +------ packages/cli/e2e/analytics.test.ts | 3 ++- packages/cli/e2e/change.test.ts | 3 ++- packages/cli/e2e/review.test.ts | 3 ++- packages/cli/e2e/whoami.test.ts | 13 +++++++++---- packages/cli/src/lib/build-reference.test.ts | 12 ++++++++++++ packages/cli/src/lib/build-reference.ts | 3 ++- 7 files changed, 30 insertions(+), 14 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cd8288e1..2cff2d39 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -73,8 +73,6 @@ jobs: e2e-core: timeout-minutes: 5 - # TODO: re-enable once snapvisor prod has seeded e2e fixture data + a USER_ACCESS_TOKEN secret (upstream-account-bound suite) - if: false env: ARGOS_API_BASE_URL: https://api.snapvisor.io/v2/ strategy: @@ -99,13 +97,12 @@ jobs: env: ARGOS_TOKEN: ${{ secrets.ARGOS_TOKEN }} USER_ACCESS_TOKEN: ${{ secrets.USER_ACCESS_TOKEN }} + ARGOS_BUILD_NUMBER: "101" NODE_VERSION: ${{ matrix.node-version }} OS: ${{ matrix.os }} e2e-core-oidc: timeout-minutes: 5 - # TODO: re-enable once GitHub-Actions OIDC exchange is configured against snapvisor prod - if: false runs-on: ubuntu-latest permissions: @@ -130,8 +127,6 @@ jobs: e2e-core-tokenless: timeout-minutes: 5 - # TODO: re-enable once GitHub-Actions OIDC exchange is configured against snapvisor prod - if: false runs-on: ubuntu-latest steps: diff --git a/packages/cli/e2e/analytics.test.ts b/packages/cli/e2e/analytics.test.ts index 265d6a8f..ad397f72 100644 --- a/packages/cli/e2e/analytics.test.ts +++ b/packages/cli/e2e/analytics.test.ts @@ -41,8 +41,9 @@ beforeAll(() => { ARGOS_TOKEN: projectToken, }).stdout, ); + // Fork: accept snapvisor hosts alongside upstream argos hosts (upstream merge may re-break this). const match = build.url.match( - /app\.argos-ci\.(?:com|dev(?::\d+)?)\/([^/?#]+)\//, + /app\.(?:argos-ci\.(?:com|dev(?::\d+)?)|snapvisor\.io)\/([^/?#]+)\//, ); if (!match) { throw new Error(`Could not parse account from build URL: ${build.url}`); diff --git a/packages/cli/e2e/change.test.ts b/packages/cli/e2e/change.test.ts index 7bfc4fa1..456f5417 100644 --- a/packages/cli/e2e/change.test.ts +++ b/packages/cli/e2e/change.test.ts @@ -43,8 +43,9 @@ beforeAll(() => { ARGOS_TOKEN: projectToken, }).stdout, ); + // Fork: accept snapvisor hosts alongside upstream argos hosts (upstream merge may re-break this). const match = build.url.match( - /app\.argos-ci\.(?:com|dev(?::\d+)?)\/([^/?#]+)\/([^/?#]+)\/builds\//, + /app\.(?:argos-ci\.(?:com|dev(?::\d+)?)|snapvisor\.io)\/([^/?#]+)\/([^/?#]+)\/builds\//, ); if (!match) { throw new Error(`Could not parse project from build URL: ${build.url}`); diff --git a/packages/cli/e2e/review.test.ts b/packages/cli/e2e/review.test.ts index 5b728484..9a3a1eba 100644 --- a/packages/cli/e2e/review.test.ts +++ b/packages/cli/e2e/review.test.ts @@ -37,8 +37,9 @@ beforeAll(() => { run(["build", "get", buildNumber, "--json"], baseEnv).stdout, ); buildUrl = build.url; + // Fork: accept snapvisor hosts alongside upstream argos hosts (upstream merge may re-break this). const match = buildUrl.match( - /app\.argos-ci\.(?:com|dev(?::\d+)?)\/([^/?#]+)\/([^/?#]+)\/builds\//, + /app\.(?:argos-ci\.(?:com|dev(?::\d+)?)|snapvisor\.io)\/([^/?#]+)\/([^/?#]+)\/builds\//, ); if (!match) { throw new Error(`Could not parse project from build URL: ${buildUrl}`); diff --git a/packages/cli/e2e/whoami.test.ts b/packages/cli/e2e/whoami.test.ts index 0802e28c..03fbfae7 100644 --- a/packages/cli/e2e/whoami.test.ts +++ b/packages/cli/e2e/whoami.test.ts @@ -32,14 +32,19 @@ describe("argos whoami", () => { ["whoami", "--token", userAccessToken, "--json"], baseEnv, ); - const user = JSON.parse(output.stdout); - expect(user.id).toBeDefined(); - expect(user.slug).toBeDefined(); + // The /me payload is { user: { id, name, email }, accounts: [{ slug, ... }] } + // (api-client `Me` schema): the user id lives under `user`, and slug is an + // account-level field. Assert against that real shape. + const me = JSON.parse(output.stdout); + expect(me.user.id).toBeDefined(); + expect(me.accounts[0]?.slug).toBeDefined(); }); test("prints human-readable user data", () => { const output = run(["whoami", "--token", userAccessToken], baseEnv); + // `formatMe` prints identity + the account slugs on an "Accounts:" line + // (there is no per-user slug — slug is account-scoped). expect(output.stdout).toContain("Logged in to Argos as"); - expect(output.stdout).toContain("Slug:"); + expect(output.stdout).toContain("Accounts:"); }); }); diff --git a/packages/cli/src/lib/build-reference.test.ts b/packages/cli/src/lib/build-reference.test.ts index 04e0f024..457e4506 100644 --- a/packages/cli/src/lib/build-reference.test.ts +++ b/packages/cli/src/lib/build-reference.test.ts @@ -33,6 +33,18 @@ describe("parseBuildReference", () => { }); }); + it("parses a snapvisor production build URL", () => { + expect( + parseBuildReference( + "https://app.snapvisor.io/devino/snapvisor-js-e2e/builds/101", + ), + ).toEqual({ + owner: "devino", + project: "snapvisor-js-e2e", + buildNumber: 101, + }); + }); + it("parses a build URL with a trailing path, query, or hash", () => { expect( parseBuildReference( diff --git a/packages/cli/src/lib/build-reference.ts b/packages/cli/src/lib/build-reference.ts index 77916af8..c166d3c5 100644 --- a/packages/cli/src/lib/build-reference.ts +++ b/packages/cli/src/lib/build-reference.ts @@ -13,8 +13,9 @@ export type BuildReference = { // Anything after the build number — extra path segments (e.g. a diff id), a // query string, or a hash — is ignored, so deep links like // `.../builds/5014/347549006` resolve to build 5014. +// Fork: accept snapvisor hosts alongside upstream argos hosts (upstream merge may re-break this). const BUILD_URL_REGEXP = - /^https:\/\/app\.argos-ci\.(?:com|dev(?::\d+)?)\/(?[^/?#]+)\/(?[^/?#]+)\/builds\/(?\d+)(?:[/?#]|$)/; + /^https:\/\/app\.(?:argos-ci\.(?:com|dev(?::\d+)?)|snapvisor\.io)\/(?[^/?#]+)\/(?[^/?#]+)\/builds\/(?\d+)(?:[/?#]|$)/; /** * Parse a build reference, accepting either a bare build number (`"1234"`) or a From 04b19abb8cd9d93288bf1a316b657213a92490ad Mon Sep 17 00:00:00 2001 From: Alaeddin <15094821+BSalaeddin@users.noreply.github.com> Date: Sat, 25 Jul 2026 01:19:24 +0100 Subject: [PATCH 2/3] ci: cap e2e-core matrix concurrency to avoid prod API rate limit --- .github/workflows/ci.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2cff2d39..74dd3349 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -77,6 +77,9 @@ jobs: ARGOS_API_BASE_URL: https://api.snapvisor.io/v2/ strategy: fail-fast: false + # Cap concurrency: 9 simultaneous full-suite jobs share the prod API + # rate-limit budget (keyed per Cloudflare edge IP) and exhaust it (429s). + max-parallel: 3 matrix: node-version: [22, 24, 26] os: [ubuntu-latest, macos-latest, windows-latest] From 7f3ae51fa81e4330bb789405da27baf1b610c923 Mon Sep 17 00:00:00 2001 From: Alaeddin <15094821+BSalaeddin@users.noreply.github.com> Date: Sat, 25 Jul 2026 02:28:39 +0100 Subject: [PATCH 3/3] test(cli): skip deploy e2e - deployments product unprovisioned in snapvisor prod --- packages/cli/e2e/deploy.test.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/cli/e2e/deploy.test.ts b/packages/cli/e2e/deploy.test.ts index 9f1ca9ac..b82f9b86 100644 --- a/packages/cli/e2e/deploy.test.ts +++ b/packages/cli/e2e/deploy.test.ts @@ -4,7 +4,12 @@ import { getRequiredEnv, run } from "./utils"; getRequiredEnv("ARGOS_TOKEN"); -test("deploys a static site with HTML and CSS assets", () => { +// TODO(fork): re-enable when Snapvisor provisions the deployments product — +// prod has no DEPLOYMENTS_BUCKET_NAME (upstream default bucket doesn't exist on +// our B2) and no preview base domain/edge worker; `snapvisor deploy` against +// prod times out at the upload step (proven in PR #8 CI, 2026-07-25). +// eslint-disable-next-line vitest/no-disabled-tests +test.skip("deploys a static site with HTML and CSS assets", () => { const deployResult = run(["deploy", "../../__fixtures__/deploy"]); console.log(deployResult.stdout);