Skip to content

Commit

Permalink
Merge branch 'master' into tkdodo/ref/prefer-for-of
Browse files Browse the repository at this point in the history
  • Loading branch information
TkDodo authored Feb 9, 2025
2 parents 2070842 + 391f870 commit 53f5dbf
Show file tree
Hide file tree
Showing 1,383 changed files with 34,868 additions and 37,059 deletions.
25 changes: 25 additions & 0 deletions .cursor/rules/tsx_tests.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
description: Rules and guidelines for running *.spec.tsx tests and writing React tests
globs: *.spec.tsx
---

# Running *.spec.tsx tests

Please run tests with command: CI=true yarn test
For example: CI=true yarn test path/to/file.spec.tsx

NOTE: `CI=true` runs jest in non-interactive mode.

# React tests

When writing React tests and using react-test-library, please use exports from 'sentry-test/reactTestingLibrary'. It re-exports from '@testing-library/react'. For example:

```
import {
render,
screen,
userEvent,
waitFor,
within,
} from 'sentry-test/reactTestingLibrary';
```
2 changes: 2 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,8 @@ tests/sentry/api/endpoints/test_organization_dashboard_widget_details.py @ge
/src/sentry/integrations/ @getsentry/product-owners-settings-integrations @getsentry/ecosystem
/src/sentry/mail/ @getsentry/alerts-notifications
/src/sentry/notifications/ @getsentry/alerts-notifications
/src/sentry/notifications/models/ @getsentry/ecosystem
/src/sentry/notifications/notifications/ @getsentry/ecosystem
/src/sentry/pipeline/ @getsentry/ecosystem
/src/sentry/plugins/ @getsentry/ecosystem
/src/sentry/shared_integrations/ @getsentry/ecosystem
Expand Down
2 changes: 1 addition & 1 deletion .github/actions/setup-sentry/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ runs:
echo "TOTAL_TEST_GROUPS=$MATRIX_INSTANCE_TOTAL" >> $GITHUB_ENV
fi
- uses: getsentry/action-setup-venv@a133e6fd5fa6abd3f590a1c106abda344f5df69f # v2.1.0
- uses: getsentry/action-setup-venv@3a832a9604b3e1a4202ae559248f26867b467cc7 # v2.1.1
with:
python-version: ${{ inputs.python-version }}
cache-dependency-path: ${{ inputs.workdir }}/requirements-dev-frozen.txt
Expand Down
4 changes: 1 addition & 3 deletions .github/workflows/acceptance.yml
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,6 @@ jobs:

- name: webpack
env:
# this is fine to not have for forks, it shouldn't fail
SENTRY_WEBPACK_WEBHOOK_SECRET: ${{ secrets.SENTRY_WEBPACK_WEBHOOK_SECRET }}
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
# should set value either as `true` or `false`
CODECOV_ENABLE_BA: ${{ needs.files-changed.outputs.frontend_all == 'true'}}
Expand Down Expand Up @@ -131,7 +129,7 @@ jobs:
- name: Collect test data
uses: ./.github/actions/collect-test-data
if: ${{ !cancelled() && needs.files-changed.outputs.backend_all == 'true' }}
if: ${{ !cancelled() }}
with:
artifact_path: .artifacts/pytest.acceptance.json
gcs_bucket: ${{ secrets.COLLECT_TEST_DATA_GCS_BUCKET }}
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/backend.yml
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ jobs:
app_id: ${{ vars.SENTRY_INTERNAL_APP_ID }}
private_key: ${{ secrets.SENTRY_INTERNAL_APP_PRIVATE_KEY }}
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- uses: getsentry/action-setup-venv@a133e6fd5fa6abd3f590a1c106abda344f5df69f # v2.1.0
- uses: getsentry/action-setup-venv@3a832a9604b3e1a4202ae559248f26867b467cc7 # v2.1.1
with:
python-version: 3.13.1
cache-dependency-path: requirements-dev-frozen.txt
Expand Down Expand Up @@ -337,7 +337,7 @@ jobs:
steps:
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7

- uses: getsentry/action-setup-venv@a133e6fd5fa6abd3f590a1c106abda344f5df69f # v2.1.0
- uses: getsentry/action-setup-venv@3a832a9604b3e1a4202ae559248f26867b467cc7 # v2.1.1
with:
python-version: 3.13.1
cache-dependency-path: requirements-dev-frozen.txt
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/development-environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ jobs:
timeout-minutes: 5
steps:
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- uses: getsentry/action-setup-venv@a133e6fd5fa6abd3f590a1c106abda344f5df69f # v2.1.0
- uses: getsentry/action-setup-venv@3a832a9604b3e1a4202ae559248f26867b467cc7 # v2.1.1
with:
python-version: 3.13.1
cache-dependency-path: |
Expand All @@ -50,7 +50,7 @@ jobs:
timeout-minutes: 5
steps:
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- uses: getsentry/action-setup-venv@a133e6fd5fa6abd3f590a1c106abda344f5df69f # v2.1.0
- uses: getsentry/action-setup-venv@3a832a9604b3e1a4202ae559248f26867b467cc7 # v2.1.1
with:
python-version: 3.13.1
cache-dependency-path: |
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/pre-commit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ jobs:
node-version-file: '.volta.json'

