CCS项目持续集成

​ 因工作需要,用户提出希望可以做ccs项目的持续集成,及代码提交后能够自动编译并提交到svn。调研过jenkins之后发现重新手写更有性价比,所以肝了几晚终于搞出来了,现在分享出来。

​ 先交代背景:

	1.	代码分两部分,一部分在git上,一部分在svn上2.	希望git上提交的代码时和svn上提交代码时都触发持续集成。

​ 实现功能:

  1. git上提交代码时自动触发持续集成

  2. svn上提交代码时,并在备注中以“编译”开头时触发持续集成

  3. 持续集成功能:

    a. 将git上的代码复制到 svn的 编译目录(记为 X)中

    b. 将svn的源码目录(记为S)复制到svn的编译目录X的子目录(X1)中

    c. 执行ccs的编译命令,编译ccs项目,

    d. 将编译出的结果文件分别复制到 svn的多个目录中,

    e. 将编译结果文件提交到svn,备注日志中包括git上的版本信息、svn源码目录(S)的版本信息。

实现说明:

  1. 使用springboot 搭建一个web项目,并提供一个接口用户触发持续集成,记为接口X

  2. 在git配置webhook,在代码检入时调用接口X (下面的配置需要使用管理员的账号)

    在这里插入图片描述

  3. 在svn中编写钩子函数,在备注信息以”编译“开头时,调用接口x

    # 构造函数代码片段,此代码在svn的仓库目录下的hooks目中,文件名称为 post-commit  对的,没有后缀
    COMMENT=$(svnlook log -r $REV $REPOS)if echo "$COMMENT" | grep -qE '^编译'; thenecho "提交日志以'编译'开头。"  >> ${SVN_LOG_FILE_PATH}curl -X post -v http://xxxx/cicd/xxx #这个就是接口x的地址了
    
  4. 接口X的具体逻辑如下:

    整体逻辑是:

    a. 将git 和svn上的代码更新到本地

    b. 将文件复制到指定目录中

    c. 执行编译命令: 编译命令使用的是ccs的编译命令

    d. 判断编译是否成功,成功的话则将编译结果复制到指定目录中

    e. 获取源码目录的最新版本号及备注信息,并拼接成备注信息,将结果文件提交到svn上。

    先将其关键代码展示:

    // 操作git,使用的是org.eclipse.jgit  5.13.3.202401111512-r
    /*** 克隆仓库** @throws Exception*/public void cloneRep(boolean force) throws Exception {File targetDirectory = new File(getLocalPath());boolean exists = targetDirectory.exists();if (exists && force) {FileUtil.del(targetDirectory);} else if (exists) {return;}Git.cloneRepository().setURI(getRepUrl()).setBranch(getBranch()).setDirectory(targetDirectory).setCredentialsProvider(new UsernamePasswordCredentialsProvider(getUsername(), getPassword())).call();}/** 获取仓库版本 */public String getRepVersion(){File localFile = new File(getLocalPath());boolean exists = localFile.exists();if (!exists) {return "";}try (Git git = Git.open(localFile)) {final Iterable<RevCommit> revCommits = git.log().setMaxCount(1).call();final RevCommit revCommit = revCommits.iterator().next();final String commitDate = DateUtil.format(revCommit.getAuthorIdent().getWhen(), "yyyy-MM-dd HH:mm:ss");final String commitName = revCommit.getAuthorIdent().getName();return String.format("%s(%s)", commitName,commitDate);} catch (Exception e) {log.error(e.getMessage(), e);}return "";}/** 更新仓库 */public void updateRep(boolean force) throws Exception {File localFile = new File(getLocalPath());boolean exists = localFile.exists();if (!exists) {cloneRep(force);return;}try (Git git = Git.open(localFile)) {if (force) {// 撤销所有未提交的本地修改git.reset().setMode(ResetCommand.ResetType.HARD).call();// 删除未跟踪的文件和目录git.clean().setCleanDirectories(true) // 递归清理子目录.call();}// 设置凭据CredentialsProvider cp = new UsernamePasswordCredentialsProvider(getUsername(), getPassword());git.fetch().setCredentialsProvider(cp).call();git.pull().setRebase(true) // 默认情况下合并(merge),这里改为变基(rebase).setCredentialsProvider(cp).call();} catch (RepositoryNotFoundException e) {// 未找到仓库cloneRep(true);}}
    
// 操作 svn
static {DAVRepositoryFactory.setup();SVNRepositoryFactoryImpl.setup();FSRepositoryFactory.setup();}public void updateRep() throws Exception {updateRep(true);}public void updateRep(boolean force) throws Exception {log.info("updateRep");BasicAuthenticationManager authManager = new BasicAuthenticationManager(getUsername(), getPassword());SVNRepository repository = SVNRepositoryFactory.create(SVNURL.parseURIEncoded(getRepUrl()));repository.setAuthenticationManager(authManager);File targetFile = new File(getLocalPath(), "\\");if (force && targetFile.exists()) {// 撤销本地修改SVNWCClient wcClient = SVNClientManager.newInstance(null, authManager).getWCClient();wcClient.doRevert(new File[]{targetFile}, SVNDepth.INFINITY, null);}// 检出SVNUpdateClient updateClient = SVNClientManager.newInstance(null, authManager).getUpdateClient();updateClient.doCheckout(repository.getLocation(), targetFile, SVNRevision.HEAD, SVNRevision.HEAD, SVNDepth.INFINITY, false);}public void commit(List<File> delFileList) throws Exception {commit("", delFileList);}public void commit(String commitMsg, List<File> delFileList) throws Exception {if (!isNeedCommit()) {log.info("不需要提交,直接跳过!");return;}BasicAuthenticationManager authManager = new BasicAuthenticationManager(getUsername(), getPassword());SVNRepository repository = SVNRepositoryFactory.create(SVNURL.parseURIEncoded(getRepUrl()));repository.setAuthenticationManager(authManager);SVNCommitClient client = SVNClientManager.newInstance(null, authManager).getCommitClient();File[] pathsToCommit = {new File(getLocalPath())};List<SVNURL> delSvnUrlList = new ArrayList<>();if (delFileList != null && !delFileList.isEmpty()) {for (File file : delFileList) {SVNURL svnUrl = getSvnUrl(file);if (isURLExist(svnUrl)) {delSvnUrlList.add(svnUrl);} else {file.delete();}}}if (!delSvnUrlList.isEmpty()) {SVNURL[] array = delSvnUrlList.toArray(new SVNURL[0]);// 先把老的旧文件删除掉。client.doDelete(array, StrUtil.isBlank(commitMsg) ? getCommitMsg() : commitMsg);}// 添加新增加的文件SVNClientManager.newInstance(null, authManager).getWCClient().doAdd(pathsToCommit, true, true, true, SVNDepth.INFINITY, true, false, true);SVNCommitInfo commitInfo = client.doCommit(pathsToCommit, false,StrUtil.isBlank(commitMsg) ? getCommitMsg() : commitMsg, false, true);log.info("Committed revision: {}", commitInfo.getNewRevision());}private boolean isURLExist(SVNURL url) {try {BasicAuthenticationManager authManager = new BasicAuthenticationManager(getUsername(), getPassword());SVNRepository svnRepository = SVNRepositoryFactory.create(url);svnRepository.setAuthenticationManager(authManager);SVNNodeKind nodeKind = svnRepository.checkPath("", -1);return nodeKind == SVNNodeKind.NONE ? false : true;} catch (SVNException e) {log.error("isURLExist error", e);}return false;}private SVNURL getSvnUrl(File file) throws SVNException {String svnUrl = StrUtil.replace(file.getAbsolutePath(), getRepLocalBasePath(), getRepUrl());svnUrl = svnUrl.replace("\\", "/");log.info("getSvnUrl: {}", svnUrl);return SVNURL.parseURIEncoded(svnUrl);}/**
获取svn指定子目录的最后提交版本。
*/public long getRepVersion() {try {log.info("getRepVersion");BasicAuthenticationManager authManager = new BasicAuthenticationManager(getUsername(), getPassword());SVNRepository repository = SVNRepositoryFactory.create(SVNURL.parseURIEncoded(getRepUrl()));log.info("getRepVersion repository.getLocation():{}", repository.getLocation().toString());repository.setAuthenticationManager(authManager);long version = repository.getLatestRevision();log.info("getRepVersion version:{}", version);File versionFile = new File(getRepLocalBasePath() + getSvnVersionPath());SVNStatus status = SVNClientManager.newInstance(null, authManager).getStatusClient().doStatus(versionFile, false);if (status != null) {version = status.getCommittedRevision().getNumber();}return version;} catch (Exception e) {log.error("getRepVersion error", e);}return -1;}/**
获取svn指定版本的日志信息.
*/public String getLogInfo(long revision) {try {BasicAuthenticationManager authManager = new BasicAuthenticationManager(getUsername(), getPassword());SVNRepository repository = SVNRepositoryFactory.create(SVNURL.parseURIEncoded(getRepUrl()));log.info("getRepVersion repository.getLocation():{}", repository.getLocation().toString());repository.setAuthenticationManager(authManager);log.info("getRepVersion version:{}", revision);File versionFile = new File(getRepLocalBasePath() + getSvnVersionPath());StringBuffer logInfoBuf = new StringBuffer();ISVNLogEntryHandler handler = logEntry -> {String logInfo = String.format("%s %s",DateUtil.format(logEntry.getDate(), "yyyyMMddHH:mm:ss"),logEntry.getMessage());logInfoBuf.append(logInfo);log.info("logInfo {}: {}", logEntry.getRevision(), logInfo);};SVNLogClient logClient = new SVNLogClient(authManager, null);logClient.doLog(new File[]{versionFile},SVNRevision.create(revision), SVNRevision.create(revision),true, true,1, handler);return logInfoBuf.toString();} catch (Exception e) {log.error("getLogInfo error", e);}return "";}
# ccs编译命令
@echo off
set ccs_home=E:\programe\ccs124
set workspace=yyyy
set proj_home=xxxxset eclipsec="%ccs_home%\ccs\eclipse\eclipsec"
set proj_name=zzzrem rmdir /S /Q "%proj_home%"\Release
rem TortoiseProc.exe /command:remove /y /path:"%proj_home%\Release\"rmdir /S /Q "%workspace%"mkdir "%workspace%"rem 导入项目"%eclipsec%" -noSplash -data "%workspace%" -application com.ti.ccstudio.apps.projectImport -ccs.location "%proj_home%" -ccs.renameTo "%proj_name%"  >> ./logs/gmakeLog_%date:~0,4%%date:~5,2%%date:~8,2%.logrem 清空项目.
"%eclipsec%" -noSplash -data "%workspace%" -application com.ti.ccstudio.apps.projectBuild -ccs.projects "%proj_name%" -ccs.clean >> ./logs/gmakeLog_%date:~0,4%%date:~5,2%%date:~8,2%.logrem 编译.
"%eclipsec%" -noSplash -data "%workspace%" -application com.ti.ccstudio.apps.projectBuild -ccs.projects "%proj_name%" -ccs.configuration Release >> ./logs/gmakeLog_%date:~0,4%%date:~5,2%%date:~8,2%.log

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2980810.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

DeepFaceLab小白教程:视频换脸过程

合适那些人阅读&#xff1f; 适合从未使用过DeepFaceLab的群体。 如果你想基于DeepFaceLab完成一次视频换脸的操作&#xff0c;可以看本篇。 下载方式 GitHub https://github.com/iperov/DeepFaceLab 我是用motrix下载。 网盘 https://pan.baidu.com/share/init?surlO4…

Conda安装包失败

Collecting package metadata: done Solving environment: / *** picosat: out of memory in resize Aborte python - Conda Install command failing - Stack Overflow conda update -n base conda

iOS - 多线程-GCD-队列组

文章目录 iOS - 多线程-GCD-队列组1. 队列组1.1 基本使用步骤 iOS - 多线程-GCD-队列组 开发过程中&#xff0c;有时候想实现这样的效果 多个任务并发执行所有任务执行完成后&#xff0c;进行下一步处理&#xff08;比如回到主线程刷新UI&#xff09; 1. 队列组 可以使用GC…

微服务项目实战-黑马头条(八):App端-文章ES搜索、MongoDB搜索记录和关键词联想

文章目录 一、今日内容介绍1.1 App端搜索-效果图1.2 今日内容 二、搭建ElasticSearch环境2.1 拉取镜像2.2 创建容器2.3 配置中文分词器 ik2.4 使用postman测试 三、app端文章搜索3.1 需求分析3.2 思路分析3.3 创建索引和映射3.4 数据初始化到索引库3.4.1 导入es-init到heima-le…

微信小程序实时日志使用,setFilterMsg用法

实时日志 背景 为帮助小程序开发者快捷地排查小程序漏洞、定位问题&#xff0c;我们推出了实时日志功能。开发者可通过提供的接口打印日志&#xff0c;日志汇聚并实时上报到小程序后台。开发者可从We分析“性能质量->实时日志->小程序日志”进入小程序端日志查询页面&am…

Day 20 Linux的WEB服务——apache

WEB服务简介 目前主流的web服务器软件 Linux&#xff1a;apache &#xff0c; nginx Windows-server&#xff1a;IIS 服务器安装nginx或apache后&#xff0c;叫做web服务器&#xff08;又称WWW服务器&#xff09; web服务器软件属于C/S框架模型 web服务器是一种被动程序只…

Barnes-Hut t-SNE:大规模数据的高效降维算法

在数据科学和分析中&#xff0c;理解高维数据集中的底层模式是至关重要的。t-SNE已成为高维数据可视化的有力工具。它通过将数据投射到一个较低维度的空间&#xff0c;提供了对数据结构的详细洞察。但是随着数据集的增长&#xff0c;标准的t-SNE算法在计算有些困难&#xff0c;…

编译器的学习

常用的编译器&#xff1a; GCCVisual CClang&#xff08;LLVM&#xff09;&#xff1a; Clang 可以被看作是建立在 LLVM 之上的一个项目, 实际上LLVM是clang的后端&#xff0c;clang作为前端前端生成LLVM IR&#xff0c;https://zhuanlan.zhihu.com/p/656699711MSVC &#xff…

【js】解决自动生成颜色时相邻颜色视觉相似问题的技术方案

解决自动生成颜色时相邻颜色视觉相似问题的技术方案 在进行大规模颜色生成时&#xff0c;特别是在数据可视化、用户界面设计等应用领域&#xff0c;一个常见的挑战是确保相邻颜色在视觉上具有足够的区分度。本文介绍的方法通过结合黄金分割比与饱和度、亮度的周期性变化&#…

C++中的list类模拟实现

目录 list类模拟实现 list类节点结构设计 list类非const迭代器结构设计 迭代器基本结构设计 迭代器构造函数 operator()函数 operator*()函数 operator!()函数 operator(int)函数 operator--()函数 operator--(int)函数 operator()函数 operator->()函数 list…

VMware 15 安装centos7虚拟机

1. 安装前准备 1.1 下载centos 阿里巴巴开源镜像站-OPSX镜像站-阿里云开发者社区 下载需要版本的centos版本 直达链接 centos7.9 &#xff1a; centos-7.9.2009-isos-x86_64安装包下载_开源镜像站-阿里云 .基础使用的话安装选择这个就行了&#xff0c;大概下载几分钟 2. …

蓝桥杯2024年第十五届省赛真题-小球反弹

以下两个解法感觉都靠谱&#xff0c;并且网上的题解每个人答案都不一样&#xff0c;目前无法判断哪个是正确答案。 方法一&#xff1a;模拟 代码参考博客 #include <iostream> #include <cmath> #include <vector>using namespace std;int main() {const i…

绿城中国北森商业综合推理40分钟28题管理人才盘点领导选拔总经理竞聘考什么?

复杂信息理解批判性评估 策略性推理概念性推理 40分钟题库实时时更新 晋升通过率>95% 绿城人寿移动航油等国企 各维度说明 ①复杂信息理解:洞察文字、图表等资料的能力&#xff0c;能否快速抓住复杂信息中的要点、提取出关键信息 ②批判性评估:批判性质疑的能力&#xff0…

springcloud Ribbon的详解

1、Ribbon是什么 Ribbon是Netflix发布的开源项目&#xff0c;Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的框架。 2、Ribbon能干什么 LB负载均衡(Load Balance)是什么&#xff1f;简单的说就是将用户的请求平摊的分配到多个服务上&#xff0c;从而达…

Python程序设计教案

文章目录&#xff1a; 一&#xff1a;软件环境安装 1.软件环境 2.技巧 3.新建工程项目 二&#xff1a;相关 1.规范 2.关键字 3.Ascll码表 三&#xff1a;语法基础 1.各种符号 1.1 注释 1.2 占位置的 1.3 回车换行 2.输入输出 2.1 输入input 2.2 输出print …

parallels desktop19.3最新版本软件新功能详细介绍

Parallels Desktop是一款运行在Mac电脑上的虚拟机软件&#xff0c;它允许用户在Mac系统上同时运行多个操作系统&#xff0c;比如Windows、Linux等。通过这款软件&#xff0c;Mac用户可以轻松地在同一台电脑上体验不同操作系统的功能和应用程序&#xff0c;而无需额外的硬件设备…

CDN、边缘计算与云计算:构建现代网络的核心技术

在数字化时代&#xff0c;数据的快速传输和处理是保持竞争力的关键。内容分发网络&#xff08;CDN&#xff09;、边缘计算和云计算共同构成了现代互联网基础架构的核心&#xff0c;使内容快速、安全地到达用户手中。本文将探讨这三种技术的功能、相互关系以及未来的发展趋势。 …

3节点ubuntu24.04服务器docker-compose方式部署高可用elk+kafka日志系统并接入nginx日志

一&#xff1a;系统版本: 二&#xff1a;部署环境&#xff1a; 节点名称 IP 部署组件及版本 配置文件路径 机器CPU 机器内存 机器存储 Log-001 10.10.100.1 zookeeper:3.4.13 kafka:2.8.1 elasticsearch:7.7.0 logstash:7.7.0 kibana:7.7.0 zookeeper:/data/zookeep…

探索未来的区块链DApp应用,畅享数字世界的无限可能

随着区块链技术的飞速发展&#xff0c;分布式应用&#xff08;DApp&#xff09;正成为数字经济中的一股强劲力量。DApp以其去中心化、透明公正的特点&#xff0c;为用户带来了全新的数字体验&#xff0c;开创了数字经济的新潮流。作为一家专业的区块链DApp应用开发公司&#xf…

全面了解俄罗斯的VK开户和Yandex投放及内容运营

俄罗斯的VKontakte&#xff08;简称VK&#xff09;和Yandex是两个重要的在线平台&#xff0c;对于希望在俄罗斯市场进行推广的企业来说&#xff0c;了解如何在这些平台上开户和投放广告以及内容运营是非常关键的。 俄罗斯vk广告如何开户&#xff1f; 通过上海上弦进行俄罗斯V…