代码托管
在这里可以安全、高效地进行团队代码协作, 管理项目代码。
开通产品
首次使用,请以项目管理员身份进入代码托管页面,点击马上开通,跳转应用市场购买开通。
为您的租户申请集群授权
集群决定了当前租户下创建的代码仓库是只限内网访问仓库还是可以互联网访问仓库,授权需要联系yanwei001@cmhk.com,
开通集群授权后才能新增代码库。
账号管理
代码库账号初始化
用户第一次使用代码托管时,会自动初始化用户的数据,点击Tips旁的已设置可查看对应的账号和密码信息,该信息将用于对代码库进行git拉取推送的认证。该密码用于登录GIT客户端,git pull/push。
新的密码随机生成,不允许手动修改,只能重新生成,用于代码库的认证,后续还可继续查看。
密码重置
点击重置密码,可对密码进行重置。
仓库管理
新增代码库
在新增代码前需要,在控制台新增应用。备注:只有项目管理员才有权限新增应用。
应用添加成功后,进入代码托管页面新增代码库(项目管理员有权限新增)。
备注:
- 同一个应用,支持建立多个代码仓库。
- 仓库名称可手动修改。
- 勾选“创建README.md”可以初始化该仓库,仓库会自动生成readme文件,不勾选。
仓库不会初始化,要用如图所示的代码进行初始化(已有仓库和关联到招商云仓库两种)。
点击确定后,代码仓库创建成功,即可使用。
导入代码库
将其他系统(例;gitlab、github、gitee)的仓库导入到招商云项目的代码托管系统里。
代码仓库:需要导入的仓库的地址;
access token:通过access token来获取所填写地址的仓库(“源代码库地址”)。
gitlab获取“access token”:
Jenkins链接gitlab需要配置access token,所以先在gitlab上生成access token,后将该token配置在Jenkins上。(access token只需配置一次,后续每个工程直接使用即可)。
1.登录gitlab,在用户头像下拉图标处,选择“setting”;
2.点击“Access token”,输入“Name”、“Expries”、,勾选“api”;
3.点击“Creat personal access token”,生成access token。
github获取“access token”:
1.登录github,点击右上角选择setting;
2.左侧列表选择Developer settings;
3.选择Prsonal access token, 点击generate new token;
4.起个名,权限选择全部;
5.最下面选择 generate token;
6.把token复制出来,不要忘记,只会显示一次。
Gitee获取“access token”:
仓库地址查看
仓库查看
代码库支持查看代码、查看创建分支、查看提交记录、标签等功能。
备注:代码库页面不支持代码的上传,只能通过用户通过git命令去完成这些操作。
代码上传下载
当前代码托管只支持在客户端通过git命令上传下载。
上传下载使用的账号密码需要使用代码库初始化时自动生成的账号密码。
提交 Pull Request
填入Pull Request的说明,点击提交Pull Request,就可以提交一个Pull Request了,如图所示:
请注意,在该界面,可以对 Pull Request 进行指派审查人员,如果勾选必须审查代码,只有对应的人员审查完毕才可以合并。
Pull Request 不能自动合并该如何处理
在提交完 Pull Request 的后,在这个 Pull Request 处理期间,由原本的能自动合并变成不能自动合并,这是一件非常正常的事情,那么,这时,我们有两种选择,一种,继续合并到目标,然后手动处理冲突部分,另一种则是先处理冲突,使得该 Pull Request 处于可以自动合并状态,然后采用自动合并,一般来讲,我们官方推荐第二种,即先处理冲突,然后再合并。
具体操作为:
先在本地切换到提交 Pull Request 的分支,然后拉取目标分支到本地,这时,会发生冲突,需要线下手动合并将冲突处理完毕,然后提交到 Pull Request 所在的分支,等待系统后台完成Pull Request的更新后,Pull Request 就变成了可自动合并状态。
仓库配置
仓库管理只有管理员才有权限操作“成员管理,仓库设置,分支保护,webhooks,代码审查设置”。普通成员不显示该四项功能。
成员管理
代码库支持在页面添加、编辑、删除成员,成员的用户范围为该项目的成员。
备注:仓库观察者,只有读的权限,没有写的权限(没法pull/push)。
代码审查
推荐通过Pull Request这个功能来进行团队中的代码审查,有如下步骤:
代码审查默认设置
设置指定人员为某仓库默认的代码审核/测试人员后,每当有新的Pull Request以此仓库内分支为目标分支时,系统会通知指定人员前去审查提交的Pull Request(也就是改动的代码内容),同时也可以设置合并Pull Request的门槛(例如是否需要全部指定人员同意才可以合并)。
代码审查流程
开发者 提交Pull Request
开发者通过 Fork仓库的分支向源仓库的分支 或 同仓库内的工作分支向源分支 提交Pull Request的方式来发起一个代码审查的请求,以达到更新源分支的代码的目的。
审查者 进行代码审核/测试
指定人员查看开发者提交的Pull Request内容,并决定是否同意接受该开发者的改动。
仓库管理员 合并 Pull Request
仓库的管理人员在审查者同意后,即可通过合并Pull Request的方式把开发者的文件改动内容同步到源分支。
Webhooks
WebHook 功能是帮助用户 push 代码后,自动回调一个您设定的 http 地址。
这是一个通用的解决方案,用户可以自己根据不同的需求,来编写自己的脚本程序(比如发邮件,自动部署等)。
添加Webhooks
测试 WebHook
在添加 WebHook 后,可测试 WebHook 是否可正常使用。开发云代码托管 将发送测试数据到事先设定好的 URL,点击下图的触发即可测试。
参数说明
URL(*): 接收 WebHook 数据的 http 地址。开发云代码托管 将发送 Post 请求到这个地址。
密码: 为了保证安全以及识别数据来源,建议设置一个密码。开发云代码托管 将会在 Post 数据中携带这个密码。
如果选择“WebHook密钥”,密码为用户输入密码。注意, 密码是明文 , webhook密钥内容会直接放在请求头字段X-Gitee-Token和请求体字段password里。
“WebHook密钥“类型的webhook请求例子如下:
假设URL:http://git.dev.cmrh.com/profile
WebHook密钥:PAAS_2021
一次webhook触发的请求内容:
Headers:
Request URL: http://git.dev.cmrh.com/profile Request Method: POST Content-Type: application/json User-Agent: git-oschina-hook X-Gitee-Token: PAAS_2021 X-Gitee-Timestamp: 1631245853338 X-Gitee-Ping: true X-Gitee-Event: Push Hook X-Git-Oschina-Event: Push HookPayload:
{ "ref": "refs/heads/master", "before": "5221c062df39e9e477ab015df22890b7bf13fbbd", "after": "1cdcd819599cbb4099289dbbec762452f006cb40", "created": false, "deleted": false, "compare": "https://gitee.com/oschina/gitee/compare/5221c062df39e9e477ab015df22890b7bf13fbbd...1cdcd819599cbb4099289dbbec762452f006cb40", "commits": [ { "id": "1cdcd819599cbb4099289dbbec762452f006cb40", "tree_id": "db78f3594ec0683f5d857ef731df0d860f14f2b2", "parent_ids": [ "a3bddf21a35af54348aae5b0f5627e6ba35be51c" ], "distinct": true, "message": "Update README.md", "timestamp": "2018-02-05T23:46:46+08:00", "url": "https://gitee.com/oschina/gitee/commit/1cdcd819599cbb4099289dbbec762452f006cb40", "author": { "time": "2018-02-05T23:46:46+08:00", "id": 1, "name": "robot", "email": "robot@gitee.com", "username": "robot", "user_name": "robot", "url": "https://gitee.com/robot" }, "committer": { "id": 1, "name": "robot", "email": "robot@gitee.com", "username": "robot", "user_name": "robot", "url": "https://gitee.com/robot" }, "added": null, "removed": null, "modified": [ "README.md" ] } ], "head_commit": { "id": "1cdcd819599cbb4099289dbbec762452f006cb40", "tree_id": "db78f3594ec0683f5d857ef731df0d860f14f2b2", "parent_ids": [ "a3bddf21a35af54348aae5b0f5627e6ba35be51c" ], "distinct": true, "message": "Update README.md", "timestamp": "2018-02-05T23:46:46+08:00", "url": "https://gitee.com/oschina/gitee/commit/1cdcd819599cbb4099289dbbec762452f006cb40", "author": { "time": "2018-02-05T23:46:46+08:00", "id": 1, "name": "robot", "email": "robot@gitee.com", "username": "robot", "user_name": "robot", "url": "https://gitee.com/robot" }, "committer": { "id": 1, "name": "robot", "email": "robot@gitee.com", "username": "robot", "user_name": "robot", "url": "https://gitee.com/robot" }, "added": null, "removed": null, "modified": [ "README.md" ] }, "total_commits_count": 1, "commits_more_than_ten": false, "repository": { "id": 120249025, "name": "Gitee", "path": "gitee", "full_name": "OSCHINA/Gitee", "owner": { "login": "robot", "avatar_url": "https://gitee.com/assets/favicon.ico", "html_url": "https://gitee.com/robot", "type": "User", "site_admin": false, "id": 1, "name": "robot", "email": "robot@gitee.com", "username": "robot", "user_name": "robot", "url": "https://gitee.com/robot" }, "private": false, "html_url": "https://gitee.com/oschina/gitee", "url": "https://gitee.com/oschina/gitee", "description": "", "fork": false, "created_at": "2018-02-05T23:46:46+08:00", "updated_at": "2018-02-05T23:46:46+08:00", "pushed_at": "2018-02-05T23:46:46+08:00", "git_url": "git://gitee.com:oschina/gitee.git", "ssh_url": "git@gitee.com:oschina/gitee.git", "clone_url": "https://gitee.com/oschina/gitee.git", "svn_url": "svn://gitee.com/oschina/gitee", "git_http_url": "https://gitee.com/oschina/gitee.git", "git_ssh_url": "git@gitee.com:oschina/gitee.git", "git_svn_url": "svn://gitee.com/oschina/gitee", "homepage": null, "stargazers_count": 11, "watchers_count": 12, "forks_count": 0, "language": "ruby", "has_issues": true, "has_wiki": true, "has_pages": false, "license": null, "open_issues_count": 0, "default_branch": "master", "namespace": "oschina", "name_with_namespace": "OSCHINA/Gitee", "path_with_namespace": "oschina/gitee" }, "project": { "id": 120249025, "name": "Gitee", "path": "gitee", "full_name": "OSCHINA/Gitee", "owner": { "login": "robot", "avatar_url": "https://gitee.com/assets/favicon.ico", "html_url": "https://gitee.com/robot", "type": "User", "site_admin": false, "id": 1, "name": "robot", "email": "robot@gitee.com", "username": "robot", "user_name": "robot", "url": "https://gitee.com/robot" }, "private": false, "html_url": "https://gitee.com/oschina/gitee", "url": "https://gitee.com/oschina/gitee", "description": "", "fork": false, "created_at": "2018-02-05T23:46:46+08:00", "updated_at": "2018-02-05T23:46:46+08:00", "pushed_at": "2018-02-05T23:46:46+08:00", "git_url": "git://gitee.com:oschina/gitee.git", "ssh_url": "git@gitee.com:oschina/gitee.git", "clone_url": "https://gitee.com/oschina/gitee.git", "svn_url": "svn://gitee.com/oschina/gitee", "git_http_url": "https://gitee.com/oschina/gitee.git", "git_ssh_url": "git@gitee.com:oschina/gitee.git", "git_svn_url": "svn://gitee.com/oschina/gitee", "homepage": null, "stargazers_count": 11, "watchers_count": 12, "forks_count": 0, "language": "ruby", "has_issues": true, "has_wiki": true, "has_pages": false, "license": null, "open_issues_count": 0, "default_branch": "master", "namespace": "oschina", "name_with_namespace": "OSCHINA/Gitee", "path_with_namespace": "oschina/gitee" }, "user_id": 1, "user_name": "robot", "user": { "id": 1, "name": "robot", "email": "robot@gitee.com", "username": "robot", "user_name": "robot", "url": "https://gitee.com/robot" }, "pusher": { "id": 1, "name": "robot", "email": "robot@gitee.com", "username": "robot", "user_name": "robot", "url": "https://gitee.com/robot" }, "sender": { "login": "robot", "avatar_url": "https://gitee.com/assets/favicon.ico", "html_url": "https://gitee.com/robot", "type": "User", "site_admin": false, "id": 1, "name": "robot", "email": "robot@gitee.com", "username": "robot", "user_name": "robot", "url": "https://gitee.com/robot" }, "enterprise": null, "hook_name": "push_hooks", "hook_id": 6, "hook_url": "https://code-intranet.cmft.com/CMHK-GRD-PAAS-PORTAL/hello-world/hooks/6/edit", "password": "PAAS_2021", "timestamp": "1631245853338", "sign": "" }
如果选择“签名密钥”的方式,在发送一次webhook请求中,密钥会签名加密,并不会直接传输明文密钥,更加安全,所以更推荐用 ”签名密钥“ 的方式设置webhook。签名加密后的内容是放在请求头字段X-Gitee-Token和请求体字段sign中。
“签名密钥“类型的webhook请求例子如下:
WebHook密钥:PAAS_2021
一次webhook触发的请求内容:
Headers:
Request URL: http://paas-st1.uat.cmft.com/api/paas-pipeline/webhook/v1/pippipeline/gitHook/authorized_pipeline_prefix?userInfo=eyJwcm9qZW Request Method: POST Content-Type: application/json User-Agent: git-oschina-hook X-Gitee-Token: rQwosP4mGUJOFxDEiiiREti43gOcgja2ebzSXEg5bQU= X-Gitee-Timestamp: 1631173535197 X-Gitee-Ping: true X-Gitee-Event: Push Hook X-Git-Oschina-Event: Push HookPayload :
{ "ref": "refs/heads/master", "before": "5221c062df39e9e477ab015df22890b7bf13fbbd", "after": "1cdcd819599cbb4099289dbbec762452f006cb40", "created": false, "deleted": false, "compare": "https://gitee.com/oschina/gitee/compare/5221c062df39e9e477ab015df22890b7bf13fbbd...1cdcd819599cbb4099289dbbec762452f006cb40", "commits": [ { "id": "1cdcd819599cbb4099289dbbec762452f006cb40", "tree_id": "db78f3594ec0683f5d857ef731df0d860f14f2b2", "parent_ids": [ "a3bddf21a35af54348aae5b0f5627e6ba35be51c" ], "distinct": true, "message": "Update README.md", "timestamp": "2018-02-05T23:46:46+08:00", "url": "https://gitee.com/oschina/gitee/commit/1cdcd819599cbb4099289dbbec762452f006cb40", "author": { "time": "2018-02-05T23:46:46+08:00", "id": 1, "name": "robot", "email": "robot@gitee.com", "username": "robot", "user_name": "robot", "url": "https://gitee.com/robot" }, "committer": { "id": 1, "name": "robot", "email": "robot@gitee.com", "username": "robot", "user_name": "robot", "url": "https://gitee.com/robot" }, "added": null, "removed": null, "modified": [ "README.md" ] } ], "head_commit": { "id": "1cdcd819599cbb4099289dbbec762452f006cb40", "tree_id": "db78f3594ec0683f5d857ef731df0d860f14f2b2", "parent_ids": [ "a3bddf21a35af54348aae5b0f5627e6ba35be51c" ], "distinct": true, "message": "Update README.md", "timestamp": "2018-02-05T23:46:46+08:00", "url": "https://gitee.com/oschina/gitee/commit/1cdcd819599cbb4099289dbbec762452f006cb40", "author": { "time": "2018-02-05T23:46:46+08:00", "id": 1, "name": "robot", "email": "robot@gitee.com", "username": "robot", "user_name": "robot", "url": "https://gitee.com/robot" }, "committer": { "id": 1, "name": "robot", "email": "robot@gitee.com", "username": "robot", "user_name": "robot", "url": "https://gitee.com/robot" }, "added": null, "removed": null, "modified": [ "README.md" ] }, "total_commits_count": 1, "commits_more_than_ten": false, "repository": { "id": 120249025, "name": "Gitee", "path": "gitee", "full_name": "OSCHINA/Gitee", "owner": { "login": "robot", "avatar_url": "https://gitee.com/assets/favicon.ico", "html_url": "https://gitee.com/robot", "type": "User", "site_admin": false, "id": 1, "name": "robot", "email": "robot@gitee.com", "username": "robot", "user_name": "robot", "url": "https://gitee.com/robot" }, "private": false, "html_url": "https://gitee.com/oschina/gitee", "url": "https://gitee.com/oschina/gitee", "description": "", "fork": false, "created_at": "2018-02-05T23:46:46+08:00", "updated_at": "2018-02-05T23:46:46+08:00", "pushed_at": "2018-02-05T23:46:46+08:00", "git_url": "git://gitee.com:oschina/gitee.git", "ssh_url": "git@gitee.com:oschina/gitee.git", "clone_url": "https://gitee.com/oschina/gitee.git", "svn_url": "svn://gitee.com/oschina/gitee", "git_http_url": "https://gitee.com/oschina/gitee.git", "git_ssh_url": "git@gitee.com:oschina/gitee.git", "git_svn_url": "svn://gitee.com/oschina/gitee", "homepage": null, "stargazers_count": 11, "watchers_count": 12, "forks_count": 0, "language": "ruby", "has_issues": true, "has_wiki": true, "has_pages": false, "license": null, "open_issues_count": 0, "default_branch": "master", "namespace": "oschina", "name_with_namespace": "OSCHINA/Gitee", "path_with_namespace": "oschina/gitee" }, "project": { "id": 120249025, "name": "Gitee", "path": "gitee", "full_name": "OSCHINA/Gitee", "owner": { "login": "robot", "avatar_url": "https://gitee.com/assets/favicon.ico", "html_url": "https://gitee.com/robot", "type": "User", "site_admin": false, "id": 1, "name": "robot", "email": "robot@gitee.com", "username": "robot", "user_name": "robot", "url": "https://gitee.com/robot" }, "private": false, "html_url": "https://gitee.com/oschina/gitee", "url": "https://gitee.com/oschina/gitee", "description": "", "fork": false, "created_at": "2018-02-05T23:46:46+08:00", "updated_at": "2018-02-05T23:46:46+08:00", "pushed_at": "2018-02-05T23:46:46+08:00", "git_url": "git://gitee.com:oschina/gitee.git", "ssh_url": "git@gitee.com:oschina/gitee.git", "clone_url": "https://gitee.com/oschina/gitee.git", "svn_url": "svn://gitee.com/oschina/gitee", "git_http_url": "https://gitee.com/oschina/gitee.git", "git_ssh_url": "git@gitee.com:oschina/gitee.git", "git_svn_url": "svn://gitee.com/oschina/gitee", "homepage": null, "stargazers_count": 11, "watchers_count": 12, "forks_count": 0, "language": "ruby", "has_issues": true, "has_wiki": true, "has_pages": false, "license": null, "open_issues_count": 0, "default_branch": "master", "namespace": "oschina", "name_with_namespace": "OSCHINA/Gitee", "path_with_namespace": "oschina/gitee" }, "user_id": 1, "user_name": "robot", "user": { "id": 1, "name": "robot", "email": "robot@gitee.com", "username": "robot", "user_name": "robot", "url": "https://gitee.com/robot" }, "pusher": { "id": 1, "name": "robot", "email": "robot@gitee.com", "username": "robot", "user_name": "robot", "url": "https://gitee.com/robot" }, "sender": { "login": "robot", "avatar_url": "https://gitee.com/assets/favicon.ico", "html_url": "https://gitee.com/robot", "type": "User", "site_admin": false, "id": 1, "name": "robot", "email": "robot@gitee.com", "username": "robot", "user_name": "robot", "url": "https://gitee.com/robot" }, "enterprise": null, "hook_name": "push_hooks", "hook_id": 55, "hook_url": "https://code-c-st1.uat.cmft.com/zml-zuhu-myGoodBaby-zml/jacoco-test-code/hooks/55/edit", "password": "", "timestamp": "1631173535197", "sign": "rQwosP4mGUJOFxDEiiiREti43gOcgja2ebzSXEg5bQU=", "userInfo": "eyJwcm9qZW" }WebHook 签名生成算法详情可通过 https://gitee.com/help/articles/4290#article-header0 了解。
钩子: 用户在 开发云代码托管 上可触发的 WebHook,支持添加多个钩子。
钩子类型
目前, 开发云代码托管 支持以下钩子:
- Push: 仓库推送代码、推送 / 删除分支;
- Tag Push: 新建 / 删除 tag;
- Pull Request: 新建、更新pr代码、合并 Pull Request;
- 评论: 评论仓库、任务、Pull Request、Commit。




























