1
+ import * as OctokitApi from '@octokit/rest' ;
1
2
import { bold , cyan , green , italic , red , yellow } from 'chalk' ;
2
3
import { existsSync , readFileSync , writeFileSync } from 'fs' ;
3
4
import { prompt } from 'inquirer' ;
@@ -41,7 +42,12 @@ class StageReleaseTask {
41
42
/** Instance of a wrapper that can execute Git commands. */
42
43
git : GitClient ;
43
44
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 ) {
45
51
this . packageJsonPath = join ( projectDir , 'package.json' ) ;
46
52
47
53
console . log ( this . projectDir ) ;
@@ -61,7 +67,9 @@ class StageReleaseTask {
61
67
process . exit ( 1 ) ;
62
68
}
63
69
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` ) ;
65
73
}
66
74
67
75
async run ( ) {
@@ -81,8 +89,7 @@ class StageReleaseTask {
81
89
this . verifyPublishBranch ( expectedPublishBranch ) ;
82
90
this . verifyLocalCommitsMatchUpstream ( expectedPublishBranch ) ;
83
91
this . verifyNoUncommittedChanges ( ) ;
84
-
85
- // TODO(devversion): Assert that GitHub statuses succeed for this branch.
92
+ await this . verifyPassingGithubStatus ( ) ;
86
93
87
94
const newVersionName = newVersion . format ( ) ;
88
95
const stagingBranch = `release-stage/${ newVersionName } ` ;
@@ -136,8 +143,8 @@ class StageReleaseTask {
136
143
137
144
// Check if current branch matches the expected publish branch.
138
145
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 ) } ".` ) ) ;
141
148
process . exit ( 1 ) ;
142
149
}
143
150
}
@@ -149,16 +156,17 @@ class StageReleaseTask {
149
156
150
157
// Check if the current branch is in sync with the remote branch.
151
158
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.` ) ) ;
154
162
process . exit ( 1 ) ;
155
163
}
156
164
}
157
165
158
166
/** Verifies that there are no uncommitted changes in the project. */
159
167
private verifyNoUncommittedChanges ( ) {
160
168
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 ` +
162
170
`should be stashed.` ) ) ;
163
171
process . exit ( 1 ) ;
164
172
}
@@ -169,10 +177,32 @@ class StageReleaseTask {
169
177
const newPackageJson = { ...this . packageJson , version : newVersionName } ;
170
178
writeFileSync ( this . packageJsonPath , JSON . stringify ( newPackageJson , null , 2 ) ) ;
171
179
}
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
+ }
172
202
}
173
203
174
204
/** Entry-point for the release staging script. */
175
205
if ( require . main === module ) {
176
- new StageReleaseTask ( join ( __dirname , '../../' ) ) . run ( ) ;
206
+ new StageReleaseTask ( join ( __dirname , '../../' ) , 'angular' , 'material2' ) . run ( ) ;
177
207
}
178
208
0 commit comments