Skip to main content

funbuild

PyPI version Python License: MIT

funbuild 是面向 Python / 混合仓库的构建与发布辅助工具:根据项目结构自动选择构建策略(UV、Poetry、旧式 PyPI 脚本、package.json 前端包、Flutter 及混合模式等),串联版本递增、构建、安装校验、发布与 Git 标签等常见流程。

特性

  • 多构建策略:按仓库布局自动匹配 UVBuild、PoetryBuild、PypiBuild、NpmFrontendBuild、UvNpmHybridBuild 等实现,无需手写切换逻辑。
  • 版本同步:以根目录 pyproject.toml 的 [project].version 为主源时,可将版本同步到仓内其它带 version 的 pyproject.toml、package.json 与 pubspec.yaml(含子目录;pubspec.yaml 只同步 major.minor.patch,+buildNumber 保持不变)。
  • 依赖与工具链:内置对 uv、ruff 等工具的调用约定;日志通过 farlog,Shell 流程通过 funshell。
  • Git 工作流:pull / push / tag 等与远程协作;push 在提交阶段优先用 aicommits 生成说明,未安装时自动回退到默认信息。
  • 失败即中止:任一 shell 步骤返回非 0 即抛出 ShellCommandError 并以非 0 码退出,构建失败不会继续推送或打标签。
  • 维护命令:clean 与 clean-history 会改写 Git 状态或强制重写远程历史,使用前请确认团队规范与备份策略。

打包支持的项目类型

funbuild 运行时会按下表顺序(从上到下)依次探测仓库根目录,命中第一个匹配的类型即停止;判定逻辑见 src/funbuild/core/registry.py。

优先级 构建类型 判定条件 适用项目
1 SubmoduleWorkspaceBuild 根目录同时存在 apps/ 目录与 scripts/funbuild.toml <product>-dev 编排仓库:apps/ 下每个 app 是独立仓库的 git submodule,仓库自身没有可构建产物,见下方专节
2 UvNpmHybridBuild 同时满足 UVBuild 与 NpmFrontendBuild 的判定条件 同一仓库里既是 UV 管理的 Python 包、又带前端 package.json 的混合项目(一条命令串联两侧构建/安装/发布)
3 UVBuild 根目录存在 pyproject.toml 且含 [project] 段 使用 uv / PEP 621 标准 pyproject.toml 的现代 Python 包(含 extbuild/、exts/ 子包)
4 PoetryBuild pyproject.toml 存在且 [tool.poetry].version 有效 使用 Poetry 管理版本与依赖的 Python 项目
5 PypiBuild 根目录存在 script/__version__.md 早期遗留的 PyPI 发布脚本项目
6 FlutterBuild pubspec.yaml 存在且 dependencies.flutter.sdk == flutter Flutter 应用/插件项目
7 NpmFrontendBuild 存在 package.json(含 extbuild/ 等子目录的多包场景) npm / pnpm / yarn 管理的纯前端项目
8 VersionFileBuild 根目录存在纯文本 VERSION 文件 没有 pyproject.toml / package.json、无需真正构建的仓库(如 Shell 脚本仓库),仅借用 upgrade / push / tag 的版本与 Git 流程
9 EmptyBuild 兜底,永远匹配 未识别到任何版本清单的仓库;upgrade、build、tag 均为空操作,仅保留提示日志

<product>-dev 提交工作区 (SubmoduleWorkspaceBuild)

面向 apps/<name> 下每个 app 都是独立仓库 git submodule 的编排仓库(配套 submodule-workspace-governance 技能约定的目录结构)。这个仓库本身没有可构建产物,scripts/funbuild.toml 里的 version 是分发给所有 app 的共享版本号,而不是每个 app 各自维护。

# scripts/funbuild.toml
version = "1.0.0"
packages = ["funtrack"]   # 可选:这些依赖在每个 app 构建前会被升级到最新版

funbuild build 在这类仓库上依次执行:

  1. pull 当前仓库,递增共享 version。
  2. 遍历 apps/ 下每个已初始化的 submodule:跳过结构上是嵌套 <something>-dev 工作区的 app(自己也有 apps/ + scripts/setup.sh,由它自己的发布节奏管理,不会被递归进入);其余 app 依次切到跟踪分支、git pull、把 packages 里配置的依赖升级到最新版(按 app 目录下存在的清单文件分派:pyproject.toml → uv add <pkg>@latest;package.json → 按 pnpm-lock.yaml/yarn.lock/默认 npm 自动选择 pnpm add / yarn add / npm install --save;pubspec.yaml → dart pub add <pkg>),再转发 funbuild build --version <共享版本号>。
  3. 统一 push、打 v{version} 标签一次,使所有 submodule 指针更新落成一个提交。

