感兴趣的同学可以关注这个翻译项目我的博客原文我的Github

前段时间翻译的Spring MVC官方文档完成了第一稿,相关的文章和仓库可以点击以下链接。这篇文章,主要是总结一下这个翻译项目自开始到上线发布,完整的一个生命流程。内容包括 翻译环境搭建项目管理自动化构建 三部分。

环境搭建

翻译与写作一样,首要之事均为专注于翻译/写作本身,而不考虑样式等方面。而章节之间的联系,自然也不想过多操心,这部分与样式一起,都可交由工具去处理。然后版本管理,不用说一定要上,后面也会看到github的生态圈使得它与其他工具做到了无缝集成。那么总结起来,我们需要的工具大体是:

  • markdown
  • markdown编辑器 Atom
  • 版本管理 Git
  • 代码托管平台 Github
  • 写书专用工具 Gitbook
  • HTML转markdown工具

Markdown

Markdown是一种近乎完美的写作标记语言,其最大的功劳便是将写作从内容中分离出来,这个分离使你只专注于写作内容本身,极大地提高了效率及工作愉悦度。没有markdown的话,会是怎样一种情况?想想HTML和写论文经常使用的word。你在HTML中为内容混入各种各样的样式,写论文时最痛苦的莫过于调样式(不过笔者当年写论文时通过Office Word的样式窗也是完美地解决了内容和格式的问题)。

比如说,上面这段文字在markdown中写出来是这样的:

## 环境搭建

翻译与写作一样,首要之事均为专注于翻译/写作本身,而不考虑样式等方面。而章节之间的联系,自然也不想过多操心,这部分与样式一起,都可交由工具去处理。然后版本管理,不用说一定要上,后面也会看到github的生态圈使得它与其他工具做到了无缝集成。那么总结起来,我们需要的工具大体是:

* markdown
* markdown编辑器 Atom
* 版本管理 Git
* 代码托管平台 Github
* 写书专用工具 Gitbook
* HTML转markdown工具

说起来markdown这个名字也有点意思,一般的标记语言叫markup language。这里将up改成down,寓意着将标记语言中与内容本身无关的标记全部剔除,形成一个精简子集。本篇不是markdown用法记,所以更多的语法请自行百度Google。我这里可以提供几个链接:

Markdown编辑器 Atom

编辑器的选择并无定式,打造一个完全符合自己操作习惯的编辑器也是每个程序员应做的一个工作,这里我不赘述。在Mac上,不错的markdown编辑器有Sublime 3、Atom、MacDown、Mark Editor、Gitbook Editor、Mou等,可挑选适合自己的,我选择的是Atom,是因为有一个刚性的需求它能够满足:

版本管理 Git

Git作为版本管理的意义也不赘言。你肯定不想自己的工作区最后变成这样:

同样本小节也不是Git入门的命令集,这部分请自行查阅学习。当然我还是可以给出一些链接,虽然没有太多的意义我真的不知道为什么我还要给。基本的几个命令能熟悉就可以满足日常的需要了。另外,zsh下的Git可以配一下 快捷键(alias) 和 自动补全,具体配置非常简单,可以来这篇文章Mac优雅的工具集——oh-my-zsh篇看一下最终的效果。

代码托管平台 Github

Github是世界上最大的同性交友平台目前最大我并无依据的代码托管平台,其生态圈之繁荣与力量令人震惊,几乎你需要的所有工具和资源都可以在上面找到。它与Git不是一个层级的概念git=github.substring(0, 3),这部分请自行搜索。在这个平台上,我可以给翻译项目一个README.md文件,为阅读的人做简单的介绍以及引流,同时它可与CI(持续集成)、Gitbook等工具完美集成,其内置的issue、pull-request功能还能与Zenhub结合,直接当成trello来进行项目管理之用。相关的工具下一节会介绍。

写书专用工具 Gitbook

