abichinger/semantic-release-pypi

Reading package version from metadata

cuent opened this issue · 6 comments

cuent commented

When making a release, the version number is hard coded. However, setup.cfg allows reading the package version from configuration files for example (if the pckg name is my_package):

setup.cfg

[metadata]
version = attr: my_package.VERSION

Problem: current implementation will override the version in setup.cfg when it should override in VERSION.

You probably have moved on by now, but I'm still going to comment on your request.

In order to override my_package.VERSION the plugin would first need to find the line of code where VERSION is assigned. As far as I know the assignment can be in any source file of the package.
The only method I can think of to accomplish this task is to use the ast module, but that seems rather difficult.

Can you think of a better solution?

pyproject.toml also allows dynamic metadata (PEP 621)

v1ack commented

@abichinger as for now you are not checking if pyproject.project.version exists

toml['project']['version'] = args.version

So dynamic version set is not possible for now

Maybe it's better to add option, which disables version change in local files, only build and upload package

@v1ack I think skipping the version update defeats the purpose of this package.

I imagine we could add an option called versionCmd. If the option is set, we skip the execution of the script set_version.py. This should make it possible to use a dynamic version.

Example:

// .releaserc.json
{
    "branches": ["main"],
    "plugins": [
        "@semantic-release/commit-analyzer",
        "@semantic-release/release-notes-generator",
        [
            "semantic-release-pypi",
            {
                "versionCmd": "hatch version {version}"
            }
        ],
    ]
}
v1ack commented

@abichinger yes, sounds good
Just to mention, there is another ability to run custom commands https://github.com/semantic-release/exec

Just to mention, there is another ability to run custom commands https://github.com/semantic-release/exec

@v1ack That's right, the difference will be that normalizeVersion is called before running the command set by versionCmd. normalizeVersion sanitizes some versions (e.g. 1.0.0-beta.1 becomes 1.0.0b1). I have to admit, I'm not sure if normalizeVersion is still necessary, because using 1.0.0-beta.1 directly works when using hatch or setuptools as build backend.

async function normalizeVersion(
version: string,
options: Options = {},
): Promise<string> {
const { stdout } = await spawn(
'python3',
[
'-c',
`from packaging.version import Version\nprint(Version('${version}'))`,
],
options,
);
return stdout as unknown as string;
}

Sources:
https://semantic-release.gitbook.io/semantic-release/usage/workflow-configuration#prerelease
https://packaging.python.org/en/latest/discussions/versioning/

versionCmd can now be used to dynamically set the version.