Flutter 插件发布到 pub.dev 操作手册

本文记录 Flutter 插件首次发布、GitHub Actions 自动发布、国内镜像处理和常见问题。

适用于:

  • Flutter Plugin
  • Flutter Package
  • Dart Package
  • macOS/Linux 开发环境
  • GitHub Actions 自动发布

一、整体发布流程

首次发布

rust 复制代码
完善插件资料
  ↓
本地检查
  ↓
切换到官方 pub.dev 源
  ↓
执行 dart pub publish
  ↓
使用 Google 账号完成授权
  ↓
在 pub.dev 配置 GitHub Actions 自动发布

pub.dev 目前只允许自动发布已经存在的包。因此,0.0.1 等第一个版本必须在本地使用 dart pub publish 发布,后续版本才能通过 GitHub Actions 自动发布。(Dart)

后续版本

复制代码
修改代码
  ↓
更新版本号
  ↓
更新 CHANGELOG.md
  ↓
提交代码
  ↓
创建 Git Tag
  ↓
推送 Tag
  ↓
GitHub Actions 自动发布

二、发布前准备

2.1 必要文件

插件根目录建议至少包含:

bash 复制代码
lib/
example/
test/
README.md
CHANGELOG.md
LICENSE
pubspec.yaml
analysis_options.yaml

其中:

文件 用途
README.md pub.dev 插件首页的主要内容
CHANGELOG.md 展示每个版本的更新记录
LICENSE 开源许可证,发布时必须提供
pubspec.yaml 插件名称、版本、依赖和仓库信息
example/ 插件使用示例
test/ 自动化测试

pub.dev 会使用 README.mdCHANGELOG.mdpubspec.yaml 生成插件页面;发布包必须包含 LICENSE。(Dart)


2.2 检查 pubspec.yaml

示例:

yaml 复制代码
name: ifl_table

description: A flexible and customizable table widget for Flutter applications.

version: 0.0.1

repository: https://github.com/your-name/ifl_table
issue_tracker: https://github.com/your-name/ifl_table/issues

environment:
  sdk: ^3.5.0
  flutter: ">=3.24.0"

dependencies:
  flutter:
    sdk: flutter

dev_dependencies:
  flutter_test:
    sdk: flutter
  flutter_lints: ^5.0.0

重点检查:

复制代码
name
description
version
repository
environment
dependencies

name

包名必须:

  • 全部小写;
  • 使用下划线分隔;
  • 只能包含 [a-z0-9_]
  • 不能以数字开头;
  • 不能和 pub.dev 已有包重名。

例如:

makefile 复制代码
name: ifl_table

description

描述需要使用英文,建议简洁说明插件解决的问题。

lua 复制代码
description: A flexible and customizable table widget for Flutter applications.

version

使用语义化版本:

makefile 复制代码
version: 主版本.次版本.修订版本

例如:

复制代码
0.0.1
0.1.0
1.0.0
1.0.1

已经发布过的版本不能修改后重新覆盖,任何修改都必须增加版本号。(Dart)

repository

填写插件实际对应的 GitHub 仓库:

arduino 复制代码
repository: https://github.com/your-name/ifl_table

如果没有单独配置 issue_tracker,且 repository 指向 GitHub,pub.dev 通常会使用仓库的 Issues 页面。(Dart)


2.3 不要配置错误的 publish_to

如果发布到官方 pub.dev,通常不要写 publish_to

bash 复制代码
# 不需要配置
# publish_to: ...

下面的配置会禁止发布:

makefile 复制代码
publish_to: none

下面的配置会尝试发布到其他仓库:

arduino 复制代码
publish_to: https://example.com

publish_to 用于指定非 pub.dev 仓库,或者通过 none 阻止包被发布。(Dart)


三、本地发布前检查

在插件根目录执行:

css 复制代码
flutter pub get

dart format --output=none --set-exit-if-changed .

flutter analyze

flutter test

dart pub publish --dry-run

3.1 dry-run 的作用

arduino 复制代码
dart pub publish --dry-run

该命令不会真正发布,主要用于:

  • 检查 pubspec.yaml
  • 检查目录结构;
  • 检查依赖;
  • 显示即将上传的文件;
  • 显示发布警告。

官方建议在真正上传前,认真检查 dry-run 输出的文件列表,避免上传无关文件或隐私文件。(Dart)


3.2 检查 Git 状态

执行:

lua 复制代码
git status

建议确保:

vbnet 复制代码
nothing to commit, working tree clean

如果还有改动,先提交:

sql 复制代码
git add .
git commit -m "chore: prepare release 0.0.1"
git push

dart pub publish 会检查 Git 状态,并在存在未提交改动时给出警告。(Dart)


3.3 检查发布文件

dart pub publish --dry-run 会列出准备上传的所有文件。

不应上传的内容包括:

