Flutter pub上传失败问题 记录

核心:翻墙,终端代理,去掉镜像系统变量

一,pub:

官方描述: Pub is the package manager for Dart. / dart 语言的包管理器

官网Url
https://pub.dartlang.org

这个域名有多个小伙伴同时 ping 过, 对应 ip 不相同,所以可知这个网站是有负载均衡的, 但是坑的地方来了, 部分在墙外,所以这就是这个网站偶尔国内访问不通畅的原因。

ping pub.dartlang.org

正在 Ping ghs.googlehosted.com [216.58.200.243] 具有 32 字节的数据:
来自 216.58.200.243 的回复: 字节=32 时间=58ms TTL=40
来自 216.58.200.243 的回复: 字节=32 时间=58ms TTL=40
来自 216.58.200.243 的回复: 字节=32 时间=58ms TTL=40
来自 216.58.200.243 的回复: 字节=32 时间=58ms TTL=40

216.58.200.243 的 Ping 统计信息:
    数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失),
往返行程的估计时间(以毫秒为单位):
    最短 = 58ms,最长 = 58ms,平均 = 58ms

国内镜像站点eg
https://pub.flutter-io.cn/

设置访问镜像
在环境变量中配置,这个根据系统不同设置方法不同:

  1. mac:
    1.1 可以使用 export 命令临时添加
    1.2 也可以在vi ~/.bash_profile,在这个文件中添加

  2. win 在系统变量中

PUB_HOSTED_URL=https://pub.flutter-io.cn
FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn

二,Package:

使用package可以创建可轻松共享的模块化代码。
一个最小的package包括:

  • 一个pubspec.yaml文件:声明了package的名称、版本、作者等的元数据文件。
  • 一个 lib 文件夹:包括包中公开的(public)代码,最少应有一个<package-name>.dart文件

三,Package类型:

  • Dart包:其中一些可能包含Flutter的特定功能,因此对Flutter框架具有依赖性,仅将其用于Flutter,例如fluro包。
  • 插件包:一种专用的Dart包,其中包含用Dart代码编写的API,以及针对Android(使用Java或Kotlin)和/或针对iOS(使用ObjC或Swift)平台的特定实现。一个具体的例子是battery插件包。

四,相关文档:

  • README.md: 介绍包的文件
  • CHANGELOG.md:记录每个版本中的更改
  • LICENSE:包含软件包许可条款的文件

五,发布packages:

有的时候我们自己写了开源库,想要发布到 pub 上怎么办呢?
dart/flutter 对于插件没有审核的概念,而且发布很简单,你可以任意发布插件到 pub 上,只要不重复就可以了,这样其他开发人员就可以轻松使用它。
发布之前,检查pubspec.yaml、README.md以及CHANGELOG.md文件,以确保其内容的完整性和正确性。

前提:

1. 代码

2. 命令行翻墙工具
命令行翻墙工具是因为国内镜像发布不了,必须要连接到 pub 的官方源

3. google 账号
google 账号是确定权限用的,绑定库和你的作者身份, 防止别人覆盖你的插件

终端翻墙

这里因为涉及到连接 google,所以你必须保证你的终端翻墙了

** mac:**
输入curl google.com,如果有成功的回文(一个 html 格式的文本信息)说明成功了,如果没有就说明你的终端还在墙内,你需要自行保证 curl 能连接成功

SS(小飞机) 的终端 http 协议翻墙可以简单在终端输入:

export http_proxy=http://127.0.0.1:1081;
export https_proxy=http://127.0.0.1:1081;

** win:**
我用的自由门:连通成功后会显示端口号。
win环境终端不能执行:curl指令,可以通过git bash看下

发布步骤:


1.运行 dry-run 命令以查看是否都准备OK了,有问题根据提示修改下,一般都是信息补全的提示。

flutter packages pub publish --dry-run

|       |-- search_input
|       |   '-- search_input.dart
|       '-- sliver
|           |-- pinned_appbar.dart
|           '-- safearea_header.dart
|-- pubspec.yaml
'-- test
    '-- flutterlib_test.dart

Looks great! Are you ready to upload your package (y/n)? 终止批处理操作吗(Y/N)? Y

或者:
Missing requirements:
* Your pubspec.yaml is missing a "homepage" field.
-- authors已经不需要了


