Skip to main content
Glama
sync-develop.yml8.63 kB
name: Sync main → develop on: pull_request: types: [closed] branches: [main] workflow_dispatch: inputs: head_branch: description: "Branch to merge FROM (default: main)." required: false default: "main" base_branch: description: "Branch to merge INTO (default: develop)." required: false default: "develop" source_pr_number: description: "If testing, the PR number to comment on (optional)." required: false test_mode: description: "Bypass PR/push guards for manual testing" required: false default: "true" permissions: contents: write pull-requests: write issues: write concurrency: group: sync-main-into-develop cancel-in-progress: false jobs: open-sync-pr: if: | github.actor != 'github-actions[bot]' && ( ( github.event_name == 'pull_request' && github.event.pull_request.merged == true ) || ( github.event_name == 'workflow_dispatch' && (inputs.test_mode == 'true') ) ) runs-on: ubuntu-latest env: # Use inputs for dispatch (testing), defaults for normal triggers HEAD_BRANCH: ${{ (github.event_name == 'workflow_dispatch' && inputs.head_branch) || 'main' }} BASE_BRANCH: ${{ (github.event_name == 'workflow_dispatch' && inputs.base_branch) || 'develop' }} SOURCE_PR: ${{ (github.event_name == 'pull_request' && github.event.pull_request.number) || inputs.source_pr_number || '' }} GH_TOKEN: ${{ secrets.GH_PAT }} steps: - uses: actions/checkout@v5 with: fetch-depth: 0 token: ${{ secrets.GH_PAT }} - name: Configure git author run: | git config --local user.name "Apollo Bot" git config --local user.email "svc-apollo-bot-2@apollographql.com" # Generate branch name from PR# when available, otherwise use first 7 commit SHA characters - name: Compute branch/name metadata id: meta run: | pr=${{ github.event.pull_request.number }} echo "sync_branch=sync/main-into-develop-pr-${pr}" >> $GITHUB_OUTPUT echo "sync_title=Sync main → develop (PR #${pr})" >> $GITHUB_OUTPUT echo "sync_body=Auto-opened after merging \`${{ github.event.pull_request.head.ref }}\` into \`main\`. Source PR: #${pr}." >> $GITHUB_OUTPUT echo "conflict_branch=conflict/main-into-develop-pr-${pr}" >> $GITHUB_OUTPUT echo "conflict_title=Sync main → develop (resolve conflicts)" >> $GITHUB_OUTPUT echo "conflict_body=Opened from a copy of \`main\` so conflicts can be resolved without pushing to a protected branch." >> $GITHUB_OUTPUT # Short-lived sync branch from develop and merge main into it (do NOT rebase) # use +e to stop errors from short-circuiting the script - name: Prepare sync branch id: prep run: | set -e git fetch origin "${BASE_BRANCH}" "${HEAD_BRANCH}" git switch -c "${{ steps.meta.outputs.sync_branch }}" "origin/${BASE_BRANCH}" set +e git merge --no-ff "origin/${HEAD_BRANCH}" rc=$? set -e git add -A || true git commit -m "WIP: merge ${HEAD_BRANCH} into ${BASE_BRANCH} via ${{ steps.meta.outputs.branch }}" || true git push origin HEAD right=$(git rev-list --count --right-only "origin/${BASE_BRANCH}...HEAD") echo "merge_status=$rc" >> "$GITHUB_OUTPUT" echo "sync_right=$right" >> "$GITHUB_OUTPUT" echo "Merge exit=$rc, sync branch ahead-by=$right" # If no merge conflicts and there are changes, open the PR targeting develop - name: Open clean PR to develop id: sync_pr if: ${{ steps.prep.outputs.merge_status == '0' && steps.prep.outputs.sync_right != '0' }} run: | # Avoid duplicate PRs existing=$(gh pr list --base "${BASE_BRANCH}" --head "${{ steps.meta.outputs.sync_branch }}" --state open --json number --jq '.[0].number' || true) if [ -n "$existing" ] && [ "$existing" != "null" ]; then echo "pr_number=$existing" >> "$GITHUB_OUTPUT" url=$(gh pr view "$existing" --json url --jq .url) echo "pr_url=$url" >> "$GITHUB_OUTPUT" exit 0 fi gh pr create \ --base "${BASE_BRANCH}" \ --head "${{ steps.meta.outputs.sync_branch }}" \ --title "${{ steps.meta.outputs.sync_title }}" \ --body "${{ steps.meta.outputs.sync_body }} (created via gh CLI)" \ --label back-merge \ --label skip-changeset \ --label automation # Fetch the newly created PR number, then its URL so that we display in a PR comment num=$(gh pr list --base "${BASE_BRANCH}" --head "${{ steps.meta.outputs.sync_branch }}" --state open --json number --jq '.[0].number') url=$(gh pr view "$num" --json url --jq .url) echo "pr_number=$num" >> "$GITHUB_OUTPUT" echo "pr_url=$url" >> "$GITHUB_OUTPUT" # If the merge hit conflicts, open a DIRECT PR: HEAD_BRANCH -> BASE_BRANCH so conflicts can be resolved prior to merge - name: Open conflict PR id: conflict_pr if: ${{ steps.prep.outputs.merge_status != '0' }} run: | set -e git fetch origin "${HEAD_BRANCH}" "${BASE_BRANCH}" git switch -c "${{ steps.meta.outputs.conflict_branch }}" "origin/${HEAD_BRANCH}" git push -u origin HEAD # Skip if no diff between conflict branch and base (should be unlikely) right=$(git rev-list --right-only --count "origin/${BASE_BRANCH}...origin/${{ steps.meta.outputs.conflict_branch }}") if [ "$right" -eq 0 ]; then echo "No diff between ${HEAD_BRANCH} and ${BASE_BRANCH}; nothing to open." exit 0 fi # Reuse existing open PR if present existing=$(gh pr list --base "${BASE_BRANCH}" --head "${{ steps.meta.outputs.conflict_branch }}" --state open --json number --jq '.[0].number' || true) if [ -n "$existing" ] && [ "$existing" != "null" ]; then echo "pr_number=$existing" >> "$GITHUB_OUTPUT" url=$(gh pr view "$existing" --json url --jq .url) echo "pr_url=$url" >> "$GITHUB_OUTPUT" exit 0 fi gh pr create \ --base "${BASE_BRANCH}" \ --head "${{ steps.meta.outputs.conflict_branch }}" \ --title "${{ steps.meta.outputs.conflict_title }}" \ --body "${{ steps.meta.outputs.conflict_body }}" \ --label back-merge \ --label automation \ --label skip-changeset \ --label conflicts # Fetch the newly created conflict PR number, then its URL so that we display in a PR comment num=$(gh pr list --base "${BASE_BRANCH}" --head "${{ steps.meta.outputs.conflict_branch }}" --state open --json number --jq '.[0].number') url=$(gh pr view "$num" --json url --jq .url) echo "pr_number=$num" >> "$GITHUB_OUTPUT" echo "pr_url=$url" >> "$GITHUB_OUTPUT" # Comment back on the ORIGINAL merged PR with a link to the sync PR - name: Comment on source PR with sync PR link if: ${{ env.SOURCE_PR != '' && (steps.sync_pr.outputs.pr_number != '' || steps.conflict_pr.outputs.pr_number != '') }} uses: actions/github-script@v7 with: script: | const owner = context.repo.owner; const repo = context.repo.repo; const issue_number = Number(process.env.SOURCE_PR); const hadConflicts = '${{ steps.prep.outputs.merge_status }}' !== '0'; const syncUrl = '${{ steps.sync_pr.outputs.pr_url || steps.conflict_pr.outputs.pr_url }}'; const head = process.env.HEAD_BRANCH; const base = process.env.BASE_BRANCH; const status = hadConflicts ? 'conflicts ❗' : 'clean ✅'; const note = hadConflicts ? 'Opened from a copy of main so conflicts can be resolved safely.' : 'Opened from a sync branch created off develop.'; const body = [ `Opened sync PR **${head} → ${base}**: ${syncUrl}`, ``, `Merge status: **${status}**`, note ].join('\n'); await github.rest.issues.createComment({ owner, repo, issue_number, body });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/apollographql/apollo-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server