1+ import * as OctokitApi from '@octokit/rest' ;
12import { bold , cyan , green , italic , red , yellow } from 'chalk' ;
23import { existsSync , readFileSync , writeFileSync } from 'fs' ;
34import { prompt } from 'inquirer' ;
@@ -41,7 +42,12 @@ class StageReleaseTask {
4142 /** Instance of a wrapper that can execute Git commands. */
4243 git : GitClient ;
4344
44- constructor ( public projectDir : string ) {
45+ /** Octokit API instance that can be used to make Github API calls. */
46+ githubApi : OctokitApi ;
47+
48+ constructor ( public projectDir : string ,
49+ public repositoryOwner : string ,
50+ public repositoryName : string ) {
4551 this . packageJsonPath = join ( projectDir , 'package.json' ) ;
4652
4753 console . log ( this . projectDir ) ;
@@ -61,7 +67,9 @@ class StageReleaseTask {
6167 process . exit ( 1 ) ;
6268 }
6369
64- this . git = new GitClient ( projectDir , this . packageJson . repository . url ) ;
70+ this . githubApi = new OctokitApi ( ) ;
71+ this . git = new GitClient ( projectDir ,
72+ `https://github.com/${ repositoryOwner } /${ repositoryName } .git` ) ;
6573 }
6674
6775 async run ( ) {
@@ -81,8 +89,7 @@ class StageReleaseTask {
8189 this . verifyPublishBranch ( expectedPublishBranch ) ;
8290 this . verifyLocalCommitsMatchUpstream ( expectedPublishBranch ) ;
8391 this . verifyNoUncommittedChanges ( ) ;
84-
85- // TODO(devversion): Assert that GitHub statuses succeed for this branch.
92+ await this . verifyPassingGithubStatus ( ) ;
8693
8794 const newVersionName = newVersion . format ( ) ;
8895 const stagingBranch = `release-stage/${ newVersionName } ` ;
@@ -136,8 +143,8 @@ class StageReleaseTask {
136143
137144 // Check if current branch matches the expected publish branch.
138145 if ( expectedPublishBranch !== currentBranchName ) {
139- console . error ( red ( `Cannot stage release from "${ italic ( currentBranchName ) } ". Please stage ` +
140- `the release from "${ bold ( expectedPublishBranch ) } ".` ) ) ;
146+ console . error ( red ( ` ✘ Cannot stage release from "${ italic ( currentBranchName ) } ". Please ` +
147+ `stage the release from "${ bold ( expectedPublishBranch ) } ".` ) ) ;
141148 process . exit ( 1 ) ;
142149 }
143150 }
@@ -149,16 +156,17 @@ class StageReleaseTask {
149156
150157 // Check if the current branch is in sync with the remote branch.
151158 if ( upstreamCommitSha !== localCommitSha ) {
152- console . error ( red ( `Cannot stage release. The current branch is not in sync with the remote ` +
153- `branch. Please make sure your local branch "${ italic ( publishBranch ) } " is up to date.` ) ) ;
159+ console . error ( red ( ` ✘ Cannot stage release. The current branch is not in sync with the ` +
160+ `remote branch. Please make sure your local branch "${ italic ( publishBranch ) } " is up ` +
161+ `to date.` ) ) ;
154162 process . exit ( 1 ) ;
155163 }
156164 }
157165
158166 /** Verifies that there are no uncommitted changes in the project. */
159167 private verifyNoUncommittedChanges ( ) {
160168 if ( this . git . hasUncommittedChanges ( ) ) {
161- console . error ( red ( `Cannot stage release. There are changes which are not committed and ` +
169+ console . error ( red ( ` ✘ Cannot stage release. There are changes which are not committed and ` +
162170 `should be stashed.` ) ) ;
163171 process . exit ( 1 ) ;
164172 }
@@ -169,10 +177,32 @@ class StageReleaseTask {
169177 const newPackageJson = { ...this . packageJson , version : newVersionName } ;
170178 writeFileSync ( this . packageJsonPath , JSON . stringify ( newPackageJson , null , 2 ) ) ;
171179 }
180+
181+ /** Verifies that the latest commit of the current branch is passing all Github statuses. */
182+ private async verifyPassingGithubStatus ( ) {
183+ const commitRef = this . git . getLocalCommitSha ( 'HEAD' ) ;
184+ const { state} = ( await this . githubApi . repos . getCombinedStatusForRef ( {
185+ owner : this . repositoryOwner ,
186+ repo : this . repositoryName ,
187+ ref : commitRef ,
188+ } ) ) . data ;
189+
190+ if ( state === 'failure' ) {
191+ console . error ( red ( ` ✘ Cannot stage release. Commit "${ commitRef } " does not pass all ` +
192+ `github status checks. Please make sure this commit passes all checks before re-running.` ) ) ;
193+ process . exit ( 1 ) ;
194+ } else if ( state === 'pending' ) {
195+ console . error ( red ( ` ✘ Cannot stage release yet. Commit "${ commitRef } " still has ` +
196+ `pending github statuses that need to succeed before staging a release.` ) ) ;
197+ process . exit ( 0 ) ;
198+ }
199+
200+ console . info ( green ( ` ✓ Upstream commit is passing all github status checks.` ) ) ;
201+ }
172202}
173203
174204/** Entry-point for the release staging script. */
175205if ( require . main === module ) {
176- new StageReleaseTask ( join ( __dirname , '../../' ) ) . run ( ) ;
206+ new StageReleaseTask ( join ( __dirname , '../../' ) , 'angular' , 'material2' ) . run ( ) ;
177207}
178208
0 commit comments