Skip to content

Commit

Permalink
fix(synthetics): synth-time failure for canary assets in nested stages (
Browse files Browse the repository at this point in the history
#27167)

Fixes #27089.

Canaries inside stages would fail at synth time after #26291 was introduced. This was due to a misunderstanding of `assetOutdir`. It turns out that `this.asset.assetPath` is a relative path of `Stage.of(scope).outdir`, not of `Stage.of(scope).assetOutdir`. These two out directories would be equivalent at the root level, but if there were nested stages, `assetOutdir` would equal `../${outdir}`.

This diagram may help:

```
CLOUD ASSEMBLY ROOT
  +-- asset.12345abcdef/
  +-- assembly-Stage
    +-- MyStack.template.json
    +-- MyStack.assets.json <- will contain { "path": "../asset.12345abcdef" }
```


----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
kaizencc authored Sep 18, 2023
1 parent fe0955f commit 7a04a5a
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 4 deletions.
5 changes: 3 additions & 2 deletions packages/@aws-cdk/aws-synthetics-alpha/lib/code.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,9 @@ export class AssetCode extends Code {
}

// Get the staged (or copied) asset path.
const assetOutDir = Stage.of(scope)?.assetOutdir;
const assetPath = assetOutDir ? path.join(assetOutDir, this.asset.assetPath): this.assetPath;
// `this.asset.assetPath` is relative to the `outdir`, not the `assetOutDir`.
const asmManifestDir = Stage.of(scope)?.outdir;
const assetPath = asmManifestDir ? path.join(asmManifestDir, this.asset.assetPath): this.assetPath;

if (path.extname(assetPath) !== '.zip') {
if (!fs.lstatSync(assetPath).isDirectory()) {
Expand Down
20 changes: 19 additions & 1 deletion packages/@aws-cdk/aws-synthetics-alpha/test/code.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as fs from 'fs';
import * as path from 'path';
import { Template } from 'aws-cdk-lib/assertions';
import * as s3 from 'aws-cdk-lib/aws-s3';
import { App, Stack, DockerImage } from 'aws-cdk-lib';
import { App, Stage, Stack, DockerImage } from 'aws-cdk-lib';
import * as cxapi from 'aws-cdk-lib/cx-api';
import * as synthetics from '../lib';
import { RuntimeFamily } from '../lib';
Expand Down Expand Up @@ -123,6 +123,24 @@ describe(synthetics.Code.fromAsset, () => {
expect(synthesized.assets.length).toEqual(1);
});

test('works when stack is a part of a stage', () => {
// GIVEN
const app = new App();
const stage1 = new Stage(app, 'Stage1');
const stage2 = new Stage(stage1, 'Stage2');
const stack = new Stack(stage2);

// WHEN
const directoryAsset = synthetics.Code.fromAsset(path.join(__dirname, 'canaries'));
new synthetics.Canary(stack, 'Canary1', {
test: synthetics.Test.custom({
handler: 'canary.handler',
code: directoryAsset,
}),
runtime: synthetics.Runtime.SYNTHETICS_NODEJS_PUPPETEER_3_8,
});
});

test('fails if path does not exist', () => {
const assetPath = path.join(__dirname, 'does-not-exist');
expect(() => synthetics.Code.fromAsset(assetPath))
Expand Down
1 change: 0 additions & 1 deletion packages/aws-cdk-lib/core/lib/stage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,6 @@ export class Stage extends Construct {
* will return an empty string.
*
* Derived from the construct path.
*
*/
public get artifactId() {
if (!this.node.path) { return ''; }
Expand Down

0 comments on commit 7a04a5a

Please sign in to comment.