If you package software or maintain automated builds, you know the drill. You need the latest stable version of some upstream project, and you'd think it's a simple API call. It isn't.
Release tags are wildly inconsistent. Some projects tag `v1.2.3`, others do `release-1.2.3-final`. Quite a few forget to mark their release candidates as pre-releases on GitHub, so the API happily returns a beta as "the latest release". And then there are projects that switch versioning schemes entirely mid-history, going from `v20150121` to `v2.0.1`.
I deal with RPM packaging, so I hit this constantly. Every upstream project required its own script. So I wrote `lastversion` to handle the mess, and it's been in production use for about 7 years now.
$ lastversion nginx/nginx
1.26.3
$ lastversion php/php-src --major 8.2
8.2.27
$ lastversion format "mysqld Ver 5.6.51-91.0 for Linux"
5.6.51
$ lastversion rocky
9.5
That last one pulls Rocky Linux's version from Wikipedia — not everything has a GitHub repo. `lastversion` works with GitHub, GitLab, BitBucket, PyPI, Mercurial, SourceForge, WordPress plugin directory, RSS feeds, Helm charts, and a few others.
The version parsing was the tricky part. Standard PEP 440 doesn't handle real-world formats like Java's `8u462-b08` or OpenSSL's `1.1.1b`, so I extended it. There's also heuristic detection for misfiled betas — when the micro version is suspiciously high (≥90) and it's not a date-based scheme, it's likely a pre-release.
You can also `lastversion download`, `extract`, or `install` releases directly. For CI scripts, the `-gt` flag gives you a non-zero exit code if no newer version exists. And if you maintain RPM specs, `lastversion update-spec nginx.spec` will update the version for you.
dvershinin•1h ago
Release tags are wildly inconsistent. Some projects tag `v1.2.3`, others do `release-1.2.3-final`. Quite a few forget to mark their release candidates as pre-releases on GitHub, so the API happily returns a beta as "the latest release". And then there are projects that switch versioning schemes entirely mid-history, going from `v20150121` to `v2.0.1`.
I deal with RPM packaging, so I hit this constantly. Every upstream project required its own script. So I wrote `lastversion` to handle the mess, and it's been in production use for about 7 years now.
That last one pulls Rocky Linux's version from Wikipedia — not everything has a GitHub repo. `lastversion` works with GitHub, GitLab, BitBucket, PyPI, Mercurial, SourceForge, WordPress plugin directory, RSS feeds, Helm charts, and a few others.The version parsing was the tricky part. Standard PEP 440 doesn't handle real-world formats like Java's `8u462-b08` or OpenSSL's `1.1.1b`, so I extended it. There's also heuristic detection for misfiled betas — when the micro version is suspiciously high (≥90) and it's not a date-based scheme, it's likely a pre-release.
You can also `lastversion download`, `extract`, or `install` releases directly. For CI scripts, the `-gt` flag gives you a non-zero exit code if no newer version exists. And if you maintain RPM specs, `lastversion update-spec nginx.spec` will update the version for you.
`pip install lastversion`. BSD licensed, ~400 GitHub stars.