🔄 Pre-Release Sync #1
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # This workflow syncs main into release before a release cycle. | |
| # Triggers: | |
| # - On demand (workflow_dispatch) | |
| # - Weekly at 3:00 AM IST on Friday (9:30 PM UTC on Thursday) | |
| name: 🔄 Pre-Release Sync | |
| on: | |
| workflow_dispatch: | |
| schedule: | |
| - cron: '30 21 * * 4' | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| env: | |
| SOURCE_BRANCH: "main" | |
| TARGET_BRANCH: "release" | |
| RELEASE_GIT_USER_NAME: "thunder-automation-bot" | |
| RELEASE_GIT_USER_EMAIL: "thunder-bot@wso2.com" | |
| jobs: | |
| sync-main-to-release: | |
| name: 🔀 Merge main -> release | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: 📥 Checkout Source Branch | |
| uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 | |
| with: | |
| fetch-depth: 0 | |
| token: ${{ secrets.THUNDER_AUTOMATION_BOT }} | |
| ref: ${{ env.SOURCE_BRANCH }} | |
| - name: 🔧 Configure Git | |
| run: | | |
| git config --local user.name "${{ env.RELEASE_GIT_USER_NAME }}" | |
| git config --local user.email "${{ env.RELEASE_GIT_USER_EMAIL }}" | |
| - name: 🌿 Create Release Branch if Missing | |
| run: | | |
| if git ls-remote --exit-code origin "${TARGET_BRANCH}" > /dev/null 2>&1; then | |
| echo "✅ Branch '${TARGET_BRANCH}' already exists on remote." | |
| else | |
| echo "🌱 Branch '${TARGET_BRANCH}' not found. Creating from '${SOURCE_BRANCH}'..." | |
| git checkout -b "${TARGET_BRANCH}" | |
| git push origin "${TARGET_BRANCH}" | |
| echo "✅ Created and pushed '${TARGET_BRANCH}' branch." | |
| fi | |
| - name: 🔄 Merge Source Branch into Target Branch | |
| id: merge_sync | |
| run: | | |
| set -euo pipefail | |
| git fetch origin "${SOURCE_BRANCH}" "${TARGET_BRANCH}" | |
| git checkout "${TARGET_BRANCH}" | |
| BEFORE_COMMIT=$(git rev-parse HEAD) | |
| if ! git merge --no-ff --no-edit "origin/${SOURCE_BRANCH}"; then | |
| echo "❌ Merge conflict detected while merging ${SOURCE_BRANCH} into ${TARGET_BRANCH}." | |
| git merge --abort || true | |
| echo "conflict_detected=true" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| echo "conflict_detected=false" >> "$GITHUB_OUTPUT" | |
| AFTER_COMMIT=$(git rev-parse HEAD) | |
| if [ "${BEFORE_COMMIT}" = "${AFTER_COMMIT}" ]; then | |
| echo "✅ ${TARGET_BRANCH} is already up to date with ${SOURCE_BRANCH}." | |
| exit 0 | |
| fi | |
| git push origin "HEAD:${TARGET_BRANCH}" | |
| echo "✅ Successfully merged ${SOURCE_BRANCH} into ${TARGET_BRANCH}." | |
| - name: 🔔 Create Sync PR for Conflict Resolution | |
| if: steps.merge_sync.outputs.conflict_detected == 'true' | |
| uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7 | |
| with: | |
| script: | | |
| const owner = context.repo.owner; | |
| const repo = context.repo.repo; | |
| const base = process.env.TARGET_BRANCH; | |
| const headBranch = process.env.SOURCE_BRANCH; | |
| const head = `${owner}:${headBranch}`; | |
| const existing = await github.rest.pulls.list({ | |
| owner, | |
| repo, | |
| state: 'open', | |
| base, | |
| head | |
| }); | |
| if (existing.data.length > 0) { | |
| const pr = existing.data[0]; | |
| core.info(`Existing sync PR found: #${pr.number} ${pr.html_url}`); | |
| return; | |
| } | |
| const created = await github.rest.pulls.create({ | |
| owner, | |
| repo, | |
| title: `Sync ${headBranch} into ${base}`, | |
| head: headBranch, | |
| base, | |
| body: [ | |
| 'Automated PR created because pre-release branch sync hit merge conflicts.', | |
| '', | |
| `Source branch: ${headBranch}`, | |
| `Target branch: ${base}`, | |
| '', | |
| `Workflow run: ${context.serverUrl}/${owner}/${repo}/actions/runs/${context.runId}` | |
| ].join('\n') | |
| }); | |
| core.info(`Created sync PR: #${created.data.number} ${created.data.html_url}`); | |
| - name: ❌ Fail Job on Merge Conflict | |
| if: steps.merge_sync.outputs.conflict_detected == 'true' | |
| run: | | |
| echo "❌ Merge conflict requires manual resolution via PR." | |
| exit 1 |