Jiang-Xuan / tuchuang.space

一个测试驱动的开源图床系统
https://tuchuang.space
MIT License
5 stars 1 forks source link

MVP 版本 #1

Closed Jiang-Xuan closed 4 years ago

Jiang-Xuan commented 5 years ago

一期页面功能需求点

Jiang-Xuan commented 5 years ago

阿里云子账号已经申请:

用户登录名称 登录密码 AccessKey ID AccessKeySecret
tuchuang.space@1803941249062137.onaliyun.com qIn#I%Oo9Ov4Z\|!cWGaRLsuq8Zs3GuaA 已修改 **** *****
Jiang-Xuan commented 4 years ago

/api/x.x.x/images 接口测试用例

Jiang-Xuan commented 4 years ago

二期工程: 接入阿里 OSS 存储

Jiang-Xuan commented 4 years ago

三期工程: 前后端接口联调

Jiang-Xuan commented 4 years ago

Github Action

Jiang-Xuan commented 4 years ago

域名购买

图床空间图片文件子域名

Jiang-Xuan commented 4 years ago

Github action 冲突

问题描述

POST /api/1.0.0/images 接口的 e2e 测试会和 阿里 oss 通讯来测试存储功能是否正常, 现在的 github actions 会同步执行3个任务, Node 8.x, 10.x, 12.x, 都是和同一个 oss 进行通讯, 会导致同名的 oss 文件被删除, 有可能导致其他任务的失败, 需要一个解决方案来处理这个问题

Bug reproduce

  1. Node 8.x 测试用例上传了 png.png 文件
  2. 这时候有可能 Node 10.x 已经执行到了 删除 png.png 的测试用例, 于是把 png.png 文件删除了
  3. 这时候 Node 8.x 有可能执行 png.png 文件是否存在的逻辑, 这时候就会失败

解决方案

想法1: 每一个任务都一个 id, 把这个 id 加到每一个上传的文件名之上 ~想法2: 每一个任务都新建一个 OSS~ 不太靠谱, oss 限制每一个账号最多拥有30 个 oss Bucket, 有可能达到上限 ~想法3: 在每一次的是之前都操作一下所有的图片~ 文件 hash 会变化, 需要在测试用例里面动态计算文件的 md5, 提升测试用例的复杂度, 不可取

采用想法1

给 config.js 加上是否有文件后缀的配置, 默认为空字符串 目前只给 e2e 测试使用, example:

// 文件名
const fileName = `${fileMd5}-${suffix}${fileExt}`
Jiang-Xuan commented 4 years ago

github action 的 浏览器 e2e 测试抛错误 https://github.com/Jiang-Xuan/tuchuang.space/runs/249370024#step:4:104

解决方案

Jiang-Xuan commented 4 years ago

frondend e2e 测试用例

Jiang-Xuan commented 4 years ago

github actions 拆分前后端测试

2

windows bat 注意点

  1. yarn/npm install 命令会中止 bat 文件的执行
  2. call 调用子进程, 如果子进程报错, 则退出进程 https://stackoverflow.com/questions/734598/how-do-i-make-a-batch-file-terminate-upon-encountering-an-error#answer-21912169
Jiang-Xuan commented 4 years ago

经验

前端 e2e 测试用例

这里的接口都指的是 mock 接口, 并不会真正的向后端服务发起请求, 因为这里只是前端的 e2e 测试, 不受后端服务的状态影响, 非 mock 接口的测试称之为集成测试

Jiang-Xuan commented 4 years ago

引入 husky , 提升代码质量

Jiang-Xuan commented 4 years ago

探索 pm2 使用

pm2 prod 环境 CD 部署流程以及一些变量 deploy-to-prod

