content: add go116-module-changes.article

Change-Id: I3645b311d205edd1dab34c9f4a2c5f295f68d4c2
Reviewed-on: https://go-review.googlesource.com/c/blog/+/293409
Trust: Jay Conrod <jayconrod@google.com>
Run-TryBot: Alexander Rakoczy <alex@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Bryan C. Mills <bcmills@google.com>
diff --git a/content/go116-module-changes.article b/content/go116-module-changes.article
new file mode 100644
index 0000000..f516943
--- /dev/null
+++ b/content/go116-module-changes.article
@@ -0,0 +1,136 @@
+# New module changes in Go 1.16
+18 Feb 2021
+Tags: modules, versioning
+Summary: Go 1.16 enables modules by default, provides a new way to install executables, and lets module authors retract published versions.
+
+Jay Conrod
+
+##
+
+We hope you're enjoying Go 1.16!
+This release has a lot of new features, especially for modules.
+The [release notes](https://golang.org/doc/go1.16) describe these changes briefly, but let's explore a few of them in depth.
+
+## Modules on by default
+
+The `go` command now builds packages in module-aware mode by default, even when no `go.mod` is present.
+This is a big step toward using modules in all projects.
+
+It's still possible to build packages in GOPATH mode by setting the `GO111MODULE` environment variable to `off`.
+You can also set `GO111MODULE` to `auto` to enable module-aware mode only when a go.mod file is present in the current directory or any parent directory.
+This was previously the default.
+Note that you can set `GO111MODULE` and other variables permanently with `go env -w`:
+
+    go env -w GO111MODULE=auto
+
+We plan to drop support for GOPATH mode in Go 1.17.
+In other words, Go 1.17 will ignore `GO111MODULE`.
+If you have projects that do not build in module-aware mode, now is the time to migrate.
+If there is a problem preventing you from migrating, please consider filing an [issue](https://github.com/golang/go/issues/new) or an [experience report](https://github.com/golang/go/wiki/ExperienceReports).
+
+## No automatic changes to go.mod and go.sum
+
+Previously, when the `go` command found a problem with `go.mod` or `go.sum` like a missing `require` directive or a missing sum, it would attempt to fix the problem automatically.
+We received a lot of feedback that this behavior was surprising, especially for commands like `go list` that don't normally have side effects.
+The automatic fixes weren't always desirable: if an imported package wasn't provided by any required module, the `go` command would add a new dependency, possibly triggering upgrades of common dependencies.
+Even a misspelled import path would result in a (failed) network lookup.
+
+In Go 1.16, module-aware commands report an error after discovering a problem in `go.mod` or `go.sum` instead of attempting to fix the problem automatically.
+In most cases, the error message recommends a command to fix the problem.
+
+
+    $ go build
+    example.go:3:8: no required module provides package golang.org/x/net/html; to add it:
+        go get golang.org/x/net/html
+    $ go get golang.org/x/net/html
+    $ go build
+
+As before, the `go` command may use the `vendor` directory if it's present (see [Vendoring](https://golang.org/ref/mod#vendoring) for details).
+Commands like `go get` and `go mod tidy` still modify `go.mod` and `go.sum`, since their main purpose is to manage dependencies.
+
+## Installing an executable at a specific version
+
+The `go install` command can now install an executable at a specific version by specifying an `@version` suffix.
+
+    go install golang.org/x/tools/gopls@v0.6.5
+
+When using this syntax, `go install` installs the command from that exact module version, ignoring any `go.mod` files in the current directory and parent directories.
+(Without the `@version` suffix, `go install` continues to operate as it always has, building the program using the version requirements and replacements listed in the current module’s `go.mod`.)
+
+We used to recommend `go get -u program` to install an executable, but this use caused too much confusion with the meaning of `go get` for adding or changing module version requirements in `go.mod`.
+And to avoid accidentally modifying `go.mod`, people started suggesting more complex commands like:
+
+    cd $HOME; GO111MODULE=on go get program@latest
+
+Now we can all use `go install program@latest` instead.
+See [`go install`](https://golang.org/ref/mod#go-install) for details.
+
+In order to eliminate ambiguity about which versions are used, there are several restrictions on what directives may be present in the program's `go.mod` file when using this install syntax.
+In particular, `replace` and `exclude` directives are not allowed, at least for now.
+In the long term, once the new `go install program@version` is working well for enough use cases, we plan to make `go get` stop installing command binaries.
+See [issue 43684](https://golang.org/issue/43684) for details.
+
+## Module retraction
+
+Have you ever accidentally published a module version before it was ready?
+Or have you discovered a problem right after a version was published that needed to be fixed quickly?
+Mistakes in published versions are difficult to correct.
+To keep module builds deterministic, a version cannot be modified after it is published.
+Even if you delete or change a version tag, [`proxy.golang.org`](https://proxy.golang.org) and other proxies probably already have the original cached.
+
+Module authors can now *retract* module versions using the `retract` directive in `go.mod`.
+A retracted version still exists and can be downloaded (so builds that depend on it won't break), but the `go` command won’t select it automatically when resolving versions like `@latest`.
+`go get` and `go list -m -u` will print warnings about existing uses.
+
+For example, suppose the author of a popular library `example.com/lib` releases `v1.0.5`, then discovers a new security issue.
+They can add a directive to their `go.mod` file like the one below:
+
+    // Remote-triggered crash in package foo. See CVE-2021-01234.
+    retract v1.0.5
+
+
+Next, the author can tag and push version `v1.0.6`, the new highest version.
+After this, users that already depend on `v1.0.5` will be notified of the retraction when they check for updates or when they upgrade a dependent package.
+The notification message may include text from the comment above the `retract` directive.
+
+    $ go list -m -u all
+    example.com/lib v1.0.0 (retracted)
+    $ go get .
+    go: warning: example.com/lib@v1.0.5: retracted by module author:
+        Remote-triggered crash in package foo. See CVE-2021-01234.
+    go: to switch to the latest unretracted version, run:
+        go get example.com/lib@latest
+
+For an interactive, browser-based guide, check out [Retract Module Versions](https://play-with-go.dev/retract-module-versions_go116_en/) on [play-with-go.dev](https://play-with-go.dev/).
+See the [`retract` directive docs](https://golang.org/ref/mod#go-mod-file-retract) for syntax details.
+
+## Controlling version control tools with GOVCS
+
+The `go` command can download module source code from a mirror like [proxy.golang.org](https://proxy.golang.org) or directly from a version control repository using `git`, `hg`, `svn`, `bzr`, or `fossil`.
+Direct version control access is important, especially for private modules that aren't available on proxies, but it's also potentially a security problem: a bug in a version control tool may be exploited by a malicious server to run unintended code.
+
+Go 1.16 introduces a new configuration variable, `GOVCS`, which lets the user specify which modules are allowed to use specific version control tools.
+`GOVCS` accepts a comma-separated list of `pattern:vcslist` rules.
+The `pattern` is a [`path.Match`](https://golang.org/pkg/path#Match) pattern matching one or more leading elements of a module path.
+The special patterns `public` and `private` match public and private modules (`private` is defined as modules matched by patterns in `GOPRIVATE`; `public` is everything else).
+The `vcslist` is a pipe-separated list of allowed version control commands or the keyword `all` or `off`.
+
+For example:
+
+    GOVCS=github.com:git,evil.com:off,*:git|hg
+
+With this setting, modules with paths on `github.com` can be downloaded using `git`; paths on `evil.com` cannot be downloaded using any version control command, and all other paths (`*` matches everything) can be downloaded using `git` or `hg`.
+
+If `GOVCS` is not set, or if a module does not match any pattern, the `go` command uses this default: `git` and `hg` are allowed for public modules, and all tools are allowed for private modules.
+The rationale behind allowing only Git and Mercurial is that these two systems have had the most attention to issues of being run as clients of untrusted servers.
+In contrast, Bazaar, Fossil, and Subversion have primarily been used in trusted, authenticated environments and are not as well scrutinized as attack surfaces.
+That is, the default setting is:
+
+    GOVCS=public:git|hg,private:all
+
+See the [Controlling version control tools with `GOVCS`](https://golang.org/ref/mod#vcs-govcs) for more details.
+
+## What's next?
+
+We hope you find these features useful. We're already hard at work on the next set of module features for Go 1.17, particularly [lazy module loading](https://github.com/golang/go/issues/36460), which should make the module loading process faster and more stable.
+As always, if you run into new bugs, please let us know on the [issue tracker](https://github.com/golang/go/issues). Happy coding!