Skip to content

Commit 669147f

Browse files
authored
chore: add CHANGELOG.md, PR changelog check, and release workflow (#581)
Introduce a CHANGELOG.md reconstructed from the project's tagged GitHub Releases, add the shared changelog-check workflow that fails a PR when CHANGELOG.md is not updated unless the description states "No customer facing changes", and add a Prepare Release workflow that stamps the Unreleased section into a versioned entry (keeping the Unreleased header) and bumps package.json, mirroring the other SDKs. Also documents the opt-out in the PR template.
1 parent b58b8b9 commit 669147f

4 files changed

Lines changed: 346 additions & 0 deletions

File tree

.github/pull_request_template.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
## 🧪 How to test?
1010
> How to test the changes added?
1111
12+
## 🧾 Changelog
13+
> Add an entry to `CHANGELOG.md`. If this PR has no customer facing changes, write "No customer facing changes" here to skip the changelog check.
14+
1215
## 📹 Loom recording if applicable
1316
> If it helps the reviewer, add a short Loom going over the changes or showcasing the change in behavior.
1417
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
name: Changelog Check
2+
on:
3+
pull_request:
4+
types: [opened, edited, synchronize, reopened]
5+
6+
permissions:
7+
contents: read
8+
pull-requests: read
9+
10+
jobs:
11+
changelog:
12+
name: Verify CHANGELOG update
13+
runs-on: ubuntu-latest
14+
steps:
15+
- name: Check CHANGELOG.md update or opt-out
16+
uses: actions/github-script@v7
17+
with:
18+
script: |
19+
const optOut = 'No customer facing changes';
20+
const body = context.payload.pull_request.body || '';
21+
22+
if (body.toLowerCase().includes(optOut.toLowerCase())) {
23+
core.info(`PR description contains "${optOut}", skipping CHANGELOG.md check.`);
24+
return;
25+
}
26+
27+
const files = await github.paginate(github.rest.pulls.listFiles, {
28+
owner: context.repo.owner,
29+
repo: context.repo.repo,
30+
pull_number: context.payload.pull_request.number,
31+
per_page: 100,
32+
});
33+
34+
const changed = files.some((f) => f.filename === 'CHANGELOG.md');
35+
if (changed) {
36+
core.info('CHANGELOG.md was updated.');
37+
return;
38+
}
39+
40+
core.setFailed(
41+
'CHANGELOG.md was not updated. Add a CHANGELOG.md entry, or if this PR has no customer facing changes, add "No customer facing changes" to the PR description to justify skipping the changelog.'
42+
);
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
name: Prepare Release
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
version:
7+
description: 'Version number (e.g., 2.3.0 or 2.3.0-beta1)'
8+
required: true
9+
type: string
10+
11+
permissions:
12+
contents: write
13+
pull-requests: write
14+
15+
jobs:
16+
prepare-release:
17+
runs-on: ubuntu-latest
18+
steps:
19+
- uses: actions/checkout@v4
20+
with:
21+
token: ${{ secrets.GITHUB_TOKEN }}
22+
23+
- name: Update Changelog
24+
id: update_changelog
25+
run: |
26+
changelog_file="CHANGELOG.md"
27+
28+
# Function to extract content between two patterns, including the first pattern
29+
extract_between() {
30+
awk "/^## \[$1\]/{p=1;print;next} /^## \[/{p=0} p" "$3"
31+
}
32+
33+
# Get the unreleased content
34+
unreleased_content=$(extract_between "Unreleased" "[0-9]" "$changelog_file")
35+
36+
if [ -z "$unreleased_content" ]; then
37+
echo "No unreleased changes found in $changelog_file"
38+
exit 1
39+
fi
40+
41+
# Get the current version
42+
current_version=$(grep -oP "^## \[\K[0-9]+\.[0-9]+\.[0-9]+(?:-[a-zA-Z0-9]+)?(?=\])" "$changelog_file" | head -n1)
43+
new_version="${{ github.event.inputs.version }}"
44+
45+
# Validate version format (includes beta versions)
46+
if ! [[ $new_version =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9]+)?$ ]]; then
47+
echo "Invalid version format. Please use semantic versioning (e.g., 2.3.0 or 2.3.0-beta1)"
48+
exit 1
49+
fi
50+
51+
echo "new_version=${new_version}" >> $GITHUB_OUTPUT
52+
53+
# Create temporary file
54+
temp_file=$(mktemp)
55+
56+
# Preserve header and write new content
57+
{
58+
# Preserve the header (first 4 lines)
59+
head -n 4 "$changelog_file"
60+
echo "## [Unreleased]"
61+
echo ""
62+
echo "## [$new_version]"
63+
# Drop the leading "## [Unreleased]" header from the extracted content
64+
echo "$unreleased_content" | tail -n +2
65+
echo ""
66+
# Get the rest of the file starting from the first version entry
67+
sed -n '/^## \[[0-9]/,$p' "$changelog_file"
68+
} > "$temp_file"
69+
70+
# Replace original file
71+
mv "$temp_file" "$changelog_file"
72+
73+
- name: Update Version
74+
run: npm --no-git-tag-version --allow-same-version version "${{ github.event.inputs.version }}"
75+
76+
- name: Create Pull Request
77+
uses: peter-evans/create-pull-request@4e1beaa7521e8b457b572c090b25bd3db56bf1c5 # v5
78+
with:
79+
token: ${{ secrets.GITHUB_TOKEN }}
80+
title: "Prepare for Release ${{ steps.update_changelog.outputs.new_version }}"
81+
body: |
82+
# Prepare for Release ${{ steps.update_changelog.outputs.new_version }}
83+
84+
## SDK Release Checklist
85+
- [ ] CHANGELOG.md updated (Unreleased section moved under the new version)
86+
- [ ] Version bumped in package.json
87+
- [ ] README.md reviewed (if needed)
88+
- [ ] All tests passing
89+
- [ ] Documentation updated (if needed)
90+
91+
branch: "prepare-for-release-${{ steps.update_changelog.outputs.new_version }}"
92+
commit-message: "Prepare for release ${{ steps.update_changelog.outputs.new_version }}"
93+
labels: release
94+
delete-branch: true

