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

  • 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 内容

flow_cmd "npm install gitbook-cli -g" --echo --retry --assert

此处的 flow_cmd 是 flow.ci 提供的一个函数,如果执行命令失败会进行重试

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

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插件需要三个参数,分别是邮件接受者、邮件主题、邮件内容模板,如下:

总结

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

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

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

  • get_commits_from_last.sh
#!/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
#!/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\ \<meta name="version" content="production|COMMIT-TAG"\>' ./dist/index.html
sed -i '/author/a\ \<meta http-equiv="last-modified" content="UPDATE-TIME"\>' ./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 <<EOF
ln -s ${DEPLOY_DIR} ${LATEST_DIR}
exit
EOF
echo "########## Deploy $HOST success ##########" exit 0

使用 flow.ci 快速发布你的项目文档的更多相关文章

  1. 使用 Github Pages 发布你的项目文档

    导读 你可能比较熟悉如何用 Github Pages 来分享你的工作,又或许你看过一堂教你建立你的第一个 Github Pages 网站的教程.近期 Github Pages 的改进使得从不同的数据源 ...

  2. 使用gitlab runner 进行CI(四):使用Gitlab Page托管项目文档

    目录 1.什么是Gitlab Pages 2.开启Gitlab Pages 3.基本过程 4.托管markdown文档 4.1 安装sphinx等依赖 4.2 配置项目的sphinx配置 4.3 编写 ...

  3. 随时发布:REST API文档的代码仓库中的持续集成与协作

    本文主要内容:API文档提供了预测客户成功的关键路径:在代码附近的文档上进行协作可以更好地检查代码和文档文件,提高自动化效率,并专门针对文档进行质量测试:提供通用文档框架,标准,自动化和工具,以提高团 ...

  4. MkDocs项目文档生成器

    简介 安装 我的配置 Chocolatey 简介 - Windows的包管理器 官方网址 安装 注意事项 Python 简介 安装 Pip 简介-Python的包管理器 升级 MkDocs的安装 使用 ...

  5. vuepress+gitee 构建在线项目文档

    目录 快速入门 在现有vue项目中安装本地开发依赖vuepress 在现有vue项目根目录下创建docs目录 创建并配置文档首页内容 运行,查看效果 可能会出现vue和vue-server-rende ...

  6. 使用Mkdocs构建你的项目文档

    使用Mkdocs构建你的项目文档 环境搭建 安装必需软件 作者是在windows下安装的,如果是linux或mac用户,官网有更详细的安装说明. windows 10 x64 当然还有广大的windo ...

  7. 通过VuePress管理项目文档(一)

    VuePress 相关链接 完整的Vue组件代码以及完整的文档,仅适用于个人参考学习: 文档预览地址:预览链接 使用VuePress编辑文档的代码访问:组件文档 完整代码:组件代码 Vue组件开发 这 ...

  8. Java-Maven-Runoob:Maven 项目文档

    ylbtech-Java-Maven-Runoob:Maven 项目文档 1.返回顶部 1. Maven 项目文档 本章节我们主要学习如何创建 Maven 项目文档. 比如我们在 C:/MVN 目录下 ...

  9. 使用 Hexo 创建项目文档网站

    当我们发布一个开源项目的时候,最重要的事情之一就是要创建项目文档.对使用项目的用户来说,文档是非常有必要的,通常我们可以使用下面这些方式来创建文档: GitHub Wiki:在 Github 上我们可 ...

随机推荐

  1. 浅谈IOS8之size class

    文章目录 1. 简介 2. 实验 3. 实战 3.1. 修改 Constraints 3.2. 安装和卸载 Constraints 3.3. 安装和卸载 View 3.4. 其他 4. 后话 以前和安 ...

  2. MVC 5学习总结笔记1

    01.使用MVC自带的DataAnnotations实现数据验证 public class ExternalLoginConfirmationViewModel { [Required] [Displ ...

  3. BZOJ3202 [Sdoi2013]项链

    Problem E: [Sdoi2013]项链 Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 427  Solved: 146[Submit][Sta ...

  4. HDU 1813 Escape from Tetris

    TMDTMD IDA*没跑了.什么是IDA*? 就是迭代深搜+A*估个价. 然而为什么调了一天? n<=2的时候我输出了东西.... 看了一天. #include<iostream> ...

  5. bzoj1121

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1121 题解: 神题啊,妈的不会写的都去吃屎吧.

  6. ML_note1

    Supervised Learning In supervised learning, we are given a data set and already know what our correc ...

  7. iOS 沙盒

    1. 概念 某个应用程序的非代码文件存放空间. 2. 文件结构 每个沙盒有三个文件夹: Documents: 存放文件 Library: 存放默认设置或状态信息.Library/caches: 缓存文 ...

  8. add jars和add external jars有什么区别

    原文add jars和add external jars有什么区别?   add jars和add external jars有什么区别?   add external jars  = 增加工程外部的 ...

  9. Mysql表锁、行锁、页锁

    参考 http://www.jb51.net/article/50047.htm <MySQL行级锁.表级锁.页级锁详细介绍> 页级:引擎 BDB.表级:引擎 MyISAM , 理解为锁住 ...

  10. delphi TServerSocket的多线程

    http://blog.sina.com.cn/s/blog_471218c2010001qc.html unit U_dxc; interface uses  Windows, Messages, ...