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>
This commit is contained in:
Ruchi Sharma 2025-03-20 13:28:34 -07:00 committed by GitHub
parent 14813de5f0
commit 6cf85af7b8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 1592 additions and 38 deletions

View File

@ -38,6 +38,6 @@ jobs:
with:
github_token: ${{ steps.github_app_token.outputs.token }}
head_template: backport/backport-<%= number %>-to-<%= base %>
files_to_skip: "CHANGELOG.md"
files_to_skip: 'CHANGELOG.md'
labels_template: "<%= JSON.stringify([...labels, 'autocut']) %>"
failure_labels: "failed backport"
failure_labels: 'failed backport'

View File

@ -111,7 +111,7 @@ jobs:
'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' ||
'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' }}
OPENSEARCH_SNAPSHOT_CMD: ${{ matrix.config == 'query_enhanced' &&
'/bin/bash -c "./opensearch-2.17.0/opensearch-tar-install.sh &"' ||
'/bin/bash -c "./opensearch-${{ env.LATEST_VERSION }}/opensearch-tar-install.sh &"' ||
matrix.config == 'dashboard' &&
'node scripts/opensearch snapshot -E cluster.routing.allocation.disk.threshold_enabled=false' ||
'node ../scripts/opensearch snapshot -E cluster.routing.allocation.disk.threshold_enabled=false' }}
@ -247,7 +247,7 @@ jobs:
- name: Run OpenSearch
if: matrix.config == 'query_enhanced'
run: |
/bin/bash -c "./opensearch-2.17.0/opensearch-tar-install.sh &"
/bin/bash -c "./opensearch-${{ env.LATEST_VERSION }}/opensearch-tar-install.sh &"
sleep 30
shell: bash

168
.github/workflows/lighthouse_testing.yml vendored Normal file
View File

