Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 38 additions & 2 deletions docs/src/content/docs/targets/aws-lambda-layer.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,27 @@ Creates a new public Lambda layer in each available AWS region and updates the S

| Option | Description |
|--------|-------------|
| `layerName` | Name of the Lambda layer |
| `layerName` | Name of the Lambda layer. Supports template variables (see below) |
| `compatibleRuntimes` | List of runtime configurations |
| `license` | Layer license |
| `linkPrereleases` | Update for preview releases. Default: `false` |
| `includeNames` | Must filter to exactly one artifact |

### Layer Name Templating

The `layerName` option supports Mustache-style template variables for dynamic version interpolation:

| Variable | Description | Example (for v10.2.3) |
|----------|-------------|----------------------|
| `{{{version}}}` | Full version string | `10.2.3` |
| `{{{major}}}` | Major version number | `10` |
| `{{{minor}}}` | Minor version number | `2` |
| `{{{patch}}}` | Patch version number | `3` |

This is useful when you want the layer name to reflect the SDK major version, making it easier for users to identify which version the layer supports.

Example: `SentryNodeServerlessSDKv{{{major}}}` becomes `SentryNodeServerlessSDKv10` when publishing version `10.2.3`.

### Runtime Configuration

```yaml
Expand All @@ -32,7 +47,9 @@ compatibleRuntimes:
| `AWS_ACCESS_KEY` | AWS account access key |
| `AWS_SECRET_ACCESS_KEY` | AWS account secret key |

## Example
## Examples

### Basic Example

```yaml
targets:
Expand All @@ -46,3 +63,22 @@ targets:
- nodejs12.x
license: MIT
```

### With Version Templating

Include the major version in the layer name so users can easily identify SDK compatibility:

```yaml
targets:
- name: aws-lambda-layer
includeNames: /^sentry-node-serverless-\d+(\.\d+)*\.zip$/
layerName: SentryNodeServerlessSDKv{{{major}}}
compatibleRuntimes:
- name: node
versions:
- nodejs18.x
- nodejs20.x
license: MIT
```

When publishing version `10.2.3`, the layer will be named `SentryNodeServerlessSDKv10`.
41 changes: 41 additions & 0 deletions src/targets/__tests__/awsLambda.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,47 @@ describe('project config parameters', () => {
});
});

describe('layer name templating', () => {
beforeAll(() => {
setAwsEnvironmentVariables();
});

test('layer name without template variables', () => {
const awsTarget = getAwsLambdaTarget();
awsTarget.config.layerName = 'SentryNodeServerlessSDK';
const resolved = awsTarget.resolveLayerName('10.2.3');
expect(resolved).toBe('SentryNodeServerlessSDK');
});

test('layer name with major version variable', () => {
const awsTarget = getAwsLambdaTarget();
awsTarget.config.layerName = 'SentryNodeServerlessSDKv{{{major}}}';
const resolved = awsTarget.resolveLayerName('10.2.3');
expect(resolved).toBe('SentryNodeServerlessSDKv10');
});

test('layer name with multiple version variables', () => {
const awsTarget = getAwsLambdaTarget();
awsTarget.config.layerName = 'SentrySDKv{{{major}}}-{{{minor}}}-{{{patch}}}';
const resolved = awsTarget.resolveLayerName('10.2.3');
expect(resolved).toBe('SentrySDKv10-2-3');
});

test('layer name with full version variable', () => {
const awsTarget = getAwsLambdaTarget();
awsTarget.config.layerName = 'SentrySDK-{{{version}}}';
const resolved = awsTarget.resolveLayerName('10.2.3');
expect(resolved).toBe('SentrySDK-10.2.3');
});

test('layer name with prerelease version', () => {
const awsTarget = getAwsLambdaTarget();
awsTarget.config.layerName = 'SentrySDKv{{{major}}}';
const resolved = awsTarget.resolveLayerName('10.2.3-alpha.1');
expect(resolved).toBe('SentrySDKv10');
});
});

describe('publish', () => {
beforeAll(() => {
setAwsEnvironmentVariables();
Expand Down
38 changes: 35 additions & 3 deletions src/targets/awsLambdaLayer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ import {
import { createSymlinks } from '../utils/symlink';
import { withTempDir } from '../utils/files';
import { isDryRun } from '../utils/helpers';
import { isPreviewRelease } from '../utils/version';
import { renderTemplateSafe } from '../utils/strings';
import { isPreviewRelease, parseVersion } from '../utils/version';
import { DEFAULT_REGISTRY_REMOTE } from '../utils/registry';

/** Config options for the "aws-lambda-layer" target. */
Expand Down Expand Up @@ -102,6 +103,34 @@ export class AwsLambdaLayerTarget extends BaseTarget {
}
}

/**
* Resolves the layer name by interpolating version variables.
*
* Supports Mustache-style templates with the following variables:
* - `{{{version}}}`: Full version string (e.g., "10.2.3")
* - `{{{major}}}`: Major version number (e.g., "10")
* - `{{{minor}}}`: Minor version number (e.g., "2")
* - `{{{patch}}}`: Patch version number (e.g., "3")
*
* Example: `SentryNodeServerlessSDKv{{{major}}}` becomes `SentryNodeServerlessSDKv10`
*
* @param version The version string to interpolate
* @returns The resolved layer name with variables substituted
*/
public resolveLayerName(version: string): string {
const layerNameTemplate = this.config.layerName as string;
const parsedVersion = parseVersion(version);

const context = {
version,
major: parsedVersion?.major ?? '',
minor: parsedVersion?.minor ?? '',
patch: parsedVersion?.patch ?? '',
};

return renderTemplateSafe(layerNameTemplate, context);
}

/**
* Publishes current lambda layer zip bundle to AWS Lambda.
* @param version New version to be released.
Expand Down Expand Up @@ -243,12 +272,15 @@ export class AwsLambdaLayerTarget extends BaseTarget {
awsRegions: string[],
artifactBuffer: Buffer
): Promise<void> {
const resolvedLayerName = this.resolveLayerName(version);
this.logger.debug(`Resolved layer name: ${resolvedLayerName}`);

await Promise.all(
this.config.compatibleRuntimes.map(async (runtime: CompatibleRuntime) => {
this.logger.debug(`Publishing runtime ${runtime.name}...`);
const layerManager = new AwsLambdaLayerManager(
runtime,
this.config.layerName,
resolvedLayerName,
this.config.license,
artifactBuffer,
awsRegions,
Expand Down Expand Up @@ -302,7 +334,7 @@ export class AwsLambdaLayerTarget extends BaseTarget {
canonical: layerManager.getCanonicalName(),
sdk_version: version,
account_number: getAccountFromArn(publishedLayers[0].arn),
layer_name: this.config.layerName,
layer_name: resolvedLayerName,
regions: regionsVersions,
};

Expand Down
Loading