Flutter 项目 (FlutterBuild)

版本号沿用 pubspec.yaml 的 major.minor.patch+buildNumber 惯例:upgrade 按 128 进制递增 major.minor.patch,同时把 +buildNumber 单独 +1(应用商店要求构建号严格递增,不与主版本号混在一起处理)。

默认命令:

阶段 默认命令
构建 flutter pub get + flutter build apk --release + flutter build web --release
安装 无(本地一般没有可安装的产物形态)
发布 经 funpub 上传到私有通用仓库(--repo-name funpackage):apk 直传,web 产物先打包成 zip 再传,远端路径为 flutter/{pubspec name}/apk 与 flutter/{pubspec name}/web
清理 flutter clean

可在 pubspec.yaml 中加一段 funbuild: 来覆盖任意阶段(字符串或字符串数组均可,数组会依次执行):

funbuild:
  build: flutter build ios --release        # 或写成数组: [flutter build apk, flutter build appbundle]
  install: flutter install
  publish: curl -T build/app/outputs/flutter-apk/app-release.apk -u "$ARTIFACT_USER:$ARTIFACT_PASS" https://packages.example.com/generic/demo/app-release.apk
  cleanDirs: [build, .dart_tool]

默认发布走 funpub upload,仓库固定为 funpackage(阿里云 Packages generic 仓库);账号、地址等凭据不经 funbuild 之手,需提前用 funsecret write ... funpub aliyun generic funpackage ... 配置好,funbuild 只负责拼装 funpub upload 命令,不接触任何凭据。如果你的团队使用别的制品仓库(自建 Nexus 等)或需要不同的 repo-name,在 funbuild.publish 里写你自己的上传命令即可完全接管这一步,同样能接入 funbuild build 的完整流水线。

系统要求

  • Python 3.10+
  • Git(版本管理与标签推送)
  • 可选:aicommits(npm install -g aicommits)。装了则 push 用它生成提交信息,没装则回退到 message 参数的值,不影响流程。
  • Flutter 项目需要本机装好 flutter 命令并加入 PATH;funbuild 本身只负责拼装 flutter 命令并不校验其可用性。
  • Flutter 项目的默认发布步骤需要安装 funpub(pip install funpub),并提前用 funsecret 配置好 funpackage 仓库的凭据,否则 funpub upload 会失败。

安装

从 PyPI 安装

pip install funbuild

从源码安装

git clone https://github.com/farfarfun/funbuild.git
cd funbuild
pip install .

使用 uv 时,可在克隆后执行 uv sync 或 uv pip install -e . 进行可编辑安装。

命令一览

在项目根目录执行(入口由 pyproject.toml 的 [project.scripts] 注册为 funbuild):

命令 参数 作用
upgrade — 版本自增并写回各清单文件
pull — git pull
push --message(默认 add)
--batch-size(默认 20)
按文件修改时间从旧到新分批提交,最后统一推送
install — 构建 + 安装到当前环境 + 清理产物
build message(位置参数,默认 add) 完整发布流水线,见下
release 同 build build 的别名,行为完全一致
tag — 打 v{version} 标签并推送
clean — 重建 Git 索引以应用新的 .gitignore(会产生一次提交)
clean-history — 破坏性:删除全部标签与提交历史并强推远程

命令名中的下划线会被 typer 转成连字符,因此是 clean-history 而非 clean_history。

版本

funbuild upgrade

自增规则为 128 进制进位:patch 满 128 向 minor 进位,minor 满 128 向 major 进位。

1.6.54  → 1.6.55
1.6.127 → 1.7.0
1.127.127 → 2.0.0

版本号会写回根 pyproject.toml,并同步到仓内所有带 version 字段的 pyproject.toml、package.json 与 pubspec.yaml(含 extbuild/ exts/ 子目录)。非三段版本按缺位补 0 处理(1.0 视作 1.0.0);1.0.0rc1 这类预发布后缀会被丢弃并打印告警。以 FlutterBuild 为主构建类型时例外:pubspec.yaml 自己的 +buildNumber 每次 upgrade 单独 +1,不受该丢弃规则影响。

CLI 未提供「写入指定版本号」参数,需要固定版本时请直接编辑清单文件。

Git

funbuild pull

# 默认每 20 个文件一次提交
funbuild push

# 自定义每个提交的文件数
funbuild push --batch-size 50

# 指定提交信息(未安装 aicommits 时生效);注意这里是选项而非位置参数
funbuild push --message "fix: typo"

push 会先执行 git reset 清空暂存区再按批次重新 add,已手工 git add 的内容会被一并纳入分批提交。

构建与发布

# 完整流水线
funbuild build

# release 是 build 的别名,两者完全等价
funbuild release

