Launch · engineers · PMs
Fixtures in CI, not a weekly HAR
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.
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. There is no invented GitHub Action to install. cargo install pixellint, npm install pixellint, or whatever your install path already is, then:
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. Warnings do not fail the process; fail the job on codes you care about if you need to. 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
A shell job, not a marketplace Action
Any CI that can run a binary can run this. Makefile, bash step, npm test. Do not wait on a pixellint/pixellint-action that does not exist in this project. 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. Nothing leaves the tab.