背景

今天写了一个轻量级的 adbutils 库,感觉写的还可以,结果发布到 pypi 上的时候 遇到了各种水坑。趁还没忘记,赶紧整理下。
本文并不打算把所有的方法都列出来,只提供一种我认为最好的。

用到了 pbr, travis

Github 上新建一个项目

参考:https://docs.openstack.org/pbr/latest/index.html

点击创建一个新项目 https://github.com/new 这里我们起名叫 fibonacci

项目中必要的文件

- setup.py
- setup.cfg
- requirements.txt
- fibonacci
   \- __init__.py

setup.py的内容很简单,主要功能就是引入 pbr

# coding: utf-8

import setuptools
setuptools.setup(setup_requires=['pbr'], pbr=True)

# For Py3 only project
# setuptools.setup(setup_requires=['pbr'], pbr=True, python_requires='>=3.6')

setup.cfg内容稍微多一点,这里只列出一个最精简的

[metadata]
name = fibonacci
license = MIT

[files]
packages =
    fibonacci

requirements.txt 里面为该库用到的依赖。pbr 会自动解析的

fibonacci/__init__.py 这个文件我们简单的实现了一个斐波那契函数

# coding: utf-8

def fib(n):
    a, b = 0, 1
    for _ in range(n):
        yield a
        a, b = b, a + b

本来想写个超简单的 fib 函数,怕你们嘲笑我 _^

本地 PyPi 发布

参考资料:https://docs.python.org/3.1/distutils/packageindex.html#pypirc

先去 pypi 官网注册个账户 https://pypi.org/account/register/

注册完之后,在 HOME 目录下,新建一个 .pypirc文件。

[distutils]
index-servers =
    pypi

[pypi]
# repository: http://www.python.org/pypi  # 默认就是这个
username: <改成你的用户名>
password: <改成你的密码>

然后再项目的目录下运行 python setup.py sdist upload
理论上应该是上传不成功的,并提示 403(Forbidden 错误)因为这个项目名已经被别人占了

error: Upload failed (403): The user 'codeskyblue' isn't allowed to upload to project 'fibonacci'. See https://pypi.org/help/#project-name for more information.

不过没关系,我们换个名字,打开setup.cfg,name 字段后面加上你的 github 账户名。比如我的改成了name = fibonacci-codeskyblue

这次应该可以愉快的发现上传成功了

Creating tar archive
removing 'fibonacci-codeskyblue-0.0.0' (and everything under it)
running upload
Submitting dist\fibonacci-codeskyblue-0.0.0.tar.gz to https://upload.pypi.org/legacy/
Server response (200): OK

这里看到我们的版本号是0.0.0,是不是很奇怪。因为 pbr 是根据项目的git tag来确定当前的版本号的。
所以我们打一个 tag 重新 upload 一次。

git tag 0.1.0
python setup.py sdist upload

这次的版本号,看到就是0.1.0了。

集成到 TravisCI 自动发布

参考资料:

安装 travis 命令行

这里推荐用 Mac,因为只要一个命令就可以装上 brew install travis
其他系统的安装方法看这里 https://github.com/travis-ci/travis.rb#installation

配置 travis.yml 文件

$ travis login
# 这里会提示输入github的用户名,密码。
Username:
Password: 

$ travis init
# 创建 .travis.yml 文件,如果已经创建过了,可以忽略
Detected repository as codeskyblue/fibonacci, is this correct? |yes| 
repository not known to Travis CI (or no access?)
triggering sync: .. done
Main programming language used: |Ruby| Python
.travis.yml file created!
codeskyblue/fibonacci: enabled :)

$ travis setup pypi
# 下面要输入的是pypi上注册的密码,一定要小心的输入,因为它根本不会校验你输入的到底对不对
Username: codeskyblue
Password: **********
release only tagged commits? |yes| 
deploy as wheel file too? |yes| 
Release only from codeskyblue/fibonacci? |yes| 
Encrypt Password? |yes|

密码加密成一个很长很长只有 travis 才能读懂的字符串。所以不用担心密码会从文本泄漏。

这里生成的.travis.yml文件还需要稍微改动一下。如下是命令生成的一个 example travis.yml

language: python
python:
- '2.7'
- '3.3'
- pypy
deploy:
  provider: pypi
  user: codeskyblue
  password:
    secure: bxCjcSCF.....还有很长很长....KDHJFLKJLJFSsdf
  on:
    tags: true
    distributions: sdist bdist_wheel
    repo: codeskyblue/fibonacci

deploy上面加上 script: echo skip test
deploy下面增加skip_existing: true 变成

script: echo skip test
deploy:
  skip_existing: true
  provider: pypi

skip_existting可以避免多次运行的时候,报上传文件已存在的错误。script是必须的一个字段

OK 之后,将修订提交到

# 提交到git上
$ git add .travis.yml
$ git commit -m "add travis.yml"
$ git push

这时就可以看到 .travis.yml文件生成了。前往 https://travis-ci.org/codeskyblue/fibonacci(注意网址中的用户名要换成自己的),就可以看到 travis 上的 job 情况了。
一般都不会失败的。因为我们就运行了一行命令 echo skip test

下面来检查一下 打 tag, push 到 github 上 是否会自动发布到 pypi 上

$ git tag 0.1.1
$ git push --tags

测试的时候发现 v0.1.1 这样的 tag 不生效。感觉可能是 travis-ci 上的 pbr 版本有点低

发布后测试

$ pip install fibonacci-codeskyblue
$ python
>>> from fibonacci import fib
>>> list(fib(7))
[0, 1, 1, 2, 3, 5, 8]

成品

结束语

终于写完了,耗时 1 小时 15 分钟。回家吃饭了


↙↙↙阅读原文可查看相关链接,并与作者交流