软件研发的协作过程中,文档是必不可少的一环,有需求文档、接口文档、使用文档等等。当开始写文档时,首先会遇到两个问题:

  • team members 之间如何协作?
  • 文档 OK 后如何分发,去哪里看?如何更新?

很早的时候采用 word+ppt 做文档,然后放到共享服务器(ftp,samba)上,这种方式会有文档锁定和覆盖的问题,几个人的小团队还可以,大不了更新的时喊一嗓子:“我要更新文档了,大家都不要占用某某文件(使用windows共享文档的童鞋应该很熟悉)”。更新完了还要再喊一嗓子。除此之外,由于 word 文件格式(word文件其实是个压缩包,由很多 xml 和其他文件构成)太过于复杂,即便是借助 git 或者 svn 做版本控制,一旦产生冲突,很难通过肉眼合并和解决冲突。

那么如何解决上述问题呢?这篇文章我用 gitbook + flow.ci 进行文档的发布、集成和部署,希望给有需求的同学一些参考。

如何进行文档协作 & 版本控制 (git+markdown)

开发团队使用 git 或 svn 作为协作和版本控制工具已经是很成熟的方案了,当然也可以用于文档,只是word文档本身天然不太适合版本控制,markdown 是一种轻量级的标记语言, 学习简单,上手容易(具体语法参考 http://wowubuntu.com/markdown/) , 配合 git 几乎能做到完美的文档版本控制 。

如何发布文档 (gitbook+nginx)

最好的方式是把文档发布为 web 网站,这样无需安装任何工具即可查看文档,更新时只需更新网站即可。在这里,用 gitbook 将 markdown 文件快速生成为网站。

什么是 gitbook 呢?官网上是这么介绍的:

GitBook is a modern publishing toolchain. Making both writing and collaboration easy.

简单来说就是将 markdown 文档转换成 html、pdf、epub 等多种格式,很多开源软件和书籍都是用 gitbook 发布的, 如:Elasticsearch 权威指南Docker — 从入门到实践 等。

如果将 markdown 文档生成静态 html 部署到服务器(nginx)上,不仅可以通过浏览器查看,而且一旦更新server,所有人看到的都是最新的文档。

如何将文档进行持续集成 & 部署 (flow.ci)

CI(Continuous Integration)意为 “持续整合”,指代码的持续测试及与其他代码修改的整合与归并。

CD(Continuous Deployment)意为 “持续部署”,指代码与其补丁的持续部署于整个代码库。

拿文档来看,持续部署就是内容的持续测试、与必要修改的归并及部署。在此,部署意为发布。举例来说,“部署文档”是指输出文件被复制于web服务器为人阅览。

关于持续集成、持续部署不是一两句话能说清的,用于实现 持续集成、持续部署的工具链也五花八门,比如:最常见的 jenkins 、TravisCI 等,使用起来配置过于复杂。这篇文章里我将使用自家的持续集成服务 —— flow.ci 来进行文档的集成和部署,仅供参考。

建一个git repo存储文档

首先,建一个git repo存储文档,此处以 flow.ci官方文档 docs.flow.ci 为例, git repo 为

git@github.com:FIRHQ/flow.ci.git

目前 flow.ci 支持 github、bitbucket、国内的coding 和 私有部署的Gitlab。只要文档放在以上代码仓库的 git repo 都可以使用 flow.ci 进行集成. 如何在 flow.ci 创建项目可以 参考文档.

在 flow.ci 上创建 flow

接着,在 flow.ci 上建一个flow,语言模板选用 nodejs(使用 gitbook 需要用到node环境)。

同时删除掉 Cache、Install、Test等 step,这几个 step 是为 nodejs 项目提供的,我们此处只需要 nodejs 运行时环境及 npm 工具。

添加自定义脚本step

删除完之后添加自定义脚本step, 如何添加自定义脚本step可参考文档。 此处要添加两个自定义脚本,一个用于安装gitbook,一个用于编译文档并发布。

安装 gitbook 的自定义脚本 step 内容

script1

shell flow_cmd "npm install gitbook-cli -g" --echo --retry --assert *此处的 flow_cmd 是 flow.ci 提供的一个函数,如果执行命令失败会进行重试*

生成静态文件 && 部署 的自定义脚本step 内容 script2

shell if [ "$FLOW_GIT_BRANCH" == "gitbook" ]; then # 只部署 gitbook分支 source get_commits_from_last.sh bash -x ./deploy.sh fi;

  • $FLOW_GIT_BRANCH 是一个环境变量,用来存储当前的git分支
  • get_commits_from_last.sh 会获取上次发布的日期以及git commit id
  • deploy.sh会调用gitbook命令编译markdown文档,并在首页head里面添加本次commit id号以及时间戳,并发布到服务器,脚本会为文末放出
  • *由于deploy.sh会将gitbook生成的静态文件使用scp的方式copy到服务器, 所以 服务器必须添加 rsa key 信任 , rsa-key可以在项目的设置页找到,将其添加倒对应user的~/.ssh/authorized_keys中即可*

添加邮件通知的step,文档部署成功后触发

Email Sender插件需要三个参数,分别是邮件接受者、邮件主题、邮件内容模板,如下:

email

总结

至此,使用 flow.ci 快速发布文档的步骤已经全部完成。flow.ci 不只是持续集成,持续部署的工具,也帮助我们用自动化的视角审视手头繁琐的工作,将更多的时间用在新鲜事物上。

有任何疑问发邮件到 my@fir.im,分享你的观点:)