# 仅构建并安装到当前环境,不发布、不推送
funbuild install

build 依次触发:pull → upgrade → 清理 → 构建 → 安装校验 → 发布 → 清理 → push → tag。实际命令序列取决于选中的 Build 类型。任一步失败会立即中止,不会继续 push 或打标签。

维护类(高风险)

funbuild clean          # 重建索引,使新增的 .gitignore 规则生效
funbuild clean-history  # 抹掉全部历史与标签并强推,不可恢复且无二次确认

发布凭据

uv publish 的凭据优先读取 UV_PUBLISH_TOKEN / UV_PUBLISH_USERNAME / UV_PUBLISH_PASSWORD / UV_PUBLISH_URL 环境变量;某个变量未设置时,才用 ~/.pypirc 里对应的值补齐(已设置的环境变量不会被 ~/.pypirc 覆盖)。服务器名的选取顺序为:pyproject.toml 中 [[tool.uv.index]] 的 name > ~/.pypirc 里 [distutils].index-servers 的首项 > 默认 pypi。

[distutils]
index-servers = pypi

[pypi]
username = __token__
password = pypi-AgEIcHl...

凭据以 UV_PUBLISH_TOKEN / UV_PUBLISH_USERNAME / UV_PUBLISH_PASSWORD / UV_PUBLISH_URL 环境变量传给 uv,不会出现在命令行参数中(否则完整命令行会通过进程表对本机所有用户可见)。

CI 环境可以不放 .pypirc,直接导出这些环境变量即可:

export UV_PUBLISH_TOKEN=pypi-AgEIcHl...
funbuild build

错误处理

所有 shell 步骤经 run_checked() 执行,退出码非 0 即抛 ShellCommandError,进程以非 0 码退出。这意味着 funbuild build 在构建或发布失败时不会再继续 push 和 tag,可直接用于 CI 的失败判定。

配置说明

  • Python 项目:在根目录 pyproject.toml 中维护 [project].version 与依赖;UV 类构建会读写该版本并同步到其它清单。
  • 纯前端 / 子包:在对应 package.json 中可使用 funbuild 字段(对象或 true)扩展行为(例如自定义 build 命令、cleanDirs 等),具体逻辑见源码中 NpmFrontendBuild。
  • Flutter 项目:在 pubspec.yaml 中可使用 funbuild 字段自定义 build / install / publish / cleanDirs,具体逻辑见源码中 FlutterBuild;详见上方「打包支持的项目类型」里的 Flutter 小节。

构建类型的判定顺序见上方「打包支持的项目类型」表格及 src/funbuild/core/registry.py 中的注册表;无需再使用旧文档中的 [tool.funbuild] 等虚构段名。

集成组件

  • uv — 包管理与构建
  • ruff — Lint / 格式化(按项目配置使用)
  • typer(typer-slim)— CLI 框架
  • aicommits — 默认与 push 流水线集成的提交信息生成(以本机 CLI 为准)

仓库布局(摘要)

funbuild/
├── src/
│   └── funbuild/
│       ├── core/       # 构建注册与各策略实现
│       └── tool/       # 附加工具入口
├── tests/              # 单元测试
├── pyproject.toml
└── README.md

参与贡献

  1. Fork funbuild
  2. 新建分支并提交变更
  3. 发起 Pull Request

本地开发示例:

git clone https://github.com/farfarfun/funbuild.git
cd funbuild
uv pip install -e .
# 或: pip install -e .

# 跑测试 (pytest 已在 dev 依赖组, uv 会自动装)
uv run pytest -q

# 格式化与静态检查
uvx ruff format .
uvx ruff check . --fix

许可证

本项目以 MIT 许可证 发布。

链接

维护者

若 funbuild 对你有帮助,欢迎点个 Star。


关于 farfarfun

farfarfun 是一个专注于实用工具库的开源组织, 涵盖云存储、数据处理、AI、多媒体与开发工具链等方向。

本项目基于 MIT 协议开源。

Metadata

Release files for funbuild 1.6.82

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distribution (wheel)

Table of built distributions (wheels) for funbuild 1.6.82
File Interpreter ABI Platform
funbuild-1.6.82-py3-none-any.whl Python 3 none any Details

Release files / funbuild-1.6.82-py3-none-any.whl

