Skip to content

Commit

Permalink
meta: improve release process for beta branch (#3809)
Browse files Browse the repository at this point in the history
  • Loading branch information
aduh95 committed Jun 9, 2022
1 parent e00b9ed commit 2be8cec
Show file tree
Hide file tree
Showing 7 changed files with 153 additions and 14 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/release.yml
Expand Up @@ -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
Expand Down
56 changes: 56 additions & 0 deletions private/release/autoFixConflicts.js
@@ -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
}
}
24 changes: 23 additions & 1 deletion private/release/choose-semverness.js
Expand Up @@ -26,6 +26,7 @@ function maxSemverness (a, b) {
export default async function pickSemverness (
spawnOptions,
LAST_RELEASE_COMMIT,
STABLE_BRANCH_MERGE_BASE_RANGE,
releaseFileUrl,
packagesList,
) {
Expand Down Expand Up @@ -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')
Expand Down
55 changes: 53 additions & 2 deletions private/release/commit-and-open-pr.js
@@ -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',
Expand All @@ -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`
Expand Down
1 change: 1 addition & 0 deletions private/release/config.js
@@ -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'
21 changes: 15 additions & 6 deletions private/release/getUpToDateRefsFromGitHub.js
Expand Up @@ -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(
Expand All @@ -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(
Expand All @@ -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()
}
Expand Down Expand Up @@ -104,5 +113,5 @@ export async function validateGitStatus (spawnOptions) {
}
}

return [await latestRelease, LOCAL_HEAD]
return [await latestRelease, LOCAL_HEAD, ...getStableBranchMergeBase(REMOTE_HEAD)]
}
6 changes: 3 additions & 3 deletions private/release/interactive.js
Expand Up @@ -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)
Expand Down

0 comments on commit 2be8cec

Please sign in to comment.