@ -0,0 +1,168 @@
name: Lighthouse Testing
on:
pull_request:
branches:
- main
permissions:
contents: read
pull-requests: write
statuses: write
issues: write
env:
NODE_OPTIONS: '--max-old-space-size=6144 --dns-result-order=ipv4first'
LATEST_VERSION: '2.17.0'
jobs:
lighthouse:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Setup Node
uses: actions/setup-node@v2
with:
node-version-file: '.nvmrc'
registry-url: 'https://registry.npmjs.org'
- name: Setup Yarn
run: |
npm uninstall -g yarn
npm i -g yarn@1.22.10
- name: Run bootstrap
run: yarn osd bootstrap
- name: Download OpenSearch
uses: suisei-cn/actions-download-file@v1.4.0
with:
url: https://artifacts.opensearch.org/releases/bundle/opensearch/${{ env.LATEST_VERSION }}/opensearch-${{ env.LATEST_VERSION }}-linux-x64.tar.gz
- name: Extract OpenSearch
run: |
tar -xzf opensearch-*.tar.gz
rm -f opensearch-*.tar.gz
shell: bash
- name: Remove security plugin
run: |
/bin/bash -c "yes | ./opensearch-${{ env.LATEST_VERSION }}/bin/opensearch-plugin remove opensearch-security"
shell: bash
- name: Run OpenSearch
run: |
/bin/bash -c "./opensearch-${{ env.LATEST_VERSION }}/opensearch-tar-install.sh &"
sleep 30
shell: bash
- name: Install Lighthouse CI
run: yarn add --dev @lhci/cli
- name: Run bootstrap
run: yarn osd bootstrap
- name: Build plugins
run: node scripts/build_opensearch_dashboards_platform_plugins --no-examples --workers 12
- name: Wait for OpenSearch to be ready
run: |
until curl -s http://localhost:9200 >/dev/null; do
echo "Waiting for OpenSearch..."
sleep 10
done
echo "OpenSearch is up!"
- name: Start OpenSearch Dashboards
run: |
yarn start --no-base-path &
until curl -s http://localhost:5601 >/dev/null; do
echo "Waiting for OpenSearch Dashboards..."
sleep 10
done
echo "OpenSearch Dashboards is up!"
- name: Mock data
run: |
curl 'http://localhost:5601/api/sample_data/ecommerce' -X 'POST' -H 'osd-version: ${{ env.VERSION }}' -H 'osd-xsrf: osd-fetch'
- name: Run Lighthouse CI
run: |
export GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }}
yarn lhci autorun --verbose
continue-on-error: true
- name: Ensure Lighthouse Reports Exist
run: |
if [ ! -d ".lighthouseci" ] || [ -z "$(ls -A .lighthouseci)" ]; then
echo "⚠️ No Lighthouse results found. Generating an empty report..."
mkdir -p .lighthouseci
echo "[]" > .lighthouseci/assertion-results.json
fi
- name: Verify Lighthouse Results
run: |
if [ ! -d ".lighthouseci" ] || [ -z "$(ls -A .lighthouseci)" ]; then
echo "❌ Lighthouse CI did not generate reports."
exit 1
fi
- name: Post Lighthouse Results into comment
run: |
# Validate if empty
if [ ! -s .lighthouseci/assertion-results.json ]; then
echo "❌ No assertion results found. Skipping PR comment."
exit 0 #Prevents failure
fi
# Ensure JSON is properly formatted
if ! jq empty .lighthouseci/assertion-results.json; then
echo "❌ Invalid JSON format in Lighthouse assertion results."
cat .lighthouseci/assertion-results.json # Print for debugging
exit 1
fi
BASELINE=$(cat ./baselines/lighthouse_baseline.json)
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)
UNIQUE_FAILURE_URLS=$(echo "$FAILURES" | jq '[.[] | .url] | unique')
if [ ! -f ".lighthouseci/links.json" ]; then
echo "⚠️ No .lighthouseci/links.json file found. Creating an empty JSON object..."
echo "{}" > .lighthouseci/links.json
fi
# Load the URL to report mapping from links.json
URL_REPORT_MAP=$(jq -c '.' .lighthouseci/links.json)
# Append report URLs to failed assertions
FAILURES_WITH_REPORTS=$(jq --argjson url_report_map "$URL_REPORT_MAP" '
map(. + {reportUrl: $url_report_map[.url]})
' <<< "$FAILURES")
# Check if there are failures before posting a comment
if [[ "$FAILURES_WITH_REPORTS" == "[]" ]]; then
echo "✅ **All Lighthouse metrics passed!** 🎉"
exit 0
fi
COMMENT="### ⚡ Lighthouse CI Performance Issues ⚡
| Metric | Expected Value | Current Value | Page URL | Report |
|--------|---------------|--------------|----------|--------|"
while IFS= read -r line; do
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')) |"
done <<< "$(echo "$FAILURES_WITH_REPORTS" | jq -c '.[]')"
echo -e "$COMMENT" > comment.txt
gh pr comment ${{ github.event.pull_request.number }} --body "$(cat comment.txt)"
continue-on-error: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Cleanup Lighthouse Reports
run: rm -f comment.txt && rm -rf .lighthouseci

4
.gitignore vendored
View File

@ -75,3 +75,7 @@ snapshots.js
# Ignore the generated antlr files
/src/plugins/data/public/antlr/**/grammar/.antlr/
# Ignore the lighthousereport generatated
.lighthouserc.js
.lhci_output.json

100
.lighthouserc.js Normal file
View File

@ -0,0 +1,100 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/
const fs = require('fs');
const baseline = JSON.parse(fs.readFileSync('baselines/lighthouse_baseline.json', 'utf8'));
const baseUrl = 'http://localhost:5601';
module.exports = {
ci: {
collect: {
url: [
`${baseUrl}/app/home`,
`${baseUrl}/app/dashboards#/view/722b74f0-b882-11e8-a6d9-e546fe2bba5f`,
`${baseUrl}/app/data-explorer/discover`,
`${baseUrl}/app/visualize`,
], // Add more URLs as needed
startServerCommand: 'yarn start --no-base-path',
numberOfRuns: 1,
settings: {
chromePath: require('puppeteer').executablePath(),
chromeFlags: '--no-sandbox --disable-gpu --headless',
formFactor: 'desktop', // This will enforce the desktop view
viewport: {
width: 1280, // Optional: Set a specific width
height: 800, // Optional: Set a specific height
},
screenEmulation: {
// Disable mobile emulation
disabled: true,
},
},
},
assert: {
assertMatrix: [
{
matchingUrlPattern: '/app/home',
assertions: {
'first-contentful-paint': [
'warn',
{
maxNumericValue: baseline['/app/home']['first-contentful-paint'],
},
],
'speed-index': ['warn', { maxNumericValue: baseline['/app/home']['speed-index'] }],
},
},
{
matchingUrlPattern: '/app/data-explorer/discover',
assertions: {
'first-contentful-paint': [
'warn',
{
maxNumericValue: baseline['/app/data-explorer/discover']['first-contentful-paint'],
},
],
'speed-index': [
'warn',
{ maxNumericValue: baseline['/app/data-explorer/discover']['speed-index'] },
],
},
},
{
matchingUrlPattern: '/app/visualize',
assertions: {
'first-contentful-paint': [
'warn',
{
maxNumericValue: baseline['/app/visualize']['first-contentful-paint'],
},
],
'speed-index': ['warn', { maxNumericValue: baseline['/app/visualize']['speed-index'] }],
},
},
{
matchingUrlPattern: '/app/dashboards',
assertions: {
'first-contentful-paint': [
'warn',
{
maxNumericValue: baseline['/app/dashboards']['first-contentful-paint'],
},
],
'speed-index': [
'warn',
{ maxNumericValue: baseline['/app/dashboards']['speed-index'] },
],
},
},
],
},
},
upload: {
target: 'temporary-public-storage', // Required for GitHub integration
githubStatusCheck: false,
},
};

View File

@ -0,0 +1,18 @@
{
"/app/home": {
"first-contentful-paint": 1800,
"speed-index": 15000
},
"/app/data-explorer/discover": {
"first-contentful-paint": 1800,
"speed-index": 20000
},
"/app/dashboards": {
"first-contentful-paint": 1800,
"speed-index": 24000
},
"/app/visualize": {
"first-contentful-paint": 1800,
"speed-index": 22000
}
}

View File

@ -0,0 +1,2 @@
feat:
- Lighthouse Page Performance Metrics CI workflow ([#9304](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/9304))

View File

@ -372,10 +372,10 @@
# 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.
# Dashboard admin will have the access to all the workspaces(workspace.enabled: true) and objects inside OpenSearch Dashboards.
# The default config is [], and no one will be dashboard admin.
# The default config is [], and no one will be dashboard admin.
# If the user config is set to wildcard ["*"], anyone will be dashboard admin.
# opensearchDashboards.dashboardAdmin.groups: ["dashboard_admin"]
# opensearchDashboards.dashboardAdmin.users: ["dashboard_admin"]
# Set the value to true to enable the new UI for savedQueries in Discover
# data.savedQueriesNewUI.enabled: true
# data.savedQueriesNewUI.enabled: true

View File

@ -281,6 +281,7 @@
"@elastic/eslint-plugin-eui": "0.0.2",
"@elastic/makelogs": "^6.1.0",
"@faker-js/faker": "^7.6.0",
"@lhci/cli": "^0.14.0",
"@microsoft/api-documenter": "^7.13.78",
"@microsoft/api-extractor": "^7.19.3",
"@osd/babel-preset": "1.0.0",
@ -476,6 +477,7 @@
"postcss": "^8.4.31",
"prettier": "^2.1.1",
"prop-types": "^15.7.2",
"puppeteer": "^24.1.1",
"react": "^16.14.0",
"react-grid-layout": "^0.16.2",
"react-markdown": "^4.3.1",
@ -511,6 +513,7 @@
"vega-schema-url-parser": "^2.1.0",
"vega-tooltip": "^0.30.0",
"vinyl-fs": "^3.0.3",
"wait-on": "^8.0.2",
"xml2js": "^0.5.0",
"xmlbuilder": "13.0.2",
"zlib": "^1.0.5"

1323
yarn.lock

File diff suppressed because it is too large Load Diff