build(deps): Bump org.checkerframework:checker-qual from 3.49.2 to 3.49.3 #18
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上运行 | |
if: contains(github.event.pull_request.user.login, 'dependabot') | |
runs-on: ubuntu-latest | |
steps: | |
- name: Checkout code | |
uses: actions/checkout@v4 | |
with: | |
ref: ${{ github.event.pull_request.head.ref }} | |
- name: Set up Java | |
uses: actions/setup-java@v4 | |
with: | |
distribution: 'temurin' | |
java-version: '17' | |
- name: Set up Node.js | |
uses: actions/setup-node@v4 | |
with: | |
node-version: '20' | |
- name: Install xml2js | |
run: npm install xml2js | |
- name: Get build file changes | |
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 | |
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); | |
// 提取properties | |
const properties = result.project?.properties || {}; | |
// 递归提取依赖的函数 | |
const allDependencies = []; | |
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 = properties[propName] || version; | |
fromProperty = propName; | |
} | |
allDependencies.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); | |
} | |
console.log("=====allDependencies====="); | |
console.log(allDependencies); | |
// 2. 分析变更 | |
const diffLines = changes.split('\n'); | |
const changedProperties = {}; | |
// 找出变更的属性 | |
const propertyRegex = /([+-])\s*<([^>]+)>\s*([^<]+)<\/[^>]+>/; | |
for (const line of diffLines) { | |
const propMatch = line.match(propertyRegex); | |
if (propMatch && propMatch[1] === '+') { | |
const propName = propMatch[2]; | |
const propValue = propMatch[3].trim(); | |
changedProperties[propName] = propValue; | |
} | |
} | |
console.log("=====changedProperties====="); | |
console.log(changedProperties); | |
// 3. 关联属性变更与依赖 | |
for (const dep of allDependencies) { | |
if (dep.version && dep.version.startsWith('${') && dep.version.endsWith('}')) { | |
const propName = dep.version.slice(2, -1); | |
if (changedProperties[propName]) { | |
dependencies.push({ | |
group: dep.groupId, | |
artifact: dep.artifactId, | |
version: changedProperties[propName], | |
fromProperty: propName | |
}); | |
} | |
} | |
} | |
// 4. 也检查直接的依赖变更 | |
let currentDep = null; | |
let inDependency = false; | |
let isNewDep = false; | |
for (const line of diffLines) { | |
if (line.startsWith('+ <dependency>')) { | |
inDependency = true; | |
isNewDep = true; | |
currentDep = {}; | |
} else if (line.startsWith('+ </dependency>') && isNewDep) { | |
inDependency = false; | |
if (currentDep.groupId && currentDep.artifactId && currentDep.version) { | |
dependencies.push({ | |
group: currentDep.groupId, | |
artifact: currentDep.artifactId, | |
version: currentDep.version | |
}); | |
} | |
} else if (inDependency && isNewDep) { | |
if (line.startsWith('+ <groupId>')) { | |
currentDep.groupId = line.replace(/^\+ <groupId>|<\/groupId>$/g, '').trim(); | |
} else if (line.startsWith('+ <artifactId>')) { | |
currentDep.artifactId = line.replace(/^\+ <artifactId>|<\/artifactId>$/g, '').trim(); | |
} else if (line.startsWith('+ <version>')) { | |
currentDep.version = line.replace(/^\+ <version>|<\/version>$/g, '').trim(); | |
} | |
} | |
} | |
} | |
core.setOutput('dependencies', JSON.stringify(dependencies)); | |
console.log("=====dependencies====="); | |
console.log(dependencies); | |
return dependencies.length; | |
} catch (error) { | |
core.setFailed(`Failed to parse dependencies: ${error}`); | |
} | |
- name: Check Aliyun Maven availability | |
if: steps.parse-deps.outputs.dependencies != '[]' | |
id: check-aliyun | |
uses: actions/github-script@v7 | |
with: | |
script: | | |
const { execSync } = require('child_process'); | |
const { context, getOctokit } = require('@actions/github'); | |
try { | |
const dependencies = JSON.parse('${{ steps.parse-deps.outputs.dependencies }}'); | |
const aliMavenUrl = 'https://maven.aliyun.com/repository/public'; | |
const results = []; | |
for (const dep of dependencies) { | |
const artifactPath = dep.group.replace(/\./g, '/') + '/' + dep.artifact + '/' + dep.version; | |
const pomUrl = `${aliMavenUrl}/${artifactPath}/${dep.artifact}-${dep.version}.pom`; | |
try { | |
execSync(`curl -I -s -o /dev/null -w "%{http_code}" ${pomUrl} | grep 200`); | |
results.push(`✅ ${dep.group}:${dep.artifact}:${dep.version} - 可用`); | |
} catch (e) { | |
results.push(`❌ ${dep.group}:${dep.artifact}:${dep.version} - 不可用`); | |
} | |
} | |
if (results.length > 0) { | |
const commentBody = `### 阿里云 Maven 依赖检查结果\n\n${results.join('\n')}`; | |
const octokit = getOctokit(process.env.GITHUB_TOKEN); | |
await octokit.rest.issues.createComment({ | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
issue_number: ${{ github.event.pull_request.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.parse-deps.outputs.dependencies != '[]' | |
run: echo "${{ steps.check-aliyun.outputs.result }}" |