Skip to content

Commit bfab2a3

Browse files
brianseederskibanamachine
authored andcommitted
[CI] Build and publish storybooks (#87701)
1 parent fbe6778 commit bfab2a3

12 files changed

Lines changed: 171 additions & 9 deletions

File tree

.ci/.storybook/main.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License
4+
* 2.0 and the Server Side Public License, v 1; you may not use this file except
5+
* in compliance with, at your election, the Elastic License 2.0 or the Server
6+
* Side Public License, v 1.
7+
*/
8+
9+
const config = require('@kbn/storybook').defaultConfig;
10+
const aliases = require('../../src/dev/storybook/aliases.ts').storybookAliases;
11+
12+
config.refs = {};
13+
14+
for (const alias of Object.keys(aliases).filter((a) => a !== 'ci_composite')) {
15+
// snake_case -> Title Case
16+
const title = alias
17+
.replace(/_/g, ' ')
18+
.split(' ')
19+
.map((n) => n[0].toUpperCase() + n.slice(1))
20+
.join(' ');
21+
22+
config.refs[alias] = {
23+
title: title,
24+
url: `${process.env.STORYBOOK_BASE_URL}/${alias}`,
25+
};
26+
}
27+
28+
module.exports = config;

.eslintignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ node_modules
1515
target
1616
snapshots.js
1717

18+
!/.ci
1819
!/.eslintrc.js
1920
!.storybook
2021

packages/kbn-storybook/lib/default_config.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,11 @@ export const defaultConfig: StorybookConfig = {
1414
typescript: {
1515
reactDocgen: false,
1616
},
17+
webpackFinal: (config, options) => {
18+
if (process.env.CI) {
19+
config.parallelism = 4;
20+
config.cache = true;
21+
}
22+
return config;
23+
},
1724
};

packages/kbn-storybook/lib/templates/index.ejs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@
1616

1717
<!-- Added for Kibana shared dependencies -->
1818
<script>
19-
window.__kbnPublicPath__ = { 'kbn-ui-shared-deps': '/' };
19+
window.__kbnPublicPath__ = { 'kbn-ui-shared-deps': '.' };
2020
</script>
21-
<script src="/kbn-ui-shared-deps.@elastic.js"></script>
22-
<script src="/kbn-ui-shared-deps.js"></script>
23-
<link href="/kbn-ui-shared-deps.css" rel="stylesheet" />
24-
<link href="/kbn-ui-shared-deps.v7.light.css" rel="stylesheet" />
21+
<script src="kbn-ui-shared-deps.@elastic.js"></script>
22+
<script src="kbn-ui-shared-deps.js"></script>
23+
<link href="kbn-ui-shared-deps.css" rel="stylesheet" />
24+
<link href="kbn-ui-shared-deps.v7.light.css" rel="stylesheet" />
2525
<!-- -->
2626

2727
<% if (typeof headHtmlSnippet !== 'undefined') { %> <%= headHtmlSnippet %> <% } %> <%

src/dev/storybook/aliases.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@
66
* Side Public License, v 1.
77
*/
88

9+
// Please also add new aliases to test/scripts/jenkins_storybook.sh
910
export const storybookAliases = {
1011
apm: 'x-pack/plugins/apm/.storybook',
1112
canvas: 'x-pack/plugins/canvas/storybook',
1213
codeeditor: 'src/plugins/kibana_react/public/code_editor/.storybook',
14+
ci_composite: '.ci/.storybook',
1315
url_template_editor: 'src/plugins/kibana_react/public/url_template_editor/.storybook',
1416
dashboard: 'src/plugins/dashboard/.storybook',
1517
dashboard_enhanced: 'x-pack/plugins/dashboard_enhanced/.storybook',

test/scripts/jenkins_storybook.sh

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#!/usr/bin/env bash
2+
3+
source src/dev/ci_setup/setup_env.sh
4+
5+
cd "$XPACK_DIR/plugins/canvas"
6+
node scripts/storybook --dll
7+
8+
cd "$KIBANA_DIR"
9+
10+
# yarn storybook --site apm # TODO re-enable after being fixed
11+
yarn storybook --site canvas
12+
yarn storybook --site ci_composite
13+
yarn storybook --site url_template_editor
14+
yarn storybook --site codeeditor
15+
yarn storybook --site dashboard
16+
yarn storybook --site dashboard_enhanced
17+
yarn storybook --site data_enhanced
18+
yarn storybook --site embeddable
19+
yarn storybook --site infra
20+
yarn storybook --site security_solution
21+
yarn storybook --site ui_actions_enhanced
22+
yarn storybook --site observability
23+
yarn storybook --site presentation

vars/githubCommitStatus.groovy

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,15 @@ def trackBuild(commit, context, Closure closure) {
4141
}
4242

4343
// state: error|failure|pending|success
44-
def create(sha, state, description, context) {
44+
def create(sha, state, description, context, targetUrl = null) {
45+
targetUrl = targetUrl ?: env.BUILD_URL
46+
4547
withGithubCredentials {
4648
return githubApi.post("repos/elastic/kibana/statuses/${sha}", [
4749
state: state,
4850
description: description,
4951
context: context,
50-
target_url: env.BUILD_URL
52+
target_url: targetUrl.toString()
5153
])
5254
}
5355
}

vars/githubPr.groovy

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,26 +169,34 @@ def getNextCommentMessage(previousCommentInfo = [:], isFinal = false) {
169169
? getBuildStatusIncludingMetrics()
170170
: buildUtils.getBuildStatus()
171171

172+
def storybooksUrl = buildState.get('storybooksUrl')
173+
def storybooksMessage = storybooksUrl ? "* [Storybooks Preview](${storybooksUrl})" : "* Storybooks not built"
174+
172175
if (!isFinal) {
176+
storybooksMessage = storybooksUrl ? storybooksMessage : "* Storybooks not built yet"
177+
173178
def failuresPart = status != 'SUCCESS' ? ', with failures' : ''
174179
messages << """
175180
## :hourglass_flowing_sand: Build in-progress${failuresPart}
176181
* [continuous-integration/kibana-ci/pull-request](${env.BUILD_URL})
177182
* Commit: ${getCommitHash()}
183+
${storybooksMessage}
178184
* This comment will update when the build is complete
179185
"""
180186
} else if (status == 'SUCCESS') {
181187
messages << """
182188
## :green_heart: Build Succeeded
183189
* [continuous-integration/kibana-ci/pull-request](${env.BUILD_URL})
184190
* Commit: ${getCommitHash()}
191+
${storybooksMessage}
185192
${getDocsChangesLink()}
186193
"""
187194
} else if(status == 'UNSTABLE') {
188195
def message = """
189196
## :yellow_heart: Build succeeded, but was flaky
190197
* [continuous-integration/kibana-ci/pull-request](${env.BUILD_URL})
191198
* Commit: ${getCommitHash()}
199+
${storybooksMessage}
192200
${getDocsChangesLink()}
193201
""".stripIndent()
194202

@@ -204,6 +212,7 @@ def getNextCommentMessage(previousCommentInfo = [:], isFinal = false) {
204212
## :broken_heart: Build Failed
205213
* [continuous-integration/kibana-ci/pull-request](${env.BUILD_URL})
206214
* Commit: ${getCommitHash()}
215+
${storybooksMessage}
207216
* [Pipeline Steps](${env.BUILD_URL}flowGraphTable) (look for red circles / failed steps)
208217
* [Interpreting CI Failures](https://www.elastic.co/guide/en/kibana/current/interpreting-ci-failures.html)
209218
${getDocsChangesLink()}

vars/kibanaPipeline.groovy

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,7 @@ def allCiTasks() {
443443
tasks.test()
444444
tasks.functionalOss()
445445
tasks.functionalXpack()
446+
tasks.storybooksCi()
446447
}
447448
},
448449
jest: {

vars/storybooks.groovy

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
def getStorybooksBucket() {
2+
return "ci-artifacts.kibana.dev/storybooks"
3+
}
4+
5+
def getDestinationDir() {
6+
return env.ghprbPullId ? "pr-${env.ghprbPullId}" : buildState.get('checkoutInfo').branch.replace("/", "__")
7+
}
8+
9+
def getUrl() {
10+
return "https://${getStorybooksBucket()}/${getDestinationDir()}"
11+
}
12+
13+
def getUrlLatest() {
14+
return "${getUrl()}/latest"
15+
}
16+
17+
def getUrlForCommit() {
18+
return "${getUrl()}/${buildState.get('checkoutInfo').commit}"
19+
}
20+
21+
def upload() {
22+
dir("built_assets/storybook") {
23+
sh "mv ci_composite composite"
24+
25+
def storybooks = sh(
26+
script: 'ls -1d */',
27+
returnStdout: true
28+
).trim()
29+
.split('\n')
30+
.collect { it.replace('/', '') }
31+
.findAll { it != 'composite' }
32+
33+
def listHtml = storybooks.collect { """<li><a href="${getUrlForCommit()}/${it}">${it}</a></li>""" }.join("\n")
34+
35+
def html = """
36+
<html>
37+
<body>
38+
<h1>Storybooks</h1>
39+
<p><a href="${getUrlForCommit()}/composite">Composite Storybook</a></p>
40+
<h2>All</h2>
41+
<ul>
42+
${listHtml}
43+
</ul>
44+
</body>
45+
</html>
46+
"""
47+
48+
writeFile(file: 'index.html', text: html)
49+
50+
withGcpServiceAccount.fromVaultSecret('secret/kibana-issues/dev/ci-artifacts-key', 'value') {
51+
kibanaPipeline.bash("""
52+
gsutil -q -m cp -r -z js,css,html,json,map,txt,svg '*' 'gs://${getStorybooksBucket()}/${getDestinationDir()}/${buildState.get('checkoutInfo').commit}/'
53+
gsutil -h "Cache-Control:no-cache, max-age=0, no-transform" cp -z html 'index.html' 'gs://${getStorybooksBucket()}/${getDestinationDir()}/latest/'
54+
""", "Upload Storybooks to GCS")
55+
}
56+
57+
buildState.set('storybooksUrl', getUrlForCommit())
58+
}
59+
}
60+
61+
def build() {
62+
withEnv(["STORYBOOK_BASE_URL=${getUrlForCommit()}"]) {
63+
kibanaPipeline.bash('test/scripts/jenkins_storybook.sh', 'Build Storybooks')
64+
}
65+
}
66+
67+
def buildAndUpload() {
68+
def sha = buildState.get('checkoutInfo').commit
69+
def context = 'Build and Publish Storybooks'
70+
71+
githubCommitStatus.create(sha, 'pending', 'Building Storybooks', context)
72+
73+
try {
74+
build()
75+
upload()
76+
githubCommitStatus.create(sha, 'success', 'Storybooks built', context, getUrlForCommit())
77+
} catch(ex) {
78+
githubCommitStatus.create(sha, 'error', 'Building Storybooks failed', context)
79+
throw ex
80+
}
81+
}
82+
83+
return this

0 commit comments

Comments
 (0)