Skip to content

Commit

Permalink
feat(aws-cdk): add CDK app version negotiation
Browse files Browse the repository at this point in the history
Tag the CDK app output with a version, so that the Toolkit can
compare the sent and expected versions and complain if there's
a mismatch.

Fixes #891.
  • Loading branch information
Rico Huijbers committed Oct 22, 2018
1 parent 33c32a8 commit e443a23
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 1 deletion.
1 change: 1 addition & 0 deletions packages/@aws-cdk/cdk/lib/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export class App extends Root {
}

const result: cxapi.SynthesizeResponse = {
version: cxapi.PROTO_RESPONSE_VERSION,
stacks: this.synthesizeStacks(Object.keys(this.stacks)),
runtime: this.collectRuntimeInformation()
};
Expand Down
22 changes: 22 additions & 0 deletions packages/@aws-cdk/cx-api/lib/cxapi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,24 @@

import { Environment } from './environment';

/**
* Bump this to the library version if and only if the CX protocol changes.
*
* We could also have used 1, 2, 3, ... here to indicate protocol versions, but
* those then still need to be mapped to software versions to be useful. So we
* might as well use the software version as protocol version and immediately
* generate a useful error message from this.
*
* Note the following:
*
* - The versions are not compared in a semver way, they are used as
* opaque ordered tokens.
* - The version needs to be set to the NEXT releasable version when it's
* updated (as the current verison in package.json has already been released!)
* - The request does not have versioning yet, only the response.
*/
export const PROTO_RESPONSE_VERSION = '0.14.0';

export const OUTFILE_NAME = 'cdk.out';
export const OUTDIR_ENV = 'CDK_OUTDIR';
export const CONTEXT_ENV = 'CDK_CONTEXT_JSON';
Expand All @@ -21,6 +39,10 @@ export interface MissingContext {
}

export interface SynthesizeResponse {
/**
* Protocol version
*/
version: string;
stacks: SynthesizedStack[];
runtime?: AppRuntime;
}
Expand Down
1 change: 1 addition & 0 deletions packages/@aws-cdk/cx-api/lib/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './cxapi';
export * from './cdk-api';
export * from './environment';
30 changes: 29 additions & 1 deletion packages/aws-cdk/bin/cdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import YAML = require('js-yaml');
import minimatch = require('minimatch');
import os = require('os');
import path = require('path');
import semver = require('semver');
import util = require('util');
import yargs = require('yargs');
import cdkUtil = require('../lib/util');
Expand Down Expand Up @@ -469,7 +470,7 @@ async function initCommandLine() {
const response = await fs.readJson(outfile);
debug(response);
return response;
return versionCheckResponse(response);
} finally {
debug('Removing outdir', outdir);
await fs.remove(outdir);
Expand Down Expand Up @@ -508,7 +509,34 @@ async function initCommandLine() {
});
}
}
}
/**
* Look at the type of response we get and upgrade it to the latest expected version
*/
function versionCheckResponse(response: cxapi.SynthesizeResponse): cxapi.SynthesizeResponse {
if (!response.version) {
// tslint:disable-next-line:max-line-length
throw new Error(`CDK Framework >= ${cxapi.PROTO_RESPONSE_VERSION} is required in order to interact with this version of the Toolkit.`);
}
const frameworkVersion = semver.coerce(response.version);
const toolkitVersion = semver.coerce(cxapi.PROTO_RESPONSE_VERSION);
if (semver.gt(frameworkVersion, toolkitVersion)) {
throw new Error(`CDK Toolkit >= ${response.version} is required in order to interact with this program.`);
}
if (semver.lt(frameworkVersion, toolkitVersion)) {
// Toolkit protocol is newer than the framework version, and we KNOW the
// version. This is a scenario in which we could potentially do some
// upgrading of the request in the future.
//
// For now though, we simply reject old responses.
throw new Error(`CDK Framework >= ${cxapi.PROTO_RESPONSE_VERSION} is required in order to interact with this version of the Toolkit.`);
}
return response;
}
/**
Expand Down
1 change: 1 addition & 0 deletions packages/aws-cdk/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"@types/request": "^2.47.1",
"@types/uuid": "^3.4.3",
"@types/yargs": "^8.0.3",
"@types/semver": "^5.5.0",
"cdk-build-tools": "^0.13.0",
"mockery": "^2.1.0",
"pkglint": "^0.13.0"
Expand Down

0 comments on commit e443a23

Please sign in to comment.