2.运行发布命令:

flutter packages pub publish

拓展:
2.1 可通过带上 -v 查看更加详细的信息
2.2 如果开了vpn还是不行的,可以尝试使用--server
flutter packages pub publish --server=https://pub.dartlang.org
将地址指向官方的,而不是国内镜像。


|       |-- search_input
|       |   '-- search_input.dart
|       '-- sliver
|           |-- pinned_appbar.dart
|           '-- safearea_header.dart
|-- pubspec.yaml
'-- test
    '-- flutterlib_test.dart

Looks great! Are you ready to upload your package (y/n)? y
Pub needs your authorization to upload packages on your behalf.
In a web browser, go to https://accounts.google.com/o/oauth2/auth?access_type=offline&approval_prompt=force&response_type=code&client_id=818368
855108-8grd2eg9tj9f38os6f1urbcvsq399u8n.apps.googleusercontent.com&redirect_uri=http%3A%2F%2Flocalhost%3A49996&scope=openid+https%3A%2F%2Fwww.g
oogleapis.com%2Fauth%2Fuserinfo.email
Then click "Allow access".

Waiting for your authorization...
Authorization received, processing...
Successfully authorized.
Uploading...
Failed to upload the package.
pub finished with exit code 1


注意事项:
1.如果是第一次发布包,需要google账号认证授权,认证成功后,后面就不需要认证的操作了。
2.如果你没有出现 google 帐号授权那个 url 只有两种情况,一个是你以前授权过,二是你连接失败了。
3.认证成功效果:https://upload-images.jianshu.io/upload_images/2097746-6d17aacb2fff4ed7.png?imageMogr2/auto-orient/strip|imageView2/2/w/1200/format/webp

|       '-- sliver
|           |-- pinned_appbar.dart
|           '-- safearea_header.dart
|-- pubspec.yaml
'-- test
    '-- flutterlib_test.dart

Looks great! Are you ready to upload your package (y/n)? y
Uploading...
Failed to upload the package.
pub finished with exit code 1


2.通过 -v的效果,能看到具体的报错信息:

MSG : Uploading...
IO  : HTTP GET https://pub.dartlang.org/api/packages/versions/new
    | Accept: application/vnd.pub.v2+json
    | authorization: <censored>
    | user-agent: Dart pub 2.7.2
FINE: Uploading finished (21.090s).
FINE: Saving OAuth2 credentials.
IO  : Writing 466 characters to text file D:\Program Files\flutter\.pub-cache\credentials.json.
ERR : Proxy failed to establish tunnel (400 Bad Request)
FINE: Exception type: ClientException
FINE: package:http/src/io_client.dart 65:7        IOClient.send
    | ===== asynchronous gap ===========================
    | dart:async                                  Future.catchError
    | package:pub/src/utils.dart 109:52           captureErrors.<fn>
    | package:stack_trace                         Chain.capture
    | package:pub/src/utils.dart 122:11           captureErrors
    | package:pub/src/command_runner.dart 171:13  PubCommandRunner.runCommand
    | dart:async                                  _completeOnAsyncReturn
    | package:pub/src/command_runner.dart         PubCommandRunner._validatePlatform
    | dart:async                                  _completeOnAsyncReturn
    | package:pub/src/io.dart                     runProcess.<fn>
pub finished with exit code 69

#0      throwToolExit (package:flutter_tools/src/base/common.dart:28:3)
#1      _DefaultPub.interactively (package:flutter_tools/src/dart/pub.dart:323:7)
<asynchronous suspension>
#2      PackagesPassthroughCommand.runCommand (package:flutter_tools/src/commands/packages.dart:269:15)
#3      FlutterCommand.verifyThenRunCommand (package:flutter_tools/src/runner/flutter_command.dart:615:18)
#4      _asyncThenWrapperHelper.<anonymous closure> (dart:async-patch/async_patch.dart:73:64)
#5      _rootRunUnary (dart:async/zone.dart:1134:38)
#6      _CustomZone.runUnary (dart:async/zone.dart:1031:19)
#7      _FutureListener.handleValue (dart:async/future_impl.dart:139:18)


3.通过 flutter doctor查看环境问题:

