Version issue
Hi @yunjunz, Thanks for updating. However, I installed in the new environment and ran simple command, smallbaseline --version, it showed 1.6.2.
I forgot to create a new version tag before cutting for the new release 😅, so for the released version of 1.6.3 from pip and conda-forge, the version number will show the wrong number of 1.6.2 when the code prints, as you have seen, although the actual version on pip (https://pypi.org/project/mintpy/) and conda-forge (https://anaconda.org/channels/conda-forge/packages/mintpy/overview) is flagged correctly.
I have fixed this confusion in the development version in #1442, so the development version after 1.6.3.post1 will show the version number correctly.
One way to fix this confusion is to cut for a new release of 1.6.4 and do it correctly. But I am open to better ideas.
I am not happy with the current mechanism of getting the version number in mintpy, which uses the version tag here: https://github.com/insarlab/MintPy/blob/c847d7fd01a2e8ae8584ae2daaf34001b450c73d/src/mintpy/version.py#L16
It could get the correct version number for both the released version (1.6.2, 1.5.3, etc.) and development version (1.6.3.post4, etc.), but required manually editting of the version tag. Is there a more automatic way to achive this, e.g. without manually editting? @jhkennedy @scottstanie @avalentino
I've been using setuptools SCM for awhile. The SCM, for "source control management", means it uses your source control to determine tags (i.e. whatever git tag --list shows).
I described what we did for dolphin here: https://github.com/isce-framework/dolphin/wiki/Release-procedure So making a new release just involves going on github and clicking around a few times. The pypi upload also happens after you make the github release with the CD (continuous deployment) action.
I think Joe has even-more-automated release actions to handle the many ASF repos
@yunjunz , yes like @scottstanie I'm using setuptools_scm and CI/CD automation as well. And I see MintPy is actually set up for it: https://github.com/insarlab/MintPy/blob/main/pyproject.toml#L2
But in version.py you hard code the version numbers and release dates. Generally, the idea would be to not record version information in files like version.py and instead leave all of that in git using setuptools_scm.
For version numbers:
importlib.metadata.version will pull the version number from the installed version of the repo, so you can effectively drop most everything in version.py and just get the version number in __init__.py:
from importlib.metadata import version
__version__ = version(__name__)
and if you want the version history you just look at the git tags or releases on GitHub.
There are a couple caveats though:
- you need to have the git history checked out for the version numbers to be computed
- importlib will throw an import error if minpy isn't installed
- if you do an editiable/develop pip install (
python -m pip instal -e .) importlib will report the version number from the last time it was installed.
Generally, that's all not a big deal. In the development environment, if you have setuptools_scm installed, python -m setuptools_scm will report the version number, and you can provide a helper around importlib like:
from importlib.metadata import PackageNotFoundError, version
try:
__version__ = version(__name__)
except PackageNotFoundError:
print(
f'{__name__} package is not installed!\n'
f'Install in editable/develop mode via (from the top of this repo):\n'
f' python -m pip install -e .\n'
f'Or, to just get the version number use:\n'
f' python -m setuptools_scm'
)
but I usually don't bother b/c I find in practice it doesn't come up much.
For release dates
The other thing you are recording in version.py is the release date, and setuptools_scm and importlib don't really give you a helper to look it up.
With dynamic version numbers, the date for any non-release will be either "last commit time" or "now" if the repo is dirty. For releases, it'll be whenever the tag was created, so there's no straightforward way to record the date. I don't personally think there's much value to recording it -- the tags, github releases page, and potentially changelog (if adopted) would all record the release date.
If you want to record it, you'll need to use something like bump-my-version to record it as it creates a new tag, and you lose the benefit of a dynamic version number without writing a bit of code to decide what date to report based on the computed version number (and it's not clear where to look for that info in all cases).
For the automation
I forgot to create a new version tag before cutting for the new release 😅, so for the released version of 1.6.3 from pip and conda-forge, the version number will show the wrong number of 1.6.2 when the code prints, as you have seen, although the actual version on pip (https://pypi.org/project/mintpy/) and conda-forge (https://anaconda.org/channels/conda-forge/packages/mintpy/overview) is flagged correctly.
I usually set things up so that when a new tag is pushed, the package is built and pushed to PyPI, so all "release" processes are just "push a tag".
The full automation we have set up is similar to what @scottstanie is doing, but a little more automated -- Philosophically, I just want to mash the big green merge button and all the repetitive release and what not things to happen automagically.
For MintPy that would look like, main is considered the "development" branch and PRs get opened there by default.
- each
mainPR has a check that ensures the CHANGELOG.md is up to date using Keep a changelog or (more complicated) common changelog format.
To release, you'd open a PR from the main branch to the release branch.
- release PRs needs to have changelog updates
- you label the pr
major/minor/patchdepending on how big the changes are - when merged, a new tag is created using bump my version and pushed
- that kicks off the github release workflow and pypi workflow (so you could also just push a tag)
- the release branch is immediately fast-forward merged back to
mainso that effectively themain->releasePR is just a "tag request" (it will show changes between the last release and the current proposed release) and we're still doing trunk-based development out ofmain. Importantlymain->releasehas to use a merge (not a squash or rebase) commit so that there is a new commit to tag and get fast-forward merged back to develop.
All our GitHub Actions workflows are here: https://github.com/ASFHyP3/actions
Though I don't have a good document describing the whole flow, and they don't work well for forking-workflows like would be typically for mintpy. But, they might be a good place to start.