Download URL funbuild-1.6.82-py3-none-any.whl
Size 47.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
1eef762b2289bcb44342fa92bb5bc56b198fbccc4b4cba07fa164c79a977aee4
BLAKE2b-256 checksum
How to use checksums
7fe1e13846516710eb939ec093747f632f8ac7159d9a8e165e0b0613a1666090
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.22 {"installer":{"name":"uv","version":"0.12.22","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release history Release notifications | RSS feed

1.6.97

1 release file

1.6.96

1 release file

1.6.95

1 release file

1.6.94

1 release file

1.6.93

1 release file

1.6.92

1 release file

1.6.91

1 release file

1.6.90

1 release file

1.6.89

1 release file

1.6.88

1 release file

1.6.87

1 release file

1.6.86

1 release file

1.6.85

1 release file

1.6.84

1 release file

1.6.83

1 release file

This release

1.6.82 This release

1 release file

1.6.81

1 release file

1.6.80

1 release file

1.6.79

1 release file

1.6.78

1 release file

1.6.77

1 release file

1.6.76

1 release file

1.6.75

1 release file

1.6.73

1 release file

1.6.72

1 release file

1.6.71

1 release file

1.6.69

1 release file

1.6.68

1 release file

1.6.67

1 release file

1.6.66

1 release file

1.6.30

1 release file

1.6.29

1 release file

1.6.28

1 release file

1.6.27

1 release file

1.6.26

1 release file

1.6.25

1 release file

1.6.24

1 release file

1.6.23

1 release file

1.6.22

1 release file

1.6.21

1 release file

1.6.20

1 release file

1.6.19

1 release file

1.6.18

1 release file

1.6.17

1 release file

1.6.16

2 release files

1.6.15

2 release files

1.6.11

2 release files

1.6.10

1 release file

1.6.9

1 release file

1.6.8

1 release file

1.6.7

1 release file

1.6.6

1 release file

1.6.5

1 release file

1.6.4

1 release file

1.6.3

1 release file

1.6.2

1 release file

1.6.1

1 release file

1.6.0

1 release file

1.5.99

1 release file

1.5.98

1 release file

1.5.97

1 release file

1.5.96

1 release file

1.5.95

1 release file

1.5.94

1 release file

1.5.93

1 release file

1.5.92

1 release file

1.5.91

1 release file

1.5.90

1 release file

1.5.89

1 release file

1.5.88

1 release file

1.5.87

1 release file

1.5.86

1 release file

1.5.84

1 release file

1.5.83

1 release file

1.5.82

1 release file

1.5.81

1 release file

1.5.80

1 release file

1.5.79

1 release file

1.5.75

2 release files

1.5.74

2 release files

1.5.73

2 release files

1.5.72

2 release files

1.5.71

2 release files

1.5.70

2 release files

1.5.68

2 release files

1.5.66

2 release files

1.5.65

2 release files

1.5.64

2 release files

1.5.63

2 release files

1.5.62

2 release files

1.5.61

2 release files

1.5.55

2 release files

1.5.54

2 release files

1.5.53

2 release files

1.5.51

2 release files

1.5.50

2 release files

1.5.49

2 release files

1.5.48

2 release files

1.5.47

2 release files

1.5.46

2 release files

1.5.45

2 release files

1.5.44

2 release files

1.5.43

2 release files

1.5.32

2 release files

1.5.31

2 release files

1.5.30

2 release files

1.5.29

2 release files

1.5.28

2 release files

1.5.27

2 release files

1.5.26

2 release files

1.5.25

2 release files

1.5.24

2 release files

1.5.23

2 release files

1.5.19

2 release files

1.5.18

2 release files

1.5.17

2 release files

1.5.16

2 release files

1.5.15

2 release files

1.5.14

2 release files

1.5.13

2 release files

1.5.12

2 release files

1.5.11

2 release files

1.5.10

2 release files

1.5.7

2 release files

1.5.6

2 release files

1.5.5

2 release files

1.5.3

2 release files

1.4.23

2 release files

1.4.22

2 release files

1.4.21

2 release files

1.4.20

2 release files

1.4.19

2 release files

1.4.18

2 release files

1.4.17

2 release files

1.4.16

2 release files

1.4.15

2 release files

1.4.14

2 release files

1.4.13

2 release files

1.4.9

2 release files

1.4.8

2 release files

1.4.7

2 release files

1.4.6

2 release files

1.4.5

1 release file

1.4.4

2 release files

1.4.3

2 release files

1.4.2

2 release files

1.4.1

2 release files

1.3.21

1 release file

1.3.19

1 release file

1.3.17

1 release file

1.3.16

1 release file

1.3.15

1 release file

1.3.14

1 release file

1.3.13

1 release file

1.3.8

1 release file

1.3.7

1 release file

1.3.6

1 release file

1.3.4

1 release file

1.3.2

1 release file

1.3.0

1 release file

1.2.29

1 release file

1.2.27

1 release file

1.2.24

1 release file

1.2.22

1 release file

1.2.20

1 release file

1.2.18

1 release file

1.2.15

1 release file

1.2.14

1 release file

1.2.13

1 release file

1.2.11

1 release file

1.2.10

1 release file

1.2.9

1 release file

1.2.8

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page