Skip to content

ref(seer-settings): Remove unused helper to bulk write Seer project preferences #313300

ref(seer-settings): Remove unused helper to bulk write Seer project preferences

ref(seer-settings): Remove unused helper to bulk write Seer project preferences #313300

Workflow file for this run

name: frontend
on:
push:
branches:
- master
pull_request:
# Cancel in progress workflows on pull_requests.
# https://docs.github.com/en/actions/using-jobs/using-concurrency#example-using-a-fallback-value
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
# hack for https://github.com/actions/cache/issues/810#issuecomment-1222550359
env:
SEGMENT_DOWNLOAD_TIMEOUT_MINS: 3
NODE_OPTIONS: '--max-old-space-size=5120'
jobs:
files-changed:
name: detect what files changed
runs-on: ubuntu-24.04
timeout-minutes: 3
permissions:
contents: read
pull-requests: read
# Map a step output to a job output
outputs:
testable_modified: ${{ steps.changes.outputs.testable_modified }}
testable_rules_changed: ${{ steps.changes.outputs.testable_rules_changed }}
frontend_all: ${{ steps.changes.outputs.frontend_all }}
frontend_all_files: ${{ steps.changes.outputs.frontend_all_files }}
frontend_lint: ${{ steps.changes.outputs.frontend_lint }}
embed_widget_schema: ${{ steps.changes.outputs.embed_widget_schema }}
steps:
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
with:
fetch-depth: 1
- name: Check for frontend file changes
uses: dorny/paths-filter@7b450fff21473bca461d4b92ce414b9d0420d706 # v4.0.2
id: changes
with:
token: ${{ github.token }}
filters: .github/file-filters.yml
list-files: shell
typescript:
if: needs.files-changed.outputs.frontend_all == 'true'
needs: files-changed
name: typescript
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- uses: ./.github/actions/setup-node-pnpm
# Setup custom TypeScript matcher, see https://github.com/actions/setup-node/issues/97
- name: setup matchers
run: |
echo "::remove-matcher owner=masters::"
echo "::add-matcher::.github/tsc.json"
- name: tsc
id: tsc
run: pnpm run typecheck
oxlint:
if: needs.files-changed.outputs.frontend_lint == 'true'
needs: files-changed
name: oxlint
runs-on: ubuntu-24.04
timeout-minutes: 15
outputs:
budgets: ${{ steps.ratchet.outputs.budgets }}
permissions:
contents: read
actions: read
steps:
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
with:
fetch-depth: ${{ github.event_name == 'pull_request' && '100' || '1' }}
- uses: ./.github/actions/setup-node-pnpm
- name: Find verified lint baseline
if: github.event_name == 'pull_request'
id: lint-baseline
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
script: |
const {findVerifiedLintBase} = await import(`${process.env.GITHUB_WORKSPACE}/.github/workflows/scripts/find-verified-lint-base.js`);
core.setOutput('base', await findVerifiedLintBase({github, context, core}));
- name: Verify lint ratchet
id: ratchet
env:
EVENT_NAME: ${{ github.event_name }}
SENTRY_OXLINT_VERIFIED_BASE: ${{ steps.lint-baseline.outputs.base }}
run: |
if [ "$EVENT_NAME" = pull_request ]; then
pnpm run lint:suppressions --ci --base HEAD^1
else
pnpm run lint:suppressions --ci
fi
# The ratchet passes with stale budgets inherited from earlier merges, but only
# exact budgets equal live debt. find-verified-lint-base.js reuses master budgets
# only after this step succeeds.
- name: Verify exact lint budgets
if: steps.ratchet.outputs.budgets == 'exact'
run: echo 'Committed oxlint budgets match live debt.'
# Decide whether to lint just the PR's impacted files or everything (see
# frontend-changed-scope.sh): we scope to impacted files only when a merge base
# resolves and changes are under static/ or to project oxlint-suppressions.json files.
# Global config or dependency changes require linting everything because
# their impact can't be traced from source files.
- name: Compute lint strategy
id: strategy
run: ./.github/workflows/scripts/frontend-changed-scope.sh >> "$GITHUB_OUTPUT"
- name: oxlint (all files)
id: oxlint
if: steps.strategy.outputs.scope == 'full'
run: pnpm run lint:js
# Lint just the files transitively impacted by the PR. Diff the merge base against
# HEAD^2 (the PR head) so we only seed on the PR's own changes. Diffing against the
# working tree (the merge commit) would also pull in everything that landed on master
# since the fork point.
- name: oxlint (impacted files)
id: oxlint-impacted
if: steps.strategy.outputs.scope == 'scoped'
run: pnpm run lint:js:changed --since "$MERGE_BASE..HEAD^2" -- node scripts/lint.ts js --no-error-on-unmatched-pattern
env:
MERGE_BASE: ${{ steps.strategy.outputs.merge_base }}
DEBUG: 'run-on-changed:*'
- name: stylelint (workspace packages)
run: pnpm --recursive --parallel --no-bail --no-include-workspace-root --if-present run lint:css
prune-oxlint-suppressions:
needs: oxlint
if: github.event_name == 'push' && github.ref == 'refs/heads/master' && needs.oxlint.outputs.budgets == 'stale'
permissions:
contents: read
uses: ./.github/workflows/prune-oxlint-suppressions.yml
secrets:
SENTRY_INTERNAL_APP_PRIVATE_KEY: ${{ secrets.SENTRY_INTERNAL_APP_PRIVATE_KEY }}
knip:
if: needs.files-changed.outputs.frontend_all == 'true'
needs: files-changed
name: ${{ matrix.command }}
runs-on: ubuntu-24.04
strategy:
fail-fast: false
matrix:
command: [knip, 'knip:prod', 'knip:cycles']
steps:
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- uses: ./.github/actions/setup-node-pnpm
- name: ${{ matrix.command }}
run: pnpm run ${{ matrix.command }}
jest-config:
if: needs.files-changed.outputs.testable_rules_changed == 'true' || needs.files-changed.outputs.testable_modified == 'true'
name: Configure Jest
runs-on: ubuntu-24.04
timeout-minutes: 3
needs: files-changed
outputs:
jest_test_matrix: ${{ steps.jest_test_config.outputs.jest_test_matrix }}
steps:
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
name: Checkout sentry
with:
# PRs need history for git merge-base to find the fork point.
fetch-depth: ${{ github.event_name == 'pull_request' && '100' || '1' }}
- uses: ./.github/actions/setup-node-pnpm
# On PRs, HEAD is the merge commit; its parents (HEAD^1, HEAD^2) are base and head.
# Merge base of those two determines which tests to run via --findRelatedTests.
# If merge base can't be computed or non-frontend files changed, the full
# test suite runs instead.
- name: Jest Test Config
id: jest_test_config
env:
FRONTEND_ALL_FILES: ${{ needs.files-changed.outputs.frontend_all_files }}
run: ./.github/workflows/scripts/jest-test-config.sh
- name: Upload jest test file list
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # 4.6.2
with:
name: jest-test-files
path: jest-test-files.json
if-no-files-found: ignore
retention-days: 1
jest-tests:
if: needs.files-changed.outputs.testable_rules_changed == 'true' || needs.files-changed.outputs.testable_modified == 'true'
needs: [files-changed, jest-config]
name: Jest (shard ${{ matrix.index }})
# If you change the runs-on image, you must also change the runner in jest-balance.yml
# so that the balancer runs in the same environment as the tests.
runs-on: ubuntu-24.04
timeout-minutes: 30
strategy:
# This helps not having to run multiple jobs because one fails, thus, reducing resource usage
# and reducing the risk that one of many runs would turn red again (read: intermittent tests)
fail-fast: false
matrix:
index: ${{ fromJson(needs.jest-config.outputs.jest_test_matrix).index }}
total: ${{ fromJson(needs.jest-config.outputs.jest_test_matrix).total }}
permissions:
contents: read
# `gh run download` in "Download jest artifacts"
actions: read
steps:
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
name: Checkout sentry
# Must run before the parallel group: it parses $GITHUB_EVENT_PATH, which the
# runner truncates whenever a step starts (getsentry/sentry#127566). It is also
# a composite action, and the runner corrupts shared job state when a composite
# overlaps another step (actions/runner#4789).
- uses: ./.github/actions/setup-node-pnpm
# None of these depend on each other, fetch them all at once. Nothing in this
# group may read $GITHUB_EVENT_PATH (e.g. actions/setup-node, pnpm/action-setup,
# actions/download-artifact, actions/github-script, actions/checkout) or be a
# composite action.
- parallel:
- name: jest transform cache
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
with:
path: |
.cache/jest
~/.cache/swc
key: jest-cache-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml', 'tests/js/createJestConfig.ts', 'tests/js/jest.config.ci.mjs') }}-${{ matrix.index }}
restore-keys: |
jest-cache-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml', 'tests/js/createJestConfig.ts', 'tests/js/jest.config.ci.mjs') }}-
jest-cache-${{ runner.os }}-
- name: Download jest artifacts
env:
GH_TOKEN: ${{ github.token }}
GH_REPO: ${{ github.repository }}
run: ./.github/workflows/scripts/download-jest-artifacts.sh
- name: jest
env:
SENTRY_DSN: ${{ secrets.SENTRY_JEST_DSN }}
CI_NODE_TOTAL: ${{ matrix.total }}
CI_NODE_INDEX: ${{ matrix.index }}
GITHUB_PR_SHA: ${{ github.event.pull_request.head.sha || github.sha }}
GITHUB_PR_REF: ${{ github.event.pull_request.head.ref || github.ref }}
# Disable testing-library from printing out any of of the DOM to
# stdout. No one actually looks through this in CI, they're just
# going to run it locally.
#
# This quiets up the logs quite a bit.
DEBUG_PRINT_LIMIT: 0
# When the "Frontend: Rerun Flaky Tests" label is on the PR,
# tests wrapped with it.isKnownFlake() run 50x to validate fixes.
RERUN_KNOWN_FLAKY_TESTS: "${{ contains(github.event.pull_request.labels.*.name, 'Frontend: Rerun Flaky Tests') }}"
run: pnpm run test-ci --forceExit
form-field-registry:
if: needs.files-changed.outputs.frontend_all == 'true'
needs: files-changed
name: form field registry
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- uses: ./.github/actions/setup-node-pnpm
- name: Generate form field registry
run: node scripts/extractFormFields.ts
- name: Check for changes
run: |
if ! git diff --exit-code static/app/views/settings/fieldRegistry.generated.ts; then
echo ""
echo "❌ Form field registry is out of sync!"
echo ""
echo "Run the following command and commit the changes:"
echo " node scripts/extractFormFields.ts"
echo ""
exit 1
fi
embed-widgets:
if: needs.files-changed.outputs.embed_widget_schema == 'true'
needs: files-changed
name: embed widgets
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- uses: ./.github/actions/setup-node-pnpm
- name: Generate embed widgets
run: pnpm run gen:embed-widgets
- name: Check for changes
run: |
if ! git diff --exit-code src/sentry/seer/agent/embed_widgets.generated.json; then
echo ""
echo "❌ Embed widgets JSON schema is out of sync!"
echo ""
echo "Run the following command and commit the changes:"
echo " pnpm run gen:embed-widgets"
echo ""
exit 1
fi
# This check runs once all dependant jobs have passed
# It symbolizes that all required Frontend checks have succesfully passed (Or skipped)
# This check is the only required Github check
frontend-required-check:
needs:
[
files-changed,
jest-config,
jest-tests,
typescript,
oxlint,
knip,
form-field-registry,
embed-widgets,
]
name: Frontend
# This is necessary since a failed/skipped dependent job would cause this job to be skipped
if: always()
runs-on: ubuntu-24.04
steps:
# If any jobs we depend on fail, we will fail since this is a required check
# NOTE: A timeout is considered a failure
- name: Check for failures
if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')
run: |
echo "One of the dependent jobs have failed. You may need to re-run it." && exit 1