上文提到了翻译内容与样式的分离。实际上在这里样式这部分就是由Gitbook自带的渲染引擎来负责的。此外,Gitbook还能帮助你管理整个书的目录结构、章节生成、搜索、词汇表、站点构建与生成等,同时它也有丰富的插件生态。这一切只需要你进行少量的配置(其实,就只是在书的根目录下运行gitbook init命令,它会生成下图所示的一个目录结构),其低学习成本与高效益,使它成为了写书最易入门的趁手工具。

.
├── README.md
└── SUMMARY.md

项目管理

项目管理方面的需求,主要是有时会有想法出现,希望增加什么特性,或者想到什么问题不想马上修,那么最好是有一个TODOLIST可以随时记录下来,并且能被方便地检索到。这方面的需求,怎么解决呢?

issue + zenhub

Github内置的issue功能已经好用到爆,再加上专为Github issue功能定制的Zenhub简直就是活生生把issue当成trello来用。一些内置特性如下,稍加体验即可满足所有小型项目管理上的需求:

  • issue可以通过commit sha直接与相关的单次提交关联,还可以 通过提交信息来引用、关闭issue
  • issue中支持GFM(Github Flavored Markdown),可以直接使用todolist的语法
  • 通过Command/Ctrl+V可以直接在留言中上传截图
  • 可以为issue添加标签(tag)、类别(pipeline, 如正在做、还没做、已完成等)
  • 可以为issue估点、指定负责人、燃尽图,简直就是为敏捷实践而生,不过在这个翻译项目中用不到这些,毕竟自己给自己估点没什么意思

自动化构建

自动化什么的构建?这还要从本翻译稿的托管平台——Gitbook——说起。gitbook是一个绝好的写作平台,官方也通过Webhooks提供了与Github的集成,只要你把代码git push到远端仓库,Gitbook就会自动拉取仓库中的内容,依照特定的格式为书本构建站点。过大概2到3分钟,你就可以在Gitbook上看到自己最新的更新已经到书上了。一切看起来都十分美好,一键提交与部署。但是有一个最大的问题:Gitbook在国内的速度不行,轻则卡顿,重则整站被墙刷不出页面

这种情况下,我决定将整个翻译同时迁移到七牛上。七牛的CDN在国内速度名声在外,用来托管静态站点再好不过只需要拍两张身份证正反双面的照片上传等待审核即可。迁移也很简单,因为gitbook生成的静态站点其实就是_book文件夹,只需要把这个文件夹下的全部东西放到七牛空间上去,在使用index.html作为入口就可以了。但是,问题又来了:

  • 七牛网站上无法上传文件夹。就算可以,我也无法忍受每次都要手动将文件夹拖上去
  • 每次仓库有更新,都需要将最新的内容同步到七牛空间上,并覆盖旧版本的同名文件
  • 第二步的操作还不能通过githook+shell的方式来做,因为整个过程的耗时会使git push的反馈周期变长,从而使得我更不倾向于频繁提交,影响翻译体验

解决方案也很简单:

  • 第一条,寻找七牛的SDK,通过命令行进行上传
  • 第二条,既然不能,[细想]也没必要在本地做,那么就在远端做好了。远端在哪里呢?CI/Pipeline啊,这样构建站点、同步文件等工作都可以并行进行了,既不会阻碍本地开发速度,也不是翻译时需要考虑的问题,我还是只需要像以前一样git push提交代码即可,站点从构建到最终上线,都有CI在负责

想法出来了,在实施的时候还是走了一些弯路的。这些折腾过程在此无法深表,只有可能带过程序员们都懂的。在CI的选择上,我选择了Jenkins 2.0,原因比较纯粹,最近项目上在使用Jenkins 2.0,我刚好当是练手。至此文章成笔之时,我仍在考察其他选择,比如travis-ci,看起来UI和配置都简单许多,这部分可能是后文了。下面会简单介绍折腾搭建Jenkins 2.0作为本翻译项目CI的步骤和关键节点。

Jenkins下载、安装与启动

