freemium-ui 2.0.132 → 2.0.134

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.
Files changed (39) hide show
  1. package/.github/actionlint.yaml +6 -0
  2. package/.github/pr_validation_guide.md +305 -0
  3. package/.github/pull_request_template.md +189 -0
  4. package/.github/workflows/pr-preview-cleanup.yml +67 -0
  5. package/.github/workflows/pr-preview-deploy.yml +300 -0
  6. package/.github/workflows/pr-quality.yml +114 -0
  7. package/.github/workflows/pr-template-validation.yml +367 -0
  8. package/.github/workflows/sonarqube-main.yml +106 -0
  9. package/.github/workflows/stale.yml +112 -0
  10. package/.nvmrc +1 -0
  11. package/README.md +9 -0
  12. package/catalog-info.yaml +33 -0
  13. package/docs/adrs/index.md +11 -0
  14. package/docs/architecture/code-structure.md +109 -0
  15. package/docs/architecture/deep-dive.md +193 -0
  16. package/docs/getting-started.md +103 -0
  17. package/docs/index.md +35 -0
  18. package/docs/operations/alerts-configuration.md +11 -0
  19. package/docs/operations/how-to-debug.md +43 -0
  20. package/docs/operations/monitoring.md +16 -0
  21. package/docs/operations/recent-issues.md +14 -0
  22. package/docs/operations/sop.md +25 -0
  23. package/docs/operations/support.md +15 -0
  24. package/lib/README.md +9 -0
  25. package/lib/index.cjs.js +5342 -5299
  26. package/lib/index.d.ts +7 -1
  27. package/lib/index.js +5231 -5187
  28. package/lib/package.json +1 -1
  29. package/mkdocs.yml +38 -0
  30. package/package.json +3 -1
  31. package/sonar-project.properties +25 -0
  32. package/tech-docs/docs/architecture/components.md +49 -0
  33. package/tech-docs/docs/architecture/index.md +54 -0
  34. package/tech-docs/docs/development/build-publish.md +42 -0
  35. package/tech-docs/docs/development/storybook.md +37 -0
  36. package/tech-docs/docs/getting-started.md +67 -0
  37. package/tech-docs/docs/index.md +47 -0
  38. package/tech-docs/docs/repositories/index.md +22 -0
  39. package/tech-docs/mkdocs.yml +28 -0
