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

Tag k8s.io repos with semver-like tags #84608

Closed
ibuildthecloud opened this issue Oct 31, 2019 · 14 comments
Closed

Tag k8s.io repos with semver-like tags #84608

ibuildthecloud opened this issue Oct 31, 2019 · 14 comments
Labels
area/code-organization Issues or PRs related to kubernetes code organization kind/feature Categorizes issue or PR as related to a new feature. sig/architecture Categorizes an issue or PR as relevant to SIG Architecture. sig/release Categorizes an issue or PR as relevant to SIG Release.

Comments

@ibuildthecloud
Copy link
Contributor

What would you like to be added:

It would help the go modules ecosystem if k8s.io repos had tags that are semver format. From a user perspective it would also be nice if the tag matched the corresponding k8s version. This means today changing the approach of adding kubernetes-vx.x.x tags to vx.x.x on all k8s.io repos that come from staging/

Why is this needed:

The majority of the issues felt by the community when using go modules with k8s has to do with the fact that go.mod will resolve all tags to commits because valid tags are not found. This makes troubleshooting extremely hard. Each repo is only compatible with a specific version from another repo (ie client-go kubernetes-vx.x.x needs to match apimachiner kubernetes-vx.x.x). Sometimes things get messed up because of transitive dependencies and commits change and then compilations fails. It is very hard to determine which versions you have are incompatible because they are all random commits.

I've heard many times before that k8s doesn't follow semver and I assume that may be a reason that k8s.io repos aren't tagged as vx.x.x. Whether k8s follows semver or not I don't think really changes things. By applying a tag it will help clarify what the user is looking at but I do not think it will change the behavior of go modules in any way (except client-go, more on that below). So I see this as only helping.

One odd point will be client-go. client-go is the one package from staging/ that has it's own tagging scheme. client-go can continue forward with v12, v13, v14 if it wishes and also apply vx.x.x matching kubernetes. I believe this will work fine. For people that want to use the old versioning scheme of major numbers they can. go modules should prefer the v1.x.x tags because all the client-go tags greater than 1 (v2, v3, etc) are all incompatible modules (the import path is wrong. more info https://research.swtch.com/vgo-import). So even though applying two versioning schemes with tags is odd, I think it will work.

@ibuildthecloud ibuildthecloud added the kind/feature Categorizes issue or PR as related to a new feature. label Oct 31, 2019
@k8s-ci-robot k8s-ci-robot added the needs-sig Indicates an issue or PR lacks a `sig/foo` label and requires one. label Oct 31, 2019
@pohly
Copy link
Contributor

pohly commented Oct 31, 2019

Isn't this a duplicate of #72638?

@liggitt
Copy link
Member

liggitt commented Oct 31, 2019

Isn't this a duplicate of #72638?

No, that is exploring switching to semantic import versioning, which effectively renames all the modules by adding a /v<N> segment after the module name (e.g. k8s.io/client-go/v17). This is proposing adding v1.x.y semver tags to the published component libraries, despite them not following semver w.r.t. go API compatibility.

@liggitt liggitt added area/code-organization Issues or PRs related to kubernetes code organization sig/architecture Categorizes an issue or PR as relevant to SIG Architecture. sig/release Categorizes an issue or PR as relevant to SIG Release. labels Oct 31, 2019
@k8s-ci-robot k8s-ci-robot removed the needs-sig Indicates an issue or PR lacks a `sig/foo` label and requires one. label Oct 31, 2019
@liggitt
Copy link
Member

liggitt commented Oct 31, 2019

I've heard many times before that k8s doesn't follow semver and I assume that may be a reason that k8s.io repos aren't tagged as vx.x.x.

That is correct.

By applying a tag it will help clarify what the user is looking at but I do not think it will change the behavior of go modules in any way (except client-go, more on that below). So I see this as only helping.

