shurcooL/home

validate and reject commits that would result in bad module zip

dmitshur opened this issue · 1 comments

Given that home implements a custom git server and module server, it is both helpful and a novel opportunity to perform some server-side validation on git commits being pushed, to ensure they produce valid Go module zips.

This can be useful to catch unintentional mistakes that a human can make, such as:

  • accidentally including two file paths that are equal under Unicode case-folding (e.g., testdata/Data.txt and testdata/DATA.txt)
  • accidentally adding a go.mod file that isn't all lower-case (e.g., Go.mod)
  • accidentally having a mismatch between major version suffix (e.g., /v2) and the major version (e.g., v3.0.0)
  • accidentally exceeding hard limits on file sizes that are enforced by the go command
  • accidentally adding symbolic links or other irregular files that will not be included in the module zip
  • accidentally adding a go.mod directory rather than file
  • accidentally pushing commits with committer times that don't sort in strictly chronological order (e.g., after rebasing many commits, they all end up having equal committer times, which can sort badly)

When implemented, it means that doing a git push of a commit that would result in a bad Go module zip (one that the go command would reject, or one that can't include all the files that are in the commit) would be rejected by the git server by default (with an option to override it). It may look like this:

image

Now that the golang.org/x/mod/zip package exists, we can use its API to accomplish most of this. It can be used inside a server-side pre-receive git hook.

This is live now.