公司定位与长远目标

我们制作并销售软件, 以此获得乐趣及收入。

原则与价值观

基本原则

  • Open 开放
  • Remote 相互信任的协作文化
  • Engineer 工程师思维

制度

  • 无加班文化

不做的事情

  • 对商业贿赂零容忍
  • 放弃大公司带来的收入

组织模式与协作

述知科技从启动的第一天开始就在分布式协作,创始人是自由职业者,为数不多的全职员工,亦分布在各地,通过远程松散式协作来逐步推进团队和平台建设。

我们同时招募了不少素未谋面的远程兼职同事,像开源项目一样讨论、分享、Review,来高质量的完成代码工作。还有不少抱着好奇、学习或尝试等心态临时参与项目的陌生网友。

让大家能够在这里参与并收获价值与乐趣,是我们一直在探索的。

⚠️ 目前述知的制作软件产品的方向是由创始人,及几个顾问来共同决策,后续发展到一定阶段,也希望能找到更好的机制来决定产研的投入方向。

成员类型

  • 创始团队,负责产品方向决策,整体资金投资回报管控;
  • 全职员工,负责平台搭建,任务分拆和评审,会被分配管理员权限
  • 兼职员工,负责具体开发任务处理和维护,会被分配具体项目组权限
  • 注册用户(GitHub 登录用户),等同于匿名用户,可以参与对外开源项目与竞争类型的开发任务

🤔 如何加入述知及 「在招」 岗位, 👉 请看这里

工作流程

  1. 飞书表格中查看任务需求、讨论确认后,标记状态为进行中
  2. Code Review 平台按照 Review 流程 进行代码修改、交付工作;
  3. 交付完成后,在限定的维护期内,对开发任务关联的问题工单进行修复处理;

开发任务

  • 需求明细、文档完整、相对独立的开发需求;
  • 工时控制在两周内(1 周开发,1 周 Review,2~4 周维护周期);
    • 最快一周内完成交付,最迟两周内;
  • 开发任务的薪酬包结构说明:
    • 1600 元(Review 通过支付 800 元,维护期结束支付 800 元);
    • 为避免兼职劳务税务成本,一般分在两个自然月内完成支付结算;
    • 并行任务造成额外的税务成本,需要个人开发者自行承担;
  • Review 审阅人员会有单独的津贴奖励,目前并未公开招募;

🤔 为什么这么设计?

薪酬包预算和时间固定,由全职团队按标准评估确认,避免评估、报价的沟通成本及信任损耗

任务类型

  • 指派任务,按计划时间执行,项目管理人员直接指派,其他人无法竞争;
  • 开放任务,谁先提交修改通过初步 Review(+1),谁获得该任务,其他人的修改作废。
    • 该任务需求说明是公开的,所有代码平台注册用户均可读。

如何加入?

这是草稿版本,可以忽略;

通用技能要求

需要掌握的知识:

  • CS 基础知识:https://lonexw.github.io/sse-book/cs/intro.html
  • Linux 与命令行:https://lonexw.github.io/sse-book/master_linux.html
  • git basic & workflow
    • https://git-scm.com/
    • https://docs.google.com/presentation/d/1IQCRPHEIX-qKo7QFxsD3V62yhyGA9_5YsYXFOiBpgkk/view#slide=id.g4d6b1121f4_0_2431
    • https://docs.google.com/presentation/d/1C73UgQdzZDw0gzpaEqIC6SPujZJhqamyqO1XOHjH-uk/view#slide=id.g4d6c16487b_1_2484
    • https://lonexw.github.io/sse-book/teamwork/intro.html
  • gerrit for code view
  • devops & ci

工程师素养

  • https://lonexw.github.io/sse-book/engineer/intro.html

[在招] 岗位及要求

  • 客户端
  • 服务器端
  • 业务端(Rust)

申请方式:

  1. 发送邮件到 lone@expound.cc, 邮件规范:
subject: [兼职岗位申请] 

content example.
  1. 直接【在招】平台提交申请;

入职准备

在你通过述知科技的面试流程后,需要处理以下事务:

📮 拿到工作邮箱账号

  1. 在工作设备或手机安装注册飞书 账号, 作为即时沟通及邮件客户端使用;
  2. 发送必要账号信息到邮箱: lone@expound.cc,邮件内容模板:
    标题:[入职申请] {真实姓名} - {岗位名称}
    内容:
    
    ---
    飞书账号:185******         // 说明:手机号码
    常用用户名:lone            // 此用户名会作为邮箱用户名,需唯一
    
    结算信息(可选):          // 亦可后续单独沟通提供
    - 真实姓名:
    - 身份证号码:             // 实名信息用于签署电子劳务合同
    - 银行账号:              // 薪酬结算账号,需本人
    - 开户行:               // 部分银行财务结算需要
    --- 
    
    // 此申请将于 1 个工作日内完成处理;
    
  3. 申请通过后,你会被加入飞书 [述知科技] 组织,在飞书邮箱中会收到需要实名签署的兼职劳务电子合同及保密协议

