Task update(s): versioning scheme and security maintenance plan

TL;DR We’re updating a couple lifter tasks in order to improve package version guidance for both lifters and subscribers. But versioning is really hard, so we appreciate your patience as we figure out the best way for lifters to provide guidance, and for subscribers to follow it!

I want to say something that bears repeating: software versioning is incredibly complex. Not only are there many unique standards—each with their own merits and rationale—but not all software projects follow those standards in the exact same way. Release cadence, backports, security vulnerabilities, and user demands add into that complexity.

With that in mind, we’ve been re-working how we enable lifters provide version guidance to Tidelift subscribers. Issues around version guidance have come up before, whether in the form of bugs, interface confusion, or our own requests for input.

Our goal in asking you to provide version guidance for subscribers is simple: we want to help subscribers get to the best, safe-to-use versions of their dependencies.

That helps subscribers by enabling their development teams to work faster and safer, and that helps lifters by getting more users off of old release streams that you don’t want to deal with any more.

Here’s where we are today:

  • Our existing “Release streams” task is unclear. It asks lifters to define which streams are “supported” (a very weighted word). This only increases complexity and confusion.
  • On top of that, the UI is is incredibly text-heavy. This adds to the confusion for lifters
  • Finally, for packages with many versions, there is no good way to identify the support status in batches, making completing this task a tedious process.

The existing Release streams task

Thanks to your feedback, we’ve taken some steps to improve how lifters provide version guidance to subscribers!

First, we want to confirm with you what the intended versioning scheme of the project is. Similar to the license of the package, this is something that we could detect automatically (or at least make an educated guess on), but, as I mentioned earlier, versioning schemes have a lot of grey areas. It’s best to ask for you to confirm your scheme with Tidelift to resolve potential issues down the road.

New Versioning scheme task

As you can see, we’re releasing this task with just the most common versioning schemes—semantic versioning. That’s based on what we know lifters are currently using. Another versioning scheme that we plan to add shortly will be PEP-440. If you use another versioning scheme, please get in touch and we will add support for it!

Once we know the versioning scheme for your package, we’ll ask you to complete the Security maintenance plan task, which will replace the existing Release streams task.

This task will have a different focus: rather than asking you to identify which release streams you’ll “support” (again, a very loaded term!), we ask you to identify which release streams you’ll be willing to provide security updates for.

This is a detail I want to emphasize: this task specifically is only currently asking about security updates. It does not relate to bug fixes, new features, or anything else that may fall under the “support” umbrella.

A few comments on this revised task design:

  • There are three security update plan options: saying that you’ll provide security fixes on a given release stream for all users, that you’ll only provide a fix on that stream if paying Tidelift subscribers are using it, or that you won’t provide any fixes on that stream.
  • A number of popular projects on Tidelift are already using the “End of life date” feature to indicate that they will stop “supporting” a release stream on a given date, so we made sure to bring that over to this task!
  • If you wish to only provide security updates on the latest release, you can check the “Only provide security updates for the latest release stream” checkbox at the top, and that will automatically update your “recommended version” to your latest release upon each subsequent release of your package.
  • If you’d like to assign up policies in batches, you can do that by selecting the check boxes or drop down, then selecting the relevant release streams. You can then select the “update level” and apply the update plan for all of those release streams at once.

This is obviously the first iteration of this new task, but we hope that it resolves the three issues that I described with the present Release streams task: it focuses on security rather than “support,” it’s more visual and less text-heavy, and it allows batch editing.

We’re not done improving this, though. Thanks to some great input from @ljharb, we’re considering how this task could be more easily completed for packages with many versions, or lifters with many packages. We’d also like to make sure that this data is kept as up to date as possible for subscribers!

One piece of inspiration for how we’ll do this is semver.npmjs.com, which has a nice UI, and makes it really easy to identify how your security update plan will shift over time. You can easily use semver carets, for example, to describe your policy on a specific release stream.

We have some other options that we’re earlier in exploring (e.g. CLI tool), but we’d love to hear from you!

How does this new task work for you? What issues are you running into?

Would something like the semver.npmjs.com interface work better? If not, is there something else you’d prefer?

We look forward to hearing what you think!!


I’m obviously super excited about this improvement :slight_smile:

1 Like

Hey everyone!
As I mentioned when we first launched this task update a couple weeks ago, the next versioning scheme we were going to add would be PEP-440. Well, today is the day!

You can now choose the PEP-440 versioning scheme within your lifter tasks, and that will allow you to provide version guidance on the broader array of PEP-440 compliant version numbering formats.

As you’ll notice, we also ask if you could identify the max number of version parts, as this helps us properly group streams for you and subscribers.

So, Python lifters using PEP-440, please let us know how this works for you! We’d love to get your feedback as we continue to improve the lifter experience!


My security maintenance plan on es5-shim has a warning that i have to support at least one stream, but there’s no streams listed and no way to add one.

1 Like

@ljharb it appears that the releases aren’t populating correctly for this package. I’ve asked the team to take a look and will let you know once this has been resolved. Thank you!

1 Like

Hey @brenna & @ksz,

Could you please explain what is the principal difference of PEP440 from SemVer? AFAIK it’s just a version format that PyPI understands so anybody who publishes a distribution package to pypi.org (or a compatible index) must obey it (non-compliant version uploads are rejected). It’s also a set of rules that Pip (the main package manager in the Python ecosystem) uses internally to compare/match versions.

So you may say that every Python lib uses this standard. But it’s also loosely compatible with some other versioning flavors and it’s totally possible to follow SemVer because the pattern is compatible. Still PEP440 doesn’t enforce a semantical meaning for major/minor/patch(micro) parts. Also, semver has a different format of extensions.

Now, let’s look at one of the projects I maintain — CherryPy.
It declares SemVer compatibility but being a Python framework it must also obey PEP440. So if I were to use 19.0.0-rc1 version from semver, I’d have to translate it into something that could actually be understood by the packaging ecosystem so it would look like 19.0.0rc1.

It looks like we’re using the idiomatic SemVer in Python ecosystem is not possible which hints me to select PEP440 in the task but then I feel like by doing this we’ll lose the semantic meaning of the version segments.

What do you think should be chosen in such a case?

P.S. When I select PEP440 it says “Help us identify point- or post-releases created by adding an additional version number.” But this is not how it works. For post-releases, .postN is to be used, also segments can be chained in different order (as in post release of a dev release for a release candidate): https://www.python.org/dev/peps/pep-0440/#post-releases.

We’re still thinking about this and iterating on the task. For example: maybe you’d pick properties/behaviors of your versioning scheme.

For now, the best differentiation is “how many segments are your release versions typically”? If it’s not always 3 segments (with some extension on the last part like -rc1), pick PEP 440. Otherwise, SemVer. We know this won’t apply perfectly in some cases, and we’ll keep refining it.

Thanks for the clarification! I’ll go with semver then :slight_smile: But really these shouldn’t be alternate choices, I’d say they might’ve been checkboxes. Or even series of checkboxes listing properties of each versioning scheme. This way somebody could select which properties of semver apply to them and which properties of other versioning schemes apply too. Plus maybe some button “select all” under semver to simplify saying that it’s 100% compliant…