CI: Switch jest unit tests to self-hosted runners (#109304)

* trigger a workflow run for baseline

* attempt to improve caching with upfront action

* CYPRESS_INSTALL_BINARY: 0

* PUPPETEER_SKIP_DOWNLOAD: true

* use ubuntu-x64-large runners

* increase to 16 shards 🚀

* fix incorrect shard total

* ubuntu-x64 runners

* Revert "ubuntu-x64 runners"

This reverts commit 3411c7c5e1039263b17a3065cd7d45fa4c3c8f69.

* try caching node_modules

* fix flakey scopes test

* try just ubuntu-x64-large for yarn-install job

* run again, last one had a dodgy trace

* try different runners for yarn instlal

* Move node_modules cache steps to composite action, use ubuntu-x64 runners for everything

* fix duplicate runs-on

* specify shell for composite action

* fix some flaky tests

* update codeowners

* dedupe yarn.lock

* align yarn action, switch tests back to ubuntu-x64-large

* align yarn action cache keys

* fix required-frontend-unit-tests not checking repo out

* try without the node_modules magic

* actually skip the node_modules caching magic

* skip hardened mode

* skip downloading cypress

* comment
This commit is contained in:
Josh Hunt 2025-08-08 14:31:14 +01:00 committed by GitHub
parent 463e544db9
commit f836ea2ada
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
20 changed files with 133 additions and 96 deletions

1
.github/CODEOWNERS vendored
View File

@ -1133,6 +1133,7 @@ embed.go @grafana/grafana-as-code
/.github/actions/setup-grafana-bench/ @Proximyst
/.github/actions/build-package @grafana/grafana-developer-enablement-squad
/.github/actions/change-detection @grafana/grafana-developer-enablement-squad
/.github/actions/setup-node @grafana/grafana-frontend-platform
/.github/workflows/actionlint-format.txt @grafana/grafana-developer-enablement-squad
/.github/workflows/actionlint.yml @grafana/grafana-developer-enablement-squad
/.github/workflows/add-to-whats-new.yml @grafana/docs-tooling

View File

@ -6,3 +6,23 @@ self-hosted-runner:
- github-hosted-ubuntu-x64-small
- github-hosted-ubuntu-x64-large
- github-hosted-windows-x64-large
- ubuntu-x64
- ubuntu-x64-io
- ubuntu-x64-small
- ubuntu-x64-small-io
- ubuntu-x64-large
- ubuntu-x64-large-io
- ubuntu-x64-xlarge
- ubuntu-x64-xlarge-io
- ubuntu-x64-2xlarge
- ubuntu-x64-2xlarge-io
- ubuntu-arm64
- ubuntu-arm64-io
- ubuntu-arm64-small
- ubuntu-arm64-small-io
- ubuntu-arm64-large
- ubuntu-arm64-large-io
- ubuntu-arm64-xlarge
- ubuntu-arm64-xlarge-io
- ubuntu-arm64-2xlarge
- ubuntu-arm64-2xlarge-io

11
.github/actions/setup-node/action.yml vendored Normal file
View File

@ -0,0 +1,11 @@
name: Setup Node.js
description: Sets up a node.js environment with presets for the Grafana repository.
runs:
using: "composite"
steps:
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'yarn'
cache-dependency-path: 'yarn.lock'

View File

@ -32,19 +32,7 @@ jobs:
persist-credentials: false
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'yarn'
- name: Cache node_modules
uses: actions/cache@v4
with:
path: |
node_modules
key: node_modules-${{ hashFiles('yarn.lock') }}
restore-keys: |
node_modules-
uses: ./.github/actions/setup-node
- name: Install dependencies
env:

View File

@ -11,7 +11,7 @@ permissions: {}
jobs:
detect-changes:
name: Detect whether code changed
runs-on: ubuntu-latest
runs-on: ubuntu-x64-small
permissions:
contents: read
outputs:
@ -31,100 +31,115 @@ jobs:
permissions:
contents: read
id-token: write
needs:
- detect-changes
# Run this workflow only for PRs from forks; if it gets merged into `main` or `release-*`,
# the `frontend-unit-tests-enterprise` workflow will run instead
needs: detect-changes
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == true && needs.detect-changes.outputs.changed == 'true'
runs-on: ubuntu-latest-8-cores
name: "Unit tests (${{ matrix.chunk }} / 8)"
runs-on: ubuntu-x64-large
name: "Unit tests (${{ matrix.shard }} / ${{ matrix.total }})"
strategy:
fail-fast: false
matrix:
chunk: [1, 2, 3, 4, 5, 6, 7, 8]
shard: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
total: [16]
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'yarn'
cache-dependency-path: 'yarn.lock'
- run: yarn install --immutable --check-cache
- name: Setup Node.js
uses: ./.github/actions/setup-node
- name: Yarn install
run: yarn install --immutable
env:
PUPPETEER_SKIP_DOWNLOAD: true
CYPRESS_INSTALL_BINARY: 0
- run: yarn run test:ci
env:
TEST_MAX_WORKERS: 2
TEST_SHARD: ${{ matrix.chunk }}
TEST_SHARD_TOTAL: 8
TEST_MAX_WORKERS: 4
TEST_SHARD: ${{ matrix.shard }}
TEST_SHARD_TOTAL: ${{ matrix.total }}
frontend-unit-tests-enterprise:
permissions:
contents: read
id-token: write
needs:
- detect-changes
# Run this workflow for non-PR events (like pushes to `main` or `release-*`) OR for internal PRs (PRs not from forks)
needs: detect-changes
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork == false && needs.detect-changes.outputs.changed == 'true'
runs-on: ubuntu-latest-8-cores
name: "Unit tests (${{ matrix.chunk }} / 8)"
runs-on: ubuntu-x64-large
name: "Unit tests (${{ matrix.shard }} / ${{ matrix.total }})"
strategy:
fail-fast: false
matrix:
chunk: [1, 2, 3, 4, 5, 6, 7, 8]
shard: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
total: [16]
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'yarn'
cache-dependency-path: 'yarn.lock'
- name: Setup Enterprise
uses: ./.github/actions/setup-enterprise
with:
github-app-name: 'grafana-ci-bot'
- run: yarn install --immutable --check-cache
- name: Setup Node.js
uses: ./.github/actions/setup-node
- name: Yarn install
run: yarn install --immutable
env:
# Switch from default hardened mode to faster mode for internal PRs
YARN_ENABLE_HARDENED_MODE: ${{ github.event.pull_request.head.repo.fork == false && '1' || '0' }}
PUPPETEER_SKIP_DOWNLOAD: true
CYPRESS_INSTALL_BINARY: 0
- run: yarn run test:ci
env:
TEST_MAX_WORKERS: 2
TEST_SHARD: ${{ matrix.chunk }}
TEST_SHARD_TOTAL: 8
TEST_MAX_WORKERS: 4
TEST_SHARD: ${{ matrix.shard }}
TEST_SHARD_TOTAL: ${{ matrix.total }}
frontend-decoupled-plugin-tests:
needs: detect-changes
needs:
- detect-changes
if: needs.detect-changes.outputs.changed == 'true'
runs-on: ubuntu-latest-8-cores
runs-on: ubuntu-x64-large
name: "Decoupled plugin tests"
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'yarn'
cache-dependency-path: 'yarn.lock'
- run: yarn install --immutable --check-cache
- name: Setup Node.js
uses: ./.github/actions/setup-node
- name: Yarn install
run: yarn install --immutable
env:
# Switch from default hardened mode to faster mode for internal PRs
YARN_ENABLE_HARDENED_MODE: ${{ github.event.pull_request.head.repo.fork == false && '1' || '0' }}
PUPPETEER_SKIP_DOWNLOAD: true
CYPRESS_INSTALL_BINARY: 0
- run: yarn run plugin:test:ci
frontend-packages-unit-tests:
needs: detect-changes
needs:
- detect-changes
if: needs.detect-changes.outputs.changed == 'true'
runs-on: ubuntu-latest-8-cores
runs-on: ubuntu-x64-large
name: "Packages unit tests"
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'yarn'
cache-dependency-path: 'yarn.lock'
- run: yarn install --immutable --check-cache
- name: Setup Node.js
uses: ./.github/actions/setup-node
- name: Yarn install
run: yarn install --immutable
env:
# Switch from default hardened mode to faster mode for internal PRs
YARN_ENABLE_HARDENED_MODE: ${{ github.event.pull_request.head.repo.fork == false && '1' || '0' }}
PUPPETEER_SKIP_DOWNLOAD: true
CYPRESS_INSTALL_BINARY: 0
- run: yarn run packages:test:ci
# This is the job that is actually required by rulesets.
# We need to require EITHER the OSS or the Enterprise job to pass.
# However, if one is skipped, GitHub won't flat-map the shards,
@ -141,15 +156,14 @@ jobs:
if: always()
name: All frontend unit tests complete
runs-on: ubuntu-latest
runs-on: ubuntu-x64-small
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- name: Check test suites
env:
NEEDS: ${{ toJson(needs) }}
run: |
FAILURES="$(echo "$NEEDS" | jq 'with_entries(select(.value.result == "failure")) | map_values(.result)')"
echo "$FAILURES"
if [ "$(echo "$FAILURES" | jq '. | length')" != "0" ]; then
exit 1
fi
echo "All OK!"
uses: ./.github/actions/check-jobs
with:
needs: ${{ toJson(needs) }}
failure-message: "One or more unit test jobs have failed"
success-message: "All unit tests completed successfully"

View File

@ -286,7 +286,7 @@
"@grafana/llm": "0.22.1",
"@grafana/monaco-logql": "^0.0.8",
"@grafana/o11y-ds-frontend": "workspace:*",
"@grafana/plugin-ui": "0.10.8",
"@grafana/plugin-ui": "0.10.9",
"@grafana/prometheus": "workspace:*",
"@grafana/runtime": "workspace:*",
"@grafana/scenes": "6.29.5",

View File

@ -20,7 +20,7 @@
"@emotion/css": "11.13.5",
"@grafana/data": "12.2.0-pre",
"@grafana/e2e-selectors": "12.2.0-pre",
"@grafana/plugin-ui": "0.10.8",
"@grafana/plugin-ui": "0.10.9",
"@grafana/runtime": "12.2.0-pre",
"@grafana/schema": "12.2.0-pre",
"@grafana/ui": "12.2.0-pre",

View File

@ -44,7 +44,7 @@
"@grafana/data": "12.2.0-pre",
"@grafana/e2e-selectors": "12.2.0-pre",
"@grafana/i18n": "12.2.0-pre",
"@grafana/plugin-ui": "0.10.8",
"@grafana/plugin-ui": "0.10.9",
"@grafana/runtime": "12.2.0-pre",
"@grafana/schema": "12.2.0-pre",
"@grafana/ui": "12.2.0-pre",

View File

@ -19,7 +19,7 @@
"@grafana/data": "12.2.0-pre",
"@grafana/e2e-selectors": "12.2.0-pre",
"@grafana/i18n": "12.2.0-pre",
"@grafana/plugin-ui": "0.10.8",
"@grafana/plugin-ui": "0.10.9",
"@grafana/runtime": "12.2.0-pre",
"@grafana/ui": "12.2.0-pre",
"@react-awesome-query-builder/ui": "6.6.15",

View File

@ -1,3 +1,5 @@
import { waitFor } from '@testing-library/dom';
import { config, locationService } from '@grafana/runtime';
import { ScopesService } from '../ScopesService';
@ -276,7 +278,7 @@ describe('Dashboards list', () => {
await updateScopes(scopesService, ['mimir']);
await searchDashboards('unknown');
expectDashboardsSearch();
expectNoDashboardsForFilter();
await waitFor(() => expectNoDashboardsForFilter());
await clearNotFound();
expectDashboardSearchValue('');

View File

@ -81,6 +81,7 @@ describe('VariablesUnknownTable', () => {
await userEvent.click(screen.getByRole('heading', { name: /renamed or missing variables/i }));
await waitFor(() => expect(screen.queryByTestId('Spinner')).not.toBeInTheDocument());
expect(screen.getByText('No renamed or missing variables found.')).toBeInTheDocument();
});
});

View File

@ -7,7 +7,7 @@
"@emotion/css": "11.13.5",
"@grafana/data": "12.2.0-pre",
"@grafana/i18n": "12.2.0-pre",
"@grafana/plugin-ui": "0.10.8",
"@grafana/plugin-ui": "0.10.9",
"@grafana/runtime": "12.2.0-pre",
"@grafana/schema": "12.2.0-pre",
"@grafana/ui": "12.2.0-pre",

View File

@ -7,7 +7,7 @@
"@emotion/css": "11.13.5",
"@grafana/data": "12.2.0-pre",
"@grafana/google-sdk": "0.3.4",
"@grafana/plugin-ui": "0.10.8",
"@grafana/plugin-ui": "0.10.9",
"@grafana/runtime": "12.2.0-pre",
"@grafana/schema": "12.2.0-pre",
"@grafana/ui": "12.2.0-pre",

View File

@ -6,7 +6,7 @@
"dependencies": {
"@emotion/css": "11.13.5",
"@grafana/data": "12.2.0-pre",
"@grafana/plugin-ui": "0.10.8",
"@grafana/plugin-ui": "0.10.9",
"@grafana/runtime": "12.2.0-pre",
"@grafana/sql": "12.2.0-pre",
"@grafana/ui": "12.2.0-pre",

View File

@ -8,7 +8,7 @@
"@grafana/data": "workspace:*",
"@grafana/e2e-selectors": "workspace:*",
"@grafana/o11y-ds-frontend": "workspace:*",
"@grafana/plugin-ui": "0.10.8",
"@grafana/plugin-ui": "0.10.9",
"@grafana/runtime": "workspace:*",
"@grafana/ui": "workspace:*",
"lodash": "4.17.21",

View File

@ -7,7 +7,7 @@
"@emotion/css": "11.13.5",
"@grafana/data": "12.2.0-pre",
"@grafana/i18n": "12.2.0-pre",
"@grafana/plugin-ui": "0.10.8",
"@grafana/plugin-ui": "0.10.9",
"@grafana/runtime": "12.2.0-pre",
"@grafana/sql": "12.2.0-pre",
"@grafana/ui": "12.2.0-pre",

View File

@ -6,7 +6,7 @@
"dependencies": {
"@emotion/css": "11.13.5",
"@grafana/data": "12.2.0-pre",
"@grafana/plugin-ui": "0.10.8",
"@grafana/plugin-ui": "0.10.9",
"@grafana/runtime": "12.2.0-pre",
"@grafana/sql": "12.2.0-pre",
"@grafana/ui": "12.2.0-pre",

View File

@ -10,7 +10,7 @@
"@grafana/lezer-traceql": "0.0.23",
"@grafana/monaco-logql": "^0.0.8",
"@grafana/o11y-ds-frontend": "workspace:*",
"@grafana/plugin-ui": "0.10.8",
"@grafana/plugin-ui": "0.10.9",
"@grafana/runtime": "workspace:*",
"@grafana/schema": "workspace:*",
"@grafana/ui": "workspace:*",

View File

@ -8,7 +8,7 @@
"@grafana/data": "workspace:*",
"@grafana/e2e-selectors": "workspace:*",
"@grafana/o11y-ds-frontend": "workspace:*",
"@grafana/plugin-ui": "0.10.8",
"@grafana/plugin-ui": "0.10.9",
"@grafana/runtime": "workspace:*",
"@grafana/ui": "workspace:*",
"lodash": "4.17.21",

View File

@ -2542,7 +2542,7 @@ __metadata:
"@grafana/e2e-selectors": "npm:12.2.0-pre"
"@grafana/i18n": "npm:12.2.0-pre"
"@grafana/plugin-configs": "npm:12.2.0-pre"
"@grafana/plugin-ui": "npm:0.10.8"
"@grafana/plugin-ui": "npm:0.10.9"
"@grafana/runtime": "npm:12.2.0-pre"
"@grafana/schema": "npm:12.2.0-pre"
"@grafana/ui": "npm:12.2.0-pre"
@ -2588,7 +2588,7 @@ __metadata:
"@grafana/data": "npm:12.2.0-pre"
"@grafana/e2e-selectors": "npm:12.2.0-pre"
"@grafana/plugin-configs": "npm:12.2.0-pre"
"@grafana/plugin-ui": "npm:0.10.8"
"@grafana/plugin-ui": "npm:0.10.9"
"@grafana/runtime": "npm:12.2.0-pre"
"@grafana/sql": "npm:12.2.0-pre"
"@grafana/ui": "npm:12.2.0-pre"
@ -2702,7 +2702,7 @@ __metadata:
"@grafana/e2e-selectors": "workspace:*"
"@grafana/o11y-ds-frontend": "workspace:*"
"@grafana/plugin-configs": "workspace:*"
"@grafana/plugin-ui": "npm:0.10.8"
"@grafana/plugin-ui": "npm:0.10.9"
"@grafana/runtime": "workspace:*"
"@grafana/ui": "workspace:*"
"@testing-library/dom": "npm:10.4.1"
@ -2789,7 +2789,7 @@ __metadata:
"@grafana/e2e-selectors": "npm:12.2.0-pre"
"@grafana/i18n": "npm:12.2.0-pre"
"@grafana/plugin-configs": "npm:12.2.0-pre"
"@grafana/plugin-ui": "npm:0.10.8"
"@grafana/plugin-ui": "npm:0.10.9"
"@grafana/runtime": "npm:12.2.0-pre"
"@grafana/sql": "npm:12.2.0-pre"
"@grafana/ui": "npm:12.2.0-pre"
@ -2821,7 +2821,7 @@ __metadata:
"@grafana/data": "npm:12.2.0-pre"
"@grafana/e2e-selectors": "npm:12.2.0-pre"
"@grafana/plugin-configs": "npm:12.2.0-pre"
"@grafana/plugin-ui": "npm:0.10.8"
"@grafana/plugin-ui": "npm:0.10.9"
"@grafana/runtime": "npm:12.2.0-pre"
"@grafana/sql": "npm:12.2.0-pre"
"@grafana/ui": "npm:12.2.0-pre"
@ -2887,7 +2887,7 @@ __metadata:
"@grafana/e2e-selectors": "npm:12.2.0-pre"
"@grafana/google-sdk": "npm:0.3.4"
"@grafana/plugin-configs": "npm:12.2.0-pre"
"@grafana/plugin-ui": "npm:0.10.8"
"@grafana/plugin-ui": "npm:0.10.9"
"@grafana/runtime": "npm:12.2.0-pre"
"@grafana/schema": "npm:12.2.0-pre"
"@grafana/ui": "npm:12.2.0-pre"
@ -2936,7 +2936,7 @@ __metadata:
"@grafana/monaco-logql": "npm:^0.0.8"
"@grafana/o11y-ds-frontend": "workspace:*"
"@grafana/plugin-configs": "npm:12.2.0-pre"
"@grafana/plugin-ui": "npm:0.10.8"
"@grafana/plugin-ui": "npm:0.10.9"
"@grafana/runtime": "workspace:*"
"@grafana/schema": "workspace:*"
"@grafana/ui": "workspace:*"
@ -2994,7 +2994,7 @@ __metadata:
"@grafana/e2e-selectors": "workspace:*"
"@grafana/o11y-ds-frontend": "workspace:*"
"@grafana/plugin-configs": "workspace:*"
"@grafana/plugin-ui": "npm:0.10.8"
"@grafana/plugin-ui": "npm:0.10.9"
"@grafana/runtime": "workspace:*"
"@grafana/ui": "workspace:*"
"@testing-library/dom": "npm:10.4.1"
@ -3374,7 +3374,7 @@ __metadata:
"@emotion/css": "npm:11.13.5"
"@grafana/data": "npm:12.2.0-pre"
"@grafana/e2e-selectors": "npm:12.2.0-pre"
"@grafana/plugin-ui": "npm:0.10.8"
"@grafana/plugin-ui": "npm:0.10.9"
"@grafana/runtime": "npm:12.2.0-pre"
"@grafana/schema": "npm:12.2.0-pre"
"@grafana/ui": "npm:12.2.0-pre"
@ -3444,9 +3444,9 @@ __metadata:
languageName: node
linkType: hard
"@grafana/plugin-ui@npm:0.10.8, @grafana/plugin-ui@npm:^0.10.1":
version: 0.10.8
resolution: "@grafana/plugin-ui@npm:0.10.8"
"@grafana/plugin-ui@npm:0.10.9, @grafana/plugin-ui@npm:^0.10.1":
version: 0.10.9
resolution: "@grafana/plugin-ui@npm:0.10.9"
dependencies:
"@emotion/css": "npm:^11.11.2"
"@hello-pangea/dnd": "npm:^17.0.0"
@ -3468,7 +3468,7 @@ __metadata:
react: ^18.2.0
react-dom: ^18.2.0
rxjs: ^7.8.1
checksum: 10/3ef5eddd9a517fe2c7a0796f3d96dcd802153b625c46d7b2733f91f0378c6a8423022cae238b3bb6f554845f7e1bf63447ed8f9d3a6a5ada7d3df1e53c9cbf09
checksum: 10/3f49f6fef04594b5ea98052738bee64ed587fa7646947d90633b833c83a7376627feabf256f077d69a5ca2f19a3df4fe7c42f67d98e1c0c834ba4712086cd423
languageName: node
linkType: hard
@ -3481,7 +3481,7 @@ __metadata:
"@grafana/data": "npm:12.2.0-pre"
"@grafana/e2e-selectors": "npm:12.2.0-pre"
"@grafana/i18n": "npm:12.2.0-pre"
"@grafana/plugin-ui": "npm:0.10.8"
"@grafana/plugin-ui": "npm:0.10.9"
"@grafana/runtime": "npm:12.2.0-pre"
"@grafana/schema": "npm:12.2.0-pre"
"@grafana/ui": "npm:12.2.0-pre"
@ -3654,7 +3654,7 @@ __metadata:
"@grafana/data": "npm:12.2.0-pre"
"@grafana/e2e-selectors": "npm:12.2.0-pre"
"@grafana/i18n": "npm:12.2.0-pre"
"@grafana/plugin-ui": "npm:0.10.8"
"@grafana/plugin-ui": "npm:0.10.9"
"@grafana/runtime": "npm:12.2.0-pre"
"@grafana/ui": "npm:12.2.0-pre"
"@react-awesome-query-builder/ui": "npm:6.6.15"
@ -18215,7 +18215,7 @@ __metadata:
"@grafana/monaco-logql": "npm:^0.0.8"
"@grafana/o11y-ds-frontend": "workspace:*"
"@grafana/plugin-e2e": "npm:2.1.7"
"@grafana/plugin-ui": "npm:0.10.8"
"@grafana/plugin-ui": "npm:0.10.9"
"@grafana/prometheus": "workspace:*"
"@grafana/runtime": "workspace:*"
"@grafana/scenes": "npm:6.29.5"