Skip to content

Commit 8ee2636

Browse files
Ref(CI): Add android sdk version check (#5686)
* add android sdk version check Co-authored-by: Claude <noreply@anthropic.com> * message cleanup * remove additional comma * add back check for file change * refresh CI: --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent bef3709 commit 8ee2636

2 files changed

Lines changed: 139 additions & 1 deletion

File tree

scripts/check-additional-danger.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ async function safeRun(fnPath, { fail, warn, message, markdown, danger }) {
77
}
88
}
99

10-
1110
module.exports = async function ({ fail, warn, message, markdown, danger }) {
1211
await safeRun('./check-github-label', { fail, warn, message, markdown, danger });
1312
await safeRun('./check-replay-stubs', { fail, warn, message, markdown, danger });
13+
await safeRun('./check-android-sdk-mismatch', { fail, warn, message, markdown, danger });
1414
};
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
const fs = require('fs');
2+
const path = require('path');
3+
const https = require('https');
4+
5+
const GRADLE_PLUGIN_FILE = 'packages/core/plugin/src/withSentryAndroidGradlePlugin.ts';
6+
const BUILD_GRADLE_FILE = 'packages/core/android/build.gradle';
7+
8+
const createSectionWarning = (title, content, icon = '❌') => {
9+
return `### ${icon} ${title}\n\n${content}\n`;
10+
};
11+
12+
/**
13+
* Fetches the SDK version from gradle.properties in the gradle plugin GitHub repo.
14+
* The file contains a line like: sdk_version = X.Y.Z
15+
*/
16+
function fetchBundledSentryAndroidVersion(gradlePluginVersion) {
17+
return new Promise((resolve, reject) => {
18+
const url = `https://raw.githubusercontent.com/getsentry/sentry-android-gradle-plugin/${gradlePluginVersion}/plugin-build/gradle.properties`;
19+
20+
https
21+
.get(url, res => {
22+
if (res.statusCode !== 200) {
23+
reject(new Error(`Could not fetch gradle.properties for version ${gradlePluginVersion}`));
24+
return;
25+
}
26+
27+
let data = '';
28+
res.on('data', chunk => (data += chunk));
29+
res.on('end', () => {
30+
// Look for: sdk_version = X.Y.Z
31+
const versionMatch = data.match(/sdk_version\s*=\s*(\S+)/);
32+
if (versionMatch) {
33+
resolve(versionMatch[1]);
34+
} else {
35+
reject(new Error(`Could not find sdk_version in gradle.properties`));
36+
}
37+
});
38+
})
39+
.on('error', reject);
40+
});
41+
}
42+
43+
module.exports = async function ({ fail, warn, __, ___, danger }) {
44+
const gradlePluginFileChanged = danger.git.modified_files.includes(GRADLE_PLUGIN_FILE);
45+
const buildGradleFileChanged = danger.git.modified_files.includes(BUILD_GRADLE_FILE);
46+
47+
if (!gradlePluginFileChanged && !buildGradleFileChanged) {
48+
console.log('Neither gradle plugin config nor build.gradle changed, skipping check.');
49+
return;
50+
}
51+
52+
console.log('Running Android SDK version mismatch check...');
53+
54+
// Read gradle plugin version from withSentryAndroidGradlePlugin.ts
55+
const gradlePluginFilePath = path.join(process.cwd(), GRADLE_PLUGIN_FILE);
56+
if (!fs.existsSync(gradlePluginFilePath)) {
57+
console.log(`File not found: ${GRADLE_PLUGIN_FILE}`);
58+
return;
59+
}
60+
61+
const gradlePluginFileContent = fs.readFileSync(gradlePluginFilePath, 'utf8');
62+
const gradlePluginVersionMatch = gradlePluginFileContent.match(
63+
/export\s+const\s+sentryAndroidGradlePluginVersion\s*=\s*['"]([^'"]+)['"]/,
64+
);
65+
66+
if (!gradlePluginVersionMatch) {
67+
warn(
68+
createSectionWarning(
69+
'Android SDK Version Check',
70+
'Could not parse `sentryAndroidGradlePluginVersion` from withSentryAndroidGradlePlugin.ts',
71+
'⚠️',
72+
),
73+
);
74+
return;
75+
}
76+
77+
const gradlePluginVersion = gradlePluginVersionMatch[1];
78+
console.log(`Gradle plugin version: ${gradlePluginVersion}`);
79+
80+
// Read sentry-android version from build.gradle
81+
const buildGradlePath = path.join(process.cwd(), BUILD_GRADLE_FILE);
82+
if (!fs.existsSync(buildGradlePath)) {
83+
console.log(`File not found: ${BUILD_GRADLE_FILE}`);
84+
return;
85+
}
86+
87+
const buildGradleContent = fs.readFileSync(buildGradlePath, 'utf8');
88+
const sentryAndroidVersionMatch = buildGradleContent.match(/api\s+['"]io\.sentry:sentry-android:([^'"]+)['"]/);
89+
90+
if (!sentryAndroidVersionMatch) {
91+
warn(
92+
createSectionWarning(
93+
'Android SDK Version Check',
94+
'Could not parse `sentry-android` version from build.gradle',
95+
'⚠️',
96+
),
97+
);
98+
return;
99+
}
100+
101+
const sdkVersion = sentryAndroidVersionMatch[1];
102+
console.log(`sentry-android version in build.gradle: ${sdkVersion}`);
103+
104+
// Fetch the version bundled by the gradle plugin
105+
let bundledVersion;
106+
try {
107+
bundledVersion = await fetchBundledSentryAndroidVersion(gradlePluginVersion);
108+
console.log(`sentry-android version bundled by gradle plugin ${gradlePluginVersion}: ${bundledVersion}`);
109+
} catch (e) {
110+
warn(
111+
createSectionWarning(
112+
'Android SDK Version Check',
113+
`⚠️ Could not determine sentry-android version bundled by gradle plugin ${gradlePluginVersion}:\n\n${e.message}`,
114+
'⚠️',
115+
),
116+
);
117+
return;
118+
}
119+
120+
// Compare versions
121+
if (sdkVersion !== bundledVersion) {
122+
fail(
123+
createSectionWarning(
124+
'Android SDK Version Mismatch',
125+
`| Component | Version |\n` +
126+
`|-----------|--------|\n` +
127+
`| \`sentry-android\` in build.gradle | **${sdkVersion}** |\n` +
128+
`| \`sentry-android\` bundled by gradle plugin ${gradlePluginVersion} | **${bundledVersion}** |\n\n` +
129+
`This mismatch will cause crashes on Android with error:\n` +
130+
`> \`IllegalStateException: Sentry SDK has detected a mix of versions\`\n\n` +
131+
`**Fix:** Update \`packages/core/android/build.gradle\` to use version \`${bundledVersion}\` ` +
132+
`or wait for a gradle plugin release that bundles \`${sdkVersion}\`.`,
133+
),
134+
);
135+
} else {
136+
console.log('✅ sentry-android versions match');
137+
}
138+
};

0 commit comments

Comments
 (0)