GITHUB ACTIONS SECRETS:

  1. PROD_DEPLOY_SSH_PRIVATE_KEY ssh public key pm2 的部署需要连接服务器, 采用 ssh key 的方式进行登录, 而不是使用密码 github secret 之中的换行尚不知道是如何处理的, 所以目前手动处理了, 将换行用 \n 替代, 然后用 sed 处理, 说起 sed, mac 的 sed 和 linux 的sed 有所不一致, 见 https://github.com/allenGKC/Blog/issues/5
  2. PROD_DEPLOY_USER deploy user 部署使用的用户名
  3. PROD_DEPLOY_HOST deploy host 部署使用的主机地址
  4. PROD_DEPLOY_PATH deploy path 部署使用的文件目录地址
  5. PROD_HOST_KEY 主机的 ssh key, 写入 known_hosts 的数据

部署流程, github actions workflow deploy to prod 在 tag 被 push 的时候执行

  1. install
  2. run test
  3. 如果 test 通过, 进行部署 prod 环境, pm2 deploy ecosystem.config.js prod setup, pm2 deploy ecosystem production

    pm2 beta 环境 CD 部署流程以及一些变量 deploy-to-beta

GITHUB ACTIONS SECRETS:

  1. BETA_DEPLOY_SSH_PRIVATE_KEY ssh public key pm2 的部署需要连接服务器, 采用 ssh key 的方式进行登录, 而不是使用密码 github secret 之中的换行尚不知道是如何处理的, 所以目前手动处理了, 将换行用 \n 替代, 然后用 sed 处理, 说起 sed, mac 的 sed 和 linux 的sed 有所不一致, 见 https://github.com/allenGKC/Blog/issues/5
  2. BETA_DEPLOY_USER deploy user 部署使用的用户名
  3. BETA_DEPLOY_HOST deploy host 部署使用的主机地址
  4. BETA_DEPLOY_PATH deploy path 部署使用的文件目录地址
  5. BETA_HOST_KEY 主机的 ssh key, 写入 known_hosts 的数据

部署流程, github action workflow deploy-to-beta 至在 master push 时候执行:

  1. install
  2. run test
  3. 如果 test 通过, 进行部署 beta 环境, pm2 deploy ecosystem.config.js beta setup, pm2 deploy ecosystem.config.js beta

pm2 deploy 问题1: https://github.com/Jiang-Xuan/tuchuang.space/runs/260033133#step:4:63

Host key verification failed.

github actions 重构 https://github.com/Jiang-Xuan/tuchuang.space/issues/1#issuecomment-542601291

探索 nginx 部署

探索如何从 beta 环境进入 prod 环境

探索如何实施猴子测试 b( ̄▽ ̄)d

Jiang-Xuan commented 4 years ago

前端资源部署方案

该文件部署在服务器之上

在 github action 上新增一个 deploy-to-beta

  1. install
  2. test
  3. 如果 test 通过, 部署至 beta 环境, pm2 deploy ecosystem.config.js beta 打包, 上传资源至 cdn, 然后发布 index.html 文件

前后端发布至 beta 环境问题

后端的接口发布必须保持接口的兼容性, 否则就应该是新接口, 或者是升级接口版本

新版本的发布必须遵循该顺序: 后端接口发布 -> 前端静态资源 cdn 发布 -> 前端 index.html 文件发布

Jiang-Xuan commented 4 years ago

版本回滚策略

Jiang-Xuan commented 4 years ago

github actions 重构

因为发布策略必须遵循顺序 backend -> frondend -> index.html 发布顺序, 所以导致发布流程不能拆分在多个 workflow 中, 必须在同一个 workflow 中:

所以将 backend deploy-to-beta, deploy-to-prod 两个 job 拆分到不同的 workflow 中, 老的方案为 https://github.com/Jiang-Xuan/tuchuang.space/blob/fec64c83b62f3c6236f78b3cd06ce3977973ef63/.github/workflows/nodejs.yml#L29 https://github.com/Jiang-Xuan/tuchuang.space/blob/fec64c83b62f3c6236f78b3cd06ce3977973ef63/.github/workflows/nodejs.yml#L55

新版方案

master(beta 环境)

deploy-to-beta workflow

on: push: branches:

install test 如果 test 成功, deploy to beta

tag 环境(prod 环境)

