I am trying to use Gitlab CI to build and host a storybook page when I push an update to any branch. Here is the current CI script:
image: node:16
stages:
- setup
- build-and-test
- deployment
- pages
# stage: setup
setup:
stage: setup
cache:
key: ${CI_COMMIT_REF_SLUG}
paths:
- node_modules/
artifacts:
paths:
- node_modules/
script:
- yarn
# stage: build-and-test (here I run linter, unit tests, and everything I want to build or test)
build:
stage: build-and-test
artifacts:
paths:
- dist/
script:
- yarn build
storybook:
stage: build-and-test
artifacts:
expire_in: 2 weeks
when: always
paths:
- storybook/
script:
- yarn build-storybook --output-dir storybook
# stage: deployment (here I deploy my app to specific stages or other artefacts like storybook)
deploy-storybook:
stage: deployment
script:
- echo "Enjoy the day. 🥳 Every job needs a script, but this job was just created to configure an environment."
environment:
name: storybook/$CI_COMMIT_REF_SLUG
url: https://<my_username>.gitlab.io/<my_project>/$CI_COMMIT_REF_SLUG/storybook/
on_stop: remove-storybook
only:
- branches
remove-storybook:
stage: deployment
cache:
key: 'my-storybook'
paths:
- public
script:
- rm -rf "public/$CI_COMMIT_REF_SLUG/storybook"
when: manual
variables:
GIT_STRATEGY: none # needed to prevent "Couldn't find remote ref" error
environment:
name: storybook/$CI_COMMIT_REF_SLUG
action: stop
# stage: pages (the stage name is custom, but the job NEEDS to be named pages)
pages:
stage: pages
cache:
key: 'my-storybook'
paths:
- public
script:
- if [ "$CI_COMMIT_REF_NAME" = "main" ]; then
mkdir -p public;
touch public/index.html;
echo "<!DOCTYPE HTML><script>window.location.href = 'https://<my_username>.gitlab.io/<my_project>/main/storybook'</script>" > public/index.html;
fi;
- rm -rf "public/$CI_COMMIT_REF_SLUG"
- mkdir -p "public/$CI_COMMIT_REF_SLUG";
- mv storybook "public/$CI_COMMIT_REF_SLUG"
artifacts:
paths:
- public
This compiles as intended but has errors in console when viewed:
iframe.html:1 Access to script at 'https://gitlab.com/oauth/authorize?client_id=<my_client_id>&redirect_uri=https://projects.gitlab.io/auth&response_type=code&state=AFyDa1QTpsd9qXqSzdoy4w==&scope=api' (redirected from 'https://<my_username>.gitlab.io/assets/iframe.8696a5de.js') from origin 'https://<my_username>.gitlab.io' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
iframe.html:374 GET https://gitlab.com/oauth/authorize?client_id=<my_client_id>&redirect_uri=https://projects.gitlab.io/auth&response_type=code&state=AFyDa1QTpsd9qXqSzdoy4w==&scope=api net::ERR_FAILED 302
The relevant section of https://<my_username>.gitlab.io/<project_name>/<branch>/storybook/assets/iframe.html
:
<head>
...
<script defer src="/node_modules/@fortawesome/fontawesome-free/js/all.min.js"></script>
<!-- iframe.html:374 -->
<script type="module" crossorigin src="/assets/iframe.8696a5de.js"></script>
<link rel="stylesheet" href="/assets/iframe.0f83afa4.css">
...
</head>
.storybook/main.cjs
const { resolve } = require("path");
const { typescript: preprocessTS } = require("svelte-preprocess");
const { loadConfigFromFile, mergeConfig } = require("vite");
module.exports = {
"stories": [
"../src/**/*.stories.mdx",
"../src/**/*.stories.@(js|jsx|ts|tsx|svelte)"
],
"addons": [
"@storybook/addon-links",
"@storybook/addon-essentials",
"@storybook/addon-interactions",
"@storybook/addon-svelte-csf"
],
"framework": "@storybook/svelte",
"core": {
"builder": "@storybook/builder-vite"
},
"svelteOptions": {
"preprocess": import("../svelte.config.js").preprocess
},
svelteOptions: {
preprocess: [
preprocessTS(),
],
},
async viteFinal(config, { configType }) {
const { config: userConfig } = await loadConfigFromFile(
resolve(__dirname, "../vite.config.ts")
);
return mergeConfig(config, {
...userConfig,
// manually specify plugins to avoid conflict
plugins: []
});
}
}
What can I do to fix this script import error? I think the generated url in the script tag is wrong, and should instead be something similar to https://<my_username>.gitlab.io/<project_name>/<branch>/storybook/assets/iframe.8696a5de.js
(instead of the current https://<my_username>.gitlab.io/assets/iframe.8696a5de.js
). Is there any way I can edit the CI to edit the root URL?
If that would not work, why not, and what would work instead?
I have found a workaround but I would not consider it a proper solution. If you are stuck with this problem, the following does work:
I used Regular Expression replacement in the GitLab CI to correct the src
and href
paths of all links in the built index.html
and iframe.html
files. The exact code I used is as follows:
- sed -i -E "s/((src|href)=\")\/?/\1.\//g" public/$CI_COMMIT_REF_SLUG/storybook/index.html
- sed -i -E "s/((src|href)=\")\/?/\1.\//g" public/$CI_COMMIT_REF_SLUG/storybook/iframe.html
This change is necessary for 2 reasons:
<user>.gitlab.io/<repo>/
). Any links from this page starting in a slash will search for their resources at <user>.gitlab.io/
and the resource won't be there, but the system never gets that far (see below).The regex replacement fixes these problems by replacing any resource written as path/name.ext
or /path/name.ext
with ./path/name.ext
which in my case works and shall hopefully work for whoever needs this.