mirror of
https://github.com/transloadit/uppy.git
synced 2026-07-27 04:05:10 +00:00
meta: improve release process for beta branch (#3809)
This commit is contained in:
parent
e00b9ed526
commit
2be8cec2af
7 changed files with 153 additions and 14 deletions
4
.github/workflows/release.yml
vendored
4
.github/workflows/release.yml
vendored
|
|
@ -84,8 +84,8 @@ jobs:
|
|||
run: gh api -X DELETE repos/${{ github.repository }}/git/refs/heads/release-candidate || echo "Already deleted"
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Remove release branch
|
||||
run: gh api -X DELETE repos/${{ github.repository }}/git/refs/heads/release
|
||||
- name: Remove release-beta branch
|
||||
run: gh api -X DELETE repos/${{ github.repository }}/git/refs/heads/release-beta
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Disable Release workflow
|
||||
|
|
|
|||
56
private/release/autoFixConflicts.js
Executable file
56
private/release/autoFixConflicts.js
Executable file
|
|
@ -0,0 +1,56 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
// Usage: autoFixConflicts.js | sh
|
||||
|
||||
import { createInterface as readLines } from 'node:readline'
|
||||
import { spawn } from 'node:child_process'
|
||||
|
||||
const VERSION_URL = /(?<=https:\/\/\S+\/v)\d+\.\d+\.\d+(?:-(?:alpha|beta)(?:[.-]\d+)?)?(?=\/)/
|
||||
|
||||
const gitStatus = spawn('git', ['status', '--porcelain'])
|
||||
|
||||
for await (const line of readLines(gitStatus.stdout)) {
|
||||
// eslint-disable-next-line no-continue
|
||||
if (!line.startsWith('UU ')) continue
|
||||
|
||||
const file = line.slice(3)
|
||||
if (file === 'yarn.lock') {
|
||||
console.log('corepack yarn install')
|
||||
console.log('git add yarn.lock')
|
||||
// eslint-disable-next-line no-continue
|
||||
continue
|
||||
}
|
||||
|
||||
if (file.endsWith('/package.json')) {
|
||||
console.log(`git checkout --ours ${file}`)
|
||||
console.log(`git add ${file}`)
|
||||
// eslint-disable-next-line no-continue
|
||||
continue
|
||||
}
|
||||
|
||||
const gitDiff = spawn('git', ['--no-pager', 'diff', '--', file])
|
||||
let conflictHasStarted = false
|
||||
let containsCDNChanges = true
|
||||
let currentConflictContainsCDNChanges = false
|
||||
|
||||
// eslint-disable-next-line no-shadow
|
||||
for await (const line of readLines(gitDiff.stdout)) {
|
||||
if (conflictHasStarted) {
|
||||
if (line.startsWith('++>>>>>>>')) {
|
||||
conflictHasStarted = false
|
||||
containsCDNChanges &&= currentConflictContainsCDNChanges
|
||||
currentConflictContainsCDNChanges = false
|
||||
} else {
|
||||
currentConflictContainsCDNChanges ||= VERSION_URL.test(line)
|
||||
}
|
||||
} else if (line === '++<<<<<<< HEAD') {
|
||||
conflictHasStarted = true
|
||||
}
|
||||
}
|
||||
if (containsCDNChanges) {
|
||||
console.log(`git checkout --ours ${file}`)
|
||||
console.log(`git add ${file}`)
|
||||
// eslint-disable-next-line no-continue
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
|
@ -26,6 +26,7 @@ function maxSemverness (a, b) {
|
|||
export default async function pickSemverness (
|
||||
spawnOptions,
|
||||
LAST_RELEASE_COMMIT,
|
||||
STABLE_BRANCH_MERGE_BASE_RANGE,
|
||||
releaseFileUrl,
|
||||
packagesList,
|
||||
) {
|
||||
|
|
@ -55,7 +56,28 @@ export default async function pickSemverness (
|
|||
spawnOptions,
|
||||
)
|
||||
if (stdout.length === 0) {
|
||||
console.log(`No commits since last release for ${name}, skipping.`)
|
||||
const { stdout } = spawnSync(
|
||||
'git',
|
||||
[
|
||||
'--no-pager',
|
||||
'log',
|
||||
'--format=- %s',
|
||||
STABLE_BRANCH_MERGE_BASE_RANGE,
|
||||
'--',
|
||||
location,
|
||||
],
|
||||
spawnOptions,
|
||||
)
|
||||
if (stdout.length === 0) {
|
||||
console.log(`No commits since last release for ${name}, skipping.`)
|
||||
} else {
|
||||
console.log(`Some commits have landed on the stable branch since last release for ${name}.`)
|
||||
releaseFile.write(` ${JSON.stringify(name)}: prerelease\n`)
|
||||
uppySemverness = maxSemverness(uppySemverness, 'prerelease')
|
||||
if (robodogDeps.includes(name)) {
|
||||
robodogSemverness = maxSemverness(robodogSemverness, 'prerelease')
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
console.log('\n')
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import { spawnSync } from 'node:child_process'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import prompts from 'prompts'
|
||||
import { REPO_OWNER, REPO_NAME } from './config.js'
|
||||
import { REPO_NAME, REPO_OWNER } from './config.js'
|
||||
|
||||
export default async function commit (spawnOptions, ...files) {
|
||||
export default async function commit (spawnOptions, STABLE_HEAD, ...files) {
|
||||
console.log(`Now is the time to do manual edits to ${files.join(',')}.`)
|
||||
await prompts({
|
||||
type: 'toggle',
|
||||
|
|
@ -15,8 +15,59 @@ export default async function commit (spawnOptions, ...files) {
|
|||
})
|
||||
|
||||
spawnSync('git', ['add', ...files.map(url => fileURLToPath(url))], spawnOptions)
|
||||
const remoteHeadSha = spawnSync('git', ['rev-parse', 'HEAD'], spawnOptions).stdout.toString().trim()
|
||||
spawnSync('git', ['commit', '-n', '-m', 'Prepare next release'], { ...spawnOptions, stdio: 'inherit' })
|
||||
const releaseSha = spawnSync('git', ['rev-parse', 'HEAD'], spawnOptions).stdout.toString().trim()
|
||||
|
||||
console.log('Attempting to merge changes from stable branch...')
|
||||
{
|
||||
// eslint-disable-next-line no-shadow
|
||||
const { status, stdout, stderr } = spawnSync(
|
||||
'git',
|
||||
[
|
||||
'merge',
|
||||
'--no-edit',
|
||||
'-m',
|
||||
'Merge stable branch',
|
||||
STABLE_HEAD,
|
||||
],
|
||||
spawnOptions,
|
||||
)
|
||||
if (status) {
|
||||
console.log(stdout.toString())
|
||||
console.error(stderr.toString())
|
||||
|
||||
await prompts({
|
||||
type: 'toggle',
|
||||
name: 'value',
|
||||
message: 'Fix the conflict before continuing. Ready?',
|
||||
initial: true,
|
||||
active: 'yes',
|
||||
inactive: 'yes',
|
||||
})
|
||||
|
||||
// eslint-disable-next-line no-shadow
|
||||
const { status } = spawnSync(
|
||||
'git',
|
||||
[
|
||||
'merge',
|
||||
'--continue',
|
||||
],
|
||||
{ ...spawnOptions, stdio: 'inherit' },
|
||||
)
|
||||
|
||||
if (status) {
|
||||
throw new Error('Merge has failed')
|
||||
}
|
||||
}
|
||||
}
|
||||
const mergeSha = spawnSync('git', ['rev-parse', 'HEAD'], spawnOptions).stdout.toString().trim()
|
||||
|
||||
spawnSync('git', ['reset', remoteHeadSha, '--hard'], spawnOptions)
|
||||
spawnSync('git', ['cherry-pick', mergeSha, '--hard'], spawnOptions)
|
||||
spawnSync('git', ['cherry-pick', releaseSha, '--hard'], spawnOptions)
|
||||
const sha = spawnSync('git', ['rev-parse', 'HEAD'], spawnOptions).stdout.toString().trim()
|
||||
|
||||
const getRemoteCommamnd = `git remote -v | grep '${REPO_OWNER}/${REPO_NAME}' | awk '($3 == "(push)") { print $1; exit }'`
|
||||
const remote = spawnSync('/bin/sh', ['-c', getRemoteCommamnd]).stdout.toString().trim()
|
||||
|| `git@github.com:${REPO_OWNER}/${REPO_NAME}.git`
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
export const REPO_OWNER = 'transloadit'
|
||||
export const REPO_NAME = 'uppy'
|
||||
export const TARGET_BRANCH = '3.x'
|
||||
export const STABLE_BRANCH = 'main'
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import fetch from 'node-fetch'
|
|||
|
||||
import { spawnSync } from 'node:child_process'
|
||||
import prompts from 'prompts'
|
||||
import { TARGET_BRANCH, REPO_NAME, REPO_OWNER } from './config.js'
|
||||
import { TARGET_BRANCH, REPO_NAME, REPO_OWNER, STABLE_BRANCH } from './config.js'
|
||||
|
||||
async function apiCall (endpoint, errorMessage) {
|
||||
const response = await fetch(
|
||||
|
|
@ -25,10 +25,10 @@ export async function getRemoteHEAD () {
|
|||
}
|
||||
|
||||
async function getLatestReleaseSHA () {
|
||||
const { tag_name } = await apiCall(
|
||||
`/releases/latest`,
|
||||
'Cannot get latest release from GitHub, check your internet connection.',
|
||||
)
|
||||
const response = await fetch(`https://raw.githubusercontent.com/${REPO_OWNER}/${REPO_NAME}/${TARGET_BRANCH}/packages/uppy/package.json`)
|
||||
if (!response.ok) throw new Error(`Network call failed: ${response.status} ${response.statusText}`)
|
||||
const { version } = await response.json()
|
||||
const tag_name = `uppy@${version}`
|
||||
console.log(`Last release was ${tag_name}.`)
|
||||
return (
|
||||
await apiCall(
|
||||
|
|
@ -38,6 +38,15 @@ async function getLatestReleaseSHA () {
|
|||
).object.sha
|
||||
}
|
||||
|
||||
function getStableBranchMergeBase (REMOTE_HEAD) {
|
||||
spawnSync('git', ['fetch', `https://github.com/${REPO_OWNER}/${REPO_NAME}.git`, STABLE_BRANCH])
|
||||
const STABLE_HEAD = spawnSync('git', ['rev-parse', 'FETCH_HEAD']).stdout.toString().trim()
|
||||
return [[
|
||||
spawnSync('git', ['merge-base', REMOTE_HEAD, 'FETCH_HEAD']).stdout.toString().trim(),
|
||||
STABLE_HEAD,
|
||||
].join('..'), STABLE_HEAD]
|
||||
}
|
||||
|
||||
async function getLocalHEAD () {
|
||||
return spawnSync('git', ['rev-parse', 'HEAD']).stdout.toString().trim()
|
||||
}
|
||||
|
|
@ -104,5 +113,5 @@ export async function validateGitStatus (spawnOptions) {
|
|||
}
|
||||
}
|
||||
|
||||
return [await latestRelease, LOCAL_HEAD]
|
||||
return [await latestRelease, LOCAL_HEAD, ...getStableBranchMergeBase(REMOTE_HEAD)]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,14 +14,14 @@ const deferredReleaseFile = new URL('./.yarn/versions/next.yml', ROOT)
|
|||
const temporaryChangeLog = new URL('./CHANGELOG.next.md', ROOT)
|
||||
|
||||
console.log('Validating local repo status and get previous release info...')
|
||||
const [LAST_RELEASE_COMMIT, LOCAL_HEAD] = await validateGitStatus(spawnOptions)
|
||||
const [LAST_RELEASE_COMMIT, LOCAL_HEAD, MERGE_BASE, STABLE_HEAD] = await validateGitStatus(spawnOptions)
|
||||
try {
|
||||
console.log('Local git repository is ready, starting release process...')
|
||||
await pickSemverness(spawnOptions, LAST_RELEASE_COMMIT, deferredReleaseFile, process.env.PACKAGES.split(' '))
|
||||
await pickSemverness(spawnOptions, LAST_RELEASE_COMMIT, MERGE_BASE, deferredReleaseFile, process.env.PACKAGES.split(' '))
|
||||
console.log('Working on the changelog...')
|
||||
await formatChangeLog(spawnOptions, LAST_RELEASE_COMMIT, temporaryChangeLog)
|
||||
console.log('Final step...')
|
||||
await commit(spawnOptions, deferredReleaseFile, temporaryChangeLog)
|
||||
await commit(spawnOptions, STABLE_HEAD, deferredReleaseFile, temporaryChangeLog)
|
||||
} finally {
|
||||
console.log('Rewinding git history...')
|
||||
await rewindGitHistory(spawnOptions, LOCAL_HEAD)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue