diff --git a/.circleci/config.yml b/.circleci/config.yml
deleted file mode 100644
index 3de5c2e9bf2..00000000000
--- a/.circleci/config.yml
+++ /dev/null
@@ -1,52 +0,0 @@
-version: 2
-
-defaults: &defaults
- docker:
- - image: vuejs/ci
-
-step_restore_cache: &restore_cache
- restore_cache:
- keys:
- - v1-dependencies-{{ checksum "yarn.lock" }}-1
- - v1-dependencies-
-
-step_install_deps: &install_deps
- run:
- name: Install Dependencies
- command: yarn --frozen-lockfile
-
-step_save_cache: &save_cache
- save_cache:
- paths:
- - node_modules
- - packages/compiler-core/node_modules
- - packages/compiler-sfc/node_modules
- - packages/vue/node_modules
- - ~/.cache/yarn
- key: v1-dependencies-{{ checksum "yarn.lock" }}-1
-
-jobs:
- test:
- <<: *defaults
- steps:
- - checkout
- - *restore_cache
- - *install_deps
- - *save_cache
- - run: yarn test --ci
-
- test-dts:
- <<: *defaults
- steps:
- - checkout
- - *restore_cache
- - *install_deps
- - *save_cache
- - run: yarn test-dts
-
-workflows:
- version: 2
- ci:
- jobs:
- - test
- - test-dts
diff --git a/.eslintrc.js b/.eslintrc.js
deleted file mode 100644
index 0732923e84b..00000000000
--- a/.eslintrc.js
+++ /dev/null
@@ -1,66 +0,0 @@
-const DOMGlobals = ['window', 'document']
-const NodeGlobals = ['module', 'require']
-
-module.exports = {
- parser: '@typescript-eslint/parser',
- parserOptions: {
- sourceType: 'module'
- },
- rules: {
- 'no-unused-vars': [
- 'error',
- // we are only using this rule to check for unused arguments since TS
- // catches unused variables but not args.
- { varsIgnorePattern: '.*', args: 'none' }
- ],
- // most of the codebase are expected to be env agnostic
- 'no-restricted-globals': ['error', ...DOMGlobals, ...NodeGlobals],
- // since we target ES2015 for baseline support, we need to forbid object
- // rest spread usage (both assign and destructure)
- 'no-restricted-syntax': [
- 'error',
- 'ObjectExpression > SpreadElement',
- 'ObjectPattern > RestElement'
- ]
- },
- overrides: [
- // tests, no restrictions (runs in Node / jest with jsdom)
- {
- files: ['**/__tests__/**', 'test-dts/**'],
- rules: {
- 'no-restricted-globals': 'off',
- 'no-restricted-syntax': 'off'
- }
- },
- // shared, may be used in any env
- {
- files: ['packages/shared/**'],
- rules: {
- 'no-restricted-globals': 'off'
- }
- },
- // Packages targeting DOM
- {
- files: ['packages/{vue,runtime-dom}/**'],
- rules: {
- 'no-restricted-globals': ['error', ...NodeGlobals]
- }
- },
- // Packages targeting Node
- {
- files: ['packages/{compiler-sfc,compiler-ssr,server-renderer}/**'],
- rules: {
- 'no-restricted-globals': ['error', ...DOMGlobals],
- 'no-restricted-syntax': 'off'
- }
- },
- // Private package, browser only + no syntax restrictions
- {
- files: ['packages/template-explorer/**', 'packages/sfc-playground/**'],
- rules: {
- 'no-restricted-globals': ['error', ...NodeGlobals],
- 'no-restricted-syntax': 'off'
- }
- }
- ]
-}
diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs
new file mode 100644
index 00000000000..d06b03a3f89
--- /dev/null
+++ b/.git-blame-ignore-revs
@@ -0,0 +1,2 @@
+# update prettier & eslint config (#9162)
+bfe6b459d3a0ce6168611ee1ac7e6e789709df9d
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
index 4a8f6fd424f..9288efdb9ac 100644
--- a/.github/FUNDING.yml
+++ b/.github/FUNDING.yml
@@ -1,3 +1,2 @@
-open_collective: vuejs
-patreon: evanyou
github: yyx990803
+open_collective: vuejs
diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
new file mode 100644
index 00000000000..95e0ca79c07
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -0,0 +1,74 @@
+name: "\U0001F41E Bug report"
+description: Create a report to help us improve
+body:
+ - type: markdown
+ attributes:
+ value: |
+ **Before You Start...**
+
+ This form is only for submitting bug reports. If you have a usage question
+ or are unsure if this is really a bug, make sure to:
+
+ - Read the [docs](https://vuejs.org/)
+ - Ask on [Discord Chat](https://chat.vuejs.org/)
+ - Ask on [GitHub Discussions](https://github.com/vuejs/core/discussions)
+ - Look for / ask questions on [Stack Overflow](https://stackoverflow.com/questions/ask?tags=vue.js)
+
+ Also try to search for your issue - it may have already been answered or even fixed in the development branch.
+ However, if you find that an old, closed issue still persists in the latest version,
+ you should open a new issue using the form below instead of commenting on the old issue.
+ - type: input
+ id: version
+ attributes:
+ label: Vue version
+ validations:
+ required: true
+ - type: input
+ id: reproduction-link
+ attributes:
+ label: Link to minimal reproduction
+ description: |
+ The easiest way to provide a reproduction is by showing the bug in [The SFC Playground](https://play.vuejs.org/).
+ If it cannot be reproduced in the playground and requires a proper build setup, try [StackBlitz](https://vite.new/vue).
+ If neither of these are suitable, you can always provide a GitHub repository.
+
+ The reproduction should be **minimal** - i.e. it should contain only the bare minimum amount of code needed
+ to show the bug. See [Bug Reproduction Guidelines](https://github.com/vuejs/core/blob/main/.github/bug-repro-guidelines.md) for more details.
+
+ Please do not just fill in a random link. The issue will be closed if no valid reproduction is provided.
+ placeholder: Reproduction Link
+ validations:
+ required: true
+ - type: textarea
+ id: steps-to-reproduce
+ attributes:
+ label: Steps to reproduce
+ description: |
+ What do we need to do after opening your repro in order to make the bug happen? Clear and concise reproduction instructions are important for us to be able to triage your issue in a timely manner. Note that you can use [Markdown](https://guides.github.com/features/mastering-markdown/) to format lists and code.
+ placeholder: Steps to reproduce
+ validations:
+ required: true
+ - type: textarea
+ id: expected
+ attributes:
+ label: What is expected?
+ validations:
+ required: true
+ - type: textarea
+ id: actually-happening
+ attributes:
+ label: What is actually happening?
+ validations:
+ required: true
+ - type: textarea
+ id: system-info
+ attributes:
+ label: System Info
+ description: Output of `npx envinfo --system --npmPackages vue --binaries --browsers`
+ render: shell
+ placeholder: System, Binaries, Browsers
+ - type: textarea
+ id: additional-comments
+ attributes:
+ label: Any additional comments?
+ description: e.g. some background/context of how you ran into this bug.
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
index ac8a00ef158..02f99c6bfbb 100644
--- a/.github/ISSUE_TEMPLATE/config.yml
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -1,8 +1,14 @@
blank_issues_enabled: false
contact_links:
- - name: Create new issue
- url: https://new-issue.vuejs.org/?repo=vuejs/vue-next
- about: Please use the following link to create a new issue.
+ - name: Feature Request
+ url: https://github.com/vuejs/rfcs/discussions
+ about: Suggest new features for consideration
+ - name: Discord Chat
+ url: https://chat.vuejs.org
+ about: Ask questions and discuss with other Vue users in real time.
+ - name: Questions & Discussions
+ url: https://github.com/vuejs/core/discussions
+ about: Use GitHub discussions for message-board style questions and discussions.
- name: Patreon
url: https://www.patreon.com/evanyou
about: Love Vue.js? Please consider supporting us via Patreon.
diff --git a/.github/bug-repro-guidelines.md b/.github/bug-repro-guidelines.md
new file mode 100644
index 00000000000..90458b30741
--- /dev/null
+++ b/.github/bug-repro-guidelines.md
@@ -0,0 +1,29 @@
+## About Bug Reproductions
+
+A bug reproduction is a piece of code that can run and demonstrate how a bug can happen.
+
+### Text is not enough
+
+It's impossible to fix a bug from mere text descriptions. First, it's very difficult to precisely describe a technical problem while keeping it easy to follow; Second, the real cause may very well be something that you forgot to even mention. A reproduction is the only way that can reliably help us understand what is going on, so please provide one.
+
+### A repro must be runnable
+
+Screenshots or videos are NOT reproductions! They only show that the bug exists, but do not provide enough information on why it happens. Only runnable code provides the most complete context and allows us to properly debug the scenario. That said, in some cases videos/gifs can help explain interaction issues that are hard to describe in text.
+
+### A repro should be minimal
+
+Some users would give us a link to a real project and hope we can help them figure out what is wrong. We generally do not accept such requests because:
+
+You are already familiar with your codebase, but we are not. It is extremely time-consuming to hunt a bug in a big and unfamiliar codebase.
+
+The problematic behavior may very well be caused by your code rather than by a bug in Vue.
+
+A minimal reproduction means it demonstrates the bug, and the bug only. It should only contain the bare minimum amount of code that can reliably cause the bug. Try your best to get rid of anything that aren't directly related to the problem.
+
+### How to create a repro
+
+For Vue 3 core reproductions, try reproducing it in [The SFC Playground](https://play.vuejs.org/).
+
+If it cannot be reproduced in the playground and requires a proper build setup, try [StackBlitz](https://vite.new/vue).
+
+If neither of these are suitable, you can always provide a GitHub repository.
diff --git a/.github/commit-convention.md b/.github/commit-convention.md
index a8522fa210a..11a64576a24 100644
--- a/.github/commit-convention.md
+++ b/.github/commit-convention.md
@@ -6,7 +6,7 @@
Messages must be matched by the following regex:
-``` js
+```regexp
/^(revert: )?(feat|fix|docs|dx|style|refactor|perf|test|workflow|build|ci|chore|types|wip)(\(.+\))?: .{1,50}/
```
@@ -44,7 +44,7 @@ This reverts commit 667ecc1654a317a13331b17617d973392f415f02.
### Full Message Format
-A commit message consists of a **header**, **body** and **footer**. The header has a **type**, **scope** and **subject**:
+A commit message consists of a **header**, **body** and **footer**. The header has a **type**, **scope** and **subject**:
```
+
+
+
+
diff --git a/.github/git-branch-workflow.excalidraw b/.github/git-branch-workflow.excalidraw
new file mode 100644
index 00000000000..dd9127938da
--- /dev/null
+++ b/.github/git-branch-workflow.excalidraw
@@ -0,0 +1,1746 @@
+{
+ "type": "excalidraw",
+ "version": 2,
+ "source": "https://excalidraw.com",
+ "elements": [
+ {
+ "type": "arrow",
+ "version": 799,
+ "versionNonce": 529220601,
+ "isDeleted": false,
+ "id": "Gao2krnDddLMCj468JSWD",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 860.0129225738813,
+ "y": 663.9911710635109,
+ "strokeColor": "#f08c00",
+ "backgroundColor": "#ffc9c9",
+ "width": 133.75296854079784,
+ "height": 149.58016791936518,
+ "seed": 1415631543,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [],
+ "updated": 1698927613071,
+ "link": null,
+ "locked": false,
+ "startBinding": null,
+ "endBinding": {
+ "elementId": "hDC6an14QljktaZCUhcPF",
+ "focus": 0.09950793234484598,
+ "gap": 1.2432497743127229
+ },
+ "lastCommittedPoint": null,
+ "startArrowhead": null,
+ "endArrowhead": "arrow",
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 25.209039386719837,
+ 85.96948921803892
+ ],
+ [
+ 133.75296854079784,
+ 149.58016791936518
+ ]
+ ]
+ },
+ {
+ "type": "arrow",
+ "version": 563,
+ "versionNonce": 290881303,
+ "isDeleted": false,
+ "id": "N3wyyEU7TQ8BsOQgxCmlR",
+ "fillStyle": "hachure",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 292.88008929085873,
+ "y": 660.7027503334302,
+ "strokeColor": "#2f9e44",
+ "backgroundColor": "#b2f2bb",
+ "width": 936.9972134376155,
+ "height": 1.3184243543457796,
+ "seed": 534235417,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [],
+ "updated": 1698927613071,
+ "link": null,
+ "locked": false,
+ "startBinding": null,
+ "endBinding": null,
+ "lastCommittedPoint": null,
+ "startArrowhead": null,
+ "endArrowhead": "arrow",
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 936.9972134376155,
+ -1.3184243543457796
+ ]
+ ]
+ },
+ {
+ "type": "arrow",
+ "version": 302,
+ "versionNonce": 883286489,
+ "isDeleted": false,
+ "id": "nRDWQs5nQa37yzCWTBiXC",
+ "fillStyle": "hachure",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 293.1231624544633,
+ "y": 820.6017661012943,
+ "strokeColor": "#f08c00",
+ "backgroundColor": "#b2f2bb",
+ "width": 790.7091601354882,
+ "height": 0.35284814071621895,
+ "seed": 515907671,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [],
+ "updated": 1698927613071,
+ "link": null,
+ "locked": false,
+ "startBinding": null,
+ "endBinding": {
+ "elementId": "ggogfJT7E_bbfEog7Hjnp",
+ "focus": -0.14000162237652433,
+ "gap": 1
+ },
+ "lastCommittedPoint": null,
+ "startArrowhead": null,
+ "endArrowhead": "arrow",
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 790.7091601354882,
+ -0.35284814071621895
+ ]
+ ]
+ },
+ {
+ "type": "text",
+ "version": 36,
+ "versionNonce": 981763127,
+ "isDeleted": false,
+ "id": "ZPdMAnEUq5Jgj1W07Zqiw",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 292.0450153578305,
+ "y": 619.3959946602608,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#b2f2bb",
+ "width": 46.875,
+ "height": 24,
+ "seed": 1311694519,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [],
+ "updated": 1698927613071,
+ "link": null,
+ "locked": false,
+ "fontSize": 20,
+ "fontFamily": 3,
+ "text": "main",
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "main",
+ "lineHeight": 1.2,
+ "baseline": 20
+ },
+ {
+ "type": "text",
+ "version": 94,
+ "versionNonce": 18759353,
+ "isDeleted": false,
+ "id": "g9IkEIfu4vA8Qkwtw01Hi",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 290.88990199912035,
+ "y": 779.1760596323645,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#b2f2bb",
+ "width": 58.59375,
+ "height": 24,
+ "seed": 329886135,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [],
+ "updated": 1698927613071,
+ "link": null,
+ "locked": false,
+ "fontSize": 20,
+ "fontFamily": 3,
+ "text": "minor",
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "minor",
+ "lineHeight": 1.2,
+ "baseline": 20
+ },
+ {
+ "type": "ellipse",
+ "version": 50,
+ "versionNonce": 1442112855,
+ "isDeleted": false,
+ "id": "RrdEQ7hwgGGDPhzDnuZj1",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 361.55609907891005,
+ "y": 649.8742329483416,
+ "strokeColor": "#2f9e44",
+ "backgroundColor": "#b2f2bb",
+ "width": 18.814646969963974,
+ "height": 18.814646969963974,
+ "seed": 2077639991,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [],
+ "updated": 1698927613071,
+ "link": null,
+ "locked": false
+ },
+ {
+ "type": "ellipse",
+ "version": 79,
+ "versionNonce": 1547173785,
+ "isDeleted": false,
+ "id": "Zmp49FKWxGSzKnVKomjQc",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 427.3015090315691,
+ "y": 650.256485100784,
+ "strokeColor": "#2f9e44",
+ "backgroundColor": "#b2f2bb",
+ "width": 18.814646969963974,
+ "height": 18.814646969963974,
+ "seed": 372652121,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [],
+ "updated": 1698927613071,
+ "link": null,
+ "locked": false
+ },
+ {
+ "type": "ellipse",
+ "version": 76,
+ "versionNonce": 586949239,
+ "isDeleted": false,
+ "id": "UOl9nLBksM7RPdH9mzjJa",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 490.9435520120701,
+ "y": 651.2601420343765,
+ "strokeColor": "#2f9e44",
+ "backgroundColor": "#b2f2bb",
+ "width": 18.814646969963974,
+ "height": 18.814646969963974,
+ "seed": 508667545,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [],
+ "updated": 1698927613071,
+ "link": null,
+ "locked": false
+ },
+ {
+ "type": "ellipse",
+ "version": 120,
+ "versionNonce": 874947705,
+ "isDeleted": false,
+ "id": "oMC55V0VO_hOXoZ1se8Kl",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 555.4481126698772,
+ "y": 650.7975189165487,
+ "strokeColor": "#2f9e44",
+ "backgroundColor": "#b2f2bb",
+ "width": 18.814646969963974,
+ "height": 18.814646969963974,
+ "seed": 1914963513,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [],
+ "updated": 1698927613071,
+ "link": null,
+ "locked": false
+ },
+ {
+ "type": "ellipse",
+ "version": 66,
+ "versionNonce": 39762839,
+ "isDeleted": false,
+ "id": "DZY5DC5uVP7-U5c3ngIZ4",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 622.5167031502219,
+ "y": 649.3743647489936,
+ "strokeColor": "#2f9e44",
+ "backgroundColor": "#b2f2bb",
+ "width": 18.814646969963974,
+ "height": 18.814646969963974,
+ "seed": 165914713,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [],
+ "updated": 1698927613071,
+ "link": null,
+ "locked": false
+ },
+ {
+ "type": "ellipse",
+ "version": 107,
+ "versionNonce": 1689103705,
+ "isDeleted": false,
+ "id": "Vsw6oIiTM3fQypkiCic3f",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 690.330195260967,
+ "y": 650.6681412649529,
+ "strokeColor": "#2f9e44",
+ "backgroundColor": "#b2f2bb",
+ "width": 18.814646969963974,
+ "height": 18.814646969963974,
+ "seed": 280044345,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [
+ {
+ "id": "lwYvAs-7FTjcwxKjcx0KV",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1698927613071,
+ "link": null,
+ "locked": false
+ },
+ {
+ "type": "ellipse",
+ "version": 148,
+ "versionNonce": 1986194201,
+ "isDeleted": false,
+ "id": "D14w9erv_2l53mINe2nSt",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 361.004283792179,
+ "y": 810.2809579853473,
+ "strokeColor": "#f08c00",
+ "backgroundColor": "#ffc9c9",
+ "width": 18.814646969963974,
+ "height": 18.814646969963974,
+ "seed": 1203257975,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [],
+ "updated": 1698927613071,
+ "link": null,
+ "locked": false
+ },
+ {
+ "type": "ellipse",
+ "version": 179,
+ "versionNonce": 1172811511,
+ "isDeleted": false,
+ "id": "6WO8xOpG0rf673b_bT0m7",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 426.74969374483805,
+ "y": 810.6632101377896,
+ "strokeColor": "#f08c00",
+ "backgroundColor": "#b2f2bb",
+ "width": 18.814646969963974,
+ "height": 18.814646969963974,
+ "seed": 2056706967,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [
+ {
+ "id": "mE8Mu0qKfFaWPCC5vmF_f",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1698927613071,
+ "link": null,
+ "locked": false
+ },
+ {
+ "type": "ellipse",
+ "version": 173,
+ "versionNonce": 820518905,
+ "isDeleted": false,
+ "id": "VB9U8oH-78hf530hIb_mG",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 490.391736725339,
+ "y": 811.6668670713822,
+ "strokeColor": "#f08c00",
+ "backgroundColor": "#b2f2bb",
+ "width": 18.814646969963974,
+ "height": 18.814646969963974,
+ "seed": 1149587639,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [],
+ "updated": 1698927613071,
+ "link": null,
+ "locked": false
+ },
+ {
+ "type": "ellipse",
+ "version": 218,
+ "versionNonce": 1227143191,
+ "isDeleted": false,
+ "id": "Bxv1hcS0VmxUwI0JLFH97",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 554.8962973831461,
+ "y": 811.2042439535543,
+ "strokeColor": "#f08c00",
+ "backgroundColor": "#b2f2bb",
+ "width": 18.814646969963974,
+ "height": 18.814646969963974,
+ "seed": 1864901079,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [
+ {
+ "id": "M14Q0Uo1DBy2Ss2SOFSgW",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1698927613071,
+ "link": null,
+ "locked": false
+ },
+ {
+ "type": "ellipse",
+ "version": 167,
+ "versionNonce": 1387509977,
+ "isDeleted": false,
+ "id": "4v23gkfhy-hzk18YdkfLz",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 621.9648878634908,
+ "y": 809.7810897859994,
+ "strokeColor": "#f08c00",
+ "backgroundColor": "#ffc9c9",
+ "width": 18.814646969963974,
+ "height": 18.814646969963974,
+ "seed": 462671607,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [
+ {
+ "id": "vEF1cIIYYWKm84KLKqEz3",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1698927613071,
+ "link": null,
+ "locked": false
+ },
+ {
+ "type": "ellipse",
+ "version": 200,
+ "versionNonce": 774085943,
+ "isDeleted": false,
+ "id": "AtEf7o4WZQn4Zxq8EN5fH",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 689.7783799742359,
+ "y": 811.0748663019584,
+ "strokeColor": "#f08c00",
+ "backgroundColor": "#b2f2bb",
+ "width": 18.814646969963974,
+ "height": 18.814646969963974,
+ "seed": 1414322199,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [
+ {
+ "id": "3heKY3vfe3-6ni4dX7Uqo",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1698927613071,
+ "link": null,
+ "locked": false
+ },
+ {
+ "type": "ellipse",
+ "version": 199,
+ "versionNonce": 1834563001,
+ "isDeleted": false,
+ "id": "ugDby5sBv4NKdNt8eC1sg",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 762.6179978227377,
+ "y": 810.2986003923828,
+ "strokeColor": "#f08c00",
+ "backgroundColor": "#b2f2bb",
+ "width": 18.814646969963974,
+ "height": 18.814646969963974,
+ "seed": 1598537015,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [],
+ "updated": 1698927613071,
+ "link": null,
+ "locked": false
+ },
+ {
+ "type": "ellipse",
+ "version": 211,
+ "versionNonce": 407428695,
+ "isDeleted": false,
+ "id": "Fwe4F2sB_0jptOZGYsusj",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 837.1081608628116,
+ "y": 810.859236882632,
+ "strokeColor": "#f08c00",
+ "backgroundColor": "#b2f2bb",
+ "width": 18.814646969963974,
+ "height": 18.814646969963974,
+ "seed": 1340669527,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [
+ {
+ "id": "M14Q0Uo1DBy2Ss2SOFSgW",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1698927613071,
+ "link": null,
+ "locked": false
+ },
+ {
+ "type": "arrow",
+ "version": 57,
+ "versionNonce": 335287961,
+ "isDeleted": false,
+ "id": "mE8Mu0qKfFaWPCC5vmF_f",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 437.60867586595543,
+ "y": 830.4227236701945,
+ "strokeColor": "#f08c00",
+ "backgroundColor": "#ffc9c9",
+ "width": 0.5232394659406623,
+ "height": 33.25787987764363,
+ "seed": 482155929,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [],
+ "updated": 1698927613071,
+ "link": null,
+ "locked": false,
+ "startBinding": {
+ "elementId": "6WO8xOpG0rf673b_bT0m7",
+ "focus": -0.1727591064041787,
+ "gap": 1.046152088903881
+ },
+ "endBinding": {
+ "elementId": "JALHBtowuh3_a86loej2x",
+ "focus": 0.015156451076917701,
+ "gap": 15.586906139714472
+ },
+ "lastCommittedPoint": null,
+ "startArrowhead": null,
+ "endArrowhead": "arrow",
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ -0.5232394659406623,
+ 33.25787987764363
+ ]
+ ]
+ },
+ {
+ "type": "arrow",
+ "version": 59,
+ "versionNonce": 1248394103,
+ "isDeleted": false,
+ "id": "AI-_jSAuzesxTqwRvpk0s",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 501.2878833373983,
+ "y": 652.3088851192829,
+ "strokeColor": "#2f9e44",
+ "backgroundColor": "#ffc9c9",
+ "width": 0,
+ "height": 40.40111211199792,
+ "seed": 1052632343,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [],
+ "updated": 1698927613071,
+ "link": null,
+ "locked": false,
+ "startBinding": null,
+ "endBinding": null,
+ "lastCommittedPoint": null,
+ "startArrowhead": null,
+ "endArrowhead": "arrow",
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ -40.40111211199792
+ ]
+ ]
+ },
+ {
+ "type": "arrow",
+ "version": 261,
+ "versionNonce": 693099385,
+ "isDeleted": false,
+ "id": "lwYvAs-7FTjcwxKjcx0KV",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 786.7392304423553,
+ "y": 649.6016935672433,
+ "strokeColor": "#2f9e44",
+ "backgroundColor": "#ffc9c9",
+ "width": 0,
+ "height": 40.40111211199792,
+ "seed": 1233043511,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [],
+ "updated": 1698927613071,
+ "link": null,
+ "locked": false,
+ "startBinding": {
+ "elementId": "s0PKxsWTJSDbQeEl_WI-C",
+ "focus": 0.016372633695398757,
+ "gap": 1
+ },
+ "endBinding": {
+ "elementId": "9ia1Uwc5X0fRw5iaahmcT",
+ "focus": 0.025318405829282714,
+ "gap": 14.862364635333904
+ },
+ "lastCommittedPoint": null,
+ "startArrowhead": null,
+ "endArrowhead": "arrow",
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ -40.40111211199792
+ ]
+ ]
+ },
+ {
+ "type": "text",
+ "version": 121,
+ "versionNonce": 952661143,
+ "isDeleted": false,
+ "id": "qWW8uxDIcV3Bkj28uvRLr",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 454.32425448306674,
+ "y": 537.8854189061962,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#ffc9c9",
+ "width": 93.75,
+ "height": 57.599999999999994,
+ "seed": 809847769,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [],
+ "updated": 1698927613071,
+ "link": null,
+ "locked": false,
+ "fontSize": 16,
+ "fontFamily": 3,
+ "text": "patch\nrelease\ne.g. 3.3.8",
+ "textAlign": "center",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "patch\nrelease\ne.g. 3.3.8",
+ "lineHeight": 1.2,
+ "baseline": 53
+ },
+ {
+ "type": "text",
+ "version": 257,
+ "versionNonce": 1838679129,
+ "isDeleted": false,
+ "id": "9ia1Uwc5X0fRw5iaahmcT",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 741.0510307156029,
+ "y": 536.7382168199114,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#ffc9c9",
+ "width": 93.75,
+ "height": 57.599999999999994,
+ "seed": 213765431,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [
+ {
+ "id": "lwYvAs-7FTjcwxKjcx0KV",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1698927613071,
+ "link": null,
+ "locked": false,
+ "fontSize": 16,
+ "fontFamily": 3,
+ "text": "patch\nrelease\ne.g. 3.3.9",
+ "textAlign": "center",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "patch\nrelease\ne.g. 3.3.9",
+ "lineHeight": 1.2,
+ "baseline": 53
+ },
+ {
+ "type": "text",
+ "version": 222,
+ "versionNonce": 1528547767,
+ "isDeleted": false,
+ "id": "JALHBtowuh3_a86loej2x",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 350.7264132088442,
+ "y": 879.2675096875524,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#ffc9c9",
+ "width": 168.75,
+ "height": 57.599999999999994,
+ "seed": 41180921,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [
+ {
+ "id": "mE8Mu0qKfFaWPCC5vmF_f",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1698927613071,
+ "link": null,
+ "locked": false,
+ "fontSize": 16,
+ "fontFamily": 3,
+ "text": "pre minor\nrelease\ne.g. 3.4.0-alpha.1",
+ "textAlign": "center",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "pre minor\nrelease\ne.g. 3.4.0-alpha.1",
+ "lineHeight": 1.2,
+ "baseline": 53
+ },
+ {
+ "type": "arrow",
+ "version": 345,
+ "versionNonce": 1286082873,
+ "isDeleted": false,
+ "id": "3heKY3vfe3-6ni4dX7Uqo",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 699.5281288163526,
+ "y": 831.0290882554708,
+ "strokeColor": "#f08c00",
+ "backgroundColor": "#ffc9c9",
+ "width": 0.5502191262773977,
+ "height": 33.25154356841597,
+ "seed": 627698359,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [],
+ "updated": 1698927613071,
+ "link": null,
+ "locked": false,
+ "startBinding": {
+ "elementId": "AtEf7o4WZQn4Zxq8EN5fH",
+ "focus": -0.05612657009295625,
+ "gap": 1.1451322685712295
+ },
+ "endBinding": {
+ "elementId": "9t6qH-tAxVUexkHHi2pd2",
+ "focus": 0.015156451076917755,
+ "gap": 15.586906139714358
+ },
+ "lastCommittedPoint": null,
+ "startArrowhead": null,
+ "endArrowhead": "arrow",
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ -0.5502191262773977,
+ 33.25154356841597
+ ]
+ ]
+ },
+ {
+ "type": "text",
+ "version": 365,
+ "versionNonce": 1049066199,
+ "isDeleted": false,
+ "id": "9t6qH-tAxVUexkHHi2pd2",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 617.3409291322284,
+ "y": 879.8675379636011,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#ffc9c9",
+ "width": 159.375,
+ "height": 57.599999999999994,
+ "seed": 1013545943,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [
+ {
+ "id": "3heKY3vfe3-6ni4dX7Uqo",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1698927613071,
+ "link": null,
+ "locked": false,
+ "fontSize": 16,
+ "fontFamily": 3,
+ "text": "pre minor\nrelease\ne.g. 3.4.0-beta.1",
+ "textAlign": "center",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "pre minor\nrelease\ne.g. 3.4.0-beta.1",
+ "lineHeight": 1.2,
+ "baseline": 53
+ },
+ {
+ "type": "arrow",
+ "version": 788,
+ "versionNonce": 1810072089,
+ "isDeleted": false,
+ "id": "vEF1cIIYYWKm84KLKqEz3",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 630.3597332113623,
+ "y": 667.2735668205443,
+ "strokeColor": "#f08c00",
+ "backgroundColor": "#ffc9c9",
+ "width": 2.258228100583324,
+ "height": 140.75112333166828,
+ "seed": 2091697367,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [],
+ "updated": 1698927613072,
+ "link": null,
+ "locked": false,
+ "startBinding": null,
+ "endBinding": {
+ "elementId": "4v23gkfhy-hzk18YdkfLz",
+ "focus": 0.13930391883256707,
+ "gap": 1.8256906627890626
+ },
+ "lastCommittedPoint": null,
+ "startArrowhead": null,
+ "endArrowhead": "arrow",
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 1.8426514015177418,
+ 69.09942755691065
+ ],
+ [
+ 2.258228100583324,
+ 140.75112333166828
+ ]
+ ]
+ },
+ {
+ "type": "arrow",
+ "version": 687,
+ "versionNonce": 2017318649,
+ "isDeleted": false,
+ "id": "M14Q0Uo1DBy2Ss2SOFSgW",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 370.5976915356099,
+ "y": 667.5155013947814,
+ "strokeColor": "#f08c00",
+ "backgroundColor": "#ffc9c9",
+ "width": 1.5329291446666957,
+ "height": 145.39303664953377,
+ "seed": 361678233,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [],
+ "updated": 1698927613072,
+ "link": null,
+ "locked": false,
+ "startBinding": null,
+ "endBinding": null,
+ "lastCommittedPoint": null,
+ "startArrowhead": null,
+ "endArrowhead": "arrow",
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ -0.34892760581925586,
+ 83.56228079137543
+ ],
+ [
+ 1.1840015388474399,
+ 145.39303664953377
+ ]
+ ]
+ },
+ {
+ "type": "text",
+ "version": 537,
+ "versionNonce": 342487319,
+ "isDeleted": false,
+ "id": "CHAOOJMz7tNaG1VsG_uzT",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 384.81046417498214,
+ "y": 725.4677076298137,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#ffc9c9",
+ "width": 131.25,
+ "height": 57.599999999999994,
+ "seed": 1656007289,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [],
+ "updated": 1698927613072,
+ "link": null,
+ "locked": false,
+ "fontSize": 16,
+ "fontFamily": 3,
+ "text": "merge main\ninto minor\nbefore release",
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "merge main\ninto minor\nbefore release",
+ "lineHeight": 1.2,
+ "baseline": 53
+ },
+ {
+ "type": "ellipse",
+ "version": 202,
+ "versionNonce": 876253145,
+ "isDeleted": false,
+ "id": "hDC6an14QljktaZCUhcPF",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 993.0386151813434,
+ "y": 810.335845473903,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#ffc9c9",
+ "width": 18.814646969963974,
+ "height": 18.814646969963974,
+ "seed": 1433430105,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [
+ {
+ "id": "Gao2krnDddLMCj468JSWD",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1698927613072,
+ "link": null,
+ "locked": false
+ },
+ {
+ "type": "arrow",
+ "version": 1525,
+ "versionNonce": 777631287,
+ "isDeleted": false,
+ "id": "ces8IwHCpQlTnELpjFDIn",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 1092.5386800881793,
+ "y": 827.5114796878765,
+ "strokeColor": "#f08c00",
+ "backgroundColor": "#ffc9c9",
+ "width": 0.3315362017829102,
+ "height": 49.45191086419197,
+ "seed": 225867737,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [],
+ "updated": 1698927613072,
+ "link": null,
+ "locked": false,
+ "startBinding": null,
+ "endBinding": {
+ "elementId": "8rWUxp-jRNGrGRmhHHfm4",
+ "focus": -0.2047594653982401,
+ "gap": 10.392197401393389
+ },
+ "lastCommittedPoint": null,
+ "startArrowhead": null,
+ "endArrowhead": "arrow",
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ -0.3315362017829102,
+ 49.45191086419197
+ ]
+ ]
+ },
+ {
+ "type": "text",
+ "version": 894,
+ "versionNonce": 1173171385,
+ "isDeleted": false,
+ "id": "8rWUxp-jRNGrGRmhHHfm4",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 1047.251646167428,
+ "y": 887.3555879534618,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#ffc9c9",
+ "width": 112.5,
+ "height": 57.599999999999994,
+ "seed": 1600918713,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [
+ {
+ "id": "ces8IwHCpQlTnELpjFDIn",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1698927613072,
+ "link": null,
+ "locked": false,
+ "fontSize": 16,
+ "fontFamily": 3,
+ "text": "stable minor\nrelease\ne.g. 3.4.0",
+ "textAlign": "center",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "stable minor\nrelease\ne.g. 3.4.0",
+ "lineHeight": 1.2,
+ "baseline": 53
+ },
+ {
+ "type": "ellipse",
+ "version": 201,
+ "versionNonce": 78435447,
+ "isDeleted": false,
+ "id": "3RHuRn_evSK0YUe02B4MY",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 909.9742423218671,
+ "y": 810.4142561718397,
+ "strokeColor": "#2f9e44",
+ "backgroundColor": "#b2f2bb",
+ "width": 18.814646969963974,
+ "height": 18.814646969963974,
+ "seed": 1199705047,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [],
+ "updated": 1698927613072,
+ "link": null,
+ "locked": false
+ },
+ {
+ "type": "ellipse",
+ "version": 371,
+ "versionNonce": 2093872087,
+ "isDeleted": false,
+ "id": "9h2Cu__8owLUgUGjGcWDe",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 848.4414471158692,
+ "y": 650.826922928275,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#b2f2bb",
+ "width": 18.814646969963974,
+ "height": 18.814646969963974,
+ "seed": 603147257,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [],
+ "updated": 1698927613072,
+ "link": null,
+ "locked": false
+ },
+ {
+ "type": "ellipse",
+ "version": 361,
+ "versionNonce": 1981618457,
+ "isDeleted": false,
+ "id": "s0PKxsWTJSDbQeEl_WI-C",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 777.1778842958995,
+ "y": 650.2466837635417,
+ "strokeColor": "#2f9e44",
+ "backgroundColor": "#b2f2bb",
+ "width": 18.814646969963974,
+ "height": 18.814646969963974,
+ "seed": 326722777,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [
+ {
+ "id": "lwYvAs-7FTjcwxKjcx0KV",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1698927613072,
+ "link": null,
+ "locked": false
+ },
+ {
+ "type": "text",
+ "version": 871,
+ "versionNonce": 1528156247,
+ "isDeleted": false,
+ "id": "3JAdSa7kqqSDSom5ZFDoE",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 904.3603861670398,
+ "y": 707.2413714353705,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#ffc9c9",
+ "width": 140.625,
+ "height": 57.599999999999994,
+ "seed": 1011049431,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [],
+ "updated": 1698927613072,
+ "link": null,
+ "locked": false,
+ "fontSize": 16,
+ "fontFamily": 3,
+ "text": "final merge\nmain into minor\nbefore release",
+ "textAlign": "center",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "final merge\nmain into minor\nbefore release",
+ "lineHeight": 1.2,
+ "baseline": 53
+ },
+ {
+ "type": "arrow",
+ "version": 591,
+ "versionNonce": 1714373785,
+ "isDeleted": false,
+ "id": "7kFBLq2Iczmj0lVnVk8Ad",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dotted",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 1100.7141458557703,
+ "y": 814.2034531496416,
+ "strokeColor": "#2f9e44",
+ "backgroundColor": "#ffffff",
+ "width": 127.38209933342364,
+ "height": 144.5383600420214,
+ "seed": 25829591,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [],
+ "updated": 1698927613072,
+ "link": null,
+ "locked": false,
+ "startBinding": null,
+ "endBinding": {
+ "elementId": "Y7VXnuc9QEz2N2l9i0xrc",
+ "focus": 0.3932764551319699,
+ "gap": 5.928572790502042
+ },
+ "lastCommittedPoint": null,
+ "startArrowhead": null,
+ "endArrowhead": "arrow",
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 88.94909573964219,
+ -43.721805169626464
+ ],
+ [
+ 127.38209933342364,
+ -144.5383600420214
+ ]
+ ]
+ },
+ {
+ "type": "text",
+ "version": 1208,
+ "versionNonce": 1254600055,
+ "isDeleted": false,
+ "id": "gwFWlPLabuYhxCOweJjWz",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 1223.0464288187204,
+ "y": 725.1565933898091,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#ffc9c9",
+ "width": 150,
+ "height": 38.4,
+ "seed": 51102743,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [],
+ "updated": 1698927613072,
+ "link": null,
+ "locked": false,
+ "fontSize": 16,
+ "fontFamily": 3,
+ "text": "main merge minor\n(fast forward)",
+ "textAlign": "center",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "main merge minor\n(fast forward)",
+ "lineHeight": 1.2,
+ "baseline": 34
+ },
+ {
+ "type": "ellipse",
+ "version": 597,
+ "versionNonce": 1760381305,
+ "isDeleted": false,
+ "id": "Y7VXnuc9QEz2N2l9i0xrc",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 1227.4473966637659,
+ "y": 647.6689320688656,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#a5d8ff",
+ "width": 18.814646969963974,
+ "height": 18.814646969963974,
+ "seed": 412038615,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [
+ {
+ "id": "7kFBLq2Iczmj0lVnVk8Ad",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1698927613072,
+ "link": null,
+ "locked": false
+ },
+ {
+ "type": "ellipse",
+ "version": 547,
+ "versionNonce": 1585505943,
+ "isDeleted": false,
+ "id": "ggogfJT7E_bbfEog7Hjnp",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 1083.7911569735343,
+ "y": 809.5203742153592,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#a5d8ff",
+ "width": 18.814646969963974,
+ "height": 18.814646969963974,
+ "seed": 741463161,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": {
+ "type": 2
+ },
+ "boundElements": [
+ {
+ "id": "nRDWQs5nQa37yzCWTBiXC",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1698927613072,
+ "link": null,
+ "locked": false
+ },
+ {
+ "type": "text",
+ "version": 229,
+ "versionNonce": 1935127129,
+ "isDeleted": false,
+ "id": "eU-EgpwDD42CLYUEIDLaD",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dotted",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 305.8405004265049,
+ "y": 389.31989430571576,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#a5d8ff",
+ "width": 581.25,
+ "height": 19.2,
+ "seed": 1086231577,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [],
+ "updated": 1698927613072,
+ "link": null,
+ "locked": false,
+ "fontSize": 16,
+ "fontFamily": 3,
+ "text": "- merge feature PRs into, and release minors from minor branch",
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "- merge feature PRs into, and release minors from minor branch",
+ "lineHeight": 1.2,
+ "baseline": 15
+ },
+ {
+ "type": "text",
+ "version": 397,
+ "versionNonce": 116088535,
+ "isDeleted": false,
+ "id": "Kt6VBAVD4sLM4IexsRGoX",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dotted",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 305.4136207977353,
+ "y": 358.61173442109686,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#a5d8ff",
+ "width": 618.75,
+ "height": 19.2,
+ "seed": 273353945,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [],
+ "updated": 1698927617946,
+ "link": null,
+ "locked": false,
+ "fontSize": 16,
+ "fontFamily": 3,
+ "text": "- merge fix / chore PRs into, and release patches from main branch",
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "- merge fix / chore PRs into, and release patches from main branch",
+ "lineHeight": 1.2,
+ "baseline": 15
+ },
+ {
+ "type": "text",
+ "version": 459,
+ "versionNonce": 440532793,
+ "isDeleted": false,
+ "id": "JwKEdnU6H_Nu74WbEAX5M",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dotted",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 305.6723761009271,
+ "y": 418.3724478537203,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#a5d8ff",
+ "width": 459.375,
+ "height": 19.2,
+ "seed": 1001222329,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [],
+ "updated": 1698927613072,
+ "link": null,
+ "locked": false,
+ "fontSize": 16,
+ "fontFamily": 3,
+ "text": "- merge main into minor before each minor release",
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "- merge main into minor before each minor release",
+ "lineHeight": 1.2,
+ "baseline": 15
+ },
+ {
+ "type": "text",
+ "version": 602,
+ "versionNonce": 1108720119,
+ "isDeleted": false,
+ "id": "mb9ZoP803MiH7MTO8wH-2",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dotted",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 305.0895924262568,
+ "y": 447.44321411383333,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#a5d8ff",
+ "width": 534.375,
+ "height": 19.2,
+ "seed": 264651479,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [],
+ "updated": 1698927613072,
+ "link": null,
+ "locked": false,
+ "fontSize": 16,
+ "fontFamily": 3,
+ "text": "- fast forward main to minor after a stable minor release",
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "- fast forward main to minor after a stable minor release",
+ "lineHeight": 1.2,
+ "baseline": 15
+ },
+ {
+ "type": "text",
+ "version": 612,
+ "versionNonce": 1588872441,
+ "isDeleted": false,
+ "id": "IfJPOFiwrCibpaBQqc5g-",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "angle": 0,
+ "x": 646.7131179044119,
+ "y": 724.4984335940012,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#ffc9c9",
+ "width": 131.25,
+ "height": 57.599999999999994,
+ "seed": 1301100087,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [],
+ "updated": 1698927613072,
+ "link": null,
+ "locked": false,
+ "fontSize": 16,
+ "fontFamily": 3,
+ "text": "merge main\ninto minor\nbefore release",
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "merge main\ninto minor\nbefore release",
+ "lineHeight": 1.2,
+ "baseline": 53
+ }
+ ],
+ "appState": {
+ "gridSize": null,
+ "viewBackgroundColor": "#ffffff"
+ },
+ "files": {}
+}
\ No newline at end of file
diff --git a/.github/git-branch-workflow.png b/.github/git-branch-workflow.png
new file mode 100644
index 00000000000..6c8ee07d484
Binary files /dev/null and b/.github/git-branch-workflow.png differ
diff --git a/.github/issue-workflow.png b/.github/issue-workflow.png
new file mode 100644
index 00000000000..92b1de0633c
Binary files /dev/null and b/.github/issue-workflow.png differ
diff --git a/.github/maintenance.md b/.github/maintenance.md
new file mode 100644
index 00000000000..b1fb550dd7a
--- /dev/null
+++ b/.github/maintenance.md
@@ -0,0 +1,123 @@
+# Vue Core Maintenance Handbook
+
+Unlike [contributing.md](./contributing.md), which targets external contributors, this document is mainly intended for team members responsible for maintaining the project. It provides guidelines on how to triage issues, review & merge PRs, and publish releases. However, it should also be valuable to external contributors even if you are not a maintainer, as it gives you a better idea of how the maintainers operate, and how you can better collaborate with them. And who knows - maybe one day you will join as a maintainer as well!
+
+- [Issue Triage Workflow](#issue-triage-workflow)
+- [Pull Request Review Guidelines](#pull-request-review-guidelines)
+ - [Reviewing a Fix](#reviewing-a-fix)
+ - [Reviewing a Refactor](#reviewing-a-refactor)
+ - [Reviewing a Feature](#reviewing-a-feature)
+ - [Common Considerations for All PRs](#common-considerations-for-all-prs)
+- [PR Merge Rules for Team Members](#pr-merge-rules-for-team-members)
+- [Git Branch and Release Workflow](#git-branch-and-release-workflow)
+
+## Issue Triage Workflow
+
+
+
+## Pull Request Review Guidelines
+
+The first step of reviewing a PR is to identify its purpose. We can usually put a PR in one of these categories:
+
+- **Fix**: fixes some wrong behavior. Usually associated with an issue that has a reproduction of the behavior being fixed.
+- **Refactor**: improves performance or code quality, but does not affect behavior.
+- **Feature**: implements something that increases the public API surface.
+
+Depending on the type of the PR, different considerations need to be taken into account.
+
+### Reviewing a Fix
+
+- Is the PR fixing a well defined issue / bug report?
+ - If not, ask to clarify context / provide reproduction or failing test case
+- In most cases, a fix PR should include a test case that fails without the fix.
+- Is it the right fix?
+ - If not, guide user to rework the PR.
+ - If the needed change is small and obvious, can directly push to the PR or add inline suggestions to reduce the back-and-forth.
+- Is the cost justified?
+ - Sometimes the fix for a rare edge case might be introducing disproportionately large overhead (perf or code size). We should try our best to reduce the overhead to make the fix a reasonable tradeoff.
+- If the reviewer is not sure about a fix, try to leave a comment explaining the concerns / reservations so the contributor at least gets some feedback.
+
+#### Verifying a Fix
+
+- **Always locally verify that the fix indeed fixes the original behavior, either through a reproduction or a failing test case.**
+- We will run [ecosystem-ci](https://github.com/vuejs/ecosystem-ci) before every release, but if you are concerned about the potential impact of a change, it never hurts to manually run ecosystem-ci by leaving a `/ecosystem-ci run` comment (only works for team members).
+- Take extra caution with snapshot tests! The CI can be "passing" even if the code generated in the snapshot contains bugs. It's best to always accompany a snapshot test with extra `expect(code).toMatch(...)` assertions.
+
+### Reviewing a Refactor
+
+- Performance: if a refactor PR claims to improve performance, there should be benchmarks showcasing said performance unless the improvement is self-explanatory.
+
+- Code quality / stylistic PRs: we should be conservative on merging this type PRs because (1) they can be subjective in many cases, and (2) they often come with large git diffs, causing merge conflicts with other pending PRs, and leading to unwanted noise when tracing changes through git history. Use your best judgement on this type of PRs on whether they are worth it.
+
+ - For PRs in this category that are approved, do not merge immediately. Group them before releasing a new minor, after all feature-oriented PRs are merged.
+
+### Reviewing a Feature
+
+- Feature PRs should always have clear context and explanation on why the feature should be added, ideally in the form of an RFC. If the PR doesn't explain what real-world problem it is solving, ask the contributor to clarify.
+
+- Decide if the feature should require an RFC process. The line isn't always clear, but a rough criteria is whether it is augmenting an existing API vs. adding a new API. Some examples:
+
+ - Adding a new built-in component or directive is "significant" and definitely requires an RFC.
+ - Template syntax additions like adding a new `v-on` modifier or a new `v-bind` syntax sugar are "substantial". It would be nice to have an RFC for it, but a detailed explanation on the use case and reasoning behind the design directly in the PR itself can be acceptable.
+ - Small, low-impact additions like exposing a new utility type or adding a new app config option can be self-explanatory, but should still provide enough context in the PR.
+
+- Always ask if the use case can be solved with existing APIs. Vue already has a pretty large API surface, so we want to make sure every new addition either solves something that wasn't possible before, or significantly improves the DX of a common task.
+
+### Common Considerations for All PRs
+
+- Scope: a PR should only contain changes directly related to the problem being addressed. It should not contain unnecessary code style changes.
+
+- Implementation: code style should be consistent with the rest of the codebase, follow common best practices. Prefer code that is boring but easy to understand over "clever" code.
+
+- Size: bundle size matters. We have a GitHub action that compares the size change for every PR. We should always aim to realize the desired changes with the smallest amount of code size increase.
+
+ - Sometimes we need to compare the size increase vs. perceived benefits to decide whether a change is justifiable. Also take extra care to make sure added code can be tree-shaken if not needed.
+
+ - Make sure to put dev-only code in `__DEV__` branches so they are tree-shakable.
+
+ - Runtime code is more sensitive to size increase than compiler code.
+
+ - Make sure it doesn't accidentally cause dev-only or compiler-only code branches to be included in the runtime build. Notable case is that some functions in @vue/shared are compiler-only and should not be used in runtime code, e.g. `isHTMLTag` and `isSVGTag`.
+
+- Performance
+
+ - Be careful about code changes in "hot paths", in particular the Virtual DOM renderer (`runtime-core/src/renderer.ts`) and component instantiation code.
+
+- Potential Breakage
+ - avoiding runtime behavior breakage is the highest priority
+ - if not sure, use `ecosystem-ci` to verify!
+ - some fix inevitably cause behavior change, these must be discussed case-by-case
+ - type level breakage (e.g upgrading TS) is possible between minors
+
+## PR Merge Rules for Team Members
+
+Given that the PR meets the review requirements:
+
+- Chore / dependencies bumps: can merge directly.
+- Fixes / refactors: can merge with two or more approvals from team members.
+ - If you believe a PR looks good but you are not 100% confident to merge, label with "ready for merge" and Evan will provide a final review before merging.
+- Features: if approved by two or more team members, label with "ready to merge". Evan will review periodically, or they can be raised and discussed at team meetings.
+
+## Git Branch and Release Workflow
+
+We use two primary work branches: `main` and `minor`.
+
+- The `main` branch is for stable releases. Changes that are bug fixes or refactors that do not affect the public API surface should land in this branch. We periodically release patch releases from the `main` branch.
+
+- The `minor` branch is the WIP branch for the next minor release. Changes that are new features or those that affect public API behavior should land in this branch. We will periodically release pre-releases (alpha / beta) for the next minor from this branch.
+
+Before each release, we merge latest `main` into `minor` so it would include the latest bug fixes.
+
+When the minor is ready, we do a final merge of `main` into `minor`, and then release a stable minor from this branch (e.g. `3.4.0`). After that, the `main` branch is fast-forwarded to the release commit, so the two branches are synced at each stable minor release.
+
+
+
+### Reasoning Behind the Workflow
+
+The reason behind this workflow is to allow merging and releasing of fixes and features in parallel. In the past, we used a linear trunk-based development model. While the linear model results in a clean git history, the downside is that we need to be careful about when to merge patches vs. features.
+
+Vue typically groups a number of features with the same scope in a minor release. We don't want to release a minor just because we happened to merge a feature PR along with a bunch of small bug fixes. So we usually "wait" until we feel we are ready to start working on a minor release before merging feature PRs.
+
+But in reality, there are always bugs to fix and patch release to work on - this caused the intervals between minors to drag on longer than we had hoped, and many feature PRs were left waiting for a long period of time.
+
+This is why we decided to separate bug fixes and feature PRs into separate branches. With this two-branch model, we are able to merge and release both types of changes in parallel.
diff --git a/.github/renovate.json5 b/.github/renovate.json5
new file mode 100644
index 00000000000..aad4afa132a
--- /dev/null
+++ b/.github/renovate.json5
@@ -0,0 +1,75 @@
+{
+ $schema: 'https://docs.renovatebot.com/renovate-schema.json',
+ extends: ['config:recommended', 'schedule:weekly', 'group:allNonMajor'],
+ labels: ['dependencies'],
+ ignorePaths: ['**/__tests__/**'],
+ rangeStrategy: 'bump',
+ packageRules: [
+ {
+ matchDepTypes: ['peerDependencies'],
+ enabled: false,
+ },
+ {
+ groupName: 'test',
+ matchPackageNames: ['vitest', 'jsdom', 'puppeteer', '@vitest{/,}**'],
+ },
+ {
+ groupName: 'playground',
+ matchFileNames: [
+ 'packages-private/sfc-playground/package.json',
+ 'packages-private/template-explorer/package.json',
+ ],
+ },
+ {
+ groupName: 'compiler',
+ matchPackageNames: ['magic-string', '@babel{/,}**', 'postcss{/,}**'],
+ },
+ {
+ groupName: 'build',
+ matchPackageNames: [
+ 'vite',
+ '@swc/core',
+ 'rollup{/,}**',
+ 'esbuild{/,}**',
+ '@rollup{/,}**',
+ '@vitejs{/,}**',
+ ],
+ },
+ {
+ groupName: 'lint',
+ matchPackageNames: [
+ 'simple-git-hooks',
+ 'lint-staged',
+ 'typescript-eslint{/,}**',
+ 'eslint{/,}**',
+ 'prettier{/,}**',
+ ],
+ },
+ ],
+ ignoreDeps: [
+ 'vue',
+
+ // manually bumping
+ 'node',
+ 'typescript',
+
+ // ESM only
+ 'estree-walker',
+
+ // pinned
+ // https://github.com/vuejs/core/issues/10300#issuecomment-1940855364
+ 'lru-cache',
+
+ // pinned
+ // https://github.com/vuejs/core/commit/a012e39b373f1b6918e5c89856e8f902e1bfa14d
+ '@rollup/plugin-replace',
+
+ // pinned
+ // only used in example for e2e tests
+ 'marked',
+
+ // pinned, 5.0+ has exports issues
+ // https://github.com/vuejs/core/issues/11603
+ 'entities',
+ ],
+}
diff --git a/.github/workflows/autofix.yml b/.github/workflows/autofix.yml
new file mode 100644
index 00000000000..9816f7f5257
--- /dev/null
+++ b/.github/workflows/autofix.yml
@@ -0,0 +1,34 @@
+name: autofix.ci
+
+on:
+ pull_request:
+permissions:
+ contents: read
+
+jobs:
+ autofix:
+ runs-on: ubuntu-latest
+ env:
+ PUPPETEER_SKIP_DOWNLOAD: 'true'
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Install pnpm
+ uses: pnpm/action-setup@v4.1.0
+
+ - name: Install Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version-file: '.node-version'
+ registry-url: 'https://registry.npmjs.org'
+ cache: 'pnpm'
+
+ - run: pnpm install
+
+ - name: Run eslint
+ run: pnpm run lint --fix
+
+ - name: Run prettier
+ run: pnpm run format
+
+ - uses: autofix-ci/action@551dded8c6cc8a1054039c8bc0b8b48c51dfc6ef
diff --git a/.github/workflows/canary-minor.yml b/.github/workflows/canary-minor.yml
new file mode 100644
index 00000000000..0b6401b8ce4
--- /dev/null
+++ b/.github/workflows/canary-minor.yml
@@ -0,0 +1,33 @@
+name: canary minor release
+on:
+ # Runs every Monday at 1 AM UTC (9:00 AM in Singapore)
+ schedule:
+ - cron: 0 1 * * MON
+ workflow_dispatch:
+
+jobs:
+ canary:
+ # prevents this action from running on forks
+ if: github.repository == 'vuejs/core'
+ runs-on: ubuntu-latest
+ environment: Release
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ ref: minor
+
+ - name: Install pnpm
+ uses: pnpm/action-setup@v4.1.0
+
+ - name: Install Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version-file: '.node-version'
+ registry-url: 'https://registry.npmjs.org'
+ cache: 'pnpm'
+
+ - run: pnpm install
+
+ - run: pnpm release --canary --publish --tag minor
+ env:
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
diff --git a/.github/workflows/canary.yml b/.github/workflows/canary.yml
new file mode 100644
index 00000000000..71c794c7078
--- /dev/null
+++ b/.github/workflows/canary.yml
@@ -0,0 +1,31 @@
+name: canary release
+on:
+ # Runs every Monday at 1 AM UTC (9:00 AM in Singapore)
+ schedule:
+ - cron: 0 1 * * MON
+ workflow_dispatch:
+
+jobs:
+ canary:
+ # prevents this action from running on forks
+ if: github.repository == 'vuejs/core'
+ runs-on: ubuntu-latest
+ environment: Release
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Install pnpm
+ uses: pnpm/action-setup@v4.1.0
+
+ - name: Install Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version-file: '.node-version'
+ registry-url: 'https://registry.npmjs.org'
+ cache: 'pnpm'
+
+ - run: pnpm install
+
+ - run: pnpm release --canary --publish
+ env:
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 00000000000..c8c217f62c4
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,42 @@
+name: 'ci'
+on:
+ push:
+ branches:
+ - '**'
+ tags:
+ - '!**'
+ pull_request:
+ branches:
+ - main
+ - minor
+
+jobs:
+ test:
+ if: ${{ ! startsWith(github.event.head_commit.message, 'release:') && (github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository) }}
+ uses: ./.github/workflows/test.yml
+
+ continuous-release:
+ if: github.repository == 'vuejs/core'
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - name: Install pnpm
+ uses: pnpm/action-setup@v4
+
+ - name: Install Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version-file: '.node-version'
+ registry-url: 'https://registry.npmjs.org'
+ cache: 'pnpm'
+
+ - name: Install deps
+ run: pnpm install
+
+ - name: Build
+ run: pnpm build --withTypes
+
+ - name: Release
+ run: pnpx pkg-pr-new publish --compact --pnpm './packages/*'
diff --git a/.github/workflows/close-cant-reproduce-issues.yml b/.github/workflows/close-cant-reproduce-issues.yml
new file mode 100644
index 00000000000..8fb48f842d8
--- /dev/null
+++ b/.github/workflows/close-cant-reproduce-issues.yml
@@ -0,0 +1,21 @@
+name: Auto close issues with "can't reproduce" label
+
+on:
+ schedule:
+ - cron: '0 0 * * *'
+
+permissions:
+ issues: write
+
+jobs:
+ close-issues:
+ if: github.repository == 'vuejs/core'
+ runs-on: ubuntu-latest
+ steps:
+ - name: can't reproduce
+ uses: actions-cool/issues-helper@v3
+ with:
+ actions: 'close-issues'
+ token: ${{ secrets.GITHUB_TOKEN }}
+ labels: "can't reproduce"
+ inactive-day: 3
diff --git a/.github/workflows/ecosystem-ci-trigger.yml b/.github/workflows/ecosystem-ci-trigger.yml
new file mode 100644
index 00000000000..b3e963ececa
--- /dev/null
+++ b/.github/workflows/ecosystem-ci-trigger.yml
@@ -0,0 +1,90 @@
+name: ecosystem-ci trigger
+
+on:
+ issue_comment:
+ types: [created]
+
+jobs:
+ trigger:
+ runs-on: ubuntu-latest
+ if: github.repository == 'vuejs/core' && github.event.issue.pull_request && startsWith(github.event.comment.body, '/ecosystem-ci run')
+ steps:
+ - name: Check user permission
+ uses: actions/github-script@v7
+ with:
+ script: |
+ const user = context.payload.sender.login
+ console.log(`Validate user: ${user}`)
+
+ let isVuejsMember = false
+ try {
+ const { status } = await github.rest.orgs.checkMembershipForUser({
+ org: 'vuejs',
+ username: user
+ });
+
+ isVuejsMember = (status === 204)
+ } catch (e) {}
+
+ if (isVuejsMember) {
+ console.log('Allowed')
+ await github.rest.reactions.createForIssueComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ comment_id: context.payload.comment.id,
+ content: '+1',
+ })
+ } else {
+ console.log('Not allowed')
+ await github.rest.reactions.createForIssueComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ comment_id: context.payload.comment.id,
+ content: '-1',
+ })
+ throw new Error('not allowed')
+ }
+ - name: Get PR info
+ uses: actions/github-script@v7
+ id: get-pr-data
+ with:
+ script: |
+ console.log(`Get PR info: ${context.repo.owner}/${context.repo.repo}#${context.issue.number}`)
+ const { data: pr } = await github.rest.pulls.get({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ pull_number: context.issue.number
+ })
+ return {
+ num: context.issue.number,
+ branchName: pr.head.ref,
+ repo: pr.head.repo.full_name,
+ commit: pr.head.sha
+ }
+ - name: Trigger run
+ uses: actions/github-script@v7
+ id: trigger
+ env:
+ COMMENT: ${{ github.event.comment.body }}
+ with:
+ github-token: ${{ secrets.ECOSYSTEM_CI_ACCESS_TOKEN }}
+ result-encoding: string
+ script: |
+ const comment = process.env.COMMENT.trim()
+ const prData = ${{ steps.get-pr-data.outputs.result }}
+
+ const suite = comment.replace(/^\/ecosystem-ci run/, '').trim()
+
+ await github.rest.actions.createWorkflowDispatch({
+ owner: context.repo.owner,
+ repo: 'ecosystem-ci',
+ workflow_id: 'ecosystem-ci-from-pr.yml',
+ ref: 'main',
+ inputs: {
+ prNumber: '' + prData.num,
+ branchName: prData.branchName,
+ repo: prData.repo,
+ suite: suite === '' ? '-' : suite,
+ commit: prData.commit
+ }
+ })
diff --git a/.github/workflows/lock-closed-issues.yml b/.github/workflows/lock-closed-issues.yml
new file mode 100644
index 00000000000..68a7d6c7a15
--- /dev/null
+++ b/.github/workflows/lock-closed-issues.yml
@@ -0,0 +1,20 @@
+name: Lock Closed Issues
+
+on:
+ schedule:
+ - cron: '0 0 * * *'
+
+permissions:
+ issues: write
+
+jobs:
+ action:
+ if: github.repository == 'vuejs/core'
+ runs-on: ubuntu-latest
+ steps:
+ - uses: dessant/lock-threads@v5
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ issue-inactive-days: '14'
+ issue-lock-reason: ''
+ process-only: 'issues'
diff --git a/.github/workflows/release-tag.yml b/.github/workflows/release-tag.yml
deleted file mode 100644
index 8781b44c872..00000000000
--- a/.github/workflows/release-tag.yml
+++ /dev/null
@@ -1,23 +0,0 @@
-on:
- push:
- tags:
- - 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10
-
-name: Create Release
-
-jobs:
- build:
- name: Create Release
- runs-on: ubuntu-latest
- steps:
- - name: Checkout code
- uses: actions/checkout@master
- - name: Create Release for Tag
- id: release_tag
- uses: yyx990803/release-tag@master
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- with:
- tag_name: ${{ github.ref }}
- body: |
- Please refer to [CHANGELOG.md](https://github.com/vuejs/vue-next/blob/master/CHANGELOG.md) for details.
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 00000000000..c260a728e71
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,55 @@
+name: Release
+
+on:
+ push:
+ tags:
+ - 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10
+
+jobs:
+ test:
+ uses: ./.github/workflows/test.yml
+
+ release:
+ # prevents this action from running on forks
+ if: github.repository == 'vuejs/core'
+ needs: [test]
+ runs-on: ubuntu-latest
+ permissions:
+ contents: write
+ id-token: write
+ # Use Release environment for deployment protection
+ environment: Release
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - name: Install pnpm
+ uses: pnpm/action-setup@v4
+
+ - name: Install Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version-file: '.node-version'
+ registry-url: 'https://registry.npmjs.org'
+ cache: 'pnpm'
+
+ - name: Install deps
+ run: pnpm install
+
+ - name: Build and publish
+ id: publish
+ run: |
+ pnpm release --publishOnly
+ env:
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
+
+ - name: Create GitHub release
+ id: release_tag
+ uses: yyx990803/release-tag@master
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ with:
+ tag_name: ${{ github.ref }}
+ body: |
+ For stable releases, please refer to [CHANGELOG.md](https://github.com/vuejs/core/blob/main/CHANGELOG.md) for details.
+ For pre-releases, please refer to [CHANGELOG.md](https://github.com/vuejs/core/blob/minor/CHANGELOG.md) of the `minor` branch.
diff --git a/.github/workflows/size-check.yml b/.github/workflows/size-check.yml
deleted file mode 100644
index 5fe9f52f904..00000000000
--- a/.github/workflows/size-check.yml
+++ /dev/null
@@ -1,22 +0,0 @@
-name: 'size'
-on:
- push:
- branches:
- - master
- pull_request:
- branches:
- - master
-jobs:
- size:
- runs-on: ubuntu-latest
- env:
- CI_JOB_NUMBER: 1
- steps:
- - uses: actions/checkout@v1
- - uses: bahmutov/npm-install@v1
-
- - uses: posva/size-check-action@v1.1.2
- with:
- github_token: ${{ secrets.GITHUB_TOKEN }}
- build_script: size
- files: packages/vue/dist/vue.global.prod.js packages/runtime-dom/dist/runtime-dom.global.prod.js packages/size-check/dist/size-check.global.prod.js
diff --git a/.github/workflows/size-data.yml b/.github/workflows/size-data.yml
new file mode 100644
index 00000000000..5a370b8b92f
--- /dev/null
+++ b/.github/workflows/size-data.yml
@@ -0,0 +1,51 @@
+name: size data
+
+on:
+ push:
+ branches:
+ - main
+ - minor
+ pull_request:
+ branches:
+ - main
+ - minor
+
+permissions:
+ contents: read
+
+env:
+ PUPPETEER_SKIP_DOWNLOAD: 'true'
+
+jobs:
+ upload:
+ if: github.repository == 'vuejs/core'
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Install pnpm
+ uses: pnpm/action-setup@v4.1.0
+
+ - name: Install Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version-file: '.node-version'
+ cache: pnpm
+
+ - name: Install dependencies
+ run: pnpm install
+
+ - run: pnpm run size
+
+ - name: Save PR number & base branch
+ if: ${{github.event_name == 'pull_request'}}
+ run: |
+ echo ${{ github.event.number }} > ./temp/size/number.txt
+ echo ${{ github.base_ref }} > ./temp/size/base.txt
+
+ - name: Upload Size Data
+ uses: actions/upload-artifact@v4
+ with:
+ name: size-data
+ path: temp/size
diff --git a/.github/workflows/size-report.yml b/.github/workflows/size-report.yml
new file mode 100644
index 00000000000..66b5ad0ef29
--- /dev/null
+++ b/.github/workflows/size-report.yml
@@ -0,0 +1,85 @@
+name: size report
+
+on:
+ workflow_run:
+ workflows: ['size data']
+ types:
+ - completed
+
+permissions:
+ contents: read
+ pull-requests: write
+ issues: write
+
+env:
+ PUPPETEER_SKIP_DOWNLOAD: 'true'
+
+jobs:
+ size-report:
+ runs-on: ubuntu-latest
+ if: >
+ github.repository == 'vuejs/core' &&
+ github.event.workflow_run.event == 'pull_request' &&
+ github.event.workflow_run.conclusion == 'success'
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Install pnpm
+ uses: pnpm/action-setup@v4.1.0
+
+ - name: Install Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version-file: '.node-version'
+ cache: pnpm
+
+ - name: Install dependencies
+ run: pnpm install
+
+ - name: Download Size Data
+ uses: dawidd6/action-download-artifact@v9
+ with:
+ name: size-data
+ run_id: ${{ github.event.workflow_run.id }}
+ path: temp/size
+
+ - name: Read PR Number
+ id: pr-number
+ uses: juliangruber/read-file-action@v1
+ with:
+ path: temp/size/number.txt
+
+ - name: Read base branch
+ id: pr-base
+ uses: juliangruber/read-file-action@v1
+ with:
+ path: temp/size/base.txt
+
+ - name: Download Previous Size Data
+ uses: dawidd6/action-download-artifact@v9
+ with:
+ branch: ${{ steps.pr-base.outputs.content }}
+ workflow: size-data.yml
+ event: push
+ name: size-data
+ path: temp/size-prev
+ if_no_artifact_found: warn
+
+ - name: Prepare report
+ run: node scripts/size-report.js > size-report.md
+
+ - name: Read Size Report
+ id: size-report
+ uses: juliangruber/read-file-action@v1
+ with:
+ path: ./size-report.md
+
+ - name: Create Comment
+ uses: actions-cool/maintain-one-comment@v3
+ with:
+ token: ${{ secrets.GITHUB_TOKEN }}
+ number: ${{ steps.pr-number.outputs.content }}
+ body: |
+ ${{ steps.size-report.outputs.content }}
+
+ body-include: ''
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
new file mode 100644
index 00000000000..1122eb35573
--- /dev/null
+++ b/.github/workflows/test.yml
@@ -0,0 +1,111 @@
+name: 'test'
+
+on: workflow_call
+
+permissions:
+ contents: read # to fetch code (actions/checkout)
+
+jobs:
+ unit-test:
+ runs-on: ubuntu-latest
+ env:
+ PUPPETEER_SKIP_DOWNLOAD: 'true'
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Install pnpm
+ uses: pnpm/action-setup@v4.1.0
+
+ - name: Install Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version-file: '.node-version'
+ cache: 'pnpm'
+
+ - run: pnpm install
+
+ - name: Run unit tests
+ run: pnpm run test-unit
+
+ unit-test-windows:
+ runs-on: windows-latest
+ env:
+ PUPPETEER_SKIP_DOWNLOAD: 'true'
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Install pnpm
+ uses: pnpm/action-setup@v4.1.0
+
+ - name: Install Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version-file: '.node-version'
+ cache: 'pnpm'
+
+ - run: pnpm install
+
+ - name: Run compiler unit tests
+ run: pnpm run test-unit compiler
+
+ - name: Run ssr unit tests
+ run: pnpm run test-unit server-renderer
+
+ e2e-test:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Setup cache for Chromium binary
+ uses: actions/cache@v4
+ with:
+ path: ~/.cache/puppeteer
+ key: chromium-${{ hashFiles('pnpm-lock.yaml') }}
+
+ - name: Install pnpm
+ uses: pnpm/action-setup@v4.1.0
+
+ - name: Install Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version-file: '.node-version'
+ cache: 'pnpm'
+
+ - run: pnpm install
+ - run: node node_modules/puppeteer/install.mjs
+
+ - name: Run e2e tests
+ run: pnpm run test-e2e
+
+ - name: verify treeshaking
+ run: node scripts/verify-treeshaking.js
+
+ lint-and-test-dts:
+ runs-on: ubuntu-latest
+ env:
+ PUPPETEER_SKIP_DOWNLOAD: 'true'
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Install pnpm
+ uses: pnpm/action-setup@v4.1.0
+
+ - name: Install Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version-file: '.node-version'
+ cache: 'pnpm'
+
+ - run: pnpm install
+
+ - name: Run eslint
+ run: pnpm run lint
+
+ - name: Run prettier
+ run: pnpm run format-check
+
+ - name: Run tsc
+ run: pnpm run check
+
+ - name: Run type declaration tests
+ run: pnpm run test-dts
diff --git a/.gitignore b/.gitignore
index 0a663edeb54..9dd21f59bf6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,3 +6,8 @@ temp
explorations
TODOs.md
*.log
+.idea
+.eslintcache
+dts-build/packages
+*.tsbuildinfo
+*.tgz
diff --git a/.node-version b/.node-version
new file mode 100644
index 00000000000..7d41c735d71
--- /dev/null
+++ b/.node-version
@@ -0,0 +1 @@
+22.14.0
diff --git a/.prettierignore b/.prettierignore
new file mode 100644
index 00000000000..ca3c40849fd
--- /dev/null
+++ b/.prettierignore
@@ -0,0 +1,3 @@
+dist
+pnpm-lock.yaml
+CHANGELOG*.md
diff --git a/.prettierrc b/.prettierrc
index f5a1bdcdd2d..759232e7cf6 100644
--- a/.prettierrc
+++ b/.prettierrc
@@ -1,3 +1,5 @@
-semi: false
-singleQuote: true
-printWidth: 80
+{
+ "semi": false,
+ "singleQuote": true,
+ "arrowParens": "avoid"
+}
diff --git a/.vscode/extensions.json b/.vscode/extensions.json
new file mode 100644
index 00000000000..91ebd56925c
--- /dev/null
+++ b/.vscode/extensions.json
@@ -0,0 +1,3 @@
+{
+ "recommendations": ["vitest.explorer"]
+}
diff --git a/.vscode/launch.json b/.vscode/launch.json
index b63ffc79b80..9fc03aa9bc4 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -5,24 +5,15 @@
"version": "0.2.0",
"configurations": [
{
- "name": "Jest",
"type": "node",
"request": "launch",
- "program": "${workspaceFolder}/node_modules/.bin/jest",
- "stopOnEntry": false,
- "args": ["${fileBasename}", "--runInBand", "--detectOpenHandles"],
- "cwd": "${workspaceFolder}",
- "preLaunchTask": null,
- "runtimeExecutable": null,
- "runtimeArgs": ["--nolazy"],
- "env": {
- "NODE_ENV": "development"
- },
- "console": "integratedTerminal",
- "sourceMaps": true,
- "windows": {
- "program": "${workspaceFolder}/node_modules/jest/bin/jest",
- }
+ "name": "Vitest - Debug Current Test File",
+ "autoAttachChildProcesses": true,
+ "skipFiles": ["
Sponsors & Backers
+
+Vue.js is an MIT-licensed open source project with its ongoing development made possible entirely by the support of the awesome sponsors and backers listed in this file. If you'd like to join them, please consider [ sponsoring Vue's development](https://vuejs.org/sponsor/).
+
+
+
+
Special Sponsor
+
+
+
+
+
+
+
+
+