feat: implement basic pep440 support
Purpose
Adds PEP440 support as dicussed in #1000, #1018 and #455
Rationale
I added version_compat as a cli flag and setting for branches. I also added PEP440 support, though not completely. Currently not added is support for multiple concurrent version specifiers (e.g. v1.2.3rc4.dev5) and support for epoch specifiers. Local versions have to be set manually via the buildmetadata option. Since the official regex was used, all possible pep440 version specifiers should at least be parsed from the tags. Setting the prerelease-token to one of the supported specifiers and setting as-prerelease makes a release with the token and prerelease version number 1. I have not yet implemented the auto-increase of the prerelease version. version_compat is not yet supported in the GitHub action. Docs are not yet updated.
How did you test?
I tested manually with a small test repository and command line. I have not yet written tests for the new functionality.
How to Verify
ToDo
- [ ] Update Documentation
- [x] Add Github Action parameter
- [ ] Add pep440 specific tests
- [ ] Rename
version_compatto a better name - [ ] Add support for multiple concurrent version specifiers
- [ ] Add support for epoch specifiers
- [ ] Add auto increase for prerelease version
This is not yet ready to be merged. I'll have to write some tests first and some of the tests fail currently. @codejedi365 tell me what you think about this implementation and I'll go ahead writing tests, improving it and adding it to the Actions.
Just a quick reminder @codejedi365 if you can have a quick look at this implementation of pep440 support, so that I know if I should go forward with the implementation.
Sorry for the delay, I was sick and then out of town for a week. Thanks for the reminder.
@lukasbehammer, did you have questions on my feedback?
Ah sorry @codejedi365 . I haven't had much time lately. The earliest time I can do some more is probably around December/January. Though I'll try to fit some minor stuff, like tests etc. in such that it's easier to merge. If you have some time feel free to continue with it.
I changed the existing tests to run with the new version-compat scheme, though I'm not sure how to implement the tests for the pep440 compatibility. Should we copy the semver ones and run them again with pep440? What is the best approach?
Should we copy the semver ones and run them again with pep440? What is the best approach?
For unit testing:
-
you will want to have a variant of the semver parse testing to ensure pep440 strings are parsed properly
-
You should probably add some comparator testing between a semver and pep440 parsed version
-
Likely need to add a set of bump tests to ensure the resulting string is pep440 compliant
For system testing:
Add to the
tests/command_line/directory
- Test the
--pep440option that it generates a pep440 version the following repos variants
-
all pep440 versions (this fixture doesn't exist, duplicate the repo with angular commits type, maybe a few of them since prereleases versions must be tested)
-
mixed pep440 and semver versions where someone started with pep440 and converted to semver
-
mixed pep440 and semver versions where someone started with semver and converted to pep440
-
Add the repo variants to the changelog_regenerate test
-
Add the new pep440 repos to any changelog update tests that make sense
-
Make sure publish command works when pointing at a pep440 version
-
Make sure changelog post to release tag works when it's a pep440 version
This is what I came up with so far from memory, if I think of something else I'll post it. It's a lot because this is like a core functionality and interoperability change. I appreciate the hard work and time you have put in.
Remember to rebase soon as there have been some changes your branch conflicts with
@codejedi365 regarding the --pep440 flag you suggested, I'd rather keep the --version-compat flag such that we're open to future versioning schemes.
Remember to rebase soon as there have been some changes your branch conflicts with
I'll do.
@codejedi365 regarding the --pep440 flag you suggested, I'd rather keep the --version-compat flag such that we're open to future versioning schemes.
Although I appreciate the forward look, I think the current name is less intuitive and I don't anticipate any more version schemes as the world has settled around semver fairly heavily. I know there is CalVer out there but that isn't directly compatible with our version bump construct. Any other version scheme would need to match the version bump construct. With that said, I stand by my comment to change to --pep440 as the option. If my predictions is wrong, I'll deal with it when the time comes.
Added another unit test idea to the list above.
Is version_scheme better than version_compat? If so I'd refactor.
@lukasbehammer, when you start running the tests you are probably going to want to add the -nauto flag for the xdist plugin to use multiple cpus. You probably will want to isolate the specific test files to run or test case while running locally because the whole suite takes a long time.
It's on the list of things to fix but it's not quite easy to change.
Also I tried to implement the Enum. Didn't really work out. Maybe you @codejedi365 can have a look at it.
Sure, I can take a look tomorrow
Should version_compat be a config file option instead of both a command line option and a config file option? It would seem error prone to have to specify on the command line every time you bump the version. You would just want to configure it once in your pyproject.toml or releaserc.toml file. In my opinion version_compat should only be a config file option. It should not be both a cli and config option.
Current implementation has a hardcoded separator between the the release and pre/post/dev token and the separator between pre/post/dev and the number. In pep440 "1.2.3-pre-1" is the same as "1.2.3pre.1". Should we have a config option for the separators? We could use the already existing prerelease option and allow something like
[semantic_release.branches.dev]
match = "develop"
prerelease_token = "-dev."
prerelease = true
The above would generate 1.2.3-dev.1 and a prerelease_token = "_dev" would generate 1.2.3_dev1. The checks on allowed prerelease_tokens could be done after the config file is parsed. This would also easily handle the post release format of 1.2.3-1
We would just have to document it correctly.
Should version_compat be a config file option instead of both a command line option and a config file option? It would seem error prone to have to specify on the command line every time you bump the version. You would just want to configure it once in your pyproject.toml or releaserc.toml file. In my opinion version_compat should only be a config file option. It should not be both a cli and config option.
Yes, we should probably have a configuration option in the config for it as it likely is a lasting setting. I still would like to maintain the cli option as that is how we provide overrides to the github action. The github action is almost configureless as the defaults will load accordingly. We will not make pep440 the default so it will need to be a cli option.
Current implementation has a hardcoded separator between the the release and pre/post/dev token and the separator between pre/post/dev and the number. In pep440 "1.2.3-pre-1" is the same as "1.2.3pre.1". Should we have a config option for the separators? We could use the already existing prerelease option and allow something like
[semantic_release.branches.dev] match = "develop" prerelease_token = "-dev." prerelease = trueThe above would generate 1.2.3-dev.1 and a
prerelease_token = "_dev"would generate 1.2.3_dev1. The checks on allowed prerelease_tokens could be done after the config file is parsed. This would also easily handle the post release format of 1.2.3-1We would just have to document it correctly.
I do not intend to provide configuration for the separator as that would result in non-conformative versions to the two supported standards. The reason it is hardcoded is because PSR builds SemVer compliant versions and once this PR is complete, it will have the ability to create PEP440 compliant versions. I will have to check on those version similarities. I hope not... I just can't stand pep440.
Should version_compat be a config file option instead of both a command line option and a config file option? It would seem error prone to have to specify on the command line every time you bump the version. You would just want to configure it once in your pyproject.toml or releaserc.toml file. In my opinion version_compat should only be a config file option. It should not be both a cli and config option.
Yes, we should probably have a configuration option in the config for it as it likely is a lasting setting. I still would like to maintain the cli option as that is how we provide overrides to the github action. The github action is almost configureless as the defaults will load accordingly. We will not make pep440 the default so it will need to be a cli option.
Having a command line flag would be inconsistent with every other setting. Why could the config file settings not work in a github action?
Having a command line flag would be inconsistent with every other setting. Why could the config file settings not work in a github action?
I don't think the command line flag is inconsistent. All the other things can be either set by a config file (e.g. pyproject.toml) or by command line options. The GitHub action currently indeed is setup to use the cli options to call the code.
On another note: I still prefer the version_compat scheme, but have no obligations against using a pep440 flag and trying to evaluate the semver first.
Having a command line flag would be inconsistent with every other setting.
That is a statement of opinion that I do not share. I consider each option and its usage independently for when it should be available as a cli flag.
Why could the config file settings not work in a github action?
I did not say that. Configuration files are parsed in a GitHub Action. Cli options are for overrides. Just like in every other Linux-flavored-cli tool. And I said the plan is to provide both.
Also I tried to implement the Enum. Didn't really work out. Maybe you @codejedi365 can have a look at it.
@lukasbehammer, sorry I didn't get back around to this, I've been working other fixes & features that have been lingering too long. Hopefully over the next month.
It has been 60 days since the last update on this confirmed PR. @python-semantic-release/team can you provide an update on the status of this PR?