diff --git a/.github/workflows/sync-next-with-main.yml b/.github/workflows/sync-next-with-main.yml deleted file mode 100644 index ef194545..00000000 --- a/.github/workflows/sync-next-with-main.yml +++ /dev/null @@ -1,193 +0,0 @@ -name: Sync next with main - -on: - push: - branches: - - main - schedule: - # Daily at 09:00 UTC. Catches release commits (`[skip ci]`) that don't - # trigger workflows via push, and any drift the push trigger missed. - - cron: '0 9 * * *' - workflow_dispatch: - -permissions: - contents: read - -concurrency: - group: ${{ github.workflow }} - cancel-in-progress: true - -env: - SYNC_BRANCH: chore/sync-main-into-next - SYNC_PR_TITLE: 'chore: merge main into next' - -jobs: - sync: - name: Sync - runs-on: ubuntu-latest - timeout-minutes: 10 - - steps: - - name: Generate bot token - id: generate_token - uses: actions/create-github-app-token@v3 - with: - app-id: ${{ secrets.DOIST_RELEASE_BOT_ID }} - private-key: ${{ secrets.DOIST_RELEASE_BOT_PRIVATE_KEY }} - permission-contents: write - permission-pull-requests: write - - - name: Get bot user ID - id: bot_user - run: | - user_id=$(gh api "/users/${{ steps.generate_token.outputs.app-slug }}[bot]" --jq .id) - if [ -z "$user_id" ]; then - echo "Failed to get bot user ID" >&2 - exit 1 - fi - echo "id=$user_id" >> "$GITHUB_OUTPUT" - env: - GH_TOKEN: ${{ steps.generate_token.outputs.token }} - - - name: Checkout next - uses: actions/checkout@v4 - with: - ref: next - token: ${{ steps.generate_token.outputs.token }} - fetch-depth: 0 - - - name: Configure git - run: | - git config user.name "${{ steps.generate_token.outputs.app-slug }}[bot]" - git config user.email "${{ steps.bot_user.outputs.id }}+${{ steps.generate_token.outputs.app-slug }}[bot]@users.noreply.github.com" - - - name: Check if main is ahead of next - id: divergence - run: | - ahead=$(git rev-list --count next..origin/main) - echo "ahead=$ahead" >> "$GITHUB_OUTPUT" - if [ "$ahead" -eq 0 ]; then - echo "next is up to date with main; nothing to do" - else - echo "main is $ahead commit(s) ahead of next" - fi - - - name: Check existing sync branch - id: existing_sync - if: steps.divergence.outputs.ahead != '0' - run: | - next_sha=$(git rev-parse origin/next) - main_sha=$(git rev-parse origin/main) - expected_email="${{ steps.bot_user.outputs.id }}+${{ steps.generate_token.outputs.app-slug }}[bot]@users.noreply.github.com" - - if ! git ls-remote --exit-code --heads origin "$SYNC_BRANCH" >/dev/null; then - echo "No existing $SYNC_BRANCH on origin; will create." - echo "should_sync=true" >> "$GITHUB_OUTPUT" - exit 0 - fi - - git fetch --no-tags origin "$SYNC_BRANCH:refs/remotes/origin/$SYNC_BRANCH" - head_sha=$(git rev-parse "refs/remotes/origin/$SYNC_BRANCH") - p1=$(git rev-parse "$head_sha^1" 2>/dev/null || echo "") - p2=$(git rev-parse "$head_sha^2" 2>/dev/null || echo "") - head_email=$(git log -1 --format='%ae' "$head_sha") - - if [ "$p1" = "$next_sha" ] && [ "$p2" = "$main_sha" ]; then - echo "$SYNC_BRANCH already merges current next and main; nothing to do." - echo "should_sync=false" >> "$GITHUB_OUTPUT" - exit 0 - fi - - if [ "$head_email" != "$expected_email" ]; then - echo "$SYNC_BRANCH HEAD authored by $head_email (not the bot); refusing to overwrite." - echo "should_sync=false" >> "$GITHUB_OUTPUT" - exit 0 - fi - - echo "$SYNC_BRANCH is bot-owned but stale; will refresh." - echo "should_sync=true" >> "$GITHUB_OUTPUT" - - - name: Create sync branch - if: steps.existing_sync.outputs.should_sync == 'true' - run: git checkout -B "$SYNC_BRANCH" - - - name: Attempt merge - if: steps.existing_sync.outputs.should_sync == 'true' - id: merge - run: | - if git merge --no-ff origin/main -m "$SYNC_PR_TITLE"; then - echo "status=clean" >> "$GITHUB_OUTPUT" - { - echo "conflicts<> "$GITHUB_OUTPUT" - else - conflicts=$(git diff --name-only --diff-filter=U | sed 's/^/- `/; s/$/`/') - git add -A - git commit -m "$SYNC_PR_TITLE (conflicts to resolve)" - echo "status=conflicts" >> "$GITHUB_OUTPUT" - { - echo "conflicts<> "$GITHUB_OUTPUT" - fi - - - name: Push sync branch - if: steps.existing_sync.outputs.should_sync == 'true' - run: git push --force origin "$SYNC_BRANCH" - - - name: Open or update PR - if: steps.existing_sync.outputs.should_sync == 'true' - env: - GH_TOKEN: ${{ steps.generate_token.outputs.token }} - MERGE_STATUS: ${{ steps.merge.outputs.status }} - CONFLICTS: ${{ steps.merge.outputs.conflicts }} - run: | - if [ "$MERGE_STATUS" = "clean" ]; then - cat > /tmp/pr-body.md <<'EOF' - Automated sync of `main` into `next`. - - The merge applied cleanly. Standard CI (Tests, Lint, Skill Sync) will validate against the merged tree. - - Once green and reviewed, merge this to publish a new `…-next.N` prerelease. - EOF - else - cat > /tmp/pr-body.md <