- name: node_modules cache
uses: actions/[email protected]
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
id: nodemodulescache
with:
path: node_modules
Expand All @@ -69,14 +69,14 @@ jobs:
if: steps.nodemodulescache.outputs.cache-hit != 'true'
run: yarn install --frozen-lockfile

- uses: getsentry/action-setup-venv@a133e6fd5fa6abd3f590a1c106abda344f5df69f # v2.1.0
- uses: getsentry/action-setup-venv@3a832a9604b3e1a4202ae559248f26867b467cc7 # v2.1.1
with:
python-version: 3.13.1
cache-dependency-path: |
requirements-dev.txt
requirements-dev-frozen.txt
install-cmd: pip install -r requirements-dev.txt -c requirements-dev-frozen.txt
- uses: actions/[email protected]
- uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
with:
path: ~/.cache/pre-commit
key: cache-epoch-1|${{ env.pythonLocation }}|${{ hashFiles('.pre-commit-config.yaml') }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/react-to-product-owners-yml-changes.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
steps:
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7

- uses: getsentry/action-setup-venv@a133e6fd5fa6abd3f590a1c106abda344f5df69f # v2.1.0
- uses: getsentry/action-setup-venv@3a832a9604b3e1a4202ae559248f26867b467cc7 # v2.1.1
with:
python-version: 3.13.1

Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/self-hosted.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:
with:
node-version-file: '.volta.json'

- uses: getsentry/action-setup-venv@a133e6fd5fa6abd3f590a1c106abda344f5df69f # v2.1.0
- uses: getsentry/action-setup-venv@3a832a9604b3e1a4202ae559248f26867b467cc7 # v2.1.1
with:
python-version: 3.13.1
cache-dependency-path: requirements-dev-frozen.txt
Expand All @@ -42,13 +42,13 @@ jobs:
echo "WEBPACK_CACHE_PATH=.webpack_cache" >> "$GITHUB_ENV"
- name: webpack cache
uses: actions/[email protected]
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
with:
path: ${{ steps.config.outputs.webpack-path }}
key: ${{ runner.os }}-self-hosted-webpack-cache-${{ hashFiles('webpack.config.ts') }}

- name: node_modules cache
uses: actions/[email protected]
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
id: nodemodulescache
with:
path: node_modules
Expand Down
4 changes: 3 additions & 1 deletion bin/benchmark_detectors
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ configure()
import time
import sentry_sdk
from sentry.testutils.performance_issues.event_generators import get_event # noqa: S007
from sentry.utils.performance_issues.detectors import FileIOMainThreadDetector
from sentry.utils.performance_issues.detectors.io_main_thread_detector import (
FileIOMainThreadDetector,
)
from sentry.utils.performance_issues.performance_detection import (
get_detection_settings,
run_detector_on_data,
Expand Down
166 changes: 37 additions & 129 deletions build-utils/sentry-instrumentation.ts
Original file line number Diff line number Diff line change
@@ -1,149 +1,68 @@
import type {Span} from '@sentry/core';
import type * as Sentry from '@sentry/node';
import crypto from 'node:crypto';
import https from 'node:https';
import os from 'node:os';
import type webpack from 'webpack';

const {
NODE_ENV,
SENTRY_INSTRUMENTATION,
SENTRY_WEBPACK_WEBHOOK_SECRET,
GITHUB_SHA,
GITHUB_REF,
SENTRY_DEV_UI_PROFILING,
} = process.env;
const {SENTRY_INSTRUMENTATION, GITHUB_SHA, GITHUB_REF} = process.env;

const IS_CI = !!GITHUB_SHA;

const PLUGIN_NAME = 'SentryInstrumentation';
const GB_BYTE = 1073741824;

const createSignature = function (secret: string, payload: string) {
const hmac = crypto.createHmac('sha1', secret);
return `sha1=${hmac.update(payload).digest('hex')}`;
};

const INCREMENTAL_BUILD_TXN = 'incremental-build';
const INITIAL_BUILD_TXN = 'initial-build';

class SentryInstrumentation {
hasInitializedBuild: boolean = false;
Sentry = require('@sentry/node');

Sentry?: typeof Sentry;

span?: Span;
hasInitializedBuild: boolean = false;
spans: Record<string, Span> = {};

constructor() {
// Only run if SENTRY_INSTRUMENTATION` is set or when in ci,
// only in the javascript suite that runs webpack
if (!SENTRY_INSTRUMENTATION && !SENTRY_DEV_UI_PROFILING) {
if (!SENTRY_INSTRUMENTATION) {
return;
}

const sentry = require('@sentry/node') as typeof Sentry;
const {nodeProfilingIntegration} = require('@sentry/profiling-node');

sentry.init({
this.Sentry.init({
dsn: 'https://[email protected]/2053674',
environment: IS_CI ? 'ci' : 'local',
tracesSampleRate: 1.0,
integrations: [nodeProfilingIntegration()],
profilesSampler: ({transactionContext}) => {
if (transactionContext.name === INCREMENTAL_BUILD_TXN) {
return 0;
}
return 1;
},
_experiments: {
// 5 minutes should be plenty
maxProfileDurationMs: 5 * 60 * 1000,
},
});

if (IS_CI) {
sentry.setTag('branch', GITHUB_REF);
}

const cpus = os.cpus();
sentry.setTag('platform', os.platform());
sentry.setTag('arch', os.arch());
sentry.setTag(
'cpu',
cpus?.length ? `${cpus[0]!.model} (cores: ${cpus.length})}` : 'N/A'
);

this.Sentry = sentry;
this.withCITags();
this.withOSPlatformTags();

this.span = sentry.startInactiveSpan({
this.spans['initial-build'] = this.Sentry.startInactiveSpan({
op: 'webpack-build',
name: INITIAL_BUILD_TXN,
name: 'initial-build',
});
}

/**
* Measures the file sizes of assets emitted from the entrypoints
*/
measureAssetSizes(compilation: webpack.Compilation) {
if (!SENTRY_WEBPACK_WEBHOOK_SECRET) {
return;
withCITags() {
if (IS_CI) {
this.Sentry.setTag('branch', GITHUB_REF);
}
}

[...compilation.entrypoints].forEach(([entrypointName, entry]) =>
entry.chunks.forEach(chunk =>
Array.from(chunk.files)
.filter(assetName => !assetName.endsWith('.map'))
.forEach(assetName => {
const asset = compilation.assets[assetName];
const size = asset!.size();
const file = assetName;
const body = JSON.stringify({
file,
entrypointName,
size,
commit: GITHUB_SHA,
environment: IS_CI ? 'ci' : '',
node_env: NODE_ENV,
});

const req = https.request({
host: 'product-eng-webhooks-vmrqv3f7nq-uw.a.run.app',
path: '/metrics/webpack/webhook',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(body),
'x-webpack-signature': createSignature(
SENTRY_WEBPACK_WEBHOOK_SECRET,
body
),
},
});
req.end(body);
})
)
withOSPlatformTags() {
this.Sentry.setTag('platform', os.platform());
this.Sentry.setTag('arch', os.arch());

const cpus = os.cpus();
this.Sentry.setTag(
'cpu',
cpus?.length ? `${cpus[0]!.model} (cores: ${cpus.length})}` : 'N/A'
);
}

measureBuildTime(startTime: number, endTime: number) {
if (!this.Sentry) {
return;
}

const span = !this.hasInitializedBuild
? this.span
: this.Sentry.startInactiveSpan({
op: 'webpack-build',
name: INCREMENTAL_BUILD_TXN,
startTime,
});
measureInitialBuildTime(startTime: number, endTime: number) {
const initialBuildSpan = this.spans['initial-build'];

if (!span) {
if (!initialBuildSpan) {
return;
}

this.Sentry.withActiveSpan(span, () => {
this.Sentry?.startInactiveSpan({
const that = this;
this.Sentry.withActiveSpan(initialBuildSpan, () => {
that.Sentry.startInactiveSpan({
op: 'build',
name: 'webpack build',
attributes: {
Expand All @@ -159,29 +78,18 @@ class SentryInstrumentation {
}).end(endTime);
});

span.end();
initialBuildSpan.end();
delete this.spans['initial-build'];
this.hasInitializedBuild = true;
}

apply(compiler: webpack.Compiler) {
compiler.hooks.done.tapAsync(
PLUGIN_NAME,
async ({compilation, startTime, endTime}, done) => {
// Only record this once and only on Travis
// Don't really care about asset sizes during local dev
if (IS_CI && !this.hasInitializedBuild) {
this.measureAssetSizes(compilation);
}

if (this.Sentry) {
this.measureBuildTime(startTime / 1000, endTime / 1000);
await this.Sentry.flush();
}

this.hasInitializedBuild = true;

done();
}
);
compiler.hooks.done.tapAsync(PLUGIN_NAME, async ({startTime, endTime}, done) => {
this.measureInitialBuildTime(startTime / 1000, endTime / 1000);

await this.Sentry.flush();
done();
});
}
}

Expand Down
Loading

0 comments on commit 53f5dbf

Please sign in to comment.