From 47cdf241f23d7836f9c646dc82a4d38540c0dece Mon Sep 17 00:00:00 2001 From: Evan You Date: Thu, 8 Aug 2024 20:44:35 +0800 Subject: [PATCH] workflow: adjust release workflow --- .github/workflows/canary-minor.yml | 2 +- .github/workflows/canary.yml | 2 +- .github/workflows/release-gh.yml | 28 ----- .github/workflows/release.yml | 60 ++-------- scripts/release.js | 172 +++++++++++++++++------------ 5 files changed, 113 insertions(+), 151 deletions(-) delete mode 100644 .github/workflows/release-gh.yml diff --git a/.github/workflows/canary-minor.yml b/.github/workflows/canary-minor.yml index ffb9b384d4e..b5d75b9cebb 100644 --- a/.github/workflows/canary-minor.yml +++ b/.github/workflows/canary-minor.yml @@ -28,6 +28,6 @@ jobs: - run: pnpm install - - run: pnpm release --canary --tag minor + - 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 index a9432ced059..bb622725aa8 100644 --- a/.github/workflows/canary.yml +++ b/.github/workflows/canary.yml @@ -26,6 +26,6 @@ jobs: - run: pnpm install - - run: pnpm release --canary + - run: pnpm release --canary --publish env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.github/workflows/release-gh.yml b/.github/workflows/release-gh.yml deleted file mode 100644 index f0cc5601ff9..00000000000 --- a/.github/workflows/release-gh.yml +++ /dev/null @@ -1,28 +0,0 @@ -on: - push: - tags: - - 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10 - -name: Create GH Release for Tag - -permissions: {} -jobs: - build: - permissions: - contents: write # to create release (yyx990803/release-tag) - - 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: | - 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/release.yml b/.github/workflows/release.yml index 350245d3b45..d1ffa668d8c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,32 +1,9 @@ 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 + push: + tags: + - 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10 jobs: release: @@ -41,9 +18,6 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 - with: - ref: ${{ inputs.branch }} - fetch-depth: 0 # need this to get tags for changelog generation - name: Install pnpm uses: pnpm/action-setup@v4 @@ -58,38 +32,20 @@ jobs: - 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 + - name: Build and publish + id: publish 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 + pnpm release --publishOnly env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - - name: Push tags - run: git push -u origin ${{ inputs.branch }} --follow-tags - - - name: Create Release for Tag + - name: Create GitHub release id: release_tag uses: yyx990803/release-tag@master env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: - tag_name: ${{ steps.release.outputs.tag }} + 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/scripts/release.js b/scripts/release.js index a85ee866ec3..a3517c30728 100644 --- a/scripts/release.js +++ b/scripts/release.js @@ -51,6 +51,13 @@ const { values: args, positionals } = parseArgs({ skipPrompts: { type: 'boolean', }, + publish: { + type: 'boolean', + default: false, + }, + publishOnly: { + type: 'boolean', + }, }, }) @@ -247,41 +254,7 @@ async function main() { } } - if (!skipTests) { - step('Checking CI status for HEAD...') - let isCIPassed = await getCIResult() - skipTests ||= isCIPassed - - 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.', - ) - } - } - - if (!skipTests) { - step('\nRunning tests...') - if (!isDryRun) { - await run('pnpm', ['run', 'test', '--run']) - } else { - console.log(`Skipped (dry run)`) - } - } else { - step('Tests skipped.') - } + await runTestsIfNeeded() // update all package versions and inter-dependencies step('\nUpdating cross dependencies...') @@ -291,16 +264,6 @@ async function main() { ) versionUpdated = true - // build all packages with types - step('\nBuilding all packages...') - if (!skipBuild && !isDryRun) { - await run('pnpm', ['run', 'build', '--withTypes']) - step('\nTesting built types...') - await run('pnpm', ['test-dts-only']) - } else { - console.log(`(skipped)`) - } - // generate changelog step('\nGenerating changelog...') await run(`pnpm`, ['run', 'changelog']) @@ -337,29 +300,15 @@ async function main() { } // publish packages - step('\nPublishing packages...') - - const additionalPublishFlags = [] - if (isDryRun) { - additionalPublishFlags.push('--dry-run') - } - if (isDryRun || skipGit) { - additionalPublishFlags.push('--no-git-checks') - } - // bypass the pnpm --publish-branch restriction which isn't too useful to us - // otherwise it leads to a prompt and blocks the release script - const branch = await getBranch() - 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) + if (args.publish) { + await buildPackages() + await publishPackages(targetVersion) + } else { + console.log( + pico.yellow( + '\nPublish step skipped (will be done in GitHub actions on successful push)', + ), + ) } // push to GitHub @@ -386,6 +335,44 @@ async function main() { console.log() } +async function runTestsIfNeeded() { + if (!skipTests) { + step('Checking CI status for HEAD...') + let isCIPassed = await getCIResult() + skipTests ||= isCIPassed + + 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.', + ) + } + } + + if (!skipTests) { + step('\nRunning tests...') + if (!isDryRun) { + await run('pnpm', ['run', 'test', '--run']) + } else { + console.log(`Skipped (dry run)`) + } + } else { + step('Tests skipped.') + } +} + async function getCIResult() { try { const sha = await getSha() @@ -492,6 +479,46 @@ function updateDeps(pkg, depType, version, getNewPackageName) { }) } +async function buildPackages() { + step('\nBuilding all packages...') + if (!skipBuild) { + await run('pnpm', ['run', 'build', '--withTypes']) + } else { + console.log(`(skipped)`) + } +} + +/** + * @param {string} version + */ +async function publishPackages(version) { + // publish packages + step('\nPublishing packages...') + + const additionalPublishFlags = [] + if (isDryRun) { + additionalPublishFlags.push('--dry-run') + } + if (isDryRun || skipGit) { + additionalPublishFlags.push('--no-git-checks') + } + // bypass the pnpm --publish-branch restriction which isn't too useful to us + // otherwise it leads to a prompt and blocks the release script + const branch = await getBranch() + 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, version, additionalPublishFlags) + } +} + /** * @param {string} pkgName * @param {string} version @@ -541,7 +568,14 @@ async function publishPackage(pkgName, version, additionalFlags) { } } -main().catch(err => { +async function publishOnly() { + await buildPackages() + await publishPackages(currentVersion) +} + +const fnToRun = args.publishOnly ? publishOnly : main + +fnToRun().catch(err => { if (versionUpdated) { // revert to current version on failed releases updateVersions(currentVersion)