pixellint

Fixtures in CI, not a weekly HAR

Short answer

The HTTP 200 from the vendor will not fail the build. A linter that knows timestamp units will. That is the point of Pixellint as a CLI.

Validate a pixel Open the rulepack

What to store

1. A golden Purchase body per ads vendor you actually POST to. 2. A golden pixel URL per browser tag. 3. The cases that must fail: unhashed email, hashed IP, 13-digit Meta event_time, 13-digit GA4 timestamp_micros, missing event name, empty PostHog distinct_id, Segment track with no event, Mixpanel array with no properties.token. 4. Template fixtures marked as template so macros are legal. 5. Example.com addresses and documented sample hashes. Never a live HAR.

One fixture per bug you already shipped is how the suite grows. A single happy-path Purchase will not catch the refund path that omits transaction_id.

Commands

Run the binary in CI like you run any other linter. The pixellint repository ships a composite GitHub Action: uses aleksUIX/pixellint at a v* tag, with path (a fixture file) and kind (url or json). cargo install pixellint and npm install pixellint are the same binary. Pin the tag. Do not float latest on a production worker.

pixellint validate url on fired or golden URLs. pixellint validate json on CAPI, MP, capture, and track bodies. --rulepack scopes the vendor. --state template is for unexpanded macros. Exit 0 when there is no error-severity finding. Warnings do not fail the process. Exit 1 when any error finding is present. Exit 2 is a usage problem. Same engine as the playground.

pixellint validate url @fixtures/meta-pixel.txt --rulepack vendor/meta
pixellint validate json @fixtures/meta-capi.json --rulepack vendor/meta-conversions-api
pixellint validate json @fixtures/ga4-mp.json --rulepack vendor/google-analytics
pixellint validate url @fixtures/g-collect.txt --rulepack vendor/google-analytics-collect

Pin the action, or call the binary

Any CI that can run a binary can run this. The composite action downloads the release tarball for the runner OS and architecture, then runs pixellint validate on the path you named. A Makefile or a bash step that calls the same binary is the same check. A step that only curls the vendor and asserts 200 is the incident the CLI exists to prevent.

Keep the commands next to the fixtures so a PR that changes the hasher shows a red job. Weekly HAR archaeology does not catch the merge that shipped Date.now() to Meta.

#!/bin/sh
set -e
pixellint validate url @fixtures/pixel.txt --rulepack vendor/meta
pixellint validate json @fixtures/capi.json --rulepack vendor/meta-conversions-api

PII in the repo

1. Fixtures use example.com and documented sample SHA-256 digests. 2. Never commit a live HAR from production. 3. Never commit access_token, api_secret, or writeKey that work. 4. Redact cookies. 5. Template fixtures may contain ${macro} or [CACHEBUSTER]; mark --state template so core privacy rules stay quiet on unfilled slots.

A golden body that still contains a real buyer email is a leak in git history. Rotate if it happened. See HAR files.

What CI will not catch

A GTM trigger that only fails on one locale. A published container that does not match the preview you stared at. A destination mapping that hashes the wrong field after Segment 200s. Pair fixtures with a sampled export and with a post-publish Network pass on a clean browser.

Pixellint is not affiliated with Meta or Google. The CLI checks the artifact you give it. It does not log into Ads Manager. That is a feature.

Check the artifact

Paste the pixel URL or JSON body into the playground. Same engine as pixellint validate. Artifacts you test may be stored; see privacy.