前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >从 0 到 1 node 项目管理系统:搭建基础平台(下)

从 0 到 1 node 项目管理系统:搭建基础平台(下)

作者头像
Cookieboty
发布2020-10-23 15:10:24
9790
发布2020-10-23 15:10:24
举报

前言

基础平台搭建上篇 介绍项目流程设计、数据库搭建、jwt 登录等模块

基础平台搭建中篇 介绍分支管理设计、webSocket 基础模块

本篇下将介绍流程管理与提测相关基础模块

后端模块

  1. DevOps - Gitlab Api使用(已完成,点击跳转)
  2. DevOps - 搭建 DevOps 基础平台(已完成 70%)
  3. DevOps - Gitlab CI 流水线构建
  4. DevOps - Jenkins 流水线构建
  5. DevOps - Docker 使用
  6. DevOps - 发布任务流程设计
  7. DevOps - 代码审查卡点
  8. DevOps - Node 服务质量监控

前端模块

  1. DevOps - H5 基础脚手架
  2. DevOps - React 项目开发

后期可能会根据 DevOps 项目的实际开发进度对上述系列进行调整

流程与提测管理

流程管理

在基础平台搭建上篇已经介绍过流程的设计,这里再简单解释下

  1. 开发同学创建对应的工程以及分支,进行功能开发
  2. 项目负责人创建流程时,关联多个开发分支,附加需求(需求模块简化成 desc 字段描述,没有单独抽出去)
  3. 流程的状态由关联的分支状态组合,当所关联所有的开发分支状态全部转变为已完成的时候,才会进入下一个状态

整个项目管理,应该拆解成项目->需求->工程,预留字段,将需求跟流程直接合并在一起,先完成主要功能,后期再进一步的拓展

提测管理
  1. 开发人员在开发完对应功能进行项目提测
  2. 未关联流程的分支不能进行提测
  3. 提测之后,测试同学介入测试,根据 desc (需求)进行测试
  4. 开发内容再提测之后,才能发布到预发或生产,否则只能在测试环境发布(禁止未测试的需求直接上线)

不要嫌麻烦,现实中,产品随便提个需求就上,出现问题到处甩锅的情况还少吗?严格卡关也是减轻工作量的一个小助力

DevOps 开发下篇

创建流程模块

代码语言:javascript
复制
import { Post, Prefix, Get } from "egg-shell-decorators";
import BaseController from "./base";

@Prefix("process")
export default class ProcessController extends BaseController {
  /**
   * @author: Cookie
   * @description: 创建 devOps 任务流
   */
  @Post("/create")
  public async createProcess({
    request: {
      body: { params },
    },
  }) {
    const { ctx } = this;
    const { username } = this.userInfo;
    const { name, branchIds, workflowTplId, desc } = params;
    const branchStatus = await ctx.service.branch.checkProcess({ branchIds });
    if (!branchStatus)
      this.error({
        msg: "已有分支在流程中",
      });
    const status = await ctx.service.process.createProcess({
      desc,
      name,
      branchIds,
      workflowTplId,
      createdUser: username,
      updateUser: username,
    });
    await ctx.service.branch.updateBranch({
      branchIds,
      opt: {
        processId: status.id,
      },
    });
    this.success(status);
  }

  /**
   * @author: Cookie
   * @description: 查询 devOps 任务流
   */
  @Get("/getList")
  public async getProcessList({ request: { query } }) {
    const { ctx } = this;
    const { pageSize = 10, pageNum = 1 } = query;
    const processList = await ctx.service.process.getProcessList({
      pageNum: parseInt(pageNum),
      pageSize: parseInt(pageSize),
    });
    // 联表查询分支信息
    for (let process of processList.rows) {
      const { branchIds } = process;
      process.branches = await ctx.service.branch.getSelfBranchList({
        branchIds,
      });
    }
    this.success(processList);
  }
}

提测模块

代码语言:javascript
复制
import { Post, Prefix, Get } from "egg-shell-decorators";
import BaseController from "./base";

@Prefix("testRecord")
export default class TestRecord extends BaseController {
  /**
   * @author: Cookie
   * @description: 创建提测记录
   */
  @Post("/create")
  public async createTestRecord({
    request: {
      body: { params },
    },
  }) {
    const { ctx } = this;
    const { id: submitUserId } = this.userInfo;
    const { desc, name, branchIds, testUserId } = params;

    const branchStatus = await ctx.service.branch.checkProcess({
      branchIds,
      status: "every",
    });

    if (branchStatus)
      this.error({
        msg: "存在未关联流程的分支",
      });

    const status = await ctx.service.testRecord.createTestRecord({
      desc,
      name,
      branchIds,
      submitUserId,
      testUserId,
      testStatus: 0,
    });
    this.success(status);
  }
}

提测消息推送采用邮件(正式)与机器人(即时),提测内容、次数、质量等写入数据库,系统本身也能追踪,作为后期效能评估的辅助

邮件推送

提测模块的具体实现代码,我们分为 3 块

  1. 发送邮件使用 nodemailer
  2. 邮件模板使用 nunjucks 模板引擎,配置邮件模板
  3. 邮件前端自定义内容使用 marked 插件解析 markdown 语法
代码语言:javascript
复制
import { MAIL_CONFIG } from "../../config/default.config";

const marked = require("marked"); // marked 转换
const nodemailer = require("nodemailer"); // 发送邮件
const nunjucks = require("nunjucks"); // 模板引擎
const path = require("path");

