codepipeline-event-notifier 0.2.7 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.editorconfig ADDED
@@ -0,0 +1,12 @@
1
+ # ~~ Generated by projen. To modify, edit .projenrc.ts and run "npx projen".
2
+
3
+ root=true
4
+
5
+ [*]
6
+ end_of_line=lf
7
+ charset=utf-8
8
+
9
+ [*\.{js,ts}]
10
+ indent_style=space
11
+ indent_size=2
12
+ max_line_length=120
package/.jsii CHANGED
@@ -8440,7 +8440,7 @@
8440
8440
  "stability": "stable"
8441
8441
  },
8442
8442
  "homepage": "https://github.com/gammarers-aws-cdk-constructs/codepipeline-event-notifier.git",
8443
- "jsiiVersion": "6.0.13 (build 5c05d06)",
8443
+ "jsiiVersion": "6.0.14 (build 44649f3)",
8444
8444
  "keywords": [
8445
8445
  "cdk"
8446
8446
  ],
@@ -8456,7 +8456,7 @@
8456
8456
  },
8457
8457
  "name": "codepipeline-event-notifier",
8458
8458
  "readme": {
8459
- "markdown": "# CodePipeline Event Notifier\n\n[![npm version](https://img.shields.io/npm/v/codepipeline-event-notifier.svg)](https://www.npmjs.com/package/codepipeline-event-notifier)\n[![license](https://img.shields.io/npm/l/codepipeline-event-notifier.svg)](LICENSE)\n\nCDK construct that listens to **AWS CodePipeline execution STARTED** events via EventBridge, invokes a Lambda notifier, and publishes execution state changes to an SNS topic.\n\n## Features\n\n- **EventBridge integration**: triggers on `CodePipeline Pipeline Execution State Change` with `state=STARTED` (customizable via `eventPattern`)\n- **SNS notifications**: publishes execution status transitions as JSON messages (`phase`: `eventbridge` / `wait`)\n- **Execution waiting**: calls `GetPipelineExecution` until a terminal state (`SUCCEEDED` / `FAILED` / `STOPPED` / `SUPERSEDED`) or timeout\n- **Configurable props**: reuse an existing SNS topic, adjust wait interval / max wait duration / Lambda timeout, and filter events\n- **No subscriptions by default**: the SNS topic is created (or reused), but subscriptions (email/HTTP/etc.) are intentionally not configured\n\n## Installation\n\n### npm\n\n```bash\nnpm install codepipeline-event-notifier\n```\n\n### yarn\n\n```bash\nyarn add codepipeline-event-notifier\n```\n\n## Usage\n\nInstantiate `CodePipelineEventNotifier` in your CDK stack:\n\n```ts\nimport { Stack } from 'aws-cdk-lib';\nimport { Construct } from 'constructs';\nimport { CodePipelineEventNotifier } from 'codepipeline-event-notifier';\n\nexport class MyStack extends Stack {\n constructor(scope: Construct, id: string) {\n super(scope, id);\n\n const notifier = new CodePipelineEventNotifier(this, 'CodePipelineEventNotifier');\n\n // Optionally subscribe to the topic created by the construct\n // notifier.topic.addSubscription(...);\n }\n}\n```\n\n### Customize with props\n\n```ts\nimport { Duration, Stack, aws_sns as sns } from 'aws-cdk-lib';\nimport { Construct } from 'constructs';\nimport { CodePipelineEventNotifier } from 'codepipeline-event-notifier';\n\nexport class MyStack extends Stack {\n constructor(scope: Construct, id: string) {\n super(scope, id);\n\n const topic = sns.Topic.fromTopicArn(this, 'ExistingTopic', 'arn:aws:sns:...');\n\n new CodePipelineEventNotifier(this, 'CodePipelineEventNotifier', {\n topic,\n waitInterval: Duration.seconds(30),\n maxWaitDuration: Duration.minutes(10),\n timeout: Duration.minutes(12),\n eventPattern: {\n source: ['aws.codepipeline'],\n detailType: ['CodePipeline Pipeline Execution State Change'],\n detail: {\n state: ['STARTED'],\n pipeline: ['my-pipeline'],\n },\n },\n });\n }\n}\n```\n\n## Options\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `topic` | `sns.ITopic` | new topic | SNS topic to publish notifications to (also exposed as `notifier.topic`) |\n| `waitInterval` | `Duration` | `10 seconds` | Interval between `GetPipelineExecution` calls |\n| `maxWaitDuration` | `Duration` | `14 minutes` | Maximum wait duration before giving up |\n| `timeout` | `Duration` | `15 minutes` | Notifier Lambda timeout (should exceed `maxWaitDuration`) |\n| `eventPattern` | `events.EventPattern` | CodePipeline `STARTED` | EventBridge rule filter |\n\nThe notifier Lambda uses these environment variables (set by the construct from props):\n\n- `SNS_TOPIC_ARN` (**required**): SNS topic ARN to publish notifications to\n- `WAIT_INTERVAL_SECONDS` (default: `10`): wait interval in seconds\n- `MAX_WAIT_MINUTES` (default: `14`): maximum wait duration in minutes\n\n## Requirements\n\n- Node.js `>= 20`\n- AWS CDK `v2` (`aws-cdk-lib` `^2.232.0`)\n- `constructs` `^10.5.1`\n\n## License\n\nThis project is licensed under the Apache-2.0 License.\n"
8459
+ "markdown": "# CodePipeline Event Notifier (CDK v2)\n\n[![npm version](https://img.shields.io/npm/v/codepipeline-event-notifier?style=flat-square)](https://www.npmjs.com/package/codepipeline-event-notifier)\n[![license](https://img.shields.io/npm/l/codepipeline-event-notifier?style=flat-square)](https://www.npmjs.com/package/codepipeline-event-notifier)\n[![Node.js](https://img.shields.io/node/v/codepipeline-event-notifier?style=flat-square)](https://www.npmjs.com/package/codepipeline-event-notifier)\n[![build](https://img.shields.io/github/actions/workflow/status/gammarers-aws-cdk-constructs/codepipeline-event-notifier/build.yml?branch=main&label=build&style=flat-square)](https://github.com/gammarers-aws-cdk-constructs/codepipeline-event-notifier/actions/workflows/build.yml)\n\n[![View on Construct Hub](https://constructs.dev/badge?package=codepipeline-event-notifier)](https://constructs.dev/packages/codepipeline-event-notifier)\n\nCDK construct that listens to **AWS CodePipeline execution STARTED** events via EventBridge, invokes a Lambda notifier, and publishes execution state changes to an SNS topic.\n\n## Features\n\n- **EventBridge integration**: triggers on `CodePipeline Pipeline Execution State Change` with `state=STARTED` (customizable via `eventPattern`)\n- **Tag-based pipeline selection**: required `targetPipeline.tags` filters which pipelines are notified (`ListTagsForResource`; keys are AND, values are OR)\n- **Least-privilege IAM**: CodePipeline API access is scoped to this account and region, or to `targetPipeline.arns` when set\n- **SNS notifications**: publishes execution status transitions as JSON messages (`phase`: `eventbridge` / `wait`)\n- **Execution waiting**: calls `GetPipelineExecution` until a terminal state (`SUCCEEDED` / `FAILED` / `STOPPED` / `SUPERSEDED`) or timeout\n- **Configurable props**: reuse an existing SNS topic, adjust wait interval / max wait duration / Lambda timeout, and optionally refine the EventBridge pattern\n- **No subscriptions by default**: the SNS topic is created (or reused), but subscriptions (email/HTTP/etc.) are intentionally not configured\n\n## How it works\n\n1. EventBridge matches a CodePipeline execution state-change event (default: `state=STARTED`) and invokes the notifier Lambda.\n2. The Lambda resolves the pipeline ARN, then keeps the event only when `targetPipeline.tags` match (`ListTagsForResource`; keys are AND, values are OR) and, if set, `targetPipeline.arns` includes the pipeline.\n3. It publishes an SNS message with `phase: eventbridge`, then calls `GetPipelineExecution` until a terminal status (`SUCCEEDED` / `FAILED` / `STOPPED` / `SUPERSEDED`) or `maxWaitDuration`.\n4. Each status change (and timeout) is published with `phase: wait`. Subscribe to `notifier.topic`; this construct does not add subscriptions.\n\n## Installation\n\n### npm\n\n```bash\nnpm install codepipeline-event-notifier\n```\n\n### yarn\n\n```bash\nyarn add codepipeline-event-notifier\n```\n\n### pnpm\n\n```bash\npnpm add codepipeline-event-notifier\n```\n\n## Usage\n\nInstantiate `CodePipelineEventNotifier` in your CDK stack:\n\n```ts\nimport { Stack } from 'aws-cdk-lib';\nimport { Construct } from 'constructs';\nimport { CodePipelineEventNotifier } from 'codepipeline-event-notifier';\n\nexport class MyStack extends Stack {\n constructor(scope: Construct, id: string) {\n super(scope, id);\n\n const notifier = new CodePipelineEventNotifier(this, 'CodePipelineEventNotifier', {\n targetPipeline: {\n tags: [\n {\n key: 'Notify',\n values: ['true'],\n },\n ],\n },\n });\n\n // Optionally subscribe to the topic created by the construct\n // notifier.topic.addSubscription(...);\n }\n}\n```\n\n### Customize with props\n\n```ts\nimport { Duration, Stack, aws_sns as sns } from 'aws-cdk-lib';\nimport { Construct } from 'constructs';\nimport { CodePipelineEventNotifier } from 'codepipeline-event-notifier';\n\nexport class MyStack extends Stack {\n constructor(scope: Construct, id: string) {\n super(scope, id);\n\n const topic = sns.Topic.fromTopicArn(this, 'ExistingTopic', 'arn:aws:sns:...');\n\n new CodePipelineEventNotifier(this, 'CodePipelineEventNotifier', {\n topic,\n waitInterval: Duration.seconds(30),\n maxWaitDuration: Duration.minutes(10),\n timeout: Duration.minutes(12),\n targetPipeline: {\n tags: [\n {\n key: 'Team',\n values: ['platform', 'infra'],\n },\n ],\n arns: [\n 'arn:aws:codepipeline:us-east-1:123456789012:my-pipeline',\n ],\n },\n eventPattern: {\n source: ['aws.codepipeline'],\n detailType: ['CodePipeline Pipeline Execution State Change'],\n detail: {\n state: ['STARTED'],\n },\n },\n });\n }\n}\n```\n\n## Options\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `targetPipeline` | `TargetPipeline` | *(required)* | Tag filters (`tags`) for pipelines that should notify. Optional `arns` restrict IAM and skip other pipelines. Default IAM is this account and region |\n| `topic` | `sns.ITopic` | new topic | SNS topic to publish notifications to (also exposed as `notifier.topic`) |\n| `waitInterval` | `Duration` | `10 seconds` | Interval between `GetPipelineExecution` calls |\n| `maxWaitDuration` | `Duration` | `14 minutes` | Maximum wait duration before giving up |\n| `timeout` | `Duration` | `15 minutes` | Notifier Lambda timeout (should exceed `maxWaitDuration`) |\n| `eventPattern` | `events.EventPattern` | CodePipeline `STARTED` | EventBridge rule filter |\n\nThe notifier Lambda uses these environment variables (set by the construct from props):\n\n- `SNS_TOPIC_ARN` (**required**): SNS topic ARN to publish notifications to\n- `TARGET_PIPELINE_TAGS` (**required**): JSON array of `{ key, values }` tag filters\n- `TARGET_PIPELINE_ARNS` (optional): JSON array of pipeline ARNs used as an allowlist when `targetPipeline.arns` is set\n- `WAIT_INTERVAL_SECONDS` (default: `10`): wait interval in seconds\n- `MAX_WAIT_MINUTES` (default: `14`): maximum wait duration in minutes\n\n## API\n\nSee the [API reference](./API.md).\n\n## Requirements\n\n- Node.js `>= 20`\n- AWS CDK `v2` (`aws-cdk-lib` `^2.232.0`)\n- `constructs` `^10.5.1`\n\n## License\n\nThis project is licensed under the Apache-2.0 License.\n"
8460
8460
  },
