> 技术文档 > Jenkins构建间代码变更记录追踪方案

Jenkins构建间代码变更记录追踪方案


Jenkins构建间代码变更记录追踪方案

概述

本方案基于现有代码逻辑,实现每次Jenkins构建时自动追踪和展示代码变更记录的功能。通过记录每次构建的commit哈希,对比当前和上次构建之间的差异,生成变更历史报告

核心逻辑

1. Commit记录追踪机制

系统使用[config_manager](file://D:\\project\\SuuntoTest\\jenkins\\config_manager.py#L0-L0)模块来持久化存储每次构建的commit哈希:

# 保存当前commit到记录文件def save_current_commit(repo_path): original_cwd = os.getcwd() os.chdir(repo_path) try: cmd = [\'git\', \'rev-parse\', \'HEAD\'] result = subprocess.run(cmd, capture_output=True, text=True, check=True) current_commit = result.stdout.strip() config_manager.update_result_json(\"last_commit\", current_commit) except subprocess.CalledProcessError as e: print(f\"保存当前commit时出错: {e}\") finally: os.chdir(original_cwd)

2. 构建间差异检测

通过比较当前commit和上次构建commit,获取变更内容:

def get_jenkins_build_commits(repo_path): original_cwd = os.getcwd() os.chdir(repo_path) try: # 获取当前HEAD的commit cmd = [\'git\', \'rev-parse\', \'HEAD\'] result = subprocess.run(cmd, capture_output=True, text=True, check=True) current_commit = result.stdout.strip() # 检查是否存在记录文件(上一次构建的commit) last_build_commit = config_manager.load_result_json().get(\'last_commit\', \'\') if last_build_commit: # 如果commit相同,则没有新的变更 if last_build_commit == current_commit: return [] # 获取变更的文件 changed_files = get_changed_files_between_commits(repo_path, last_build_commit, current_commit) # 根据变更的文件获取相关的commit commits = get_commits_for_files(repo_path, changed_files, last_build_commit, current_commit) return commits # ... 其他逻辑

3. 文件级别变更追踪

系统不仅追踪commit级别的变更,还能精确到文件级别的变更:

def get_changed_files_between_commits(repo_path, old_commit, new_commit): original_cwd = os.getcwd() os.chdir(repo_path) try: # 获取从旧commit到新commit的文件变更 cmd = [\'git\', \'diff\', \'--name-only\', f\'{old_commit}..{new_commit}\'] result = subprocess.run(cmd, capture_output=True, text=True, check=True) changed_files = result.stdout.strip().split(\'\\n\') changed_files = [f for f in changed_files if f] return changed_files except subprocess.CalledProcessError as e: print(f\"获取变更文件时出错: {e}\") return [] finally: os.chdir(original_cwd)

工作流程

1. 初始化阶段

  • 系统首次运行时,由于没有历史记录,会获取所有commit记录
  • 将当前commit哈希保存到[result.json](file://D:\\project\\SuuntoTest\\jenkins\\result.json)文件中

2. 后续构建阶段

  • 读取上一次构建保存的commit哈希
  • 获取当前commit哈希
  • 比较两次commit之间的差异
  • 获取变更的文件列表
  • 根据变更的文件获取相关的commit记录
  • 生成HTML报告展示变更历史
  • 更新[result.json](file://D:\\project\\SuuntoTest\\jenkins\\result.json)中的commit哈希为当前值

3. 报告生成

  • 生成包含变更commit信息的HTML报告
  • 报告中包含作者、日期、commit消息等信息
  • 提供到GitHub commit页面的链接

Jenkins归档配置

为了确保生成的HTML报告能够在Jenkins中正确显示和访问,需要在Jenkinsfile或构建配置中添加归档步骤:

post { always { // 归档commit历史报告 archiveArtifacts artifacts: \'commit_history.html\', fingerprint: true // 也可以归档其他相关文件 archiveArtifacts artifacts: \'jenkins/result.json\', fingerprint: true }}

或者在Pipeline中使用archiveArtifacts步骤:

stage(\'Archive commit history\') { steps { script { // 确保报告文件存在 if (fileExists(\'commit_history.html\')) { archiveArtifacts artifacts: \'commit_history.html\', fingerprint: true } } }}

HTML报告显示优化

针对Jenkins中的内容安全策略(CSP)限制,HTML报告中已添加了适当的meta标签:

<meta http-equiv=\"Content-Security-Policy\" content=\"default-src * \'unsafe-inline\' \'unsafe-eval\'; script-src * \'unsafe-inline\' \'unsafe-eval\'; connect-src * \'unsafe-inline\'; img-src * data: blob: \'unsafe-inline\'; frame-src *; style-src * \'unsafe-inline\';\">

这确保了报告在Jenkins环境中能够正确显示样式和格式。

关键特性

1. 精确的变更追踪

  • 基于文件级别的变更检测,而非整个仓库的commit历史
  • 只显示与变更文件相关的commit记录

2. 自动化的记录管理

  • 自动保存和读取构建历史信息
  • 无需手动维护commit记录

3. 智能去重机制

  • 对获取到的commit记录进行去重处理
  • 按时间倒序排列,最新的变更显示在最前面

4. 完善的错误处理

  • 包含完整的异常处理机制
  • 即使某个步骤出错也不会影响整体流程

使用方法

在Jenkins构建流程中执行以下命令:

python jenkins/git_commit_report.py . commit_history.html

这将:

  1. 分析当前构建与上次构建之间的代码变更
  2. 生成包含变更记录的HTML报告
  3. 更新commit记录以供下次构建使用

然后确保在Jenkins配置中添加归档步骤以保存和展示报告:

archiveArtifacts artifacts: \'commit_history.html\', fingerprint: true

优势

  1. 精准追踪:只显示与实际变更相关的commit记录
  2. 自动化管理:无需手动维护历史记录
  3. 易于集成:可轻松集成到现有Jenkins构建流程中
  4. 可视化展示:生成易于阅读的HTML报告
  5. 可追溯性:提供到GitHub commit页面的直接链接
  6. Jenkins友好:生成的报告能正确在Jenkins中显示和归档