Cargo: Allow publishing the reason for yanking?

The argument you're providing is a strong argument for --allow-yanked as a version resolution mode. It is also a strong argument against the current recommendation to not commit Cargo.lock for libraries; a Cargo.lock serves as a receipt that the library built and was tested against that resolution of the dependency forest.

It is not, however, an argument supporting the inability to yank mark any crate version as unfit for use.

An example fresh on my mind: tracing-subscriber recently published 0.3.12 and 0.3.13 with a new feature I wrote. Unfortunately, these releases had a critical bug that in certain cases would prevent the recording of any events. This makes these versions completely unfit for use, though, even though the fix is just replacing a single false with true in a trait implementation.

So what I would take away as the desired changes:

  • Libraries should strongly consider keeping Cargo.lock in version control. This increases the reliability of testing historical versions, such as for bisection.
  • If a dependency tree fails to resolve, and a yanked version would have been selected if it weren't yanked, cargo should tell the user that yanked crate versions were excluded from consideration rather than the generic resolution failure message.
  • Allow tagging yanked versions with the high-level reason for the version being excluded from default version resolution. The OP list is imho reasonable here, but the important distinction is unfit versus broken. An unfit version has some critical implementation issue. A broken version has some critical API issue, such as failing to build or a semver-wrong change.
    • (If I understand your position correctly, you argue against ever yanking a version for being unfit.)
  • Provide a version resolution option that allows the use of yanked versions, optionally specifying specific allowed yank reasons (e.g. including unfit but excluding broken).
  • And one feature from npm that I think is very specifically useful to your use case: provide a version resolution mode that does resolution on the index as it existed on a given date.
    • The index (hopefully?) includes change dates on its append-only structure. This mode merely ignores any updates (new versions, yank requests) made after the specified datetime.
    • Bisection can ask to resolve commits' dependencies as they were available when the commit was made.
10 Likes

This is possible on the git index by choosing to look at it via a commit from that date (though having those dates correct is not required by the registry spec, and for the crates.io index will require pulling the old archived branches too for older dates). It's not possible via the new sparse-registry format as there are no explicitly recorded change dates anywhere.

1 Like

It's probably not possible to make this data available in the registry for existing metadata, but providing it for new changes seems like it would be useful.

tracing-subscriber wouldn't be subject to the policy I'm proposing. Obviously there should be some period when a release can be yanked, but I find it unreasonable that any version can be yanked at any time. This is just inviting the left-pad disaster into the ecosystem. It must be possible to build on a solid foundation which won't be yanked from under your feet.

The unpublish policy of npm looks like a generally reasonable approach. Quoting:

For newly created packages, as long as no other packages in the npm Public Registry depend on your package, you can unpublish anytime within the first 72 hours after publishing. Regardless of how long ago a package was published, you can unpublish a package that:

  • no other packages in the npm Public Registry depend on
  • had less than 300 downloads over the last week
  • has a single owner/maintainer

The exact numbers could be tweaked (e.g. I think a grace period of 1-2 weeks may be better than 3 days), but the general approach is what I would want to see in Rust: if you have published a widely used package, you cannot remove it or break people's builds in any way.

That would be very useful for e.g. bisections, but I don't know how easy it would be to implement. This also wouldn't help with something like testing minimal dependencies.

Yanking and what happened with left-pad aren't quite the same thing.

With npm, the left-pad package was effectively deleted. Even if you already had it in your package-lock.json, it still broke your project.

Not so with Cargo yanking, where things continue to work so long as a package is already in your Cargo.lock. This makes yanking much less disruptive than a left-pad-style event.

7 Likes

I'd say being unable to create new projects, update dependencies or make a patch to a library counts as very disruptive in my book.

What you actually need is a snapshot of the index of a similar vintage to your commit (yank status and all). Otherwise you're bisecting your code against modern dependencies (e.g., a patch version of a dep may have fixed your problem and cargo update, with or without yanking, will hide it from you). Reading further comments, it seems that you and others agree with such a feature existing.

Alternatively:

Agreed, but I don't think removing the ability to yank will resolve the problem you're looking to tackle.

4 Likes

I find your tone rude. It is also quite easy to split a branch into a separate topic, if you believe that the discussion has derailed.

I don't consider my comments to be off-topic. My position is that there should be no other possible reason for yanking than "we have botched our latest release". A crate version which was released 2-3 days ago doesn't need any better reason than "we messed up", a crate which was released a long time ago shouldn't be yanked ever.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.