Sync Upstream #23
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
| name: Sync Upstream | |
| on: | |
| schedule: | |
| - cron: '20 16 * * *' # UTC 16:20 = Beijing 00:20, daily | |
| workflow_dispatch: | |
| jobs: | |
| sync: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| actions: write | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Configure Git | |
| run: | | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| - name: Add upstream and fetch | |
| run: | | |
| git remote add upstream https://github.com/openai/codex.git || true | |
| git fetch upstream main | |
| - name: Check for updates | |
| id: check | |
| run: | | |
| LOCAL=$(git rev-parse HEAD) | |
| UPSTREAM=$(git rev-parse upstream/main) | |
| if [ "$LOCAL" = "$UPSTREAM" ]; then | |
| echo "No updates from upstream" | |
| echo "has_updates=false" >> $GITHUB_OUTPUT | |
| else | |
| echo "Upstream has new commits" | |
| echo "has_updates=true" >> $GITHUB_OUTPUT | |
| fi | |
| - name: Attempt merge | |
| id: merge | |
| if: steps.check.outputs.has_updates == 'true' | |
| run: | | |
| # Files that should always keep our version (ours strategy) | |
| OURS_FILES=( | |
| "codex-rs/common/src/model_presets.rs" | |
| ) | |
| if git merge upstream/main --no-edit; then | |
| echo "status=success" >> $GITHUB_OUTPUT | |
| git push origin main | |
| else | |
| echo "Merge conflict detected, attempting auto-resolution..." | |
| # Get list of conflicted files | |
| CONFLICTED=$(git diff --name-only --diff-filter=U) | |
| UNRESOLVED="" | |
| for file in $CONFLICTED; do | |
| KEEP_OURS=false | |
| for ours_file in "${OURS_FILES[@]}"; do | |
| if [ "$file" = "$ours_file" ]; then | |
| KEEP_OURS=true | |
| break | |
| fi | |
| done | |
| if [ "$KEEP_OURS" = true ]; then | |
| echo "Auto-resolving conflict in $file (keeping ours)" | |
| git checkout --ours "$file" | |
| git add "$file" | |
| else | |
| UNRESOLVED="$UNRESOLVED $file" | |
| fi | |
| done | |
| # Check if all conflicts are resolved | |
| REMAINING=$(git diff --name-only --diff-filter=U) | |
| if [ -z "$REMAINING" ]; then | |
| echo "All conflicts auto-resolved" | |
| git commit --no-edit | |
| echo "status=success" >> $GITHUB_OUTPUT | |
| git push origin main | |
| else | |
| echo "Unresolved conflicts remain: $REMAINING" | |
| echo "status=conflict" >> $GITHUB_OUTPUT | |
| git merge --abort | |
| fi | |
| fi | |
| - name: Create PR on conflict | |
| if: steps.merge.outputs.status == 'conflict' | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| BRANCH="sync/upstream-$(date +%Y-%m-%d)" | |
| git checkout -b "$BRANCH" | |
| git merge upstream/main --no-commit || true | |
| git add -A | |
| git commit -m "chore: sync upstream (conflicts need resolution)" || true | |
| git push -u origin "$BRANCH" --force | |
| # Check if PR already exists | |
| EXISTING_PR=$(gh pr list --head "$BRANCH" --json number --jq '.[0].number') | |
| if [ -z "$EXISTING_PR" ]; then | |
| gh pr create \ | |
| --title "🔄 Sync upstream $(date +%Y-%m-%d) - CONFLICTS" \ | |
| --body "自动同步上游更新时发现冲突,需要手动解决。 | |
| ## 冲突文件 | |
| 请检查并解决以下冲突后合并此 PR。 | |
| --- | |
| *This PR was automatically created by the sync-upstream workflow.*" \ | |
| --head "$BRANCH" \ | |
| --base main | |
| else | |
| echo "PR #$EXISTING_PR already exists for branch $BRANCH" | |
| fi | |
| - name: Trigger release on success | |
| if: steps.merge.outputs.status == 'success' | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| gh workflow run 88code-release.yml --repo ${{ github.repository }} |