import execa from 'execa' ; import chalk from 'chalk' ; import path from 'path' ; import pRetry from 'p-retry' ; import pMap from 'p-map' ; import { getPackages , getPublishOrder , getPackageDependencies } from './ci/publish' ; import fetch from 'node-fetch' ; async function main ( ) { const buildOnly = process . argv [ 2 ] === '--build' ; if ( process . env . BUILDKITE_TAG && ! process . env . RELEASE_PROMOTE_DEV ) { throw new Error ( `When providing BUILDKITE_TAG, you also need to provide the env var RELEASE_PROMOTE_DEV, which
has to point to the dev version you want to promote, for example 2.1.0-dev.123` ) ; } if ( process . env . RELEASE_PROMOTE_DEV && ! process . env . BUILDKITE_TAG ) { throw new Error ( `You provided RELEASE_PROMOTE_DEV without BUILDKITE_TAG, which doesn't make sense.` ) ; } if ( process . env . CI && ! process . env . SKIP_GIT ) { await run ( '.' , `git config --global user.email "prismabots@gmail.com"` ) ; await run ( '.' , `git config --global user.name "prisma-bot"` ) ; } if ( process . env . RELEASE_PROMOTE_DEV ) { const versions = await getPrismaCommitFromPackageJsonViaUnpkg ( process . env . RELEASE_PROMOTE_DEV ) ; await run ( `.` , `git stash` ) ; await run ( `.` , `git checkout ${ versions . prisma }` , true ) ; } else if ( process . env . PATCH_BRANCH ) { await checkoutPatchBranches ( process . env . PATCH_BRANCH ) ; console . log ( `Commit we're on:` ) ; await execa . command ( 'git rev-parse HEAD' , { stdio : 'inherit' , } ) ; } else if ( process . env . UPDATE_STUDIO ) { await execa . command ( `git stash` , { stdio : 'inherit' , } ) ; await execa . command ( `git checkout ${ process . env . BUILDKITE_BRANCH }` , { stdio : 'inherit' , } ) ; } const rawPackages = await getPackages ( ) ; const packages = getPackageDependencies ( rawPackages ) ; const publishOrder = getPublishOrder ( packages ) ; console . log ( 'publish order' , publishOrder ) ; if ( buildOnly === false ) { console . debug ( `Installing dependencies` ) ; await run ( '.' , `pnpm i` ) . catch ( ( e ) => { console . error ( e ) ; } ) ; } console . debug ( `Building packages` ) ; for ( const batch of publishOrder ) { await pMap ( batch , async ( pkgName ) => { const pkg = packages [ pkgName ] ; const pkgDir = path . dirname ( pkg . path ) ; const runPromise = run ( pkgDir , 'pnpm run build' ) ; if ( buildOnly ) { runPromise . catch ( console . error ) ; if ( [ '@prisma/migrate' , '@prisma/integration-tests' ] . includes ( pkgName ) ) { await run ( pkgDir , 'pnpm rebuild' ) ; } } await runPromise ; } , { concurrency : 1 } ) ; } if ( buildOnly ) { return ; } for ( const batch of publishOrder ) { for ( const pkgName of batch ) { const pkg = packages [ pkgName ] ; if ( pkg . packageJson . scripts . postinstall ) { const pkgDir = path . dirname ( pkg . path ) ; await run ( pkgDir , 'pnpm run postinstall' ) ; } } } await pRetry ( async ( ) => { await run ( '.' , 'pnpm i' ) ; } , { retries : 6 , onFailedAttempt : ( e ) => { console . error ( e ) ; } , } ) ; } if ( ! module . parent ) { main ( ) . catch ( ( e ) => { console . error ( e ) ; process . exit ( 1 ) ; } ) ; } export async function run ( cwd , cmd , dry = false ) { const args = [ chalk . underline ( './' + cwd ) . padEnd ( 20 ) , chalk . bold ( cmd ) ] ; if ( dry ) { args . push ( chalk . dim ( '(dry)' ) ) ; } console . debug ( args . join ( ' ' ) ) ; if ( dry ) { return ; } try { return await execa . command ( cmd , { cwd , stdio : 'inherit' , } ) ; } catch ( _e ) { const e = _e as execa . ExecaError ; throw new Error ( chalk . bold . red ( `Error running ${ chalk . bold ( cmd ) } in ${ chalk . underline ( cwd ) }:` ) + ( e . stack || e . message ) ) ; } } param cwd param cmd async function runResult ( cwd , cmd ) { try { const result = await execa . command ( cmd , { cwd , stdio : 'pipe' , shell : true , } ) ; return result . stdout ; } catch ( _e ) { const e = _e as execa . ExecaError ; throw new Error ( chalk . red ( `Error running ${ chalk . bold ( cmd ) } in ${ chalk . underline ( cwd ) }:` ) + ( e . stderr || e . stack || e . message ) ) ; } } async function checkoutPatchBranches ( patchBranch ) { const repoPath = path . join ( __dirname , '../../' ) ; if ( await branchExists ( repoPath , patchBranch ) ) { await run ( repoPath , `git checkout ${ patchBranch }` ) ; } else { await run ( repoPath , `git checkout -b ${ patchBranch }` ) ; } } async function branchExists ( dir , branch ) { const output = await runResult ( dir , `git branch --list ${ branch }` ) ; const exists = output . trim ( ) . length > 0 ; if ( exists ) { console . log ( `Branch exists: ${ exists }` ) ; } return exists ; } async function getPrismaCommitFromPackageJsonViaUnpkg ( npmVersion ) { return fetch ( `https://unpkg.com/prisma@${ npmVersion }/package.json` , { headers : { accept : 'application/json' , } , } ) . then ( ( res ) => res . json ( ) ) . then ( ( pkg ) => { return pkg . prisma . prismaCommit ; } ) ; }