D:\workspace1\flutterlib>flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[√] Flutter (Channel stable, v1.12.13+hotfix.9, on Microsoft Windows [Version 10.0.14393], locale zh-CN)

[√] Android toolchain - develop for Android devices (Android SDK version 29.0.2)
[√] Android Studio (version 3.6)
[!] Proxy Configuration
    ! NO_PROXY is not set
[√] Connected device (1 available)

! Doctor found issues in 1 category.


4.如果终端没有成功设置代理,无法正常访问google账号

|       '-- sliver
|           |-- pinned_appbar.dart
|           '-- safearea_header.dart
|-- pubspec.yaml
'-- test
    '-- flutterlib_test.dart

Looks great! Are you ready to upload your package (y/n)? y
Uploading...
It looks like accounts.google.com is having some trouble.
Pub will wait for a while before trying to connect again.


5.上传成功的效果:

|       '-- sliver
|           |-- pinned_appbar.dart
|           '-- safearea_header.dart
|-- pubspec.yaml
'-- test
    '-- flutterlib_test.dart

Looks great! Are you ready to upload your package (y/n)? y
Uploading...
Successfully uploaded package.


上传的库在pub上可以看到:
https://pub.flutter-io.cn/packages/flutterlib

六,发布packages失败的问题:

  1. 谷歌邮箱验证成功,却报了一个错误,无法访问accounts.google.com。
It looks like accounts.google.com is having some trouble.
Pub will wait for a while before trying to connect again.

方案:设置终端代理(端口号是翻墙工具里面连通的端口),代理设置后,重新上传。
设置代理不要用sock5协议,不然可能会出现Invalid request method

export http_proxy=http://127.0.0.1:1080
export https_proxy=http://127.0.0.1:1080

set http_proxy=http://127.0.0.1:8580
set https_proxy=https://127.0.0.1:8580

思考:这里我也设置了,但是上传还是失败,没有定位到具体原因。(可能需要重启终端)

Github解决方案:
https://github.com/flutter/flutter/issues/17070

  1. Failed to upload the package
Uploading...
Failed to upload the package.
pub finished with exit code 1

方案:
1.Android Studio中系统设置的配置的HTTP Proxy可能你CHeck connection是有效的,但是还是会出现以上问题,需要在Terminal中输入以下命令,重新执行本步骤。
set http_proxy=http://127.0.0.1:8580
set https_proxy=https://127.0.0.1:8580


2.如果按照官网推荐设置了镜像:
export PUB_HOSTED_URL=https://pub.flutter-io.cn
export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn
一定要在上传前注释掉,win环境去掉对应系统变量。


3.Github解决方案:
https://github.com/flutter/flutter/issues/16658


网上有说权限不够:
sudo flutter packages pub publish -v
但是win环境不能执行sudo,不得而知。

贴一下网上讨论:

sharpron commented on 22 Jul 2019
我用的windows翻了墙还是不行,换mac后解决

 @yuxuelian
yuxuelian commented on 21 Aug 2019
我也是 Windows 报同样的错误 我终端可以curl www.google.com,但是仍然失败

有很多网友,很多开发着都遇到了这样的问题,没有解决。
也从侧面说明win环境对这个兼容不是很友好。

  1. win环境最终成功的经历:
1.首先也是根据网上说的步骤经过一些列疯狂的操作,发现怎么都是长传失败,认证也成功了,
最后也没有出现无法访问google账号的提示,就是上传失败。

2.想着提升下win权限,mac sodu的操作试试这个,通过:
打开命令提示符,输入命令“taskkill /f /im explorer.exe” 并回车
命令提示符下继续输入“at time /interactive %systemroot%explorer.exe”并回车。
直接卡死黑屏了。

3.然后重新开机打开studio,设置http proxy代理(http,https),打开翻墙软件,然后又在终端设置:
set http_proxy=http://127.0.0.1:8580
set https_proxy=https://127.0.0.1:8580
尝试了两次最后成功上传了。


总结思考:
1.核心问题还是墙的问题,给终端设置代理,让终端也能翻墙,并且保证能设置代理成功。
win环境不像mac那样对命令行那样友好,设置代理如果还是不成功,可以考虑重启电脑后再试试。

参考:
https://flutterchina.club/developing-packages/

推荐阅读更多精彩内容