// 邮箱配置初始化
const transporter = nodemailer.createTransport({
  host: MAIL_CONFIG.service,
  secureConnection: true, // 使用 SSL 方式(安全方式,防止被窃取信息)
  port: MAIL_CONFIG.port,
  auth: {
    user: MAIL_CONFIG.user_email, // 账号
    pass: MAIL_CONFIG.auth_code, // 授权码
  },
});

const htmlModel = ({ storyMail, exitInfo, summitUser, iterationMail }) => {
  const html = nunjucks.render(path.join(__dirname, "./emailTpl/email.njk"), {
    storyMail,
    exitInfo,
    summitUser,
    iterationMail,
  });
  return html;
};

/*
 * toEmail: String 接收者,可以同时发送多个,以逗号隔开
 * subject: String 标题
 * cc: String 抄送
 * text: String 文本
 * html: Object titleList表头 conterFontList内容
 * attachments: any 附件
 * [
 *  {
     filename: 'img1.png',            // 改成你的附件名
     path: 'public/images/img1.png',  // 改成你的附件路径
     cid : '00000001'                 // cid可被邮件使用
    }
 * ]
 */

interface mailInterface {
  toEmail: string;
  subject: string;
  cc?: string;
  text?: string;
  html?: any;
  attachments?: any;
  storyMail?: any;
  exitInfo?: any;
  summitUser?: String;
  iterationMail?: any;
}

const sendMail = async (mailOptions: mailInterface) => {
  const {
    toEmail,
    subject,
    cc,
    text,
    attachments,
    storyMail,
    exitInfo,
    summitUser,
    iterationMail,
  } = mailOptions;
  Object.keys(exitInfo).forEach((key) => {
    exitInfo[key] = marked(exitInfo[key]);
  });
  const html = htmlModel({ storyMail, exitInfo, summitUser, iterationMail });
  const mailOpts = {
    from: MAIL_CONFIG.user_email, // 发送者,与上面的 user 一致
    to: toEmail,
    subject,
    cc,
    text,
    html,
    attachments,
  };
  try {
    transporter.sendMail(mailOpts);
    return true;
  } catch (err) {
    console.log(err);
    return false;
  }
};

export default { sendMail };
钉钉群机器人

具体参考钉钉机器人文档下面附带具体的实现代码(为了安全且简单,采用加签的安全验证)

代码语言:javascript
复制
const crypto = require("crypto");
const secret ="";
const sendUrl =""; // 替换成自己的

export default (app) => {
  return {
    async send(content) {
      const timestamp = Date.now();
      const str = crypto
        .createHmac("sha256", secret)
        .update(timestamp + "\n" + secret)
        .digest()
        .toString("base64", "UTF-8");

      try {
        const { res, data } = await app.curl(
          `${sendUrl}×tamp=${timestamp}&sign=${encodeURIComponent(str)}`,
          {
            headers: {
              "Content-Type": "application/json; charset=utf-8",
            },
            method: "POST",
            data: JSON.stringify(content),
          }
        );
        return res;
      } catch (error) {
        return error;
      }
    },
    text({ content = {}, at }) {
      console.log("content===>", content);
      at = at || {};
      this.send({
        msgtype: "text",
        text: {
          content,
        },
        at,
      });
    },
  };
};

// 测试机器人 Controller
import { Post, Prefix, Get } from "egg-shell-decorators";
import BaseController from "./base";

@Prefix("robot")
export default class ProjectController extends BaseController {
  @Post("/ding")
  public async getProjectList({
    request: {
      body: { params },
    },
  }) {
    const { ctx } = this;
    const { content } = params;
    await ctx.helper.robot.ding.text({ content });
    this.success({});
  }
}

上述只附带了 text 文本消息推送,markdown、link、FeedCard 等其他消息类型,照着例子直接上手改就行了

建议

从第一篇看到目前这篇博客的同学,如果团队缺少合适的项目管理或者想练习 node 的情况下,可以上手试试看,一般关键的代码,我有直接贴在博客上(大部分复制就能用啊)。

后面的内容就是贴合业务直接 curd 代码,基础篇到此结束。

下一篇就会出构建篇,团队可以结合自己项目实际情况增减功能,完善团队基础管理流程。

不明白的地方可以留言

尾声

此项目是从零开发,后续此系列博客会根据实际开发进度推出(真 TMD 累),项目完成之后,会开放部分源码供各位同学参考。

为什么是开放部分源码,因为有些业务是需要贴合实际项目针对性开发的,开放出去的公共模块我写的认真点

为了写个系列博客,结果要写完一整个系统(不是一般的累),觉得不错的同学麻烦顺手三连(点赞,关注,转发)。

如对文章内容有任何疑问、见解可添加微信 沟通。

另外关注公众号 Cookieboty1024,欢迎加入前端小兵成长营

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-08-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 前端小兵成长营 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 流程与提测管理
    • 流程管理
      • 提测管理
      • DevOps 开发下篇
        • 创建流程模块
          • 提测模块
            • 邮件推送
            • 钉钉群机器人
        • 建议
        • 尾声
        相关产品与服务
        CODING DevOps
        CODING DevOps 一站式研发管理平台,包括代码托管、项目管理、测试管理、持续集成、制品库等多款产品和服务,涵盖软件开发从构想到交付的一切所需,使研发团队在云端高效协同,实践敏捷开发与 DevOps,提升软件交付质量与速度。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档