Skip to content

Commit 47650f2

Browse files
authored
feat: Add self-contained binary artifacts (#806)
The added forced resolution for `simple-plist` is to fix bundling issues with this package that is solved in the latest version. Context: wollardj/simple-plist/issues#58 Fixes #758.
1 parent 2cb35de commit 47650f2

File tree

16 files changed

+660
-229
lines changed

16 files changed

+660
-229
lines changed

.github/workflows/build.yml

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ jobs:
1010
job_build:
1111
name: Build
1212
runs-on: ubuntu-latest
13+
env:
14+
APPLE_CERT_PATH: /tmp/certs.p12
15+
APPLE_API_KEY_PATH: /tmp/apple_key.json
1316
steps:
1417
- uses: actions/checkout@v4
1518
- name: Set up Node
@@ -21,14 +24,38 @@ jobs:
2124
run: yarn install --frozen-lockfile
2225
- name: Build
2326
run: yarn build
27+
- name: Setup Apple Code Signing
28+
env:
29+
APPLE_CERT_DATA: ${{ secrets.APPLE_CERT_DATA }}
30+
APPLE_API_KEY: ${{ secrets.APPLE_API_KEY }}
31+
run: |
32+
curl -L 'https://github.com/indygreg/apple-platform-rs/releases/download/apple-codesign%2F0.28.0/apple-codesign-0.28.0-x86_64-unknown-linux-musl.tar.gz' | tar -xz --strip-components=1
33+
mv rcodesign /usr/local/bin/rcodesign
34+
echo "$APPLE_CERT_DATA" | base64 --decode > ${{ env.APPLE_CERT_PATH }}
35+
echo "$APPLE_API_KEY" | base64 --decode > ${{ env.APPLE_API_KEY_PATH }}
36+
- name: Fossilize Cache
37+
uses: actions/cache@v4
38+
with:
39+
key: yarn-${{ hashFiles('yarn.lock') }}
40+
restore-keys: yarn-
41+
path: |
42+
${{ github.workspace }}/.node-cache
43+
- name: Build SEA Binaries
44+
env:
45+
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
46+
APPLE_CERT_PASSWORD: ${{ secrets.APPLE_CERT_PASSWORD }}
47+
run: yarn fossilize -n 22 --sign -p linux-x64 -p linux-arm64 -p win-x64 -p darwin-x64 -p darwin-arm64
2448
- name: Pack
2549
run: yarn pack
2650
- name: Archive Artifacts
2751
uses: actions/upload-artifact@v4
2852
with:
2953
name: ${{ github.sha }}
54+
if-no-files-found: error
55+
compression-level: 3
3056
path: |
3157
${{ github.workspace }}/*.tgz
58+
${{ github.workspace }}/dist-bin/*
3259
3360
job_lint:
3461
name: Lint
@@ -108,8 +135,12 @@ jobs:
108135
flutter pub get
109136
- name: Install dependencies with yarn
110137
run: yarn install --frozen-lockfile
138+
- name: Download built binaries from build job
139+
uses: actions/download-artifact@v4
140+
with:
141+
name: ${{ github.sha }}
111142
- name: Run End-to-End Tests
112-
run: yarn test:e2e ${{ matrix.wizard }}
143+
run: yarn test:e2e:bin ${{ matrix.wizard }}
113144
- name: Push code coverage to codecov
114145
uses: codecov/codecov-action@13ce06bfc6bbe3ecf90edbbf1bc32fe5978ca1d3 # [email protected]
115146
with:

.gitignore

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ npm-debug.log
1616
ios
1717
./android
1818
yarn-error.log
19+
.node-cache
1920

2021
scratch/
2122

@@ -26,6 +27,9 @@ scratch/
2627

2728
sentry.properties
2829
dist/
30+
dist-bin/
31+
# npm package
32+
*.tgz
2933
coverage/
3034
plugins
3135

@@ -36,4 +40,4 @@ package-lock.json
3640

3741
.env
3842

39-
.sentryclirc
43+
.sentryclirc

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
- ref: No more dynamic requires ([#801](https://github.com/getsentry/sentry-wizard/pull/801))
99
- ref: Remove @sentry/cli as a dependency ([#802](https://github.com/getsentry/sentry-wizard/pull/802))
1010
- fix: Fix broken legacy wizard ([#811](https://github.com/getsentry/sentry-wizard/pull/811))
11+
- feat: Add self-contained binary artifacts ([#806](https://github.com/getsentry/sentry-wizard/pull/806))
1112
- fix: Add fallback from parsing project package path candidates ([#814](https://github.com/getsentry/sentry-wizard/pull/814))
1213
- fix: Refactor the wizard version lookup to handle gracefully ([#816](https://github.com/getsentry/sentry-wizard/pull/816))
1314

bin.ts

Lines changed: 84 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -52,85 +52,90 @@ const PRESELECTED_PROJECT_OPTIONS = {
5252
};
5353

5454
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
55-
const argv = yargs(hideBin(process.argv)).options({
56-
debug: {
57-
default: false,
58-
describe: 'Enable verbose logging\nenv: SENTRY_WIZARD_DEBUG',
59-
type: 'boolean',
60-
},
61-
uninstall: {
62-
default: false,
63-
describe: 'Revert project setup process\nenv: SENTRY_WIZARD_UNINSTALL',
64-
type: 'boolean',
65-
},
66-
'skip-connect': {
67-
default: false,
68-
describe:
69-
'Skips the connection to the server\nenv: SENTRY_WIZARD_SKIP_CONNECT',
70-
type: 'boolean',
71-
},
72-
quiet: {
73-
default: false,
74-
describe:
75-
'Do not fallback to prompting user asking questions\nenv: SENTRY_WIZARD_QUIET',
76-
type: 'boolean',
77-
},
78-
i: {
79-
alias: 'integration',
80-
choices: Object.keys(Integration),
81-
describe: 'Choose the integration to setup\nenv: SENTRY_WIZARD_INTEGRATION',
82-
},
83-
p: {
84-
alias: 'platform',
85-
choices: Object.keys(Platform),
86-
describe: 'Choose platform(s)\nenv: SENTRY_WIZARD_PLATFORM',
87-
type: 'array',
88-
},
89-
u: {
90-
alias: 'url',
91-
describe: 'The url to your Sentry installation\nenv: SENTRY_WIZARD_URL',
92-
},
93-
project: {
94-
type: 'string',
95-
describe: 'The Sentry project slug to use',
96-
defaultDescription: 'Select project during setup',
97-
default: undefined,
98-
},
99-
org: {
100-
type: 'string',
101-
describe: 'The Sentry org slug to use',
102-
defaultDescription: 'Select org during setup',
103-
default: undefined,
104-
},
105-
saas: {
106-
default: false,
107-
describe: 'Skip the self-hosted or SaaS URL selection process',
108-
defaultDescription: 'Select self-hosted or SaaS during setup',
109-
type: 'boolean',
110-
},
111-
s: {
112-
alias: 'signup',
113-
default: false,
114-
describe: 'Redirect to signup page if not logged in',
115-
type: 'boolean',
116-
},
117-
'disable-telemetry': {
118-
default: false,
119-
describe: "Don't send telemetry data to Sentry",
120-
type: 'boolean',
121-
},
122-
'promo-code': {
123-
alias: 'promo-code',
124-
describe: 'A promo code that will be applied during signup',
125-
type: 'string',
126-
},
127-
'force-install': {
128-
default: false,
129-
describe: 'Force install the SDK NPM package',
130-
type: 'boolean',
131-
},
132-
...PRESELECTED_PROJECT_OPTIONS,
133-
}).argv;
55+
const argv = yargs(hideBin(process.argv), process.cwd())
56+
.options({
57+
debug: {
58+
default: false,
59+
describe: 'Enable verbose logging\nenv: SENTRY_WIZARD_DEBUG',
60+
type: 'boolean',
61+
},
62+
uninstall: {
63+
default: false,
64+
describe: 'Revert project setup process\nenv: SENTRY_WIZARD_UNINSTALL',
65+
type: 'boolean',
66+
},
67+
'skip-connect': {
68+
default: false,
69+
describe:
70+
'Skips the connection to the server\nenv: SENTRY_WIZARD_SKIP_CONNECT',
71+
type: 'boolean',
72+
},
73+
quiet: {
74+
default: false,
75+
describe:
76+
'Do not fallback to prompting user asking questions\nenv: SENTRY_WIZARD_QUIET',
77+
type: 'boolean',
78+
},
79+
i: {
80+
alias: 'integration',
81+
choices: Object.keys(Integration),
82+
describe:
83+
'Choose the integration to setup\nenv: SENTRY_WIZARD_INTEGRATION',
84+
},
85+
p: {
86+
alias: 'platform',
87+
choices: Object.keys(Platform),
88+
describe: 'Choose platform(s)\nenv: SENTRY_WIZARD_PLATFORM',
89+
type: 'array',
90+
},
91+
u: {
92+
alias: 'url',
93+
describe: 'The url to your Sentry installation\nenv: SENTRY_WIZARD_URL',
94+
},
95+
project: {
96+
type: 'string',
97+
describe: 'The Sentry project slug to use',
98+
defaultDescription: 'Select project during setup',
99+
default: undefined,
100+
},
101+
org: {
102+
type: 'string',
103+
describe: 'The Sentry org slug to use',
104+
defaultDescription: 'Select org during setup',
105+
default: undefined,
106+
},
107+
saas: {
108+
default: false,
109+
describe: 'Skip the self-hosted or SaaS URL selection process',
110+
defaultDescription: 'Select self-hosted or SaaS during setup',
111+
type: 'boolean',
112+
},
113+
s: {
114+
alias: 'signup',
115+
default: false,
116+
describe: 'Redirect to signup page if not logged in',
117+
type: 'boolean',
118+
},
119+
'disable-telemetry': {
120+
default: false,
121+
describe: "Don't send telemetry data to Sentry",
122+
type: 'boolean',
123+
},
124+
'promo-code': {
125+
alias: 'promo-code',
126+
describe: 'A promo code that will be applied during signup',
127+
type: 'string',
128+
},
129+
'force-install': {
130+
default: false,
131+
describe: 'Force install the SDK NPM package',
132+
type: 'boolean',
133+
},
134+
...PRESELECTED_PROJECT_OPTIONS,
135+
})
136+
// This prevents `yargs` from trying to read the local package.json
137+
// as it's not available in the Node Single Executable Binary artifacts versions
138+
.version(process.env.npm_package_version as string).argv;
134139

135140
// @ts-expect-error - for some reason TS doesn't recognize the aliases as valid properties
136141
// meaning it only knows e.g. u but not url. Maybe a bug in this old version of yargs?

e2e-tests/tests/flutter.test.ts

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
1+
import * as fs from 'node:fs';
2+
import * as path from 'node:path';
13
/* eslint-disable jest/expect-expect */
24
import { Integration } from '../../lib/Constants';
35
import {
6+
KEYS,
47
// checkEnvBuildPlugin,
58
cleanupGit,
6-
KEYS,
79
revertLocalChanges,
810
} from '../utils';
911
import { startWizardInstance } from '../utils';
1012
import {
1113
checkFileContents,
14+
checkIfFlutterBuilds,
1215
// checkFileExists,
1316
checkSentryProperties,
14-
checkIfFlutterBuilds,
1517
} from '../utils';
16-
import * as path from 'path';
17-
import * as fs from 'fs';
1818

1919
describe('Flutter', () => {
2020
const integration = Integration.flutter;
@@ -26,67 +26,67 @@ describe('Flutter', () => {
2626
describe('with apple platforms', () => {
2727
beforeAll(async () => {
2828
const wizardInstance = startWizardInstance(integration, projectDir);
29-
29+
3030
const tracingOptionPrompted = await wizardInstance.waitForOutput(
3131
// "Do you want to enable Tracing", sometimes doesn't work as `Tracing` can be printed in bold.
3232
'to track the performance of your application?',
3333
);
34-
34+
3535
const profilingOptionPrompted = tracingOptionPrompted &&
3636
(await wizardInstance.sendStdinAndWaitForOutput(
3737
[KEYS.ENTER],
3838
// "Do you want to enable Profiling", sometimes doesn't work as `Profiling` can be printed in bold.
3939
'to analyze CPU usage and optimize performance-critical code on iOS & macOS?',
4040
));
41-
41+
4242
profilingOptionPrompted &&
4343
(await wizardInstance.sendStdinAndWaitForOutput(
4444
[KEYS.ENTER],
4545
'Successfully installed the Sentry Flutter SDK!',
4646
));
47-
47+
4848
wizardInstance.kill();
4949
});
50-
50+
5151
afterAll(() => {
5252
revertLocalChanges(projectDir);
5353
cleanupGit(projectDir);
5454
});
55-
55+
5656
test('pubspec.yaml is updated.', () => {
5757
checkFileContents(`${projectDir}/pubspec.yaml`, `sentry_flutter:`); // dependencies
5858
checkFileContents(`${projectDir}/pubspec.yaml`, `sentry_dart_plugin:`); // dev_dependencies
5959
checkFileContents(`${projectDir}/pubspec.yaml`, `sentry:`); // gradle plugin options
6060
});
61-
61+
6262
test('sentry.properties exists and has auth token', () => {
6363
checkSentryProperties(projectDir);
6464
});
65-
65+
6666
test('.gitignore has sentry.properties', () => {
6767
checkFileContents(`${projectDir}/.gitignore`, `sentry.properties`);
6868
});
69-
69+
7070
test('lib/main.dart calls sentry init', () => {
7171
checkFileContents(`${projectDir}/lib/main.dart`, `import 'package:sentry_flutter/sentry_flutter.dart';`);
7272
checkFileContents(`${projectDir}/lib/main.dart`, `await SentryFlutter.init(`);
7373
});
74-
74+
7575
test('lib/main.dart enables tracing and profiling', () => {
7676
checkFileContents(`${projectDir}/lib/main.dart`, `options.tracesSampleRate = 1.0;`);
7777
checkFileContents(`${projectDir}/lib/main.dart`, `options.profilesSampleRate = 1.0;`);
7878
});
79-
79+
8080
test('builds correctly', async () => {
8181
await checkIfFlutterBuilds(projectDir, '✓ Built build/web');
8282
});
8383
});
8484

8585
describe('without apple platforms', () => {
8686
beforeAll(async () => {
87-
87+
8888
const wizardInstance = startWizardInstance(integration, projectDir);
89-
89+
9090
if (fs.existsSync(`${projectDir}/ios`)) {
9191
fs.renameSync(`${projectDir}/ios`, `${projectDir}/_ios`);
9292
}
@@ -104,16 +104,16 @@ describe('Flutter', () => {
104104
// "Do you want to enable Tracing", sometimes doesn't work as `Tracing` can be printed in bold.
105105
'to track the performance of your application?',
106106
));
107-
107+
108108
tracingOptionPrompted &&
109109
(await wizardInstance.sendStdinAndWaitForOutput(
110110
[KEYS.ENTER],
111111
'Successfully installed the Sentry Flutter SDK!',
112112
));
113-
113+
114114
wizardInstance.kill();
115115
});
116-
116+
117117
afterAll(() => {
118118
revertLocalChanges(projectDir);
119119
cleanupGit(projectDir);

0 commit comments

Comments
 (0)