bash 复制代码
.idea/
.vscode/
build/
.dart_tool/
*.jks
*.keystore
*.p12
*.mobileprovision
.env
私钥
Token
测试账号密码
无关截图或大型文件

一般情况下,pub 会忽略:

  • . 开头的隐藏文件;
  • .gitignore 中忽略的文件;
  • .pubignore 中忽略的文件。

如果希望发布规则与 Git 忽略规则不同,可以创建 .pubignore。(Dart)


四、处理国内 pub 镜像

4.1 常见错误

发布时出现:

vbnet 复制代码
Do you want to publish ifl_table 0.0.1 to
https://pub.flutter-io.cn (y/N)?

或者:

csharp 复制代码
package repository requested authentication!

dart pub token add https://pub.flutter-io.cn

Authentication failed!

这说明当前终端配置了:

ini 复制代码
PUB_HOSTED_URL=https://pub.flutter-io.cn

PUB_HOSTED_URL 会把 Dart 默认包仓库切换成指定的镜像服务器。(Dart)

这里不应该给国内镜像添加 Token,因为真正的发布目标应该是:

arduino 复制代码
https://pub.dev

4.2 查看当前配置

macOS/Linux:

bash 复制代码
echo $PUB_HOSTED_URL

如果输出:

arduino 复制代码
https://pub.flutter-io.cn

说明当前使用的是国内镜像。


4.3 临时取消镜像

只对当前终端生效:

bash 复制代码
unset PUB_HOSTED_URL

再次确认:

bash 复制代码
echo $PUB_HOSTED_URL

没有任何输出即可。

然后重新执行:

rust 复制代码
dart pub publish --dry-run
dart pub publish

确认提示中的地址为:

arduino 复制代码
https://pub.dev

4.4 只在发布命令中取消镜像

也可以不修改当前终端环境,直接执行:

arduino 复制代码
env -u PUB_HOSTED_URL dart pub publish --dry-run

正式发布:

bash 复制代码
env -u PUB_HOSTED_URL dart pub publish

4.5 永久删除镜像配置

检查 Shell 配置文件:

bash 复制代码
grep -n "PUB_HOSTED_URL" \
  ~/.zshrc \
  ~/.zprofile \
  ~/.bash_profile \
  ~/.bashrc \
  2>/dev/null

找到:

arduino 复制代码
export PUB_HOSTED_URL=https://pub.flutter-io.cn

删除或者注释:

shell 复制代码
# export PUB_HOSTED_URL=https://pub.flutter-io.cn

然后重新加载:

bash 复制代码
source ~/.zshrc

五、首次发布插件

5.1 正式发布

确保当前目录是插件根目录,然后执行:

rust 复制代码
dart pub publish

正确的确认信息应该是:

vbnet 复制代码
Do you want to publish ifl_table 0.0.1 to https://pub.dev (y/N)?

确认:

  • 包名正确;
  • 版本号正确;
  • 地址是 https://pub.dev
  • 上传文件没有问题。

然后输入:

复制代码
y

5.2 登录授权

第一次发布时,终端通常会:

  • 自动打开浏览器;或者
  • 输出一个登录授权地址。

使用 Google 账号登录并授权。

首次成功发布包的账号,会成为该包最初的 uploader,并具有后续版本发布权限。(Dart)


5.3 发布成功后检查

发布完成后检查:

rust 复制代码
插件首页
README 展示
CHANGELOG 展示
支持的平台
源码仓库链接
API 文档
示例代码
版本号
pub points

pub.dev 的分析可能不会立即完成,插件页面刚发布时部分评分和平台检测可能仍在处理中。


六、配置 GitHub Actions 自动发布

首次版本发布成功后,才能配置自动发布。(Dart)

6.1 在 pub.dev 配置仓库

进入插件的 Admin 页面:

bash 复制代码
pub.dev/packages/ifl_table/admin

找到:

复制代码
Automated publishing

点击:

csharp 复制代码
Enable publishing from GitHub Actions

填写 GitHub 仓库:

复制代码
GitHub用户名/仓库名

例如:

bash 复制代码
your-name/ifl_table

Tag Pattern 填写:

复制代码
v{{version}}

对应关系:

makefile 复制代码
pubspec.yaml:version: 0.0.2
Git Tag:     v0.0.2

仓库地址、Tag Pattern 和 pubspec.yaml 版本必须相互匹配。(Dart)


6.2 GitHub Actions 配置

创建:

bash 复制代码
.github/workflows/publish.yml

内容:

yaml 复制代码
name: Publish to pub.dev

on:
  push:
    tags:
      - 'v[0-9]+.[0-9]+.[0-9]+'

jobs:
  publish:
    permissions:
      id-token: write

    uses: dart-lang/setup-dart/.github/workflows/publish.yml@v1