附上所有 step 中涉及的脚本:

  • get_commits_from_last.sh

```shell

!/usr/bin/env bash

usage: sh get_commits_from_last.sh

会export 2个环境变量:

DEPLOY_DIFF 与上次部署的时间差

DEPLOY_LOG 与上次部署的变化

set -e

STAGE="docs" URL="${STAGE}.flow.ci" HTML=eval curl -sS ${URL} # 获取首页html

从首页html中提取上次 部署的ID 和 部署时间

LAST_ID=echo $HTML | awk 'match($0, /-[0-9a-f]{7}/) { print substr( $0, RSTART+1, RLENGTH-1 )}' LAST_TIME=echo $HTML | awk 'match($0, /[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}/) { print substr( $0, RSTART, RLENGTH )}'"Z"

FMT="%Y-%m-%dT%H:%M:%SZ" currDate=date -u +"$FMT"

if [[ uname == 'Darwin' ]]; then ts=$(date -j -f "$FMT" "${currDate}" "+%s") ts2=$(date -j -f "$FMT" "${LAST_TIME}" "+%s") else ts=$(date --date="${currDate}" +"%s") ts2=$(date --date="${LAST_TIME}" +"%s") fi

(( diff=(ts-ts2)/60 ))

export DEPLOY_DIFF=$diff echo "Last $1 version : $LAST_ID @ ${LAST_TIME} (${DEPLOY_DIFF} minutes ago)" echo "-----------------------------------------" export DEPLOY_LOG=git log --oneline $LAST_ID..HEAD echo "${DEPLOY_LOG}" ```

  • deploy.sh

```shell

!/bin/bash

set -e

VARS

DEPLOY_TIME=date +%Y%m%d%H%M%S REMOTE_DIR="/var/www/flow-doc" RELEASE_DIR="${REMOTE_DIR}/release" DEPLOY_DIR="${RELEASE_DIR}/${DEPLOY_TIME}" LATEST_DIR="${REMOTE_DIR}/latest"

TARGET=prod USER=deploy # 需添加 rsa key 信任 HOST="此处修改为server的ip" PORT=22 # ssh端口

使用gitbook 生成静态文件

gitbook build docs dist

获取当前时间

FMT="%Y-%m-%dT%H:%M:%SZ" currDate=date -u +"$FMT" if [[ uname == 'Darwin' ]]; then ts=$(date -j -f "$FMT" "${currDate}" "+%s") else ts=$(date --date="${currDate}" +"%s") fi

获取当前分支

branch=$(git rev-parse --abbrev-ref HEAD) if [ -n "$FLOW_GIT_BRANCH" ] ; then branch=$FLOW_GIT_BRANCH fi

获取commit log

commit=$(git rev-parse --short HEAD)

将本次部署的时间和COMMIT ID 嵌入倒首页html中

sed -i '/author/a\ \' ./dist/index.html sed -i '/author/a\ \' ./dist/index.html

sed -i "s/COMMIT-TAG/${branch}-${commit}/g" ./dist/index.html sed -i "s/UPDATE-TIME/${currDate}/g" ./dist/index.html

开始部署

echo "########## Deploy to ${TARGET} ##########" ssh ${USER}@${HOST} -p ${PORT} "mkdir -p ${DEPLOY_DIR}" ssh ${USER}@${HOST} -p ${PORT} "rm -rfv ${LATEST_DIR}"

scp -P ${PORT} -rv ./dist/* ${USER}@${HOST}:${DEPLOY_DIR} ssh ${USER}@${HOST} -p ${PORT} bash -x <

exit 0 ```

评论

本文目前还没有评论……

我要评论

需要登录后才能发言
登录未成功,请修改提交。