Skip to content

Commit

Permalink
Merge pull request getsentry#7036 from getsentry/develop
Browse files Browse the repository at this point in the history
  • Loading branch information
Lms24 authored Feb 2, 2023
2 parents 980054d + 5e05e04 commit 503a1c2
Show file tree
Hide file tree
Showing 23 changed files with 164 additions and 278 deletions.
9 changes: 8 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ on:
push:
branches:
- develop
- master
- release/**
pull_request:
workflow_dispatch:
Expand Down Expand Up @@ -136,6 +137,10 @@ jobs:
# Note: These next three have to be checked as strings ('true'/'false')!
is_develop: ${{ github.ref == 'refs/heads/develop' }}
is_release: ${{ startsWith(github.ref, 'refs/heads/release/') }}
is_gitflow_sync: |
github.event_name == 'pull_request' &&
(github.head_ref == 'refs/heads/develop' || github.head_ref == 'refs/heads/master') &&
contains(steps.pr-labels.outputs.labels, ' Dev: Gitflow ')
force_skip_cache:
${{ github.event_name == 'pull_request' && contains(steps.pr-labels.outputs.labels, ' ci-skip-cache ') }}

Expand All @@ -144,7 +149,9 @@ jobs:
needs: job_get_metadata
runs-on: ubuntu-20.04
timeout-minutes: 15
if: needs.job_get_metadata.outputs.changed_any_code == 'true' || github.event_name != 'pull_request'
if: |
needs.job_get_metadata.outputs.is_gitflow_sync == 'false' &&
(needs.job_get_metadata.outputs.changed_any_code == 'true' || github.event_name != 'pull_request')
steps:
- name: 'Check out current commit (${{ needs.job_get_metadata.outputs.commit_label }})'
uses: actions/checkout@v3
Expand Down
16 changes: 10 additions & 6 deletions .github/workflows/gitflow-sync-develop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ on:
workflow_dispatch:

env:
DEV_BRANCH: develop
SOURCE_BRANCH: master
TARGET_BRANCH: develop

jobs:
main:
Expand All @@ -29,10 +30,13 @@ jobs:
id: open-pr
uses: repo-sync/pull-request@v2
with:
destination_branch: ${{ env.DEV_BRANCH }}
pr_title: '[Gitflow] Merge ${{ github.ref_name }} into ${{ env.DEV_BRANCH }}'
pr_body: 'Merge ${{ github.ref_name }} branch into ${{ env.DEV_BRANCH }}'
source_branch: ${{ env.SOURCE_BRANCH }}
destination_branch: ${{ env.TARGET_BRANCH }}
pr_title: '[Gitflow] Merge ${{ env.SOURCE_BRANCH }} into ${{ env.TARGET_BRANCH }}'
pr_body: 'Merge ${{ env.SOURCE_BRANCH }} branch into ${{ env.TARGET_BRANCH }}'
pr_label: 'Dev: Gitflow'
# This token is scoped to Daniel Griesser
github_token: ${{ secrets.REPO_SCOPED_TOKEN }}

# https://github.com/marketplace/actions/enable-pull-request-automerge
- name: Enable automerge for PR
Expand All @@ -44,9 +48,9 @@ jobs:

# https://github.com/marketplace/actions/auto-approve
- name: Auto approve PR
# Always skip this for now, until we got a proper bot setup
if: steps.open-pr.outputs.pr_number != ''
uses: hmarr/auto-approve-action@v3
with:
pull-request-number: ${{ steps.open-pr.outputs.pr_number }}
review-message: 'Auto approved automated PR'
# TODO: Use the token of some user here??
# github-token: ${{ secrets.SOME_USERS_PAT }}
32 changes: 20 additions & 12 deletions .github/workflows/gitflow-sync-master.yml
Original file line number Diff line number Diff line change
@@ -1,16 +1,10 @@
name: Gitflow - Sync develop into master
on:
push:
branches:
- develop
paths:
# We want to trigger this when ONLY the changlog is changed on develop, but nothing else
- 'CHANGELOG.md'
- '!packages'
- '!**/*.js'
- '!**/*.json'
- '!**/*.ts'
workflow_dispatch:
pull_request:
- types: [closed]
- branches:
- 'develop'