@@ -0,0 +1,6 @@
1
+ self-hosted-runner:
2
+ # fw-shared is the org's shared self-hosted runner label, used by every
3
+ # pull_request-triggered quality-gate job across the survey/freemium repos
4
+ # (e.g. survey-admin-microfrontend). Not an unknown/typo'd label.
5
+ labels:
6
+ - fw-shared
@@ -0,0 +1,305 @@
1
+ # PR Validation Guide
2
+
3
+ This document explains how PR validation works in the `freemium-ui` repository.
4
+
5
+ ## Overview
6
+
7
+ Validation happens in two layers:
8
+
9
+ ```text
10
+ ┌──────────────────────┬─────────────────────────────────────┬─────────────────────┐
11
+ │ Layer │ What It Validates │ When │
12
+ ├──────────────────────┼─────────────────────────────────────┼─────────────────────┤
13
+ │ Git Hooks (Local) │ Commit message format (fail-fast) │ On commit │
14
+ │ │ Lint, format, install, build │ On commit │
15
+ ├──────────────────────┼─────────────────────────────────────┼─────────────────────┤
16
+ │ GitHub Actions │ PR template completeness │ On PR open/edit │
17
+ │ │ Stale PR management │ Daily cron │
18
+ └──────────────────────┴─────────────────────────────────────┴─────────────────────┘
19
+ ```
20
+
21
+ ---
22
+
23
+ ## Local Validation — Git Hooks (Husky)
24
+
25
+ ### `.husky/pre-commit`
26
+
27
+ Runs every time you commit, **before** the commit message is checked. Executes the quality & build chain:
28
+
29
+ ```text
30
+ npm run lint → npm run format → npm install → npm run build
31
+ ```
32
+
33
+ Any failure aborts the commit with a non-zero exit code.
34
+
35
+ > The repo currently has no unit tests, so `npm run test` is intentionally **not** part of the pre-commit chain. Add it back once tests exist.
36
+
37
+ ### `.husky/commit-msg`
38
+
39
+ Runs after `pre-commit` passes. Validates only the commit message format — no lint/test/build work happens here.
40
+
41
+ Required format:
42
+
43
+ ```text
44
+ type: [TICKET-ID] message
45
+ ```
46
+
47
+ - **Valid types:** `feat`, `fix`, `chore`, `docs`, `refactor`, `test`, `perf`, `ci`, `build`, `style`, `revert`
48
+ - **Valid tickets:** `MP-xxxx`, `FS-xxxx`, `FSURVEY-xxxx`, `DEVREL-xxxx`, `PLAT-xxxx`, `MISC`, `Docs`
49
+
50
+ Examples:
51
+
52
+ ```text
53
+ ✅ feat: [FSURVEY-2024] Add new Dropdown variant
54
+ ✅ fix: [MP-12345] Fix Tooltip positioning
55
+ ✅ chore: [MISC] Bump rollup version
56
+ ✅ docs: [Docs] Update Storybook README
57
+ ❌ Add dropdown component (no type, no ticket)
58
+ ❌ feat: Add dropdown component (no ticket)
59
+ ❌ Feat: [MP-123] Add dropdown (type must be lowercase)
60
+ ```
61
+
62
+ **Skipped automatically for:**
63
+
64
+ - Merge commits (`Merge branch ...`, `Merge pull request ...`)
65
+ - Revert commits (`Revert ...`)
66
+ - Dependabot-style commits (`Bump X from Y to Z`)
67
+
68
+ ### Bypass (Emergency Only)
69
+
70
+ ```bash
71
+ git commit --no-verify -m "..."
72
+ ```
73
+
74
+ Skips all local hooks. Server-side PR validation will still enforce the title format on PR open.
75
+
76
+ ---
77
+
78
+ ## GitHub Actions Workflows
79
+
80
+ ### 1. PR Template Validation
81
+
82
+ **File:** `.github/workflows/pr-template-validation.yml`
83
+
84
+ **Triggers:** PR `opened`, `edited`, `synchronize`
85
+
86
+ **Purpose:** Ensures the PR title and description follow the template contract. Posts a sticky validation comment and fails the check (blocks merge via branch protection) when required sections are missing.
87
+
88
+ **Automated PRs are skipped** (Dependabot, Renovate, github-actions[bot], mergify[bot], snyk-bot, and any author ending in `[bot]`).
89
+
90
+ #### 🔴 REQUIRED — Blocks merge if missing
91
+
92
+ | # | Check | Rule |
93
+ | --- | ---------------------------- | ------------------------------------------------------------------------------ |
94
+ | 1 | PR Title | Must match `type: [TICKET-ID] description` with valid type and ticket |
95
+ | 2 | Type of Change | At least one `- [x]` checked |
96
+ | 3 | Ticket Reference | PR body must contain `- **Ticket ID**: [FSURVEY-xxxx]` (or other valid prefix) |
97
+ | 4 | Changes Made | At least **3** real bullet points (placeholders like `Change 1:` don't count) |
98
+ | 5 | Affected Areas | At least one `- [x]` checked |
99
+ | 6 | Breaking Changes | Exactly one of "Yes" / "No" checked |
100
+ | 7 | Breaking Changes Description | If "Yes" selected, description must be > 50 characters |
101
+
102
+ #### 🟡 RECOMMENDED — Warning only, does not block
103
+
104
+ | # | Check | Rule |
105
+ | --- | ------------------ | -------------------------------------------------------------------------------------------------------- |
106
+ | 1 | Testing | Numbered test steps with real content (not just `1. Step 1`) |
107
+ | 2 | SDET Guidance | > 30 chars of real content (placeholders stripped) |
108
+ | 3 | Screenshots/Videos | If `.tsx` files under `src/components/` or `src/stories/` changed and no image/video URL in Screenshots |
109
+
110
+ ### 2. Stale PR Management
111
+
112
+ **File:** `.github/workflows/stale.yml`
113
+
114
+ **Triggers:** Daily cron (`0 0 * * *`) and manual dispatch.
115
+
116
+ **Purpose:** Closes/labels stale PRs and issues to keep the backlog tidy.
117
+
118
+ ---
119
+
120
+ ## Validation Flow
121
+
122
+ When you run `git commit`:
123
+
124
+ ```text
125
+ .husky/pre-commit
126
+ └─ npm run lint → npm run format → npm install → npm run build
127
+ .husky/commit-msg
128
+ └─ validate message format (fails fast if malformed)
129
+ ```
130
+
131
+ When you open a PR:
132
+
133
+ ```text
134
+ GitHub Actions:
135
+ └─ PR Template Validation (sticky comment, can block merge)
136
+
137
+ Manual:
138
+ └─ Code review approval
139
+ ```
140
+
141
+ ---
142
+
143
+ ## What Gets Checked Where
144
+
145
+ | Check | Local (Husky) | GitHub Actions |
146
+ | -------------------------- | :---------------: | :------------: |
147
+ | Commit message format | ✅ (`commit-msg`) | |
148
+ | Lint | ✅ (`pre-commit`) | |
149
+ | Format | ✅ (`pre-commit`) | |
150
+ | Unit tests | ⏸️ (none yet) | |
151
+ | Install | ✅ (`pre-commit`) | |
152
+ | Build (rollup) | ✅ (`pre-commit`) | |
153
+ | PR title format | | ✅ |
154
+ | Type of Change selected | | ✅ |
155
+ | Ticket ID in body | | ✅ |
156
+ | Changes Made (min 3) | | ✅ |
157
+ | Affected Areas selected | | ✅ |
158
+ | Breaking Changes selection | | ✅ |
159
+ | Breaking description (>50) | | ✅ |
160
+ | Testing info | | ⚠️ (warn) |
161
+ | SDET guidance | | ⚠️ (warn) |
162
+ | Screenshots for UI changes | | ⚠️ (warn) |
163
+
164
+ ---
165
+
166
+ ## How to Fix Validation Failures
167
+
168
+ ### Local: "Invalid commit message format!"
169
+
170
+ The `commit-msg` hook rejected your message (this runs after `pre-commit`). Re-run with the correct shape:
171
+
172
+ ```bash
173
+ git commit -m "feat: [FSURVEY-8530] Add new Dropdown variant"
174
+ ```
175
+
176
+ Since the message is preserved in `.git/COMMIT_EDITMSG`, re-running `git commit` (no `-m`) will reopen your editor with the previous content.
177
+
178
+ ### Local: Lint/format/install/build failed
179
+
180
+ The `pre-commit` hook ran the quality chain and one step failed. Run the failing step directly to debug:
181
+
182
+ ```bash
183
+ npm run lint
184
+ npm run format
185
+ npm install
186
+ npm run build
187
+ ```
188
+
189
+ ### PR Template Validation Failed (GitHub Actions)
190
+
191
+ 1. Open the PR on GitHub → click **Edit** on the description
192
+ 2. Read the sticky "🔍 PR Template Validation Report" comment — it lists every failing check
193
+ 3. Fix the sections it flags. Common issues:
194
+ - **Ticket Reference missing:** Your body still has the placeholder `[FSURVEY-xxxx / PLAT-xxxx / MISC / Docs]`. Replace with the exact form: `- **Ticket ID**: [FSURVEY-8530]`
195
+ - **Changes Made insufficient:** Need at least 3 real bullets under `## Changes Made` — placeholders like `Change 1:` don't count
196
+ - **Breaking Changes:** Must check exactly one of Yes/No; both unchecked or both checked fails
197
+ 4. Save the PR description — the workflow re-runs automatically on the `edited` event
198
+
199
+ ### Common Gotchas
200
+
201
+ | Symptom | Cause |
202
+ | ------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------- |
203
+ | Validation fails with valid-looking title | PR title is lowercase `feat:` (correct) but ticket bracket has extra text like `[FSURVEY-8530 test]` |
204
+ | "Ticket Reference missing" despite filling it in | The placeholder text `[FSURVEY-xxxx / PLAT-xxxx / MISC / Docs]` was not replaced with a real ticket like `[FSURVEY-8530]` |
205
+ | Screenshot warning on non-visual PR | Path-based detection — any `.tsx` under `src/components/` or `src/stories/` triggers it even for pure logic changes |
206
+
207
+ ---
208
+
209
+ ## Best Practices
210
+
211
+ ### Before Committing
212
+
213
+ Since the `pre-commit` hook runs lint/format/install/build, ensure they pass cleanly:
214
+
215
+ ```bash
216
+ npm run lint
217
+ npm run format
218
+ npm install
219
+ npm run build
220
+ ```
221
+
222
+ ### Writing a Good PR
223
+
224
+ 1. **Keep it focused** — small, single-purpose PRs review faster
225
+ 2. **Fill the template honestly** — at least 3 meaningful bullets under Changes Made
226
+ 3. **Describe "why", not just "what"** — the Motivation section is free-form for a reason
227
+ 4. **Add screenshots/videos / Storybook links** for any UI/component change (recommended, not enforced)
228
+ 5. **Fill SDET guidance** when the change has non-obvious edge cases
229
+
230
+ ### PR Description Checklist
231
+
232
+ Before you submit:
233
+
234
+ - ✅ Type of Change has at least one `[x]`
235
+ - ✅ Ticket ID line shows `- **Ticket ID**: [FSURVEY-0000]` with the real number
236
+ - ✅ Changes Made has 3+ real bullets
237
+ - ✅ Affected Areas has at least one `[x]`
238
+ - ✅ Breaking Changes has exactly one `[x]` (Yes or No)
239
+ - ✅ If breaking Yes: description > 50 chars
240
+ - ✅ Screenshots / Storybook link added for UI changes (recommended)
241
+ - ✅ Testing & SDET Guidance filled (recommended)
242
+
243
+ ---
244
+
245
+ ## Troubleshooting
246
+
247
+ ### GitHub Actions doesn't run on my PR
248
+
249
+ 1. Check the **Actions** tab of the repo for errors
250
+ 2. Verify the workflow file is on the PR's base branch (not only the feature branch)
251
+ 3. Confirm the PR author isn't auto-classified as a bot (skip logic inspects `user.type` and login suffix `[bot]`)
252
+ 4. The workflow uses `secrets.RUNWAYCI_GITHUB_PAT_TOKEN` — if it's missing or expired, the validation step fails before running any check
253
+
254
+ ### Validation seems wrong
255
+
256
+ 1. Copy your exact PR description and inspect it against the regexes in `.github/workflows/pr-template-validation.yml`
257
+ 2. Remember: checkboxes must use `- [x]` (lowercase `x`), though the code is actually case-insensitive (`[X]` also works)
258
+ 3. Bold must be `**Ticket ID**:` exactly — no underscores, no extra spaces inside the `**`
259
+
260
+ ### Need to bypass validation
261
+
262
+ - **Local hook:** `git commit --no-verify` (skips both `pre-commit` and `commit-msg`)
263
+ - **PR template validation:** Cannot be bypassed without repo admin disabling the required status check — this is intentional
264
+
265
+ ---
266
+
267
+ ## Configuration
268
+
269
+ To change validation rules:
270
+
271
+ | File | What to change |
272
+ | ---------------------------------------------- | -------------------------------------------------------------------------------- |
273
+ | `.github/workflows/pr-template-validation.yml` | Server-side template validation logic (regexes, thresholds, required vs warning) |
274
+ | `.github/pull_request_template.md` | The template users see when opening a PR |
275
+ | `.husky/commit-msg` | Local commit message format validation |
276
+ | `.husky/pre-commit` | Local lint / format / test / install / build chain |
277
+
278
+ ### Ticket Prefix Changes
279
+
280
+ Valid ticket prefixes are defined in **two** places and must stay in sync:
281
+
282
+ - `.husky/commit-msg` — regex `ticket_pattern` around line 30
283
+ - `.github/workflows/pr-template-validation.yml` — `titleRegex` (line ~100) and `ticketRegex` (line ~137)
284
+
285
+ ---
286
+
287
+ ## Summary
288
+
289
+ This system enforces:
290
+
291
+ - ✅ Consistent commit messages (local, fail-fast)
292
+ - ✅ Compilable, linted, formatted, tested code (local, before commit)
293
+ - ✅ Complete PR descriptions with traceability to a ticket (GitHub Actions)
294
+
295
+ All automated — fill the PR template properly and use the commit format, and the checks will pass.
296
+
297
+ ---
298
+
299
+ ## Related Files
300
+
301
+ - [Pull Request Template](./pull_request_template.md)
302
+ - [PR Template Validation Workflow](./workflows/pr-template-validation.yml)
303
+ - [Stale PR Workflow](./workflows/stale.yml)
304
+ - [Husky commit-msg Hook](../.husky/commit-msg)
305
+ - [Husky pre-commit Hook](../.husky/pre-commit)
@@ -0,0 +1,189 @@
1
+ <!---
2
+ 📋 PR Template Guidelines:
3
+ - PR TITLE must follow format: type: [TICKET-ID] description
4
+ Example: feat: [MP-12345] Add new Dropdown variant · feat: [FS-12345] for FS tickets
5
+ - Sections marked with ⚠️ REQUIRED will be validated by GitHub Actions
6
+ - Sections marked with ⚠️ RECOMMENDED should be filled for better reviews
7
+ - Incomplete required sections will block PR merge
8
+ - See .github/workflows/pr-template-validation.yml for validation rules
9
+ -->
10
+
11
+ ## Type of Change ⚠️ REQUIRED
12
+
13
+ <!--- REQUIRED: Put an `x` in at least ONE box that applies -->
14
+ <!--- This should match your commit message type (feat/fix/chore/docs/etc.) -->
15
+
16
+ - [ ] Feature (new functionality)
17
+ - [ ] Bugfix (fixes an issue)
18
+ - [ ] Refactor (code improvement without changing functionality)
19
+ - [ ] Maintenance (dependency updates, chores)
20
+ - [ ] Performance (optimization)
21
+ - [ ] Documentation (content or code documentation updates)
22
+ - [ ] Security (security fixes or improvements)
23
+ - [ ] Configuration (build, CI/CD, or tooling changes)
24
+
25
+ ## Ticket Reference ⚠️ REQUIRED
26
+
27
+ <!--- REQUIRED: Link to the related ticket or story -->
28
+
29
+ - **Ticket ID**: [FSURVEY-xxxx / PLAT-xxxx / MISC / Docs]
30
+ - **Ticket Link**: [Link to Freshrelease story or issue]
31
+
32
+ ## Motivation
33
+
34
+ <!--- Why is this change required? What problem does it solve? -->
35
+ <!--- If it fixes an open issue, please link to the freshrelease story here or ensure the id is in the PR title. -->
36
+ <!--- Please ensure that you have run all lints related to this repo and also ensure that your PR is small enough for quick review. -->
37
+
38
+ ## Changes Made ⚠️ REQUIRED
39
+
40
+ <!--- REQUIRED: Provide a clear description of what you changed -->
41
+ <!--- REQUIRED: List at least 3 main changes in bullet points -->
42
+
43
+ - Change 1:
44
+ - Change 2:
45
+ - Change 3:
46
+
47
+ ## Affected Areas ⚠️ REQUIRED
48
+
49
+ <!--- REQUIRED: Put an `x` in at least ONE box that applies -->
50
+
51
+ - [ ] Source (`src`)
52
+ - [ ] Build / Bundling (`rollup.config.ts`, `scripts/`, `tsconfig.json`)
53
+ - [ ] CI/CD workflows (`.github/workflows`)
54
+ - [ ] Dependencies (`package.json`)
55
+
56
+ ## Breaking Changes ⚠️ REQUIRED
57
+
58
+ <!--- REQUIRED: Select one option -->
59
+
60
+ - [ ] Yes, this PR introduces breaking changes
61
+ - [ ] No breaking changes
62
+
63
+ <!--- REQUIRED if Yes: Describe the breaking changes (API changes, removed props, renamed components, version-bump impact) and migration steps below -->
64
+
65
+ ## Checklist
66
+
67
+ <!--- Go over all the following points, and put an `x` in all the boxes that apply. -->
68
+ <!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->
69
+
70
+ ### Code Quality
71
+
72
+ - [ ] My code follows the code style of this project
73
+ - [ ] I have run `npm run lint` and fixed all errors
74
+ - [ ] I have run `npm run format` to format the code
75
+ - [ ] No console.log or debugging code left in the changes
76
+ - Format: `type: [TICKET-ID] message`
77
+ - Valid types: feat, fix, chore, docs, refactor, test, perf, ci, build, style, revert
78
+ - Valid tickets: FSURVEY-xxxx / PLAT-xxxx / MISC / Docs
79
+
80
+ ### Testing
81
+
82
+ - [ ] I have added tests to cover my changes
83
+ - [ ] I have verified the component visually in Storybook (`npm run storybook`)
84
+ - [ ] I have tested on multiple browsers (if UI changes)
85
+ - [ ] All new and existing tests passed (`npm run test`)
86
+ - [ ] I have tested the production bundle (`npm run build`)
87
+
88
+ ### Documentation
89
+
90
+ - [ ] My change requires a change to the documentation
91
+ - [ ] I have updated the documentation / Storybook stories accordingly
92
+ - [ ] I have updated code comments where necessary
93
+ - [ ] I have added JSDoc comments for new functions/components
94
+
95
+ ### Accessibility & Security
96
+
97
+ - [ ] I have tested keyboard navigation (if UI changes)
98
+ - [ ] I have verified ARIA labels and semantic HTML (if UI changes)
99
+ - [ ] I have validated component props (required vs optional, defaults)
100
+ - [ ] I have checked for security vulnerabilities (`npm audit`)
101
+
102
+ ### Dependencies
103
+
104
+ - [ ] I have added new dependencies (list them below)
105
+ - [ ] I have updated existing dependencies (list them below)
106
+ - [ ] I have verified dependency compatibility with existing peer dependencies
107
+ - [ ] I have checked for security vulnerabilities in new dependencies
108
+
109
+ <!--- List new or updated dependencies here -->
110
+
111
+ **New/Updated Dependencies:**
112
+
113
+ -
114
+ -
115
+
116
+ ## How Has This Been Tested? ⚠️ RECOMMENDED
117
+
118
+ <!--- RECOMMENDED: Describe in detail how you tested your changes -->
119
+ <!--- Include details of your testing environment and test steps -->
120
+
121
+ **Testing Environment:**
122
+
123
+ - Node version:
124
+ - npm version:
125
+ - Browser(s) tested:
126
+
127
+ **Test Steps:**
128
+
129
+ 1. Step 1
130
+ 2. Step 2
131
+ 3. Step 3
132
+
133
+ **Test Results:**
134
+
135
+ - Result 1
136
+
137
+ ## Screenshots/Videos ⚠️ REQUIRED FOR UI CHANGES
138
+
139
+ <!--- REQUIRED for UI changes: Add screenshots, videos, or a Storybook link to demonstrate the changes -->
140
+ <!--- REQUIRED: Include before/after screenshots for visual changes -->
141
+
142
+ **Before:**
143
+
144
+ **After:**
145
+
146
+ ## Performance Impact
147
+
148
+ <!--- Describe any performance implications of this change -->
149
+
150
+ - [ ] No performance impact
151
+ - [ ] Performance improvement (describe below)
152
+ - [ ] Potential performance impact (describe below)
153
+
154
+ <!--- If applicable, include bundle size changes, build time changes, etc. -->
155
+
156
+ ## Deployment / Release Notes
157
+
158
+ <!--- Any special publish considerations? -->
159
+ <!--- Version bump type (patch/minor/major), consumer migration, peer-dep updates, etc. -->
160
+
161
+ - [ ] No special release steps required
162
+ - [ ] Requires a specific version bump (patch / minor / major — describe below)
163
+ - [ ] Requires consumer migration (describe below)
164
+
165
+ ## What should the SDET know? ⚠️ RECOMMENDED
166
+
167
+ <!--- RECOMMENDED: Provide testing guidance for QA team -->
168
+ <!--- Include test scenarios, edge cases, and areas to focus on -->
169
+
170
+ - Test scenario 1:
171
+ - Edge case to check:
172
+ - Focus area:
173
+
174
+ ## Additional Context
175
+
176
+ <!--- Add any other context, links, or information that reviewers should know -->
177
+ <!--- Related PRs, design documents, API documentation, etc. -->
178
+
179
+ ## Reviewer Checklist
180
+
181
+ <!--- For reviewers - ensure these are verified -->
182
+
183
+ - [ ] Code changes align with the motivation and description
184
+ - [ ] No unnecessary files or changes included
185
+ - [ ] Code follows project conventions and style guide
186
+ - [ ] Tests / stories are adequate and passing
187
+ - [ ] Documentation is updated if needed
188
+ - [ ] No security vulnerabilities introduced
189
+ - [ ] Performance / bundle-size impact is acceptable
@@ -0,0 +1,67 @@
1
+ # Removes preview assets from S3 and invalidates CloudFront when a PR targeting
2
+ # main is closed (merged or abandoned), keeping the bucket clean.
3
+
4
+ name: Preview Cleanup
5
+
6
+ on:
7
+ pull_request:
8
+ types: [closed]
9
+ branches: [main]
10
+
11
+ permissions:
12
+ contents: read
13
+
14
+ # Prevent concurrent cleanup runs for the same PR.
15
+ concurrency:
16
+ group: preview-${{ github.event.pull_request.number }}
17
+ cancel-in-progress: false
18
+
19
+ jobs:
20
+ cleanup:
21
+ runs-on: fw-shared
22
+ timeout-minutes: 10
23
+ # Skip cleanup for forked PRs — secrets are not available for forks so
24
+ # AWS calls would fail. Forks never get a preview deployed either.
25
+ if: github.event.pull_request.head.repo.fork == false
26
+ steps:
27
+ # Assumes the IAM role using the runner's base credentials (instance profile)
28
+ # and exports temporary credentials to GITHUB_ENV for subsequent AWS steps.
29
+ - name: Configure AWS credentials
30
+ run: |
31
+ SESSION=$(aws sts assume-role \
32
+ --role-arn "${{ secrets.AWS_IAM_ROLE }}" \
33
+ --role-session-name "GitHubActionsCleanupSession")
34
+
35
+ echo "AWS_ACCESS_KEY_ID=$(echo "$SESSION" | jq -r '.Credentials.AccessKeyId')" >> $GITHUB_ENV
36
+ echo "AWS_SECRET_ACCESS_KEY=$(echo "$SESSION" | jq -r '.Credentials.SecretAccessKey')" >> $GITHUB_ENV
37
+ echo "AWS_SESSION_TOKEN=$(echo "$SESSION" | jq -r '.Credentials.SessionToken')" >> $GITHUB_ENV
38
+ echo "AWS_DEFAULT_REGION=${{ vars.AWS_REGION || 'us-east-1' }}" >> $GITHUB_ENV
39
+
40
+ # Recursively deletes all objects under previews/{PR_NUM}/ in the S3 bucket
41
+ # so stale preview files don't accumulate after the PR is closed.
42
+ - name: Delete preview prefix from S3
43
+ env:
44
+ BUCKET: ${{ secrets.PREVIEW_S3_BUCKET }}
45
+ PR_NUM: ${{ github.event.pull_request.number }}
46
+ run: |
47
+ if [ -z "$BUCKET" ]; then
48
+ echo "Set repository secret PREVIEW_S3_BUCKET."
49
+ exit 1
50
+ fi
51
+ aws s3 rm "s3://${BUCKET}/previews/${PR_NUM}/" --recursive
52
+
53
+ # Invalidates the CloudFront cache for the deleted preview path so the
54
+ # files are no longer served. Skipped if CLOUDFRONT_DISTRIBUTION_ID is
55
+ # not configured.
56
+ - name: Invalidate CloudFront
57
+ env:
58
+ DIST_ID: ${{ secrets.CLOUDFRONT_DISTRIBUTION_ID }}
59
+ PR_NUM: ${{ github.event.pull_request.number }}
60
+ run: |
61
+ if [ -z "$DIST_ID" ]; then
62
+ echo "Skipping CloudFront invalidation (CLOUDFRONT_DISTRIBUTION_ID not set)."
63
+ exit 0
64
+ fi
65
+ aws cloudfront create-invalidation \
66
+ --distribution-id "$DIST_ID" \
67
+ --paths "/previews/${PR_NUM}/*"