Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bintray: check remote file hash prior to upload #8905

Merged
merged 1 commit into from Oct 12, 2020
Merged

bintray: check remote file hash prior to upload #8905

merged 1 commit into from Oct 12, 2020

Conversation

jonchang
Copy link
Contributor

If the remote file is published and has a hash matching the file we're about to upload, just skip uploading and publishing it entirely, rather than bailing out with an error.

This should reduce the number of cases where maintainers have to go and delete remote bottles when those bottles were correctly published but the homebrew/core git repository didn't update due to transient network errors.

  • Have you followed the guidelines in our Contributing document?
  • Have you checked to ensure there aren't other open Pull Requests for the same change?
  • Have you added an explanation of what your changes do and why you'd like us to include them?
  • Have you written new tests for your changes? Here's an example.
  • Have you successfully run brew style with your changes locally?
  • Have you successfully run brew tests with your changes locally?
  • Have you successfully run brew man locally and committed any changes?

Copy link
Member

@MikeMcQuaid MikeMcQuaid left a comment

Choose a reason for hiding this comment

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

Good idea here 👏🏻

false
result = curl_output "--fail", "--silent", "--head", url
if result.success?
[:present, result.stdout.match(/^X-Checksum-Sha2: ([0-9a-f]{64})/i)[1]]
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
[:present, result.stdout.match(/^X-Checksum-Sha2: ([0-9a-f]{64})/i)[1]]
{
success: true,
checksum: result.stdout.match(/^X-Checksum-Sha2: ([0-9a-f]{64})/i)[1]]
}

or similar; I think a hash makes this a little more readable.

Also: can this fail if it's a success but it can't find the checksum header? What about making the presence of a checksum imply success and checking explicitly for the header before returning a (possibly) missing match?

Copy link
Contributor Author

@jonchang jonchang Oct 12, 2020

Choose a reason for hiding this comment

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

Yeah, I haven't seen any cases where the checksum doesn't exist. But, also the Bintray API documentation is so sparse that it's not clear if the situation where the file exists but doesn't return a checksum is even possible.

How about this:

file exists and has checksum: return checksum
file exists but doesn't have checksum: return true
file doesn't exist: return false

That way, a truthy return value always means "the file exists", and you can additionally compare the return value against your local hash to look for a mismatch. (If the remote file exists but doesn't have a checksum, you can't tell if a previous upload already succeeded anyway, so this will still alert you of a mismatch and prompt you to delete the remote file).

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, I haven't seen any cases where the checksum doesn't exist. But, also the Bintray API documentation is so sparse that it's not clear if the situation where the file exists but doesn't return a checksum is even possible.

Yeh, with external APIs I always like to assume they will break at any point and start returning garbage 😂

file exists and has checksum: return checksum
file exists but doesn't have checksum: return true
file doesn't exist: return false

Didn't realise there was essentially three cases here. I'd say in that case return a checksum, empty string, nil (or false)?


if remote_status == :present
if remote_hash.presence == sha256
odebug "#{filename} is published with matching hash."
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
odebug "#{filename} is published with matching hash."
odebug "#{filename} is already published with matching hash."

If the remote file is published and has a hash matching the file we're
about to upload, just skip uploading and publishing it entirely, rather
than bailing out with an error.
@jonchang
Copy link
Contributor Author

Ok, revamped this a bit. Probably easier to check the w=1 diff: https://github.com/Homebrew/brew/pull/8905/files?w=1

Copy link
Member

@MikeMcQuaid MikeMcQuaid left a comment

Choose a reason for hiding this comment

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

Nice cleanup and work here!

@jonchang jonchang merged commit b8a9327 into Homebrew:master Oct 12, 2020
@jonchang jonchang deleted the bintray-dont-error-on-matching-files branch October 12, 2020 13:20
@jonchang
Copy link
Contributor Author

Thanks for the review :shipit:

@jonchang jonchang mentioned this pull request Oct 12, 2020
5 tasks
@BrewTestBot BrewTestBot added the outdated PR was locked due to age label Dec 1, 2020
@Homebrew Homebrew locked as resolved and limited conversation to collaborators Dec 1, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
outdated PR was locked due to age
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants