-
Notifications
You must be signed in to change notification settings - Fork 195
ci: add create-release-pr workflow action #1084
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
fbe4d4d
b1a61e7
75b3e8e
b8f0374
aeaf864
243127a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,302 @@ | ||
| name: Create Release PR | ||
|
|
||
| on: | ||
| # For making a release pr from android / ios sdk actions | ||
| workflow_call: | ||
| inputs: | ||
| cordova_version: | ||
| description: 'New Cordova Version (e.g., 5.2.15 or 5.2.15-beta.1)' | ||
| required: true | ||
| type: string | ||
| android_version: | ||
| description: 'New Android SDK Version (e.g., 2.3.0). Leave blank to skip.' | ||
| required: false | ||
| type: string | ||
| ios_version: | ||
| description: 'New iOS SDK Version (e.g., 1.5.0). Leave blank to skip.' | ||
| required: false | ||
| type: string | ||
|
|
||
| # For making a release pr from cordova github actions | ||
| workflow_dispatch: | ||
| inputs: | ||
| cordova_version: | ||
| description: 'New Cordova Version (e.g., 5.2.15 or 5.2.15-beta.1)' | ||
| required: true | ||
| type: string | ||
| android_version: | ||
| description: 'New Android SDK Version (e.g., 2.3.0). Leave blank to skip.' | ||
| required: false | ||
| type: string | ||
| ios_version: | ||
| description: 'New iOS SDK Version (e.g., 1.5.0). Leave blank to skip.' | ||
| required: false | ||
| type: string | ||
|
|
||
| jobs: | ||
| update-version: | ||
| runs-on: ubuntu-latest | ||
|
|
||
| env: | ||
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
|
|
||
| steps: | ||
| - name: Checkout repository | ||
| uses: actions/checkout@v5 | ||
| with: | ||
| fetch-depth: 0 | ||
| fetch-tags: true | ||
|
|
||
| - name: Set up Bun | ||
| uses: oven-sh/setup-bun@v2 | ||
| with: | ||
| bun-version: latest | ||
|
|
||
| - name: Get last release commit | ||
| id: last_commit | ||
| run: | | ||
| CURRENT_VERSION=$(bun -e "console.log(require('./package.json').version)") | ||
| LAST_RELEASE_DATE=$(git show -s --format=%cI "$CURRENT_VERSION") | ||
| echo "date=$LAST_RELEASE_DATE" >> $GITHUB_OUTPUT | ||
|
|
||
| - name: Release branch name | ||
| id: release_branch | ||
| run: | | ||
| BRANCH_VERSION=$(echo "${{ inputs.cordova_version }}" | sed 's/\(-[a-z]*\)\.[0-9]*$/\1/') | ||
| echo "releaseBranch=rel/$BRANCH_VERSION" >> $GITHUB_OUTPUT | ||
|
|
||
| - name: Get merged PRs since last release | ||
| id: get_prs | ||
| uses: actions/github-script@v8 | ||
| with: | ||
| script: | | ||
| const lastReleaseDate = '${{ steps.last_commit.outputs.date }}'; | ||
| const releaseBranch = '${{ steps.release_branch.outputs.releaseBranch }}'; | ||
|
|
||
| // Get merged PRs | ||
| const { data: prs } = await github.rest.pulls.list({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| state: 'closed', | ||
| base: 'main', | ||
| per_page: 100 | ||
| }); | ||
| const { data: relPrs } = await github.rest.pulls.list({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| state: 'closed', | ||
| base: releaseBranch, | ||
| per_page: 100 | ||
| }); | ||
|
|
||
| // Filter and process PRs | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i am thinking if we can standardize this across all PRs? that way we haev one way of doing it everywhere.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ive added a call to get prs merged into rel/ |
||
| const mergedPrs = [...prs, ...relPrs] | ||
| .filter(pr => pr.merged_at && new Date(pr.merged_at) > new Date(lastReleaseDate)) | ||
| .map(pr => ({ | ||
| number: pr.number, | ||
| title: pr.title, | ||
| })); | ||
| core.setOutput('prs', JSON.stringify(mergedPrs)); | ||
|
|
||
| - name: Create release branch | ||
| run: | | ||
| releaseBranch="${{ steps.release_branch.outputs.releaseBranch }}" | ||
| git checkout -b "$releaseBranch" | ||
| git push -u origin "$releaseBranch" | ||
|
|
||
| - name: Capture current native SDK versions | ||
| id: current_versions | ||
| run: | | ||
| # Extract current Android SDK version | ||
| ANDROID_VERSION=$(grep -oP 'com\.onesignal:OneSignal:\K[0-9.]+' plugin.xml | head -1) | ||
|
|
||
| # Extract current iOS SDK version | ||
| IOS_VERSION=$(grep -oP 'OneSignalXCFramework.*spec="\K[0-9.]+' plugin.xml | head -1) | ||
|
|
||
| echo "prev_android=$ANDROID_VERSION" >> $GITHUB_OUTPUT | ||
| echo "prev_ios=$IOS_VERSION" >> $GITHUB_OUTPUT | ||
|
|
||
| # Cordova specific steps | ||
| - name: Update Android SDK version | ||
| if: inputs.android_version != '' | ||
| run: | | ||
| VERSION="${{ inputs.android_version }}" | ||
|
|
||
| # Validate version exists on GitHub | ||
| RELEASE=$(curl -s -H "Authorization: token ${{ github.token }}" \ | ||
| "https://api.github.com/repos/OneSignal/OneSignal-Android-SDK/releases/tags/v${VERSION}") | ||
|
|
||
| if echo "$RELEASE" | grep -q "\"id\""; then | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is this a safe validation? have you tested it?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will test when its merged |
||
| # Update plugin.xml with new version | ||
| sed -i "s|<framework src=\"com\.onesignal:OneSignal:[^\"]*\" />|<framework src=\"com.onesignal:OneSignal:${VERSION}\" />|" plugin.xml | ||
| echo "✓ Updated plugin.xml with Android SDK ${VERSION}" | ||
| else | ||
| echo "✗ Android SDK version ${VERSION} not found" | ||
| exit 1 | ||
| fi | ||
|
|
||
| - name: Update iOS SDK version | ||
| if: inputs.ios_version != '' | ||
| run: | | ||
| VERSION="${{ inputs.ios_version }}" | ||
|
|
||
| # Validate version exists on GitHub | ||
| RELEASE=$(curl -s -H "Authorization: token ${{ github.token }}" \ | ||
| "https://api.github.com/repos/OneSignal/OneSignal-iOS-SDK/releases/tags/v${VERSION}") | ||
|
|
||
| if echo "$RELEASE" | grep -q "\"id\""; then | ||
fadi-george marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| # Update plugin.xml with new version | ||
| sed -i "s|<pod name=\"OneSignalXCFramework\" spec=\"[^\"]*\" />|<pod name=\"OneSignalXCFramework\" spec=\"${VERSION}\" />|" plugin.xml | ||
| echo "✓ Updated plugin.xml with iOS SDK ${VERSION}" | ||
|
|
||
| # Need to clear the Podfile.lock to force a re-install of the framework | ||
| rm -f example/IonicCapOneSignal/ios/App/Podfile.lock | ||
| else | ||
| echo "✗ iOS SDK version ${VERSION} not found" | ||
| exit 1 | ||
| fi | ||
|
|
||
| - name: Capacitor update | ||
| run: | | ||
| bunx cap sync || exit 1 | ||
| git add . | ||
|
|
||
| - name: Update sdk version | ||
| run: | | ||
| NEW_VERSION="${{ inputs.cordova_version }}" | ||
| git config user.name "github-actions[bot]" | ||
| git config user.email "github-actions[bot]@users.noreply.github.com" | ||
|
|
||
| # Convert version format for OneSignal wrapper (e.g., 5.2.15 -> 050215) | ||
| # For pre-releases, extract base version first (e.g., 5.2.15-alpha.1 -> 5.2.15) | ||
| BASE_VERSION=$(echo "$NEW_VERSION" | sed 's/-[a-z].*//') | ||
| WRAPPER_VERSION=$(echo "$BASE_VERSION" | awk -F'.' '{printf "%02d%02d%02d", $1, $2, $3}') | ||
|
|
||
| # Update package.json version | ||
| npm pkg set version="$NEW_VERSION" | ||
|
|
||
| # Update plugin.xml cordova plugin version (target <plugin> element specifically) | ||
| sed -i 's|<plugin \(xmlns="[^"]*" xmlns:android="[^"]*" id="[^"]*"\) version="[^"]*"|<plugin \1 version="'"$NEW_VERSION"'"|' plugin.xml | ||
|
|
||
| # Update OneSignalPush.java wrapper version | ||
| sed -i "s/OneSignalWrapper\.setSdkVersion(\"[^\"]*\")/OneSignalWrapper.setSdkVersion(\"$WRAPPER_VERSION\")/g" src/android/com/onesignal/cordova/OneSignalPush.java | ||
|
|
||
| # Update OneSignalPush.m wrapper version | ||
| sed -i "s/OneSignalWrapper\.sdkVersion = @\"[^\"]*\"/OneSignalWrapper.sdkVersion = @\"$WRAPPER_VERSION\"/g" src/ios/OneSignalPush.m | ||
|
|
||
| git add package.json plugin.xml src/android/com/onesignal/cordova/OneSignalPush.java src/ios/OneSignalPush.m | ||
|
|
||
| git commit -m "Release $NEW_VERSION" | ||
| git push | ||
|
|
||
| - name: Check native SDK version changes | ||
| id: native_deps | ||
| run: | | ||
| # Get the current plugin.xml | ||
| CURRENT_PLUGIN=$(cat plugin.xml) | ||
|
|
||
| # Extract current Android SDK version | ||
| ANDROID_VERSION=$(echo "$CURRENT_PLUGIN" | grep -oP 'com\.onesignal:OneSignal:\K[0-9.]+' | head -1) | ||
| PREVIOUS_ANDROID="${{ steps.current_versions.outputs.prev_android }}" | ||
|
|
||
| # Extract current iOS SDK version | ||
| IOS_VERSION=$(echo "$CURRENT_PLUGIN" | grep -oP 'OneSignalXCFramework.*spec="\K[0-9.]+' | head -1) | ||
| PREVIOUS_IOS="${{ steps.current_versions.outputs.prev_ios }}" | ||
|
|
||
| # Build output for native dependency changes | ||
| NATIVE_UPDATES="" | ||
| if [[ "$ANDROID_VERSION" != "$PREVIOUS_ANDROID" && ! -z "$PREVIOUS_ANDROID" ]]; then | ||
| printf -v NATIVE_UPDATES '%sANDROID_UPDATE=true\nANDROID_FROM=%s\nANDROID_TO=%s\n' "$NATIVE_UPDATES" "$PREVIOUS_ANDROID" "$ANDROID_VERSION" | ||
| fi | ||
|
|
||
| if [[ "$IOS_VERSION" != "$PREVIOUS_IOS" && ! -z "$PREVIOUS_IOS" ]]; then | ||
| printf -v NATIVE_UPDATES '%sIOS_UPDATE=true\nIOS_FROM=%s\nIOS_TO=%s\n' "$NATIVE_UPDATES" "$PREVIOUS_IOS" "$IOS_VERSION" | ||
| fi | ||
|
|
||
| # Output the variables | ||
| echo "$NATIVE_UPDATES" >> $GITHUB_OUTPUT | ||
|
|
||
| - name: Get release type | ||
| id: release_type | ||
| run: | | ||
| NEW_VERSION="${{ inputs.cordova_version }}" | ||
| if [[ "$NEW_VERSION" =~ -alpha ]]; then | ||
| echo "release-type=Alpha" >> $GITHUB_OUTPUT | ||
| elif [[ "$NEW_VERSION" =~ -beta ]]; then | ||
| echo "release-type=Beta" >> $GITHUB_OUTPUT | ||
| else | ||
| echo "release-type=Current" >> $GITHUB_OUTPUT | ||
| fi | ||
|
|
||
| - name: Generate release notes | ||
| id: release_notes | ||
| uses: actions/github-script@v8 | ||
| with: | ||
| script: | | ||
| // Trim whitespace from PR titles | ||
| const prs = JSON.parse('${{ steps.get_prs.outputs.prs }}').map(pr => ({ | ||
| ...pr, | ||
| title: pr.title.trim() | ||
| })); | ||
|
|
||
| // Categorize PRs | ||
| const features = prs.filter(pr => /^feat/i.test(pr.title)); | ||
| const fixes = prs.filter(pr => /^fix/i.test(pr.title)); | ||
| const improvements = prs.filter(pr => /^(perf|refactor|chore)/i.test(pr.title)); | ||
|
|
||
| // Helper function to build section | ||
| const buildSection = (title, prs) => { | ||
| if (prs.length === 0) return ''; | ||
| let section = `### ${title}\n\n`; | ||
| prs.forEach(pr => { | ||
| section += `- ${pr.title} (#${pr.number})\n`; | ||
| }); | ||
| return section + '\n'; | ||
| }; | ||
|
|
||
| let releaseNotes = `Channels: ${{ steps.release_type.outputs.release-type }}\n\n`; | ||
| releaseNotes += buildSection('🚀 New Features', features); | ||
| releaseNotes += buildSection('🐛 Bug Fixes', fixes); | ||
| releaseNotes += buildSection('✨ Improvements', improvements); | ||
|
|
||
| // Check for native dependency changes | ||
| const hasAndroidUpdate = '${{ steps.native_deps.outputs.ANDROID_UPDATE }}' === 'true'; | ||
| const hasIosUpdate = '${{ steps.native_deps.outputs.IOS_UPDATE }}' === 'true'; | ||
|
|
||
| if (hasAndroidUpdate || hasIosUpdate) { | ||
| releaseNotes += '\n### 🛠️ Native Dependency Updates\n\n'; | ||
| if (hasAndroidUpdate) { | ||
| releaseNotes += `- Update Android SDK from ${{ steps.native_deps.outputs.ANDROID_FROM }} to ${{ steps.native_deps.outputs.ANDROID_TO }}\n`; | ||
| releaseNotes += `- See [release notes](https://github.com/OneSignal/OneSignal-Android-SDK/releases) for full details\n`; | ||
| } | ||
| if (hasIosUpdate) { | ||
| releaseNotes += `- Update iOS SDK from ${{ steps.native_deps.outputs.IOS_FROM }} to ${{ steps.native_deps.outputs.IOS_TO }}\n`; | ||
| releaseNotes += `- See [release notes](https://github.com/OneSignal/OneSignal-iOS-SDK/releases) for full details\n`; | ||
| } | ||
| releaseNotes += '\n'; | ||
| } | ||
|
|
||
| core.setOutput('notes', releaseNotes); | ||
|
|
||
| - name: Create release PR | ||
| run: | | ||
| NEW_VERSION="${{ inputs.cordova_version }}" | ||
| RELEASE_TYPE="${{ steps.release_type.outputs.release-type }}" | ||
|
|
||
| # Determine base branch based on release type | ||
| if [[ "$RELEASE_TYPE" == "Current" ]]; then | ||
| BASE_BRANCH="main" | ||
| else | ||
| BASE_BRANCH="${{ steps.release_branch.outputs.releaseBranch }}" | ||
| fi | ||
|
|
||
| # Write release notes to file to avoid shell interpretation | ||
| cat > release_notes.md << 'EOF' | ||
| ${{ steps.release_notes.outputs.notes }} | ||
| EOF | ||
|
|
||
| gh pr create \ | ||
| --title "Release $NEW_VERSION" \ | ||
| --body-file release_notes.md \ | ||
| --base "$BASE_BRANCH" \ | ||
| --reviewer fadi-george,sherwinski,jkasten2 | ||
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what is if its a non release branch?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ive updated to check if cordova version is prerelease and use rel/ e.g. rel/5.3.0-beta (minus the beta number)