From 322915b0fd400a7c37301c49b64849d505963f43 Mon Sep 17 00:00:00 2001 From: Tim Hockin Date: Sat, 13 Jan 2024 16:53:18 -0800 Subject: [PATCH] KEP 4402: Go workspaces for k/k --- .../prod-readiness/sig-architecture/4402.yaml | 3 + .../4402-go-workspaces/README.md | 455 ++++++++++++++++++ .../4402-go-workspaces/kep.yaml | 27 ++ v2-experiment.md | 441 +++++++++++++++++ 4 files changed, 926 insertions(+) create mode 100644 keps/prod-readiness/sig-architecture/4402.yaml create mode 100644 keps/sig-architecture/4402-go-workspaces/README.md create mode 100644 keps/sig-architecture/4402-go-workspaces/kep.yaml create mode 100644 v2-experiment.md diff --git a/keps/prod-readiness/sig-architecture/4402.yaml b/keps/prod-readiness/sig-architecture/4402.yaml new file mode 100644 index 000000000000..d83fd49fe775 --- /dev/null +++ b/keps/prod-readiness/sig-architecture/4402.yaml @@ -0,0 +1,3 @@ +kep-number: 4402 +stable: + approver: "@jpbetz" diff --git a/keps/sig-architecture/4402-go-workspaces/README.md b/keps/sig-architecture/4402-go-workspaces/README.md new file mode 100644 index 000000000000..2666b8f002f6 --- /dev/null +++ b/keps/sig-architecture/4402-go-workspaces/README.md @@ -0,0 +1,455 @@ + +# KEP-NNNN: Go workspaces for k/k + + +- [Release Signoff Checklist](#release-signoff-checklist) +- [Summary](#summary) +- [Motivation](#motivation) + - [Goals](#goals) + - [Non-Goals](#non-goals) +- [Proposal](#proposal) + - [Go and v2](#go-and-v2) + - [Alternatives to gengo/v2](#alternatives-to-gengov2) + - [Risks and Mitigations](#risks-and-mitigations) + - [Test Plan](#test-plan) + - [Prerequisite testing updates](#prerequisite-testing-updates) + - [Unit tests](#unit-tests) + - [Integration tests](#integration-tests) + - [e2e tests](#e2e-tests) + - [Graduation Criteria](#graduation-criteria) + - [Upgrade / Downgrade Strategy](#upgrade--downgrade-strategy) + - [Version Skew Strategy](#version-skew-strategy) +- [Production Readiness Review Questionnaire](#production-readiness-review-questionnaire) + - [Feature Enablement and Rollback](#feature-enablement-and-rollback) + - [Rollout, Upgrade and Rollback Planning](#rollout-upgrade-and-rollback-planning) + - [Monitoring Requirements](#monitoring-requirements) + - [Dependencies](#dependencies) + - [Scalability](#scalability) + - [Troubleshooting](#troubleshooting) +- [Implementation History](#implementation-history) +- [Drawbacks](#drawbacks) +- [Alternatives](#alternatives) +- [Infrastructure Needed (Optional)](#infrastructure-needed-optional) + + +## Release Signoff Checklist + +Items marked with (R) are required *prior to targeting to a milestone / release*. + +- [ ] (R) Enhancement issue in release milestone, which links to KEP dir in [kubernetes/enhancements] (not the initial KEP PR) +- [ ] (R) KEP approvers have approved the KEP status as `implementable` +- [ ] (R) Design details are appropriately documented +- [ ] (R) Test plan is in place, giving consideration to SIG Architecture and SIG Testing input (including test refactors) + - [ ] e2e Tests for all Beta API Operations (endpoints) + - [ ] (R) Ensure GA e2e tests meet requirements for [Conformance Tests](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/conformance-tests.md) + - [ ] (R) Minimum Two Week Window for GA e2e tests to prove flake free +- [ ] (R) Graduation criteria is in place + - [ ] (R) [all GA Endpoints](https://github.com/kubernetes/community/pull/1806) must be hit by [Conformance Tests](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/conformance-tests.md) +- [ ] (R) Production readiness review completed +- [ ] (R) Production readiness review approved +- [ ] "Implementation History" section is up-to-date for milestone +- [ ] User-facing documentation has been created in [kubernetes/website], for publication to [kubernetes.io] +- [ ] Supporting documentation—e.g., additional design documents, links to mailing list discussions/SIG meetings, relevant PRs/issues, release notes + +[kubernetes.io]: https://kubernetes.io/ +[kubernetes/enhancements]: https://git.k8s.io/enhancements +[kubernetes/kubernetes]: https://git.k8s.io/kubernetes +[kubernetes/website]: https://git.k8s.io/website + +## Summary + +The main Kubernetes git repo (github.com/kubernetes/kubernetes, colloquially +called "k/k") is the embodiment of evolution. When it was created, the only +way to build Go applications was GOPATH. Over time we built tooling which +understood GOPATH, and it leaked into many parts of our build, test, and +release systems. Then Go added modules, in part because GOPATH was unpleasant +and had a tendency to leak into tools. We adopted modules, but we also added +the idea of "staging" repositories - a way to eat our cake and have, too. We +get the benefits of a monorepo (atomic commits, fast iteration across repos) +and then publish those to standalone repos for downstream consumption. To make +this work with modules, we abused GOPATH even harder and wrote even more tools. + +The Go project saw what we (and others) were doing and did not like it. So +they created [workspaces](https://go.dev/doc/tutorial/workspaces). They +basically created a solution that is purpose-built for us. + +This KEP proposes that we adopt Go workspaces and bring our tooling up to +modern standards. In fact, the author started this work in 2021 or 2022, +discovering issues along the way that the Go team has worked to resolve. + +This is not a user-facing change. No k8s cluster-user or cluster-admin should +know or care that this happened. On the surface, it seems like something that +should not warrant a KEP, but: + a) KEPs are how we communicate big changes; + b) This is a big change; + c) There's some ecosystem impact to developers + +## Motivation + +Anyone who has had to maintain the multitude of `verify-*` and `update-*` +scripts has felt this pain. Anyone who has had to deal with how we build and +test Kubernetes has run into the mess. It's a constant source of complexity +and friction for maintainers, and it leaks out into our developer ecosystem. + +This is the sort of mess that wise people back away from. The author is not so +wise. + +### Goals + +1) To get rid of our reliance on GOPATH hackery to build Kubernetes and to run + verifier tools and code-generators. +2) To simplify and clarify our tooling with regards to multi-module operation. +3) To be able to use upstream tooling, such as `gopls` across multiple modules. + +### Non-Goals + +1) To rewrite our code-generators (though some could use it). +2) To make the build or tools faster. +3) To change the meaning or structure of staging or the publishing bot system. + +## Proposal + +This KEP proposes to add a `go.work` file (checked in) and fix all the tools +that break because of that. At the end, there will be no reliance on GOPATH. +verify and update scripts can use normal Go conventions for building and +running code. Abominations like `run-in-gopath.sh` will be deleted. + +The implementation will come in several waves, which will have to be sequenced +across k8s.io/kubernetes, k8s.io/gengo, and k8s.io/kube-openapi repos. In +order to not leave repos in a broken state, some PRs will need to be larger +than we might otherwise like, but commits can tell the story. + +This is a proposed merge sequence: + +1. Retool the core of gengo to handle workspaces. This will be gengo/v2. The + hand-rolled parsing logic will be removed and replaced with + `golang.org/x/tools/go/packages.Load`, which understands workspaces. +1. Update kube-openapi to use gengo/v2. TBD as to whether this represents + kube-openapi/v2 (that may be simplest). +1. Introduce workspaces to k/k. + 1. Add a `go.work` file (which breaks a ton of intra-repo tools). + 1. Convert non-gengo parts of our build (e.g. `make`, `make test`, many + `verify-foo.sh and `update-foo.sh` scripts) to use workspaces (often just + removing things like `GO111MODULE=off` or `-mod=mod` decorations). + 1. Update gengo and kube-openapi versions in k/k (vendored). + 1. Convert gengo-based tools (in staging/src/k8s.io/code-generator) to + gengo/v2 and kube-openapi/v2. + 1. Fix any remaining tools which had dependencies on the gengo-based tools. + 1. Remove detritus, including (but not limited to) run-in-gopath.sh, + references to GOPATH, workarounds for vendored packages, etc. + +Along the way, some tools will need more touch than others. At least one - +import-boss - seems best to retool away from gengo entirely. + +Somewhere in there, we want to make deeper changes to gengo/v2 to simplify it. +Some of the framework seemed clean at the time, but nearly a decade later, just +makes the tools harder to understand. This could happen after all of this +work (repeating the sequence) or at the same time, making for larger but more +complete reworking. + +### Go and v2 + +There's been a lot written about Go's v2 problem. It can be confusing for +producers and consumers. That said, it seems to work for what we want, which +is to NOT make explicit releases of gengo, even though there's a "v2". + +Once consumers switch to v2 (`go get k8s.io/gengo/v2`), they can simply use +normal Go unversioned updates (`go get -u k8s.io/gengo/v2`). See [this +report](v2-experiment.md) for more details. +of this KEP for more. + +### Alternatives to gengo/v2 + +We did consider some options before landing on gengo/v2. + + 1. Put it in `gengo/v2` with a README that says "don't use this unless you + are part of kubernetes". Pro: simple. + 1. Put it in a new `k8s.io/` repo with a README that says "don't + use this unless you are part of kubernetes". + 1. Put it in `k8s.io/code-generator/` with a README that says + "don't use this unless you are part of kubernetes" (pro: that puts it into + k/k so atomic commits are OK). + 1. Try to make a k8s.io/internal github org work, and put it as + `k8s.io/internal/`. Pro: stronger than a README. + +The general feeling was that `gengo/v2` is simplest and "good enough". + +### Risks and Mitigations + +There's not a clean way to do this. Go workspaces DOES NOT work with our +symlinks-in-vendor hack, and all of our tools do not work without it. We have +a LOT of tools and the hacks run DEEP. We have a decade of legacy to scrub +off. Worse, many of our tools make dubious assumptions about the +interchangeability of Go package paths (e.g. "example.com/foo/bar") and disk +paths. Those assumptions held as long as we used GOPATH, BARELY held with +staging modules, and break totally in workspaces. + +This means that some of our ecosystem-facing APIs (codegen tools, in +particular) *must* change. We can mitigate some of the impact by creating "v2" +of things like k8s.io/gengo (which powers many tools). We might choose to do +the same in kube-openapi, though its API is not changing, just the +implementation. + +However, k8s.io/code-generator is more challenging. It holds all of our tools +and some scripts for invoking them, and is used by a non-trivial number of +downstream projects (operators, custom API servers, etc). Making a v2 of this +(which itself lives in staging, and is subject to this KEP!!) is something we +have not done before. The simple answer is to rely on the fact that it was +never really versioned before, and just make the changes. We could move it all +to a new "legacy-code-generator" staging repo and explain that it gets no +further support, or we could just tag the last legacy release of +k8s.io/code-generator and tell people to sync to that tag (or just rely on the +existing `v0.29.x` tag). Same effect. + +Another risk is that this depends on +[Go 1.22](https://tip.golang.org/doc/go1.22) and +[vendoring in workspace mode](https://github.com/golang/go/issues/60056), which +are not yet released. Go 1.22 is scheduled to release in February 2024, which +seems like good timing for k8s 1.30, but has not yet been confirmed as +plan-of-record. As of Jan 13, 2024, people on the release team think it's +likely that we will release k8s 1.30 on Go 1.22, but +[that work](https://github.com/kubernetes/release/issues/3280) has not yet +begun. The closer we get to the Kubernetes release, the more risk this +introduces, so if we can't get it in early, we should probably wait until 1.31. + +We won't not merge things to master that require go 1.22 until master is +solidly on go 1.22 (1.22.0+, not a release candidate), with no known +regressions / release blockers for at least a couple weeks. + +Another risk is that there are many tools in use which DO NOT HAVE TESTS. They +seem to work today, but upon closer inspection it's not always clear that they +work correctly or completely, or what the exact semantics are intended to be. +Changing these is dangerous. As we proceed with this work, we will have to add +tests to tools and verifiers, and look closely at the results of the various +code-generators. Ideally there will be NO CHANGE in generated code. + +### Test Plan + +We will add some tests to untested tools, though complete functional coverage +is difficult, and would be a prohibitively high bar (e.g. it's unreasonable to +demand net-new tests for every codegen tool which exercises every path). That +said, we will look carefully at how each tool works, to mitigate risks. At the +time of this writing, the author has spent upwards of 100 hours in the +debugger, single-stepping through each tool. + +[X] I/we understand the owners of the involved components may require updates to +existing tests to make this code solid enough prior to committing the changes necessary +to implement this enhancement. + +##### Prerequisite testing updates + +##### Unit tests + +We will add tests for critical subsystems and tools being changed (e.g. gengo's +package loading). + +##### Integration tests + +N/A - see e2e + +##### e2e tests + +The best test for work like this is, more or less, "did it work?". + +If the codegen tools emit the exact same code (or changes are manually +verifiable as correct) then "it works". Part of this process must be to +exercise it on out-of-tree consumers, which will be difficult to do until it is +merged. We expect some amount of ex post facto problem reports from +downstreams. + +### Graduation Criteria + +N/A - once this merges it is live. + +### Upgrade / Downgrade Strategy + +N/A - not user-facing. + +### Version Skew Strategy + +N/A - not user-facing. + +## Production Readiness Review Questionnaire + +### Feature Enablement and Rollback + +###### How can this feature be enabled / disabled in a live cluster? + +N/A for clusters. Once we merge it, it is active for developers in k/k. Once +we cut a release tag, it is active for consumers of k8s.io/code-generator. If +we should need to back it out, it will be a complex set of git reverts, across +at least k/k and kube-openapi repos. + +As such, we must make sure that each PR works and is self-contained - no +leaving the repo(s) in a broken state. + +###### Does enabling the feature change any default behavior? + +No. + +###### Can the feature be disabled once it has been enabled (i.e. can we roll back the enablement)? + +N/A. + +###### What happens if we reenable the feature if it was previously rolled back? + +N/A. + +###### Are there any tests for feature enablement/disablement? + +N/A. + +### Rollout, Upgrade and Rollback Planning + +N/A. + +###### How can a rollout or rollback fail? Can it impact already running workloads? + +N/A. + +###### What specific metrics should inform a rollback? + +If there is massive downstream breakage, we may need to revert. If we adopt Go +1.22, merge this KEP, then decide to roll-back to Go 1.21 for some reason, we +WILL need to revert this KEP. We should have pretty high confidence in Go 1.22 +before we merge this. + +###### Were upgrade and rollback tested? Was the upgrade->downgrade->upgrade path tested? + +N/A. + +###### Is the rollout accompanied by any deprecations and/or removals of features, APIs, fields of API types, flags, etc.? + +Yes. The CLI of various code-gen tools has to change. These tools are used by +downstream developers. + +### Monitoring Requirements + +N/A. + +###### How can an operator determine if the feature is in use by workloads? + +N/A. + +###### How can someone using this feature know that it is working for their instance? + +N/A. + +###### What are the reasonable SLOs (Service Level Objectives) for the enhancement? + +N/A. + +###### What are the SLIs (Service Level Indicators) an operator can use to determine the health of the service? + +N/A. + +###### Are there any missing metrics that would be useful to have to improve observability of this feature? + +N/A. + +### Dependencies + +Go 1.22 + +###### Does this feature depend on any specific services running in the cluster? + +No. + +### Scalability + +N/A. + +###### Will enabling / using this feature result in any new API calls? + +No. + +###### Will enabling / using this feature result in introducing new API types? + +No. + +###### Will enabling / using this feature result in any new calls to the cloud provider? + +No. + +###### Will enabling / using this feature result in increasing size or count of the existing API objects? + +No. + +###### Will enabling / using this feature result in increasing time taken by any operations covered by existing SLIs/SLOs? + +No. + +###### Will enabling / using this feature result in non-negligible increase of resource usage (CPU, RAM, disk, IO, ...) in any components? + +No. + +###### Can enabling / using this feature result in resource exhaustion of some node resources (PIDs, sockets, inodes, etc.)? + +No. + +### Troubleshooting + +###### How does this feature react if the API server and/or etcd is unavailable? + +N/A. + +###### What are other known failure modes? + +None. + +###### What steps should be taken if SLOs are not being met to determine the problem? + +N/A. + +## Implementation History + +* Started work in 2022, needed more from Go team. +* Work went stale. +* Restarted in 2023. +* KEP. + +## Drawbacks + +None. + +## Alternatives + +1) Do nothing (keep our toos and dev-exp semi-broken) +2) Change how we manage our repos (abandon staging) +3) Abandon the mono-repo +4) Something more dramatic? + +## Infrastructure Needed (Optional) + +None. diff --git a/keps/sig-architecture/4402-go-workspaces/kep.yaml b/keps/sig-architecture/4402-go-workspaces/kep.yaml new file mode 100644 index 000000000000..00e2bc326094 --- /dev/null +++ b/keps/sig-architecture/4402-go-workspaces/kep.yaml @@ -0,0 +1,27 @@ +title: Go workspaces for k/k +kep-number: 4402 +authors: + - "@thockin" +owning-sig: sig-architecture +participating-sigs: + - sig-release + - sig-api-machinery +status: provisional +creation-date: 2024-01-13 +reviewers: + - "@sttts" + - "@pohly" + - "@alexzielenski" +approvers: + - "@jpbetz" + - "@liggitt" +see-also: + - https://github.com/kubernetes/enhancements/tree/master/keps/sig-architecture/917-go-modules +replaces: [] +stage: stable +latest-milestone: "v1.30" +milestone: + stable: "v1.30" +feature-gates: [] +disable-supported: false +metrics: [] diff --git a/v2-experiment.md b/v2-experiment.md new file mode 100644 index 000000000000..f434d76b314d --- /dev/null +++ b/v2-experiment.md @@ -0,0 +1,441 @@ +# Experimenting with Go behaviors wrt "v2" + +The document details an experiment performed to see exactly what Go does with +regards to v2. + +TL;DR: It seems OK with no tags in play, but if there are tags it seems to +break down. + +## Setup + +I created a fake-lib repo: + +``` +thockin-glaptop4 fake-lib 0b906 main /$ cat go.mod +module github.com/thockin/fake-lib + +go 1.21.3 + +thockin-glaptop4 fake-lib 0b906 main /$ cat fake.go +package fakelib + +var X = "fake lib v0.0.0" +``` + +I created a fake-app repo: + +``` +thockin-glaptop4 fake-app 8efd0 main /$ cat go.mod +module github.com/thockin/fake-app + +go 1.21.3 + +thockin-glaptop4 fake-app 8efd0 main /$ cat app.go +package main + +import ( + "fmt" + + fakelib "github.com/thockin/fake-lib" +) + +func main() { + fmt.Println(fakelib.X) +} + +thockin-glaptop4 fake-app 8efd0 main /$ go run . +app.go:6:2: no required module provides package github.com/thockin/fake-lib; to add it: + go get github.com/thockin/fake-lib + +thockin-glaptop4 fake-app 8efd0 main /$ GOPROXY=direct go get github.com/thockin/fake-lib +go: downloading github.com/thockin/fake-lib v0.0.0-20240118195027-0b90652648a0 +go: upgraded github.com/thockin/fake-lib v0.0.0-20240118184109-2ef452a3761b => v0.0.0-20240118195027-0b90652648a0 + +thockin-glaptop4 fake-app 8efd0 main /$ cat go.mod +module github.com/thockin/fake-app + +go 1.21.3 + +require github.com/thockin/fake-lib v0.0.0-20240118195027-0b90652648a0 // indirect + +thockin-glaptop4 fake-app 8efd0 main /$ go run . +fake lib v0.0.0 +``` + +## Edits without tags + +I changed the lib: + +``` +commit 8c845166b6b12838779b995919cc3d7f6fedd62c (HEAD -> main) +Good "git" signature for thockin@google.com with ED25519 key SHA256:M2+rk0pn34LtCBIVneq+UkpS+MLUTLylIUjHPq6OGSE +Author: Tim Hockin +Date: Thu Jan 18 12:00:26 2024 -0800 + + v0.0.0 edit 1 + +diff --git a/fake.go b/fake.go +index 4dd1ccd..273a71e 100644 +--- a/fake.go ++++ b/fake.go +@@ -1,3 +1,3 @@ + package fakelib + +-var X = "fake lib v0.0.0" ++var X = "fake lib v0.0.0 edit 1" +``` + +In the app: + +``` +thockin-glaptop4 fake-app 8efd0 main /$ GOPROXY=direct go get -u github.com/thockin/fake-lib +go: downloading github.com/thockin/fake-lib v0.0.0-20240118200026-8c845166b6b1 +go: upgraded github.com/thockin/fake-lib v0.0.0-20240118195027-0b90652648a0 => v0.0.0-20240118200026-8c845166b6b1 + +thockin-glaptop4 fake-app 8efd0 main /$ go run . +fake lib v0.0.0 edit 1 +``` + +This is effectively what we do with repos like `k8s.io/gengo` today. + +## Introducing v2 + +I made fake-lib/v2 without any tags: + +``` +thockin-glaptop4 fake-lib 7f1be main /v2$ git show +commit 7f1be8fbd1ee46c2c84483002f97c5f43730f577 (HEAD -> main) +Good "git" signature for thockin@google.com with ED25519 key SHA256:M2+rk0pn34LtCBIVneq+UkpS+MLUTLylIUjHPq6OGSE +Author: Tim Hockin +Date: Thu Jan 18 12:03:57 2024 -0800 + + v2 untagged + +diff --git a/v2/fake.go b/v2/fake.go +new file mode 100644 +index 0000000..0601f26 +--- /dev/null ++++ b/v2/fake.go +@@ -0,0 +1,3 @@ ++package fakelib ++ ++var X = "fake lib v2 untagged" +diff --git a/v2/go.mod b/v2/go.mod +new file mode 100644 +index 0000000..d6b26fb +--- /dev/null ++++ b/v2/go.mod +@@ -0,0 +1,3 @@ ++module github.com/thockin/fake-lib/v2 ++ ++go 1.21.3 +``` + +In the app, I tried a naive (I knew it won't work) approach: + +``` +thockin-glaptop4 fake-app 8efd0 main /$ GOPROXY=direct go get -u github.com/thockin/fake-lib +go: downloading github.com/thockin/fake-lib v0.0.0-20240118200357-7f1be8fbd1ee +go: upgraded github.com/thockin/fake-lib v0.0.0-20240118200026-8c845166b6b1 => v0.0.0-20240118200357-7f1be8fbd1ee + +thockin-glaptop4 fake-app 8efd0 main /$ go run . +fake lib v0.0.0 edit 1 + +thockin-glaptop4 fake-app 8efd0 main /$ sed -i 's|fake-lib|fake-lib/v2|' app.go + +thockin-glaptop4 fake-app 8efd0 main /$ go run . +app.go:6:2: no required module provides package github.com/thockin/fake-lib/v2; to add it: + go get github.com/thockin/fake-lib/v2 +``` + +OK, as expected. Let's do it right. + +``` +thockin-glaptop4 fake-app 8efd0 main /$ git co -- . + +thockin-glaptop4 fake-app 8efd0 main /$ GOPROXY=direct go get github.com/thockin/fake-lib/v2 +go: downloading github.com/thockin/fake-lib/v2 v2.0.0-20240118200357-7f1be8fbd1ee +go: added github.com/thockin/fake-lib/v2 v2.0.0-20240118200357-7f1be8fbd1ee + +thockin-glaptop4 fake-app 8efd0 main /$ sed -i 's|fake-lib|fake-lib/v2|' app.go + +thockin-glaptop4 fake-app 8efd0 main /$ go mod tidy + +thockin-glaptop4 fake-app 8efd0 main /$ cat go.mod +module github.com/thockin/fake-app + +go 1.21.3 + +require github.com/thockin/fake-lib/v2 v2.0.0-20240118200357-7f1be8fbd1ee + +thockin-glaptop4 fake-app 8efd0 main /$ go run . +fake lib v2 untagged +``` + +OK so far - back to the lib, make some edits: + +``` +thockin-glaptop4 fake-lib 58927 main /v2$ git show +commit 589276a8e3e3909948b34ffeeca402b6f4691102 (HEAD -> main) +Good "git" signature for thockin@google.com with ED25519 key SHA256:M2+rk0pn34LtCBIVneq+UkpS+MLUTLylIUjHPq6OGSE +Author: Tim Hockin +Date: Thu Jan 18 12:10:10 2024 -0800 + + v2 untagged, edit 1 + +diff --git a/v2/fake.go b/v2/fake.go +index 0601f26..bcaf878 100644 +--- a/v2/fake.go ++++ b/v2/fake.go +@@ -1,3 +1,3 @@ + package fakelib + +-var X = "fake lib v2 untagged" ++var X = "fake lib v2 untagged, edit 1" +``` + +And in the app: + +``` +thockin-glaptop4 fake-app 8efd0 main /$ GOPROXY=direct go get -u github.com/thockin/fake-lib/v2 +go: downloading github.com/thockin/fake-lib/v2 v2.0.0-20240118201010-589276a8e3e3 +go: downloading github.com/thockin/fake-lib v0.0.0-20240118201010-589276a8e3e3 +go: upgraded github.com/thockin/fake-lib/v2 v2.0.0-20240118200357-7f1be8fbd1ee => v2.0.0-20240118201010-589276a8e3e3 + +thockin-glaptop4 fake-app 8efd0 main /$ go mod tidy + +thockin-glaptop4 fake-app 8efd0 main /$ cat go.mod +module github.com/thockin/fake-app + +go 1.21.3 + +require github.com/thockin/fake-lib/v2 v2.0.0-20240118201010-589276a8e3e3 + +thockin-glaptop4 fake-app 8efd0 main /$ go run . +fake lib v2 untagged, edit 1 +``` + +That seems to work. For good measure, one more time: + +``` +thockin-glaptop4 fake-lib 64082 main /v2$ git show +commit 640822f7fd61faed90ac05005e027b2a875787b9 (HEAD -> main, origin/main, origin/HEAD) +Good "git" signature for thockin@google.com with ED25519 key SHA256:M2+rk0pn34LtCBIVneq+UkpS+MLUTLylIUjHPq6OGSE +Author: Tim Hockin +Date: Thu Jan 18 12:13:40 2024 -0800 + + v2 untagged, edit 2 + +diff --git a/v2/fake.go b/v2/fake.go +index bcaf878..27d791e 100644 +--- a/v2/fake.go ++++ b/v2/fake.go +@@ -1,3 +1,3 @@ + package fakelib + +-var X = "fake lib v2 untagged, edit 1" ++var X = "fake lib v2 untagged, edit 2" +``` + +``` +thockin-glaptop4 fake-app 8efd0 main /$ GOPROXY=direct go get -u github.com/thockin/fake-lib/v2 +go: downloading github.com/thockin/fake-lib/v2 v2.0.0-20240118201340-640822f7fd61 +go: downloading github.com/thockin/fake-lib v0.0.0-20240118201340-640822f7fd61 +go: upgraded github.com/thockin/fake-lib/v2 v2.0.0-20240118201010-589276a8e3e3 => v2.0.0-20240118201340-640822f7fd61 + +thockin-glaptop4 fake-app 8efd0 main /$ go mod tidy + +thockin-glaptop4 fake-app 8efd0 main /$ cat go.mod +module github.com/thockin/fake-app + +go 1.21.3 + +require github.com/thockin/fake-lib/v2 v2.0.0-20240118201340-640822f7fd61 + +thockin-glaptop4 fake-app 8efd0 main /$ go run . +fake lib v2 untagged, edit 2 +thockin-glaptop4 fake-app 8efd0 main /$ +``` + +## With tags + +It all seems to work without any tags. Let's mess it up. + +lib: + +``` +thockin-glaptop4 fake-lib 0e7a2 main /v2$ git show +commit 0e7a25e511f2b7893ce39aefa1c3dc83592bd734 (HEAD -> main) +Good "git" signature for thockin@google.com with ED25519 key SHA256:M2+rk0pn34LtCBIVneq+UkpS+MLUTLylIUjHPq6OGSE +Author: Tim Hockin +Date: Thu Jan 18 12:16:52 2024 -0800 + + v2.0.0 tagged + +diff --git a/v2/fake.go b/v2/fake.go +index 27d791e..bdf0e8a 100644 +--- a/v2/fake.go ++++ b/v2/fake.go +@@ -1,3 +1,3 @@ + package fakelib + +-var X = "fake lib v2 untagged, edit 2" ++var X = "fake lib v2.0.0 tagged" + +thockin-glaptop4 fake-lib 0e7a2 main /v2$ git tag v2.0.0 + +thockin-glaptop4 fake-lib 0e7a2 main /v2$ git push --tags +``` + +app: + +``` +thockin-glaptop4 fake-app 8efd0 main /$ GOPROXY=direct go get -u github.com/thockin/fake-lib/v2 + +thockin-glaptop4 fake-app 8efd0 main /$ # That had no effect + +thockin-glaptop4 fake-app 8efd0 main /$ cat go.mod +module github.com/thockin/fake-app + +go 1.21.3 + +require github.com/thockin/fake-lib/v2 v2.0.0-20240118201340-640822f7fd61 + +thockin-glaptop4 fake-app 8efd0 main /$ GOPROXY=direct go get -u github.com/thockin/fake-lib/v2@latest +go: downloading github.com/thockin/fake-lib/v2 v2.0.0 +go: upgraded github.com/thockin/fake-lib/v2 v2.0.0-20240118201340-640822f7fd61 => v2.0.0 + +thockin-glaptop4 fake-app 8efd0 main /$ go mod tidy + +thockin-glaptop4 fake-app 8efd0 main /$ cat go.mod +module github.com/thockin/fake-app + +go 1.21.3 + +require github.com/thockin/fake-lib/v2 v2.0.0 + +thockin-glaptop4 fake-app 8efd0 main /$ go run . +fake lib v2.0.0 tagged +``` + +And let's bump it without tags: + +``` +thockin-glaptop4 fake-lib 203cf main /v2$ git show +commit 203cfc208120f01d03ce671dc65a087c91d79c3c (HEAD -> main, origin/main, origin/HEAD) +Good "git" signature for thockin@google.com with ED25519 key SHA256:M2+rk0pn34LtCBIVneq+UkpS+MLUTLylIUjHPq6OGSE +Author: Tim Hockin +Date: Thu Jan 18 12:20:15 2024 -0800 + + v2.0.0 tagged, edit 1 + +diff --git a/v2/fake.go b/v2/fake.go +index bdf0e8a..7d33402 100644 +--- a/v2/fake.go ++++ b/v2/fake.go +@@ -1,3 +1,3 @@ + package fakelib + +-var X = "fake lib v2.0.0 tagged" ++var X = "fake lib v2.0.0 tagged, edit 1" +``` + +``` +thockin-glaptop4 fake-app 8efd0 main /$ GOPROXY=direct go get -u github.com/thockin/fake-lib/v2 +go: downloading github.com/thockin/fake-lib v0.0.0-20240118202015-203cfc208120 + +thockin-glaptop4 fake-app 8efd0 main /$ # Whoah, not what I expected: v0.0.0 ??? + +thockin-glaptop4 fake-app 8efd0 main /$ cat go.mod +module github.com/thockin/fake-app + +go 1.21.3 + +require github.com/thockin/fake-lib/v2 v2.0.0 +thockin-glaptop4 fake-app 8efd0 main /$ go run . +fake lib v2.0.0 tagged +``` + +So the tag's existence broke `go get -u`. Let's try some other things: + +``` +thockin-glaptop4 fake-app 8efd0 main /$ GOPROXY=direct go get -u github.com/thockin/fake-lib/v2@latest + +thockin-glaptop4 fake-app 8efd0 main /$ GOPROXY=direct go get -u github.com/thockin/fake-lib/v2@master +go: github.com/thockin/fake-lib/v2@master: invalid version: unknown revision master + +thockin-glaptop4 fake-app 8efd0 main /$ GOPROXY=direct go get -u github.com/thockin/fake-lib/v2@main +go: downloading github.com/thockin/fake-lib/v2 v2.0.1-0.20240118202015-203cfc208120 +go: upgraded github.com/thockin/fake-lib/v2 v2.0.0 => v2.0.1-0.20240118202015-203cfc208120 + +thockin-glaptop4 fake-app 8efd0 main /$ go mod tidy + +thockin-glaptop4 fake-app 8efd0 main /$ cat go.mod +module github.com/thockin/fake-app + +go 1.21.3 + +require github.com/thockin/fake-lib/v2 v2.0.1-0.20240118202015-203cfc208120 +thockin-glaptop4 fake-app 8efd0 main /$ go run . +fake lib v2.0.0 tagged, edit 1 +``` + +OK, so naming the branch worked. That's unpleasant because it is whatever the +lib wants. I pushed a lib "edit 2" + +``` + $ GOPROXY=direct go get -u github.com/thockin/fake-lib/v2 +go: downloading github.com/thockin/fake-lib/v2 v2.0.1-0.20240118202458-f889dc37dc89 +go: downloading github.com/thockin/fake-lib v0.0.0-20240118202458-f889dc37dc89 +go: upgraded github.com/thockin/fake-lib/v2 v2.0.1-0.20240118202015-203cfc208120 => v2.0.1-0.20240118202458-f889dc37dc89 + +thockin-glaptop4 fake-app 8efd0 main /$ go run . +fake lib v2.0.0 tagged, edit 2 +``` + +Well that is even WEIRDER. I pushed an "edit 3" + +``` +$ GOPROXY=direct go get -u github.com/thockin/fake-lib/v2@HEAD +go: downloading github.com/thockin/fake-lib/v2 v2.0.1-0.20240118202641-9ce247c3b4f4 +go: downloading github.com/thockin/fake-lib v0.0.0-20240118202641-9ce247c3b4f4 +go: upgraded github.com/thockin/fake-lib/v2 v2.0.1-0.20240118202458-f889dc37dc89 => v2.0.1-0.20240118202641-9ce247c3b4f4 + +thockin-glaptop4 fake-app 8efd0 main /$ go run . +fake lib v2.0.0 tagged, edit 3 +``` + +That works, too. Let's make another tag. + +``` +$ git show +commit 0056b80c4b59c5499185348176f56a75c763d2f6 (HEAD -> main) +Good "git" signature for thockin@google.com with ED25519 key SHA256:M2+rk0pn34LtCBIVneq+UkpS+MLUTLylIUjHPq6OGSE +Author: Tim Hockin +Date: Thu Jan 18 12:28:09 2024 -0800 + + v2.1.0 tagged + +diff --git a/v2/fake.go b/v2/fake.go +index fccb833..81a9c0c 100644 +--- a/v2/fake.go ++++ b/v2/fake.go +@@ -1,3 +1,3 @@ + package fakelib + +-var X = "fake lib v2.0.0 tagged, edit 3" ++var X = "fake lib v2.1.0 tagged" +``` + +``` +thockin-glaptop4 fake-app 8efd0 main /$ GOPROXY=direct go get -u github.com/thockin/fake-lib/v2 +go: downloading github.com/thockin/fake-lib/v2 v2.1.0 +go: upgraded github.com/thockin/fake-lib/v2 v2.0.1-0.20240118202641-9ce247c3b4f4 => v2.1.0 + +thockin-glaptop4 fake-app 8efd0 main /$ go run . +fake lib v2.1.0 tagged +``` + +So, final anwer: It works as we want without tags. Once tags are in play, we +have to keep using tags. The v0.0.0 behavior seems like a bug, but maybe not +worth hunting.