我是如何进行Spring MVC文档翻译项目的环境搭建、项目管理及自动化构建工作的
前段时间翻译的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,是因为有一个刚性的需求它能够满足:
- 与终端(terminal)的集成。由于使用了版本管理,同时有时有拷贝文件、查看目录等需求,命令行肯定是必须随时在手的。终端方面我的选择是iTerm2+zsh,关于它们的配置和特性,可以查看博客的这两篇文章 Mac优雅的工具集——iTerm2篇 和 Mac优雅的工具集——oh-my-zsh篇。对如何在Mac上构建一个优雅的工具集有兴趣的同学,也可以前往Gitbook看看我正在写的这个系列:关于优雅地使用Mac OS的理念、想法、工具与实践集,不过还没写完就是了。
版本管理 Git
Git作为版本管理的意义也不赘言。你肯定不想自己的工作区最后变成这样:
同样本小节也不是Git入门的命令集,这部分请自行查阅学习。当然我还是可以给出一些链接,虽然没有太多的意义我真的不知道为什么我还要给。基本的几个命令能熟悉就可以满足日常的需要了。另外,zsh下的Git可以配一下 快捷键(alias) 和 自动补全,具体配置非常简单,可以来这篇文章Mac优雅的工具集——oh-my-zsh篇看一下最终的效果。
- Git - 简易指南
- A Visual Git Reference
- 廖雪峰的官方网站:史上最浅显易懂的Git教程这浮夸的标题收视率果然好
代码托管平台 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文档翻译项目的环境搭建、项目管理及自动化构建工作的的更多相关文章
- Spring MVC基础知识整理➣环境搭建和Hello World
概述 Spring MVC属于SpringFrameWork的产品,采用Model-View-Controller进行数据交互,已经融合在Spring Web Flow里面.Spring 框架提供了构 ...
- 零基础搭建 spring mvc 4 项目(本文基于 Servlet 3.0)
作者各必备工具的版本如下: Tomcat:apache-tomcat-7.0.63 (下载链接) Java EE - Eclipse:Luna Service Release 1 v4.4.1 (下载 ...
- SSM 框架-03-MyEclipse+Tomcat+MAVEN+SVN项目完整环境搭建
SSM 框架-03-MyEclipse+Tomcat+MAVEN+SVN项目完整环境搭建 如果你是使用 Eclipse 你需要先安装 MyEclipse,请参考:SSM 框架-02-MyEclipse ...
- java项目测试环境搭建
java项目测试环境搭建 2019-03-06 13:45:26 木瓜小少年 阅读数 691更多 分类专栏: 测试 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原 ...
- Eclipse+Tomcat+MAVEN+SVN项目完整环境搭建
1.JDK的安装 首先下载JDK,这个从sun公司官网可以下载,根据自己的系统选择64位还是32位,安装过程就是next一路到底.安装完成之后当然要配置环境变量了. ————————————————— ...
- 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- ...
- Hadoop项目开发环境搭建(Eclipse\MyEclipse + Maven)
写在前面的话 可详细参考,一定得去看 HBase 开发环境搭建(Eclipse\MyEclipse + Maven) Zookeeper项目开发环境搭建(Eclipse\MyEclipse + Mav ...
- Hive项目开发环境搭建(Eclipse\MyEclipse + Maven)
写在前面的话 可详细参考,一定得去看 HBase 开发环境搭建(Eclipse\MyEclipse + Maven) Zookeeper项目开发环境搭建(Eclipse\MyEclipse + Mav ...
- Linux(三)—— 项目部署环境搭建
目录 项目部署环境搭建 一.linux上网 二.rpm包管理 1.光盘挂载 2.安装卸载rpm包 3.查询是否安装 4.查看软件包 5.互相依赖关系的软件包 三.yum包管理 1.使用aliyun的y ...
随机推荐
- Android混合开发之WebView与Javascript交互
前言: 最近公司的App为了加快开发效率选择了一部分功能采用H5开发,从目前市面的大部分App来讲,大致分成Native App.Web App.Hybrid App三种方式,个人觉得目前以Hybri ...
- 关于面试题 Array.indexof() 方法的实现及思考
这是我在面试大公司时碰到的一个笔试题,当时自己云里雾里的胡写了一番,回头也曾思考过,最终没实现也就不了了之了. 昨天看到有网友说面试中也碰到过这个问题,我就重新思考了这个问题的实现方法. 对于想进大公 ...
- [C#] 进阶 - LINQ 标准查询操作概述
LINQ 标准查询操作概述 序 “标准查询运算符”是组成语言集成查询 (LINQ) 模式的方法.大多数这些方法都在序列上运行,其中的序列是一个对象,其类型实现了IEnumerable<T> ...
- [C#] 了解过入口函数 Main() 吗?带你用批处理玩转 Main 函数
了解过入口函数 Main() 吗?带你用批处理玩转 Main 函数 目录 简介 特点 方法的参数 方法的返回值 与批处理交互的一个示例 简介 我们知道,新建一个控制台应用程序的时候,IDE 会同时创建 ...
- springMVC学习笔记--知识点总结1
以下是学习springmvc框架时的笔记整理: 结果跳转方式 1.设置ModelAndView,根据view的名称,和视图渲染器跳转到指定的页面. 比如jsp的视图渲染器是如下配置的: <!-- ...
- C++ 事件驱动型银行排队模拟
最近重拾之前半途而废的C++,恰好看到了<C++ 实现银行排队服务模拟>,但是没有实验楼的会员,看不到具体的实现,正好用来作为练习. 模拟的是银行的排队叫号系统,所有顾客以先来后到的顺序在 ...
- 【QQ红包】手机发抢不到的口令红包
这方法95%的人都抢不了 在QQ输入框输入一个表情,例如:阴险那个表情 将表情剪切到口令红包的口令里 这时候口令里的那个表情表情变成了符号 将符号删去一格,然后全选.复制 然后返回到QQ输入框粘贴 然 ...
- 一种简单,轻量,灵活的C#对象转Json对象的方案(续)
本文参考资料 一种简单,轻量,灵活的C#对象转Json对象的方案 [源码]Literacy 快速反射读写对象属性,字段 一段废话 之前我已经介绍了这个方案的名称为JsonBuilder,这套方案最大的 ...
- ABP源码分析二十:ApplicationService
IApplicationService : 空接口,起标识作用.所有实现了IApplicationService 的类都会被自动注入到容器中.同时所有IApplicationService对象都会被注 ...
- 在linux平台实现atosl
➠更多技术干货请戳:听云博客 序言 怎么在linux 平台下实现一个类似于mac 平台下的 atos 工具( iOS 符号化解析)? 分析问题 在github上找到了几年前的开源实现,[https:/ ...