I'm really hesitant to apply v1.x.y tags. We could consider applying v0.x.y tags. That would accurately reflect the current lack of go API stability guarantees between releases, but would be a usability improvement over random date/time SHAs for people trying to understand their go.mod files.

For example, kubernetes v1.16.1 could correspond to k8s.io/{api,apimachinery,apiserver,...} v0.16.1.

One odd point will be client-go.

Yes :-/

client-go can continue forward with v12, v13, v14 if it wishes and also apply vx.x.x matching kubernetes. I believe this will work fine. For people that want to use the old versioning scheme of major numbers they can.

go1.13 strictly enforces module-aware components with major versions >=2.x using semantic import versioning. Until client-go switches to semantic import versioning, it cannot add new major version tags (xref #84372). Once it does, it can no longer use v0.x.y or v1.x.y tags.

@liggitt
Copy link
Member

liggitt commented Oct 31, 2019

cc @sttts

@dims
Copy link
Member

dims commented Oct 31, 2019

cc @nikhita

@sttts
Copy link
Contributor

sttts commented Oct 31, 2019

I like the v0.17.0 approach.
-1 for v1.17.0 as we don't follow the compatiblity conventions it implies.

Would like to see some way to experiment with that, maybe with a tag rewriting goproxy if that is feasible.

@ibuildthecloud
Copy link
Contributor Author

-1 for v1.17.0 as we don't follow the compatiblity conventions it implies.

Can somebody explain what the harm is here? I would like to hear the next level of detail beyond "we don't follow" semver. Very, very few projects follow semver properly so you really are no worse or better than the rest of the ecosystem. Basically v0.x and v1.x will function the same from the go modules perspective. So I'm fine if you want to go with v0.x but don't fully the need for it. I can't think of a scenario in which v0.x will do something better for the consumer than v1.x.

go1.13 strictly enforces module-aware components with major versions >=2.x using semantic import versioning. Until client-go switches to semantic import versioning, it cannot add new major version tags (xref #84372). Once it does, it can no longer use v0.x.y or v1.x.y tags.

I think I'm a bit confused here. I'm proposing client-go never switches to semantic import versioning. The v11, v12 tags can exist solely for people using something other than go modules. client-go w/ go modules would use v0.x or v1.x.

@liggitt
Copy link
Member

liggitt commented Nov 1, 2019

I can't think of a scenario in which v0.x will do something better for the consumer than v1.x.

It accurately represents the go API guarantees currently being made.

The v11, v12 tags can exist solely for people using something other than go modules. client-go w/ go modules would use v0.x or v1.x.

Intentionally adding tags that don't work with go tooling doesn't seem like a good idea (go get k8s.io/client-go@v12.0.0 would fail with go1.13+, for example).

Would like to see some way to experiment with that, maybe with a tag rewriting goproxy if that is feasible.

I spent some time experimenting with a module structured similarly to how client-go would end up (with non-module-aware major version tags greater than 2.x, module-aware v0.x and v1.x tags, and non-semver tags) in https://github.com/liggitt/gomodule_example_a/releases

  1. go get without a version auto-selects the latest semver tag for that import path (the latest semver tag among v0.x tags, v1.x tags, or v2+ tags that are not module-aware). For this example, that is v3.1.0+incompatible. For client-go, that would be v11.0.0+incompatible. (This is also the version selected by auto-upgrade, e.g. go get -u).

    $ go get github.com/liggitt/gomodule_example_a
    $ go mod tidy
    $ grep require go.mod
    require github.com/liggitt/gomodule_example_a v3.1.0+incompatible
    
  2. go get with a semver tag works as expected and preserves the tag in the go.mod file:

    $ go get github.com/liggitt/gomodule_example_a@v0.1.0
    go: finding github.com/liggitt/gomodule_example_a v0.1.0
    go: downloading github.com/liggitt/gomodule_example_a v0.1.0
    go: extracting github.com/liggitt/gomodule_example_a v0.1.0
    $ go mod tidy
    $ grep require go.mod
    require github.com/liggitt/gomodule_example_a v0.1.0
    
    $ go get github.com/liggitt/gomodule_example_a@v1.1.0
    go: finding github.com/liggitt/gomodule_example_a v1.1.0
    go: downloading github.com/liggitt/gomodule_example_a v1.1.0
    go: extracting github.com/liggitt/gomodule_example_a v1.1.0
    $ go mod tidy
    $ grep require go.mod
    require github.com/liggitt/gomodule_example_a v1.1.0
    
  3. go get with a non-semver tag that resolves to a sha that is also tagged with a semver tag places the semver tag in the go.mod file. For this example, that is v1.1.0. For client-go that would mean go get k8s.io/client-go@kubernetes-v.17.0 would place v0.17.0 in the go.mod file.

    $ go get github.com/liggitt/gomodule_example_a@non-semver
    go: finding github.com/liggitt/gomodule_example_a non-semver
    go: downloading github.com/liggitt/gomodule_example_a v1.1.0
    go: extracting github.com/liggitt/gomodule_example_a v1.1.0
    $ go mod tidy
    $ grep require go.mod
    require github.com/liggitt/gomodule_example_a v1.1.0
    
  4. go get with a particular SHA that is not tagged works as expected by finding the closest ancestor semver tag:

    go get github.com/liggitt/gomodule_example_a@8056a35271fd
    go: finding github.com/liggitt/gomodule_example_a 8056a35271fd
    go: downloading github.com/liggitt/gomodule_example_a v1.1.1-0.20191101134122-8056a35271fd
    go: extracting github.com/liggitt/gomodule_example_a v1.1.1-0.20191101134122-8056a35271fd
    $ go mod tidy
    $ grep require go.mod
    require github.com/liggitt/gomodule_example_a v1.1.1-0.20191101134122-8056a35271fd
    

In summary, adding v0.x.y tags does not fix version auto-selection or auto-upgrade, but does significantly improve usability of the resulting go.mod files when choosing a specific version.

I plan to update the go modules KEP with this evolution.

@pohly
Copy link
Contributor

pohly commented Nov 1, 2019

Isn't this a duplicate of #72638?
No, that is exploring switching to semantic import versioning, which effectively renames all the modules by adding a /v segment after the module name (e.g. k8s.io/client-go/v17). This is proposing adding v1.x.y semver tags to the published component libraries, despite them not following semver w.r.t. go API compatibility.

It also proposed to "have the tags as 13.0.1" or something similar, so it is also about semantic versioning. But as you noted, when tagging with vX.Y.Z with X >= 2 then one must use semantic imports, otherwise go mod refuses to import it. The tagging with v0.x.y will be simpler and indeed a better match for the lack of API stability.

@liggitt
Copy link
Member

liggitt commented Nov 1, 2019

opened kubernetes/enhancements#1350 to propose adding v0.x.y tags

@lavalamp
Copy link
Member

lavalamp commented Nov 1, 2019

I think it's super ironic that client-go, the one place we actually tried to be semver compliant, is the thing that's hardest to fix :(

@liggitt
Copy link
Member

liggitt commented Nov 1, 2019

Yup

@liggitt
Copy link
Member

liggitt commented Dec 11, 2019

Starting in v1.17.0+, for Kubernetes v1.x.y, published repos have corresponding v0.x.y semver tags

/close

@k8s-ci-robot
Copy link
Contributor

@liggitt: Closing this issue.

In response to this:

Starting in v1.17.0+, published repos have corresponding v0.x.y semver tags

/close

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/code-organization Issues or PRs related to kubernetes code organization kind/feature Categorizes issue or PR as related to a new feature. sig/architecture Categorizes an issue or PR as relevant to SIG Architecture. sig/release Categorizes an issue or PR as relevant to SIG Release.
Projects
None yet
Development

No branches or pull requests

7 participants