env:
MAIN_BRANCH: master
Expand All @@ -19,6 +13,9 @@ jobs:
main:
name: Create PR develop->master
runs-on: ubuntu-20.04
if: |
github.event.pull_request.merged == true
&& startsWith(github.event.pull_request.title, "meta(changelog):")
permissions:
pull-requests: write
contents: write
Expand All @@ -35,6 +32,8 @@ jobs:
pr_title: '[Gitflow] Merge ${{ github.ref_name }} into ${{ env.MAIN_BRANCH }}'
pr_body: 'Merge ${{ github.ref_name }} branch into ${{ env.MAIN_BRANCH }}'
pr_label: 'Dev: Gitflow'
# This token is scoped to Daniel Griesser
github_token: ${{ secrets.REPO_SCOPED_TOKEN }}

# https://github.com/marketplace/actions/enable-pull-request-automerge
- name: Enable automerge for PR
Expand All @@ -46,9 +45,18 @@ jobs:

# https://github.com/marketplace/actions/auto-approve
- name: Auto approve PR
# Always skip this for now, until we got a proper bot setup
if: steps.open-pr.outputs.pr_number != ''
uses: hmarr/auto-approve-action@v3
with:
pull-request-number: ${{ steps.open-pr.outputs.pr_number }}
review-message: 'Auto approved automated PR'
# TODO: Use the token of some user here??
# github-token: ${{ secrets.SOME_USERS_PAT }}

skipped:
runs-on: ubuntu-20.04
if: |
github.event.pull_request.merged == false
|| startsWith(github.event.pull_request.title, "meta(changelog):") == false
steps:
- name: Sync skipped
run: echo "OK"
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,17 @@

- "You miss 100 percent of the chances you don't take. — Wayne Gretzky" — Michael Scott

## 7.36.0

This Release re-introduces the accidentally removed but still deprecated `maskInputOptions` option for Session Replay.
Furthermore, replays are now stopped instead of paused when a rate limit is encountered.

