89 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			89 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| /**
 | |
|  * @license
 | |
|  * Copyright Google LLC All Rights Reserved.
 | |
|  *
 | |
|  * Use of this source code is governed by an MIT-style license that can be
 | |
|  * found in the LICENSE file at https://angular.io/license
 | |
|  */
 | |
| 
 | |
| import fetch from 'node-fetch';
 | |
| import {fetchActiveReleaseTrains, ReleaseTrain} from '../../release/versioning/index';
 | |
| 
 | |
| import {bold, debug, info} from '../../utils/console';
 | |
| import {BaseModule} from './base';
 | |
| 
 | |
| 
 | |
| /** The result of checking a branch on CI. */
 | |
| type CiBranchStatus = 'success'|'failed'|'not found';
 | |
| 
 | |
| /** A list of results for checking CI branches. */
 | |
| type CiData = {
 | |
|   active: boolean,
 | |
|   name: string,
 | |
|   label: string,
 | |
|   status: CiBranchStatus,
 | |
| }[];
 | |
| 
 | |
| export class CiModule extends BaseModule<CiData> {
 | |
|   async retrieveData() {
 | |
|     const gitRepoWithApi = {api: this.git.github, ...this.git.remoteConfig};
 | |
|     const releaseTrains = await fetchActiveReleaseTrains(gitRepoWithApi);
 | |
| 
 | |
|     const ciResultPromises = Object.entries(releaseTrains).map(async ([trainName, train]: [
 | |
|                                                                  string, ReleaseTrain|null
 | |
|                                                                ]) => {
 | |
|       if (train === null) {
 | |
|         return {
 | |
|           active: false,
 | |
|           name: trainName,
 | |
|           label: '',
 | |
|           status: 'not found' as const,
 | |
|         };
 | |
|       }
 | |
| 
 | |
|       return {
 | |
|         active: true,
 | |
|         name: train.branchName,
 | |
|         label: `${trainName} (${train.branchName})`,
 | |
|         status: await this.getBranchStatusFromCi(train.branchName),
 | |
|       };
 | |
|     });
 | |
| 
 | |
|     return await Promise.all(ciResultPromises);
 | |
|   }
 | |
| 
 | |
|   async printToTerminal() {
 | |
|     const data = await this.data;
 | |
|     const minLabelLength = Math.max(...data.map(result => result.label.length));
 | |
|     info.group(bold(`CI`));
 | |
|     data.forEach(result => {
 | |
|       if (result.active === false) {
 | |
|         debug(`No active release train for ${result.name}`);
 | |
|         return;
 | |
|       }
 | |
|       const label = result.label.padEnd(minLabelLength);
 | |
|       if (result.status === 'not found') {
 | |
|         info(`${result.name} was not found on CircleCI`);
 | |
|       } else if (result.status === 'success') {
 | |
|         info(`${label} ✅`);
 | |
|       } else {
 | |
|         info(`${label} ❌`);
 | |
|       }
 | |
|     });
 | |
|     info.groupEnd();
 | |
|     info();
 | |
|   }
 | |
| 
 | |
|   /** Get the CI status of a given branch from CircleCI. */
 | |
|   private async getBranchStatusFromCi(branch: string): Promise<CiBranchStatus> {
 | |
|     const {owner, name} = this.git.remoteConfig;
 | |
|     const url = `https://circleci.com/gh/${owner}/${name}/tree/${branch}.svg?style=shield`;
 | |
|     const result = await fetch(url).then(result => result.text());
 | |
| 
 | |
|     if (result && !result.includes('no builds')) {
 | |
|       return result.includes('passing') ? 'success' : 'failed';
 | |
|     }
 | |
|     return 'not found';
 | |
|   }
 | |
| }
 |