build(deps): Bump com.cedarsoftware:java-util from 3.5.0 to 3.6.0 #305
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Check Aliyun Maven Dependencies | |
on: | |
pull_request_target: | |
types: [ opened, synchronize, reopened ] | |
workflow_dispatch: | |
permissions: | |
contents: read | |
pull-requests: write | |
jobs: | |
check-dependencies: | |
# 只在dependabot的PR上运行 | |
runs-on: ubuntu-latest | |
steps: | |
- name: Check if PR is from dependabot | |
id: check-author | |
run: | | |
if [[ "${{ github.event.pull_request.user.login }}" == *"dependabot"* ]]; then | |
echo "is_dependabot=true" >> $GITHUB_OUTPUT | |
else | |
echo "is_dependabot=false" >> $GITHUB_OUTPUT | |
fi | |
- name: Skip non-dependabot PRs with success | |
if: steps.check-author.outputs.is_dependabot == 'false' | |
run: exit 0 | |
- name: Checkout code | |
if: steps.check-author.outputs.is_dependabot == 'true' | |
uses: actions/checkout@v4 | |
with: | |
ref: ${{ github.event.pull_request.head.ref }} | |
- name: Set up Java | |
if: steps.check-author.outputs.is_dependabot == 'true' | |
uses: actions/setup-java@v4 | |
with: | |
distribution: 'temurin' | |
java-version: '17' | |
- name: Set up Node.js | |
if: steps.check-author.outputs.is_dependabot == 'true' | |
uses: actions/setup-node@v4 | |
with: | |
node-version: '20' | |
- name: Install dependencies | |
if: steps.check-author.outputs.is_dependabot == 'true' | |
run: | | |
npm install xml2js | |
npm install @actions/github | |
- name: Get build file changes | |
if: steps.check-author.outputs.is_dependabot == 'true' | |
id: get-changes | |
run: | | |
# 检测项目类型并获取变更内容 | |
if [ -f "pom.xml" ]; then | |
echo "build_type=maven" >> $GITHUB_OUTPUT | |
# PR事件获取当前PR的pom.xml变更 | |
git diff origin/${{ github.event.pull_request.base.ref }} -- pom.xml > changes.diff || true | |
elif [ -f "build.gradle" ]; then | |
echo "build_type=gradle" >> $GITHUB_OUTPUT | |
git diff origin/${{ github.event.pull_request.base.ref }} -- build.gradle > changes.diff || true | |
else | |
echo "No supported build file found" | |
exit 0 | |
fi | |
echo "changes<<EOF" >> $GITHUB_OUTPUT | |
cat changes.diff >> $GITHUB_OUTPUT | |
echo "EOF" >> $GITHUB_OUTPUT | |
- name: Parse dependencies | |
if: steps.check-author.outputs.is_dependabot == 'true' | |
id: parse-deps | |
uses: actions/github-script@v7 | |
with: | |
script: | | |
const fs = require('fs'); | |
const xml2js = require('xml2js'); | |
try { | |
const buildType = '${{ steps.get-changes.outputs.build_type }}'; | |
const changes = '${{ steps.get-changes.outputs.changes }}'; | |
const dependencies = []; | |
if (buildType === 'gradle') { | |
// Gradle 依赖解析 | |
const regex = /([+-])\s*(implementation|api|compile|testImplementation|runtimeOnly)\s*['"]([^'"]+)['"]/g; | |
let match; | |
while ((match = regex.exec(changes)) !== null) { | |
if (match[1] === '+') { | |
const depParts = match[3].split(':'); | |
if (depParts.length === 3) { | |
dependencies.push({ | |
group: depParts[0], | |
artifact: depParts[1], | |
version: depParts[2] | |
}); | |
} | |
} | |
} | |
} else if (buildType === 'maven') { | |
// Maven 依赖解析 | |
// 1. 读取并解析整个pom.xml | |
const pomContent = fs.readFileSync('pom.xml', 'utf-8'); | |
// 使用xml2js解析pom.xml | |
const parser = new xml2js.Parser({ explicitArray: false }); | |
const result = await parser.parseStringPromise(pomContent); | |
// 2. 分析变更 | |
const diffLines = changes.split('\n'); | |
const changedProperties = {}; | |
// 提取properties | |
const properties = result.project?.properties || {}; | |
// 找出变更的属性 | |
const propertyRegex = /^([+-])\s*<([^>]+\.version)>\s*([^<]+)\s*<\/[^>]+>$/; | |
for (const line of diffLines) { | |
const match = line.match(propertyRegex); | |
if (match && match[1] === '+') { | |
const propName = match[2]; // 获取属性名 | |
const propValue = match[3].trim(); // 获取新值 | |
changedProperties[propName] = propValue; | |
} | |
} | |
// 3. 合并变更后的属性 | |
const effectiveProperties = { ...properties, ...changedProperties }; | |
console.log("=====changedProperties====="); | |
console.log(changedProperties); | |
// 递归提取依赖的函数 | |
const extractDeps = (deps, scope) => { | |
if (!deps?.dependency) return; | |
const depList = Array.isArray(deps.dependency) ? deps.dependency : [deps.dependency]; | |
depList.forEach(dep => { | |
if (!dep.groupId || !dep.artifactId) return; | |
// 处理版本号(可能是直接值或属性引用) | |
let version = dep.version || ''; | |
let fromProperty = ''; | |
if (version.startsWith('${') && version.endsWith('}')) { | |
const propName = version.slice(2, -1); | |
version = effectiveProperties[propName] || version; | |
fromProperty = propName; | |
} | |
// 只有当属性有变更或版本直接变更时才包含 | |
if (fromProperty in changedProperties || !version.startsWith('${')) { | |
dependencies.push({ | |
group: dep.groupId, | |
artifact: dep.artifactId, | |
version: version, | |
scope: scope || dep.scope || 'compile', | |
fromProperty: fromProperty || undefined, | |
isManaged: scope === 'management' | |
}); | |
} | |
}); | |
}; | |
// 1. 提取dependencyManagement中的依赖 | |
if (result.project?.dependencyManagement?.dependencies) { | |
extractDeps(result.project.dependencyManagement.dependencies, 'management'); | |
} | |
// 2. 提取普通dependencies | |
if (result.project?.dependencies) { | |
extractDeps(result.project.dependencies); | |
} | |
} | |
core.setOutput('dependencies', JSON.stringify(dependencies)); | |
console.log("=====dependencies.length====="); | |
console.log(dependencies.length); | |
return dependencies.length; | |
} catch (error) { | |
core.setFailed(`Failed to parse dependencies: ${error}`); | |
} | |
- name: Check Aliyun Maven availability | |
if: steps.check-author.outputs.is_dependabot == 'true' && steps.parse-deps.outputs.dependencies != '[]' | |
id: check-aliyun | |
uses: actions/github-script@v7 | |
with: | |
github-token: ${{ secrets.GITHUB_TOKEN }} | |
script: | | |
const { execSync } = require('child_process'); | |
try { | |
const dependencies = JSON.parse('${{ steps.parse-deps.outputs.dependencies }}'); | |
const aliMavenUrl = 'https://maven.aliyun.com/repository/public'; | |
const results = []; | |
const errresults = []; | |
for (const dep of dependencies) { | |
if (dep.artifact.startsWith("javafxTool-")) { | |
continue; | |
} | |
const artifactPath = dep.group.replace(/\./g, '/') + '/' + dep.artifact + '/' + dep.version; | |
const pomUrl = `${aliMavenUrl}/${artifactPath}/${dep.artifact}-${dep.version}.pom`; | |
console.log(pomUrl); | |
try { | |
execSync(`curl -I -s -o /dev/null -w "%{http_code}" ${pomUrl} | grep 200`); | |
results.push(`✅ ${dep.group}:${dep.artifact}:${dep.version} - 可用`); | |
} catch (e) { | |
errresults.push(`❌ ${dep.group}:${dep.artifact}:${dep.version} - 不可用`); | |
} | |
} | |
if (results.length > 0) { | |
const { data: comments } = await github.rest.issues.listComments({ | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
issue_number: context.issue.number, | |
}); | |
// 查找我们之前发布的评论(通过特定标识) | |
const botComment = comments.find(comment => | |
comment.user.login === 'github-actions[bot]' && | |
comment.body.startsWith('### 阿里云 Maven 依赖检查结果') | |
); | |
const commentBody = `### 阿里云 Maven 依赖检查结果\n\n${errresults.join('\n')}\n\n<details><summary>点击查看可用的依赖</summary>${results.join('<br>\n')}<br></details>`; | |
if (botComment) { | |
// 更新现有评论 | |
await github.rest.issues.updateComment({ | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
comment_id: botComment.id, | |
body: commentBody | |
}); | |
} else { | |
// 创建新评论 | |
github.rest.issues.createComment({ | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
issue_number: context.issue.number, | |
body: commentBody | |
}); | |
} | |
core.setOutput('result', commentBody); | |
} | |
return 'Dependency check completed'; | |
} catch (error) { | |
core.setFailed(`Action failed with error: ${error}`); | |
} | |
- name: Output result | |
if: steps.check-author.outputs.is_dependabot == 'true' && steps.parse-deps.outputs.dependencies != '[]' | |
run: echo "${{ steps.check-aliyun.outputs.result }}" | |