Skip to content

Feat/per 7809 disk logs minimal#2209

Draft
pranavz28 wants to merge 4 commits intofeat/per-7795-max-cache-ramfrom
feat/per-7809-disk-logs-minimal
Draft

Feat/per 7809 disk logs minimal#2209
pranavz28 wants to merge 4 commits intofeat/per-7795-max-cache-ramfrom
feat/per-7809-disk-logs-minimal

Conversation

@pranavz28
Copy link
Copy Markdown
Contributor

No description provided.

shantanuk-browserstack and others added 4 commits April 22, 2026 10:22
…013) (#2204)

The runtime config schema accepted `pseudoClassEnabledElements`, but the
TypeScript definition in @percy/core did not include it, forcing TS users
to suppress type errors when passing the option to percySnapshot. Adding
it to CommonSnapshotOptions fixes the type for every SDK that imports
SnapshotOptions from @percy/core (ember, puppeteer, playwright, selenium,
webdriverio, etc.).

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(env): auto-detect 10 additional CI providers (PER-7828)

Add detection plus commit/branch/PR/parallel-nonce extraction for:
TeamCity, AWS CodeBuild, Google Cloud Build, Atlassian Bamboo, Bitrise,
Codemagic, Vercel, Cloudflare Pages, GoCD, Woodpecker.

Detection ordering:
- Woodpecker placed before Drone (guards against pre-3.x Woodpecker
  installs that set DRONE=true for backwards compatibility).
- GCB placed last before the CI/unknown fallback because BUILD_ID +
  PROJECT_ID is the most generic marker; defensive !JENKINS_URL guard
  added.

Parallel-nonce rerun-stability choices:
- Bamboo uses bamboo_buildResultKey (includes build-N suffix) rather
  than bamboo_buildNumber (reused on rerun).
- Cloudflare Pages uses a composite \${commit}-\${url} nonce with a
  strict null-guard on commit SHA so we never emit "undefined".
- GoCD uses a composite \${pipeline}.\${stage} counter so stage reruns
  do not collide.

Each provider gets a dedicated test file covering detection, PR builds
(where applicable), edge cases (CodeBuild manual triggers, GCB manual
submits, Vercel system-env-vars-off, Woodpecker Drone-compat collision,
Jenkins-over-GCB precedence), and PERCY_* override precedence.

API side is a no-op: the 'source' field is free-form metadata with no
allowlist.

Tekton/Argo excluded — no standard git env vars.
Documentation for the 10 new providers (plus doc gaps for Harness,
Heroku CI, Probo.CI) ships in a follow-up PR.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(env): fix CF Pages nonce + add Tekton/Argo detection

E2E testing revealed the Cloudflare Pages composite nonce
(CF_PAGES_COMMIT_SHA-CF_PAGES_URL) exceeded Percy's 64-char
API limit, causing build creation to fail. Switched to
CF_PAGES_COMMIT_SHA alone — this also gives correct rerun
dedup behavior since the URL changes per redeploy.

Added opt-in detection for Tekton Pipelines and Argo Workflows.
Neither auto-injects identifying env vars into step containers,
so users set them via template substitution:

  # Tekton
  env:
    - name: TEKTON_PIPELINE_RUN
      value: "$(context.pipelineRun.name)"
    - name: TEKTON_COMMIT_SHA
      value: "$(params.commit-sha)"
    - name: TEKTON_BRANCH
      value: "$(params.branch)"

  # Argo Workflows
  env:
    - name: ARGO_WORKFLOW_NAME
      value: "{{workflow.name}}"
    - name: ARGO_WORKFLOW_UID
      value: "{{workflow.uid}}"
    - name: ARGO_COMMIT_SHA
      value: "{{workflow.parameters.commit-sha}}"
    - name: ARGO_BRANCH
      value: "{{workflow.parameters.branch}}"

🤖 Generated with Claude Opus 4.7 (1M context) via Claude Code
  + Compound Engineering v2.50.0

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(env): list all 12 new CI providers + opt-in setup

Adds README entries for the 10 auto-detect providers (TeamCity, AWS
CodeBuild, GCB, Bamboo, Bitrise, Codemagic, Vercel, Cloudflare Pages,
GoCD, Woodpecker), backfills Harness CI (was detected in code but
missing from the list), and documents the opt-in setup for Tekton
Pipelines and Argo Workflows with copy-paste YAML snippets.

Also calls out the Vercel System Env Vars + PERCY_PARALLEL_TOTAL=-1
requirement surfaced during E2E testing.

🤖 Generated with Claude Opus 4.7 (1M context) via Claude Code
  + Compound Engineering v2.50.0

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replaces @percy/logger's unbounded `messages` Set with a JSONL-backed
hybrid store that keeps resident memory bounded across long builds
(10k snapshots, 8-hour deferUploads runs) while preserving byte-for-byte
parity with master's `/logs` upload payload and per-snapshot log resources.

Design
------
- writes go through a 500-entry / 100ms buffer flushed via
  fs.appendFileSync to ${tmpdir}/percy-logs/<pid>/<ts>-<rand>.jsonl
- snapshotLogs(meta) reads the disk delta into a bounded `cache` keyed by
  snapshot meta; evictSnapshot drops the cache entry once the snapshot's
  upload is complete; late entries are allowed to repopulate (retry-safe)
- query(filter) streams the JSONL once per call (chunked 64KB read);
  in-memory mode preserves master's identity-mutation contract that
  redactSecrets relies on
- disk-init failures, mid-build appendFileSync failures, and the
  PERCY_LOGS_IN_MEMORY=1 rollback all flip to an unbounded in-memory Set
  (master parity) — including replaying entries already on disk so the
  upload still includes them
- circular meta is sanitized via JSON.stringify try/catch, but
  meta.snapshot is preserved so the entry still routes via snapshotLogs
- exit cleanup uses a process-scoped Set on `process[Symbol.for(...)]`
  shared across module copies; supports multiple live instances and
  unlinks every active disk file on `exit` / `beforeExit`
- per-pid subdir prevents concurrent percy processes (CI matrix, parallel
  workers, npx invocations) from clobbering each other's files; cleanup
  best-effort rmdirs the subdir so long-lived runners don't accumulate

Wiring
------
- packages/core/src/discovery.js — uses snapshotLogs/evictSnapshot for
  per-snapshot log resources
- packages/core/src/api.js — /test/logs and the test-mode reset path now
  use logger.query() / logger.instance.reset()
- packages/core/test/helpers/index.js — defaults setupTest to memory mode
  (master parity) so downstream tests using mockfs don't flake against
  the disk path's live volume

Tests
-----
- 68 specs, 100% statements/branches/functions/lines on logger.js
- the existing 37-case logger suite runs under the disk path by default
  (no PERCY_LOGS_IN_MEMORY set in helpers.mock); 25+ new specs in
  describe('disk-backed storage') cover round-trip, snapshotLogs / evict
  retry semantics, fallback after appendFileSync / mkdirSync failures,
  the 100ms timer, the 500-entry size cap, per-pid subdir, the
  Symbol.for latch, multi-instance cleanup, rmdir best-effort, and
  circular-meta snapshot preservation
- cli-exec / cli-snapshot / cli-build / cli-doctor / cli-upload /
  cli-command / cli / core / config / client / env / monitoring /
  webdriver-utils all green locally on Node 14

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
An error occurred while trying to automatically change base from feat/per-7795-max-cache-ram to master May 6, 2026 08:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants