@@ -4,7 +4,7 @@ import chalk from 'chalk';
44import log from 'loglevel' ;
55import { create } from './helpers/create-app-version' ;
66import { deploy } from './helpers/deploy-app-version-to-env' ;
7- import { DBError } from './helpers/Errors' ;
7+ import { DBError , DBGroupDeployTriggerError , DBHealthinessCheckError } from './helpers/Errors' ;
88import { waitForGroupHealthiness } from './helpers/healthiness' ;
99import { IDeployToGroupProps , IHealthCheckProps } from './helpers/Interfaces' ;
1010
@@ -56,13 +56,56 @@ async function createAppVersionsForGroup(client: ElasticBeanstalkClient, props:
5656 log . info ( chalk . green ( 'All needed application versions exist.' ) ) ;
5757}
5858
59+ async function preDeployHealthcheck ( client : ElasticBeanstalkClient , props : IDeployToGroupProps ) {
60+ try {
61+ log . info ( chalk . blue ( 'Verifying environments are ready to receive deployment before initiating...' ) ) ;
62+ await waitForGroupHealthiness ( {
63+ client,
64+ group : props . group ,
65+ force : props . force ?? DEFAULT_FORCE ,
66+ checkVersion : false ,
67+ ...( props . preDeployHealthCheckProps ?? DEFAULT_HEALTH_CHECK_PROPS ) ,
68+ } ) ;
69+ } catch ( e ) {
70+ if ( e instanceof DBHealthinessCheckError ) {
71+ e . message = `preDeployHealthcheck(): ${ e . message } ` ;
72+ }
73+ throw e ;
74+ }
75+ }
76+
77+ async function postDeployHealthcheck ( client : ElasticBeanstalkClient , props : IDeployToGroupProps ) {
78+ log . info ( chalk . blue ( 'Verifying environments successfully receive the deployment...this could take a while.' ) ) ;
79+ try {
80+ await waitForGroupHealthiness ( {
81+ client,
82+ group : props . group ,
83+ force : props . force ?? DEFAULT_FORCE ,
84+ checkVersion : true ,
85+ ...( props . postDeployHealthCheckProps ?? DEFAULT_HEALTH_CHECK_PROPS ) ,
86+ } ) ;
87+ } catch ( e ) {
88+ if ( e instanceof DBHealthinessCheckError ) {
89+ e . message = `postDeployHealthcheck(): ${ e . message } ` ;
90+ }
91+ throw e ;
92+ }
93+
94+ log . info (
95+ chalk . green ( 'Successfully deployed version ' ) +
96+ chalk . blue ( props . group . versionProps . label ) +
97+ chalk . green ( ' to beanstalk group ' ) +
98+ chalk . blue ( props . group . name ) ,
99+ ) ;
100+ }
101+
59102/**
60- * For each Beanstalk Environment in group, deploys the respective Application
61- * Version and then waits to verify their healthiness .
103+ * For each Beanstalk Environment in the group, deploys the respective
104+ * Application Version .
62105 */
63106async function deployAppVersionsToGroup ( client : ElasticBeanstalkClient , props : IDeployToGroupProps ) {
64107 log . info ( `Asynchronously kicking off deployment to the ${ props . group . name } group of beanstalks.` ) ;
65- const triggerErr = new DBError ( 'deployAppVersionsToGroup: ' , [ ] ) ;
108+ const triggerErr = new DBGroupDeployTriggerError ( 'deployAppVersionsToGroup: ' , [ ] ) ;
66109 const force = props . force ?? DEFAULT_FORCE ;
67110 await Promise . all (
68111 props . group . environments . map ( async ( env ) => {
@@ -80,59 +123,70 @@ async function deployAppVersionsToGroup(client: ElasticBeanstalkClient, props: I
80123 }
81124 } ) ,
82125 ) ;
83- try {
84- // Verify the group successfully receives the deployment.
85- await waitForGroupHealthiness ( {
86- client,
87- group : props . group ,
88- force,
89- checkVersion : true ,
90- ...( props . postDeployHealthCheckProps ?? DEFAULT_HEALTH_CHECK_PROPS ) ,
91- } ) ;
92- log . info (
93- chalk . green ( 'Successfully deployed version ' ) +
94- chalk . blue ( props . group . versionProps . label ) +
95- chalk . green ( ' to beanstalk group ' ) +
96- chalk . blue ( props . group . name ) ,
97- ) ;
98- } catch ( e ) {
99- if ( triggerErr . errors . length === 0 ) throw e ;
100- triggerErr . errors . push ( e as Error ) ;
101- throw triggerErr ;
102- }
126+ if ( triggerErr . errors . length !== 0 ) throw triggerErr ;
103127}
104128
105129/**
106- * Iterates over a group of Beanstalk Environments , creates Application
107- * Versions for their respective Beanstalk Applications, and then deploys
108- * those versions to the Beanstalk Environments and verifies their health .
130+ * Initializes the Beanstalk Client , creates the needed Application Versions,
131+ * and verifies the Beanstalk Environments in the group are ready to receive
132+ * the deployment .
109133 */
110- export async function deployToGroup ( props : IDeployToGroupProps ) {
111- const group = props . group ;
112- const force = props . force ?? DEFAULT_FORCE ;
134+ async function preDeploySteps ( props : IDeployToGroupProps ) : Promise < ElasticBeanstalkClient > {
113135 try {
114- log . setLevel ( props . logLevel ?? log . levels . INFO ) ;
115- log . info ( chalk . green ( 'Beginning deploy process for beanstalk group ' ) + chalk . blue ( group . name ) ) ;
116136 const client = new ElasticBeanstalkClient ( {
117137 maxAttempts : AWS_CLIENT_REQUEST_MAX_ATTEMPTS_DEFAULT ,
118- region : group . region ,
138+ region : props . group . region ,
119139 } ) ;
120140 await createAppVersionsForGroup ( client , props ) ;
121- log . info ( chalk . blue ( 'Verifying environments are ready to receive deployment before initiating...' ) ) ;
122- await waitForGroupHealthiness ( {
123- client,
124- group,
125- force,
126- checkVersion : false ,
127- ...( props . preDeployHealthCheckProps ?? DEFAULT_HEALTH_CHECK_PROPS ) ,
128- } ) ;
129- await deployAppVersionsToGroup ( client , props ) ;
141+ await preDeployHealthcheck ( client , props ) ;
142+ return client ;
130143 } catch ( e ) {
131144 log . error ( chalk . red ( e ) ) ;
132145 if ( e instanceof DBError ) {
133146 e . errors . forEach ( ( err ) => log . error ( chalk . red ( err ) ) ) ;
134147 }
135- log . error ( chalk . red ( 'Deploy to beanstalk group ' ) + chalk . blue ( group . name ) + chalk . red ( ' failed.' ) ) ;
148+ log . error ( chalk . red ( 'Could not trigger deployment to beanstalk group ' ) + chalk . blue ( props . group . name ) ) ;
136149 throw e ;
137150 }
138151}
152+
153+ /**
154+ * Triggers the deployment of the newly created Application Version to each
155+ * Beanstalk Environment in the group, then verifies they reach a healthy state
156+ * and successfully land the expected version.
157+ */
158+ async function deploySteps ( client : ElasticBeanstalkClient , props : IDeployToGroupProps ) {
159+ let deployErrs : DBError = new DBError ( 'deploySteps(): ' , [ ] ) ;
160+ try {
161+ await deployAppVersionsToGroup ( client , props ) ;
162+ } catch ( e ) {
163+ // We still want to see status of Beanstalks who did have deploy triggered
164+ deployErrs . errors . push ( e as Error ) ;
165+ }
166+
167+ try {
168+ await postDeployHealthcheck ( client , props ) ;
169+ } catch ( e ) {
170+ log . error ( chalk . red ( e ) ) ;
171+ if ( e instanceof DBError ) {
172+ e . errors . forEach ( ( err ) => log . error ( chalk . red ( err ) ) ) ;
173+ }
174+ log . error ( chalk . red ( 'Deployment to beanstalk group ' ) + chalk . blue ( props . group . name ) + chalk . red ( ' failed.' ) ) ;
175+ deployErrs . errors . push ( e as Error ) ;
176+ }
177+
178+ if ( deployErrs . errors . length !== 0 ) throw deployErrs ;
179+ }
180+
181+ /**
182+ * Iterates over a group of Beanstalk Environments, creates Application
183+ * Versions for their respective Beanstalk Applications, and then deploys
184+ * those versions to the Beanstalk Environments and verifies their health.
185+ */
186+ export async function deployToGroup ( props : IDeployToGroupProps ) {
187+ const group = props . group ;
188+ log . setLevel ( props . logLevel ?? log . levels . INFO ) ;
189+ log . info ( chalk . green ( 'Beginning deploy process for beanstalk group ' ) + chalk . blue ( group . name ) ) ;
190+
191+ await deploySteps ( await preDeploySteps ( props ) , props ) ;
192+ }
0 commit comments