该工作流使用 GitHub OIDC 临时凭证,不需要在 GitHub Secrets 中保存长期的 pub.dev Token。官方推荐优先使用 Dart 团队提供的 reusable workflow。(Dart)


6.3 插件不在仓库根目录

如果仓库结构是:

markdown 复制代码
repository/
├── apps/
└── packages/
    └── ifl_table/
        ├── pubspec.yaml
        └── lib/

配置:

yaml 复制代码
name: Publish ifl_table to pub.dev

on:
  push:
    tags:
      - 'ifl_table-v[0-9]+.[0-9]+.[0-9]+'

jobs:
  publish:
    permissions:
      id-token: write

    uses: dart-lang/setup-dart/.github/workflows/publish.yml@v1

    with:
      working-directory: packages/ifl_table

pub.dev 中的 Tag Pattern 对应设置为:

复制代码
ifl_table-v{{version}}

一个仓库中包含多个包时,官方建议为不同的包使用独立 Tag Pattern 和独立发布工作流。(Dart)


七、发布后续版本

假设当前版本为:

makefile 复制代码
version: 0.0.1

准备发布:

makefile 复制代码
version: 0.0.2

7.1 修改版本号

makefile 复制代码
version: 0.0.2

7.2 更新 CHANGELOG.md

markdown 复制代码
## 0.0.2

- Fixed table layout issues.
- Improved documentation.
- Added new configuration options.

建议将最新版本放在最上面。


7.3 本地检查

css 复制代码
flutter pub get
dart format --output=none --set-exit-if-changed .
flutter analyze
flutter test
env -u PUB_HOSTED_URL dart pub publish --dry-run

7.4 提交代码

sql 复制代码
git add .
git commit -m "chore: release 0.0.2"
git push origin main

7.5 创建并推送 Tag

perl 复制代码
git tag v0.0.2
git push origin v0.0.2

推送 Tag 后,GitHub Actions 会自动运行并发布插件。pub.dev 要求自动发布工作流由 Git Tag push 触发,普通分支 push 或无 Tag 的工作流触发会被拒绝。(Dart)

可以在 GitHub 仓库的 Actions 页面查看发布日志。(Dart)


八、版本号规则

建议遵循:

复制代码
MAJOR.MINOR.PATCH
主版本.次版本.修订版本

修复问题

例如:

复制代码
0.0.1 → 0.0.2
1.0.0 → 1.0.1

适用于:

  • 修复 Bug;
  • 修改文档;
  • 优化性能;
  • 不破坏现有 API 的小改动。

新增兼容功能

例如:

复制代码
0.1.0 → 0.2.0
1.1.0 → 1.2.0

适用于:

  • 新增参数;
  • 新增组件;
  • 新增平台支持;
  • 新增功能,同时保持向后兼容。

存在破坏性修改

例如:

复制代码
1.4.0 → 2.0.0

适用于:

  • 删除公开 API;
  • 修改参数含义;
  • 修改返回类型;
  • 用户必须修改代码才能升级。

预发布版本

例如:

makefile 复制代码
version: 1.0.0-dev.1
version: 1.0.0-alpha.1
version: 1.0.0-beta.1
version: 1.0.0-rc.1

适合测试尚未完全稳定的新版本。pub.dev 支持在版本号后添加 prerelease 后缀。(Dart)


九、常见问题

9.1 发布地址是 pub.flutter-io.cn

原因:

复制代码
配置了 PUB_HOSTED_URL

处理:

bash 复制代码
unset PUB_HOSTED_URL
dart pub publish

或者:

bash 复制代码
env -u PUB_HOSTED_URL dart pub publish

9.2 Authentication failed

先检查发布地址。

如果地址是:

arduino 复制代码
https://pub.flutter-io.cn

不要执行:

csharp 复制代码
dart pub token add https://pub.flutter-io.cn

应取消国内镜像,重新发布到:

arduino 复制代码
https://pub.dev

dart pub token 主要用于需要认证的第三方或私有包仓库。(Dart)


9.3 Package name already exists

说明包名已经被其他人占用。

需要修改:

makefile 复制代码
name: 新的包名

包名在整个 pub.dev 中必须唯一。


9.4 Version already exists

例如 0.0.1 已发布,再次发布相同版本会失败。

修改:

makefile 复制代码
version: 0.0.2

同时更新:

复制代码
CHANGELOG.md
Git Tag

已经发布的版本不可覆盖。(Dart)


9.5 GitHub Action 没有触发

检查以下三处是否一致:

css 复制代码
pubspec.yaml:
version: 0.0.2

pub.dev Tag Pattern:
v{{version}}

实际 Git Tag:
v0.0.2

再检查 workflow:

ini 复制代码
on:
  push:
    tags:
      - 'v[0-9]+.[0-9]+.[0-9]+'

