diff --git a/.github/workflows/weekly-branch-promotions.yml b/.github/workflows/weekly-branch-promotions.yml new file mode 100644 index 0000000..7b1a8c4 --- /dev/null +++ b/.github/workflows/weekly-branch-promotions.yml @@ -0,0 +1,69 @@ +name: 🔁 Weekly Branch Promotions + +on: + schedule: + - cron: "0 6 * * 1" + workflow_dispatch: + +permissions: + contents: read + pull-requests: write + +concurrency: + group: weekly-branch-promotions + cancel-in-progress: false + +jobs: + open-promotion-pr: + name: Open ${{ matrix.head }} → ${{ matrix.base }} + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + include: + - head: develop + base: design + title: "chore: merge develop into design" + - head: design + base: main + title: "chore: merge design into main" + + steps: + - name: ⬇️ Checkout + uses: actions/checkout@v6 + with: + fetch-depth: 0 + + - name: 🔁 Open promotion PR + env: + GH_TOKEN: ${{ github.token }} + BASE_BRANCH: ${{ matrix.base }} + HEAD_BRANCH: ${{ matrix.head }} + PR_TITLE: ${{ matrix.title }} + run: | + set -euo pipefail + + git fetch origin "$BASE_BRANCH" "$HEAD_BRANCH" + + if git merge-base --is-ancestor "origin/$HEAD_BRANCH" "origin/$BASE_BRANCH"; then + echo "No promotion needed: $BASE_BRANCH already contains $HEAD_BRANCH." + exit 0 + fi + + existing_pr="$(gh pr list \ + --state open \ + --base "$BASE_BRANCH" \ + --head "$GITHUB_REPOSITORY_OWNER:$HEAD_BRANCH" \ + --json number \ + --jq '.[0].number // empty')" + + if [ -n "$existing_pr" ]; then + echo "Promotion PR already open: #$existing_pr." + exit 0 + fi + + gh pr create \ + --base "$BASE_BRANCH" \ + --head "$HEAD_BRANCH" \ + --title "$PR_TITLE" \ + --body "Automated weekly promotion PR from \`$HEAD_BRANCH\` to \`$BASE_BRANCH\`."