Skip to content

Commit

Permalink
Performance: Add Lighthouse CI (sourcegraph#25455)
Browse files Browse the repository at this point in the history
  • Loading branch information
umpox authored Oct 11, 2021
1 parent 48766f9 commit 88575ac
Show file tree
Hide file tree
Showing 9 changed files with 607 additions and 37 deletions.
36 changes: 32 additions & 4 deletions .buildkite/pipeline.async.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
env:
ENTERPRISE: "1"
MINIFY: "1"
FORCE_COLOR: "3"
ENTERPRISE: '1'
MINIFY: '1'
FORCE_COLOR: '3'

steps:
- command:
Expand All @@ -10,4 +10,32 @@ steps:
- yarn run cover-storybook
- yarn nyc report -r json
- bash <(curl -s https://codecov.io/bash) -c -F typescript -F storybook
label: ":storybook::codecov: Storybook coverage"
label: ':storybook::codecov: Storybook coverage'
- command:
- dev/ci/yarn-build.sh client/web
- dev/ci/create-client-artifact.sh
key: lighthouse:prep
label: ':lighthouse: Lighthouse production build'
env:
NODE_ENV: production
WEBPACK_SERVE_INDEX: 'true'
- command: dev/ci/yarn-lighthouse.sh homepage /
depends_on: lighthouse:prep
label: ':lighthouse: lighthouse:homepage'
env:
SOURCEGRAPH_API_URL: https://sourcegraph.com
- command: dev/ci/yarn-lighthouse.sh search_results /search?q=repo:sourcegraph/lighthouse-ci-test-repository+file:index.js
depends_on: lighthouse:prep
label: ':lighthouse: lighthouse:search_results'
env:
SOURCEGRAPH_API_URL: https://sourcegraph.com
- command: dev/ci/yarn-lighthouse.sh repository_page /github.com/sourcegraph/lighthouse-ci-test-repository
depends_on: lighthouse:prep
label: ':lighthouse: lighthouse:repository_page'
env:
SOURCEGRAPH_API_URL: https://sourcegraph.com
- command: dev/ci/yarn-lighthouse.sh file_blob /github.com/sourcegraph/lighthouse-ci-test-repository/-/blob/index.js
depends_on: lighthouse:prep
label: ':lighthouse: lighthouse:file_blob'
env:
SOURCEGRAPH_API_URL: https://sourcegraph.com
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -144,3 +144,6 @@ sg.config.overwrite.yaml
# Generated sitemaps are not committed, they're hosted in a GCS bucket.
sitemap/
sitemap_query.db

# Lighthouse CI reports
.lighthouseci/
10 changes: 8 additions & 2 deletions client/web/dev/server/production.server.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import chalk from 'chalk'
import compression from 'compression'
import historyApiFallback from 'connect-history-api-fallback'
import express, { RequestHandler } from 'express'
import { createProxyMiddleware } from 'http-proxy-middleware'
Expand All @@ -11,7 +12,9 @@ import {
environmentConfig,
getCSRFTokenAndCookie,
STATIC_ASSETS_PATH,
STATIC_INDEX_PATH,
WEB_SERVER_URL,
shouldCompressResponse,
} from '../utils'

const { SOURCEGRAPH_API_URL, SOURCEGRAPH_HTTPS_PORT } = environmentConfig
Expand All @@ -27,13 +30,13 @@ async function startProductionServer(): Promise<void> {

const app = express()

// Compress all HTTP responses
app.use(compression({ filter: shouldCompressResponse }))
// Serve index.html in place of any 404 responses.
app.use(historyApiFallback() as RequestHandler)
// Attach `CSRF_COOKIE_NAME` cookie to every response to avoid "CSRF token is invalid" API error.
app.use(getCSRFTokenCookieMiddleware(csrfCookieValue))

// Serve index.html.
app.use(express.static(STATIC_ASSETS_PATH))
// Serve build artifacts.
app.use('/.assets', express.static(STATIC_ASSETS_PATH))

Expand All @@ -49,6 +52,9 @@ async function startProductionServer(): Promise<void> {
)
)

// Redirect remaining routes to index.html
app.get('/*', (_request, response) => response.sendFile(STATIC_INDEX_PATH))

app.listen(SOURCEGRAPH_HTTPS_PORT, () => {
signale.success(`Production server is ready at ${chalk.blue.bold(WEB_SERVER_URL)}`)
})
Expand Down
1 change: 1 addition & 0 deletions client/web/dev/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import path from 'path'

export const ROOT_PATH = path.resolve(__dirname, '../../../../')
export const STATIC_ASSETS_PATH = path.resolve(ROOT_PATH, 'ui/assets')
export const STATIC_INDEX_PATH = path.resolve(STATIC_ASSETS_PATH, 'index.html')
export const STATIC_ASSETS_URL = '/.assets/'
export const DEV_SERVER_LISTEN_ADDR = { host: 'localhost', port: 3080 }
export const DEV_SERVER_PROXY_TARGET_ADDR = { host: 'localhost', port: 3081 }
Expand Down
24 changes: 24 additions & 0 deletions dev/ci/yarn-lighthouse.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/usr/bin/env bash

set -e

BASE_URL=http://localhost:3443
TEST_LABEL=$1
TEST_PATH=$2

# Store results on `main` so future branches can be compared against a baseline
[[ "$BUILDKITE_BRANCH" == "main" ]] && SHOULD_STORE_RESULTS='true' || SHOULD_STORE_RESULTS='false'

echo "--- Download pre-built client artifact"
buildkite-agent artifact download 'client.tar.gz' . --step 'lighthouse:prep'
tar -xf client.tar.gz -C .

echo "--- Yarn install in root"
# mutex is necessary since CI runs various yarn installs in parallel
NODE_ENV='' yarn --mutex network --frozen-lockfile --network-timeout 60000

echo "--- Collecting Lighthouse results"
yarn lhci collect --url="$BASE_URL$TEST_PATH"

echo "--- Uploading Lighthouse results"
yarn lhci upload --githubStatusContextSuffix="/$TEST_LABEL" --uploadUrlMap="$SHOULD_STORE_RESULTS"
13 changes: 13 additions & 0 deletions doc/dev/how-to/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,19 @@ Flakiness in snapshot tests can be caused by the search response time, order of

This can be solved with [Percy specific CSS](https://docs.percy.io/docs/percy-specific-css) that will be applied only when taking the snapshot and allow you to hide flaky elements with `display: none`. In simple cases, you can simply apply the `percy-hide` CSS class to the problematic element and it will be hidden from Percy.

### Lighthouse tests

We run Lighthouse performance tests through [Lighthouse CI](https://github.com/GoogleChrome/lighthouse-ci). These tests are relatively hands-off and run a series of Lighthouse audits against a deployed server. The flow for running these tests is:


#### Running the tests locally
1. Create a production bundle that can be served locally. `NODE_ENV=production WEBPACK_SERVE_INDEX=true yarn workspace @sourcegraph/web build`
2. Run the Lighthouse CI tests. `yarn test-lighthouse`. This will automatically serve the production bundle and start running audits through Puppeteer. Note: It's possible to provide different URLs or config through editing `lighthouserc.js` or by providing CLI flags to this command.

#### Running the tests in CI
The CI flow is quite similar to the local flow, the main difference is that we provide some additional flags to Lighthouse. We provide a specific URL for each parallel step, and we add some additional config to support reporting results back to GitHub PRs as status checks.


## Continuous Integration

The test suite is exercised on every pull request. For the moment CI output
Expand Down
30 changes: 30 additions & 0 deletions lighthouserc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// @ts-check

const config = {
ci: {
collect: {
// Note: We override this URL in CI through ./dev/ci/yarn-lighthouse.sh
url: 'http://localhost:3443/',
startServerCommand: 'yarn workspace @sourcegraph/web serve:prod',
settings: {
preset: 'desktop',
chromeFlags: '--no-sandbox',
// We skip a series of audits that are not currently supported by the local server
skipAudits: [
// SEO: Normally enabled dynamically for different paths in the production server
'meta-description',
// Best practices: HTTPS currently disabled in local server: https://github.com/sourcegraph/sourcegraph/issues/21869
'is-on-https',
'uses-http2',
// SEO: Robots.txt file isn't served locally
'robots-txt',
],
},
},
upload: {
target: 'temporary-public-storage',
},
},
}

module.exports = config
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"cover-integration:base": "nyc --hook-require=false yarn test-integration:base",
"cover-integration": "nyc --hook-require=false yarn test-integration",
"cover-browser-integration": "nyc --hook-require=false yarn --cwd client/browser test-integration",
"test-lighthouse": "SOURCEGRAPH_API_URL=https://sourcegraph.com lhci collect && lhci open",
"test-e2e": "TS_NODE_PROJECT=client/web/src/end-to-end/tsconfig.json mocha ./client/web/src/end-to-end/end-to-end.test.ts",
"cover-e2e": "nyc --hook-require=false --silent=true yarn test-e2e",
"storybook": "yarn workspace @sourcegraph/storybook run start",
Expand Down Expand Up @@ -108,6 +109,7 @@
"@graphql-codegen/typescript-operations": "1.17.8",
"@istanbuljs/nyc-config-typescript": "^1.0.1",
"@jest/types": "^27.0.6",
"@lhci/cli": "0.8.1",
"@mermaid-js/mermaid-cli": "^8.7.0",
"@octokit/rest": "^16.36.0",
"@peculiar/webcrypto": "^1.1.7",
Expand Down Expand Up @@ -228,6 +230,7 @@
"chromatic": "^5.5.0",
"chrome-webstore-upload-cli": "^1.2.0",
"command-exists": "^1.2.9",
"compression": "^1.7.4",
"connect-history-api-fallback": "^1.6.0",
"cross-env": "^7.0.2",
"css-loader": "^5.2.6",
Expand Down
Loading

0 comments on commit 88575ac

Please sign in to comment.