如果推送的是:

复制代码
0.0.2

而 workflow 只匹配:

复制代码
v0.0.2

则不会触发。(Dart)


9.6 Action 触发但认证失败

检查工作流是否包含:

yaml 复制代码
permissions:
  id-token: write

以及是否使用:

arduino 复制代码
uses: dart-lang/setup-dart/.github/workflows/publish.yml@v1

同时确认已经在 pub.dev 的 Admin 页面中绑定正确的 GitHub 仓库和 Tag Pattern。(Dart)


9.7 发布了错误版本怎么办

已发布版本通常不能直接删除。

如果只是普通 Bug,推荐:

  1. 修复问题;
  2. 增加版本号;
  3. 更新 CHANGELOG.md
  4. 发布新版本。

pub.dev 支持在发布后的七天内 retract 某个版本,但 retract 并不等于删除,且通常应该优先发布修复版本。(Dart)


十、Verified Publisher

个人插件可以直接使用 Google 账号发布。

公司或组织维护的插件,可以创建 Verified Publisher,用公司域名展示发布者身份。

当前新包不能直接通过命令发布到 Verified Publisher。通常流程是:

复制代码
个人 Google 账号首次发布
  ↓
进入插件 Admin 页面
  ↓
将插件转移到 Verified Publisher

转移到 Verified Publisher 后不能再转回个人账号,因此操作前需要确认归属。(Dart)


十一、推荐发布命令

首次发布

css 复制代码
flutter pub get

dart format --output=none --set-exit-if-changed .

flutter analyze

flutter test

git status

env -u PUB_HOSTED_URL dart pub publish --dry-run

env -u PUB_HOSTED_URL dart pub publish

后续自动发布

0.0.2 为例:

sql 复制代码
flutter pub get

dart format --output=none --set-exit-if-changed .

flutter analyze

flutter test

env -u PUB_HOSTED_URL dart pub publish --dry-run

git add .

git commit -m "chore: release 0.0.2"

git push origin main

git tag v0.0.2

git push origin v0.0.2

十二、发布检查清单

插件资料

  • 包名没有被占用
  • description 使用英文
  • README.md 内容完整
  • CHANGELOG.md 已更新
  • 存在 LICENSE
  • repository 地址正确
  • example/ 可以运行
  • 公开 API 有必要的注释

代码质量

  • dart format 通过
  • flutter analyze 通过
  • flutter test 通过
  • 没有密钥、密码和 Token
  • 没有无关的大文件
  • Git 工作区已提交

发布配置

  • pubspec.yaml 版本号正确
  • 没有 publish_to: none
  • 已取消 PUB_HOSTED_URL
  • dry-run 没有错误
  • 发布地址是 https://pub.dev

自动发布

  • 第一个版本已经手动发布
  • pub.dev 已绑定 GitHub 仓库
  • Tag Pattern 配置为 v{{version}}
  • workflow 包含 id-token: write
  • Git Tag 与版本号一致
  • CHANGELOG.md 与版本号一致

十三、最简发布流程

以后发布新版本,只需要记住下面几步:

markdown 复制代码
1. 修改 pubspec.yaml 版本号
2. 更新 CHANGELOG.md
3. 执行 flutter analyze 和 flutter test
4. 执行 dart pub publish --dry-run
5. 提交并推送代码
6. 创建与版本号一致的 Git Tag
7. 推送 Tag,等待 GitHub Actions 发布

示例:

perl 复制代码
git add .
git commit -m "chore: release 0.0.2"
git push origin main
git tag v0.0.2
git push origin v0.0.2
相关推荐
花燃柳卧19 小时前
跨平台路由组件工程源码补充上传
android·flutter·kotlin
心中有国也有家20 小时前
E-Brufen 技术选型全景:Flutter + 鸿蒙 + Hive CE
hive·hadoop·学习·flutter·华为·harmonyos
Mandy的名字被占用了1 天前
Dart 与 Flutter 快速入门指南
后端·flutter·dart
心中有国也有家1 天前
离线优先:无网络权限的鸿蒙 Flutter 应用设计
网络·学习·flutter·华为·harmonyos
心中有国也有家1 天前
Flutter 鸿蒙编译与构建流程深度解析
学习·flutter·华为·harmonyos
心中有国也有家2 天前
使用 DevEco Studio 配置 Flutter 鸿蒙签名
学习·flutter·华为·harmonyos
nice先生的狂想曲2 天前
Stream与StreamController以及对应的使用场景
flutter·客户端
心中有国也有家2 天前
鸿蒙Flutter开发环境从零搭建教程(Windows/macOS双平台·避坑版)
学习·flutter·华为·harmonyos
心中有国也有家2 天前
Flutter 鸿蒙适配第一步:从 hive 迁移到 hive\_ce
hive·学习·flutter·华为·harmonyos