Skip to content

Commit ed1082f

Browse files
add android sdk version check
Co-authored-by: Claude <noreply@anthropic.com>
1 parent bef3709 commit ed1082f

2 files changed

Lines changed: 143 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: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
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+
/* Ignored for testing.
48+
if (!gradlePluginFileChanged && !buildGradleFileChanged) {
49+
console.log('Neither gradle plugin config nor build.gradle changed, skipping check.');
50+
return;
51+
}
52+
*/
53+
54+
console.log('Running Android SDK version mismatch check...');
55+
56+
// Read gradle plugin version from withSentryAndroidGradlePlugin.ts
57+
const gradlePluginFilePath = path.join(process.cwd(), GRADLE_PLUGIN_FILE);
58+
if (!fs.existsSync(gradlePluginFilePath)) {
59+
console.log(`File not found: ${GRADLE_PLUGIN_FILE}`);
60+
return;
61+
}
62+
63+
const gradlePluginFileContent = fs.readFileSync(gradlePluginFilePath, 'utf8');
64+
const gradlePluginVersionMatch = gradlePluginFileContent.match(
65+
/export\s+const\s+sentryAndroidGradlePluginVersion\s*=\s*['"]([^'"]+)['"]/,
66+
);
67+
68+
if (!gradlePluginVersionMatch) {
69+
warn(
70+
createSectionWarning(
71+
'Android SDK Version Check',
72+
'⚠️ Could not parse `sentryAndroidGradlePluginVersion` from withSentryAndroidGradlePlugin.ts',
73+
'⚠️',
74+
),
75+
);
76+
return;
77+
}
78+
79+
const gradlePluginVersion = gradlePluginVersionMatch[1];
80+
console.log(`Gradle plugin version: ${gradlePluginVersion}`);
81+
82+
// Read sentry-android version from build.gradle
83+
const buildGradlePath = path.join(process.cwd(), BUILD_GRADLE_FILE);
84+
if (!fs.existsSync(buildGradlePath)) {
85+
console.log(`File not found: ${BUILD_GRADLE_FILE}`);
86+
return;
87+
}
88+
89+
const buildGradleContent = fs.readFileSync(buildGradlePath, 'utf8');
90+
const sentryAndroidVersionMatch = buildGradleContent.match(/api\s+['"]io\.sentry:sentry-android:([^'"]+)['"]/);
91+
92+
if (!sentryAndroidVersionMatch) {
93+
warn(
94+
createSectionWarning(
95+
'Android SDK Version Check',
96+
'⚠️ Could not parse `sentry-android` version from build.gradle',
97+
'⚠️',
98+
),
99+
);
100+
return;
101+
}
102+
103+
const sdkVersion = sentryAndroidVersionMatch[1];
104+
console.log(`sentry-android version in build.gradle: ${sdkVersion}`);
105+
106+
// Fetch the version bundled by the gradle plugin
107+
let bundledVersion;
108+
try {
109+
bundledVersion = await fetchBundledSentryAndroidVersion(gradlePluginVersion);
110+
console.log(`sentry-android version bundled by gradle plugin ${gradlePluginVersion}: ${bundledVersion}`);
111+
} catch (e) {
112+
warn(
113+
createSectionWarning(
114+
'Android SDK Version Check',
115+
`⚠️ Could not determine sentry-android version bundled by gradle plugin ${gradlePluginVersion}:\n\n${e.message}`,
116+
'⚠️',
117+
),
118+
);
119+
return;
120+
}
121+
122+
// Compare versions
123+
if (sdkVersion !== bundledVersion) {
124+
fail(
125+
createSectionWarning(
126+
'Android SDK Version Mismatch',
127+
`❌ **Version mismatch detected!**\n\n` +
128+
`| Component | Version |\n` +
129+
`|-----------|--------|\n` +
130+
`| \`sentry-android\` in build.gradle | **${sdkVersion}** |\n` +
131+
`| \`sentry-android\` bundled by gradle plugin ${gradlePluginVersion} | **${bundledVersion}** |\n\n` +
132+
`This mismatch will cause crashes on Android with error:\n` +
133+
`> \`IllegalStateException: Sentry SDK has detected a mix of versions\`\n\n` +
134+
`**Fix:** Update \`packages/core/android/build.gradle\` to use version \`${bundledVersion}\` ` +
135+
`or wait for a gradle plugin release that bundles \`${sdkVersion}\`.`,
136+
'❌',
137+
),
138+
);
139+
} else {
140+
console.log('✅ sentry-android versions match');
141+
}
142+
};

0 commit comments

Comments
 (0)