-
Notifications
You must be signed in to change notification settings - Fork 59
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
feat(fw|ci): add EEST versioning to framework #443
base: main
Are you sure you want to change the base?
feat(fw|ci): add EEST versioning to framework #443
Conversation
Requires that settings within https://github.com/ethereum/execution-spec-tests/settings/actions, are set to the following: |
The workflow should leave us with a PR to main with something like the following: spencer-tb#38 |
ce5b9c6
to
f685b90
Compare
8fefbcf
to
c5a62ea
Compare
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.
Some comments but looks great overall!
@@ -100,6 +102,7 @@ def fill_info( | |||
self.info["filling-transition-tool"] = t8n.version() | |||
if ref_spec is not None: | |||
ref_spec.write_info(self.info) | |||
self.info["framework-version"] = get_framework_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.
I think we should pass this as a parameter to the filler with type str | None
, and ignore if None
, but the main advantage would be avoid calling get_framework_version
every fixture we need to fill info for, and reusing the data for all tests.
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.
Nice, this could definitely be called only once
description = Ethereum execution client test authoring framework | ||
long_description = file: README.md | ||
long_description_content_type = text/markdown | ||
version = 1.0.0 | ||
version = v2.1.0 |
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.
Oh man, we had not updated this in a long time.
|
||
- name: Set environment variables | ||
run: | | ||
echo "NEW_VERSION=${{ github.event.release.tag_name }}" >> $GITHUB_ENV |
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.
I think the problem is probably going to be that the tag points to a commit that is parent to the commit that the created PR is trying to merge, or I might be misunderstanding something.
Maybe if we do instead a manually triggered workflow that takes the new version number as parameter and does everything, even creating the tag, automatically?
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.
I thought on this a bit. This is true, these changes would create a PR to main after the release. So they would not be included in the release - I am not sure what was going through my mind here. Ideally we do this before the release, so everything is included before we publish.
Following your comment:
Maybe if we do instead a manually triggered workflow that takes the new version number as parameter and does everything, even creating the tag, automatically?
I am thinking we first rename/move CHANGELOG.md
to RELEASE_NOTES.md
, this would now hold all the release notes and changes for every release so far. We then useCHANGELOG.md
as the current log and release notes for what is being worked on. So in a workflow we can simply copy the contents of the changelog to the full set of release notes.
The release process could then be:
-
We update the new changelog file with everything we want to include in the new release notes, including the description. This would be the final manual PR before drafting a new release, where it allows us all a way to review what the release will look like. This PR would be labelled with something like
release-minor
,release-major
orrelease-patch
, such that it can be used to trigger a workflow when merged. -
When this PR is merged it would start the
pre_release.yaml
workflow. This would essentially automate all the relavant changes that have to occur before a release. First the changelog would be copied into the cumulative release notes file, and the changelog template copied into the changelog file. Secondly the version would be automatically bumped withinsetup.cfg
based on major/minor/patch label we applied. This would then create a PR to main (as we are already doing here) allowing us to review these changes quickly. -
When the automated
pre_release.yaml
PR is merged to main, this would then trigger thedraft_release.yaml
workflow. Essentially doing what you suggested. Extract the new version, create/push the new tag with the version, and draft the new release copying the contents within the release notes. We can then review/edit the draft and publish.
What do you think? It should be pretty easy for me to add now - I would add this release flow to the documentation too so its extremely simple to follow. :)
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.
I don't know how easy it would be to detect the PR name but it sounds a bit more complicated from what I had in mind.
With manually trigger I meant to go to https://github.com/ethereum/execution-spec-tests/actions, and under "Workflows", like in this image:
We can create a new workflow that is called "Prepare Release and Tag", which takes the version number here:
Does the automatic commit with all the appropriate changes, and pushes to main (which could be dangerous but we can bail on any minimal error) and then creates the tag that points to the commit that was just pushed.
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.
Really like this! There's two things I'd like to discuss before going into details!
-
This suggestion tightly couples the execution-spec-tests package version with the fixture release version (i.e. they have the same version 🙂 ). This is probably ok, but it's worth briefly discussing whether they should be distinct. This is only relevant if developers start using execution-spec-tests in their packages. Then it could be worth using two semvers: one for fixtures and one the code/api. For fixtures, we should aim (imo) to reserve a major version bump for changes that require client teams to re-work their CI, a minor bump for new tests and a patch for bug-fixes to a test/fixture release. There would often be an overlap, but often a fixture release wouldn't involve a package release. If we couple these, then downstream users of an execution-spec-tests package will have a hard time making sense of versioning.
-
Should EEST use a (popular) Python package to help versioning instead of implementing a custom solution? Couple of examples below.
There's a few reasons I'd suggest to go this route.
i. Keep things "more" standard, instead of a completely custom solution, we would follow the best practices used by a common package. There is no single best practice/package in Python as far as I can tell. But typically, for example, a package would get a__version__
property that can be used within the source code.
ii. I think the version string returned below isn't quite sufficient (see comment below). This could be improved without an external package of course. How about something like the following:
-v2.1.1-g1076c97
- if the current head is a tag (in this casev0.1.1
)
-v2.1.1+2.g1076c97-dev
- if the current head is 2 commits past the last tag (release)
-v2.1.1+2.g1076c97.dirty
- if the current repo status is 2 commits past the last tag and dirty (local edits).
Everything before the+
is a semver; everything after is to be interpreted as "build metadata".iii. Remove custom github actions code/dependency on Github Actions. Would enable creating a release locally on the command-line (or doing a dry run of creating a release for verification purposes).
Examples of versioning packages:
@@ -126,6 +133,14 @@ def pytest_addoption(parser): | |||
help="Path to dump the transition tool debug output.", | |||
) | |||
|
|||
version_group = parser.getgroup("version_info", "Versioning of the EEST framework") | |||
version_group.addoption( | |||
"--version-info", |
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.
How about just...
"--version-info", | |
"--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.
If we use --version
it conflicts with the existing flag from pytest
I assumed thats why we used fill --test-help
instead of fill --help
I can look into a workaround
pytest.exit( | ||
f"'Displaying framework version information'\n" f"> {get_framework_version()}\n" | ||
) |
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.
How about?
pytest.exit( | |
f"'Displaying framework version information'\n" f"> {get_framework_version()}\n" | |
) | |
pytest.exit(get_framework_version()) |
I.e.,
➜ fill --version-info
execution-spec-tests v2.1.0-c5a62ea
instead of
➜ fill --version-info
Exit: 'Displaying framework version information'
> execution-spec-tests v2.1.0-c5a62ea
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.
If we use: pytest.exit(get_framework_version())
We get:
➜ fill --version-info
Exit:
execution-spec-tests v2.1.0-c5a62ea
I figured it would be nice to have a reason for the exit as there is no way of silencing the "Exit:\n"
@@ -67,6 +67,7 @@ lint = | |||
flake8>=6.1.0,<7 | |||
pep8-naming==0.13.3 | |||
fname8>=0.0.3 | |||
GitPython>=3.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.
GitPython>=3.1 |
This needs to be in
[options]
install_requires=
not in
[options.extras_require]
lint =
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.
Whoops! Nice catch
Big fan of this! Versioneer looks ideal for a versioning package :) I would love to discuss 1) & 3) on Wednesday's call, to determine what the best options are together. |
🗒️ Description
Adds versioning to the framework. Uses the assumption that the current version of the framework matches that of the latest release. The full version is denoted as:
execution-spec-tests v2.1.0-1e4ef51
._info
section during filling:fill --version-info
which outputs the following:release.yaml
is added with jobs to perform when a release is published.version
field withinsetup.cfg
.setup.cfg
.main
.🔗 Related Issues
Resolves: #442
Required for: #436
Remaining Todos
Pre-Review
get_framework_version()
elsewhere and not within base spec. (Createdethereum_test_tools/utilities
)Post-Review
✅ Checklist
mkdocs serve
locally and verified the auto-generated docs for new tests in the Test Case Reference are correctly formatted.