💼 熟悉工作平台

飞书项目进度管理文档

在飞书表格文档上面可以看到所有的指派任务和开放任务,示例项目:拼加增长工具箱任务管理

代码审阅平台 code.expound.cc

code.expound.cc

使用谷歌的开源项目 Gerrit Code Review 工具来管控代码质量和交付,支持 GitHub 授权登陆,查看使用介绍

文档资料

团队 Wiki:wiki.expound.cc

提交代码修改

软件工程有点像制作音乐,一段看起来简单、符合逻辑的代码修改,实际上需要多次修改和大量工作的投入迭代才能最终定版,合并到代码仓库。这份代码日常,通常来讲包含以下部分:

  • 修复编译错误
  • 代码抽象和方法重构,避免重复代码
  • 使用更好的算法设计,更快、性能更好
  • 处理各种异常情况,是程序更加健壮
  • 添加测试代码,避免异常回归或引入错误
  • 预发环境测试,验证修改结果和带来的改变
  • 整理代码,提升可读性
  • 改进修改提交消息,解释为什么要做这次提交

半成品的代码,最好不要放进代码仓库中,我们使用 Gerrit 来协助处理代码合入 Code base 前的协作。

Consider Queen’s six-minute long Bohemian Rhapsody, which took three weeks to record. Some segments were overdubbed 180 times!

接到开发任务,开始工作

项目列表中找到需要的代码仓库,项目权限可以找开发任务所属的项目负责人分配。

从项目仓库中,拉取最新的代码到本地:

git clone https://code.expound.cc/expound-wiki

在个人设置页面 #HTTPCredentials 可以生成 HTTP 密码;

提交本地代码修改

⚠️ 在你完成本地的代码修改工作后,在提交代码之前需要注意的事项:

1)确认当前项目的 git 用户配置是否和 Expound Review 系统一致, 在项目目录(只对该项目生效):

git config -l                             # 查看所有 git 配置信息
git config user.email "{user}@expound.cc" # 邮箱必须是工作邮箱,否则会拒绝此提交
git config user.name "{your username}"    # 可选配置

2)为了在 commit 消息中自动插入 Review 流程的 Change-ID, 需安装 git hooks:

# 从 Gerrit Server 上直接下载到项目目录
curl -Lo .git/hooks/commit-msg https://code.expound.cc/tools/hooks/commit-msg
# 确保 hook 是可以执行的
chmod u+x .git/hooks/commit-msg

3)提交本地修改:

git commit -a -m "You Commit Message"

推送代码修改到 Review 流程

直接向指定分支推送代码或者推送新分支都是不允许的,如果你想往 develop 分支推送代码:

git push origin HEAD:refs/for/develop  # 分支规范:refs/for/{branch}

推送成功后,在网页端可以邀请其他同事(专家、利益相关者、或团队成员)进行 Review,讨论代码问题:

...

remote: Processing changes: refs: 1, new: 1, done
remote:
remote: SUCCESS
remote:
remote:   https://code.expound.cc/c/expound-wiki/+/2 修改介绍页面跳转链接 🔗 [NEW]
remote:
To https://code.expound.cc/expound-wiki
 * [new reference]   HEAD -> refs/for/develop

Gerrit Code Review 网页端功能使用说明

根据 Review 意见进行修改,再次提交

$ <rework>
$ git commit --amend # Rebase the commit if needed
$ git push origin HEAD:refs/for/develop

在满足 Code-Review Label 的投票规则后,该修改即可等待提交自动合并。

Rebase a Change locally

// update the remote tracking branches
$ git fetch

// fetch and checkout the change
// (checkout command copied from change screen)
$ git fetch https://gerrithost/myProject refs/changes/74/67374/2 && git checkout FETCH_HEAD

// do the rebase
$ git rebase origin/main

// resolve conflicts if needed and stage the conflict resolution
...
$ git add <path-of-file-with-conflicts-resolved>

// continue the rebase
$ git rebase --continue

// push the commit with the conflict resolution as new patch set
$ git push origin HEAD:refs/for/develop

同时开发多个功能,建议为每个功能在本地配置多个 feature 分支。

代码维护指南

待实践总结,维护环节难得是如何定位问题。

代码规范(开发必读)

基于微信云托管及微信生态等基础设施,我们对平台的技术架构进行了整体规划:

Architecture

查看架构图

