From 49d17955d10e8c632266d995a639314a259ed99a Mon Sep 17 00:00:00 2001 From: Aaron Craelius Date: Wed, 27 Apr 2022 11:03:34 -0400 Subject: [PATCH 1/4] docs(): add ADR 053 Go Module Refactoring --- docs/architecture/README.md | 1 + .../adr-053-go-module-refactoring.md | 101 ++++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 docs/architecture/adr-053-go-module-refactoring.md diff --git a/docs/architecture/README.md b/docs/architecture/README.md index 18ed71c2df6a..fecaa118be93 100644 --- a/docs/architecture/README.md +++ b/docs/architecture/README.md @@ -83,3 +83,4 @@ When writing ADRs, follow the same best practices for writing RFCs. When writing - [ADR 044: Guidelines for Updating Protobuf Definitions](./adr-044-protobuf-updates-guidelines.md) - [ADR 047: Extend Upgrade Plan](./adr-047-extend-upgrade-plan.md) +- [ADR 053: Go Module Refactoring](./adr-053-go-module-refactoring.md) diff --git a/docs/architecture/adr-053-go-module-refactoring.md b/docs/architecture/adr-053-go-module-refactoring.md new file mode 100644 index 000000000000..73f9175a7d7d --- /dev/null +++ b/docs/architecture/adr-053-go-module-refactoring.md @@ -0,0 +1,101 @@ +# ADR 053: Go Module Refactoring + +## Changelog + +* 2022-04-27: First Draft + +## Status + +DRAFT + +## Abstract + +The current SDK is built as a single monolithic go module. This ADR describes +how we refactor the SDK into smaller independently versioned go modules +for ease of maintenance. + +## Context + +Go modules impose certain requirements on software projects with respect to +stable version numbers (anything above 0.x) in that [any API breaking changes +necessitate a major version](https://go.dev/doc/modules/release-workflow#breaking) +increase which technically creates a new go module +(with a v2, v3, etc. suffix). + +[Keeping modules API compatible](https://go.dev/blog/module-compatibility) in +this way requires a fair amount of fair thought and discipline. + +The Cosmos SDK is a fairly large project which originated before go modules +came into existence and has always been under a v0.x release even though +it has been used in production for years now, not because it isn't production +quality software, but rather because the API compatibility guarantees required +by go modules are fairly complex to adhere to with such a large project. +Up to now, it has generally been deemed more important to be able to break the +API if needed rather than require all users update all package import paths +to accommodate breaking changes causing v2, v3, etc. releases. This is in +addition to the other complexities related to protobuf generated code that will +be addressed in a separate ADR. + +Nevertheless, the desire for semantic versioning has been [strong in the +community](https://github.com/cosmos/cosmos-sdk/discussions/10162) and the +single go module release process has made it very hard to +release small changes to isolated features in a timely manner. Release cycles +often exceed six months which means small improvements done in a day or +two get bottle-necked by everything else in the monolithic release cycle. + +## Decision + +To improve the current situation, the SDK is being refactored into multiple +go modules within the current repository. There has been a [fair amount of +debate](https://github.com/cosmos/cosmos-sdk/discussions/10582#discussioncomment-1813377) +as to how to do this, with some developers arguing for larger vs smaller +module scopes. There are pros and cons to both approaches (which will be +discussed below in the [Consequences](#consequences) section), but the +approach being adopted is the following: +* a go module should generally be scoped to a specific coherent set of +functionality (such as math, errors, store, etc.) +* when code is removed from the core SDK and moved to a new module path, every +effort should be made to avoid API breaking changes in the existing code using +aliases and wrapper types (as done in https://github.com/cosmos/cosmos-sdk/pull/10779 +and https://github.com/cosmos/cosmos-sdk/pull/11788) +* new go modules should be moved to a standalone domain (`cosmossdk.io`) before +being tagged as `v1.0.0` to accommodate the possibility that they may be +better served by a standalone repository in the future +* all go modules should follow the guidelines in https://go.dev/blog/module-compatibility +before `v1.0.0` is tagged and should make use of `internal` packages to limit +the exposed API surface + +## Consequences + +### Backwards Compatibility + +If the above guidelines are followed to use aliases or wrapper types pointing +in existing APIs that point back to the new go modules, there should be no or +very limited breaking changes to existing APIs. + +### Positive + +* standalone pieces of software will reach `v1.0.0` sooner +* new features to specific functionality will be released sooner + +### Negative + +* there will be more go module versions to update in the SDK itself and +per-project, although most of these will hopefully be indirect + +### Neutral + +## Further Discussions + +Further discussions are occurring in primarily in +https://github.com/cosmos/cosmos-sdk/discussions/10582 and within +the Cosmos SDK Framework Working Group. + +## References + +* https://go.dev/doc/modules/release-workflow +* https://go.dev/blog/module-compatibility +* https://github.com/cosmos/cosmos-sdk/discussions/10162 +* https://github.com/cosmos/cosmos-sdk/discussions/10582 +* https://github.com/cosmos/cosmos-sdk/pull/10779 +* https://github.com/cosmos/cosmos-sdk/pull/11788 \ No newline at end of file From b684385b120275a5b249b6fdbb898808589acf7b Mon Sep 17 00:00:00 2001 From: Aaron Craelius Date: Wed, 27 Apr 2022 11:04:13 -0400 Subject: [PATCH 2/4] update to PROPOSED --- docs/architecture/adr-053-go-module-refactoring.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/architecture/adr-053-go-module-refactoring.md b/docs/architecture/adr-053-go-module-refactoring.md index 73f9175a7d7d..a5216c779596 100644 --- a/docs/architecture/adr-053-go-module-refactoring.md +++ b/docs/architecture/adr-053-go-module-refactoring.md @@ -6,7 +6,7 @@ ## Status -DRAFT +PROPOSED ## Abstract From e458b7175b42b11448667a955c14130b2136e85c Mon Sep 17 00:00:00 2001 From: Aaron Craelius Date: Wed, 27 Apr 2022 11:07:58 -0400 Subject: [PATCH 3/4] update --- docs/architecture/adr-053-go-module-refactoring.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/architecture/adr-053-go-module-refactoring.md b/docs/architecture/adr-053-go-module-refactoring.md index a5216c779596..8eabfcf84f6f 100644 --- a/docs/architecture/adr-053-go-module-refactoring.md +++ b/docs/architecture/adr-053-go-module-refactoring.md @@ -64,6 +64,10 @@ better served by a standalone repository in the future * all go modules should follow the guidelines in https://go.dev/blog/module-compatibility before `v1.0.0` is tagged and should make use of `internal` packages to limit the exposed API surface +* the new go module's API may deviate from the existing code where there are +clear improvements to be made or to remove legacy dependencies (for instance on +amino or gogo proto), as long the old package attempts +to avoid API breakage with aliases and wrappers ## Consequences From 8decc91a7325d13c18bb65415c92ca8b7ffb5488 Mon Sep 17 00:00:00 2001 From: Aaron Craelius Date: Wed, 27 Apr 2022 11:27:06 -0400 Subject: [PATCH 4/4] update --- docs/architecture/adr-053-go-module-refactoring.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/architecture/adr-053-go-module-refactoring.md b/docs/architecture/adr-053-go-module-refactoring.md index 8eabfcf84f6f..9093ae9d9013 100644 --- a/docs/architecture/adr-053-go-module-refactoring.md +++ b/docs/architecture/adr-053-go-module-refactoring.md @@ -68,6 +68,10 @@ the exposed API surface clear improvements to be made or to remove legacy dependencies (for instance on amino or gogo proto), as long the old package attempts to avoid API breakage with aliases and wrappers +* care should be taken when simply trying to turn an existing package into a +new go module: https://github.com/golang/go/wiki/Modules#is-it-possible-to-add-a-module-to-a-multi-module-repository. +In general, it seems safer to just create a new module path (appending v2, v3, etc. +if necessary), rather than trying to make an old package a new module. ## Consequences