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

Semantic or other meaningful versioning of the GnoVM #2755

Closed
wyhaines opened this issue Sep 3, 2024 · 14 comments
Closed

Semantic or other meaningful versioning of the GnoVM #2755

wyhaines opened this issue Sep 3, 2024 · 14 comments

Comments

@wyhaines
Copy link
Contributor

wyhaines commented Sep 3, 2024

Description

Currently, the only way for someone to determine what version of the gnovm they are using is to look at the git commit hash of whatever version they have installed (and hope that they have not updated their repository in the time since the last installation). This provides a subpar developer experience for any issue where it's useful to know what version one is using, particularly as we advance towards mainnet and the prospect of onboarding larger numbers of people.

So far as I have been able to tell, there is currently no in-code data structure that contains any sort of a meaningful version. Adding something would make is straightforward for someone to then implement a gno version subcommand, and it would make it a lot easier for the Playground to make very clear to users which version of the gnovm it is using.

I think, again, that this is important before mainnet, as it will allow quality of life features to be implemented to help people to avoid, or at least easily identify and understand version-mismatch related problems.

@thehowl
Copy link
Member

thehowl commented Sep 3, 2024

there's a slightly out-of-date PR to create this: #2477

the ideas there are mostly still valid; but we officially started having a 0.1.0 with the launch of test4. we'll likely do a similar release (0.2.0) for test4.5 (ie. the re-launch).

@wyhaines
Copy link
Contributor Author

wyhaines commented Sep 3, 2024

I would suggest some sort of Git workflow automation so that, essentially, every commit to master bumps the patch level version by 1, automatically.

It's completely fine to have really large patch versions. There is nothing wrong with v0.3.387, for example. However, imagine that someone followed the Getting Started instructions on docs.gno.land, and, according to their gno executable they have version 0.1.0. A week later I update my local installation with a rebuild of everything, also from the same repo, and it also reports a version of 0.1.0. However, in between when the other person did the install and when I did the install, there were actually a bunch of commits. Both of our installations would report that they are v0.1.0, but they would not actually be the same at all.

Now, that said, I'll go read through that whole PR in detail so that I can absorb the whole discussion, see the suggested implementation, etc.... Thanks for linking to it. I searched issues for anything that mentioned "version" to see if I could find prior discussion, but I didn't search existing pull requests.

@leohhhn leohhhn changed the title Semantic or other meaninful versioning of the gnovm Semantic or other meaningful versioning of the GnoVM Sep 4, 2024
@moul
Copy link
Member

moul commented Sep 21, 2024

Please avoid creating artificial versioning. Version numbers like 0.1.0 or 0.2.0 are not particularly relevant for test4 or test5, which should not be tied to specific tags. These testnets should function with clear goals, whether they involve no significant code changes (e.g., testing different onboarding methods for validators) or multiple substantial changes.

We should maintain one branch for each testnet and use versioning specific to each, such as test4.0 and test4.1.

The focus should be on whether the code is up to date or not. Partial support is not planned; our priority should be on improving the master branch. Versioning discussions can be postponed until closer to the launch.

Using versioning like v0.3.387, which indicates 387 commits different from v0.3.0, clutters the git tag experience on both our terminal and GitHub.

This command provides a concise string combining the last tag, the number of commits since, and a hash, allowing explicit access to GitHub:

$ git describe --tags
v0.2.0-31-g9897b6674

We can update the Makefile with the following:

VCS_REF ?= `git rev-parse --short HEAD`
VERSION ?= `git describe --tags --always`
LDFLAGS ?= -ldflags="-X github.com/gnolang/gno/build.VcsRef=$(VCS_REF) -X github.com/gnolang/gno/build.Version=$(VERSION)"

@thehowl
Copy link
Member

thehowl commented Sep 25, 2024

Versioning meeting proposal