类似微服务架构,服务层将业务功能拆分成 n 个独立的:业务模块(Bussiness Module)

  • 每个业务模块由 3 个核心子模块组成:
    • moduler-server:数据服务(迁移及模型管理),给业务平台提供数据接口;
    • module-api: 业务接口,给前端小程序提供数据及业务能力;
    • module-opeapi: 模块开放接口,提供定制业务对接使用,外网可访问;
  • 子模块之间可以通过 http/websocket 的方式相互内网调用,可以跨业务模块调用;
  • 子模块都是独立的代码仓库,技术框架一致,都可以独立容器部署

前端业务规范:

🏷️ 代码协作

  1. 开始新的开发任务,获取最新的主分支(main)作为代码基础,无需创建新分支
  2. 多人协作,完成代码修改后,提交审阅前最好进行 rebase,跟上最新提交;
  3. 主分支最新代码会自动同步到预览环境,生产环境代码部署需要指定 tag 版本号

📑 API 版本变更策略

直接在路由路径中增加版本号,以新增接口的方式实现:

GET /api/{api_version}/module/status

在 Apifox 中以版本号为名称作为接口子目录,增加新版本的接口说明:

API_VERSION

🔨 工具推荐

代码编辑:

依赖管理:

数据库管理:

文档管理:

数据库 schema 修改规范

命名规范

  • 数据库名称使用下划线风格:pinjia_preview
  • 数据表名称使用下划线风格(复数):lottery_codes、activities
  • 代码及文档中的数据模型名称使用大驼峰风格:LotteryCode、Activity
  • 数据库中的字段使用下划线风格:created_at、last_name

字段注释规范

  • 中文名;字段说明

MODULE-server 开发说明

module-server 模块的核心目的是完成某个业务模块的数据模型、数据库迁移管理,并为业务平台提供数据管理的接口服务。

代码说明:

1)根据业务需求,完成数据模型定义

拉取最新的项目代码,在本地启动服务后即可开始工作和代码提交:

# 默认连接预览(preview)环境的数据库: database/config.json
pnpm run dev 

⁉️ 如果你的工作涉及到数据库的变更:

  1. 首先按照 database/config.json 文件中的 development & test 环境信息,创建本地数据库账号及 database:

    • 建议使用 MySQL 8.0 版本,与线上环境保持一致;
    • 账号密码默认为: root / P@ssw0rd
    • 手动创建本地需要的开发和测试数据库:pinjia_dev & pinjia_test
  2. 新建 migration 文件并执行迁移:

    # 快速生成 migration 文件,也可以手动创建
    npx sequelize migration:generate --name=create-users
    # 📝 创建或修改数据表结构, 记得补全注释信息
    code database/migrations/${timestamp}-create-users.js
    # 执行 migrate 进行数据库变更,db:migrate:undo
    npx sequelize db:migrate   
    
  3. 建议单独提交 schema 变更代码进行审阅,提交合并后,预览(preview)环境会自动进行同步变更;

    • 破坏性的数据库变更需要进行审阅才可以发布;
    • 本地无法对预览环境数据库直接运行迁移,无变更权限;
  4. 如果你想在开发时使用本地数据库,可以设置环境变量:

    NODE_ENV=local pnpm run dev  # 快捷命令:pnpm run local
    

🔖 项目负责人职责:完成数据库模型定义修改 & 审阅发布后,需要手动进行 API 文档 - 数据模型 的数据库导入覆盖。

深入了解:

2)API 文档先行,完成数据服务接口代码

在进行具体的接口开发任务时,需要遵循 API 文档先行 的开发方式;

  1. 开发中的接口在 Apifox 分支 preview 迭代更新,不允许直接修改 main 分支的接口
  2. 在对应项目的接口管理中新增或修改已有接口,完成详细的接口说明和 mock 配置
  3. 根据接口文档,完成具体的服务接口代码修改工作,提交代码审阅;

单元测试必须在提交审阅前完成,阅读教程

🔖 项目负责人职责:在代码审阅完成及发布预览环境后,需要手动合并接口文档到 main 分支;

还有就是记得及时更新 API 文档的接口状态 [ 开发中/测试中/已发布 ]

3)生产环境发布流程

云托管 CLI 工具文档:https://cloud.weixin.qq.com/cli/guide.html

pnpm install -g @wxcloud/cli

记得配置生产环境的必要环境变量,否则会无法启动,导致部署失败;

wxcloud migrate # 生产 Dockfile 以及 wxcloud.config.js 文件
wxcloud deploy  # 部署密钥文件位置 ~/.wxcloudconfig

延伸文档:如何在本地进行容器调试

MODULE-api 开发说明

MODULE-opeapi 开发说明

业务后台开发规范

📖 快速熟悉 eggjs 框架

