1import chalk from 'chalk'; 2 3import Git from '../../Git'; 4import logger from '../../Logger'; 5import { Task } from '../../TasksRunner'; 6import { CommandOptions, Parcel, TaskArgs } from '../types'; 7import { selectPackagesToPublish } from './selectPackagesToPublish'; 8 9const { blue } = chalk; 10 11/** 12 * Commits staged changes made by all previous tasks. 13 */ 14export const commitStagedChanges = new Task<TaskArgs>( 15 { 16 name: 'commitStagedChanges', 17 dependsOn: [selectPackagesToPublish], 18 }, 19 async (parcels: Parcel[], options: CommandOptions) => { 20 const stagedFiles = await Git.getStagedFilesAsync(); 21 22 if (stagedFiles.length === 0) { 23 // This may happen if versions have already been updated — manually or by previous publish 24 // that failed after committing and pushing to remote. It's safe to just skip this step 25 // and use the current head commit as the publish commit. 26 logger.info(`\n Nothing to commit — using previous commit as the publish commit`); 27 return; 28 } 29 30 const commitMessage = commitMessageForOptions(options); 31 const commitDescription = parcels 32 .map(({ pkg, state }) => `${pkg.packageName}@${state.releaseVersion}`) 33 .join('\n'); 34 35 logger.info(`\n Committing changes with message: ${blue(commitMessage)}`); 36 37 await Git.commitAsync({ 38 title: commitMessage, 39 body: commitDescription, 40 }); 41 } 42); 43 44/** 45 * If commit message was provided as an option then it's returned. 46 * Otherwise it is auto-generated based on provided package names. 47 */ 48function commitMessageForOptions(options: CommandOptions): string { 49 if (options.commitMessage) { 50 return options.commitMessage; 51 } 52 if (0 < options.packageNames.length && options.packageNames.length < 4) { 53 return `Publish ${options.packageNames.join(', ')}`; 54 } 55 return 'Publish packages'; 56} 57