present @zivkovicmilos @thehowl @ajnavarro @wyhaines @aeddi @sw360cab

  • Software version: git describe --tags
    • used in make install, github releaser artifacts, other places
  • Testnet versioning: <master-version>-test5.0
    • for instance: v0.3.0-test5.0, patch to test5 is v0.3.0-test5.1. This can be used as the version on external repositories in the go.mod
    • Instruct dependabot on related repositories to understand testnet syntax like this
  • master versioning
    • Requirement: set up the CI script to "define" a breaking change (if it changes, it's a breaking change)
    • @zivkovicmilos after that to create a version every two weeks until mainnet, bumping the minor or patch version depending on whether the script was changed

Why "prereleases" for testnet?

@moul
Copy link
Member

moul commented Sep 25, 2024

Software version: git describe --tags

💯

Testnet versioning: -test5.0

Starting testnet versions with semantic versioning will signal to tools that they can be installed automatically. A testnet branch diverges from the master branch; it functions like a fork and can have dedicated commits. In other words, it should only be checked out intentionally, not by mistake or due to a tool's decision.

Instruct dependabot on related repositories to understand testnet syntax like this

Which tool needs to know a testnet Git hash?

Requirement: set up the CI script to "define" a breaking change (if it changes, it's a breaking change)
@zivkovicmilos after that to create a version every two weeks until mainnet, bumping the minor or patch version depending on whether the script was changed

It seems like a premature non-optimization.

Before the launch, we want to support only the master branch. After the launch, we will focus on creating meaningful releases for users; these will likely be manual and irregular.

The system you are trying to implement appears to be generating meaningless git tags and will require significant development, operational, and support time.


What if we simply expect people to configure their tools and makefiles to update to master?

@thehowl
Copy link
Member

thehowl commented Sep 25, 2024

In other words, it should only be checked out intentionally, not by mistake or due to a tool's decision.

dependabot doesn't even understand pre-releases

go modules use pre-releases on @latest only if there is no tagged release: https://go.dev/ref/mod#version-queries

i don't think there are other tools that would select pre-releases by default?

The system you are trying to implement appears to be generating meaningless git tags and will require significant development, operational, and support time.

i get that your POV is that there should only be the PL and the master branch, and users should only use that. However, testnets exist and are an effort that the team is undertaking in order to create tools and systems that rely on a "long-running" network. I'm with you though that our references should say "use master, versions are not useful to you, deploy on the portal loop".

I see these points in the exercise:

  • starting to define what is a breaking change, in a way that will be useful for us when we launch 1.0.0 where we won't have to start from absolute scratch.
  • giving us a concise version number to talk about upgrades when communicating among the core team and externally.
    • for instance, I could clearly communicate how the upgrade to test4 was working by referencing 0.1.1 and 0.2.0; instead of 1543-1fe3fe7 (as an example). They have a meaning because we use them in versions and upgrades and operations and docker tags, and they're simple enough that they can be typed from memory rather than copying and pasting. A version signals a point which is meaningful for any kind of development and deployment; and insisting on "it is a fork" would IMO mean having to instead devote development time to build the system around following a specific branch.
  • giving us an easy way to see version numbers that are easy to compare also in go.mod files and dependabot alerts; rather than meaningless timestamps + git hashes.

we won't have automated releases, and if all goes to plan there'll be < 10 releases from here to the release of 1.0.0. We can adapt this to be more or less frequent based on usefulness. We give no expectation of support on previous releases, but instead as part of this proposal we're starting to have clear version strings in our binaries that we can talk about and easily compare against our master branch.

@moul
Copy link
Member

moul commented Sep 25, 2024

dependabot doesn't even understand pre-releases

Great.

starting to define what is a breaking change, in a way that will be useful for us when we launch 1.0.0 where we won't have to start from absolute scratch.

It's premature.

In the future, we will have two versioning strategies:

  • One for the network, which will not be managed by "breaking/non-breaking" but simply by whether we want to make a new deployment.
  • The other will involve our libraries when we start extracting components from the monorepo. At that point, we will adopt different versioning strategies. The new goal will shift from managing network releases to providing developers with a way to import our libraries.

Who needs to define "what constitutes a breaking change", today?

  • PL, gnodev -> you're on master, or you're not anymore.
  • Testnets -> you're using one of the git tags, or you're on the testX branch with a few new unreleased commits.

Testnet tags do not target the master branch but rather the testX branches. We should continue the approach we used for test2.x and test3.x. I’m not sure what you did with test4.x, but before that, it was simple, effective, and clear.

for instance, I could clearly communicate how the upgrade to test4 was working by referencing 0.1.1 and 0.2.0

I was the one uprading the previous testnets, and what I can say is that we don't "hotfix" a tesnet by following the master versions; a testnet branch is only clean the day we create it; after it contains commits that are specific to this branch, and there is no guarantee that you will merge a full master git tag on your testnet branch; chances are that you'll just cherry-pick a few commits.

Every testnet tag, testX.Y (which will be rare), should include upgrade notes that may be empty if we're fortunate. The diff is automatically provided by Git by comparing textX.Y and testX.Y-1.

giving us an easy way to see version numbers that are easy to compare also in go.mod files and dependabot alerts; rather than meaningless timestamps + git hashes.

A timestamp and git hash provide more meaningful information than an outdated git tag for determining whether you're up-to-date with master or not.


What if:

  • We remove the existing semver tags that are causing issues (people not against master), and expect people to configure Dependabot to update against the master branch?
  • We keep the textX branches and testX.Y git tags for testnets, like test2 and test3, so testnet tool writers can utilize them.

@moul
Copy link
Member

moul commented Sep 25, 2024

The alternative I see is to align with your approach and accept that we should not expect Git tags to be meaningful for deployments. We use them for various developer-related reasons. When we want to manage network releases, we will need to move away from the built-in Git tag system and create a separate solution.

I believe this can work, but we should clarify from the beginning that our focus is on creating Git tags related to "the repo" rather than "the product." I am starting to be open to this.

@moul
Copy link
Member

moul commented Sep 25, 2024

We should discourage working on non-master branches unless necessary (such as tools). These semver tags create an unnecessary layer of versioning that is neither master nor a specific testnet; it’s just "something."

I believe I have given enough warnings for us to pursue what we think is best while considering my concerns. Therefore, I expect us to limit the time spent on tools, processes, and the additional support generated by this new collection of "something."


i get that your POV is that there should only be the PL and the master branch, and users should only use that. However, testnets exist and are an effort that the team is undertaking in order to create tools and systems that rely on a "long-running" network. I'm with you though that our references should say "use master, versions are not useful to you, deploy on the portal loop".

Are you really claiming that what you wrote represents my point of view and that I essentially don't care about people who need long-running testnets?

@moul
Copy link
Member

moul commented Sep 25, 2024

CleanShot 2024-09-25 at 20 36 02

The first five tags are ones I created myself, and they all correspond to a testnet release. They are meaningful.

All the other tags are meaningless. Prove me wrong.

@thehowl
Copy link
Member

thehowl commented Sep 26, 2024

There has been a long discussion on Signal following @moul's comments. Here's the tl;dr plan of action:

  • remove all tags except chain/*
    • enables us to use dependabot automatically on master; same as go.mod's @latest, so that's good and aligns with a master-first philosophy. (note, we'll rename 0.1.0, 0.1.1, 0.2.0 to chain/test4.{0,1,2})
    • this will break devx's workflows, but they're welcome to have their own tags/system; or keep their current and wait to update when we launch 1.0.0
  • software version, written in binaries and result of gno version, etc: branch.N+hash, eg. master.1624+e872fa, N = len(commits)
    • git describe is not useful on master. i tried removing all tags and it was just returning chain/test3.0-N-Hash.
    • notable exception: chain branches - git describe makes sense for versions in chain/test3 branch, for instance
  • our tooling will update to master, unless it makes sense for it to lock-in to a specific chain version, where then they can use tags/branches.
  • eventually, master will version on 1.0.0 on mainnet. later semver version = upgrade, improvement of all previous versions. (TODO: patch versioning happens on master? or maintenance branches?)

why:

  • manual versioning creates manual overhead in a time we don't need it, and we want most of our tools to work off of master for now; since it's the only "version" we support
  • chains should have their own versioning, as they are "products" unto themselves. nobody should really be locking into these versions, unless it's for specific deployments or testnet-dependent tools like gnoscan.

I'll remove all tags starting with v next monday, and move the test4-related tags to chain/test4.X tags.

Discussion with Manfred - for more context

Manfred:
Your claim that I could ignore or don’t care about people needing long-term network is 👎

This topic is going too far; we had something simple, including tags for testnets that I did create myself; testnets that I launched for such people.

You all want to create something that is nonsense with semver on our monorepo while we should focus on master or testnet

And now I’m the one who don’t want to support people who need a long running network ?

What’s wrong with https://github.com/gnolang/gno/releases/tag/chain%2Ftest3.2?
8:34 PM

---

Morgan:
>Your claim that I could ignore or don’t care about people needing long-term network is 👎
No, sorry it came out that way, but I'm frustrated by the difficulty in reaching consensus without someone feeling unconsidered, and thus from not being able  understanding your POV properly when it seems to me to come from a position that is stuck on "it's not meaningful" when the versions have been useful to coordinate upgrades with multiple validators and have been useful to update software with automated tools like dependabot which we didn't have to change
9:21 PM

---

Manfred:
They should coordinate on test tags not master semver

That’s the wrong thing

Test4 didn’t use the simple way of aligning on tags

And we expect a vanity tag on master to be meaningful

What’s meaningful is master to be master and test tags to match a test release

Master semver, on the monorepo, before mainnet is meaningless; and create an unnecessary layer of vanity versionnibg

It creates something new that doesn’t reflect anything specific

Even if we go with semver on master because I want to give up on this

You should use testnet tags that aren’t related with semver

Because else; they will either limit, or lie

Testnets should not be linked with semver or master

Master is master; our main target

The new strange thing about semver is premature and promote not using master; we can eventually go in that direction but at:
- no time cost (premature is already a problem; but if you add procrastination on top of it; it becomes a joke)
- no support of these tags (we support master and testnet branches)
9:30 PM

---

Morgan:
But it's not uncommon to have patch versions be on separate branches for maintenance; that's I think also the part I don't understand
So if a testnet starts from a commit on master, then branches off into something else, it's like a 1.3.0 with a maintenance branch which publishes patch versions
And since tooling understands it properly, and we can lock thing into receiving updates as long as it has the same minor version, I see using semver as being better than using chain/ prefix

There are dangers and problems and "lack of meaning" you refer to that maybe I simply don't have experience enough with long running software to understand and to agree with, but that's where I struggle with it

---

Manfred:
it's not uncommon to have patch versions on separate branch -> yes; but:
1. that's what I suggest too :) testX.Y to be git tag on separate testX branch
2. we're not a common software, we're maintaining testnets that will receive commits that will eventually never be merged on master; or cherry-pick things; just remember gnochess; gnochess was a fork of the gno repo, in a branch; testnets are like gnochess; after the branch creation, there is no sense to keep the master semver into account, because we just cherry-pick things in the two directions

what makes me even considering this issue a problem is exactely because "it's not uncommon" or in other words "google is doing it, we should do it"

there are multiple topics and it's important to separate them, let's speak about testnets, and then semvers

testnets arent master, they are independent, standalone lifecycle, they DO need git branches for this; and they DO need git tags, because several people needs to coordinate both on validators things and also on tool writing

things were good for test1, 2, 3

don't you agree that things were good for test 1,2,3?
9:43 PM

---

Morgan:
 my problem is I don't get why I need to have my own versioning with chain/testX.Y when I have the rest of my tools that understand vN.X.Y without added config

---

manfred:
because chain/text4.5 isn't the evoluion of test3.2

test 3.3 is the evoluation of test3.2

test 4.5 is the evoluation of test4.4

test 4.0 isn't the evolution of test 3.2

it's not semver

each testnet is a fork

think about gnochess

let's say you started doing your stuff on the gnochess branch at v1.2.3

do you consider that v1.8.9 is the evolution of gnochess?

no, v1.8.9 is the volution of v1.2.3

gnochess is a fork

you can cherry-pick things in the two directions

but chain/testX.Y can basically see a relationship on "Y, Y+1"

but not on X, and X+1

it's not semver compatible

and even if it were semver compatible

it's not compatible with master's semver

when i say that it's either a limitation or a lie; it's because i don't see any way to not limit ourselves or lying if we expect testnets to be linked with master's semver

maybe it was the case for your unique experience of release a new version for test4

it was the case 0 time for all the previous releases

and it wasn't the case for gnochess too
9:47 PM

---

Manfred:
please, look at test3 branch and tag

and give me a single example where it was a problem for a remote tool

imo you're confused between testnets and master

testnets were clear thanks to the tags I did on test2 and 3

playground can have an explcit git tag for each testnet and follow the upgrades

master is different

becuase people weren't trying to use git describe or something and they didn't tried to make master release

so we created a notion of nightlies

then of manual semver

and now we consider semi-automated semver

but this discussion shouldn't be releated with testnets

if ever we impelment semver on master; i don't see why a tool would prefer listing 35 differnet semver and remember that this one is test3, test4, test5; instead of using test3,4,5.{max} both for humans in the html select and for git

the problem with test4 is that it didn't use this method and instead believed that having a semver was a good idea

it created a limitation

for instance, we've PRs on master that are about adding new validators on test4 AFTER the initial release of test4

here, it's not a lie, but a limitation

because master becomes where we hotfix our testnets

test3 was hotfixed on test3, then some commits were extracted on master with or without subtle changes to make them more generic

this is the way
9:56 PM

---

Morgan:

What's your take on what we should do with tooling

Just dependabot with master updates?
9:57 PM

---

Manfred:

are you talking about gnoscan?

like "tools that NEEDS to work on testnets"?
9:57 PM

---

Morgan:

tx-indexer, tx-archive, gnoblog-cli, [...]
9:57 PM

---

Manfred:

tx-indexer should match master by default; and we can create git tag that match the version that was compatible with the release of a testnet; and under rare conditions, we can create dedicated branches; but i think we won't need to; just git tag at the same date (that can be done retroactively) WHEN it's needed

tx-archive is a remote tool?

should not

should be in the main repo

let's move it to the main repo

gnoblog-cli -> should target master

what else?

gnoscan -> more complex

i don't think it's just a problem about "git tagging", but more about how they can manage multiple verisons in a single binary

i'm not a JS expert, but I think that I would just target master and keep some hardcoded compatibilty files for testnets, that I keep up to date manually

or maybe i would do something with docker ontainers matching each version; and make an orchestrator who call the same command, but on versionnned binaries that match the corresponding testnet

i really don't think that the challenge is about how we manage git

@sw360cab
Copy link
Contributor

sw360cab commented Oct 2, 2024

What impact will this have on the release process in goreleaser which relies on incremental semver?

https://goreleaser.com/limitations/semver/

@thehowl
Copy link
Member

thehowl commented Oct 23, 2024

I renamed/removed all the tags.

Let's see what happens.

@thehowl
Copy link
Member

thehowl commented Oct 23, 2024

Closing in favour of #3005.

Let's see about external tools depending on gno - maybe we can update the go version using GOPROXY=direct go get -v github.com/gnolang/gno@upgrade or @latest - not sure. Or we might need to retract versions; but that will also be a separate issue.

@thehowl thehowl closed this as completed Oct 23, 2024
@github-project-automation github-project-automation bot moved this from 📥 Inbox to ✅ Done in 😎 Manfred's Board Oct 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Archived in project
Development

No branches or pull requests

5 participants