话说Jenkins不愧为CI/CD领域的先锋,这个产品每周都会发一个小版本(目前最新是2.11)。Jenkins 2.0的安装,可以通过直接下载安装包的方式下载,在Mac上也可以通过brew install jenkins来下载安装。安装完成后,运行jenkins即可在localhost:8080启动一个本地的jenkins。

注册一个七牛开发者账号

流程十分简单,免费用户可以有一个空间,有一定的流量限制,不过通常来说对于只有一个空间需求的用户来说,这样的流量应该不会超吧。由于我已经超过了一个空间的需求,同时我又有配置独立域名的需求,所以需要更多的权限。流程也很简单,进行实名认证、填写身份证、上传本人及身份证正反面照片各一张本人不需拍反面,最后保证账户里有最少10元即可。

Jenkins:新建一个类型为pipeline的项目

pipeline搭建起来了,接下来我们需要捋一捋前面说到的两个步骤:构建站点、上传站点文件到七牛空间。细分下来,主要是有以下的task要做:

  • 引入必要的依赖
  • 构建站点
  • 同步到七牛

使用NPM,引入gitbook/gitbook-cli/qiniu

我们想要构建站点,必然使用gitbook的命令行工具;要使用七牛的命令行,也必然引入相应的工具。这里我走过一些弯路,比如尝试将七牛工具以插件形式引入到Jenkins job中来,但是2.0以后,我们更倾向于使用脚本来描述构建工作,而非将Jenkins单纯当作一个转存/转储的工作区间并为该workspace零散地写一些适配脚本。因此,在pipeline类型的项目就不存在每个job特定的配置空间,若想使用插件,配置起来有些麻烦。于是,最后我决定使用七牛的npm包(肯定是有的),并通过NPM来管理所有依赖。以下是一个package.json文件需引入的依赖:

{
...
"devDependencies": {
"gitbook": "^3.1.1",
"gitbook-cli": "^2.3.0",
"qiniu": "^6.1.11"
},
...
}

另外,需要注意的是,Gitbook的渲染引擎已经升级到v3.1.1版本,与Legacy v2.6.7版引擎相比,主要的区别是v3支持多个部分(part)的文章、默认关闭了目录中章节前的数字等。其中multipart的部分有些小bug但还可以忍受,但是默认关闭的目录数字则需要通过以下的配置给设置回来。在book.json文件中:

{
"gitbook": ">=3.1.0",
"pluginsConfig": {
"theme-default": {
"showLevel": true
}
}
}

构建站点

简单地运行命令gitbook build即可生成站点目录。最后的构建脚本Jenkinsfile.groovy如下所示:

node ('main') {
stage 'Pull latest changes from SCM'
git([
url: 'git@github.com:linesh-simplicity/translation-spring-mvc-4-documentation.git',
branch: 'master'
]) stage 'Download dependencies: Gitbook/Gitbook-cli/Qiniu'
sh 'npm install' stage 'Build book serving directory through Gitbook'
sh 'gitbook build --gitbook=3.1.1' stage 'Upload production _book to Qiniu through their API'
sh './jenkins/sync-book-to-qiniu.sh'
}

上传文件到七牛

使用七牛的命令行工具进行文件上传,需要配置一些东西,主要是要同步的本地目录、七牛的Access key和Secret Key等,示例代码则可以从七牛SDK的官网上参考。我最后完成的这份同步脚本sync-book-to-qiniu.js如下所示,其中完成了 准备本地同步目录排除不同步文件指定覆盖上传策略等工作:

const qiniu  = require("qiniu");
const glob = require('glob');
const crypto = require('crypto-js') const ignoredFiles = [
'Jenkinsfile.groovy',
'sync-book-to-qiniu.js',
'sync-book-to-qiniu.sh',
'mvc-origin.md',
'package.json'
]; // node ./jenkins/sync-book-to-qiniu.js $ACCESS_KEY $SECRET_KEY
let qiniuAccessKey = process.argv.slice(2, 3);
let qiniuSecretKey = process.argv.slice(3); // Prepare Qiniu configuration options
qiniu.conf.ACCESS_KEY = qiniuAccessKey.toString(crypto.enc.Utf8);
qiniu.conf.SECRET_KEY = qiniuSecretKey.toString(crypto.enc.Utf8);
bucket = 'mvc-linesh-tw'; glob.sync('_book/**/*.*', {}).filter(filename => {
for (let ignored of ignoredFiles) {
if (filename.endsWith(ignored)) return false;
}
return true;
}).forEach(filepath => {
const resource_key_in_qiniu_api = filepath.substring('_book/'.length, filepath.length);
// ':' means allow override upload. For further details refer to offical API docs
const policyToken = new qiniu.rs.PutPolicy(bucket + ":" + resource_key_in_qiniu_api).token();
uploadFile(policyToken, resource_key_in_qiniu_api, filepath)
}) function uploadFile(uptoken, key, localFile) {
let extra = new qiniu.io.PutExtra();
qiniu.io.putFile(uptoken, key, localFile, extra, function(error, response) {
if(!error) {
console.log('[Success] File uploaded: ' + response.key);
} else {
console.log(error);
}
});
}

同行们求review代码啊~

避免提交七牛的AK和SK

AK(Access Key)和SK(Secret Key)是七牛分配给注册开发者的一对密钥,不能泄露,否则其他人得到了就可以对你的七牛空间进行任意操作。但是,你要把构建工作自动化,就必须这段脚本提交到github上,同时CI还要能从你的代码中读出正确的AK和SK,这要如何做到呢?回答是,通过CI提供的接口,由pipeline将参数注入到你的代码中。这样,AK和SK就被保存在了pipeline上,别人无权对其进行访问。在Jenkins CI上,这是通过一个EnvInject插件来做到的,在travis-ci中则更加简单,直接设置。

总结

呼呼,最后看到这个图的时候还是很激动的,所有的部署工作都成功了。那么也是时候结束了,本篇文章总结起来,先是提到如何准备和搭建让翻译工作更加专注和高效的环境和工具,如markdown/atom/gitbook/git/github等,然后讲到如何使用github的issue和zenhub来辅助管理翻译项目中的待办事项和协作,最后一节讲述了如何使用CI工具将整个站点的构建和发布自动化,提高翻译和部署效率。任何有疑问或说错的地方,也请各位给我指出。

—— 2016-07-01

Bonus:Marketing

