Skip to content

Commit a244678

Browse files
committed
EAS Build Hooks
1 parent 74979ac commit a244678

7 files changed

Lines changed: 976 additions & 1 deletion

File tree

packages/core/package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,10 @@
4545
"lint:prettier": "prettier --config ../../.prettierrc.json --ignore-path ../../.prettierignore --check \"{src,test,scripts,plugin/src}/**/**.ts\""
4646
},
4747
"bin": {
48-
"sentry-expo-upload-sourcemaps": "scripts/expo-upload-sourcemaps.js"
48+
"sentry-expo-upload-sourcemaps": "scripts/expo-upload-sourcemaps.js",
49+
"sentry-eas-build-on-error": "scripts/eas-build-on-error.js",
50+
"sentry-eas-build-on-success": "scripts/eas-build-on-success.js",
51+
"sentry-eas-build-on-complete": "scripts/eas-build-on-complete.js"
4952
},
5053
"keywords": [
5154
"react-native",
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
#!/usr/bin/env node
2+
/**
3+
* EAS Build Hook: on-complete
4+
*
5+
* This script captures EAS build completion events and reports them to Sentry.
6+
* It uses the EAS_BUILD_STATUS environment variable to determine whether
7+
* the build succeeded or failed.
8+
*
9+
* Add it to your package.json scripts:
10+
*
11+
* "eas-build-on-complete": "sentry-eas-build-on-complete"
12+
*
13+
* Required environment variables:
14+
* - SENTRY_DSN: Your Sentry DSN
15+
*
16+
* Optional environment variables:
17+
* - SENTRY_EAS_BUILD_CAPTURE_SUCCESS: Set to 'true' to also capture successful builds
18+
* - SENTRY_EAS_BUILD_TAGS: JSON string of additional tags
19+
* - SENTRY_EAS_BUILD_ERROR_MESSAGE: Custom error message for failed builds
20+
* - SENTRY_EAS_BUILD_SUCCESS_MESSAGE: Custom success message for successful builds
21+
*
22+
* EAS Build provides:
23+
* - EAS_BUILD_STATUS: 'finished' or 'errored'
24+
*
25+
* @see https://docs.expo.dev/build-reference/npm-hooks/
26+
* @see https://docs.sentry.io/platforms/react-native/
27+
*/
28+
29+
const path = require('path');
30+
const fs = require('fs');
31+
32+
// Try to load environment variables
33+
function loadEnv() {
34+
// Try @expo/env first
35+
try {
36+
require('@expo/env').load('.');
37+
} catch (_e) {
38+
// Fallback to dotenv if available
39+
try {
40+
const dotenvPath = path.join(process.cwd(), '.env');
41+
if (fs.existsSync(dotenvPath)) {
42+
const dotenvFile = fs.readFileSync(dotenvPath, 'utf-8');
43+
const dotenv = require('dotenv');
44+
Object.assign(process.env, dotenv.parse(dotenvFile));
45+
}
46+
} catch (_e2) {
47+
// No dotenv available, continue with existing env vars
48+
}
49+
}
50+
51+
// Also load .env.sentry-build-plugin if it exists
52+
try {
53+
const sentryEnvPath = path.join(process.cwd(), '.env.sentry-build-plugin');
54+
if (fs.existsSync(sentryEnvPath)) {
55+
const dotenvFile = fs.readFileSync(sentryEnvPath, 'utf-8');
56+
const dotenv = require('dotenv');
57+
Object.assign(process.env, dotenv.parse(dotenvFile));
58+
}
59+
} catch (_e) {
60+
// Continue without .env.sentry-build-plugin
61+
}
62+
}
63+
64+
async function main() {
65+
loadEnv();
66+
67+
// Dynamically import the hooks module (it's compiled to dist/)
68+
let captureEASBuildComplete;
69+
try {
70+
// Try the compiled output first
71+
const hooks = require('../dist/js/tools/easBuildHooks.js');
72+
captureEASBuildComplete = hooks.captureEASBuildComplete;
73+
} catch (_e) {
74+
console.error('[Sentry] Could not load EAS build hooks module. Make sure @sentry/react-native is properly installed.');
75+
process.exit(1);
76+
}
77+
78+
// Parse options from environment variables
79+
const options = {
80+
dsn: process.env.SENTRY_DSN,
81+
errorMessage: process.env.SENTRY_EAS_BUILD_ERROR_MESSAGE,
82+
successMessage: process.env.SENTRY_EAS_BUILD_SUCCESS_MESSAGE,
83+
captureSuccessfulBuilds: process.env.SENTRY_EAS_BUILD_CAPTURE_SUCCESS === 'true',
84+
};
85+
86+
// Parse additional tags if provided
87+
if (process.env.SENTRY_EAS_BUILD_TAGS) {
88+
try {
89+
options.tags = JSON.parse(process.env.SENTRY_EAS_BUILD_TAGS);
90+
} catch (_e) {
91+
console.warn('[Sentry] Could not parse SENTRY_EAS_BUILD_TAGS as JSON. Ignoring.');
92+
}
93+
}
94+
95+
try {
96+
await captureEASBuildComplete(options);
97+
console.log('[Sentry] EAS build complete hook finished.');
98+
} catch (error) {
99+
console.error('[Sentry] Error in eas-build-on-complete hook:', error);
100+
// Don't fail the build hook itself
101+
}
102+
}
103+
104+
main();
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
#!/usr/bin/env node
2+
/**
3+
* EAS Build Hook: on-error
4+
*
5+
* This script captures EAS build failures and reports them to Sentry.
6+
* Add it to your package.json scripts:
7+
*
8+
* "eas-build-on-error": "sentry-eas-build-on-error"
9+
*
10+
* Required environment variables:
11+
* - SENTRY_DSN: Your Sentry DSN
12+
*
13+
* Optional environment variables:
14+
* - SENTRY_EAS_BUILD_TAGS: JSON string of additional tags
15+
* - SENTRY_EAS_BUILD_ERROR_MESSAGE: Custom error message
16+
*
17+
* @see https://docs.expo.dev/build-reference/npm-hooks/
18+
* @see https://docs.sentry.io/platforms/react-native/
19+
*/
20+
21+
const path = require('path');
22+
const fs = require('fs');
23+
24+
// Try to load environment variables
25+
function loadEnv() {
26+
// Try @expo/env first
27+
try {
28+
require('@expo/env').load('.');
29+
} catch (_e) {
30+
// Fallback to dotenv if available
31+
try {
32+
const dotenvPath = path.join(process.cwd(), '.env');
33+
if (fs.existsSync(dotenvPath)) {
34+
const dotenvFile = fs.readFileSync(dotenvPath, 'utf-8');
35+
const dotenv = require('dotenv');
36+
Object.assign(process.env, dotenv.parse(dotenvFile));
37+
}
38+
} catch (_e2) {
39+
// No dotenv available, continue with existing env vars
40+
}
41+
}
42+
43+
// Also load .env.sentry-build-plugin if it exists
44+
try {
45+
const sentryEnvPath = path.join(process.cwd(), '.env.sentry-build-plugin');
46+
if (fs.existsSync(sentryEnvPath)) {
47+
const dotenvFile = fs.readFileSync(sentryEnvPath, 'utf-8');
48+
const dotenv = require('dotenv');
49+
Object.assign(process.env, dotenv.parse(dotenvFile));
50+
}
51+
} catch (_e) {
52+
// Continue without .env.sentry-build-plugin
53+
}
54+
}
55+
56+
async function main() {
57+
loadEnv();
58+
59+
// Dynamically import the hooks module (it's compiled to dist/)
60+
let captureEASBuildError;
61+
try {
62+
// Try the compiled output first
63+
const hooks = require('../dist/js/tools/easBuildHooks.js');
64+
captureEASBuildError = hooks.captureEASBuildError;
65+
} catch (_e) {
66+
console.error('[Sentry] Could not load EAS build hooks module. Make sure @sentry/react-native is properly installed.');
67+
process.exit(1);
68+
}
69+
70+
// Parse options from environment variables
71+
const options = {
72+
dsn: process.env.SENTRY_DSN,
73+
errorMessage: process.env.SENTRY_EAS_BUILD_ERROR_MESSAGE,
74+
};
75+
76+
// Parse additional tags if provided
77+
if (process.env.SENTRY_EAS_BUILD_TAGS) {
78+
try {
79+
options.tags = JSON.parse(process.env.SENTRY_EAS_BUILD_TAGS);
80+
} catch (_e) {
81+
console.warn('[Sentry] Could not parse SENTRY_EAS_BUILD_TAGS as JSON. Ignoring.');
82+
}
83+
}
84+
85+
try {
86+
await captureEASBuildError(options);
87+
console.log('[Sentry] EAS build error hook completed.');
88+
} catch (error) {
89+
console.error('[Sentry] Error in eas-build-on-error hook:', error);
90+
// Don't fail the build hook itself
91+
}
92+
}
93+
94+
main();
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
#!/usr/bin/env node
2+
/**
3+
* EAS Build Hook: on-success
4+
*
5+
* This script captures EAS build successes and reports them to Sentry.
6+
* Add it to your package.json scripts:
7+
*
8+
* "eas-build-on-success": "sentry-eas-build-on-success"
9+
*
10+
* Required environment variables:
11+
* - SENTRY_DSN: Your Sentry DSN
12+
* - SENTRY_EAS_BUILD_CAPTURE_SUCCESS: Set to 'true' to capture successful builds
13+
*
14+
* Optional environment variables:
15+
* - SENTRY_EAS_BUILD_TAGS: JSON string of additional tags
16+
* - SENTRY_EAS_BUILD_SUCCESS_MESSAGE: Custom success message
17+
*
18+
* @see https://docs.expo.dev/build-reference/npm-hooks/
19+
* @see https://docs.sentry.io/platforms/react-native/
20+
*/
21+
22+
const path = require('path');
23+
const fs = require('fs');
24+
25+
// Try to load environment variables
26+
function loadEnv() {
27+
// Try @expo/env first
28+
try {
29+
require('@expo/env').load('.');
30+
} catch (_e) {
31+
// Fallback to dotenv if available
32+
try {
33+
const dotenvPath = path.join(process.cwd(), '.env');
34+
if (fs.existsSync(dotenvPath)) {
35+
const dotenvFile = fs.readFileSync(dotenvPath, 'utf-8');
36+
const dotenv = require('dotenv');
37+
Object.assign(process.env, dotenv.parse(dotenvFile));
38+
}
39+
} catch (_e2) {
40+
// No dotenv available, continue with existing env vars
41+
}
42+
}
43+
44+
// Also load .env.sentry-build-plugin if it exists
45+
try {
46+
const sentryEnvPath = path.join(process.cwd(), '.env.sentry-build-plugin');
47+
if (fs.existsSync(sentryEnvPath)) {
48+
const dotenvFile = fs.readFileSync(sentryEnvPath, 'utf-8');
49+
const dotenv = require('dotenv');
50+
Object.assign(process.env, dotenv.parse(dotenvFile));
51+
}
52+
} catch (_e) {
53+
// Continue without .env.sentry-build-plugin
54+
}
55+
}
56+
57+
async function main() {
58+
loadEnv();
59+
60+
// Dynamically import the hooks module (it's compiled to dist/)
61+
let captureEASBuildSuccess;
62+
try {
63+
// Try the compiled output first
64+
const hooks = require('../dist/js/tools/easBuildHooks.js');
65+
captureEASBuildSuccess = hooks.captureEASBuildSuccess;
66+
} catch (_e) {
67+
console.error('[Sentry] Could not load EAS build hooks module. Make sure @sentry/react-native is properly installed.');
68+
process.exit(1);
69+
}
70+
71+
// Parse options from environment variables
72+
const options = {
73+
dsn: process.env.SENTRY_DSN,
74+
successMessage: process.env.SENTRY_EAS_BUILD_SUCCESS_MESSAGE,
75+
captureSuccessfulBuilds: process.env.SENTRY_EAS_BUILD_CAPTURE_SUCCESS === 'true',
76+
};
77+
78+
// Parse additional tags if provided
79+
if (process.env.SENTRY_EAS_BUILD_TAGS) {
80+
try {
81+
options.tags = JSON.parse(process.env.SENTRY_EAS_BUILD_TAGS);
82+
} catch (_e) {
83+
console.warn('[Sentry] Could not parse SENTRY_EAS_BUILD_TAGS as JSON. Ignoring.');
84+
}
85+
}
86+
87+
try {
88+
await captureEASBuildSuccess(options);
89+
console.log('[Sentry] EAS build success hook completed.');
90+
} catch (error) {
91+
console.error('[Sentry] Error in eas-build-on-success hook:', error);
92+
// Don't fail the build hook itself
93+
}
94+
}
95+
96+
main();

0 commit comments

Comments
 (0)