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
[RFC] Setup a way to consistently manage go versions across scripts and go.mods #17876
Conversation
a260bce
to
7ae33c3
Compare
source ./scripts/test_lib.sh | ||
|
||
TARGET_GO_VERSION="${TARGET_GO_VERSION:-"$(cat "${ETCD_ROOT_DIR}/.go-version")"}" | ||
find . -name 'go.mod' -exec go mod edit -toolchain=go${TARGET_GO_VERSION} {} \; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are three options,
- only sync go line, e.g.
go 1.22.2
; - only sync toolchain line, e.g.
toolchain go1.22.2
; - sync both go and toolchain lines.
No matter which way we select, it will always use the highest go version by default.
For simplicity, can we go with option 1?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ahrtr, if I understand correctly, the issue I see with option 1 and 3 is that whenever we allow bumping the go
directive, we are also forcing developers of etcd and other projects that import etcd modules to bump their versions. From https://go.dev/doc/toolchain:
the go line sets the minimum required Go version necessary to use a module or workspace.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it's true. It's OK to go for option 2. But please also see my next related comment #17876 (comment)
for mod in $(find . -name 'go.mod'); do | ||
toolchain_version="$(go mod edit -json ${mod} | jq -r .Toolchain)" | ||
if [[ "go${target_go_version}" != "${toolchain_version}" ]]; then | ||
log_error "go toolchain directive out of sync for ${mod}, got: ${toolchain_version}" | ||
out_of_sync="true" | ||
fi | ||
done |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The go
lines in all etcd's go.mod
files are also automatically bumped if any etcd's dependency bumped its go version. Should we also verify that the version in go lines
<= .go-version
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ahrtr that's a good point, however I'm not sure what the course of action is once the dependency bump PRs are merged. If a go line
bump occurred and the PR is merged, do we just update the .go-version
file then?
My main concern with allowing dependency bumps to also bump the go line is that it can cause an issue with projects like Kubernetes that import go.etcd.io...
modules. If the go lines of these projects are behind those of the etcd modules, then they will be either forced to bump or they cannot update the dependency till they catch up (kubernetes/kubernetes#123744)
This behaviour won't be an issue in go1.23, but till that is released and we can adopt that, it is risky allowing the go line to be bumped at all, especially from a perspective of Kubernetes consuming etcd. For bumps related to security fixes or bugs that we see in etcd, we should probably discuss what the course of action should be, but we should probably we a little more aware for usual maintenance bumps.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
they cannot update the dependency till they catch up
I think we should follow this.
For main branch, it isn't a problem because usually we keep using the latest go version (e.g. 1.22.2 for now).
For stable releases (3.5 and 3.4 for now), usually we keep using the latest patch of previous minor version (e.g. 1.21.9 for now). Usually, we don't proactively bump dependencies for etcd stable releases unless there are any CVEs or bugs that affect etcd. If bumping a dependency for a stable release leads to the go version being automatically bumped,
- check whether there is an alternative. For example, if both 4.20.6 and 4.21.0 of a dependency resolve a CVE, but 4.20.6 requires go1.21.9 and 4.21.0 requires go 1.22.2, then we bump 4.20.6 for etcd stable releases (3.4/3.5).
- if there is no alternative
- if we have to bump the dependency, then we bump go version for etcd stable releases (3.4/3.5) as well.
- if we don't have to bump the dependency (it's unlikely running into this case), we can hold off for now until we bump go version.
We need to clearly document the behaviour in https://github.com/etcd-io/etcd/blob/main/Documentation/contributor-guide/dependency_management.md#golang-versions
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ahrtr that sounds good, I've added the extra check.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, ack on documenting this.
Please also resolve the workflow failure: We also need to clearly document the behaviour. |
5b0aaa0
to
5f4b46c
Compare
@ahrtr on thinking about this a little more:
This means that automated PRs, if it runs I've also changed the workflow to a presubmit instead of a periodic because now either case should not be allowed to be merged. |
e284a89
to
e41b372
Compare
59416d7
to
229e2fc
Compare
@ahrtr can you PTAL? Thank you! |
63a7a70
to
5b3ec07
Compare
Overall looks good. Could you rebase this PR although github doesn't show any conflict? I see that it's still based on a commit of 2 weeks ago. |
Additionally, provide ability to opt-out of the .go-version and use a custom one via env vars: FORCE_HOST_GO and GO_VERSION. Signed-off-by: Madhav Jivrajani <madhav.jiv@gmail.com>
This commit adds a script to sync the version present in .go-version across all go.mod files as the toolchain directive. As part of that, this commit also modifies go.mod files that did not have synced toolchain directives. Additionally, this also adds a script to verify all toolchain and go directives against the version present in .go-version as follows: (1) The go directive <= version in .go-version (2) The toolchain directive == version in .go-version This script runs as part of the `make verify` target, making it run as a presbumit by default. Signed-off-by: Madhav Jivrajani <madhav.jiv@gmail.com>
5b3ec07
to
f6a35f8
Compare
Done @ahrtr |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work!
Thanks @MadhavJivrajani
Please also consider to update the doc as mentioned in #17876 (comment). It can be resolved in a separate PR.
@@ -36,5 +36,7 @@ run_for_modules run ${GO_CMD} fmt || exit 2 | |||
run_for_module tests bom_fix || exit 2 | |||
bash_ws_fix || exit 2 | |||
|
|||
log_callout "Syncing go toolchain directives" | |||
run ./scripts/sync_go_toolchain_directive.sh || exit 2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would prefer to move subroutines from ./scripts/fix.sh
to makefile targets. As you already have a makefile target sync-toolchain-directive
why not add it as subtarget to fix
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not add it as subtarget to
fix
?
Yes, it's another option. Either way works for me.
We can even breakdown the existing ./script/fix.sh into a couple of Makefile targets
- fix-go-dependency (in which we will run
mod_tidy_fix
and thesync_go_toolchain_directive.sh
) - fix-gofmt
- fix-script-whitespace
It can be discussed & resolved in a separate PR.
Hi @ahrtr @serathius @MadhavJivrajani , do we consider to apply this to library project, like bbolt and raft? since we have discussion about this in bbolt project two days ago. REF: etcd-io/bbolt#747 |
I think YES. Please see #17857 (comment), and please feel free to add comment in the issue. |
This PR does the following:
scripts: default to using .go-version's version for tests and builds
Additionally, provide ability to opt-out of the .go-version and use a
custom one via env vars: FORCE_HOST_GO and GO_VERSION.
.*: sync go toolchain version and add ability to verify versions
This commit adds a script to sync the version present in .go-version
across all go.mod files as the toolchain directive. As part of that,
this commit also modifies go.mod files that did not have synced toolchain
directives.
Additionally, this also adds a script to verify all toolchain and go
directives against the version present in .go-version as follows:
(1) The go directive <= version in .go-version
(2) The toolchain directive == version in .go-version
The make target for this script is run as part of
make verify
which will automatically be run as a presubmit./assign @ahrtr @jmhbnz @serathius