UNPKG

@pdecat/semantic-release-python

Version:

A semantic-release plugin for Python (with support for both setup.cfg/setup.py and pyproject.toml with e.g. Poetry and uv). Fork of https://github.com/unimonkiez/semantic-release-python which is a fork of https://github.com/megabyte-labs/semantic-release-

114 lines (100 loc) 3.09 kB
import fs from 'fs' import path from 'path' import { execa } from 'execa' import { getPyprojectTool, getOption, normalizeVersion, setopt } from './util.js' /** * @param setupPy * @param version */ export async function setReleaseVersion(setupPy, version) { try { await setopt(setupPy, 'metadata', 'version', version) } catch (error) { throw new Error(`failed to set release version ${version}\n${error}`) } } /** * @param setupPy * @param distDir */ export async function sDistPackage(setupPy, distDir) { try { await execa('python3', [path.basename(setupPy), 'sdist', '--dist-dir', distDir], { cwd: path.dirname(setupPy) }) } catch { throw new Error(`failed to build source archive`) } } /** * @param setupPy * @param distDir */ export async function bDistPackage(setupPy, distDir) { try { await execa('python3', [path.basename(setupPy), 'bdist_wheel', '--dist-dir', distDir], { cwd: path.dirname(setupPy) }) } catch { throw new Error(`failed to build wheel`) } } /** * @param pluginConfig * @param nextRelease * @param logger */ async function prepareSetupCfg(pluginConfig, nextRelease, logger) { const setupPy = getOption(pluginConfig, 'setupPy') const distDir = getOption(pluginConfig, 'distDir') const pypiPublish = getOption(pluginConfig, 'pypiPublish') const version = await normalizeVersion(nextRelease.version) logger.log(`Setting version to ${version}`) await setReleaseVersion(setupPy, version) if (pypiPublish !== false) { logger.log(`Build source archive`) await sDistPackage(setupPy, distDir) logger.log(`Build wheel`) await bDistPackage(setupPy, distDir) } } /** * @param pluginConfig * @param nextRelease * @param logger */ async function preparePyproject(pluginConfig, nextRelease, logger) { const setupPy = getOption(pluginConfig, 'setupPy') const version = await normalizeVersion(nextRelease.version) const tool = getPyprojectTool(setupPy) logger.log(`Setting version to ${version}`) const dir = path.dirname(setupPy) try { const { stdout, stderr } = await execa(tool, ['version', nextRelease.version], { cwd: dir }) logger.log(`${stdout}`) logger.log(`${stderr}`) } catch (error) { throw new Error(`Failed to run "${tool} version ${nextRelease.version} in ${dir}: ${error.stdout} ${error.stderr}"`) } } /** * @param pluginConfig * @param root0 * @param root0.nextRelease * @param root0.logger */ export async function prepare(pluginConfig, { nextRelease, logger }) { const setupPy = getOption(pluginConfig, 'setupPy'); if (fs.existsSync(setupPy)) { if (path.basename(setupPy) === "setup.cfg") { await prepareSetupCfg(pluginConfig, nextRelease, logger) } else if (path.basename(setupPy) === "pyproject.toml") { await preparePyproject(pluginConfig, nextRelease, logger) } } else { const pypiPublish = getOption(pluginConfig, 'pypiPublish') if (pypiPublish !== false) { throw new Error(`Project must have either a setup.cfg or a pyproject.toml file`) } } }