代码托管与审阅

作为技术驱动的企业,代码是极为重要的工作产出和资产,是工程师日常工作的核心阵地。

代码协作、审查、交付的工作流是一家技术企业信仰和价值观的直接体现。

且考虑到我们团队的组织形式和传统公司不一样,所有人都在远程异步协作,且有大量兼职开发和公开用户的参与,更像一个开源组织的技术管理,所以决定使用 Gerrit 工具来完成代码托管和审阅的工作。

🌿 述知 Code Review 平台地址:code.expound.cc

本地试运行 Gerrit 工具

Gerrit 是一个免费、开源的 Code Review 工具软件,允许开发者通过 Web 界面审阅代码,使用 Git 作为底层的版本控制系统,支持私有化部署、权限控制,以及通过插件进行扩展, 由谷歌提供维护。

它本身是为管理 Android 代码而出现,最早是用 Python2.7 + Django(fork of Rietveld) 编写,在 2.0 版本之后改用 Java 来写,Gerrit 源代码使用的语言级别仍保留在 Java 11 上,但是,Gerrit 是针对 Java 17 构建和分发的,这是在生产中运行它的推荐 JVM 版本,前端使用 Ploymer Web UI。

Java 环境及软件包

需要在本地环境安装 Java11 以上的版本和 Bazel 软件包构建工具。

1)源码构建软件包
git clone --recurse-submodules https://gerrit.googlesource.com/gerrit

# 本地编译
cd gerrit && bazel build release

# 如果切换分支或者更新代码之后,运行下面的命令后再重新编译
git submodule update
git clean -ffd

编译成功后,在 ./bazel-bin 目录下可以看到二进制包: release.war

2)直接下载编译好的 war 软件包 | 查看 Release 版本
wget https://gerrit-releases.storage.googleapis.com/gerrit-3.9.1.war

本地启动

指定测试站点的目录位置(环境变量)

export GERRIT_SITE=~/gerrit_testsite

进行站点初始化,并启动项目:

# --batch 默认的 gerrit 基础配置
# --dev 默认的 Auth 选项为 DEVELOPMENT_BECOME_ANY_ACCOUNT
# --install-all-plugins 可以安装所有插件
java -jar bazel-bin/release.war init --batch --dev -d $GERRIT_SITE

# 或者不初始化站点,直接启动:
java -jar bazel-bin/release.war daemon -d $GERRIT_SITE --console-log

在浏览器中访问:http://localhost:8080, 也可以修改默认端口号:

git config --file $GERRIT_SITE/etc/gerrit.config httpd.listenUrl \
	 'http://localhost:8081'

# Restart Gerrit, or Stop
$GERRIT_SITE/bin/gerrit.sh restart

延伸阅读:

部署 Gerrit 到生产环境

Docker 快速部署

docker run -ti -p 8080:8080 -p 29418:29418 docker.io/gerritcodereview/gerrit:3.9.1

Use docker persistent volumes to keep Gerrit data across restarts. Below is a sample docker-compose.yaml with externally-mounted Lucene indexes, Caches and Git repositories.

version: '3'
services:
  gerrit:
    image: docker.io/gerritcodereview/gerrit:gerrit:3.9.1
    volumes:
       - git-volume:/var/gerrit/git
       - index-volume:/var/gerrit/index
       - cache-volume:/var/gerrit/cache
    ports:
       - "29418:29418"
       - "8080:8080"
volumes:
  git-volume:
  index-volume:
  cache-volume:

Run docker compose up (or docker-compose up with older versions of Docker) to trigger the build and execution of your container.

Docker 镜像项目地址:https://gerrit.googlesource.com/docker-gerrit

Linux 裸机 Standalone Daemon 部署

在需要部署的服务器上安装 Java 环境(推荐 Java17 版本),这里不赘述步骤。

初始化配置

上传编译好或直接下载的软件包到服务器:

# 推荐新建 gerrit 用户部署启动
sudo adduser gerrit && sudo su gerrit

# 初始化项目,注意 gerrit 用户对项目目录的权限
export GERRIT_SITE = /path/to/your/gerrit_application_directory # 可以放到 .bashrc 文件
java -jar gerrit.war init -d $GERRIT_SITE

在初始化过程中,根据提示对项目进行初步配置,·也可以编辑配置文件 $GERRIT_SITE/etc/gerrit.config 来修改,重启服务即可生效。

管理守护进程

$GERRIT_SITE/bin/gerrit.sh start # status | stop | restart

反向代理配置

使用 web server 来反向代理访问服务,方便我们配置域名及 SSL。修改配置文件:

[httpd]
		listenUrl = proxy-http://127.0.0.1:8081

以 Nginx 为示例:

server {
    # HTTP反向代理相关配置开始 >>>
    location ~ /purge(/.*) {
        proxy_cache_purge cache_one 127.0.0.1$request_uri$is_args$args;
    }
    location ^~ {
        proxy_pass http://127.0.0.1:8081;
        proxy_set_header Host 127.0.0.1:$server_port;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header REMOTE-HOST $remote_addr;
        add_header X-Cache $upstream_cache_status;
        proxy_set_header X-Host $host:$server_port;
        proxy_set_header X-Scheme $scheme;
        proxy_connect_timeout 30s;
        proxy_read_timeout 86400s;
        proxy_send_timeout 30s;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
    # HTTP反向代理相关配置结束 <<<
}

数据备份

All primary data is stored in git.

  • Git 仓库镜像自动同步到主流 Git 托管服务平台,如 Gitee;
  • 定时服务器快照备份(云服务厂商付费功能);
  • 网站目录定时冷存储到云服务 COS 存储;

上传项目代码到 Gerrit

1)创建项目

手动创建

确认 Gerrit 配置文件中确认 git 仓库的存放地址 gerrit.basePath,在服务器端运行:

git --git-dir=$base_path/project.git init

重启服务即可看到项目,也可以通过 ssh 刷新项目列表缓存:

ssh {username}@{gerrit_server} gerrit flush-caches --cache project_list

该种方式不会自动分配项目权限,需要在网页端手动编辑处理。

通过 ssh 创建

Caller must be a member of 'Administrators' group, or granted the 'Create Project' capability.

为了使用方便,建议配置本地 ssh 客户端, ~/.ssh/config

Host gerrit-expound
  Hostname code.expound.cc
  Port 29418	# curl https://code.expound.cc/ssh_info
  User git-test # username in Settring/Profile Section
ssh gerrit-expound gerrit create-project tool.git --description "'Tools used by build system'"

参数说明:https://gerrit-review.googlesource.com/Documentation/cmd-create-project.html

其他创建方式

  • 在网页端,BROWSE > Repositories 页面,点击新建按钮新建代码仓库;
  • via the Create Project REST endpoint

2)配置成员及权限

需要在 Administrators 用户组的用户才可以进行用户组的创建和成员管理。

同时创建 Team Group & Team Admin Group,将 Team Group 的所有权移交给 Team Admin Group 是最佳实践;

所有项目权限都继承于 All-Projects,可以把它当作系统全局配置,可以快速从项目模板中继承权限。

  • 对外开源的项目: open-project-template
    • 对所有用户(匿名和注册用户)可读;
    • 所有注册用户可提交修改;
  • 公司内部的项目: bussiness-project-template
    • 所有注册用户可读和可提交修改;
    • 匿名用户无法查看;
  • 指定团队的项目: team-project-template
  • 无需 Code Review 的项目: no-code-review-project-template

管理组成员可向所有项目直接 push 代码,无需经过 review 流程;

3)同步代码

从远程仓库拉取项目最新代码:

git clone https://code.expound.cc/open-project-template

# 或者 fetch 指定分支
mkdir open-project-template
cd open-project-template/ && git init
git clone https://code.expound.cc/open-project-template
git checkout FETCH_HEAD

项目如果已有代码库,直接推送本地代码:

git clone https://code.expound.cc/open-project-template
git push -u origin main

Gerrit 项目管理者指南

项目拥有者必读,学习如何定制项目的工作流配置。

访问权限

项目的配置文件信息存储在特定的代码分支:refs/meta/config, 可以在本地拉取查看:

git fetch ssh://localhost:29418/project refs/meta/config & git checkout FETCH_HEAD
git log project.config

📑 所有配置项目说明

