crate-ci/cargo-release

Failures to complete `cargo publish --execute <STEP>` leave unknown partial modifications.

nathan-at-least opened this issue · 2 comments

I just started trying cargo publish on a crate and I've run into three different failure cases which were not caught by dry runs, and each of them has lead to partially complete publication that I tried to back out. In the last case, I'm not even sure how to back out the changes.

First, I checked out a new test branch because I was anxious about modifying my main branch: git checkout -b cargo-release-test.

That failed, because it attempted a git push and this is a new branch. Easy enough to revert.

Second, I was not authenticated to crates.io. This had created a new git commit, which I rolled back with git reset --hard HEAD^ which I think was sufficient (but I'm not certain).

Third, I was authenticated to crates.io, but my git remote to push to was not called origin. I looked up the correct argument (--push-to <MY REMOTE>), but now I cannot rollback the operation. Rollback steps:

  1. error: tag v0.1.4 already exists, so I did git delete v0.1.4
  2. Next: error: <my crate> 0.1.4 is already published, so I did cargo yank --version 0.1.4
  3. Now I still get the same error message, and I cannot tell how or where cargo-publish gets this information, since the crate is yanked from crates.io and there is no git tag.

I assume failures like this are common, so how can users safely revert a publication? Or is the best path forward to simply issue a new release, then yank the botched release versions?

My ideal (and I'm not sure this is possible) would be some way to "fully prepare" a publication, then "atomically" commit or rollback. I assume this is impossible to do atomically since crates.io and git must be fully in sync. Any thoughts along these lines?

Assuming that ideal isn't possible, then perhaps a good improvement is to provide a hint to users about what to do if a publication fails part-way through, something like:

error: …

This publication is in an incomplete state. To proceed, fix the issue, then make a new release with a new version, then do cargo yank --version XXX, then tag the incomplete releases: git tag vXXX-publish-failure

epage commented

What to do depends a lot on the specific case.

We try to catch what errors we can before the confirmation prompt.

Some failures happen during the publish. If nothing was published, then its easy to just revert. If some packages were published, the user likely should fix them up and resume from where they left off. For failures after publish, I just resume where I left off. We specifically offer the Step subcommands to allow people to pick up where they left off. You mentioned yanking, that is also another possible route. The problem is identifying these correctly and clearly specifying the options can get pretty complicated, both to implement and for users to process.

As there isn't a way to do fully perform operations or roll back, we show all of the relevant information in the dry run (if you increase the verbosity level enough), and we've designed things to be more recoverable (pick up where left off it it is appropriate, revert if not, etc), I'm going to go ahead and close this.

If there are thoughts on more concrete actionable steps to take, let us know!