Skip to content

svelte-build

Builds a project's Svelte/Vite frontend bundle(s) and exposes them as a job artifact, so the release job can embed the real UI.

Only for projects that don't use go:generate

Go projects that embed a Svelte UI via a //go:generate build-web.sh directive (run by goreleaser's go generate before-hook) already build the bundle there — using svelte-build too would double-build at tag. See Explanation: the Svelte frontend track for the full go:generate-vs-svelte-build decision. This component is for projects that don't have that hook.

For projects that do use it: the artifact-handoff pattern is goreleaser: needs: [{ job: svelte-build, artifacts: true }] — handing goreleaser a prebuilt artifact is cleaner and cacheable than a goreleaser before.hooks entry that couples the npm build into every consumer's .goreleaser.yaml.

Runs on node-tools (Node 24 + corepack). MR-gated for build visibility and tag-gated to feed goreleaser.

The two are separate rules, deliberately. The release rule carries no changes: at all, per spec 0029 D1 — "deploy/release/schedule rules stay unfiltered". A tag pipeline has no diff, so a change filter there is always-true: it reads as a filter and filters nothing. Splitting the rules states the behaviour instead of inheriting it from a GitLab quirk, which matters now that goreleaser takes a hard needs: [svelte-build].

paths is required (no default) — a space-separated list of frontend root(s); every consumer states its own. Each root builds independently.

Jobs

Job What it runs
svelte-build Per path: npm ci && npm run $[[ inputs.build_script ]]. Artifacts every **/$[[ inputs.output_dir ]] directory (node_modules excluded), preserving its path so the release job's artifact download lands the bundle back at <root>/<output_dir>.

Inputs

Input Type Default Description
image string node-tools:v0.1.0 Image with Node + npm.
stage string build GitLab CI stage.
paths string (required) Space-separated frontend root(s).
build_script string "build" npm script run in each path.
output_dir string "embed" Build output directory name (vite outDir) under each root. Matches the go:embed convention (pkg/studio/web/embed).
if string '$CI_PIPELINE_SOURCE == "merge_request_event" || $CI_COMMIT_TAG' Gating rules:if:. MR pipelines (visibility) + release tags (feed goreleaser). Gates both rules, so narrowing it removes tag builds too.
ignore_install_scripts string "true" Blocks npm lifecycle scripts during dependency installation, via the npm_config_ignore_scripts job variable so every install in the job inherits it. Set "false" only if a dependency needs its install hook (a native module that compiles on install); the project's own prebuild/postbuild are unaffected. See spec 0069.
changes array ["**/*.svelte", "**/*.ts", "**/*.js", "**/*.css", "**/*.html", "**/package.json", "**/package-lock.json", "**/vite.config.*", "**/svelte.config.*", "**/tsconfig*.json", ".gitlab-ci.yml"] Change-detection paths. Applied to the merge-request rule only; the release rule is unfiltered.

Usage

include:
  - component: gitlab.com/phpboyscout/cicd/[email protected]
    inputs:
      paths: "pkg/studio/web"
      stage: build

goreleaser:
  needs:
    - job: svelte-build
      artifacts: true

See also