如何在setup.cfg中读取变量实现STAGE/PROD环境Python包差异化构建
方案说明
原生setup.cfg是静态INI配置文件,标准setuptools解析流程不支持自定义变量占位、环境变量读取替换的能力,你想要的占位符动态替换效果没法直接在原生setup.cfg里实现。结合你要求遵循PEP-517/PEP-518、不使用setup.py的约束,下面两种方案都可以满足同一份代码打STAGE、PROD两个不同包的需求。
方案1:setuptools 动态字段 + 构建时环境变量(推荐,规范兼容性最好)
这个方案完全符合PEP标准,不需要引入第三方构建插件,所有动态逻辑通过setuptools原生支持的动态属性能力实现。
- 在你的业务包目录下(比如包名为
my_project),新建一个构建元数据文件my_project/_build_meta.py,内容如下:
import os # 读取构建时注入的环境变量,默认走生产环境配置 BUILD_ENV = os.getenv("PY_BUILD_ENV", "prod").strip().lower() if BUILD_ENV == "stage": __project_name__ = "my-project-stage" __package_configs__ = ["config/stage.toml"] else: __project_name__ = "my-project" __package_configs__ = ["config/prod.toml"]
- 配置
pyproject.toml,把需要动态调整的name、package_data字段标记为动态,关联到上面文件里的属性:
[build-system] requires = ["setuptools>=64", "wheel"] build-backend = "setuptools.build_meta" [project] # 所有固定不变的元数据正常静态配置即可 version = "1.0.0" description = "Python client application" requires-python = ">=3.8" # 标记需要动态生成的字段 dynamic = ["name"] [tool.setuptools.dynamic] name = {attr = "my_project._build_meta.__project_name__"} [tool.setuptools.packages.find] where = ["."] include = ["my_project*"] [tool.setuptools.package-data] my_project = {attr = "my_project._build_meta.__package_configs__"}
- 在ADO流水线的两个构建任务里分别注入环境变量即可:
- STAGE构建任务:添加环境变量
PY_BUILD_ENV=stage,再执行标准构建命令python -m build - PROD构建任务:不设置该变量,或者显式设置
PY_BUILD_ENV=prod后执行构建
方案2:流水线预替换配置占位符(零业务代码侵入)
如果不想在项目代码里加入构建相关的逻辑,可以把动态替换的步骤全部放到ADO流水线侧实现,不需要依赖setuptools的动态能力。
- 在
pyproject.toml/setup.cfg里提前写好固定占位符,比如pyproject.toml示例:
[project] name = "{{PROJECT_NAME}}" version = "1.0.0" # 其余固定元数据正常配置 [tool.setuptools.package-data] my_project = ["{{ENV_CONFIG_PATH}}"]
- 在流水线的每个构建任务执行构建前,加一步文本替换步骤:
- STAGE构建:把
{{PROJECT_NAME}}替换为my-project-stage,把{{ENV_CONFIG_PATH}}替换为config/stage.toml - PROD构建:把
{{PROJECT_NAME}}替换为my-project,把{{ENV_CONFIG_PATH}}替换为config/prod.toml
Linux构建代理直接用sed就能完成替换:
# STAGE环境替换示例 sed -i 's/{{PROJECT_NAME}}/my-project-stage/g' pyproject.toml sed -i 's/{{ENV_CONFIG_PATH}}/config\/stage.toml/g' pyproject.toml
Windows代理用PowerShell的文本替换命令也可以实现同等效果,替换完成后再执行正常的构建打包命令即可。
不推荐的思路说明
不要尝试找第三方setuptools插件实现setup.cfg内的变量替换,这类插件大多对PEP-517的隔离构建模式兼容性差,很容易出现本地构建正常、流水线隔离环境构建失败的问题,生产构建流程尽量依赖标准setuptools原生能力或者流水线侧的逻辑实现。
内容的提问来源于stack exchange,提问作者FreeGor
相关产品推荐
相关产品推荐