8461
8461
  "repository": {
8462
8462
  "type": "git",
@@ -8483,7 +8483,7 @@
8483
8483
  },
8484
8484
  "locationInModule": {
8485
8485
  "filename": "src/constructs/codepipeline-event-notifier.ts",
8486
- "line": 63
8486
+ "line": 177
8487
8487
  },
8488
8488
  "parameters": [
8489
8489
  {
@@ -8509,7 +8509,6 @@
8509
8509
  "summary": "construct properties."
8510
8510
  },
8511
8511
  "name": "props",
8512
- "optional": true,
8513
8512
  "type": {
8514
8513
  "fqn": "codepipeline-event-notifier.CodePipelineEventNotifierProps"
8515
8514
  }
@@ -8519,7 +8518,7 @@
8519
8518
  "kind": "class",
8520
8519
  "locationInModule": {
8521
8520
  "filename": "src/constructs/codepipeline-event-notifier.ts",
8522
- "line": 52
8521
+ "line": 166
8523
8522
  },
8524
8523
  "name": "CodePipelineEventNotifier",
8525
8524
  "properties": [
@@ -8531,7 +8530,7 @@
8531
8530
  "immutable": true,
8532
8531
  "locationInModule": {
8533
8532
  "filename": "src/constructs/codepipeline-event-notifier.ts",
8534
- "line": 56
8533
+ "line": 170
8535
8534
  },
8536
8535
  "name": "topic",
8537
8536
  "type": {
@@ -8552,10 +8551,26 @@
8552
8551
  "kind": "interface",
8553
8552
  "locationInModule": {
8554
8553
  "filename": "src/constructs/codepipeline-event-notifier.ts",
8555
- "line": 8
8554
+ "line": 42
8556
8555
  },
8557
8556
  "name": "CodePipelineEventNotifierProps",
8558
8557
  "properties": [
8558
+ {
8559
+ "abstract": true,
8560
+ "docs": {
8561
+ "stability": "stable",
8562
+ "summary": "Pipelines that should produce notifications, selected by resource tags."
8563
+ },
8564
+ "immutable": true,
8565
+ "locationInModule": {
8566
+ "filename": "src/constructs/codepipeline-event-notifier.ts",
8567
+ "line": 46
8568
+ },
8569
+ "name": "targetPipeline",
8570
+ "type": {
8571
+ "fqn": "codepipeline-event-notifier.TargetPipeline"
8572
+ }
8573
+ },
8559
8574
  {
8560
8575
  "abstract": true,
8561
8576
  "docs": {
@@ -8566,7 +8581,7 @@
8566
8581
  "immutable": true,
8567
8582
  "locationInModule": {
8568
8583
  "filename": "src/constructs/codepipeline-event-notifier.ts",
8569
- "line": 45
8584
+ "line": 84
8570
8585
  },
8571
8586
  "name": "eventPattern",
8572
8587
  "optional": true,
@@ -8585,7 +8600,7 @@
8585
8600
  "immutable": true,
8586
8601
  "locationInModule": {
8587
8602
  "filename": "src/constructs/codepipeline-event-notifier.ts",
8588
- "line": 30
8603
+ "line": 69
8589
8604
  },
8590
8605
  "name": "maxWaitDuration",
8591
8606
  "optional": true,
@@ -8604,7 +8619,7 @@
8604
8619
  "immutable": true,
8605
8620
  "locationInModule": {
8606
8621
  "filename": "src/constructs/codepipeline-event-notifier.ts",
8607
- "line": 38
8622
+ "line": 77
8608
8623
  },
8609
8624
  "name": "timeout",
8610
8625
  "optional": true,
@@ -8623,7 +8638,7 @@
8623
8638
  "immutable": true,
8624
8639
  "locationInModule": {
8625
8640
  "filename": "src/constructs/codepipeline-event-notifier.ts",
8626
- "line": 15
8641
+ "line": 54
8627
8642
  },
8628
8643
  "name": "topic",
8629
8644
  "optional": true,
@@ -8641,7 +8656,7 @@
8641
8656
  "immutable": true,
8642
8657
  "locationInModule": {
8643
8658
  "filename": "src/constructs/codepipeline-event-notifier.ts",
8644
- "line": 22
8659
+ "line": 61
8645
8660
  },
8646
8661
  "name": "waitInterval",
8647
8662
  "optional": true,
@@ -8651,8 +8666,127 @@
8651
8666
  }
8652
8667
  ],
8653
8668
  "symbolId": "src/constructs/codepipeline-event-notifier:CodePipelineEventNotifierProps"
8669
+ },
8670
+ "codepipeline-event-notifier.TargetPipeline": {
8671
+ "assembly": "codepipeline-event-notifier",
8672
+ "datatype": true,
8673
+ "docs": {
8674
+ "stability": "stable",
8675
+ "summary": "Selection criteria for pipelines that should trigger notifications."
8676
+ },
8677
+ "fqn": "codepipeline-event-notifier.TargetPipeline",
8678
+ "kind": "interface",
8679
+ "locationInModule": {
8680
+ "filename": "src/constructs/codepipeline-event-notifier.ts",
8681
+ "line": 24
8682
+ },
8683
+ "name": "TargetPipeline",
8684
+ "properties": [
8685
+ {
8686
+ "abstract": true,
8687
+ "docs": {
8688
+ "stability": "stable",
8689
+ "summary": "Tag filters applied to CodePipeline resources."
8690
+ },
8691
+ "immutable": true,
8692
+ "locationInModule": {
8693
+ "filename": "src/constructs/codepipeline-event-notifier.ts",
8694
+ "line": 28
8695
+ },
8696
+ "name": "tags",
8697
+ "type": {
8698
+ "collection": {
8699
+ "elementtype": {
8700
+ "fqn": "codepipeline-event-notifier.TargetPipelineTag"
8701
+ },
8702
+ "kind": "array"
8703
+ }
8704
+ }
8705
+ },
8706
+ {
8707
+ "abstract": true,
8708
+ "docs": {
8709
+ "default": "all CodePipeline resources in this account and region",
8710
+ "remarks": "When set, the notifier also ignores STARTED events whose pipeline ARN is not in this list.",
8711
+ "stability": "stable",
8712
+ "summary": "Pipeline ARNs used as IAM resources for `GetPipelineExecution` and `ListTagsForResource`."
8713
+ },
8714
+ "immutable": true,
8715
+ "locationInModule": {
8716
+ "filename": "src/constructs/codepipeline-event-notifier.ts",
8717
+ "line": 36
8718
+ },
8719
+ "name": "arns",
8720
+ "optional": true,
8721
+ "type": {
8722
+ "collection": {
8723
+ "elementtype": {
8724
+ "primitive": "string"
8725
+ },
8726
+ "kind": "array"
8727
+ }
8728
+ }
8729
+ }
8730
+ ],
8731
+ "symbolId": "src/constructs/codepipeline-event-notifier:TargetPipeline"
8732
+ },
8733
+ "codepipeline-event-notifier.TargetPipelineTag": {
8734
+ "assembly": "codepipeline-event-notifier",
8735
+ "datatype": true,
8736
+ "docs": {
8737
+ "remarks": "Keys across entries are AND; values within an entry are OR.",
8738
+ "stability": "stable",
8739
+ "summary": "Tag filter for selecting CodePipeline pipelines."
8740
+ },
8741
+ "fqn": "codepipeline-event-notifier.TargetPipelineTag",
8742
+ "kind": "interface",
8743
+ "locationInModule": {
8744
+ "filename": "src/constructs/codepipeline-event-notifier.ts",
8745
+ "line": 9
8746
+ },
8747
+ "name": "TargetPipelineTag",
8748
+ "properties": [
8749
+ {
8750
+ "abstract": true,
8751
+ "docs": {
8752
+ "stability": "stable",
8753
+ "summary": "Tag key that must be present on the pipeline."
8754
+ },
8755
+ "immutable": true,
8756
+ "locationInModule": {
8757
+ "filename": "src/constructs/codepipeline-event-notifier.ts",
8758
+ "line": 13
8759
+ },
8760
+ "name": "key",
8761
+ "type": {
8762
+ "primitive": "string"
8763
+ }
8764
+ },
8765
+ {
8766
+ "abstract": true,
8767
+ "docs": {
8768
+ "stability": "stable",
8769
+ "summary": "Accepted values for {@link key}."
8770
+ },
8771
+ "immutable": true,
8772
+ "locationInModule": {
8773
+ "filename": "src/constructs/codepipeline-event-notifier.ts",
8774
+ "line": 18
8775
+ },
8776
+ "name": "values",
8777
+ "type": {
8778
+ "collection": {
8779
+ "elementtype": {
8780
+ "primitive": "string"
8781
+ },
8782
+ "kind": "array"
8783
+ }
8784
+ }
8785
+ }
8786
+ ],
8787
+ "symbolId": "src/constructs/codepipeline-event-notifier:TargetPipelineTag"
8654
8788
  }
8655
8789
  },
8656
- "version": "0.2.7",
8657
- "fingerprint": "y54/CjTZc5/U0G0edVc1uldzU6rZkhzbjpkz8SymIKM="
8790
+ "version": "0.3.0",
8791
+ "fingerprint": "86gKdiBIuLlaQSHsQEbGErh5OLIFIlSh2M5r4a6i2eg="
8658
8792
  }
package/API.md CHANGED
@@ -11,7 +11,7 @@ Provisions an EventBridge rule that listens for CodePipeline execution STARTED e
11
11
  ```typescript
12
12
  import { CodePipelineEventNotifier } from 'codepipeline-event-notifier'
13
13
 
14
- new CodePipelineEventNotifier(scope: Construct, id: string, props?: CodePipelineEventNotifierProps)
14
+ new CodePipelineEventNotifier(scope: Construct, id: string, props: CodePipelineEventNotifierProps)
15
15
  ```
16
16
 
17
17
  | **Name** | **Type** | **Description** |
@@ -38,7 +38,7 @@ the construct id.
38
38
 
39
39
  ---
40
40
 
41
- ##### `props`<sup>Optional</sup> <a name="props" id="codepipeline-event-notifier.CodePipelineEventNotifier.Initializer.parameter.props"></a>
41
+ ##### `props`<sup>Required</sup> <a name="props" id="codepipeline-event-notifier.CodePipelineEventNotifier.Initializer.parameter.props"></a>
42
42
 
43
43
  - *Type:* <a href="#codepipeline-event-notifier.CodePipelineEventNotifierProps">CodePipelineEventNotifierProps</a>
44
44
 
@@ -176,6 +176,7 @@ const codePipelineEventNotifierProps: CodePipelineEventNotifierProps = { ... }
176
176
 
177
177
  | **Name** | **Type** | **Description** |
178
178
  | --- | --- | --- |
179
+ | <code><a href="#codepipeline-event-notifier.CodePipelineEventNotifierProps.property.targetPipeline">targetPipeline</a></code> | <code><a href="#codepipeline-event-notifier.TargetPipeline">TargetPipeline</a></code> | Pipelines that should produce notifications, selected by resource tags. |
179
180
  | <code><a href="#codepipeline-event-notifier.CodePipelineEventNotifierProps.property.eventPattern">eventPattern</a></code> | <code>aws-cdk-lib.aws_events.EventPattern</code> | EventBridge event pattern that triggers the notifier. |
180
181
  | <code><a href="#codepipeline-event-notifier.CodePipelineEventNotifierProps.property.maxWaitDuration">maxWaitDuration</a></code> | <code>aws-cdk-lib.Duration</code> | Maximum duration to wait for execution state changes. |
181
182
  | <code><a href="#codepipeline-event-notifier.CodePipelineEventNotifierProps.property.timeout">timeout</a></code> | <code>aws-cdk-lib.Duration</code> | Timeout for the notifier Lambda function. |
@@ -184,6 +185,18 @@ const codePipelineEventNotifierProps: CodePipelineEventNotifierProps = { ... }
184
185
 
185
186
  ---
186
187
 
188
+ ##### `targetPipeline`<sup>Required</sup> <a name="targetPipeline" id="codepipeline-event-notifier.CodePipelineEventNotifierProps.property.targetPipeline"></a>
189
+
190
+ ```typescript
191
+ public readonly targetPipeline: TargetPipeline;
192
+ ```
193
+
194
+ - *Type:* <a href="#codepipeline-event-notifier.TargetPipeline">TargetPipeline</a>
195
+
196
+ Pipelines that should produce notifications, selected by resource tags.
197
+
198
+ ---
199
+
187
200
  ##### `eventPattern`<sup>Optional</sup> <a name="eventPattern" id="codepipeline-event-notifier.CodePipelineEventNotifierProps.property.eventPattern"></a>
188
201
 
189
202
  ```typescript
@@ -255,5 +268,100 @@ Interval between `GetPipelineExecution` waits.
255
268
 
256
269
  ---
257
270
 
271
+ ### TargetPipeline <a name="TargetPipeline" id="codepipeline-event-notifier.TargetPipeline"></a>
272
+
273
+ Selection criteria for pipelines that should trigger notifications.
274
+
275
+ #### Initializer <a name="Initializer" id="codepipeline-event-notifier.TargetPipeline.Initializer"></a>
276
+
277
+ ```typescript
278
+ import { TargetPipeline } from 'codepipeline-event-notifier'
279
+
280
+ const targetPipeline: TargetPipeline = { ... }
281
+ ```
282
+
283
+ #### Properties <a name="Properties" id="Properties"></a>
284
+
285
+ | **Name** | **Type** | **Description** |
286
+ | --- | --- | --- |
287
+ | <code><a href="#codepipeline-event-notifier.TargetPipeline.property.tags">tags</a></code> | <code><a href="#codepipeline-event-notifier.TargetPipelineTag">TargetPipelineTag</a>[]</code> | Tag filters applied to CodePipeline resources. |
288
+ | <code><a href="#codepipeline-event-notifier.TargetPipeline.property.arns">arns</a></code> | <code>string[]</code> | Pipeline ARNs used as IAM resources for `GetPipelineExecution` and `ListTagsForResource`. |
289
+
290
+ ---
291
+
292
+ ##### `tags`<sup>Required</sup> <a name="tags" id="codepipeline-event-notifier.TargetPipeline.property.tags"></a>
293
+
294
+ ```typescript
295
+ public readonly tags: TargetPipelineTag[];
296
+ ```
297
+
298
+ - *Type:* <a href="#codepipeline-event-notifier.TargetPipelineTag">TargetPipelineTag</a>[]
299
+
300
+ Tag filters applied to CodePipeline resources.
301
+
302
+ ---
303
+
304
+ ##### `arns`<sup>Optional</sup> <a name="arns" id="codepipeline-event-notifier.TargetPipeline.property.arns"></a>
305
+
306
+ ```typescript
307
+ public readonly arns: string[];
308
+ ```
309
+
310
+ - *Type:* string[]
311
+ - *Default:* all CodePipeline resources in this account and region
312
+
313
+ Pipeline ARNs used as IAM resources for `GetPipelineExecution` and `ListTagsForResource`.
314
+
315
+ When set, the notifier also ignores STARTED events whose pipeline ARN is not in this list.
316
+
317
+ ---
318
+
319
+ ### TargetPipelineTag <a name="TargetPipelineTag" id="codepipeline-event-notifier.TargetPipelineTag"></a>
320
+
321
+ Tag filter for selecting CodePipeline pipelines.
322
+
323
+ Keys across entries are AND; values within an entry are OR.
324
+
325
+ #### Initializer <a name="Initializer" id="codepipeline-event-notifier.TargetPipelineTag.Initializer"></a>
326
+
327
+ ```typescript
328
+ import { TargetPipelineTag } from 'codepipeline-event-notifier'
329
+
330
+ const targetPipelineTag: TargetPipelineTag = { ... }
331
+ ```
332
+
333
+ #### Properties <a name="Properties" id="Properties"></a>
334
+
335
+ | **Name** | **Type** | **Description** |
336
+ | --- | --- | --- |
337
+ | <code><a href="#codepipeline-event-notifier.TargetPipelineTag.property.key">key</a></code> | <code>string</code> | Tag key that must be present on the pipeline. |
338
+ | <code><a href="#codepipeline-event-notifier.TargetPipelineTag.property.values">values</a></code> | <code>string[]</code> | Accepted values for {@link key}. |
339
+
340
+ ---
341
+
342
+ ##### `key`<sup>Required</sup> <a name="key" id="codepipeline-event-notifier.TargetPipelineTag.property.key"></a>
343
+
344
+ ```typescript
345
+ public readonly key: string;
346
+ ```
347
+
348
+ - *Type:* string
349
+
350
+ Tag key that must be present on the pipeline.
351
+
352
+ ---
353
+
354
+ ##### `values`<sup>Required</sup> <a name="values" id="codepipeline-event-notifier.TargetPipelineTag.property.values"></a>
355
+
356
+ ```typescript
357
+ public readonly values: string[];
358
+ ```
359
+
360
+ - *Type:* string[]
361
+
362
+ Accepted values for {@link key}.
363
+
364
+ ---
365
+
258
366
 
259
367
 
package/README.md CHANGED
@@ -1,18 +1,31 @@
1
- # CodePipeline Event Notifier
1
+ # CodePipeline Event Notifier (CDK v2)
2
2
 
3
- [![npm version](https://img.shields.io/npm/v/codepipeline-event-notifier.svg)](https://www.npmjs.com/package/codepipeline-event-notifier)
4
- [![license](https://img.shields.io/npm/l/codepipeline-event-notifier.svg)](LICENSE)
3
+ [![npm version](https://img.shields.io/npm/v/codepipeline-event-notifier?style=flat-square)](https://www.npmjs.com/package/codepipeline-event-notifier)
4
+ [![license](https://img.shields.io/npm/l/codepipeline-event-notifier?style=flat-square)](https://www.npmjs.com/package/codepipeline-event-notifier)
5
+ [![Node.js](https://img.shields.io/node/v/codepipeline-event-notifier?style=flat-square)](https://www.npmjs.com/package/codepipeline-event-notifier)
6
+ [![build](https://img.shields.io/github/actions/workflow/status/gammarers-aws-cdk-constructs/codepipeline-event-notifier/build.yml?branch=main&label=build&style=flat-square)](https://github.com/gammarers-aws-cdk-constructs/codepipeline-event-notifier/actions/workflows/build.yml)
7
+
8
+ [![View on Construct Hub](https://constructs.dev/badge?package=codepipeline-event-notifier)](https://constructs.dev/packages/codepipeline-event-notifier)
5
9
 
6
10
  CDK construct that listens to **AWS CodePipeline execution STARTED** events via EventBridge, invokes a Lambda notifier, and publishes execution state changes to an SNS topic.
7
11
 
8
12
  ## Features
9
13
 
10
14
  - **EventBridge integration**: triggers on `CodePipeline Pipeline Execution State Change` with `state=STARTED` (customizable via `eventPattern`)
15
+ - **Tag-based pipeline selection**: required `targetPipeline.tags` filters which pipelines are notified (`ListTagsForResource`; keys are AND, values are OR)
16
+ - **Least-privilege IAM**: CodePipeline API access is scoped to this account and region, or to `targetPipeline.arns` when set
11
17
  - **SNS notifications**: publishes execution status transitions as JSON messages (`phase`: `eventbridge` / `wait`)
12
18
  - **Execution waiting**: calls `GetPipelineExecution` until a terminal state (`SUCCEEDED` / `FAILED` / `STOPPED` / `SUPERSEDED`) or timeout
13
- - **Configurable props**: reuse an existing SNS topic, adjust wait interval / max wait duration / Lambda timeout, and filter events
19
+ - **Configurable props**: reuse an existing SNS topic, adjust wait interval / max wait duration / Lambda timeout, and optionally refine the EventBridge pattern
14
20
  - **No subscriptions by default**: the SNS topic is created (or reused), but subscriptions (email/HTTP/etc.) are intentionally not configured
15
21
 
22
+ ## How it works
23
+
24
+ 1. EventBridge matches a CodePipeline execution state-change event (default: `state=STARTED`) and invokes the notifier Lambda.
25
+ 2. The Lambda resolves the pipeline ARN, then keeps the event only when `targetPipeline.tags` match (`ListTagsForResource`; keys are AND, values are OR) and, if set, `targetPipeline.arns` includes the pipeline.
26
+ 3. It publishes an SNS message with `phase: eventbridge`, then calls `GetPipelineExecution` until a terminal status (`SUCCEEDED` / `FAILED` / `STOPPED` / `SUPERSEDED`) or `maxWaitDuration`.
27
+ 4. Each status change (and timeout) is published with `phase: wait`. Subscribe to `notifier.topic`; this construct does not add subscriptions.
28
+
16
29
  ## Installation
17
30
 
18
31
  ### npm
@@ -27,6 +40,12 @@ npm install codepipeline-event-notifier
27
40
  yarn add codepipeline-event-notifier
28
41
  ```
29
42
 
43
+ ### pnpm
44
+
45
+ ```bash
46
+ pnpm add codepipeline-event-notifier
47
+ ```
48
+
30
49
  ## Usage
31
50
 
32
51
  Instantiate `CodePipelineEventNotifier` in your CDK stack:
@@ -40,7 +59,16 @@ export class MyStack extends Stack {
40
59
  constructor(scope: Construct, id: string) {
41
60
  super(scope, id);
42
61
 
43
- const notifier = new CodePipelineEventNotifier(this, 'CodePipelineEventNotifier');
62
+ const notifier = new CodePipelineEventNotifier(this, 'CodePipelineEventNotifier', {
63
+ targetPipeline: {
64
+ tags: [
65
+ {
66
+ key: 'Notify',
67
+ values: ['true'],
68
+ },
69
+ ],
70
+ },
71
+ });
44
72
 
45
73
  // Optionally subscribe to the topic created by the construct
46
74
  // notifier.topic.addSubscription(...);
@@ -66,12 +94,22 @@ export class MyStack extends Stack {
66
94
  waitInterval: Duration.seconds(30),
67
95
  maxWaitDuration: Duration.minutes(10),
68
96
  timeout: Duration.minutes(12),
97
+ targetPipeline: {
98
+ tags: [
99
+ {
100
+ key: 'Team',
101
+ values: ['platform', 'infra'],
102
+ },
103
+ ],
104
+ arns: [
105
+ 'arn:aws:codepipeline:us-east-1:123456789012:my-pipeline',
106
+ ],
107
+ },
69
108
  eventPattern: {
70
109
  source: ['aws.codepipeline'],
71
110
  detailType: ['CodePipeline Pipeline Execution State Change'],
72
111
  detail: {
73
112
  state: ['STARTED'],
74
- pipeline: ['my-pipeline'],
75
113
  },
76
114
  },
77
115
  });
@@ -83,6 +121,7 @@ export class MyStack extends Stack {
83
121
 
84
122
  | Prop | Type | Default | Description |
85
123
  | --- | --- | --- | --- |
124
+ | `targetPipeline` | `TargetPipeline` | *(required)* | Tag filters (`tags`) for pipelines that should notify. Optional `arns` restrict IAM and skip other pipelines. Default IAM is this account and region |
86
125
  | `topic` | `sns.ITopic` | new topic | SNS topic to publish notifications to (also exposed as `notifier.topic`) |
87
126
  | `waitInterval` | `Duration` | `10 seconds` | Interval between `GetPipelineExecution` calls |
88
127
  | `maxWaitDuration` | `Duration` | `14 minutes` | Maximum wait duration before giving up |
@@ -92,9 +131,15 @@ export class MyStack extends Stack {
92
131
  The notifier Lambda uses these environment variables (set by the construct from props):
93
132
 
94
133
  - `SNS_TOPIC_ARN` (**required**): SNS topic ARN to publish notifications to
134
+ - `TARGET_PIPELINE_TAGS` (**required**): JSON array of `{ key, values }` tag filters
135
+ - `TARGET_PIPELINE_ARNS` (optional): JSON array of pipeline ARNs used as an allowlist when `targetPipeline.arns` is set
95
136
  - `WAIT_INTERVAL_SECONDS` (default: `10`): wait interval in seconds
96
137
  - `MAX_WAIT_MINUTES` (default: `14`): maximum wait duration in minutes
97
138
 
139
+ ## API
140
+
141
+ See the [API reference](./API.md).
142
+
98
143
  ## Requirements
99
144
 
100
145
  - Node.js `>= 20`