- feat(replay): Add back deprecated `maskInputOptions` (#6981)
- feat(replay): Stop recording when hitting a rate limit (#7018)
- fix(integrations): Report `BaseClient` integrations added after init (#7011)
- fix(replay): Don't mangle private rrweb property (#7033)
- fix(replay): Fix feature detection of PerformanceObserver (#7029)

## 7.35.0

Session Replay is deprecating privacy options in favor of a more streamlined API. Please see the [Replay migration guide](https://github.com/getsentry/sentry-javascript/blob/master/packages/replay/MIGRATION.md) for further information.
Expand All @@ -27,6 +38,8 @@ Additionally, the following configuration options will no longer be configurable
- fix(utils): Account for null prototype during normalization (#6925)
- ref(replay): Log warning if sample rates are all undefined (#6959)

Work in this release contributed by @boblauer. Thank you for your contribution!

## 7.34.0

This release adds automatic injection of the Next.js SDK into serverside `app` directory bundles, allowing users to call the Sentry SDK in server components.
Expand Down
3 changes: 1 addition & 2 deletions docs/publishing-a-release.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,9 @@ _These steps are only relevant to Sentry employees when preparing and publishing
## Updating the Changelog

1. Create a new branch.
2. Run `git log --format="- %s"` and copy everything since the last release.
2. Run `yarn changelog` and copy everything
3. Create a new section in the changelog, deciding based on the changes whether it should be a minor bump or a patch release.
4. Paste in the logs you copied earlier.
5. Delete any which aren't user-facing changes.
6. Alphabetize the rest.
7. If any of the PRs are from external contributors, include underneath the commits `Work in this release contributed by <list of external contributors' GitHub usernames>. Thank you for your contributions!`. If there's only one external PR, don't forget to remove the final `s`. If there are three or more, use an Oxford comma. (It's in the Sentry styleguide!)
8. Commit, push, and open a PR with the title `meta: Update changelog for <fill in relevant version here>` against `develop` branch.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"clean:all": "run-p clean:build clean:caches clean:deps",
"codecov": "codecov",
"fix": "lerna run fix",
"changelog": "ts-node ./scripts/get-commit-list.ts",
"link:yarn": "lerna exec yarn link",
"lint": "lerna run lint",
"lint:eslint": "lerna run lint:eslint",
Expand Down
4 changes: 4 additions & 0 deletions packages/core/src/baseclient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,10 @@ export abstract class BaseClient<O extends ClientOptions> implements Client<O> {
*/
protected _prepareEvent(event: Event, hint: EventHint, scope?: Scope): PromiseLike<Event | null> {
const options = this.getOptions();
const integrations = Object.keys(this._integrations);
if (!hint.integrations && integrations.length > 0) {
hint.integrations = integrations;
}
return prepareEvent(options, event, hint, scope);
}

Expand Down
6 changes: 2 additions & 4 deletions packages/core/src/utils/prepareEvent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,10 @@ export function prepareEvent(
event_id: event.event_id || hint.event_id || uuid4(),
timestamp: event.timestamp || dateTimestampInSeconds(),
};
const integrations = hint.integrations || options.integrations.map(i => i.name);

applyClientOptions(prepared, options);
applyIntegrationsMetadata(
prepared,
options.integrations.map(i => i.name),
);
applyIntegrationsMetadata(prepared, integrations);

// If we have scope given to us, use it as the base for further modifications.
// This allows us to prevent unnecessary copying of data if `captureContext` is not provided.
Expand Down
21 changes: 20 additions & 1 deletion packages/core/test/lib/base.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { dsnToString, logger, SentryError, SyncPromise } from '@sentry/utils';
import { Hub, makeSession, Scope } from '../../src';
import * as integrationModule from '../../src/integration';
import { getDefaultTestClientOptions, TestClient } from '../mocks/client';
import { TestIntegration } from '../mocks/integration';
import { AdHocIntegration, TestIntegration } from '../mocks/integration';
import { makeFakeTransport } from '../mocks/transport';

const PUBLIC_DSN = 'https://username@domain/123';
Expand Down Expand Up @@ -678,6 +678,25 @@ describe('BaseClient', () => {
});
});

test('send all installed integrations in event sdk metadata', () => {
expect.assertions(1);

const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN, integrations: [new TestIntegration()] });
const client = new TestClient(options);
client.setupIntegrations();
client.addIntegration(new AdHocIntegration());

client.captureException(new Error('test exception'));

expect(TestClient.instance!.event).toEqual(
expect.objectContaining({
sdk: expect.objectContaining({
integrations: expect.arrayContaining(['TestIntegration', 'AdHockIntegration']),
}),
}),
);
});

test('normalizes event with default depth of 3', () => {
expect.assertions(1);

Expand Down
10 changes: 10 additions & 0 deletions packages/core/test/mocks/integration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,13 @@ export class AddAttachmentTestIntegration implements Integration {
});
}
}

export class AdHocIntegration implements Integration {
public static id: string = 'AdHockIntegration';

public name: string = 'AdHockIntegration';

public setupOnce(): void {
// Noop
}
}
3 changes: 3 additions & 0 deletions packages/replay/src/integration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ export class Replay implements Integration {
// eslint-disable-next-line deprecation/deprecation
blockSelector,
// eslint-disable-next-line deprecation/deprecation
maskInputOptions,
// eslint-disable-next-line deprecation/deprecation
maskTextClass,
// eslint-disable-next-line deprecation/deprecation
maskTextSelector,
Expand All @@ -77,6 +79,7 @@ export class Replay implements Integration {
}: ReplayConfiguration = {}) {
this._recordingOptions = {
maskAllInputs,
maskInputOptions: { ...(maskInputOptions || {}), password: true },
maskTextFn: maskFn,
maskInputFn: maskFn,

Expand Down
38 changes: 3 additions & 35 deletions packages/replay/src/replay.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
import { EventType, record } from '@sentry-internal/rrweb';
import { captureException } from '@sentry/core';
import type { Breadcrumb, ReplayRecordingMode } from '@sentry/types';
import type { RateLimits } from '@sentry/utils';
import { disabledUntil, logger } from '@sentry/utils';
import { logger } from '@sentry/utils';

import {
ERROR_CHECKOUT_TIME,
Expand Down Expand Up @@ -40,7 +39,6 @@ import { isExpired } from './util/isExpired';
import { isSessionExpired } from './util/isSessionExpired';
import { overwriteRecordDroppedEvent, restoreRecordDroppedEvent } from './util/monkeyPatchRecordDroppedEvent';
import { sendReplay } from './util/sendReplay';
import { RateLimitError } from './util/sendReplayRequest';

/**
* The main replay container class, which holds all the state and methods for recording and sending replays.
Expand Down Expand Up @@ -476,8 +474,8 @@ export class ReplayContainer implements ReplayContainerInterface {
this._handleException(err);
}

// _performanceObserver //
if (!('_performanceObserver' in WINDOW)) {
// PerformanceObserver //
if (!('PerformanceObserver' in WINDOW)) {
return;
}

Expand Down Expand Up @@ -809,11 +807,6 @@ export class ReplayContainer implements ReplayContainerInterface {
} catch (err) {
this._handleException(err);

if (err instanceof RateLimitError) {
this._handleRateLimit(err.rateLimits);
return;
}

// This means we retried 3 times, and all of them failed
// In this case, we want to completely stop the replay - otherwise, we may get inconsistent segments
this.stop();
Expand Down Expand Up @@ -873,29 +866,4 @@ export class ReplayContainer implements ReplayContainerInterface {
saveSession(this.session);
}
}

/**
* Pauses the replay and resumes it after the rate-limit duration is over.
*/
private _handleRateLimit(rateLimits: RateLimits): void {
// in case recording is already paused, we don't need to do anything, as we might have already paused because of a
// rate limit
if (this.isPaused()) {
return;
}

const rateLimitEnd = disabledUntil(rateLimits, 'replay');
const rateLimitDuration = rateLimitEnd - Date.now();

if (rateLimitDuration > 0) {
__DEBUG_BUILD__ && logger.warn('[Replay]', `Rate limit hit, pausing replay for ${rateLimitDuration}ms`);
this.pause();
this._debouncedFlush.cancel();

setTimeout(() => {
__DEBUG_BUILD__ && logger.info('[Replay]', 'Resuming replay after rate limit');
this.resume();
}, rateLimitDuration);
}
}
}
12 changes: 8 additions & 4 deletions packages/replay/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,14 @@ export interface DeprecatedPrivacyOptions {
* @deprecated Use `block` which accepts an array of CSS selectors
*/
blockClass?: RecordingOptions['blockClass'];
/**
* @deprecated Use `ignore` which accepts an array of CSS selectors
*/
ignoreClass?: RecordingOptions['ignoreClass'];
/**
* @deprecated Use `mask` which accepts an array of CSS selectors
*/
maskInputOptions?: RecordingOptions['maskInputOptions'];
/**
* @deprecated Use `mask` which accepts an array of CSS selectors
*/
Expand All @@ -166,10 +174,6 @@ export interface DeprecatedPrivacyOptions {
* @deprecated Use `mask` which accepts an array of CSS selectors
*/
maskTextSelector?: RecordingOptions['maskTextSelector'];
/**
* @deprecated Use `ignore` which accepts an array of CSS selectors
*/
ignoreClass?: RecordingOptions['ignoreClass'];
}

export interface ReplayConfiguration
Expand Down
1 change: 1 addition & 0 deletions packages/replay/src/types/rrweb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,5 @@ export type recordOptions = {
maskTextClass?: maskTextClass;
maskTextSelector?: string;
blockSelector?: string;
maskInputOptions?: Record<string, boolean>;
} & Record<string, unknown>;
3 changes: 2 additions & 1 deletion packages/replay/src/util/getPrivacyOptions.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { DeprecatedPrivacyOptions, ReplayIntegrationPrivacyOptions } from '../types';

type GetPrivacyOptions = Required<Omit<ReplayIntegrationPrivacyOptions, 'maskFn'>> & DeprecatedPrivacyOptions;
type GetPrivacyOptions = Required<Omit<ReplayIntegrationPrivacyOptions, 'maskFn'>> &
Omit<DeprecatedPrivacyOptions, 'maskInputOptions'>;
interface GetPrivacyReturn {
maskTextSelector: string;
unmaskTextSelector: string;
Expand Down
Loading

0 comments on commit 503a1c2

Please sign in to comment.