From be544077294745b997433f7e654c6edfddf807a2 Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Tue, 6 Oct 2026 13:25:06 -0400 Subject: [PATCH] ci: adds branches auto-sync workflows Signed-off-by: Vincent Biret --- .github/workflows/sync-dev-to-vX.Y-dev.yaml | 77 +++++++++++++++++++++ .github/workflows/sync-main-to-dev.yaml | 67 ++++++++++++++++++ 2 files changed, 144 insertions(+) create mode 100644 .github/workflows/sync-dev-to-vX.Y-dev.yaml create mode 100644 .github/workflows/sync-main-to-dev.yaml diff --git a/.github/workflows/sync-dev-to-vX.Y-dev.yaml b/.github/workflows/sync-dev-to-vX.Y-dev.yaml new file mode 100644 index 0000000..de6a1f1 --- /dev/null +++ b/.github/workflows/sync-dev-to-vX.Y-dev.yaml @@ -0,0 +1,77 @@ +name: sync-dev-to-vX.Y-dev + +# author: @ralfhandl + +# +# This workflow creates PRs to update the vX.Y-dev branch with the latest changes from dev +# + +# run this on push to dev +on: + push: + branches: + - dev + workflow_dispatch: {} + +jobs: + sync-branches: + if: github.repository == 'OAI/Overlay-Specification' + runs-on: ubuntu-latest + steps: + - name: Generate access token + id: generate-token + uses: actions/create-github-app-token@v3 + with: + client-id: ${{ secrets.OAI_SPEC_PUBLISHER_APPID }} + private-key: ${{ secrets.OAI_SPEC_PUBLISHER_PRIVATE_KEY }} + + - name: Checkout repository + uses: actions/checkout@v7 + with: + fetch-depth: 0 + token: ${{ steps.generate-token.outputs.token }} + + - name: Create pull requests + id: pull_requests + shell: bash + run: | + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + + DEV_BRANCHES=$(git branch -r --list origin/v?.?-dev) + for DEV_BRANCH in $DEV_BRANCHES; do + BASE=${DEV_BRANCH:7} + SYNC="$BASE-sync-with-$HEAD" + + git checkout -b $SYNC origin/$SYNC || git checkout -b $SYNC origin/$BASE + git merge origin/$HEAD -m "Merge $HEAD into $SYNC" + git checkout origin/$BASE src/ + # exclude mjs files because we want to sync from the head + # neutralizes non-zero exit code because an empty selection result returns 1 + git checkout origin/$BASE -- tests/schema/ ':!*.mjs' || echo "" + # Preserve the destination branch's schema test runner. + git checkout "origin/$BASE" -- tests/schema/schema.test.mjs + git commit -m "Restored src/ and tests/schema/" || echo "" + git push -u origin $SYNC + + EXISTS=$(gh pr list --base $BASE --head $SYNC \ + --json number --jq '.[] | .number') + if [ ! -z "$EXISTS" ]; then + echo "PR #$EXISTS already wants to merge $SYNC into $BASE" + continue + fi + + PR=$(gh pr create --base $BASE --head $SYNC \ + --label "Housekeeping" \ + --title "$BASE: sync with $HEAD" \ + --body "Merge relevant changes from \`$HEAD\` into \`$BASE\`.") + echo "" + echo "PR to sync $BASE with $HEAD: $PR" + sleep 60 # allow status checks to be triggered + + gh pr checks $PR --watch --required || continue + gh pr merge $PR --merge --admin + done + env: + GH_TOKEN: ${{ steps.generate-token.outputs.token }} + HEAD: dev diff --git a/.github/workflows/sync-main-to-dev.yaml b/.github/workflows/sync-main-to-dev.yaml new file mode 100644 index 0000000..647bdad --- /dev/null +++ b/.github/workflows/sync-main-to-dev.yaml @@ -0,0 +1,67 @@ +name: sync-main-to-dev + +# author: @ralfhandl + +# +# This workflow creates PRs to update the dev branch with the latest changes from main +# + +# run this on push to main +on: + push: + branches: + - main + workflow_dispatch: {} + +jobs: + sync-branch: + if: github.repository == 'OAI/Overlay-Specification' + runs-on: ubuntu-latest + steps: + - name: Generate access token + id: generate-token + uses: actions/create-github-app-token@v3 + with: + client-id: ${{ secrets.OAI_SPEC_PUBLISHER_APPID }} + private-key: ${{ secrets.OAI_SPEC_PUBLISHER_PRIVATE_KEY }} + + - name: Checkout repository + uses: actions/checkout@v7 + with: + fetch-depth: 0 + token: ${{ steps.generate-token.outputs.token }} + + - name: Create pull request + id: pull_request + shell: bash + run: | + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + SYNC="$BASE-sync-with-$HEAD" + + git checkout -b $SYNC origin/$SYNC || git checkout -b $SYNC origin/$BASE + git merge origin/$HEAD -m "Merge $HEAD into $SYNC" + git checkout origin/$BASE src/ + # exclude mjs files because we want to sync from the head + # neutralizes non-zero exit code because an empty selection result returns 1 + git checkout origin/$BASE -- tests/schema/ ':!*.mjs' || echo "" + # Preserve the destination branch's schema test runner. + git checkout "origin/$BASE" -- tests/schema/schema.test.mjs + git commit -m "Restored src/ and tests/schema/" || echo "" + git push -u origin $SYNC + + EXISTS=$(gh pr list --base $BASE --head $SYNC \ + --json number --jq '.[] | .number') + if [ ! -z "$EXISTS" ]; then + echo "PR #$EXISTS already wants to merge $SYNC into $BASE" + exit 0 + fi + + gh pr create --base $BASE --head $SYNC \ + --label "Housekeeping" \ + --title "$BASE: sync with $HEAD" \ + --body "Merge relevant changes from \`$HEAD\` into \`$BASE\`." + env: + GH_TOKEN: ${{ steps.generate-token.outputs.token }} + HEAD: main + BASE: dev