Skip to content

Commit 6cf85af

Browse files
ruchidhUbuntuopensearch-changeset-bot[bot]
authored
Lighthouse performance metrics setup (#9304)
* lighthouse performance metrics setup Signed-off-by: Ruchi Sharma <ruchi492@gmail.com> --------- Signed-off-by: Ubuntu <ubuntu@ip-172-31-47-220.us-west-2.compute.internal> Signed-off-by: Ruchi Sharma <ruchi492@gmail.com> Co-authored-by: Ubuntu <ubuntu@ip-172-31-47-220.us-west-2.compute.internal> Co-authored-by: opensearch-changeset-bot[bot] <154024398+opensearch-changeset-bot[bot]@users.noreply.github.com>
1 parent 14813de commit 6cf85af

File tree

10 files changed

+1592
-38
lines changed

10 files changed

+1592
-38
lines changed

.github/workflows/backport.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,6 @@ jobs:
3838
with:
3939
github_token: ${{ steps.github_app_token.outputs.token }}
4040
head_template: backport/backport-<%= number %>-to-<%= base %>
41-
files_to_skip: "CHANGELOG.md"
41+
files_to_skip: 'CHANGELOG.md'
4242
labels_template: "<%= JSON.stringify([...labels, 'autocut']) %>"
43-
failure_labels: "failed backport"
43+
failure_labels: 'failed backport'

.github/workflows/cypress_workflow.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ jobs:
111111
'node scripts/opensearch_dashboards --dev --no-base-path --no-watch --savedObjects.maxImportPayloadBytes=10485760 --server.maxPayloadBytes=1759977 --logging.json=false --data.search.aggs.shardDelay.enabled=true' ||
112112
'node ../scripts/opensearch_dashboards --dev --no-base-path --no-watch --savedObjects.maxImportPayloadBytes=10485760 --server.maxPayloadBytes=1759977 --logging.json=false --data.search.aggs.shardDelay.enabled=true --csp.warnLegacyBrowsers=false --uiSettings.overrides["query:enhancements:enabled"]=false' }}
113113
OPENSEARCH_SNAPSHOT_CMD: ${{ matrix.config == 'query_enhanced' &&
114-
'/bin/bash -c "./opensearch-2.17.0/opensearch-tar-install.sh &"' ||
114+
'/bin/bash -c "./opensearch-${{ env.LATEST_VERSION }}/opensearch-tar-install.sh &"' ||
115115
matrix.config == 'dashboard' &&
116116
'node scripts/opensearch snapshot -E cluster.routing.allocation.disk.threshold_enabled=false' ||
117117
'node ../scripts/opensearch snapshot -E cluster.routing.allocation.disk.threshold_enabled=false' }}
@@ -247,7 +247,7 @@ jobs:
247247
- name: Run OpenSearch
248248
if: matrix.config == 'query_enhanced'
249249
run: |
250-
/bin/bash -c "./opensearch-2.17.0/opensearch-tar-install.sh &"
250+
/bin/bash -c "./opensearch-${{ env.LATEST_VERSION }}/opensearch-tar-install.sh &"
251251
sleep 30
252252
shell: bash
253253

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
name: Lighthouse Testing
2+
3+
on:
4+
pull_request:
5+
branches:
6+
- main
7+
permissions:
8+
contents: read
9+
pull-requests: write
10+
statuses: write
11+
issues: write
12+
13+
env:
14+
NODE_OPTIONS: '--max-old-space-size=6144 --dns-result-order=ipv4first'
15+
LATEST_VERSION: '2.17.0'
16+
17+
jobs:
18+
lighthouse:
19+
runs-on: ubuntu-latest
20+
steps:
21+
- name: Checkout repository
22+
uses: actions/checkout@v2
23+
24+
- name: Setup Node
25+
uses: actions/setup-node@v2
26+
with:
27+
node-version-file: '.nvmrc'
28+
registry-url: 'https://registry.npmjs.org'
29+
30+
- name: Setup Yarn
31+
run: |
32+
npm uninstall -g yarn
33+
npm i -g yarn@1.22.10
34+
35+
- name: Run bootstrap
36+
run: yarn osd bootstrap
37+
38+
- name: Download OpenSearch
39+
uses: suisei-cn/actions-download-file@v1.4.0
40+
with:
41+
url: https://artifacts.opensearch.org/releases/bundle/opensearch/${{ env.LATEST_VERSION }}/opensearch-${{ env.LATEST_VERSION }}-linux-x64.tar.gz
42+
43+
- name: Extract OpenSearch
44+
run: |
45+
tar -xzf opensearch-*.tar.gz
46+
rm -f opensearch-*.tar.gz
47+
shell: bash
48+
49+
- name: Remove security plugin
50+
run: |
51+
/bin/bash -c "yes | ./opensearch-${{ env.LATEST_VERSION }}/bin/opensearch-plugin remove opensearch-security"
52+
shell: bash
53+
54+
- name: Run OpenSearch
55+
run: |
56+
/bin/bash -c "./opensearch-${{ env.LATEST_VERSION }}/opensearch-tar-install.sh &"
57+
sleep 30
58+
shell: bash
59+
60+
- name: Install Lighthouse CI
61+
run: yarn add --dev @lhci/cli
62+
63+
- name: Run bootstrap
64+
run: yarn osd bootstrap
65+
66+
- name: Build plugins
67+
run: node scripts/build_opensearch_dashboards_platform_plugins --no-examples --workers 12
68+
69+
- name: Wait for OpenSearch to be ready
70+
run: |
71+
until curl -s http://localhost:9200 >/dev/null; do
72+
echo "Waiting for OpenSearch..."
73+
sleep 10
74+
done
75+
echo "OpenSearch is up!"
76+
77+
- name: Start OpenSearch Dashboards
78+
run: |
79+
yarn start --no-base-path &
80+
until curl -s http://localhost:5601 >/dev/null; do
81+
echo "Waiting for OpenSearch Dashboards..."
82+
sleep 10
83+
done
84+
echo "OpenSearch Dashboards is up!"
85+
86+
- name: Mock data
87+
run: |
88+
curl 'http://localhost:5601/api/sample_data/ecommerce' -X 'POST' -H 'osd-version: ${{ env.VERSION }}' -H 'osd-xsrf: osd-fetch'
89+
90+
- name: Run Lighthouse CI
91+
run: |
92+
export GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }}
93+
yarn lhci autorun --verbose
94+
continue-on-error: true
95+
96+
- name: Ensure Lighthouse Reports Exist
97+
run: |
98+
if [ ! -d ".lighthouseci" ] || [ -z "$(ls -A .lighthouseci)" ]; then
99+
echo "⚠️ No Lighthouse results found. Generating an empty report..."
100+
mkdir -p .lighthouseci
101+
echo "[]" > .lighthouseci/assertion-results.json
102+
fi
103+
104+
- name: Verify Lighthouse Results
105+
run: |
106+
if [ ! -d ".lighthouseci" ] || [ -z "$(ls -A .lighthouseci)" ]; then
107+
echo "❌ Lighthouse CI did not generate reports."
108+
exit 1
109+
fi
110+
111+
- name: Post Lighthouse Results into comment
112+
run: |
113+
# Validate if empty
114+
if [ ! -s .lighthouseci/assertion-results.json ]; then
115+
echo "❌ No assertion results found. Skipping PR comment."
116+
exit 0 #Prevents failure
117+
fi
118+
119+
# Ensure JSON is properly formatted
120+
if ! jq empty .lighthouseci/assertion-results.json; then
121+
echo "❌ Invalid JSON format in Lighthouse assertion results."
122+
cat .lighthouseci/assertion-results.json # Print for debugging
123+
exit 1
124+
fi
125+
126+
BASELINE=$(cat ./baselines/lighthouse_baseline.json)
127+
128+
FAILURES=$(jq --argjson baseline "$BASELINE" -r '[.[] | select(.passed==false) | {metric: .auditId, expected: ($baseline[(.url | sub("^.*?//[^/]+"; ""))][.auditId] // "N/A"), actual: (if .actual then (.actual | floor) else "N/A" end), url: .url}]' .lighthouseci/assertion-results.json)
129+
130+
UNIQUE_FAILURE_URLS=$(echo "$FAILURES" | jq '[.[] | .url] | unique')
131+
132+
if [ ! -f ".lighthouseci/links.json" ]; then
133+
echo "⚠️ No .lighthouseci/links.json file found. Creating an empty JSON object..."
134+
echo "{}" > .lighthouseci/links.json
135+
fi
136+
137+
# Load the URL to report mapping from links.json
138+
URL_REPORT_MAP=$(jq -c '.' .lighthouseci/links.json)
139+
140+
# Append report URLs to failed assertions
141+
FAILURES_WITH_REPORTS=$(jq --argjson url_report_map "$URL_REPORT_MAP" '
142+
map(. + {reportUrl: $url_report_map[.url]})
143+
' <<< "$FAILURES")
144+
145+
# Check if there are failures before posting a comment
146+
if [[ "$FAILURES_WITH_REPORTS" == "[]" ]]; then
147+
echo "✅ **All Lighthouse metrics passed!** 🎉"
148+
exit 0
149+
fi
150+
151+
COMMENT="### ⚡ Lighthouse CI Performance Issues ⚡
152+
153+
| Metric | Expected Value | Current Value | Page URL | Report |
154+
|--------|---------------|--------------|----------|--------|"
155+
156+
while IFS= read -r line; do
157+
COMMENT+="\n| $(echo "$line" | jq -r '.metric') | $(echo "$line" | jq -r '.expected') | $(echo "$line" | jq -r '.actual') | $(echo "$line" | jq -r '.url') | [Report]($(echo "$line" | jq -r '.reportUrl')) |"
158+
done <<< "$(echo "$FAILURES_WITH_REPORTS" | jq -c '.[]')"
159+
160+
echo -e "$COMMENT" > comment.txt
161+
162+
gh pr comment ${{ github.event.pull_request.number }} --body "$(cat comment.txt)"
163+
continue-on-error: true
164+
env:
165+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
166+
167+
- name: Cleanup Lighthouse Reports
168+
run: rm -f comment.txt && rm -rf .lighthouseci

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,3 +75,7 @@ snapshots.js
7575

7676
# Ignore the generated antlr files
7777
/src/plugins/data/public/antlr/**/grammar/.antlr/
78+
79+
# Ignore the lighthousereport generatated
80+
.lighthouserc.js
81+
.lhci_output.json

.lighthouserc.js

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
/*
2+
* Copyright OpenSearch Contributors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
const fs = require('fs');
7+
8+
const baseline = JSON.parse(fs.readFileSync('baselines/lighthouse_baseline.json', 'utf8'));
9+
10+
const baseUrl = 'http://localhost:5601';
11+
12+
module.exports = {
13+
ci: {
14+
collect: {
15+
url: [
16+
`${baseUrl}/app/home`,
17+
`${baseUrl}/app/dashboards#/view/722b74f0-b882-11e8-a6d9-e546fe2bba5f`,
18+
`${baseUrl}/app/data-explorer/discover`,
19+
`${baseUrl}/app/visualize`,
20+
], // Add more URLs as needed
21+
startServerCommand: 'yarn start --no-base-path',
22+
numberOfRuns: 1,
23+
settings: {
24+
chromePath: require('puppeteer').executablePath(),
25+
chromeFlags: '--no-sandbox --disable-gpu --headless',
26+
formFactor: 'desktop', // This will enforce the desktop view
27+
viewport: {
28+
width: 1280, // Optional: Set a specific width
29+
height: 800, // Optional: Set a specific height
30+
},
31+
screenEmulation: {
32+
// Disable mobile emulation
33+
disabled: true,
34+
},
35+
},
36+
},
37+
assert: {
38+
assertMatrix: [
39+
{
40+
matchingUrlPattern: '/app/home',
41+
assertions: {
42+
'first-contentful-paint': [
43+
'warn',
44+
{
45+
maxNumericValue: baseline['/app/home']['first-contentful-paint'],
46+
},
47+
],
48+
'speed-index': ['warn', { maxNumericValue: baseline['/app/home']['speed-index'] }],
49+
},
50+
},
51+
{
52+
matchingUrlPattern: '/app/data-explorer/discover',
53+
assertions: {
54+
'first-contentful-paint': [
55+
'warn',
56+
{
57+
maxNumericValue: baseline['/app/data-explorer/discover']['first-contentful-paint'],
58+
},
59+
],
60+
'speed-index': [
61+
'warn',
62+
{ maxNumericValue: baseline['/app/data-explorer/discover']['speed-index'] },
63+
],
64+
},
65+
},
66+
{
67+
matchingUrlPattern: '/app/visualize',
68+
assertions: {
69+
'first-contentful-paint': [
70+
'warn',
71+
{
72+
maxNumericValue: baseline['/app/visualize']['first-contentful-paint'],
73+
},
74+
],
75+
'speed-index': ['warn', { maxNumericValue: baseline['/app/visualize']['speed-index'] }],
76+
},
77+
},
78+
{
79+
matchingUrlPattern: '/app/dashboards',
80+
assertions: {
81+
'first-contentful-paint': [
82+
'warn',
83+
{
84+
maxNumericValue: baseline['/app/dashboards']['first-contentful-paint'],
85+
},
86+
],
87+
'speed-index': [
88+
'warn',
89+
{ maxNumericValue: baseline['/app/dashboards']['speed-index'] },
90+
],
91+
},
92+
},
93+
],
94+
},
95+
},
96+
upload: {
97+
target: 'temporary-public-storage', // Required for GitHub integration
98+
githubStatusCheck: false,
99+
},
100+
};

baselines/lighthouse_baseline.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"/app/home": {
3+
"first-contentful-paint": 1800,
4+
"speed-index": 15000
5+
},
6+
"/app/data-explorer/discover": {
7+
"first-contentful-paint": 1800,
8+
"speed-index": 20000
9+
},
10+
"/app/dashboards": {
11+
"first-contentful-paint": 1800,
12+
"speed-index": 24000
13+
},
14+
"/app/visualize": {
15+
"first-contentful-paint": 1800,
16+
"speed-index": 22000
17+
}
18+
}

changelogs/fragments/9304.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
feat:
2+
- Lighthouse Page Performance Metrics CI workflow ([#9304](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/9304))

config/opensearch_dashboards.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -372,10 +372,10 @@
372372

373373
# Set the backend roles in groups or users, whoever has the backend roles or exactly match the user ids defined in this config will be regard as dashboard admin.
374374
# Dashboard admin will have the access to all the workspaces(workspace.enabled: true) and objects inside OpenSearch Dashboards.
375-
# The default config is [], and no one will be dashboard admin.
375+
# The default config is [], and no one will be dashboard admin.
376376
# If the user config is set to wildcard ["*"], anyone will be dashboard admin.
377377
# opensearchDashboards.dashboardAdmin.groups: ["dashboard_admin"]
378378
# opensearchDashboards.dashboardAdmin.users: ["dashboard_admin"]
379379

380380
# Set the value to true to enable the new UI for savedQueries in Discover
381-
# data.savedQueriesNewUI.enabled: true
381+
# data.savedQueriesNewUI.enabled: true

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,7 @@
281281
"@elastic/eslint-plugin-eui": "0.0.2",
282282
"@elastic/makelogs": "^6.1.0",
283283
"@faker-js/faker": "^7.6.0",
284+
"@lhci/cli": "^0.14.0",
284285
"@microsoft/api-documenter": "^7.13.78",
285286
"@microsoft/api-extractor": "^7.19.3",
286287
"@osd/babel-preset": "1.0.0",
@@ -476,6 +477,7 @@
476477
"postcss": "^8.4.31",
477478
"prettier": "^2.1.1",
478479
"prop-types": "^15.7.2",
480+
"puppeteer": "^24.1.1",
479481
"react": "^16.14.0",
480482
"react-grid-layout": "^0.16.2",
481483
"react-markdown": "^4.3.1",
@@ -511,6 +513,7 @@
511513
"vega-schema-url-parser": "^2.1.0",
512514
"vega-tooltip": "^0.30.0",
513515
"vinyl-fs": "^3.0.3",
516+
"wait-on": "^8.0.2",
514517
"xml2js": "^0.5.0",
515518
"xmlbuilder": "13.0.2",
516519
"zlib": "^1.0.5"

0 commit comments

Comments
 (0)