Skip to content

Commit 1580212

Browse files
committed
add new create release pr workflow
1 parent 165db42 commit 1580212

File tree

2 files changed

+331
-18
lines changed

2 files changed

+331
-18
lines changed
Lines changed: 331 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,331 @@
1+
name: Create Release PR
2+
3+
on:
4+
# For making a release pr from android / ios sdk actions
5+
workflow_call:
6+
inputs:
7+
rn_version:
8+
description: 'New React Native Version (e.g., 5.2.15 or 5.2.15-beta.1)'
9+
required: true
10+
type: string
11+
android_version:
12+
description: 'New Android SDK Version (e.g., 2.3.0). Leave blank to skip.'
13+
required: false
14+
type: string
15+
ios_version:
16+
description: 'New iOS SDK Version (e.g., 1.5.0). Leave blank to skip.'
17+
required: false
18+
type: string
19+
20+
# For making a release pr from cordova github actions
21+
workflow_dispatch:
22+
inputs:
23+
rn_version:
24+
description: 'New React Native Version (e.g., 5.2.15 or 5.2.15-beta.1)'
25+
required: true
26+
type: string
27+
android_version:
28+
description: 'New Android SDK Version (e.g., 2.3.0). Leave blank to skip.'
29+
required: false
30+
type: string
31+
ios_version:
32+
description: 'New iOS SDK Version (e.g., 1.5.0). Leave blank to skip.'
33+
required: false
34+
type: string
35+
36+
jobs:
37+
update-version:
38+
runs-on: macos-latest
39+
40+
env:
41+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
42+
43+
steps:
44+
- name: Checkout
45+
uses: actions/checkout@v5
46+
with:
47+
fetch-depth: 0
48+
fetch-tags: true
49+
50+
- name: Setup Bun
51+
uses: oven-sh/setup-bun@v2
52+
with:
53+
bun-version: latest
54+
55+
- name: Install
56+
run: bun install --frozen-lockfile
57+
58+
- name: Get release type
59+
id: release_type
60+
run: |
61+
NEW_VERSION="${{ inputs.cordova_version }}"
62+
if [[ "$NEW_VERSION" =~ -alpha ]]; then
63+
echo "release-type=Alpha" >> $GITHUB_OUTPUT
64+
elif [[ "$NEW_VERSION" =~ -beta ]]; then
65+
echo "release-type=Beta" >> $GITHUB_OUTPUT
66+
else
67+
echo "release-type=Current" >> $GITHUB_OUTPUT
68+
fi
69+
70+
- name: Get last release commit
71+
id: last_commit
72+
run: |
73+
CURRENT_VERSION=$(bun -e "console.log(require('./package.json').version)")
74+
LAST_RELEASE_DATE=$(git show -s --format=%cI "$CURRENT_VERSION")
75+
echo "date=$LAST_RELEASE_DATE" >> $GITHUB_OUTPUT
76+
77+
- name: Release branch name
78+
id: release_branch
79+
run: |
80+
# Omit alpha/beta version e.g. 5.2.15-beta.1 -> 5.2.15-beta
81+
BRANCH_VERSION=$(echo "${{ inputs.cordova_version }}" | sed 's/\(-[a-z]*\)\.[0-9]*$/\1/')
82+
echo "releaseBranch=rel/$BRANCH_VERSION" >> $GITHUB_OUTPUT
83+
84+
- name: Create release branch
85+
run: |
86+
releaseBranch="${{ steps.release_branch.outputs.releaseBranch }}"
87+
releaseType="${{ steps.release_type.outputs.release-type }}"
88+
89+
if ! git checkout -b "$releaseBranch" 2>/dev/null; then
90+
# Branch already exists
91+
if [[ "$releaseType" == "Current" ]]; then
92+
echo "Error: Release branch already exists for Current release"
93+
exit 1
94+
fi
95+
# For Alpha/Beta, use existing branch
96+
git checkout "$releaseBranch"
97+
fi
98+
git push -u origin "$releaseBranch"
99+
100+
- name: Get merged PRs
101+
id: get_prs
102+
uses: actions/github-script@v8
103+
with:
104+
script: |
105+
const lastReleaseDate = '${{ steps.last_commit.outputs.date }}';
106+
const releaseBranch = '${{ steps.release_branch.outputs.releaseBranch }}';
107+
108+
// Get the creation date of the release branch (when it diverged from main)
109+
const { data: branchInfo } = await github.rest.repos.getBranch({
110+
owner: context.repo.owner,
111+
repo: context.repo.repo,
112+
branch: releaseBranch
113+
});
114+
const branchCreatedAt = branchInfo.commit.commit.committer.date;
115+
116+
// Get PRs merged to main since last release but BEFORE release branch was created
117+
const { data: prs } = await github.rest.pulls.list({
118+
owner: context.repo.owner,
119+
repo: context.repo.repo,
120+
state: 'closed',
121+
base: 'main',
122+
per_page: 100
123+
});
124+
125+
const mergedPrs = prs
126+
.filter(pr =>
127+
pr.merged_at &&
128+
new Date(pr.merged_at) > new Date(lastReleaseDate) &&
129+
new Date(pr.merged_at) <= new Date(branchCreatedAt) // Only before branch creation
130+
)
131+
.map(pr => ({
132+
number: pr.number,
133+
title: pr.title,
134+
}));
135+
core.setOutput('prs', JSON.stringify(mergedPrs));
136+
- name: Get current native SDK versions
137+
id: current_versions
138+
run: |
139+
# Extract current Android SDK version
140+
ANDROID_VERSION=$(sed -n 's/.*com\.onesignal:OneSignal:\([0-9.]*\).*/\1/p' plugin.xml | head -1)
141+
142+
# Extract current iOS SDK version
143+
IOS_VERSION=$(sed -n 's/.*OneSignalXCFramework.*spec="\([0-9.]*\)".*/\1/p' plugin.xml | head -1)
144+
145+
echo "prev_android=$ANDROID_VERSION" >> $GITHUB_OUTPUT
146+
echo "prev_ios=$IOS_VERSION" >> $GITHUB_OUTPUT
147+
148+
# Cordova specific steps
149+
- name: Setup Capacitor
150+
run: |
151+
bun link
152+
cd example/IonicCapOneSignal
153+
bun install --frozen-lockfile
154+
bun run build
155+
156+
- name: Update Android SDK version
157+
if: inputs.android_version != ''
158+
run: |
159+
VERSION="${{ inputs.android_version }}"
160+
161+
# Validate version exists on GitHub
162+
RELEASE=$(curl -s -H "Authorization: token ${{ github.token }}" \
163+
"https://api.github.com/repos/OneSignal/OneSignal-Android-SDK/releases/tags/${VERSION}")
164+
165+
if sed -n '/\"id\"/p' <<< "$RELEASE" | grep -q .; then
166+
# Update plugin.xml with new version
167+
# mac os sed syntax
168+
sed -i '' 's|<framework src="com\.onesignal:OneSignal:[^"]*" />|<framework src="com.onesignal:OneSignal:'"$VERSION"'" />|' plugin.xml
169+
echo "✓ Updated plugin.xml with Android SDK ${VERSION}"
170+
171+
cd example/IonicCapOneSignal
172+
bunx cap sync android
173+
git add .
174+
else
175+
echo "✗ Android SDK version ${VERSION} not found"
176+
exit 1
177+
fi
178+
179+
- name: Update iOS SDK version
180+
if: inputs.ios_version != ''
181+
run: |
182+
VERSION="${{ inputs.ios_version }}"
183+
184+
# Validate version exists on GitHub
185+
RELEASE=$(curl -s -H "Authorization: token ${{ github.token }}" \
186+
"https://api.github.com/repos/OneSignal/OneSignal-iOS-SDK/releases/tags/${VERSION}")
187+
188+
if sed -n '/\"id\"/p' <<< "$RELEASE" | grep -q .; then
189+
# Update plugin.xml with new version
190+
# mac os sed syntax
191+
sed -i '' "s|<pod name=\"OneSignalXCFramework\" spec=\"[^\"]*\" />|<pod name=\"OneSignalXCFramework\" spec=\"${VERSION}\" />|" plugin.xml
192+
echo "✓ Updated plugin.xml with iOS SDK ${VERSION}"
193+
194+
# Need to regenerate the Podfile.lock
195+
cd example/IonicCapOneSignal/ios/App
196+
rm -f Podfile.lock
197+
cd ../..
198+
bunx cap sync ios
199+
git add .
200+
201+
else
202+
echo "✗ iOS SDK version ${VERSION} not found"
203+
exit 1
204+
fi
205+
206+
- name: Update sdk version
207+
run: |
208+
NEW_VERSION="${{ inputs.cordova_version }}"
209+
git config user.name "github-actions[bot]"
210+
git config user.email "github-actions[bot]@users.noreply.github.com"
211+
212+
# Convert version format for OneSignal wrapper (e.g., 5.2.15 -> 050215)
213+
# For pre-releases, extract base version first (e.g., 5.2.15-alpha.1 -> 5.2.15)
214+
BASE_VERSION=$(echo "$NEW_VERSION" | sed 's/-[a-z].*//')
215+
WRAPPER_VERSION=$(echo "$BASE_VERSION" | awk -F'.' '{printf "%02d%02d%02d", $1, $2, $3}')
216+
217+
# Update package.json version
218+
npm pkg set version="$NEW_VERSION"
219+
220+
# Update plugin.xml cordova plugin version (target <plugin> element specifically)
221+
sed -i '' '/<plugin/,/>/ { s/version="[^"]*"/version="'"$NEW_VERSION"'"/; }' plugin.xml
222+
223+
# Update OneSignalPush.java wrapper version
224+
sed -i '' "s/OneSignalWrapper\.setSdkVersion(\"[^\"]*\")/OneSignalWrapper.setSdkVersion(\"$WRAPPER_VERSION\")/g" src/android/com/onesignal/cordova/OneSignalPush.java
225+
226+
# Update OneSignalPush.m wrapper version
227+
sed -i '' "s/OneSignalWrapper\.sdkVersion = @\"[^\"]*\"/OneSignalWrapper.sdkVersion = @\"$WRAPPER_VERSION\"/g" src/ios/OneSignalPush.m
228+
229+
git add package.json plugin.xml src/android/com/onesignal/cordova/OneSignalPush.java src/ios/OneSignalPush.m
230+
231+
git commit -m "Release $NEW_VERSION"
232+
git push
233+
234+
- name: Document native sdk changes
235+
id: native_deps
236+
run: |
237+
# Get the current plugin.xml
238+
CURRENT_PLUGIN=$(cat plugin.xml)
239+
240+
# Extract current Android SDK version
241+
ANDROID_VERSION=$(sed -n 's/.*com\.onesignal:OneSignal:\([0-9.]*\).*/\1/p' <<< "$CURRENT_PLUGIN" | head -1)
242+
PREVIOUS_ANDROID="${{ steps.current_versions.outputs.prev_android }}"
243+
244+
# Extract current iOS SDK version
245+
IOS_VERSION=$(sed -n 's/.*OneSignalXCFramework.*spec="\([0-9.]*\)".*/\1/p' <<< "$CURRENT_PLUGIN" | head -1)
246+
PREVIOUS_IOS="${{ steps.current_versions.outputs.prev_ios }}"
247+
248+
# Build output for native dependency changes
249+
NATIVE_UPDATES=""
250+
if [[ "$ANDROID_VERSION" != "$PREVIOUS_ANDROID" && ! -z "$PREVIOUS_ANDROID" ]]; then
251+
printf -v NATIVE_UPDATES '%sANDROID_UPDATE=true\nANDROID_FROM=%s\nANDROID_TO=%s\n' "$NATIVE_UPDATES" "$PREVIOUS_ANDROID" "$ANDROID_VERSION"
252+
fi
253+
254+
if [[ "$IOS_VERSION" != "$PREVIOUS_IOS" && ! -z "$PREVIOUS_IOS" ]]; then
255+
printf -v NATIVE_UPDATES '%sIOS_UPDATE=true\nIOS_FROM=%s\nIOS_TO=%s\n' "$NATIVE_UPDATES" "$PREVIOUS_IOS" "$IOS_VERSION"
256+
fi
257+
258+
# Output the variables
259+
echo "$NATIVE_UPDATES" >> $GITHUB_OUTPUT
260+
261+
- name: Generate release notes
262+
id: release_notes
263+
uses: actions/github-script@v8
264+
with:
265+
script: |
266+
// Trim whitespace from PR titles
267+
const prs = JSON.parse('${{ steps.get_prs.outputs.prs }}').map(pr => ({
268+
...pr,
269+
title: pr.title.trim()
270+
}));
271+
272+
// Categorize PRs (exclude internal changes like ci/chore)
273+
const features = prs.filter(pr => /^feat/i.test(pr.title));
274+
const fixes = prs.filter(pr => /^fix/i.test(pr.title));
275+
const improvements = prs.filter(pr => /^(perf|refactor)/i.test(pr.title));
276+
277+
// Helper function to build section
278+
const buildSection = (title, prs) => {
279+
if (prs.length === 0) return '';
280+
let section = `### ${title}\n\n`;
281+
prs.forEach(pr => {
282+
section += `- ${pr.title} (#${pr.number})\n`;
283+
});
284+
return section + '\n';
285+
};
286+
287+
let releaseNotes = `Channels: ${{ steps.release_type.outputs.release-type }}\n\n`;
288+
releaseNotes += buildSection('🚀 New Features', features);
289+
releaseNotes += buildSection('🐛 Bug Fixes', fixes);
290+
releaseNotes += buildSection('✨ Improvements', improvements);
291+
292+
// Check for native dependency changes
293+
const hasAndroidUpdate = '${{ steps.native_deps.outputs.ANDROID_UPDATE }}' === 'true';
294+
const hasIosUpdate = '${{ steps.native_deps.outputs.IOS_UPDATE }}' === 'true';
295+
296+
if (hasAndroidUpdate || hasIosUpdate) {
297+
releaseNotes += '\n### 🛠️ Native Dependency Updates\n\n';
298+
if (hasAndroidUpdate) {
299+
releaseNotes += `- Update Android SDK from ${{ steps.native_deps.outputs.ANDROID_FROM }} to ${{ steps.native_deps.outputs.ANDROID_TO }}\n`;
300+
releaseNotes += ` - See [release notes](https://github.com/OneSignal/OneSignal-Android-SDK/releases) for full details\n`;
301+
}
302+
if (hasIosUpdate) {
303+
releaseNotes += `- Update iOS SDK from ${{ steps.native_deps.outputs.IOS_FROM }} to ${{ steps.native_deps.outputs.IOS_TO }}\n`;
304+
releaseNotes += ` - See [release notes](https://github.com/OneSignal/OneSignal-iOS-SDK/releases) for full details\n`;
305+
}
306+
releaseNotes += '\n';
307+
}
308+
309+
core.setOutput('notes', releaseNotes);
310+
311+
- name: Create release PR
312+
run: |
313+
NEW_VERSION="${{ inputs.cordova_version }}"
314+
RELEASE_TYPE="${{ steps.release_type.outputs.release-type }}"
315+
316+
# Determine base branch based on release type
317+
if [[ "$RELEASE_TYPE" == "Current" ]]; then
318+
BASE_BRANCH="main"
319+
else
320+
BASE_BRANCH="${{ steps.release_branch.outputs.releaseBranch }}"
321+
fi
322+
323+
# Write release notes to file to avoid shell interpretation
324+
cat > release_notes.md << 'EOF'
325+
${{ steps.release_notes.outputs.notes }}
326+
EOF
327+
328+
gh pr create \
329+
--title "chore: Release $NEW_VERSION" \
330+
--body-file release_notes.md \
331+
--base "$BASE_BRANCH"

.github/workflows/npm_deploy.yml

Lines changed: 0 additions & 18 deletions
This file was deleted.

0 commit comments

Comments
 (0)