Skip to content

Commit ffbfbd5

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

File tree

34 files changed

+300
-224
lines changed

34 files changed

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

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

531
The `KONFLUX-INFO` directory contains:
632

733
```bash
834
.
9-
├── auto-alert-schema.json # JSON shema definition for auto-alert-content.yaml
1035
├── base/ # Common resources (e.g., RBAC)
1136
├── production/ # Production cluster configurations
1237
├── staging/ # Staging cluster configurations
1338
├── banner-schema.json # JSON schema definition for validating banner-content.yaml files
14-
39+
├── notification-schema.json # JSON schema definition for validating notification-content.json
1540
```
1641

1742
Each cluster directory contains:
1843

1944
```bash
2045
.
21-
├── auto-alerts # The directory manages auto-generated alerts content shown in the UI
46+
├── system-notifications # The directory manages auto-generated notifications content shown in the UI
2247
├── banner-content.yaml # The banner content shown in the UI
2348
├── info.json # Metadata about the cluster
24-
└── kustomization.yaml # Kustomize configuration for this cluster, including base, auto-alerts, and other configs
49+
└── kustomization.yaml # Kustomize configuration for this cluster, including base, system-notifications, and other configs
2550

2651
```
2752

2853
---
2954

30-
## ✅ Banner Content Validation
55+
## 2. <a name='KonfluxBanner'></a>📢 Konflux Banner
56+
57+
### 2.1. <a name='BannerContentValidation'></a>✅ Banner Content Validation
3158

3259
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).
3360

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

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

5279
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`).
5380

54-
### **Schema**
81+
#### 2.2.1. <a name='Schema'></a>**Schema**
5582

5683
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.
5784

5885
The file must contain a **YAML list** where each item represents a banner configuration.
5986

6087
---
6188

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**
89+
#### 2.2.2. <a name='RequiredandOptionalFieldsforEachBanner'></a>**Required and Optional Fields for Each Banner**
7090

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

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

87107
---
88108

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

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

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

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

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

115135
For a single event on a specific date:
116136

@@ -133,7 +153,7 @@ For a single event in today
133153
endTime: "14:00"
134154
```
135155
136-
#### ✅ **2. Weekly Recurring Banner**
156+
#### 2.3.3. <a name='3.WeeklyRecurringBanner'></a>✅ **3. Weekly Recurring Banner**
137157
138158
For an event that repeats every week:
139159
@@ -145,7 +165,7 @@ For an event that repeats every week:
145165
endTime: "04:00"
146166
```
147167
148-
#### ✅ **3. Monthly Recurring Banner**
168+
#### 2.3.4. <a name='4.MonthlyRecurringBanner'></a>✅ **4. Monthly Recurring Banner**
149169
150170
For an event that happens on the same day each month:
151171
@@ -158,7 +178,7 @@ For an event that happens on the same day each month:
158178
timeZone: "Asia/Shanghai"
159179
```
160180
161-
#### ✅ **4. Always-On Banner**
181+
#### 2.3.5. <a name='5.Always-OnBanner'></a>✅ **5. Always-On Banner**
162182
163183
For an event that requires immediate notification:
164184
@@ -167,7 +187,7 @@ For an event that requires immediate notification:
167187
type: "info"
168188
```
169189
170-
#### ✅ **5. Empty Banner**
190+
#### 2.3.6. <a name='6.EmptyBanner'></a>✅ **6. Empty Banner**
171191
172192
When there are no events to announce:
173193
@@ -177,7 +197,7 @@ When there are no events to announce:
177197

178198
---
179199

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

182202
1. Locate the target cluster directory:
183203

@@ -225,7 +245,18 @@ When there are no events to announce:
225245
Purpose: Release announcement for Konflux 1.2
226246
```
227247
228-
## ❓ Frequently Asked Questions
248+
### 2.5. <a name='UIBehavior'></a>✅ UI Behavior
249+
250+
- 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.
251+
- If multiple banners are configured, <strong style="color: red;">order matters</strong>.
252+
- <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.
253+
254+
<strong>To convey duration or timing details, please include them within the `summary`.</strong>
255+
256+
- <strong style="color: red;">The `type` and `summary` fields are displayed directly in the UI</strong>.
257+
- 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.
258+
259+
### 2.6. <a name='FrequentlyAskedQuestions'></a>❓ Frequently Asked Questions
229260

