This document describes the continuous integration pipeline, automated testing, package preview system, and the release process for publishing new versions of Svelte to npm. For information about local development and testing, see Testing Infrastructure. For details on project structure and tooling, see Development Environment.
The Svelte repository uses GitHub Actions for continuous integration and automated releases. The CI/CD system performs:
CI Workflow Overview
Sources: .github/workflows/ci.yml1-116 .github/workflows/pkg.pr.new.yml1-236 .github/workflows/ecosystem-ci-trigger.yml1-144
The Tests job in .github/workflows/ci.yml14-45 uses a matrix strategy for cross-platform and cross-version testing:
| Job Name | Node Versions | Operating Systems | Timeout | Purpose |
|---|---|---|---|---|
Tests | 18, 20, 22, 24 | windows-latest, macOS-latest, ubuntu-latest | 15 min | Full test suite via vitest run |
TestNoAsync | 22 | ubuntu-latest | 10 min | Runtime tests with SVELTE_NO_ASYNC=true flag |
TSGo | 24 | ubuntu-latest | 5 min | Type checking with @typescript/native-preview |
Lint | 24 | ubuntu-latest | 5 min | pnpm check, pnpm lint, type generation validation |
Benchmarks | 18 | ubuntu-latest | 15 min | pnpm bench for performance regression detection |
Test Job Execution Steps
Sources: .github/workflows/ci.yml14-45 .github/workflows/ci.yml46-62 .github/workflows/ci.yml63-79 package.json21
<old_str>
The ecosystem-ci-trigger.yml workflow allows maintainers to test PR changes against downstream projects. It triggers on issue_comment events matching /ecosystem-ci run.
Ecosystem CI Workflow
Security Controls:
| Control | Implementation | Location |
|---|---|---|
| Permission check | github.rest.repos.getCollaboratorPermissionLevel validates data.user.permissions.triage | .github/workflows/ecosystem-ci-trigger.yml19-56 |
| Timing validation | Compares comment.created_at with pr.head.repo.pushed_at to detect post-comment pushes | .github/workflows/ecosystem-ci-trigger.yml70-98 |
| Token isolation | GitHub App token scoped only to svelte and svelte-ecosystem-ci repos | .github/workflows/ecosystem-ci-trigger.yml107-115 |
| Input sanitization | Suite name extracted from first line of comment body | .github/workflows/ecosystem-ci-trigger.yml129 |
Sources: .github/workflows/ecosystem-ci-trigger.yml1-144 .github/workflows/ecosystem-ci-trigger.yml19-56 .github/workflows/ecosystem-ci-trigger.yml58-106 .github/workflows/ecosystem-ci-trigger.yml107-144 </old_str>
<new_str>
The package preview system publishes every commit to pkg.pr.new, enabling testing changes before merging. The workflow has three jobs with security sandboxing:
pkg.pr.new Workflow Architecture
Comment Content Format:
pnpm add https://pkg.pr.new/svelte@{issue_number}
Security Design:
The three-job architecture prevents code injection:
build job runs untrusted PR code with no GitHub permissionssanitize job filters output against ALLOWED_PACKAGES=['svelte'] and validates SHA format matches /^[0-9a-f]{7}$/comment job runs with elevated permissions but only processes sanitized dataSources: .github/workflows/pkg.pr.new.yml17-53 .github/workflows/pkg.pr.new.yml57-103 .github/workflows/pkg.pr.new.yml105-198 .github/workflows/pkg.pr.new.yml76-95
The Lint job performs comprehensive code quality checks:
The generated types validation ensures that type definitions remain in sync with the source code:
pnpm build to regenerate type definitionsgit status --porcelain=v1 to detect changesgit diff for debuggingSources: .github/workflows/ci.yml80-100
The package preview system publishes every commit to pkg.pr.new, enabling developers to test changes before merging:
Comment Format:
For pull requests, the bot posts a comment with:
https://svelte.dev/playground?version=pr-{number}pnpm add https://pkg.pr.new/svelte@{pr-number}Sources: .github/workflows/pkg.pr.new.yml1-45 .github/workflows/pkg.pr.new-comment.yml1-116
The release process uses Changesets for version management. The release.yml workflow runs on every push to main with a concurrency lock to prevent race conditions.
Changesets Release Flow
Concurrency Control:
The workflow uses concurrency.group: ${{ github.workflow }} to ensure only one release process runs at a time, preventing race conditions during version bumps or npm publishes.
npm Provenance:
Published packages include build provenance by setting NPM_CONFIG_PROVENANCE=true, which creates a signed attestation linking the npm package to the specific GitHub Actions workflow run that built it. This enhances supply chain security.
Sources: .github/workflows/release.yml1-52 .github/workflows/release.yml8-11 .github/workflows/release.yml43-51 package.json22-23
Root-level scripts from package.json16-26 used in CI/CD:
| Script | Command | Used By | Purpose |
|---|---|---|---|
build | pnpm -r --filter=./packages/* build | All CI jobs, release workflow | Recursive build of workspace packages |
check | cd packages/svelte && pnpm build && cd ../../ && pnpm -r check | Lint job | Build svelte, then run TypeScript type checking |
lint | eslint && prettier --check . | Lint job | ESLint + Prettier validation |
test | vitest run | Tests, TestNoAsync jobs | Execute Vitest test suites |
changeset:version | changeset version && pnpm -r generate:version && git add --all | release.yml via changesets/action | Bump versions, run generate:version, stage changes |
changeset:publish | changeset publish | release.yml via changesets/action | Publish to npm with tags |
bench | NODE_ENV=production node --allow-natives-syntax ./benchmarking/run.js | Benchmarks job | Run performance benchmarks with V8 natives |
pnpm Workspace Filters:
pnpm -r (recursive): Runs command in all workspace packages--filter=./packages/*: Limits scope to packages under packages/ directorySources: package.json16-26 .github/workflows/ci.yml113 .github/workflows/ci.yml43 .github/workflows/release.yml41 .github/workflows/release.yml47-48
The Changesets system is configured via .changeset/config.json:
| Configuration | Value | Purpose |
|---|---|---|
changelog | @svitejs/changesets-changelog-github-compact | Compact changelog with GitHub links |
commit | false | Don't auto-commit changes |
access | public | Publish as public packages |
baseBranch | main | Target branch for releases |
bumpVersionsWithWorkspaceProtocolOnly | true | Only bump workspace dependencies |
ignore | !(@sveltejs/*|svelte) | Only manage svelte packages |
Sources: .changeset/config.json1-12
The release workflow requires specific GitHub permissions:
npm Provenance: The workflow publishes packages with provenance information by setting NPM_CONFIG_PROVENANCE=true, which links the published package to the specific GitHub Actions workflow run that created it.
Sources: .github/workflows/release.yml13-16 .github/workflows/release.yml46
Pull requests must meet the following requirements before merging:
Changeset Requirement: If the PR modifies code in packages/svelte/src, it must include a changeset file created by running npx changeset. This ensures that all code changes are documented and versioned appropriately.
Sources: .github/PULL_REQUEST_TEMPLATE.md1-12 CONTRIBUTING.md146
Key scripts used in the CI/CD pipeline from package.json:
| Script | Command | Usage |
|---|---|---|
build | pnpm -r --filter=./packages/* build | Build all packages |
check | cd packages/svelte && pnpm build && cd ../../ && pnpm -r check | TypeScript type checking |
lint | eslint && prettier --check . | Code quality checks |
test | vitest run | Execute test suite |
changeset:version | changeset version && pnpm -r generate:version && git add --all | Update versions and generate changelogs |
changeset:publish | changeset publish | Publish packages to npm |
bench | node --allow-natives-syntax ./benchmarking/run.js | Run performance benchmarks |
Sources: package.json16-26
The repository uses pnpm for package management with specific configurations:
[email protected] (specified in packageManager field)>=9.0.0 (specified in engines).npmrc (installed manually in CI)pnpm-lock.yaml must be used (--frozen-lockfile in CI)Sources: package.json8-10 .npmrc1
The CI workflows implement several optimizations:
actions/setup-node@v4 cache for faster installs${{ success() }} || ${{ failure() }})Timeout Configuration:
Sources: .github/workflows/ci.yml17 .github/workflows/ci.yml49 .github/workflows/ci.yml66 .github/workflows/ci.yml83 .github/workflows/ci.yml104
Refresh this wiki