权限分配的粒度 References

  • refs/heads/* : 所有分支代码
  • refs/tags/* : 所有标签
  • refs/for/<ref> : changes 修改上传分支代码
  • ^refs/heads/rel-.* : 正则表达式,所有 rel-* 分支代码
  • Special references:
    • refs/changes/*
    • refs/meta/config
    • refs/meta/dashboards/*
    • refs/notes/review

Groups & User 权限

  • Gerrit also has a set of special system groups that you might find useful.
  • External groups need to be prefixed when assigning access rights to them, e.g. LDAP group names need to be prefixed with ldap/.
  • If the singleusergroup plugin is installed you can also directly assign access rights to users, by prefixing the username with user/ or the user’s account ID by userid/.

Access controls in Gerrit are group based.

  • 系统定义的用户组:Anonymous Users | Change Owner | Project Owners | Registered Users
  • 预定义的用户组:Administrators | Service Users
  • 自定义用户组

详细文档:https://gerrit-review.googlesource.com/Documentation/access-control.html

代码修改提交方式 Sumbit.type

这个方式选择影响整个代码的协作方式,以及开发舒适度的权衡。

  • Fast Forward Only: 限制非常严格,在提交一项修改后,所有基于此分支基础进行的分支都必须重新调整(rebase), 适用于变化很少的分支,但是可以确保目标分支永远不会被破坏。
  • Merge If Necessary:开发者友好,工程师只需要在有冲突时进行 rebase 调整,缺点是存在破坏目标分支的风险,推荐在开发阶段分支上面使用。
    • 等同于 git merge --ff
  • Merge Always: 提交更改时,直接创建合并请求,不关心是否可以快进。
    • 等同于 git merge --no-ff
  • Rebase if necessary: 在无法快进的状态下,自动进行 rebase 操作。
    • Using this submit action results in a linear history of the target branch, unless merge commits are being submitted. For some people this is an advantage since they find the linear history easier to read.
  • Rebase always:提交代码更改时,会直接进行 rebase 操作,不关心是否可以快进
    • rebase always 操作可以被认为与 cherry pick 操作类似,但有一个重要的区别,即 rebase always 不会忽略依赖关系,这就是为什么使用该操作应该优先于 cherry pick 提交操作
  • Cherry Pick: 通过此提交操作,在提交更改时,Gerrit 始终会对当前补丁集执行挑选。 这会忽略父沿袭,而是在目标分支的当前头之上创建一个全新的提交。 提交者成为新提交的提交者,并且保留原始提交作者。
    • 忽略依赖关系还意味着提交者需要以正确的顺序单独提交更改。 否则,提交可能会因冲突而失败,或者目标分支被破坏。
    • 不建议使用此提交操作,因为它会忽略更改依赖项,而应始终使用 rebase。

提交方式配置也可以从其他项目继承,默认是 'merge if necessary';

提交信息的检查

Plugins:

  • https://gerrit-review.googlesource.com/admin/repos/plugins/uploadvalidator,general
  • https://gerrit-review.googlesource.com/admin/repos/plugins/commit-message-length-validator,general

Review 流程 - 标签功能 Labels

CI 工具集成

  • https://gerrit-documentation.storage.googleapis.com/Documentation/3.9.1/intro-project-owner.html#continuous-integration

问题追踪 Issue Tracker Integration

飞书文档项目追踪示例:拼加项目工单

  • https://gerrit-documentation.storage.googleapis.com/Documentation/3.9.1/intro-project-owner.html#issue-tracker-integration

其他操作

Gerrit Admin 配置

登录授权

OpenID: 去中心化的网上身份认证系统

[auth]
	type = OpenID	# Or OpenID_SSO
	openIdSsoUrl = # OpenID 服务商提供的单点登录地址
	allowedOpenID = https://	# 限定可以登录的 OpenID 列表,正则表达式
	trustedOpenID = https://login.launchpad.net/+openid # 区分匿名和注册用户
	openIdDomain = example.com	# List of allowed OpenID email address domains
	maxOpenIdSessionAge = 7200s # Session 有效时间

OpenID Connect 概念解释:

HTTP Basic Authentication

[auth]
	type = HTTP
	auth.httpHeader = # HTTP header to trust the username from
					  # or unset to select HTTP basic authentication
	auth.httpDisplaynameHeader = 
	auth.httpEmailHeader = 
	auth.httpExternalIdHeader = 
	auth.loginUrl = 
	auth.loginText = "Sign In" # Only used if auth.loginUrl is set.
	auth.registerPageUrl = 
	auth.logoutUrl = 
	emailFormat = {0}@example.com

此时,Gerrit 会假设 Web 服务器在讲请求交给自己之前,已经完成了身份验证。

LDAP or LDAP_BIND

OAUTH

[auth]
	type = OAUTH
	gitBasicAuthPolicy = HTTP
[plugin "gerrit-oauth-provider-phabricator-oauth"]
	client-id = PHID-OASC-duqhnip4x7p5mza7guxf
	root-url = https://phab.xyz

auth.gitOAuthProvider 需要插件支持:Gerrit OAuth2 authentication provider

DEVELOPMENT_BECOME_ANY_ACCOUNT

Only for use in a development environment.

auth.gitBasicAuthPolicy

授权方式说明:https://gerrit-review.googlesource.com/Documentation/config-sso.html

Accounts 管理

https://gerrit-review.googlesource.com/Documentation/config-accounts.html#external-ids

主题样式

在 GERRIT_SITE 目录中创建或者修改定制 theme 文件,可以在登录页面生效:

  • etc/GerritSiteHeader.html
  • etc/GerritSiteFooter.html
  • etc/GerritSite.css
  • static/ 静态资源位置

例如,可以在 GerritSiteFooter.html 中增加站点统计代码:

<div>
  <!-- standard analytics code -->
  <script type="text/javascript">
      var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
      document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
    </script>
    <script type="text/javascript">
      var pageTracker = _gat._getTracker("UA-nnnnnnn-n");
      pageTracker._trackPageview();
    </script>
  be <!-- /standard analytics code -->

  <script type="text/javascript">
    window.onload = function() {
      var p = window.location.pathname;
      Gerrit.on('history', function (s) {
        pageTracker._trackPageview(p + '/' + s)
      });
    };
  </script>
</div>

The *.html files must be valid XHTML, with one root element, typically a single <div> tag.

深度的界面定制:

WebUI plugin 示例:

(() => {
  'use strict';

  Gerrit.install(plugin => {
    const rule = `
      html {
        --header-background-color: #347dbe;
        --header-text-color: #fff;
        --header-title-content: "🌿 述知 Code Review";
        --header-title-font-size: 1.4em;
        --header-icon: url("https://phab-xyz-1255747930.cos.ap-beijing.myqcloud.com/expound.png");
        --header-icon-size: 0em;
      }
    `;
    plugin.styleApi(). insertCSSRule(rule);
  });
})();

安装 JS 插件:

ssh -p 29418 lone@code.expound.cc gerrit plugin add -n header-webui-plugin.js - < header-webui-plugin.js

Integration with other tools

REST API

https://gerrit-documentation.storage.googleapis.com/Documentation/3.9.1/intro-project-owner.html#tool-integration

机器人自动评论集成

gerrit.config

配置文件的位置: $GERRIT_SITE/etc/gerrit.config , 下面是部分配置项说明:

[gerrit]
	basePath = git		        # 所有 git 仓库存储的基础路径(相对路径)
	defaultBranch = 	        # 项目创建时的默认分支,默认是 refs/heads/main
	canonicalWebUrl = 	        # 自定义域名
	cdnPath = 		        # Path prefix for Gerrit's static resources if using a CDN.
[accounts]
	visibility = ALL		# 账号之间的可见权限控制,ALL | SMAE_GROUP | VISIABLE_GROUP | NONE
	defaultDisplayName = FULL_NAME	# FULL_NAME | USERNAME | FIRST_NAME
[auth]
	type = HTTP 			# 账号的登录方式配置,比如可以增加 OAUTH、SSO、LDAP 的支持
[oauth]
	allowRegisterNewEmail = true          # additional email addresses can be registered 
	allowEditFullName =             # the full name can be edited in the contact information.
[cache]
	directory = cache		# Gerrit 缓存目录配置(相对路径),持久化为 H2 databases 文件
	h2CacheSize = 250m              # in-memory cache for each opened H2 cache database
[capability]
	administrateServer = group Fail Safe Admins # 管理员用户组配置
	makeFirstUserAdmin = true 	# 是否将第一个用户设置为管理员,默认为 true
[change]
	allowBlame = true		# 是否在 diff 代码时,显示追责按钮
	disablePrivateChanges	        # 是否允许创建私有 Change
	enableAssignee = false	        # 是否允许在界面上进行 指派(Assign) 功能
[httpd]                                 # 使用 Nginx or Apache Web Server 进行反向代理
  	listenUrl = proxy-http://127.0.0.1:8081
[container]
	heapLimit = 512m 		# Maximum heap size of the Java process running Gerrit
	javaHome = 			# Path of the JRE/JDK installation to run Gerrit with.
	javaOptions = 			# Additional options to pass along to the Java runtime.
[sendemail]				# SMTP 邮件发送配置
	smtpServer = 
	smtpServerPort = 465
	smtpEncryption = SSL
	smtpUser =

更多配置:https://gerrit-review.googlesource.com/Documentation/config-gerrit.html

重新加载配置文件或重启服务,运行下面的命令:

$GERRIT_SITE/bin/gerrit.sh restart

云原生 DevOps(运维必读)

拼加:营销增长工具箱

在招: 开源的招聘管理 SaaS 平台

开发任务需求模板

标题:活动管理模块 需求详细说明: 1. 2. 3.

  • 产品文档地址:https://pinjia-wiki.expound.cc

代码要求: 1. 2. 3.

  • 项目代码仓库地址:https://code.expound.cc/plugins/gitiles/expound-wiki

时间要求说明:

  • 开发时间:2024.3.4 ~ 3.11(一周内);
  • Code Review 截止时间:2024.3.15
  • 维护时间周期:交付后 2 周内;2024.3.15~2024.4.01

任务进度管理地址:https://phab.xyz/T20

个人贡献者许可协议

感谢您对述知软件拥有或管理的开源项目的关注。

本贡献者许可协议(“CLA”或“协议”)允许您为项目做出贡献。为了明确任何个人或实体针对其提交的贡献所授予的权利,述知软件需存档由每一位贡献者签署,并表明贡献者同意以下条款的贡献者许可协议。本协议在保护作为贡献者的您的同时,也保护了述知软件;本协议不会改变您将自己的贡献用于其他任何目的的权利。

在填写和签署本协议前,请仔细阅读本贡献者许可协议,并留存一份副本作为您的记录。签署本协议即表示您知悉并同意项目和您对项目的贡献是公开的,且述知软件可能会保留您贡献的记录(包括您随附提供的个人信息,如您的姓名和电子邮箱地址)。

就您目前和未来的贡献,您接受并同意以下条款和条件。除根据本协议授予述知软件和述知软件所分发软件接受者的许可外,您保留与您的贡献相关的所有权利、权属和权益。

1.定义。

“述知软件”是指成都优帆雅成科技发展有限公司及其关联公司。

“项目”是指由述知软件拥有或管理的一个或多个开源项目。

“贡献者”或“您”是指与述知软件签署本协议的并自愿向“项目”提交贡献的版权所有者或经版权所有者授权的个人或法律实体。关于法律实体,做出“贡献”的实体以及控制该实体、受控该实体或与该实体共同被控制的所有其他实体都会被视为同一贡献者。为本定义之目的,“控制”是指:(i)通过合同或其他方式,拥有直接或间接地指导或管理该实体的权力,或(ii)拥有该实体50%或以上的已发行股份,或(iii)该实体的受益所有人。

“贡献”是指您提交给述知软件且可能被并入述知软件拥有或管理的任何文档或产品中的来源于您的原创作品,包括对现有作品进行修改或补充的原创作品。为本定义之目的,当包含您的贡献的交流以电子、口头或书面等任意形式发送给述知软件时,您的贡献视为已“提交”,“贡献”包括但不限于,为沟通和改进之目的,关于述知软件管理或其代表管理的项目的电子邮件清单、源代码控制系统或问题跟踪系统等方面的交流,但不包括您以书面形式明显标注或以其他方式指定为“非贡献”的交流。

2.版权许可授权。

在本协议条款的约束下,您在此授予述知软件和述知软件所分发软件的接收者永久的、全世界范围内的、非独占的、免费的、免授权费的、不可撤销的版权许可,以复制、使用、开发衍生作品、公开展示、公开表演、再许可和分发您的贡献及其衍生作品。

3.专利权许可授权。

在本协议条款约束下,您在此授予述知软件和述知软件所分发软件的接收者永久的、全世界范围内的、非独占的、免费的、免授权费的、不可撤销的(本条款下述情形除外)专利许可,以制造、委托制造、使用、许诺销售、销售、进口和以其他方式转让您的贡献及其衍生作品。该专利许可仅适用于您有权授予且如您不授予,您单独提交的贡献或包含您提交的贡献的项目将必然造成侵权的情况。如果任何实体针对您或其他任何实体提起专利诉讼(包括诉讼中的交叉诉讼或反诉),指控您的贡献或包含您提交的贡献的项目构成直接或间接专利侵权,则您根据本协议就该“贡献”或“项目”授予该实体的任何专利许可自该实体提起诉讼之日起终止。

4.您承诺,您在法律上有权授予上述许可。如果您的雇主对您的贡献享有权利,您承诺您的雇主已授权您提交该“贡献”并放弃此类将该“贡献”提交给述知软件的权利,或您的雇主已与述知软件单独签署企业贡献者协议。

5.您承诺,您的每一个贡献都是您的原创作品(如代表他人授权请参照第7节)。您承诺,您提交的贡献包括所有您个人知悉并与您贡献的任何部分相关的任意第三方许可或其他限制(包括但不限于相关专利和商标)的完整详尽信息。

6.除非您自愿,您并无义务为您的贡献提供支持服务。您可以提供免费的、付费的或不提供支持服务。除非相关法律或本协议要求,您提供的贡献仅是“按现状”提供,不附带任何明示、默示或法定的保证、保障或条件,包括但不限于有关不侵权、适销性或针对特定目的的适用性的保证。

7.如果您拟提交非原创作品,您可以将该作品与您的贡献进行区分后提交给述知软件,但需根据您已知悉的信息去注明该部分内容的来源以及任何许可或限制(包括但不限于相关专利、商标和许可协议)的完整细节信息,并明显地将该部分内容标记为“代表第三方【名称】提交”。

8.您同意,如果您发现您在本协议项下承诺的任何事实或事项有不准确的情况时,您将及时通知述知软件。

9.您同意,项目没有义务接受和包含您的贡献。

10.本贡献者许可协议以中、英文书写,如两种版本存在分歧,以中文版为准。