230261
- Why is only one banner shown even when multiple are configured?
231262

@@ -245,41 +276,125 @@ When there are no events to announce:
245276

246277
<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>
247278

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

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

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.
306+
We recommend using <strong>a single JSON object representing one notification</strong> in `notification-content.json`.
253307

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

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

258312
```yaml
259313
apiVersion: v1
260314
kind: ConfigMap
261315
metadata:
262-
name: konflux-auto-alert-xyz
316+
name: konflux-system-notification-xyz
263317
namespace: konflux-info
264318
labels:
265-
konflux-auto-alert: "true" # Required. UI filter alerts out by this label.
319+
konflux.system.notification: "true"
266320
data:
267-
auto-alert-content.yaml: |
268-
enable: true
269-
summary: "Builds are delayed due to maintenance"
270-
type: "warning"
321+
notification-content.json: |-
322+
{
323+
"summary": "Builds are delayed due to maintenance",
324+
"type": "warning",
325+
"title": "From Builds Service",
326+
"activeTimestamp": "2025-08-12T14:30:00Z"
327+
}
271328
```
272329

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

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

277357
```bash
278358
279-
auto-alerts/ # Alert ConfigMaps (one file = one alert)
359+
system-notifications/
280360
.
281-
├── alert-1.yaml # Fully valid ConfigMap YAML
282-
├── alert-2.yaml
283-
└── kustomization.yaml # Auto-generated, includes all alert YAMLs
361+
├── notification-1.yaml # A ConfigMap representing one notification
362+
├── notification-2.yaml
363+
└── kustomization.yaml # Auto-generated, includes all notifications YAMLs
284364
285365
```
366+
367+
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.
368+
369+
### 3.5. <a name='UIBehavior-1'></a>✅ **UI Behavior**
370+
371+
- The UI discovers and filters notifications by detecting ConfigMaps labeled with
372+
`konflux.system.notification: "true".`
373+
- When a valid notification ConfigMap exists, its notification will be shown in the UI only if the active time has been reached.
374+
- The UI respects the `activeTimestamp` field to control when notifications are displayed:
375+
- If `activeTimestamp` is set to a future time, the notification remains hidden until that time arrives.
376+
- If `activeTimestamp` is not set, the notification uses the resource's `creationTimestamp` to determine when to show.
377+
- To remove a notification from the UI, the corresponding ConfigMap must be deleted or renamed so it no longer matches the label.
378+
- When multiple notifications exist, the UI lists them ordered by their active time, <strong>showing the most recent first</strong>.
379+
- The `type` field control the notification icon shown before the title in the Notification Drawer.
380+
- If the `title` field is omitted in the JSON, it falls back to using component.metadata.name as the default in the UI.
381+
- 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.
382+
- All notifications are always shown as unread. There is no backend tracking for notification state, so <strong>`read/unread` functionality is not supported</strong>.
383+
384+
### 3.6. <a name='WhentoAddorRemoveNotifications'></a>✅ **When to Add or Remove Notifications**
385+
386+
<strong>These notification ConfigMaps are automatically generated or removed</strong> by monitoring or scripting systems based on current system status.
387+
388+
- Add a notification:
389+
390+
1. Generate a new ConfigMap YAML file under `system-notifications/`.
391+
2. Refresh the `kustomization.yaml` in that folder to include the new file.
392+
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.
393+
394+
- Remove a notification:
395+
396+
1. Delete the corresponding ConfigMap YAML file from `system-notifications/`.
397+
2. Refresh `kustomization.yaml` to remove the reference.
398+
3. If no notifications remain, delete the `system-notifications/` directory and remove its reference from the parent kustomization.
399+
400+
⚠️ <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)