Skip to content

feat(resolver): Stabilize min-publish-age - #17335

Open
epage wants to merge 1 commit into
rust-lang:masterfrom
epage:min-publish-age
Open

feat(resolver): Stabilize min-publish-age#17335
epage wants to merge 1 commit into
rust-lang:masterfrom
epage:min-publish-age

Conversation

@epage

@epage epage commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

What does this PR try to resolve?

To ensure dependencies have had a chance to be scanned, a user can set:

[registry]
global-min-publish-age = "7 days"

To force a critical update through, a user can

$ CARGO_RESOLVER_INCOMPATIBLE_PUBLISH_AGE=allow cargo update -p foo

That will be preserved within the lockfile.

To ensure users can observe what is going on and address concerns,

  • Locking messages notify of:
    • That min-publish-age is in use and what the age is if there is a single one
    • a newer, unpicked version is available and its age
    • a version is being used that is incompatible with min-publish-age (either through allow or an unchange dep shown through -v)
  • Error messages notify of:
    • a newer, unpicked version is available and its age
    • a compatible version requirement to downgrade to
    • how to use CARGO_RESOLVER_INCOMPATIBLE_PUBLISH_AGE

Fixes #17009

How to test and review this PR?

Items from the tracking issue:

  • deny precedence between this and incompatible-rust-version: we can always adjust this over time
  • the registry.min-publish-age / registries.*.min-publish-age precedence rule: mimics credential providers
  • cargo install behavior
    • there was some confusion over what was being stabilized due to edits that happened during the FCP that weren't noticed
    • resolver is defined as not affecting cargo install which this preserves, just like incompatible-rust-version
  • cargo update --breaking: this feature is being stabilized first and the other is being considered for removal (fix(update)!: Remove unstable --breaking #17333)

To ensure dependencies have had a chance to be scanned, a user can set:
```toml
[registry]
global-min-publish-age = "7 days"
```
To force a critical update through, a user can
```console
$ CARGO_RESOLVER_INCOMPATIBLE_PUBLISH_AGE=allow cargo update -p foo
```
That will be preserved within the lockfile.

To ensure users can observe what is going on and address concerns,
- Locking messages notify of:
  - That min-publish-age is in use and what the age is if there is a
    single one
  - a newer, unpicked version is available and its age
  - a version is being used that is incompatible with min-publish-age
    (either through `allow` or an unchange dep shown through `-v`)
- Error messages notify of:
  - a newer, unpicked version is available and its age
  - a compatible version requirement to downgrade to
  - how to use `CARGO_RESOLVER_INCOMPATIBLE_PUBLISH_AGE`

Items from the tracking issue:
- `deny` precedence between this and `incompatible-rust-version`: we can
  always adjust this over time
- the `registry.min-publish-age` / `registries.*.min-publish-age` precedence rule: mimics credential providers
- `cargo install` behavior
  - there was some confusion over what was being stabilized due to edits
    that happened during the FCP that weren't noticed
  - `resolver` is defined as not affecting `cargo install` which this
    preserves, just like `incompatible-rust-version`
- `cargo update --breaking`: this feature is being stabilized first and
  the other is being considered for removal (rust-lang#17333)

Fixes rust-lang#17009
@rustbot rustbot added A-dependency-resolution Area: dependency resolution and the resolver A-documenting-cargo-itself Area: Cargo's documentation A-unstable Area: nightly unstable support A-workspaces Area: workspaces S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Aug 7, 2026
@rustbot

rustbot commented Aug 7, 2026

Copy link
Copy Markdown
Collaborator

r? @weihanglo

rustbot has assigned @weihanglo.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: @epage, @weihanglo
  • @epage, @weihanglo expanded to epage, weihanglo

@weihanglo weihanglo Aug 7, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before diving into other aspects of the stabilization, have we got any feedback for this using in CI / production?

View changes since the review

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not that I know of.


See [Registry Authentication](registry-authentication.md) for more information.

#### `registry.min-publish-age`

@weihanglo weihanglo Aug 10, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is listed as an unsolved question:

The registry.min-publish-age / registries.min-publish-age precedence rule

Still not sure about the [registry] table. Feel like the table was a mistake and a source of confusion that I'd like to avoid adding any new features to it. Like registry.default can change the default registry but registry.token or registry.min-publish-age is still crates.io only.

View changes since the review

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the only "soft" blocker I have. I am totally fine that we stabilize this as is.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only historical context I've seen so far: #12334 (comment)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

weihanglo#100 has some (LLM-generated, sorry) analysis showing the inconsistency, pretty much matching what I remembered.

Comment thread doc/book/src/reference/config.md
@rustbot

rustbot commented Aug 10, 2026

Copy link
Copy Markdown
Collaborator

This PR was rebased onto a different master commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

@rustbot

rustbot commented Aug 10, 2026

Copy link
Copy Markdown
Collaborator

☔ The latest upstream changes (possibly #17345) made this pull request unmergeable. Please resolve the merge conflicts.

pull Bot pushed a commit to Mattlk13/cargo that referenced this pull request Aug 10, 2026
pull Bot pushed a commit to Mattlk13/cargo that referenced this pull request Aug 10, 2026
### What does this PR try to resolve?

As identified at
rust-lang#17335 (comment)

### How to test and review this PR?
weihanglo added a commit to weihanglo/cargo that referenced this pull request Aug 11, 2026
# `[registry]` vs `[registries.<name>]` per-key semantics

Review notes for [rust-lang#17335] (min-publish-age stabilization),
comparing how each config key behaves across the two tables.
Verified against PR head `7b009184` with repro tests in
`tests/testsuite/registry_table_confusion.rs`
and the PR's own `tests/testsuite/min_publish_age.rs`.

[rust-lang#17335]: rust-lang#17335 (comment)

| Key | `[registry]` | `[registries.crates-io]` | `[registries.<alt>]` | Evidence |
|---|---|---|---|---|
| `token` | works for crates.io; does **not** follow `registry.default` | **silently ignored** (config and `CARGO_REGISTRIES_CRATES_IO_TOKEN` env) | works | `registries_crates_io_token_ignored_for_crates_io`, `registry_token_does_not_follow_registry_default` |
| `credential-provider` | works for crates.io | **silently ignored** | works | `registries_crates_io_credential_provider_ignored` |
| `secret-key` / `secret-key-subject` | works for crates.io | silently ignored (same code path as `token`) | works | code: `src/util/auth/mod.rs:212` returns `[registry]` for crates.io before any name lookup |
| `min-publish-age` (new) | crates.io only; ignored for alt registries even with `registry.default` pointing at them | **honored; overrides `registry.min-publish-age`** | honored | `registry_alt_ignores_min_publish_age`, `registries_crates_io_overrides_registry_default` |
| `global-min-publish-age` (new) | fallback for **all** registries | silently ignored (not a `RegistryConfig` field) | silently ignored | code: `src/context/schema.rs:530` |
| `protocol` | silently ignored (not a `GlobalRegistryConfig` field) | honored | parsed but unused (`_protocol`) | code: `SourceId::crates_io_is_sparse` reads `registries.crates-io.protocol` only |
| `index` | hard error: "no longer supported" | silently ignored (`SourceId::alt_registry` short-circuits `crates-io`) | required; defines the registry | code: `check_registry_index_not_set`, `src/workspace/source_id.rs:296` |
| `default` | selects target registry for `publish`/`login`/`owner`/`yank` when `--registry`/`--index` absent | silently ignored | n/a | code: `src/util/command_prelude.rs:919` |
| `global-credential-providers` | fallback providers for **all** registries | silently ignored | silently ignored | code: `src/util/auth/mod.rs:57` |

Key asymmetries:

* `min-publish-age` is the first key where `[registries.crates-io]` both works
  and overrides its `[registry]` counterpart;
  for the auth keys, `[registries.crates-io]` is dead config.
* Auth resolves crates.io **by URL first** (`is_crates_io()`, `src/util/auth/mod.rs:212`);
  min-publish-age resolves **by name first** (`alt_registry_key()`, `src/resolver/version_prefs.rs:279`).
  A named mirror of crates.io's index gets `[registry]` credentials
  but `registries.<mirror>.min-publish-age`.
* `registries.<name>.global-min-publish-age` and `registry.protocol` are silent no-ops —
  the same "subtle `s` distinction" concern raised in
  [rust-lang#12334](rust-lang#12334 (comment)).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-dependency-resolution Area: dependency resolution and the resolver A-documenting-cargo-itself Area: Cargo's documentation A-unstable Area: nightly unstable support A-workspaces Area: workspaces S-waiting-on-review Status: Awaiting review from the assignee but also interested parties.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Tracking Issue for min-publish-age RFC 3923

3 participants