惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

大猫的无限游戏
大猫的无限游戏
Security Archives - TechRepublic
Security Archives - TechRepublic
T
Threat Research - Cisco Blogs
A
Arctic Wolf
S
Securelist
O
OpenAI News
T
Threatpost
Forbes - Security
Forbes - Security
N
News and Events Feed by Topic
S
Secure Thoughts
H
Heimdal Security Blog
S
Security Affairs
P
Privacy International News Feed
C
Cisco Blogs
C
CERT Recently Published Vulnerability Notes
Cyberwarzone
Cyberwarzone
N
News and Events Feed by Topic
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
P
Palo Alto Networks Blog
S
Security @ Cisco Blogs
Hacker News - Newest:
Hacker News - Newest: "LLM"
博客园 - 三生石上(FineUI控件)
月光博客
月光博客
T
Tailwind CSS Blog
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Hacker News: Ask HN
Hacker News: Ask HN
T
Troy Hunt's Blog
S
SegmentFault 最新的问题
腾讯CDC
V
Visual Studio Blog
Last Week in AI
Last Week in AI
H
Hacker News: Front Page
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Project Zero
Project Zero
WordPress大学
WordPress大学
NISL@THU
NISL@THU
博客园 - 【当耐特】
博客园 - Franky
Webroot Blog
Webroot Blog
博客园_首页
T
Tenable Blog
雷峰网
雷峰网
Google Online Security Blog
Google Online Security Blog
阮一峰的网络日志
阮一峰的网络日志
V2EX - 技术
V2EX - 技术
Recent Commits to openclaw:main
Recent Commits to openclaw:main
L
Lohrmann on Cybersecurity
The Hacker News
The Hacker News

卡瓦邦噶!

服务器高性能网络调优 | 卡瓦邦噶! 为何写作 | 卡瓦邦噶! 读《金阁寺》 | 卡瓦邦噶! 雨季又来 | 卡瓦邦噶! MTU Probe 引起的初始延迟 | 卡瓦邦噶! 3.5 秒的固定延迟问题 | 卡瓦邦噶! 学习网络的一点经验 | 卡瓦邦噶! ARP 问题诊断 | 卡瓦邦噶! 网络断断续续…… | 卡瓦邦噶! Piccolo P2P 镜像分发 | 卡瓦邦噶! 一起看电影 | 卡瓦邦噶! 《征服C指针》 | 卡瓦邦噶! 我的姥姥 | 卡瓦邦噶! Python的哲学 Python 3.5的新特性 学校不教的计算机课 垃圾回收(GC)的三种基本方式 在编程中体验纯粹的快乐 从《美丽新世界》谈自由 在快钱实习 迷人的嗓音和迷人的故事——《Sleepyhead》 Python 的十个自然语言处理工具 记一个愚蠢的bug 一年炉石传说的游戏体验 《以撒的结合:重生》网页版图鉴 分清 C++的指针、引用和数组 笑话三则 自由比皇帝更伟大——《悲惨世界》笔记 Git 10 周年访谈:Linus 讲述背后故事 用 0x3f3f3f3f 设定最大int值的优点 Joel给计算机系学生的建议 一个词法分析器的简单实现 怎样才算健康的生活方式 MacVim 配置攻略 学习培训课程的视频效果好吗? 语言的控制 可悲的大多数 CSS样式思维导图 2014年终总结 奥巴马成为首位写程序的美国总统 青岛老城区的下水道好在哪里? 做优秀 UI 的七个建议(第二部分) 选择爱情的骑士 Git简明教程 Java集合总览 读 《1984》 java问答:终极父类(六)——等待/唤醒和接口 Java 问答:终极父类(五)——toString() Hyperlapse快速视频背后的技术细节 平庸之恶 Java程序员须知的七个日志管理工具 苏州 逛书摊随想 关于考试作弊 你的工作不仅仅是编程 推荐在线学习Java的英文资源 关注女性命运——《千禧年三部曲》 用好你的幻灯片——《演说之禅》 使用ReentrantLock和Lambda表达式让同步更纯净 新手学编程,从哪里开始? 程序员都是工程师吗? 不要学习代码,要学会思考 Java 问答:终极父类(四)——hashCode() Java 问答:终极父类(三)——finalize()和 getClass() 程序员职业之路的选择 我是一名摄影家 写给何小树的城市指南 为什么一些语言会比别的快? Java的常见误区与细节 跟朋友在一起玩游戏 死神永生——读《三体》 五种类型的程序员 创业圣经——读《黑客与画家》 纪念加西亚·马尔克斯 Junit中处理异常的另一种方式:catch-exception Java8采用Martin Fowler的方法创建内部DSL Linux HotSopt虚拟机GC线程的CPU占用率 J2EE概念介绍 如何成为一名黑客 Java 问答:终极父类(二)——equals()方法 为什么我喜欢Java Java 问答:终极父类(一)——clone()方法 七个改变世界的Java项目 java中默认类型转换的小问题 传统与创新 欢迎来到互联网 莫言和马尔克斯——读《生死疲劳》 位运算的妙用 读《人为什么活着》 写博客教会我的事情 中国特色操作系统 2013年总结 《永不妥协》影评 恨不相逢未嫁时——《廊桥遗梦》影评 如何优雅地使用PPT 给明年依然年轻的我们 天才与柱子 黑客守则和黑客精神 Looking for Freedom——《被解救的姜戈》 简洁之道
IRedis 开发记2:CircleCI workflow 自动发布到 pypi
laixintao · 2019-09-02 · via 卡瓦邦噶!

上周末设置了一下在 CircleCI 的流程,之前也讲过如何设置一个 Django 的 CircleCI,那只是一个简单的 CI build。本文讲一下如何设置一个更加复杂和自动化的流程。以及 IRedis 项目最近一些开发进展(项目主页)。

