With the dart pub tool, what does `dart pub publish --dry-run` check, and how do you control which files the upload contains?
answer
- validate without uploading
- pubspec and layout conventions
- the printed file list
- .pubignore overrides .gitignore
- errors block, warnings prompt
basics
~20 sdart pub publish --dry-run runs the client-side publishing checks - pubspec, layout, LICENSE, dependencies, analyzer diagnostics, likely secrets - and prints every file it would upload, without uploading. Hidden files and anything matched by .gitignore or .pubignore stay out.
solid answer
~40 s`--dry-run` (`-n`) goes through the same validation as a real publish and stops before the upload. It checks the pubspec format and package layout conventions, needs a `LICENSE` file and a working resolution with only hosted and SDK dependencies, and warns when `dart analyze` reports diagnostics, when `CHANGELOG.md` doesn't mention the current version, or when a file looks like a leaked secret; it also shows the sizes of large files. Then it lists the upload: every file under the package root except hidden ones and those matched by `.gitignore` or `.pubignore` - where a directory has both, `.pubignore` wins and that `.gitignore` is ignored. Errors stop a publish; warnings don't, but they make the dry run exit non-zero unless you add `--ignore-warnings` (Dart 3.11+).
code
bash · 10 linescd colour_tools
# Validate and list the files that would be uploaded; nothing is published.
dart pub publish --dry-run
# Same check, but exit non-zero only for errors (Dart 3.11+).
dart pub publish --dry-run --ignore-warnings
# The real upload: validates again, shows the file list, asks to confirm.
dart pub publishgo deeper
Recall that --dry-run validates and lists files without uploading, and that hidden and ignored files are left out of the package.
Explain the individual checks - LICENSE, hosted-only dependencies, analyzer diagnostics, CHANGELOG entry, secret scanning - and the .pubignore rule that replaces .gitignore per directory.
Build it into the release routine: fail CI on dry-run errors, review warnings by hand, never publish with --force unreviewed, and read the file list for leaked config.
Weigh what automation may decide: a dry run can gate a release, but an irreversible upload still deserves a human look at warnings and the file list.
## What a dry run is `dart pub publish` uploads a new version of a package to pub.dev (or to the repository named by `publish_to`). Because a published version is effectively permanent, the command has a rehearsal mode: **`dart pub publish --dry-run`**, short form `-n`. It performs the client-side validation a real publish would, prints what it would upload, reports a count of warnings, and then stops. Nothing leaves your machine. ## The checks it runs The validation grew over many SDK releases; in Dart 3.13 the notable checks are: 1. **Pubspec format and package layout** - required fields such as `name`, `version`, `description` and `environment`, likely typos in pubspec keys, and the conventional directory layout. 2. **A `LICENSE` file** - pub.dev requires one; dart.dev recommends the BSD 3-clause licence but any appropriate licence works. 3. **Dependencies** - the package must resolve, and it may depend only on hosted packages from the default repository and SDK dependencies such as `sdk: flutter`; `git` and `path` sources are not allowed in a published package. 4. **Static analysis** - since Dart 2.19 publishing warns if `dart analyze` reports diagnostics. 5. **`CHANGELOG.md`** - pub complains if the changelog does not mention the version being published. 6. **Potential secrets** - since Dart 2.15 pub scans files for likely leaked keys; a genuine false positive is listed under `false_secrets` in `pubspec.yaml`. 7. **Size** - pub shows the sizes of large files, and dart.dev recommends staying under 100 MB gzipped and 256 MB uncompressed. A real `dart pub publish` also warns, since Dart 3.6, when files tracked in git have uncommitted changes, then shows the file list and asks for confirmation before uploading. ## Which files are published The upload is **every file under the package root**, minus two groups: - **Hidden files and directories** - anything whose name starts with a dot. - **Ignored paths** - anything matched by a `.gitignore` or a `.pubignore` file. The two ignore files interact in one specific way: | Ignore files in a directory | Rules pub applies there | |---|---| | only `.gitignore` | the `.gitignore` rules | | only `.pubignore` | the `.pubignore` rules | | both | only `.pubignore`; the `.gitignore` in that directory is ignored | `.pubignore` uses the same pattern format as `.gitignore`. The usual reason to add one is to publish something git ignores, or to exclude something git tracks - but because it *replaces* the local `.gitignore`, any exclusions you still want must be repeated in it. Most packages never need a `.pubignore`. Whatever you use, **read the file list** the dry run prints and cancel if anything unexpected appears, such as local config, large fixtures or build output. ## Errors, warnings and exit codes | Invocation | Behaviour | |---|---| | `dart pub publish --dry-run` | validates and lists files; exits non-zero on errors **and** on warnings | | `dart pub publish --dry-run --ignore-warnings` | same, but exits non-zero **only** on errors (Dart 3.11+) | | `dart pub publish` | validates, lists files, asks for confirmation, uploads | | `dart pub publish --force` | no confirmation prompt; errors still block, but a package with only warnings **is** uploaded | | `dart pub publish --skip-validation` | skips client-side validation and dependency resolution entirely | `--skip-validation` exists for advanced cases, such as publishing two interdependent packages back to back before the first is visible on pub.dev. It is not a way to silence a warning you have not read. ## Using it in a release routine For an open-source `colour_tools` package, a sensible order is: 1. Bump the version and add a `CHANGELOG.md` entry for it. 2. Run `dart pub publish --dry-run` and fix every error; read each warning and either fix it or accept it deliberately. 3. Inspect the file list. 4. Run `dart pub publish` without `--force`, so the confirmation prompt is a last look. ```text # .pubignore in the package root (replaces .gitignore rules here) build/ .dart_tool/ tool/benchmarks/fixtures/ ``` ## Summary - A dry run is the full client-side check without the upload. - Hidden files and ignored paths are left out; `.pubignore` overrides `.gitignore` per directory. - Errors always block; warnings block only a dry run's exit code, unless `--ignore-warnings` is given.
- You add a `.pubignore` next to the package's `.gitignore`. What happens to the `.gitignore` rules?In that directory pub stops reading `.gitignore` and applies only `.pubignore`, which uses the same pattern format. Any exclusions you still want - `build/`, local config, large fixtures - must be copied into `.pubignore`, or they will be uploaded. Always check the dry run's file list after adding one.
- What does `--force` change, and why is it risky without a dry run first?`--force` (`-f`) skips the confirmation prompt. Errors still stop the upload, but a package that has only warnings is published with them. Since versions are effectively permanent, a warning about a likely secret or an oversized file becomes a public problem, so run `--dry-run` first or drop `--force`.
- A dry run warns that a test fixture looks like a secret. How do you handle it?Confirm it really is fake, then list its path under `false_secrets` in `pubspec.yaml` so pub's leak detection skips it. If it is a real credential, remove it from the package and rotate it; whitelisting a real key only publishes it.
saying these in an interview costs you the question
- A dry run only checks YAML syntax; the real validation happens on pub.dev
- .gitignore rules still apply in a directory that also has a .pubignore
- Hidden files such as .env are uploaded unless you list them somewhere
- --force publishes a package even when validation reports errors
- A package can depend on a git or path package once it is on pub.dev