我是如何进行Spring MVC文档翻译项目的环境搭建、项目管理及自动化构建工作的的更多相关文章

  1. Spring MVC基础知识整理➣环境搭建和Hello World

    概述 Spring MVC属于SpringFrameWork的产品,采用Model-View-Controller进行数据交互,已经融合在Spring Web Flow里面.Spring 框架提供了构 ...

  2. 零基础搭建 spring mvc 4 项目(本文基于 Servlet 3.0)

    作者各必备工具的版本如下: Tomcat:apache-tomcat-7.0.63 (下载链接) Java EE - Eclipse:Luna Service Release 1 v4.4.1 (下载 ...

  3. SSM 框架-03-MyEclipse+Tomcat+MAVEN+SVN项目完整环境搭建

    SSM 框架-03-MyEclipse+Tomcat+MAVEN+SVN项目完整环境搭建 如果你是使用 Eclipse 你需要先安装 MyEclipse,请参考:SSM 框架-02-MyEclipse ...

  4. java项目测试环境搭建

    java项目测试环境搭建 2019-03-06 13:45:26 木瓜小少年 阅读数 691更多 分类专栏: 测试   版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原 ...

  5. Eclipse+Tomcat+MAVEN+SVN项目完整环境搭建

    1.JDK的安装 首先下载JDK,这个从sun公司官网可以下载,根据自己的系统选择64位还是32位,安装过程就是next一路到底.安装完成之后当然要配置环境变量了. ————————————————— ...

  6. Eclipse4.6(Neon) + Tomcat8 + MAVEN3.3.9 + SVN项目完整环境搭建

    软件清单 jdk-8u102-windows-x64.exe eclipse-inst-win64.exe (Eclipse4.6 Neon) apache-tomcat-8.5.5-windows- ...

  7. Hadoop项目开发环境搭建(Eclipse\MyEclipse + Maven)

    写在前面的话 可详细参考,一定得去看 HBase 开发环境搭建(Eclipse\MyEclipse + Maven) Zookeeper项目开发环境搭建(Eclipse\MyEclipse + Mav ...

  8. Hive项目开发环境搭建(Eclipse\MyEclipse + Maven)

    写在前面的话 可详细参考,一定得去看 HBase 开发环境搭建(Eclipse\MyEclipse + Maven) Zookeeper项目开发环境搭建(Eclipse\MyEclipse + Mav ...

  9. Linux(三)—— 项目部署环境搭建

    目录 项目部署环境搭建 一.linux上网 二.rpm包管理 1.光盘挂载 2.安装卸载rpm包 3.查询是否安装 4.查看软件包 5.互相依赖关系的软件包 三.yum包管理 1.使用aliyun的y ...

随机推荐

  1. 基于Oracle安装Zabbix

    软件版本 Oracle Enterprise Linux 7.1 64bit Oracle Enterprise Edition 12.1.0.2 64bit Zabbix 3.2.1 准备工作 上传 ...

  2. WebForm获取GET或者POST参数到实体的转换,ADO.NET数据集自动转换实体

    最近在修改维护以前的webform项目(维护别人开发的.....)整个aspx没有用到任何的控件,这个我也比较喜欢不用控件所以在提交信息的时候需要自己手动的去Request.QueryString[] ...

  3. BPM配置故事之案例4-子表

    公司渐渐对采购管理重视起来了,新招聘了采购主管老李,老李对现有的申请表很不满意,要求将申请物资和申请原因改成物资明细表 物资明细表 小明只好继续致电大毛-- 大毛:把申请物资和申请原因删掉,新增一个数 ...

  4. 解决mysql插入数据时出现Incorrect string value: '\xF0\x9F...' for column 'name' at row 1的异常

    这个问题,原因是UTF-8编码有可能是两个.三个.四个字节.Emoji表情或者某些特殊字符是4个字节,而MySQL的utf8编码最多3个字节,所以数据插不进去. 我的解决方案是这样的 1.在mysql ...

  5. 关于sqlmap的使用

    好记性不如烂笔头,记录一下. 带cookie的注入 python sqlmap.py -u "http://www.xxx.com?id=1" --cookie="coo ...

  6. [DS] 标记字段

    标记字段 代码中有时候有这种需求:需要一个公共访问的标记字段,以下称为标记字段. 下面是案例: 一个订单详情页面,如果页面在显示中,程序中其它地方需要访问这个"正在查看中"的订单信 ...

  7. ucos实时操作系统学习笔记——任务间通信(信号量)

    ucos实时操作系统的任务间通信有好多种,本人主要学习了sem, mutex, queue, messagebox这四种.系统内核代码中,这几种任务间通信机制的实现机制相似,接下来记录一下本人对核心代 ...

  8. 探索 Linux 系统的启动过程

    引言 之所以想到写这些东西,那是因为我确实想让大家也和我一样,把 Linux 桌面系统打造成真真正正日常使用的工具,而不是安装之后试用几把再删掉.我是真的在日常生活和工作中都使用 Linux,比如在 ...

  9. FireFox调试手机浏览器

    https://developer.mozilla.org/en-US/docs/Tools/Remote_Debugging/Firefox_for_Android IN THIS ARTICLE ...

  10. Android自定义控件之自定义ViewGroup实现标签云

    前言: 前面几篇讲了自定义控件绘制原理Android自定义控件之基本原理(一),自定义属性Android自定义控件之自定义属性(二),自定义组合控件Android自定义控件之自定义组合控件(三),常言 ...