Package a clean, secret-free, audit-ready zip of any git repository. Single
POSIX sh tool, no runtime dependencies, config-driven per-project extension
via .zipit.yaml, fail-closed secret scanning (filename and content),
delta/baseline builds.
curl -fsSL https://raw.githubusercontent.com/Tigon32/zipit/main/install.sh | sh
./zipit.sh --dry-run # see what would be included, build nothing
./zipit.sh # build <repo-basename>-<UTC-date>.zip into ~/Downloads11+ divergent packaging scripts existed across a set of projects, all
solving the same problem with drifted, inconsistent, and in places
advisory-only secret handling. zipit is the single canonical
implementation those scripts migrate to, with every project-specific
behavior expressed as .zipit.yaml config instead of bespoke shell logic.
See docs/adr/0001-canonical-zipit-tool.md for the full design rationale
and trade-offs.
zipit.sh [OPTIONS]
--dry-run / --report List included/excluded files, build nothing.
--key-files Show the effective must-be-present file set.
--with-data / --no-data Opt in/out of data_paths (default: excluded).
--output FILE Output zip path. Relative paths resolve under
~/Downloads by default ($ZIPIT_OUTPUT_DIR
overridable; an absolute path bypasses this).
--verify-only FILE Re-run cleanliness + key-file checks against
an existing zip.
--delta [--baseline FILE] Build only added/modified files since a
baseline manifest (auto-discovered if not given).
--validate-config Parse .zipit.yaml against the supported
subset; exit non-zero with a line number on
anything unsupported.
-h, --help
Per-project extension config. See .zipit.yaml.example for the full,
commented schema. Five list-valued extension keys, plus two scalars
(output_name, max_file_size_kb):
| Key | Purpose |
|---|---|
extra_exclude_patterns |
additional glob excludes |
extra_force_include_patterns |
re-include a path an exclude rule would otherwise drop (cannot override a hardcoded secret pattern) |
extra_key_files |
paths that must be present or the build fails |
extra_discovery_rules |
glob patterns that must match ≥1 included file or the build fails |
data_paths |
paths stripped by default, restorable via --with-data |
max_file_size_kb |
(scalar) exclude any file larger than this many KB, applied after pattern-based excludes/force-includes; unset = no cap |
Only a restricted YAML subset is supported (scalar strings and block
sequences of plain scalars — no nested maps, no flow-style lists). Run
zipit.sh --validate-config after any edit.
Every default build (not just --verify-only) runs two independent
cleanliness checks before writing a zip, and exits non-zero with no zip
written if either fails:
- Filename-based — no archive member path may match a hardcoded
secret-shaped glob (
.env,*.pem,.npmrc,.netrc,*.tfstate*, SSH keys, etc.). This list cannot be overridden by.zipit.yaml— a config attempting to force-include a matching path is rejected at startup. - Content-based — every included text file's contents are checked
against a set of secret-shaped regexes (AWS keys, JWTs, GitHub tokens,
sk--style API keys, generic_authToken=assignments). Binary files are skipped, not scanned.
Legitimate-looking secrets (including public CA certificates, e.g.
*.crt/*.pem) have no carve-out: SECRET_EXCLUDES is never
overridable by .zipit.yaml, by design, with no exceptions. A project
that genuinely needs to distribute a cert alongside its source should not
use this tool for that file.
- POSIX
sh(tested againstdashandbash --posix), macOS and Linux. - Requires:
git,zip/unzip,sha256sumorshasum -a 256, standard coreutils (find,grep,awk,sed). - Must be run inside a git repository — no non-git fallback mode.
scripts/smoke.sh— structural checks (plugin manifest, skill/command frontmatter, script executability and syntax validity).tests/run.sh— behavioral test suite against real fixture repos: default excludes, every.zipit.yamlextension key, fail-closed content-scan rejection, delta/baseline add/modify/delete classification, and--validate-configrejection of out-of-subset YAML.
Run both before trusting a change to zipit.sh:
./scripts/smoke.sh
./tests/run.shSee docs/adr/0001-canonical-zipit-tool.md for the full design record,
including the two independent adversarial reviews (safety-focused and
technical-design-focused) run against the implementation plan and their
finding-by-finding disposition.
Vendored per-project via install.sh (curl-install), not a package
manager dependency or git submodule — keeps each project's copy
self-contained and independently pinned. Re-running install.sh updates
zipit.sh in place without touching an existing .zipit.yaml.
MIT