Skip to content

Commit 88d81d1

Browse files
committed
feat(KFLUXUI-592): improve the Readme.md for system notifications
1 parent eb3c899 commit 88d81d1

File tree

34 files changed

+290
-224
lines changed

34 files changed

+290
-224
lines changed
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
name: Validate System Notification ConfigMaps
2+
3+
on:
4+
pull_request:
5+
paths:
6+
- "components/konflux-info/system-notifications/**/*.yaml"
7+
- "components/konflux-info/notification-schema.json"
8+
env:
9+
NOTIFICATION_DIR: components/konflux-info
10+
SCHEMA_FILE: components/konflux-info/notification-schema.json
11+
TMP_DIR: .tmp/notifications
12+
13+
jobs:
14+
validate:
15+
runs-on: ubuntu-latest
16+
17+
steps:
18+
- uses: actions/checkout@v3
19+
20+
- name: Install yq (YAML processor)
21+
run: |
22+
sudo wget https://github.com/mikefarah/yq/releases/download/v4.34.1/yq_linux_amd64 -O /usr/bin/yq
23+
sudo chmod +x /usr/bin/yq
24+
25+
- name: Check konflux-system-notification label present
26+
run: |
27+
mkdir -p ${{ env.TMP_DIR }}
28+
for file in ${{ env.NOTIFICATION_DIR }}/**/**/system-notifications/*.yaml; do
29+
if [[ "$(basename "$file")" == "kustomization.yaml" ]]; then
30+
continue
31+
fi
32+
label=$(yq e '.metadata.labels."konflux.system.notification"' "$file")
33+
if [[ "$label" != "\"true\"" && "$label" != "true" ]]; then
34+
echo "ERROR: $file is missing konflux-system-notification: \"true\" label"
35+
exit 1
36+
fi
37+
done
38+
39+
- name: Validate notification-content.json against schema
40+
uses: actions/setup-node@v3
41+
with:
42+
node-version: "18"
43+
44+
- name: Install ajv-cli for JSON Schema validation
45+
run: |
46+
npm install -g ajv-cli
47+
48+
- name: Validate notification-content.json files
49+
run: |
50+
mkdir -p ${{ env.TMP_DIR }}
51+
for file in ${{ env.NOTIFICATION_DIR }}/**/**/system-notifications/*.yaml; do
52+
file_name=$(basename "$file")
53+
if [[ "$file_name" == "kustomization.yaml" ]]; then
54+
continue
55+
fi
56+
# Extract JSON content from ConfigMap
57+
yq e '.data."notification-content.json"' "$file" > "${TMP_DIR}/${file_name}.json"
58+
ajv validate -s "${SCHEMA_FILE}" -d "${TMP_DIR}/${file_name}.json" --errors=text
59+
if [ $? -ne 0 ]; then
60+
echo "ERROR: notification-content.json in ${file} does not validate against schema"
61+
exit 1
62+
fi
63+
done

components/konflux-info/README.md

Lines changed: 152 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,58 @@
1+
- 1. [📂 Directory Structure](#DirectoryStructure)
2+
- 2. [📢 Konflux Banner](#KonfluxBanner)
3+
- 2.1. [✅ Banner Content Validation](#BannerContentValidation)
4+
- 2.2. [✅ Banner Content Specification](#BannerContentSpecification)
5+
- 2.2.1. [**Schema**](#Schema)
6+
- 2.2.2. [**Required and Optional Fields for Each Banner**](#RequiredandOptionalFieldsforEachBanner)
7+
- 2.3. [Usage Scenarios & Examples](#UsageScenariosExamples)
8+
- 2.3.1. [**1. Multiple Banners**](#1.MultipleBanners)
9+
- 2.3.2. [**2. One-Time Banner**](#2.One-TimeBanner)
10+
- 2.3.3. [**3. Weekly Recurring Banner**](#3.WeeklyRecurringBanner)
11+
- 2.3.4. [**4. Monthly Recurring Banner**](#4.MonthlyRecurringBanner)
12+
- 2.3.5. [**5. Always-On Banner**](#5.Always-OnBanner)
13+
- 2.3.6. [**6. Empty Banner**](#6.EmptyBanner)
14+
- 2.4. [📝 How to submit a PR for Banner](#HowtosubmitaPRforBanner)
15+
- 2.5. [✅ UI Behavior](#UIBehavior)
16+
- 2.6. [❓ Frequently Asked Questions](#FrequentlyAskedQuestions)
17+
- 3. [📢 System Notifications](#SystemNotifications)
18+
- 3.1. [**Notification JSON Format**](#NotificationJSONFormat)
19+
- 3.2. [**Example Notification ConfigMap**](#ExampleNotificationConfigMap)
20+
- 3.3. [**Notification Content Validation**](#NotificationContentValidation)
21+
- 3.4. [**Folder Structure**](#FolderStructure)
22+
- 3.5. [**UI Behavior**](#UIBehavior-1)
23+
- 3.6. [**When to Add or Remove Notifications**](#WhentoAddorRemoveNotifications)
24+
125
# 🚀 konflux-info Repository Guide
226

3-
## 📂 Directory Structure
27+
## 1. <a name='DirectoryStructure'></a>📂 Directory Structure
428

529
The `KONFLUX-INFO` directory contains:
630

731
```bash
832
.
9-
├── auto-alert-schema.json # JSON shema definition for auto-alert-content.yaml
1033
├── base/ # Common resources (e.g., RBAC)
1134
├── production/ # Production cluster configurations
1235
├── staging/ # Staging cluster configurations
1336
├── banner-schema.json # JSON schema definition for validating banner-content.yaml files
14-
37+
├── notification-schema.json # JSON schema definition for validating notification-content.json
1538
```
1639

1740
Each cluster directory contains:
1841

1942
```bash
2043
.
21-
├── auto-alerts # The directory manages auto-generated alerts content shown in the UI
44+
├── system-notifications # The directory manages auto-generated notifications content shown in the UI
2245
├── banner-content.yaml # The banner content shown in the UI
2346
├── info.json # Metadata about the cluster
24-
└── kustomization.yaml # Kustomize configuration for this cluster, including base, auto-alerts, and other configs
47+
└── kustomization.yaml # Kustomize configuration for this cluster, including base, system-notifications, and other configs
2548

2649
```
2750

2851
---
2952

30-
## ✅ Banner Content Validation
53+
## 2. <a name='KonfluxBanner'></a>📢 Konflux Banner
54+
55+
### 2.1. <a name='BannerContentValidation'></a>✅ Banner Content Validation
3156

3257
To maintain consistency, a GitHub workflow named **`banner-validate`** automatically validates all `banner-content.yaml` files against the schema defined in [`banner-schema.json`](./banner-schema.json).
3358

@@ -47,26 +72,19 @@ To maintain consistency, a GitHub workflow named **`banner-validate`** automatic
4772
- Review the error message in the PR checks.
4873
- Compare your changes with the [schema](./banner-schema.json) and [examples in README](#usage-scenarios--examples).
4974

50-
## ✅ Banner Content Specification
75+
### 2.2. <a name='BannerContentSpecification'></a>✅ Banner Content Specification
5176

5277
The `banner-content.yaml` file defines one or more banners displayed in the Konflux UI. Each cluster has its own `banner-content.yaml` under its directory (e.g., `staging/stone-stage-p01/banner-content.yaml`).
5378

54-
### **Schema**
79+
#### 2.2.1. <a name='Schema'></a>**Schema**
5580

5681
The schema for banner content is defined in [`banner-schema.json`](./banner-schema.json) and validated automatically by the `banner-validate` GitHub workflow on every PR.
5782

5883
The file must contain a **YAML list** where each item represents a banner configuration.
5984

6085
---
6186

62-
### **Important Behavior**
63-
64-
- The <strong style="color: red;">UI displays only the first valid active banner</strong> from the list, based on current date, time, and optional recurrence settings.
65-
- If multiple banners are configured, <strong style="color: red;">order matters</strong>.
66-
67-
---
68-
69-
### **Required and Optional Fields for Each Banner**
87+
#### 2.2.2. <a name='RequiredandOptionalFieldsforEachBanner'></a>**Required and Optional Fields for Each Banner**
7088

7189
📎 For the full schema used in CI validation, see banner-schema.json. This table is a human-friendly reference for banner authors.
7290

@@ -86,9 +104,9 @@ The file must contain a **YAML list** where each item represents a banner config
86104

87105
---
88106

89-
### **Usage Scenarios & Examples**
107+
### 2.3. <a name='UsageScenariosExamples'></a>Usage Scenarios & Examples
90108

91-
#### **1. Multiple Banners**
109+
#### 2.3.1. <a name='1.MultipleBanners'></a>**1. Multiple Banners**
92110

93111
Example of a `banner-content.yaml` with multiple banners (first active one is shown in UI):
94112

@@ -110,7 +128,7 @@ Example of a `banner-content.yaml` with multiple banners (first active one is sh
110128
# No timezone is needed when you expect it's UTC.
111129
```
112130

113-
#### **2. One-Time Banner**
131+
#### 2.3.2. <a name='2.One-TimeBanner'></a>**2. One-Time Banner**
114132

115133
For a single event on a specific date:
116134

@@ -133,7 +151,7 @@ For a single event in today
133151
endTime: "14:00"
134152
```
135153
136-
#### ✅ **2. Weekly Recurring Banner**
154+
#### 2.3.3. <a name='3.WeeklyRecurringBanner'></a>✅ **3. Weekly Recurring Banner**
137155
138156
For an event that repeats every week:
139157
@@ -145,7 +163,7 @@ For an event that repeats every week:
145163
endTime: "04:00"
146164
```
147165
148-
#### ✅ **3. Monthly Recurring Banner**
166+
#### 2.3.4. <a name='4.MonthlyRecurringBanner'></a>✅ **4. Monthly Recurring Banner**
149167
150168
For an event that happens on the same day each month:
151169
@@ -158,7 +176,7 @@ For an event that happens on the same day each month:
158176
timeZone: "Asia/Shanghai"
159177
```
160178
161-
#### ✅ **4. Always-On Banner**
179+
#### 2.3.5. <a name='5.Always-OnBanner'></a>✅ **5. Always-On Banner**
162180
163181
For an event that requires immediate notification:
164182
@@ -167,7 +185,7 @@ For an event that requires immediate notification:
167185
type: "info"
168186
```
169187
170-
#### ✅ **5. Empty Banner**
188+
#### 2.3.6. <a name='6.EmptyBanner'></a>✅ **6. Empty Banner**
171189
172190
When there are no events to announce:
173191
@@ -177,7 +195,7 @@ When there are no events to announce:
177195

178196
---
179197

180-
## 📝 How to submit a PR for Banner
198+
### 2.4. <a name='HowtosubmitaPRforBanner'></a>📝 How to submit a PR for Banner
181199

182200
1. Locate the target cluster directory:
183201

@@ -225,7 +243,18 @@ When there are no events to announce:
225243
Purpose: Release announcement for Konflux 1.2
226244
```
227245
228-
## ❓ Frequently Asked Questions
246+
### 2.5. <a name='UIBehavior'></a>✅ UI Behavior
247+
248+
- The <strong style="color: red;">UI displays only the first valid active banner</strong> from the list, based on current date, time, and optional recurrence settings.
249+
- If multiple banners are configured, <strong style="color: red;">order matters</strong>.
250+
- <strong style="color: red;">Time-related fields like `startTime` and `endTime` are not displayed in the UI</strong>; they only control when the banner is active.
251+
252+
<strong>To convey duration or timing details, please include them within the `summary`.</strong>
253+
254+
- <strong style="color: red;">The `type` and `summary` fields are displayed directly in the UI</strong>.
255+
- We enjoyed leveraging the [PatternFly Banner component (v5)](https://v5-archive.patternfly.org/components/banner/) to implement the UI, following its design principles for clarity and consistency.
256+
257+
### 2.6. <a name='FrequentlyAskedQuestions'></a>❓ Frequently Asked Questions
229258

230259
- Why is only one banner shown even when multiple are configured?
231260

@@ -245,41 +274,122 @@ When there are no events to announce:
245274

246275
<strong style="color: red;">📝 If multiple messages need to be shared at the same time, consider combining them into a well-written summary inside a single banner.</strong>
247276

248-
## 📢 Auto Alerts(WIP)
277+
## 3. <a name='SystemNotifications'></a>📢 System Notifications
278+
279+
The infrastructure team uses System Notifications to automatically surface important operational notifications in the Konflux UI.
280+
281+
These notifications are generated from monitoring systems or automation scripts as Kubernetes ConfigMaps.
282+
283+
The Konflux UI detects and displays these notifications to inform users about system-wide conditions.
284+
285+
### 3.1. <a name='NotificationJSONFormat'></a>✅ **Notification JSON Format**
286+
287+
System notifications are stored as Kubernetes ConfigMaps in the `system-notifications/` directory.
288+
289+
Each ConfigMap contains notification data in the `notification-content.json` field as JSON.
290+
291+
<strong>Key points:</strong>
292+
293+
- The JSON payload supports these fields for each notification object:
294+
295+
- <strong>title (optional)</strong>: A short heading.
296+
- <strong>summary (required)</strong>: A brief, user-facing message displayed as the notification content.
297+
- <strong>type (required)</strong>: It sets the bell icon. Allowed values: `info`, `warning`, or `danger`.
298+
- <strong>activeTimestamp (optional)</strong>: The time when the notification should be shown, specified as an ISO 8601 timestamp (e.g., `"2025-08-11T11:08:17Z"`).
299+
- If set to a future time, the UI will delay displaying the notification until that time is reached.
300+
- If not set, the system falls back to using the resource’s raw `creationTimestamp` to decide when to show the notification.
249301

250-
We enables the infrastructure team to automatically surface specific operational issues or warnings in the Konflux UI.
302+
- Payload structure:
251303

252-
These alerts would be auto-generated from monitoring systems or automation scripts, written as Kubernetes ConfigMaps, and automatically picked up by the Konflux UI to inform users of system-wide conditions.
304+
We recommend using <strong>a single JSON object representing one notification</strong> in `notification-content.json`.
253305

254-
### ✅ Alert YAML Format
306+
However, <strong>a JSON list (array) of notification objects is also allowed</strong> if multiple notifications need to be included in one ConfigMap.
255307

256-
Each file under auto-alerts/ must be a valid Kubernetes ConfigMap, including at minimum:
308+
### 3.2. <a name='ExampleNotificationConfigMap'></a>✅ **Example Notification ConfigMap**
257309

258310
```yaml
259311
apiVersion: v1
260312
kind: ConfigMap
261313
metadata:
262-
name: konflux-auto-alert-xyz
314+
name: konflux-system-notification-xyz
263315
namespace: konflux-info
264316
labels:
265-
konflux-auto-alert: "true" # Required. UI filter alerts out by this label.
317+
konflux.system.notification: "true"
266318
data:
267-
auto-alert-content.yaml: |
268-
enable: true
269-
summary: "Builds are delayed due to maintenance"
270-
type: "warning"
319+
notification-content.json: |-
320+
{
321+
"summary": "Builds are delayed due to maintenance",
322+
"type": "warning",
323+
"title": "From Builds Service",
324+
"activeTimestamp": "2025-08-12T14:30:00Z"
325+
}
271326
```
272327

273-
🔐 The data.banner-content.yaml should follow the schema defined in `auto-alert-schema.json`
328+
⚠️ `title` and `activeTimestamp` are optional fields. Include them only when necessary.
274329

275-
### Folder Structure
330+
### 3.3. <a name='NotificationContentValidation'></a>✅ **Notification Content Validation**
331+
332+
To ensure consistency, a GitHub workflow named `notification-validate` automatically checks that all ConfigMaps in the `system-notifications` folder include the required labels and validates all `notification-content.json` objects against the schema defined in [notification-schema.json](./notification-schema.json).
333+
334+
**When does it run?**
335+
336+
- On any pull request that changes:
337+
- `notification-schema.json` (schema definition)
338+
- Any `yaml` file defined under `system-notifications`
339+
340+
**What does it check?**
341+
342+
- Ensures the JSON structure matches the schema (e.g., required fields, allowed values).
343+
- Ensure the configmaps are labelled well.
344+
- Prevents invalid or misconfigured notifications from being merged.
345+
346+
**How to fix validation errors?**
347+
348+
- Review the error message in the PR checks.
349+
- Compare your changes with the [schema](./notification-schema.json) and your labels.
350+
351+
### 3.4. <a name='FolderStructure'></a>✅ **Folder Structure**
352+
353+
Notifications are organized under the `system-notifications/` directory:
276354

277355
```bash
278356
279-
auto-alerts/ # Alert ConfigMaps (one file = one alert)
357+
system-notifications/
280358
.
281-
├── alert-1.yaml # Fully valid ConfigMap YAML
282-
├── alert-2.yaml
283-
└── kustomization.yaml # Auto-generated, includes all alert YAMLs
359+
├── notification-1.yaml # A ConfigMap representing one notification
360+
├── notification-2.yaml
361+
└── kustomization.yaml # Auto-generated, includes all notifications YAMLs
284362
285363
```
364+
365+
When there are no active notifications, both the `system-notifications/` folder and its reference in the parent `kustomization.yaml` should be removed automatically to avoid kustomize errors.
366+
367+
### 3.5. <a name='UIBehavior-1'></a>✅ **UI Behavior**
368+
369+
- The UI discovers and filters notifications by detecting ConfigMaps labeled with
370+
`konflux.system.notification: "true".`
371+
- When a valid notification ConfigMap exists, its notification will be shown in the UI.
372+
- To remove a notification from the UI, the corresponding ConfigMap must be deleted or renamed so it no longer matches the label.
373+
- When multiple notifications exist, the UI lists them ordered by their creation time (`creationTimestamp`), <strong>showing the most recent first</strong>.
374+
- The `type` field control the notification icon shown before the title in the Notification Drawer.
375+
- If the `title` field is omitted in the JSON, it falls back to using component.metadata.name as the default in the UI.
376+
- We leveraged [PatternFly Notification Drawer (v5)](https://v5-archive.patternfly.org/components/notification-drawer/html/#ws-core-c-notification-drawer-basic) and [Notification Badge (v5)](https://v5-archive.patternfly.org/components/notification-badge) components to implement the UI, following their design principles for consistency and usability.
377+
- All notifications are always shown as unread. There is no backend tracking for notification state, so <strong>`read/unread` functionality is not supported</strong>.
378+
379+
### 3.6. <a name='WhentoAddorRemoveNotifications'></a>✅ **When to Add or Remove Notifications**
380+
381+
<strong>These notification ConfigMaps are automatically generated or removed</strong> by monitoring or scripting systems based on current system status.
382+
383+
- Add a notification:
384+
385+
1. Generate a new ConfigMap YAML file under `system-notifications/`.
386+
2. Refresh the `kustomization.yaml` in that folder to include the new file.
387+
3. If the folder does not exist (e.g., no prior notifications), create it and its `kustomization.yaml`, and ensure the parent kustomization includes it.
388+
389+
- Remove a notification:
390+
391+
1. Delete the corresponding ConfigMap YAML file from `system-notifications/`.
392+
2. Refresh `kustomization.yaml` to remove the reference.
393+
3. If no notifications remain, delete the `system-notifications/` directory and remove its reference from the parent kustomization.
394+
395+
⚠️ <strong>These add/remove operations are expected to be automated</strong>. Manual edits should only be done in emergencies or for debugging.

0 commit comments

Comments
 (0)