CHANGELOG.md

Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
# Change Log
2+
3+
All notable changes to this project will be documented in this file.
4+
This project adheres to [Semantic Versioning](https://semver.org/).
5+
6+
## [Unreleased]
7+
8+
## [2.2.2]
9+
### Fixes
10+
- Added the user email to the in-app events payload, with corresponding tests (SDK-364).
11+
- Pinned `axios` to v1.14.0 and bumped the package version (SDK-405).
12+
- Updated the publish workflow to use npm Trusted Publishing, and fixed its Node version.
13+
- Added CodeQL scanning and a Playwright-based in-app smoke test suite (MOB-12019, MOB-12020).
14+
15+
## [2.2.1]
16+
### Fixes
17+
- Fixed a persistent scrollbar in in-app message iframes (MOB-11504).
18+
- Resolved security vulnerabilities by bumping `axios`, `jest` (v28), and the `on-headers` dependency (MOB-12120, MOB-12122, MOB-12129).
19+
- Added initial Playwright setup (MOB-12017).
20+
21+
## [2.2.0]
22+
### Updates
23+
- Added Unknown User Activation (UUA) public beta support, including capturing user consent.
24+
- Resolved minor issues and bugs in the Unknown User Activation feature.
25+
26+
## [2.1.0]
27+
### Updates
28+
- Added an `.nvmrc` config to the project (MOB-11702).
29+
### Fixes
30+
- Added build steps to the publish workflow (MOB-11716).
31+
32+
## [2.0.0]
33+
### Updates
34+
- Upgraded the `webpack` dependency and `webpack-dev-server`, and bumped the supported Node version (MOB-11487, MOB-11507).
35+
- Added support for non-JWT requests in the React sample app (MOB-11524).
36+
- Resolved remaining vulnerable security dependencies (MOB-11616).
37+
### Fixes
38+
- Fixed ESLint errors in the vanilla JS sample app and resolved lint warnings (MOB-11503, MOB-11554).
39+
- Deduplicated lockfiles (MOB-11618).
40+
41+
## [1.2.0]
42+
### Updates
43+
- Added `maxWidth` to the `getInAppMessages` payload (MOB-11427).
44+
- Exposed `baseIterableRequest` (MOB-11346).
45+
- Added Codecov to the Web SDK (MOB-11001).
46+
### Fixes
47+
- Bumped `axios`, `jest`, and `express` dependency versions (MOB-11441, MOB-11449, MOB-11443).
48+
49+
## [1.1.3]
50+
### Updates
51+
- Enabled tree-shaking (MOB-9520).
52+
- Updated docs: changed "EUDC" to "EDC" (DOCS-4858).
53+
### Dependencies
54+
- Bumped `webpack` from 5.76.0 to 5.94.0.
55+
56+
## [1.1.2]
57+
### Updates
58+
- Added stricter linting rules and the `prefer-for-of` TypeScript rule (MOB-9066, MOB-9256).
59+
- Updated EUDC instructions (DOCS-4818).
60+
### Dependencies
61+
- Bumped several dependencies (`braces`, `ws`, `axios`, `postcss`, `requirejs`, `micromatch`).
62+
63+
## [1.1.1]
64+
### Fixes
65+
- Properly formatted query params for GET requests, fixing handling of `placementIds` when fetching embedded messages (MOB-9087).
66+
67+
## [1.1.0]
68+
### Updates
69+
- Embedded Messaging is now GA (MOB-8539). This includes out-of-the-box views (cards, notifications, and banners) and an `IterableEmbeddedSessionManager` for tracking sessions and impressions.
70+
- Breaking changes vs the beta: `EmbeddedManager` is now `IterableEmbeddedManager` and is instantiated with your app's package name.
71+
- `trackEmbeddedClick` is now a standalone import instead of a method on the manager.
72+
- Signatures changed for `syncMessages`, `getMessages`, `getMessagesForPlacement`, `addUpdateListener`, and `getUpdateHandlers`.
73+
- `handleEmbeddedMessageClick` was renamed to `click(clickedUrl)`.
74+
- Several types were renamed (for example `IEmbeddedMessage` is now `IterableEmbeddedMessage`). See PR #365 for details.
75+
- Updated the README to more accurately document `initializeWithConfig` (#401).
76+
- Added the Playwright testing framework as a dev dependency (QAE-1182).
77+
### Fixes
78+
- Prepublish checks and fixes (MOB-8854).
79+
80+
## [1.0.11]
81+
### Updates
82+
- Added new SDK configuration options `isEuIterableService` and `dangerouslyAllowJsPopupsSDK` (MOB-8649).
83+
- `dangerouslyAllowJsPopupsSDK` replaces the `DANGEROUSLY_ALLOW_JS_POPUP_EXECUTION` environment variable, which is no longer supported.
84+
- `isEuIterableService` is an alternative to the `IS_EU_ITERABLE_SERVICE` environment variable, which is still available.
85+
86+
## [1.0.10]
87+
### Fixes
88+
- Resolved some TypeScript errors and updated the example app.
89+
- Added `allow-popups-to-escape-sandbox` so Safari can open in-app message link clicks in a clean browsing context (MOB-8515).
90+
### Dependencies
91+
- Bumped `follow-redirects`, `webpack-dev-middleware`, `express`, and `ip`.
92+
93+
## [1.0.9]
94+
### Fixes
95+
- Passed additional EU-related environment variables to webpack (resolves issue #356).
96+
97+
## [1.0.8]
98+
### Fixes
99+
- Fixed the iframe height setter and updated vulnerable dependencies (MOB-7613, MOB-7390).
100+
- Updated the README for iOS browser handling (MOB-7682).
101+
102+
## [1.0.7]
103+
### Fixes
104+
- Bumped `axios` from 0.21.4 to 1.6.2.
105+
- Fixed the nullish coalescing operator.
106+
- Exported authorization typings.
107+
108+
## [1.0.6]
109+
### Fixes
110+
- Added a new filter method that leaves only JSON-only messages (MOB-7175).
111+
112+
## [1.0.5]
113+
### Fixes
114+
- Added EU Domain Configuration (EUDC) support and release cut (MOB-5933, MOB-6617).
115+
- Fixed a docs discrepancy for imports and updated the close button README (MOB-6374).
116+
117+
## [1.0.4]
118+
### Fixes
119+
- Repositioned the close (x) button (MOB-6229).
120+
121+
## [1.0.3]
122+
### Fixes
123+
- JWT token can now be refreshed manually (MOB-5654).
124+
- Fixed an infinite loop when the JWT expiration time is invalid.
125+
- Updated the React example to include `logout` and refresh-JWT-token buttons.
126+
127+
## [1.0.2]
128+
### Fixes
129+
- Fixed some Safari dismissal bugs (MOB-5930).
130+
131+
## [1.0.1]
132+
### Fixes
133+
- Fixed an infinite loop.
134+
135+
## [1.0.0]
136+
### Changed
137+
- Updated `getMessages` requests to use the new web endpoint (MOB-4055).
138+
- Deprecated the boolean value for the `getInAppMessages` `showInAppMessagesAutomatically` param (MOB-4490).
139+
- No longer adds an autogenerated close button when an in-app message is displayed in Safari (MOB-4959).
140+
### Fixed
141+
- Fixed a discrepancy in iframe heights and refactored mock data to test cached messages (MOB-4936).
142+
- Fixed `handleLinks` support for iframe links in Safari (MOB-4718).
143+
144+
## [0.4.2]
145+
### Fixes
146+
- Fixed iframe height setting (MOB-4840).
147+
148+
## [0.4.1]
149+
### Updates
150+
- Refactored `inapp.ts` and removed excessive footers from the sample apps (MOB-4789).
151+
### Fixes
152+
- Filtered out messages set to deliver silently (MOB-4740).
153+
154+
## [0.4.0]
155+
### Updates
156+
- Prevented dismissing of an in-app message when clicking outside of the message (MOB-4677).
157+
- Secured the unprotected raw HTML path with an iframe (MOB-4576).
158+
### Fixes
159+
- Resolved security issues with the `terser` dependency (MOB-4726).
160+
161+
## [0.3.0]
162+
### Changed
163+
- Persisted the same type of credential to sign future JSON Web Tokens, even after invoking `updateUserEmail` (#134). Previously, if a user called `setUserID` then updated the email with `updateUserEmail`, future JWTs would be signed with the new email even though the consumer code originally authorized with user ID.
164+
### Fixed
165+
- Fixed an issue where calling `resumeMessageStream` showed the next in-app message in the queue even if `pauseMessageStream` was not called first (#135).
166+
167+
## [0.2.1]
168+
### Changed
169+
- Upgraded TypeScript and fixed new errors (#131).
170+
- Prevented JS from running in the in-app message iframe (#132).
171+
172+
## [0.2.0]
173+
### Changed
174+
- Updated `getInAppMessages`, making it possible to defer the display of in-app messages (#123).
175+
176+
## [0.1.3]
177+
### Fixed
178+
- Fixed a case where, when `setEmail` or `setUserId` was called multiple times, the SDK would always request a JWT for the first email or userID (#121).
179+
180+
## [0.1.2]
181+
### Fixed
182+
- Fixed a max-height issue (#109).
183+
- Updated documentation (#107, #108).
184+
185+
## [0.1.1]
186+
### Changed
187+
- Updated documentation (#104).
188+
### Fixed
189+
- Persisted POST `/trackInAppClick` calls when the browser navigates to a new link (#105).
190+
191+
## [0.1.0]
192+
Initial release.
193+
194+
### Added
195+
- `initialize`
196+
- `getInAppMessages`
197+
- `track`
198+
- `trackInAppClick`
199+
- `trackInAppClose`
200+
- `trackInAppConsume`
201+
- `trackInAppDelivery`
202+
- `trackInAppOpen`
203+
- `trackPurchase`
204+
- `updateCart`
205+
- `updateSubscriptions`
206+
- `updateUser`
207+
- `updateUserEmail`

0 commit comments

Comments
 (0)