workflow: adjust release workflow

This commit is contained in:
Evan You 2024-08-08 20:44:35 +08:00
parent 32a1433e0d
commit 47cdf241f2
No known key found for this signature in database
GPG Key ID: 00E9AB7A6704CE0A
5 changed files with 113 additions and 151 deletions

View File

@ -28,6 +28,6 @@ jobs:
- run: pnpm install - run: pnpm install
- run: pnpm release --canary --tag minor - run: pnpm release --canary --publish --tag minor
env: env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

View File

@ -26,6 +26,6 @@ jobs:
- run: pnpm install - run: pnpm install
- run: pnpm release --canary - run: pnpm release --canary --publish
env: env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

View File

@ -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.

View File

@ -1,32 +1,9 @@
name: Release name: Release
on: on:
workflow_dispatch: push:
inputs: tags:
branch: - 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10
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: jobs:
release: release:
@ -41,9 +18,6 @@ jobs:
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v4
with:
ref: ${{ inputs.branch }}
fetch-depth: 0 # need this to get tags for changelog generation
- name: Install pnpm - name: Install pnpm
uses: pnpm/action-setup@v4 uses: pnpm/action-setup@v4
@ -58,38 +32,20 @@ jobs:
- name: Install deps - name: Install deps
run: pnpm install run: pnpm install
- name: Configure git user as vue bot - name: Build and publish
id: publish
run: | run: |
git config user.name "vue-bot" pnpm release --publishOnly
git config user.email "<bot@vuejs.org>"
- 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: env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Push tags - name: Create GitHub release
run: git push -u origin ${{ inputs.branch }} --follow-tags
- name: Create Release for Tag
id: release_tag id: release_tag
uses: yyx990803/release-tag@master uses: yyx990803/release-tag@master
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with: with:
tag_name: ${{ steps.release.outputs.tag }} tag_name: ${{ github.ref }}
body: | body: |
For stable releases, please refer to [CHANGELOG.md](https://github.com/vuejs/core/blob/main/CHANGELOG.md) for details. 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. For pre-releases, please refer to [CHANGELOG.md](https://github.com/vuejs/core/blob/minor/CHANGELOG.md) of the `minor` branch.

View File

@ -51,6 +51,13 @@ const { values: args, positionals } = parseArgs({
skipPrompts: { skipPrompts: {
type: 'boolean', type: 'boolean',
}, },
publish: {
type: 'boolean',
default: false,
},
publishOnly: {
type: 'boolean',
},
}, },
}) })
@ -247,41 +254,7 @@ async function main() {
} }
} }
if (!skipTests) { await runTestsIfNeeded()
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.')
}
// update all package versions and inter-dependencies // update all package versions and inter-dependencies
step('\nUpdating cross dependencies...') step('\nUpdating cross dependencies...')
@ -291,16 +264,6 @@ async function main() {
) )
versionUpdated = true 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 // generate changelog
step('\nGenerating changelog...') step('\nGenerating changelog...')
await run(`pnpm`, ['run', 'changelog']) await run(`pnpm`, ['run', 'changelog'])
@ -337,29 +300,15 @@ async function main() {
} }
// publish packages // publish packages
step('\nPublishing packages...') if (args.publish) {
await buildPackages()
const additionalPublishFlags = [] await publishPackages(targetVersion)
if (isDryRun) { } else {
additionalPublishFlags.push('--dry-run') console.log(
} pico.yellow(
if (isDryRun || skipGit) { '\nPublish step skipped (will be done in GitHub actions on successful push)',
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)
} }
// push to GitHub // push to GitHub
@ -386,6 +335,44 @@ async function main() {
console.log() 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() { async function getCIResult() {
try { try {
const sha = await getSha() 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} pkgName
* @param {string} version * @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) { if (versionUpdated) {
// revert to current version on failed releases // revert to current version on failed releases
updateVersions(currentVersion) updateVersions(currentVersion)