on: push: tags:

install test 如果 test 成功, deploy to prod

对于 browsers.yml 和 nodejs.yml workflow 的修改

将只运行于 非 tag 和 master 的分支

on: [push]

改为:

on:
    push:
        branchs-ignore:
         - master
        tags-ignore:
        - *

frondend 代码发布方案

采用 pm2 deploy 发布, 在 post-deploy 中执行以下步骤:

  1. 打包
  2. 发布 dist 目录下的所有静态资源到 cdn
  3. ~发布 index.html 到 backend 目录之下~ 发布至 backend 目录之下严重的将 backend 和 frondend 耦合在了一起, index.html 依赖 backend 的目录, 所以考虑可以在前端做中间层, 将 ui 渲染层交给 frondend 层处理, api 路由交给 backend 处理, 可以在 nginx 层做转发, tuchuang.space/[^api]/**/* 路由交给 frondend 处理, tuchuang.space/api/**/* 交给 backend 处理, 这里说一下对于未来的期望 可以采用 api.tuchuang.space 来做 api 层, 用二级域名区分 frondend 和 backend
Jiang-Xuan commented 4 years ago

image

Jiang-Xuan commented 4 years ago

项目 0.0.1 版本 wiki

API 文档

Jiang-Xuan commented 4 years ago

前端 cdn 资源引用路径

Jiang-Xuan commented 4 years ago

nginx 配置

linode 提供的文档是非常棒的 https://www.linode.com/docs/web-servers/nginx/use-nginx-reverse-proxy/

Jiang-Xuan commented 4 years ago

Bug Report

上传图片的文件名配置 https://github.com/Jiang-Xuan/tuchuang.space/blob/ded87c7896d75f79deb0917a689d98a32b974ffc/backend/config.js#L38

该配置是为了解决这个问题 https://github.com/Jiang-Xuan/tuchuang.space/issues/1#issuecomment-538709220 实际部署的时候不会使用, 但是目前上传完毕的图片会出现 image bug

Jiang-Xuan commented 4 years ago

bug: 前端 e2e 测试 关于使用 react-router 测试跳转的测试用例

背景

现在测试用例的测试方法为, webpack 打包出资源, puppeteer 访问 file://foo/bar/index.html 来进行测试,

复现

  1. 接入 react-router 并且使用 browserRouter image

  2. 测试点击 api 是否跳转进了 /api 路由

  3. 页面无法正常加载, react-router 路由失效

原因

react-router 使用 pathname 匹配路由. file://foo/bar/index.html 的 pathname 为 /foo/bar/index.html 所以无法正确的匹配路由

解决方案

使用一个静态服务器托管 dist 目录

遇到的问题, close 会 grace shutdown, 会减缓测试的执行速度:

https://github.com/nodejs/node/issues/2642

afterAll(async () => {
    await new Promise((resolve, reject) => {
      testServer.close(error => error ? reject(error) : resolve())
    })
  })

解决方案: https://github.com/hunterloftis/stoppable

Jiang-Xuan commented 4 years ago

backend 移除图片的 e2e 测试用例

请求格式 DELETE /api/1.0.0/images HTTP/1.1

Body:

content-type: application/json

{ key: <移除图片的 key> }

// arrange 上传一张图片至 ali oss const deleteKey = '' // deleteKey 文件:key = 1:1

// act request(app).delete('/api/1.0.0/images').send({ key: deleteKey })

// assert 该图片已经不存在于 ali oss 中

key 不正确的测试用例

请求格式 DELETE /api/1.0.0/images HTTP/1.1

Body:

content-type: application/json

{ key: <不正确的移除图片的 key> }

// arrange const deleteKey = 'abcdefghijklmnopq'

// act request(app).delete('/api/1.0.0/images').send({ key: deleteKey })

// assert 响应 404

key 不存在响应 422 Unprocessable Entity

Jiang-Xuan commented 4 years ago

已发布 https://github.com/Jiang-Xuan/tuchuang.space/releases/tag/v0.1.3