diff --git a/.github/workflows/backmerge-pr.yaml b/.github/workflows/backmerge-pr.yaml index f21a5a30..868a7689 100644 --- a/.github/workflows/backmerge-pr.yaml +++ b/.github/workflows/backmerge-pr.yaml @@ -1,8 +1,7 @@ # This workflow creates a backmerge PR into `develop` whenever a new version tag is pushed (v*). # # Key points: -# - The PR head is a temporary branch that points at the *tag commit* (refs/tags/vX.Y.Z). -# After merging, `develop` can `git describe` as vX.Y.Z-... because the tag commit becomes an ancestor. +# - Creates a PR from `master` to `develop` when a new tag is pushed. # - The PR is auto-merged using a MERGE COMMIT (not squash) via a GitHub App token. # The GitHub App must be added to the develop ruleset bypass list. # @@ -12,7 +11,7 @@ # - Actions secret: ES_BACKMERGE_PRIVATE_KEY (GitHub App private key PEM) # - Actions variable: ES_BACKMERGE_APP_ID (GitHub App ID) -name: Backmerge PR (tag -> develop) +name: Backmerge PR (master -> develop) on: push: @@ -34,56 +33,42 @@ jobs: app-id: ${{ vars.BACKMERGE_APP_ID }} private-key: ${{ secrets.BACKMERGE_PRIVATE_KEY }} - - name: Checkout tag commit + - name: Checkout repository uses: actions/checkout@v5 with: - ref: ${{ github.ref }} # refs/tags/vX.Y.Z fetch-depth: 0 token: ${{ steps.app-token.outputs.token }} - - name: Create and push backmerge branch at tag - id: vars + - name: Create PR from master to develop (or reuse if exists) + id: pr run: | set -euo pipefail TAG='${{ github.ref_name }}' - BRANCH="backmerge/${TAG}" - echo "tag=${TAG}" >> "$GITHUB_OUTPUT" - echo "branch=${BRANCH}" >> "$GITHUB_OUTPUT" + TITLE="Backmerge: ${TAG} from master into develop" - git config user.name "github-actions[bot]" - git config user.email "github-actions[bot]@users.noreply.github.com" + BODY="⚠️ This PR is created automatically for backmerge of the release tag \`${TAG}\` from \`master\` into \`develop\`. - # Create/move branch to point exactly at the tag commit - git checkout -B "$BRANCH" + It is labeled \`[maintainer] auto-pull-request\` and is excluded from release notes and version bump logic." - # Push (force makes re-runs idempotent for the same tag) - git push --force --set-upstream origin "$BRANCH" - env: - GITHUB_TOKEN: ${{ steps.app-token.outputs.token }} - - - name: - Create PR from tag backmerge branch to develop (or reuse if exists) - run: | - set -euo pipefail - - TITLE="Backmerge: ${{ steps.vars.outputs.tag }} into develop" - - BODY="⚠️ This PR is created automatically for backmerge of a new release tag commit \`${{ steps.vars.outputs.tag }}\` into \`develop\`. - - It is labeled `[maintainer] auto-pull-request` and is excluded from release notes and version bump logic." + # Check if a PR from master to develop already exists + EXISTING_PR=$(gh pr list --repo "${{ github.repository }}" --base develop --head master --state open --json number --jq '.[0].number // empty') - if gh pr view --repo "${{ github.repository }}" --head "${{ steps.vars.outputs.branch }}" >/dev/null 2>&1; then - echo "PR already exists for head=${{ steps.vars.outputs.branch }}" + if [ -n "$EXISTING_PR" ]; then + echo "PR #${EXISTING_PR} already exists for master -> develop" + echo "pr_number=${EXISTING_PR}" >> "$GITHUB_OUTPUT" else - gh pr create \ + PR_URL=$(gh pr create \ --repo "${{ github.repository }}" \ --base develop \ - --head "${{ steps.vars.outputs.branch }}" \ + --head master \ --title "$TITLE" \ --label "[maintainer] auto-pull-request" \ - --body "$BODY" + --body "$BODY") + PR_NUMBER=$(echo "$PR_URL" | grep -oE '[0-9]+$') + echo "Created PR #${PR_NUMBER}" + echo "pr_number=${PR_NUMBER}" >> "$GITHUB_OUTPUT" fi env: GH_TOKEN: ${{ steps.app-token.outputs.token }} @@ -91,7 +76,6 @@ jobs: - name: Enable auto-merge using MERGE COMMIT run: | set -euo pipefail - # Merge the PR identified by its head branch. - gh pr merge --repo "${{ github.repository }}" --merge --auto "${{ steps.vars.outputs.branch }}" + gh pr merge --repo "${{ github.repository }}" --merge --auto "${{ steps.pr.outputs.pr_number }}" env: GH_TOKEN: ${{ steps.app-token.outputs.token }} diff --git a/src/easydiffraction/utils/logging.py b/src/easydiffraction/utils/logging.py index 4ed83d36..b56f4a53 100644 --- a/src/easydiffraction/utils/logging.py +++ b/src/easydiffraction/utils/logging.py @@ -555,7 +555,7 @@ def section(cls, title: str) -> None: """Formats a section header with bold green text.""" full_title = f'{title.upper()}' line = '━' * len(full_title) - formatted = f'[bold green]{full_title}\n{line}[/bold green]' + formatted = f'[bold green]\n{line}\n{full_title}\n{line}[/bold green]' if not in_jupyter(): formatted = f'\n{formatted}' cls._console.print(formatted) diff --git a/tools/tweak_notebooks.py b/tools/tweak_notebooks.py index 91a24e1f..bcc95df9 100644 --- a/tools/tweak_notebooks.py +++ b/tools/tweak_notebooks.py @@ -53,7 +53,7 @@ def _get_bootstrap_source() -> str: '\n' "if (hasattr(builtins, '__IPYTHON__') and\n" " importlib.util.find_spec('easydiffraction') is None):\n" - f" !pip install '{pip_specifier}'\n" + f" !pip install '{pip_specifier}'" )