Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Present the approval notifications in a slightly better way #35

Merged
merged 5 commits into from
Dec 17, 2023
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
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,19 +44,20 @@ module "codepipeline_notifications" {
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_additional_tag_map"></a> [additional\_tag\_map](#input\_additional\_tag\_map) | Additional tags for appending to tags\_as\_list\_of\_maps. Not added to `tags`. | `map(string)` | `{}` | no |
| <a name="input_approval_event_type_ids"></a> [approval\_event\_type\_ids](#input\_approval\_event\_type\_ids) | The list of pipeline events to trigger a notification on | `list(string)` | <pre>[<br> "started",<br> "succeeded",<br> "failed"<br>]</pre> | no |
| <a name="input_attributes"></a> [attributes](#input\_attributes) | Additional attributes (e.g. `1`) | `list(string)` | `[]` | no |
| <a name="input_codepipelines"></a> [codepipelines](#input\_codepipelines) | CodePipeline resources that should trigger Slack notifications | `list(any)` | n/a | yes |
| <a name="input_context"></a> [context](#input\_context) | Single object for setting entire context at once.<br>See description of individual variables for details.<br>Leave string and numeric variables as `null` to use default value.<br>Individual variable settings (non-null) override settings in context object,<br>except for attributes, tags, and additional\_tag\_map, which are merged. | `any` | <pre>{<br> "additional_tag_map": {},<br> "attributes": [],<br> "delimiter": null,<br> "enabled": true,<br> "environment": null,<br> "id_length_limit": null,<br> "label_key_case": null,<br> "label_order": [],<br> "label_value_case": null,<br> "name": null,<br> "namespace": null,<br> "regex_replace_chars": null,<br> "stage": null,<br> "tags": {}<br>}</pre> | no |
| <a name="input_delimiter"></a> [delimiter](#input\_delimiter) | Delimiter to be used between `namespace`, `environment`, `stage`, `name` and `attributes`.<br>Defaults to `-` (hyphen). Set to `""` to use no delimiter at all. | `string` | `null` | no |
| <a name="input_enabled"></a> [enabled](#input\_enabled) | Set to false to prevent the module from creating any resources | `bool` | `null` | no |
| <a name="input_environment"></a> [environment](#input\_environment) | Environment, e.g. 'uw2', 'us-west-2', OR 'prod', 'staging', 'dev', 'UAT' | `string` | `null` | no |
| <a name="input_event_type_ids"></a> [event\_type\_ids](#input\_event\_type\_ids) | The list of event type to trigger a notification on | `list(string)` | <pre>[<br> "failed",<br> "canceled",<br> "started",<br> "resumed",<br> "succeeded",<br> "superseded"<br>]</pre> | no |
| <a name="input_id_length_limit"></a> [id\_length\_limit](#input\_id\_length\_limit) | Limit `id` to this many characters (minimum 6).<br>Set to `0` for unlimited length.<br>Set to `null` for default, which is `0`.<br>Does not affect `id_full`. | `number` | `null` | no |
| <a name="input_label_key_case"></a> [label\_key\_case](#input\_label\_key\_case) | The letter case of label keys (`tag` names) (i.e. `name`, `namespace`, `environment`, `stage`, `attributes`) to use in `tags`.<br>Possible values: `lower`, `title`, `upper`.<br>Default value: `title`. | `string` | `null` | no |
| <a name="input_label_order"></a> [label\_order](#input\_label\_order) | The naming order of the id output and Name tag.<br>Defaults to ["namespace", "environment", "stage", "name", "attributes"].<br>You can omit any of the 5 elements, but at least one must be present. | `list(string)` | `null` | no |
| <a name="input_label_value_case"></a> [label\_value\_case](#input\_label\_value\_case) | The letter case of output label values (also used in `tags` and `id`).<br>Possible values: `lower`, `title`, `upper` and `none` (no transformation).<br>Default value: `lower`. | `string` | `null` | no |
| <a name="input_name"></a> [name](#input\_name) | Solution name, e.g. 'app' or 'jenkins' | `string` | `null` | no |
| <a name="input_namespace"></a> [namespace](#input\_namespace) | Namespace, which could be your organization name or abbreviation, e.g. 'eg' or 'cp' | `string` | `null` | no |
| <a name="input_pipeline_event_type_ids"></a> [pipeline\_event\_type\_ids](#input\_pipeline\_event\_type\_ids) | The list of pipeline events to trigger a notification on | `list(string)` | <pre>[<br> "started",<br> "failed",<br> "canceled",<br> "resumed",<br> "succeeded",<br> "superseded"<br>]</pre> | no |
| <a name="input_regex_replace_chars"></a> [regex\_replace\_chars](#input\_regex\_replace\_chars) | Regex to replace chars with empty string in `namespace`, `environment`, `stage` and `name`.<br>If not set, `"/[^a-zA-Z0-9-]/"` is used to remove all characters other than hyphens, letters and digits. | `string` | `null` | no |
| <a name="input_slack_channel"></a> [slack\_channel](#input\_slack\_channel) | A slack channel to send the deployment notifications to | `string` | n/a | yes |
| <a name="input_slack_emoji"></a> [slack\_emoji](#input\_slack\_emoji) | The emoji avatar of the user that sends the notifications | `string` | `":rocket:"` | no |
Expand Down
39 changes: 30 additions & 9 deletions lambdas/notifier/notifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,19 @@
logger = logging.getLogger(__name__)

STATE_COLORS = {
"STARTED": "#1a9edb",
"SUCCEEDED": "#50ba32",
"RESUMED": "#1a9edb",
"FAILED": "#f02b1d",
"CANCELED": "#919191",
"SUPERSEDED": "#919191",
"Deployment": {
"STARTED": "#1a9edb",
"SUCCEEDED": "#50ba32",
"RESUMED": "#1a9edb",
"FAILED": "#f02b1d",
"CANCELED": "#919191",
"SUPERSEDED": "#919191",
},
"Approval": {
"STARTED": "#f5d142",
"SUCCEEDED": "#50ba32",
"FAILED": "#f02b1d",
},
}


Expand All @@ -31,6 +38,7 @@ def format_slack_attachment(
execution_id: str,
environment: str,
region: str,
action: str,
revision_summary: t.Optional[str],
revision_url: t.Optional[str],
) -> dict:
Expand All @@ -57,8 +65,12 @@ def format_slack_attachment(
},
]
return {
"color": STATE_COLORS[pipeline_state],
"fallback": (f"`{pipeline_name}` has `{pipeline_state}`"),
"color": STATE_COLORS[action][pipeline_state],
"fallback": format_slack_text(
pipeline_name=pipeline_name,
pipeline_state=pipeline_state,
action=action,
).replace("*", ""),
"fields": [
{"title": "Pipeline", "value": pipeline_name},
{"title": "Execution ID", "value": execution_link},
Expand All @@ -70,6 +82,13 @@ def format_slack_attachment(


def format_slack_text(*, pipeline_name: str, pipeline_state: str, action: str):
if action == "Approval":
if pipeline_state == "STARTED":
return f"*Deployment* of *{pipeline_name}* is awaiting approval."
elif pipeline_state == "FAILED":
return f"*Deployment* of *{pipeline_name}* has been rejected."
elif pipeline_state == "SUCCEEDED":
return f"*Deployment* of *{pipeline_name}* has been approved."
return f"*{action}* of *{pipeline_name}* has {pipeline_state.lower()}."


Expand All @@ -90,18 +109,20 @@ def build_slack_message_from_event(event):
revision = pipeline_execution["artifactRevisions"][0]
revision_url = revision.get("revisionUrl")
revision_summary = revision.get("revisionSummary")
action = pipeline_action or "Deployment"

# Build a message with an attachment with details
text = format_slack_text(
pipeline_name=pipeline_name,
pipeline_state=pipeline_state,
action=pipeline_action or "Deployment",
action=action,
)
attachment = format_slack_attachment(
pipeline_name=pipeline_name,
pipeline_state=pipeline_state,
execution_id=execution_id,
region=region,
action=action,
revision_summary=revision_summary,
revision_url=revision_url,
environment=os.environ["ENVIRONMENT"],
Expand Down
Loading
Loading