|
1 | 1 | name: Create Unity Release PR |
2 | 2 |
|
3 | 3 | on: |
4 | | - push: |
5 | | - branches: |
6 | | - - "ci-unity" |
7 | 4 | workflow_dispatch: |
8 | 5 | inputs: |
9 | | - release-type: |
10 | | - description: "Release type" |
| 6 | + bump_command: |
| 7 | + description: "Version bump type (major, minor, patch, specify)" |
11 | 8 | required: true |
12 | | - default: "stable" |
13 | 9 | type: choice |
14 | 10 | options: |
15 | | - - Current |
16 | | - - Beta |
17 | | - - Alpha |
18 | | - |
| 11 | + - major |
| 12 | + - minor |
| 13 | + - patch |
| 14 | + - specify |
| 15 | + postfix: |
| 16 | + description: "Optional postfix (e.g. preview, beta, or specific version when using 'specify')" |
| 17 | + required: false |
| 18 | + type: string |
19 | 19 |
|
20 | 20 | permissions: |
21 | 21 | contents: write |
22 | 22 | pull-requests: write |
23 | 23 |
|
24 | 24 | jobs: |
25 | | - bump-version: |
| 25 | + compose-unity-release: |
| 26 | + name: Compose Unity Release |
26 | 27 | runs-on: ubuntu-latest |
| 28 | + timeout-minutes: 30 |
| 29 | + |
| 30 | + env: |
| 31 | + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
| 32 | + BUMP_COMMAND: ${{ github.event.inputs.bump_command }} |
| 33 | + POSTFIX: ${{ github.event.inputs.postfix }} |
27 | 34 |
|
28 | 35 | steps: |
29 | | - - name: Checkout repository |
30 | | - uses: actions/checkout@v5 |
| 36 | + - name: Checkout Repository |
| 37 | + uses: actions/checkout@v4 |
31 | 38 | with: |
32 | 39 | fetch-depth: 0 |
33 | 40 | fetch-tags: true |
34 | 41 |
|
35 | | - - name: Get current SDK version |
36 | | - id: current_version |
37 | | - run: | |
38 | | - CURRENT_VERSION=$(grep "bundleVersion:" ProjectSettings/ProjectSettings.asset | sed 's/.*bundleVersion: //') |
39 | | - echo "current=$CURRENT_VERSION" >> $GITHUB_OUTPUT |
40 | | -
|
41 | | - - name: Get last release commit |
42 | | - id: last_commit |
43 | | - run: | |
44 | | - LAST_RELEASE_DATE=$(git show -s --format=%cI "${{ steps.current_version.outputs.current }}") |
45 | | - echo "date=$LAST_RELEASE_DATE" >> $GITHUB_OUTPUT |
46 | | - |
47 | | - - name: Create release branch from base |
48 | | - run: | |
49 | | - if git ls-remote --exit-code --heads origin "$BRANCH"; then |
50 | | - echo "Deleting remote branch $BRANCH" |
51 | | - git push origin --delete "$BRANCH" |
52 | | - fi |
53 | | -
|
54 | | - echo "Creating release branch $BRANCH from main" |
55 | | - git checkout -b "$BRANCH" origin/main |
56 | | -
|
57 | | - - name: Get merged PRs since last release |
58 | | - id: get_prs |
59 | | - uses: actions/github-script@v8 |
| 42 | + # required for linux runners |
| 43 | + - name: Set up Unity |
| 44 | + uses: game-ci/unity-install@v4 |
60 | 45 | with: |
61 | | - script: | |
62 | | - const lastReleaseDate = '${{ steps.last_commit.outputs.date }}'; |
63 | | -
|
64 | | - // Get merged PRs |
65 | | - const { data: prs } = await github.rest.pulls.list({ |
66 | | - owner: context.repo.owner, |
67 | | - repo: context.repo.repo, |
68 | | - state: 'closed', |
69 | | - base: 'main', |
70 | | - per_page: 100 |
71 | | - }); |
72 | | -
|
73 | | - // Filter and process PRs |
74 | | - const mergedPrs = prs |
75 | | - .filter(pr => pr.merged_at && new Date(pr.merged_at) > new Date(lastReleaseDate)) |
76 | | - .map(pr => ({ |
77 | | - number: pr.number, |
78 | | - title: pr.title, |
79 | | - })); |
80 | | - core.setOutput('prs', JSON.stringify(mergedPrs)); |
81 | | -
|
82 | | - const hasFeatures = mergedPrs.some(pr => /^feat/i.test(pr.title)); |
83 | | - core.setOutput('isFeature', hasFeatures); |
84 | | - |
85 | | - - name: Calculate new version |
86 | | - id: new_version |
87 | | - run: | |
88 | | - CURRENT="${{ steps.current_version.outputs.current }}" |
89 | | - RELEASE_TYPE="${{ inputs.release-type }}" |
90 | | - IS_FEATURE='${{ steps.get_prs.outputs.isFeature }}' |
91 | | -
|
92 | | - # Extract base version and determine current pre-release type |
93 | | - if [[ "$CURRENT" =~ -alpha\. ]]; then |
94 | | - BASE_VERSION="${CURRENT%-alpha.*}" |
95 | | - PRERELEASE_NUM="${CURRENT##*-alpha.}" |
96 | | - PRERELEASE_TYPE="alpha" |
97 | | - elif [[ "$CURRENT" =~ -beta\. ]]; then |
98 | | - BASE_VERSION="${CURRENT%-beta.*}" |
99 | | - PRERELEASE_NUM="${CURRENT##*-beta.}" |
100 | | - PRERELEASE_TYPE="beta" |
101 | | - else |
102 | | - BASE_VERSION="$CURRENT" |
103 | | - PRERELEASE_TYPE="stable" |
104 | | - fi |
105 | | -
|
106 | | - # Helper function to bump version |
107 | | - bump_version() { |
108 | | - local base=$1 |
109 | | - local is_feature=$2 |
110 | | - local major=${base:0:2} |
111 | | - local minor=${base:2:2} |
112 | | - local patch=${base:4:2} |
113 | | -
|
114 | | - if [[ "$is_feature" == "true" ]]; then |
115 | | - minor=$(printf "%02d" $((10#$minor + 1))) |
116 | | - patch="00" |
117 | | - else |
118 | | - patch=$(printf "%02d" $((10#$patch + 1))) |
119 | | - fi |
| 46 | + unityVersion: '2021.3.0f1' # the oldest version of Unity we want to support and upload from |
| 47 | + components: linux-il2cpp android ios |
| 48 | + githubToken: ${{ secrets.GITHUB_TOKEN }} |
120 | 49 |
|
121 | | - echo "${major}${minor}${patch}" |
122 | | - } |
123 | | -
|
124 | | - # Determine new version based on current and desired release types |
125 | | - if [[ "$RELEASE_TYPE" == "Alpha" ]]; then |
126 | | - if [[ "$PRERELEASE_TYPE" == "alpha" ]]; then |
127 | | - # Increment alpha number |
128 | | - NEW_VERSION="$BASE_VERSION-alpha.$((PRERELEASE_NUM + 1))" |
129 | | - else |
130 | | - # New alpha release from stable or beta |
131 | | - NEW_VERSION="$(bump_version "$BASE_VERSION" "$IS_FEATURE")-alpha.1" |
132 | | - fi |
133 | | - elif [[ "$RELEASE_TYPE" == "Beta" ]]; then |
134 | | - if [[ "$PRERELEASE_TYPE" == "beta" ]]; then |
135 | | - # Increment beta number |
136 | | - NEW_VERSION="$BASE_VERSION-beta.$((PRERELEASE_NUM + 1))" |
137 | | - elif [[ "$PRERELEASE_TYPE" == "alpha" ]]; then |
138 | | - # Promote alpha to beta |
139 | | - NEW_VERSION="$BASE_VERSION-beta.1" |
140 | | - else |
141 | | - # New beta release from stable |
142 | | - NEW_VERSION="$(bump_version "$BASE_VERSION" "$IS_FEATURE")-beta.1" |
143 | | - fi |
144 | | - else |
145 | | - # Release type is Current (stable) |
146 | | - if [[ "$PRERELEASE_TYPE" != "stable" ]]; then |
147 | | - # Promote pre-release to stable |
148 | | - NEW_VERSION="$BASE_VERSION" |
149 | | - else |
150 | | - # Bump stable version |
151 | | - NEW_VERSION="$(bump_version "$CURRENT" "$IS_FEATURE")" |
152 | | - fi |
153 | | - fi |
154 | | -
|
155 | | - echo "version=$NEW_VERSION" >> $GITHUB_OUTPUT |
156 | | - |
157 | | - - name: Create release branch |
| 50 | + - name: Prepare Environment |
158 | 51 | run: | |
159 | | - git checkout -b rel/${{ steps.new_version.outputs.version }} |
160 | | - git push -u origin rel/${{ steps.new_version.outputs.version }} |
| 52 | + brew install gh jq || true |
| 53 | + gh auth status || gh auth login --with-token <<< "$GH_TOKEN" |
161 | 54 |
|
162 | | - - name: Create temp branch |
163 | | - if: inputs.release-type == 'Alpha' || inputs.release-type == 'Beta' |
164 | | - run: | |
165 | | - git checkout -b release-${{ steps.new_version.outputs.version }} |
166 | | - git push -u origin release-${{ steps.new_version.outputs.version }} |
167 | | - |
168 | | - # Unity specific steps |
169 | 55 | - name: Run composeRelease.sh |
170 | 56 | run: | |
171 | 57 | chmod +x ./composeRelease.sh |
172 | | - ./composeRelease.sh $VERSION |
173 | | - shell: bash |
174 | | - |
175 | | - - name: Check native SDK version changes |
176 | | - id: native_deps |
177 | | - run: | |
178 | | - # Get the current plugin.xml |
179 | | - CURRENT_PLUGIN=$(cat plugin.xml) |
180 | | -
|
181 | | - # Extract current Android SDK version |
182 | | - ANDROID_VERSION=$(echo "$CURRENT_PLUGIN" | grep -oP 'com\.onesignal:OneSignal:\K[0-9.]+' | head -1) |
183 | | -
|
184 | | - # Extract current iOS SDK version |
185 | | - IOS_VERSION=$(echo "$CURRENT_PLUGIN" | grep -oP 'OneSignalXCFramework.*spec="\K[0-9.]+' | head -1) |
186 | | -
|
187 | | - # Get previous plugin.xml from HEAD~1 (before the commit we just made) |
188 | | - PREVIOUS_PLUGIN=$(git show HEAD~1:plugin.xml) |
189 | | -
|
190 | | - # Extract previous Android SDK version |
191 | | - PREVIOUS_ANDROID=$(echo "$PREVIOUS_PLUGIN" | grep -oP 'com\.onesignal:OneSignal:\K[0-9.]+' | head -1) |
192 | | -
|
193 | | - # Extract previous iOS SDK version |
194 | | - PREVIOUS_IOS=$(echo "$PREVIOUS_PLUGIN" | grep -oP 'OneSignalXCFramework.*spec="\K[0-9.]+' | head -1) |
195 | | -
|
196 | | - # Build output for native dependency changes |
197 | | - NATIVE_UPDATES="" |
198 | | - if [[ "$ANDROID_VERSION" != "$PREVIOUS_ANDROID" && ! -z "$PREVIOUS_ANDROID" ]]; then |
199 | | - printf -v NATIVE_UPDATES '%sANDROID_UPDATE=true\nANDROID_FROM=%s\nANDROID_TO=%s\n' "$NATIVE_UPDATES" "$PREVIOUS_ANDROID" "$ANDROID_VERSION" |
200 | | - fi |
201 | | -
|
202 | | - if [[ "$IOS_VERSION" != "$PREVIOUS_IOS" && ! -z "$PREVIOUS_IOS" ]]; then |
203 | | - printf -v NATIVE_UPDATES '%sIOS_UPDATE=true\nIOS_FROM=%s\nIOS_TO=%s\n' "$NATIVE_UPDATES" "$PREVIOUS_IOS" "$IOS_VERSION" |
| 58 | + if [[ -n "$POSTFIX" ]]; then |
| 59 | + ./composeRelease.sh "$BUMP_COMMAND" "$POSTFIX" || echo "composeRelease.sh failed, continuing to patch manually" |
| 60 | + else |
| 61 | + ./composeRelease.sh "$BUMP_COMMAND" || echo "composeRelease.sh failed, continuing to patch manually" |
204 | 62 | fi |
205 | 63 |
|
206 | | - # Output the variables |
207 | | - echo "$NATIVE_UPDATES" >> $GITHUB_OUTPUT |
208 | | -
|
209 | | - - name: Generate release notes |
210 | | - id: release_notes |
211 | | - uses: actions/github-script@v8 |
212 | | - with: |
213 | | - script: | |
214 | | - // Trim whitespace from PR titles |
215 | | - const prs = JSON.parse('${{ steps.get_prs.outputs.prs }}').map(pr => ({ |
216 | | - ...pr, |
217 | | - title: pr.title.trim() |
218 | | - })); |
219 | | -
|
220 | | - // Categorize PRs |
221 | | - const features = prs.filter(pr => /^feat/i.test(pr.title)); |
222 | | - const fixes = prs.filter(pr => /^fix/i.test(pr.title)); |
223 | | - const improvements = prs.filter(pr => /^(perf|refactor|chore)/i.test(pr.title)); |
224 | | -
|
225 | | - // Helper function to build section |
226 | | - const buildSection = (title, prs) => { |
227 | | - if (prs.length === 0) return ''; |
228 | | - let section = `### ${title}\n\n`; |
229 | | - prs.forEach(pr => { |
230 | | - section += `- ${pr.title} (#${pr.number})\n`; |
231 | | - }); |
232 | | - return section + '\n'; |
233 | | - }; |
234 | | -
|
235 | | - let releaseNotes = `Channels: ${{ inputs.release-type }}\n\n`; |
236 | | - releaseNotes += buildSection('🚀 New Features', features); |
237 | | - releaseNotes += buildSection('🐛 Bug Fixes', fixes); |
238 | | - releaseNotes += buildSection('✨ Improvements', improvements); |
239 | | -
|
240 | | - // Check for native dependency changes |
241 | | - const hasAndroidUpdate = '${{ steps.native_deps.outputs.ANDROID_UPDATE }}' === 'true'; |
242 | | - const hasIosUpdate = '${{ steps.native_deps.outputs.IOS_UPDATE }}' === 'true'; |
243 | | -
|
244 | | - if (hasAndroidUpdate || hasIosUpdate) { |
245 | | - releaseNotes += '\n### 🛠️ Native Dependency Updates\n\n'; |
246 | | - if (hasAndroidUpdate) { |
247 | | - releaseNotes += `- Update Android SDK from ${{ steps.native_deps.outputs.ANDROID_FROM }} to ${{ steps.native_deps.outputs.ANDROID_TO }}\n`; |
248 | | - releaseNotes += `- See [release notes](https://github.com/OneSignal/OneSignal-Android-SDK/releases) for full details\n`; |
249 | | - } |
250 | | - if (hasIosUpdate) { |
251 | | - releaseNotes += `- Update iOS SDK from ${{ steps.native_deps.outputs.IOS_FROM }} to ${{ steps.native_deps.outputs.IOS_TO }}\n`; |
252 | | - releaseNotes += `- See [release notes](https://github.com/OneSignal/OneSignal-iOS-SDK/releases) for full details\n`; |
253 | | - } |
254 | | - releaseNotes += '\n'; |
255 | | - } |
256 | | -
|
257 | | - core.setOutput('notes', releaseNotes); |
258 | | -
|
259 | | - - name: Create release PR |
| 64 | + - name: 🔍 Confirm PR Exists |
260 | 65 | run: | |
261 | | - NEW_VERSION="${{ steps.new_version.outputs.version }}" |
262 | | -
|
263 | | - # Write release notes to file to avoid shell interpretation |
264 | | - cat > release_notes.md << 'EOF' |
265 | | - ${{ steps.release_notes.outputs.notes }} |
266 | | - EOF |
267 | | -
|
268 | | - gh pr create \ |
269 | | - --title "Release $NEW_VERSION" \ |
270 | | - --body-file release_notes.md \ |
271 | | - --base main \ |
272 | | - --reviewer jkasten2 |
| 66 | + PR_URL=$(gh pr list --head "release/$VERSION" --json url --jq '.[0].url') |
| 67 | + if [[ -n "$PR_URL" ]]; then |
| 68 | + echo "✅ Release PR found: $PR_URL" |
| 69 | + else |
| 70 | + echo "⚠️ No PR found. composeRelease.sh should have created one." |
| 71 | + echo "If missing, create manually from release/$VERSION → main." |
| 72 | + fi |
0 commit comments