zip -r: Recursively Archive a Directory
zip -r walks a directory tree and adds every file it finds into the archive.
Packaging a build output folder is the most common reason CI calls zip. Without -r, zip stores only the named entries and skips the contents of directories.
What it does
zip -r recursively traverses the named directories and adds all files and subdirectories to the archive, recreating the relative paths inside the zip. Paths are stored relative to the current working directory unless you cd into the directory first.
Common usage
zip -r build.zip dist
# archive several inputs into one zip
zip -r release.zip dist config README.md
# store paths relative to dist by entering it first
cd dist && zip -r ../build.zip . && cd -Options
| Flag | What it does |
|---|---|
| -r | Recurse into directories |
| -r0 | Recurse but store without compression |
| <archive> | First non-flag argument is the output zip |
| <files...> | Inputs to add; directories need -r |
| -q | Quiet, suppress the per-file listing |
In CI
The path you pass becomes the path inside the zip. Running zip -r build.zip dist nests everything under a dist/ folder; cd into dist and zip . if you want the files at the archive root, which most extractors and deploy targets expect.
Common errors in CI
"zip: command not found" means the zip package is not preinstalled, which is common on slim container images and some self-hosted runners; install it (apt-get install -y zip on Debian/Ubuntu, apk add zip on Alpine). "zip warning: name not matched" means the input path does not exist relative to the current directory. Adding a directory without -r silently stores only the empty directory entry, producing an archive missing its contents.