How to filename sanitiser for build & release engineering
- Step 1Produce the release artefact — Build as usual and grab the packaged ZIP, tar.gz, or 7z from your CI artefact store. The Sanitiser takes one file at a time, so sanitise the final distributable, not the build tree.
- Step 2Drop it on the Sanitiser — Open Filename Sanitiser and drop the artefact. No options to set — the cross-platform rule set is fixed, which is what you want for a deterministic gate.
- Step 3Review the rename count — Check
Renamesin the result. In a healthy pipeline this should be 0; a non-zero count means the build introduced unsafe names — treat it as a packaging defect to fix at source, not just paper over. - Step 4Download the safe ZIP — Grab
<artefact-stem>-sanitized.zip. This is your cross-platform-safe distributable. The payload bytes are identical to the build output. - Step 5Verify checksums of contents — Extract and re-checksum the binaries — they must match the build output, since only names changed. This confirms code-signing and supply-chain hashes survive.
- Step 6Wire it into the release runbook — Add 'sanitise + assert zero renames' as a manual pre-publish step, or automate via the JAD runner (headless-browser; archive tools expose no REST API). Fix the root cause upstream when renames appear.
Release-name failures the Sanitiser fixes
Common cross-platform packaging problems in release artefacts and what the fixed rule set does to them.
| Release problem | Example entry | After sanitising | Risk if shipped |
|---|---|---|---|
| Colon in generated report | coverage:lcov.info | coverage_lcov.info | Windows extraction error |
| Glob char in bundle name | assets/*.min.js | assets/_.min.js | NTFS rejects the name |
| Vendored dep traversal | node_modules/../../x | node_modules/_/_/x | Zip Slip — writes outside install dir |
| Reserved device name | bin/aux | bin/_aux | Windows refuses to create the file |
| Pipe in a log artefact | build|win.log | build_win.log | Illegal on Windows |
| Backslash from a Win path leak | dir\sub\file | dir/sub/file | Inconsistent separators across OSes |
Tier limits for CI / release artefacts
Pick a tier by your largest release ZIP and its entry count. The entry-count cap is enforced separately from byte size.
| Tier | Max archive size | Max entries | Files per run |
|---|---|---|---|
| Free | 50 MB | 500 | 1 |
| Pro | 500 MB | 50,000 | 20 |
| Pro-media | 2 GB | 500,000 | 100 |
| Developer | 2 GB | 500,000 | unlimited |
Cookbook
Release-artefact entry names before and after the gate, drawn from typical cross-platform packaging slip-ups.
Linux-built report with a colon
Coverage and timestamped reports often embed : on Unix file systems. Shipped to a Windows user, the extractor errors. The gate fixes it to extract cleanly everywhere.
release.zip entries: reports/coverage:html/index.html reports/2026-06-13T10:30:run.log Sanitised: reports/coverage_html/index.html reports/2026-06-13T10_30_run.log Renames: 2
Transitive dependency traversal
A vendored package shipped a path that climbs out of the package root. Collapsing .. runs makes the artefact safe to extract anywhere.
Entry: vendor/pkg/../../../bootstrap Sanitised: vendor/pkg/_/_/_/bootstrap (cannot escape the extraction directory)
Generated file named like a device
A code generator emitted a module literally called aux. On Windows this is unwritable. The reserved-name prefix saves the release.
release.zip: src/generated/aux.ts src/generated/con.d.ts Sanitised: src/generated/_aux.ts src/generated/_con.d.ts
7z build output normalised to a Windows-friendly ZIP
Your build packs a 7z for size, but customers want a double-clickable ZIP. The Sanitiser reads the 7z and emits a clean ZIP in one step.
Input: app-1.4.0.7z (entries with | and * chars) Output: app-1.4.0-sanitized.zip -> all forbidden chars replaced with _ -> single ZIP, no 7-Zip needed on the customer's machine
Zero-rename happy path as a gate assertion
A clean artefact produces zero renames. Treat any non-zero result as a packaging regression to investigate, not silently accept.
Input: app-1.4.1.zip (well-formed) Result: Renames: 0 Entries: 412 Gate: PASS (no unsafe names introduced this build)
Edge cases and what actually happens
Release artefact exceeds 50 MB on free tier
413 rejectedMost real release ZIPs blow past 50 MB. Use Pro (500 MB / 50,000 entries) or Pro-media/Developer (2 GB / 500,000) for production artefacts. The entry-count cap also matters for monorepo bundles.
Artefact has hundreds of thousands of entries
Entry limit rejectedA bundled node_modules can exceed 500,000 entries. Even Developer caps there; prune or split (e.g. exclude dev deps) before sanitising. The entry cap is independent of size.
Output is always ZIP
By designIf your distribution channel requires the original tar.gz or 7z, sanitise here then re-pack/convert with archive-format-converter. The Sanitiser only emits ZIP.
Two artefact paths collide after sanitising
Last write winsIf a:b and a*b both become a_b, the later entry overwrites the earlier. For releases this is a real risk — assert that Entries out equals entries in when collisions would corrupt the build.
Code-signing manifest references the old name
Manual fixupRenaming an entry doesn't update references inside other files (e.g. a manifest or a signature that lists report:final.html). If a manifest points at a renamed entry, update it after sanitising — file contents are not rewritten.
Encrypted release ZIP
Read errorIf your pipeline encrypts artefacts, the Sanitiser can't read them (no password input). Sanitise before encrypting, or decrypt first. To produce an encrypted distributable afterwards, use encrypted-zip-creator.
COM5+/LPT3+ device names slip through
Known gapThe reserved set is CON/PRN/AUX/NUL/COM1–4/LPT1–2. A generated file named com9 would not be prefixed and would fail on Windows. Rare, but worth a lint rule upstream if you generate device-like names.
WASM blocked on a locked-down CI runner browser
WASM error7z/RAR/bz2/xz inputs need libarchive WASM. If your automation browser blocks WebAssembly, feed it ZIP/GZIP/TAR (pure-JS fflate) instead, or unpack the exotic format first.
You only need to drop a top-level build folder
Wrong toolStripping a leading dist/ prefix is path-prefix-remover's job; removing empty dirs is empty-folder-pruner. The Sanitiser fixes unsafe characters, not structure.
Frequently asked questions
Why sanitise release artefacts if CI passed?
CI runs on the build OS, where Linux/macOS names are legal. The failure surfaces only when a customer on Windows extracts the artefact — by then it's a support ticket. Sanitising is a cheap pre-ship gate that catches it on your side.
Does sanitising change my binaries or break code signing?
No. Only entry names are rewritten; file contents are byte-identical. SHA-256 checksums and signatures of the extracted files are unchanged. The only caveat is a manifest that references an entry by its old name.
Can I assert zero renames in my release runbook?
Yes — that's the intended gate. A clean artefact reports Renames: 0. Any non-zero value means the build introduced an unsafe name; treat it as a packaging regression and fix it upstream.
It outputs ZIP, but we ship tar.gz — now what?
Sanitise here to get safe names, then convert the result with archive-format-converter or repack with folder-to-zip. The Sanitiser's writer only produces ZIP.
How big a release ZIP can it handle?
Free 50 MB / 500 entries; Pro 500 MB / 50,000; Pro-media and Developer 2 GB / 500,000. Production artefacts usually need Pro or higher. The entry-count cap is separate from byte size.
Can I automate this in the release pipeline?
Archive tools have no REST API — automation runs through the JAD runner in a short-lived headless-browser session. For a fully scripted gate without a UI, a local equivalent script reproducing the rule set is also an option.
Will it fix traversal that a malicious or buggy dependency added?
Yes for the path part: every .. run collapses to _, so the entry can't write outside the extraction directory. It does not scan file contents — it only makes names safe.
Does it handle 7z release outputs?
Yes — it reads 7z (and RAR, bzip2, xz) via libarchive WASM and emits a safe ZIP, so customers don't need 7-Zip installed just to unpack a fixed-name artefact.
What about reserved device names like CON or AUX in generated code?
It prefixes CON, PRN, AUX, NUL, COM1–4, LPT1–2 with _ so they extract on Windows. Higher-numbered devices (COM5+, LPT3+) aren't covered, so add an upstream lint if your generators can emit those.
Can two entries collide and one get lost?
Yes — if two distinct names sanitise to the same safe form, the later one overwrites the earlier in the output. For a release artefact this is worth guarding against by comparing entry counts in and out.
Is the file uploaded to JAD servers?
No. Sanitising runs entirely in the browser. Unreleased artefacts never reach a third-party server — only an anonymous processed-file counter is recorded for signed-in dashboards.
What sibling tools pair well in a release flow?
Confirm soundness with archive-integrity-tester, generate release hashes with checksum-generator, and tidy structure with path-prefix-remover — then sanitise as the final cross-platform gate.
Privacy first
Every JAD Archive tool runs entirely in your browser using fflate, @zip.js/zip.js, and the libarchive WASM bridge. Your archives never leave your device — verified by zero outbound network requests during processing.