diff --git a/.github/workflows/release-tag.yml b/.github/workflows/release-gh.yml similarity index 96% rename from .github/workflows/release-tag.yml rename to .github/workflows/release-gh.yml index d93510607a9..f0cc5601ff9 100644 --- a/.github/workflows/release-tag.yml +++ b/.github/workflows/release-gh.yml @@ -3,7 +3,7 @@ on: tags: - 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10 -name: Create Release +name: Create GH Release for Tag permissions: {} jobs: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000000..fcf0c3fac51 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,94 @@ +name: Release + +on: + workflow_dispatch: + inputs: + branch: + description: 'Branch to publish' + required: true + default: 'main' + type: choice + options: + - main + - minor + bump: + description: 'Bump version' + required: true + default: 'patch' + type: choice + options: + - patch + - minor + - prepatch + - preminor + - custom + custom_version: + description: 'Custom version' + required: false + default: '' + type: string + +jobs: + release: + # prevents this action from running on forks + if: github.repository == 'vuejs/core' + 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 + with: + ref: ${{ inputs.branch }} + + - 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: Configure git user as vue bot + run: | + git config user.name "vue-bot" + git config user.email "" + + - name: Import GPG key + uses: crazy-max/ghaction-import-gpg@v6 + with: + gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} + passphrase: ${{ secrets.GPG_PASSPHRASE }} + git_user_signingkey: true + git_commit_gpgsign: true + + - name: Run release script + id: release + run: | + pnpm release ${{ inputs.bump != 'custom' && inputs.bump || inputs.custom_version }} --skipPrompts + RELEASE_TAG=$(git describe --tags --abbrev=0) + echo "tag=$RELEASE_TAG" >> $GITHUB_OUTPUT + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + + - name: Push tags + run: git push -u origin ${{ inputs.branch }} --follow-tags + + - name: Create Release for Tag + id: release_tag + uses: yyx990803/release-tag@master + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: ${{ steps.release.outputs.tag }} + 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-data.yml b/.github/workflows/size-data.yml index a702d0fef90..664f75aeeca 100644 --- a/.github/workflows/size-data.yml +++ b/.github/workflows/size-data.yml @@ -4,6 +4,7 @@ on: push: branches: - main + - minor pull_request: branches: - main diff --git a/.github/workflows/size-report.yml b/.github/workflows/size-report.yml index 5cec662874e..25c93d8ed04 100644 --- a/.github/workflows/size-report.yml +++ b/.github/workflows/size-report.yml @@ -58,7 +58,7 @@ jobs: - name: Download Previous Size Data uses: dawidd6/action-download-artifact@v6 with: - branch: main + branch: ${{ github.base_ref }} workflow: size-data.yml event: push name: size-data diff --git a/CHANGELOG.md b/CHANGELOG.md index 70d5e5a1ea4..efa86394958 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,16 @@ +## [3.4.36](https://github.com/vuejs/core/compare/v3.4.35...v3.4.36) (2024-08-06) + +### Bug Fixes + +* **compiler-core:** fix expression transform for try...catch block params ([077a1ae](https://github.com/vuejs/core/commit/077a1aeb3c222b729a7e190f46864656ecc65325)), closes [#11465](https://github.com/vuejs/core/issues/11465) [#11467](https://github.com/vuejs/core/issues/11467) +* **compiler-core:** properly handle for loop variable declarations in expression transforms ([67bb820](https://github.com/vuejs/core/commit/67bb820904d53480fa37536fc3cb4109a4c6d3e2)), ref [#11467](https://github.com/vuejs/core/issues/11467) +* **compiler-ssr:** don't render v-if comments in TransitionGroup + static tag ([#11515](https://github.com/vuejs/core/issues/11515)) ([275354c](https://github.com/vuejs/core/commit/275354caba295a6fb50695b70e97888a33c504e0)), closes [#11514](https://github.com/vuejs/core/issues/11514) +* **hydration:** force hydrate custom element dynamic props ([7d473b7](https://github.com/vuejs/core/commit/7d473b7721b423050dba62823b16f3d39e640567)), closes [#7203](https://github.com/vuejs/core/issues/7203) [#8038](https://github.com/vuejs/core/issues/8038) +* **ssr:** respect textContent/innerHTML from getSSRProps in optimized SSR output ([79602f9](https://github.com/vuejs/core/commit/79602f9ecd9559954f844774a90286305b13e056)), closes [#8112](https://github.com/vuejs/core/issues/8112) +* **types/withDefaults:** ensure default values of type `any` do not include `undefined` ([#11490](https://github.com/vuejs/core/issues/11490)) ([4592b63](https://github.com/vuejs/core/commit/4592b63c6a8a3d69bfe4ac1f9458b4a86a9676a4)) + + + ## [3.4.35](https://github.com/vuejs/core/compare/v3.4.34...v3.4.35) (2024-07-31) diff --git a/package.json b/package.json index 20f244a4d21..87f10e911b0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "private": true, - "version": "3.4.35", + "version": "3.4.36", "packageManager": "pnpm@9.6.0", "type": "module", "scripts": { diff --git a/packages/compiler-core/package.json b/packages/compiler-core/package.json index b9a4f58c911..a268685df0a 100644 --- a/packages/compiler-core/package.json +++ b/packages/compiler-core/package.json @@ -1,6 +1,6 @@ { "name": "@vue/compiler-core", - "version": "3.4.35", + "version": "3.4.36", "description": "@vue/compiler-core", "main": "index.js", "module": "dist/compiler-core.esm-bundler.js", diff --git a/packages/compiler-dom/package.json b/packages/compiler-dom/package.json index f988fa1dd70..6b28a5f209c 100644 --- a/packages/compiler-dom/package.json +++ b/packages/compiler-dom/package.json @@ -1,6 +1,6 @@ { "name": "@vue/compiler-dom", - "version": "3.4.35", + "version": "3.4.36", "description": "@vue/compiler-dom", "main": "index.js", "module": "dist/compiler-dom.esm-bundler.js", diff --git a/packages/compiler-sfc/package.json b/packages/compiler-sfc/package.json index d90375fcd05..f5834ed0ad9 100644 --- a/packages/compiler-sfc/package.json +++ b/packages/compiler-sfc/package.json @@ -1,6 +1,6 @@ { "name": "@vue/compiler-sfc", - "version": "3.4.35", + "version": "3.4.36", "description": "@vue/compiler-sfc", "main": "dist/compiler-sfc.cjs.js", "module": "dist/compiler-sfc.esm-browser.js", diff --git a/packages/compiler-ssr/__tests__/ssrElement.spec.ts b/packages/compiler-ssr/__tests__/ssrElement.spec.ts index 4056b4c3c71..723ef7b3592 100644 --- a/packages/compiler-ssr/__tests__/ssrElement.spec.ts +++ b/packages/compiler-ssr/__tests__/ssrElement.spec.ts @@ -288,12 +288,27 @@ describe('ssr: element', () => { }>\`" `) }) + }) - test('custom dir', () => { + describe('custom directives', () => { + // #8112 should respect textContent / innerHTML from directive getSSRProps + // if the element has no children + test('custom dir without children', () => { expect(getCompiledString(`
`)).toMatchInlineSnapshot(` + "\`\${ + ("textContent" in _temp0) ? _ssrInterpolate(_temp0.textContent) : _temp0.innerHTML ?? '' + }
\`" + `) + }) + + test('custom dir with children', () => { + expect(getCompiledString(`
hello
`)) + .toMatchInlineSnapshot(` "\`\`" + }>hello\`" `) }) @@ -301,30 +316,36 @@ describe('ssr: element', () => { expect(getCompiledString(`
`)) .toMatchInlineSnapshot(` "\`
\`" + _ssrRenderAttrs(_temp0 = _mergeProps({ class: "foo" }, _ssrGetDirectiveProps(_ctx, _directive_xxx))) + }>\${ + ("textContent" in _temp0) ? _ssrInterpolate(_temp0.textContent) : _temp0.innerHTML ?? '' + }\`" `) }) test('custom dir with v-bind', () => { expect(getCompiledString(`
`)) .toMatchInlineSnapshot(` - "\`
\`" - `) + "\`\${ + ("textContent" in _temp0) ? _ssrInterpolate(_temp0.textContent) : _temp0.innerHTML ?? '' + }\`" + `) }) test('custom dir with object v-bind', () => { expect(getCompiledString(`
`)) .toMatchInlineSnapshot(` - "\`
\`" - `) + "\`\${ + ("textContent" in _temp0) ? _ssrInterpolate(_temp0.textContent) : _temp0.innerHTML ?? '' + }\`" + `) }) test('custom dir with object v-bind + normal bindings', () => { @@ -332,11 +353,13 @@ describe('ssr: element', () => { getCompiledString(`
`), ).toMatchInlineSnapshot(` "\`
\`" + }>\${ + ("textContent" in _temp0) ? _ssrInterpolate(_temp0.textContent) : _temp0.innerHTML ?? '' + }\`" `) }) }) diff --git a/packages/compiler-ssr/__tests__/ssrTransitionGroup.spec.ts b/packages/compiler-ssr/__tests__/ssrTransitionGroup.spec.ts index 905e6a4895d..431ebaa77ee 100644 --- a/packages/compiler-ssr/__tests__/ssrTransitionGroup.spec.ts +++ b/packages/compiler-ssr/__tests__/ssrTransitionGroup.spec.ts @@ -38,6 +38,28 @@ describe('transition-group', () => { `) }) + // #11514 + test('with static tag + comment', () => { + expect( + compile( + `
`, + ).code, + ).toMatchInlineSnapshot(` + "const { ssrRenderAttrs: _ssrRenderAttrs, ssrRenderList: _ssrRenderList } = require("vue/server-renderer") + + return function ssrRender(_ctx, _push, _parent, _attrs) { + _push(\`\`) + _ssrRenderList(_ctx.list, (i) => { + _push(\`
\`) + }) + if (false) { + _push(\`
\`) + } + _push(\`\`) + }" + `) + }) + test('with dynamic tag', () => { expect( compile( diff --git a/packages/compiler-ssr/package.json b/packages/compiler-ssr/package.json index 7876676326a..bf1045952ae 100644 --- a/packages/compiler-ssr/package.json +++ b/packages/compiler-ssr/package.json @@ -1,6 +1,6 @@ { "name": "@vue/compiler-ssr", - "version": "3.4.35", + "version": "3.4.36", "description": "@vue/compiler-ssr", "main": "dist/compiler-ssr.cjs.js", "types": "dist/compiler-ssr.d.ts", diff --git a/packages/compiler-ssr/src/transforms/ssrTransformElement.ts b/packages/compiler-ssr/src/transforms/ssrTransformElement.ts index 7175b797d48..45d4d76fe9a 100644 --- a/packages/compiler-ssr/src/transforms/ssrTransformElement.ts +++ b/packages/compiler-ssr/src/transforms/ssrTransformElement.ts @@ -163,6 +163,25 @@ export const ssrTransformElement: NodeTransform = (node, context) => { ]), ] } + } else if (directives.length && !node.children.length) { + const tempId = `_temp${context.temps++}` + propsExp.arguments = [ + createAssignmentExpression( + createSimpleExpression(tempId, false), + mergedProps, + ), + ] + rawChildrenMap.set( + node, + createConditionalExpression( + createSimpleExpression(`"textContent" in ${tempId}`, false), + createCallExpression(context.helper(SSR_INTERPOLATE), [ + createSimpleExpression(`${tempId}.textContent`, false), + ]), + createSimpleExpression(`${tempId}.innerHTML ?? ''`, false), + false, + ), + ) } if (needTagForRuntime) { diff --git a/packages/compiler-ssr/src/transforms/ssrTransformTransitionGroup.ts b/packages/compiler-ssr/src/transforms/ssrTransformTransitionGroup.ts index a2e284ae841..1d99a691094 100644 --- a/packages/compiler-ssr/src/transforms/ssrTransformTransitionGroup.ts +++ b/packages/compiler-ssr/src/transforms/ssrTransformTransitionGroup.ts @@ -108,7 +108,7 @@ export function ssrProcessTransitionGroup( context.pushStringPart(` ${scopeId}`) } context.pushStringPart(`>`) - processChildren(node, context, false, true) + processChildren(node, context, false, true, true) context.pushStringPart(``) } } else { diff --git a/packages/reactivity/package.json b/packages/reactivity/package.json index 9da115b811a..37faf6c6921 100644 --- a/packages/reactivity/package.json +++ b/packages/reactivity/package.json @@ -1,6 +1,6 @@ { "name": "@vue/reactivity", - "version": "3.4.35", + "version": "3.4.36", "description": "@vue/reactivity", "main": "index.js", "module": "dist/reactivity.esm-bundler.js", diff --git a/packages/runtime-core/package.json b/packages/runtime-core/package.json index 614f2beb793..f6f2533de20 100644 --- a/packages/runtime-core/package.json +++ b/packages/runtime-core/package.json @@ -1,6 +1,6 @@ { "name": "@vue/runtime-core", - "version": "3.4.35", + "version": "3.4.36", "description": "@vue/runtime-core", "main": "index.js", "module": "dist/runtime-core.esm-bundler.js", diff --git a/packages/runtime-dom/package.json b/packages/runtime-dom/package.json index f01d252b612..a0a0113114f 100644 --- a/packages/runtime-dom/package.json +++ b/packages/runtime-dom/package.json @@ -1,6 +1,6 @@ { "name": "@vue/runtime-dom", - "version": "3.4.35", + "version": "3.4.36", "description": "@vue/runtime-dom", "main": "index.js", "module": "dist/runtime-dom.esm-bundler.js", diff --git a/packages/server-renderer/package.json b/packages/server-renderer/package.json index 18d1a92f0d2..cc7c27b610c 100644 --- a/packages/server-renderer/package.json +++ b/packages/server-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@vue/server-renderer", - "version": "3.4.35", + "version": "3.4.36", "description": "@vue/server-renderer", "main": "index.js", "module": "dist/server-renderer.esm-bundler.js", diff --git a/packages/shared/package.json b/packages/shared/package.json index f0eadfca16d..26324eeaf77 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -1,6 +1,6 @@ { "name": "@vue/shared", - "version": "3.4.35", + "version": "3.4.36", "description": "internal utils shared across @vue packages", "main": "index.js", "module": "dist/shared.esm-bundler.js", diff --git a/packages/vue-compat/package.json b/packages/vue-compat/package.json index 18d818f3e41..cbcf29a5a7a 100644 --- a/packages/vue-compat/package.json +++ b/packages/vue-compat/package.json @@ -1,6 +1,6 @@ { "name": "@vue/compat", - "version": "3.4.35", + "version": "3.4.36", "description": "Vue 3 compatibility build for Vue 2", "main": "index.js", "module": "dist/vue.runtime.esm-bundler.js", diff --git a/packages/vue/package.json b/packages/vue/package.json index 891900f875e..1a1e1ee324d 100644 --- a/packages/vue/package.json +++ b/packages/vue/package.json @@ -1,6 +1,6 @@ { "name": "vue", - "version": "3.4.35", + "version": "3.4.36", "description": "The progressive JavaScript framework for building modern web UI.", "main": "index.js", "module": "dist/vue.runtime.esm-bundler.js", diff --git a/scripts/release.js b/scripts/release.js index eed71c2fd19..a85ee866ec3 100644 --- a/scripts/release.js +++ b/scripts/release.js @@ -218,6 +218,12 @@ async function main() { } } + // @ts-expect-error + if (versionIncrements.includes(targetVersion)) { + // @ts-expect-error + targetVersion = inc(targetVersion) + } + if (!semver.valid(targetVersion)) { throw new Error(`invalid target version: ${targetVersion}`) } @@ -246,15 +252,23 @@ async function main() { let isCIPassed = await getCIResult() skipTests ||= isCIPassed - if (isCIPassed && !skipPrompts) { - /** @type {{ yes: boolean }} */ - const { yes: promptSkipTests } = await prompt({ - type: 'confirm', - name: 'yes', - message: `CI for this commit passed. Skip local tests?`, - }) - - skipTests = promptSkipTests + if (isCIPassed) { + if (!skipPrompts) { + /** @type {{ yes: boolean }} */ + const { yes: promptSkipTests } = await prompt({ + type: 'confirm', + name: 'yes', + message: `CI for this commit passed. Skip local tests?`, + }) + skipTests = promptSkipTests + } else { + skipTests = true + } + } else if (skipPrompts) { + throw new Error( + 'CI for the latest commit has not passed yet. ' + + 'Only run the release workflow after the CI has passed.', + ) } } @@ -338,6 +352,11 @@ async function main() { if (branch !== 'main') { additionalPublishFlags.push('--publish-branch', branch) } + // add provenance metadata when releasing from CI + // canary release commits are not pushed therefore we don't need to add provenance + if (process.env.CI && !isCanary) { + additionalPublishFlags.push('--provenance') + } for (const pkg of packages) { await publishPackage(pkg, targetVersion, additionalPublishFlags) @@ -514,7 +533,7 @@ async function publishPackage(pkgName, version, additionalFlags) { ) console.log(pico.green(`Successfully published ${pkgName}@${version}`)) } catch (/** @type {any} */ e) { - if (e.stderr.match(/previously published/)) { + if (e.message?.match(/previously published/)) { console.log(pico.red(`Skipping already published: ${pkgName}`)) } else { throw e