CircleCI 整体的使用体验不错,相比于之前只用了 jobs,这一次引入了 workflow 的概念。workflow 就是先定义好 jobs,然后在 Workflow 中将这些 jobs 组合起来,形成一个完整的开发部署流程。

现在,只要我在 master 分支上打一个 tag,就会触发整个构建流程:

ZSH

1

2

[iredis] iredis git:(master) bumpversion patch

[iredis] iredis git:(master) git push && git push --tags

首先会进行单元测试、black 强制代码风格检查,flake8 检查,全部通过后就会构建一个 pip package,然后测试这个 package 是否可用,确认可用之后上传到 pypi。上传这一步只会在有 tag 的时候执行,如果没有 tag 就说明不是一个新版本,不会上传。

实现方法可以参考这个 PR。总体上是比较简单的,就是用 yaml 文件编排一个 workflow。

这里有一个小坑,是完成“只在有 tag 的时候上传”这个语义实现上。CircleCI 不支持“仅在 Master 分支上,有 tag 的时候执行”这个语义的。即不支持 AND 关系,只支持 OR 关系。

如果你使用下面这种声明方式:

YAML

1

2

3

4

5

6

7

8

      - upload-to-pypi:

          requires:

            - test-release

          filters:

            branches:

              only: master

            tags:

              only: /^v[0-9]+(\.[0-9]+)*$/

那么实际的意思是:

  1. master 分支所有的 commit 都执行;
  2. tag 符合条件的都执行;

即满足任何一个条件都会执行,而不是两者同时满足才会执行。

这个坑踩了很久,才发现一个 work around 的方法:

YAML

1

2

3

4

5

6

7

8

      - upload-to-pypi:

          requires:

            - test-release

          filters:

            branches:

              ignore: /.*/

            tags:

              only: /^v[0-9]+(\.[0-9]+)*$/

这样首先我们忽略所有的 branch,这样所有的分支都不会执行,然后只有在有新 tag 的时候执行。就可以完成上传的需求了。

上传到 Pypi 很简单,首先 pypi.org 提供了针对每一个包设置一个上传 Token 的功能,非常好用,权限最小化。然后 CircleCI 设置一个环境变量,在 CI 中读取这个环境变量即可。配合上传包的命令行工具 twine 可以这么用:

Python

1

2

3

4

5

      - run:

          name: "upload files to pypi: https://pypi.org/project/iredis/#history"

          command: |

            . venv/bin/activate

            twine upload /tmp/workspace/dist/* -u __token__ -p ${PYPITOKEN}

其中注意 Token 的申请,和设置,需要分别在 Pypi.org 和 CircleCI 的 web 界面上操作好。

Workflow 中可以添加定时构建任务,在需要 nightly build 的项目中非常实用;也可以添加需要手动确认的任务,比如将自动发布集成到流程中,但是发布之前需要手动确认一下。More on this. 但是要知道,每一个手动确认的东西,在增加了安全性的同时,也拉长了整个流程,有人操作的地方就会卡住,会成为最耗时的东西,某一天也许会成为一种形式主义,所以我个人非常不喜欢需要人工确认的东西。

除了发布到 pypi,因为这个项目是一个 Redis 的命令行工具,所以也准备发布到其他的软件源,比如 apt,yum,brew 等。

再来说下这段时间其他一些更新。

更友好的补全

key 的补全,我自己实现了一个超屌的 Completer,在做自动补全的时候,最近使用过的 key 会出现在最前面(PR)。除了 KEYS 命令之外,所有包含 key 的 Redis 命令都会更新 Completer。效果如下(注意所有包含 key 的命令,都将输入过的 key 放到了 completers 列表中):

支持命令提示

也许在上张图你发现了,在 最底下一行含有命令的提示,包括这个命令适用于 Redis 哪种数据类型,命令的语法是什么,什么 redis-server 版本出现的,命令的复杂度是什么。redis-cli 的 readline 风格提示,在输入的过程中如果匹配不上命令,hint 会消失,我觉得体验不太好。另外输入的阴影我用来显示历史命令了,用  键可以快速输入。

放一张开发的时候写的脚本,渲染出所有的命令(laike9m说我的配色辣眼睛):

Transaction 支持

这是某天我想出来的一个 idea,觉得不错,就是在 transaction 状态中的时候,用右侧的 prompt 来提示用户状态。这个想法我记了 issue,Github 上的哥们帮我实现了(Thanks guoweikuang)。

效果如下:

其他还有一个项目内部中的重构,比如一套更加合理的命令前 hook,命令后 hook 方式,命令结果渲染框架等。打包方式也替换成了 poetry,写 pyproject.toml 比写 setup.py 爽多了。

发点牢骚,很多人对这种工具开发不屑一顾,张口闭口高并发,觉得架构设计啊才能显示出自己的技术,但是代码写的稀烂,一个很简单的系统虽然几十万并发量,却用了上千台机器,算下来一分钟请求才几百而已,非常可笑。我觉得一个靠谱的程序员首先应该精通自己的工具,工具不好工作就不能高效,自己的工具遇到问题解决不好,工作上遇到问题也稀松。自己的问题没有现成的工具解决,就没办法了,工作上除了搭积木水平也一般。

牢骚发完,顺便说下,这个项目正在开发中,如果你对一个 Redis 命令行有什么期待,有什么 Feature Request,或者想法,欢迎 issues,我来实现。也欢迎参与到开发中。目前有很多命令还没有实现,最近我在写 string 部分的命令。打算在所有的命令都实现了语法解析和结果渲染之后发布1.0版本。