Update Scribe #4
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
| # Keep Scriptorium on the newest Scribe. | |
| # | |
| # A git submodule pins one exact commit, which is what makes a Scriptorium | |
| # checkout reproducible — but it also means Scribe moving forward does not move | |
| # Scriptorium. This job does the moving: weekly (or on demand) it bumps | |
| # lib/scribe to the tip of Scribe's main and opens a PR with the intervening | |
| # Scribe commits in the body, so the bump is reviewed rather than silent. | |
| # | |
| # Note on CI: the PR is opened with the built-in GITHUB_TOKEN, and GitHub does | |
| # not fire `push` / `pull_request` workflow events for anything that token | |
| # creates. No test workflow exists in this repo today, so nothing is missed — | |
| # but if one is added, it will NOT run on these auto-generated PRs. Swap in a | |
| # PAT or GitHub App token at that point if you want checks on them. | |
| # | |
| # To bump by hand instead, run scripts/update-scribe.sh. | |
| name: Update Scribe | |
| on: | |
| schedule: | |
| # Mondays, 06:00 UTC. | |
| - cron: '0 6 * * 1' | |
| workflow_dispatch: | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| concurrency: | |
| group: update-scribe | |
| cancel-in-progress: false | |
| jobs: | |
| bump: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Check out Scriptorium (with submodules) | |
| uses: actions/checkout@v4 | |
| with: | |
| submodules: recursive | |
| - name: Bump lib/scribe to the tip of Scribe main | |
| id: bump | |
| run: | | |
| before="$(git -C lib/scribe rev-parse HEAD)" | |
| git -C lib/scribe fetch --quiet origin main | |
| after="$(git -C lib/scribe rev-parse FETCH_HEAD)" | |
| if [ "$before" = "$after" ]; then | |
| echo "Already on the newest Scribe ($(git -C lib/scribe log -1 --format=%h))." | |
| echo "changed=no" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| # The pin can sit ahead of main (e.g. it points at a Scribe branch | |
| # whose PR has not merged). Bumping would be a downgrade. | |
| if git -C lib/scribe merge-base --is-ancestor "$after" "$before"; then | |
| echo "The pinned Scribe is ahead of main — nothing to bump." | |
| echo "changed=no" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| # Diverged: moving to main's tip would drop the commits unique to the | |
| # pinned revision. Fail loudly rather than open a regression PR. | |
| if ! git -C lib/scribe merge-base --is-ancestor "$before" "$after"; then | |
| echo "::error::Scribe main has diverged from the pinned revision;" \ | |
| "pinned-only $(git -C lib/scribe rev-list --count "$after..$before")," \ | |
| "main-only $(git -C lib/scribe rev-list --count "$before..$after")." \ | |
| "Refusing to bump — resolve upstream first." | |
| exit 1 | |
| fi | |
| git -C lib/scribe log --oneline --no-decorate "$before..$after" > /tmp/scribe-log.txt | |
| git -C lib/scribe checkout --quiet --detach "$after" | |
| { | |
| echo "changed=yes" | |
| echo "before=$(git -C lib/scribe rev-parse --short "$before")" | |
| echo "after=$(git -C lib/scribe rev-parse --short "$after")" | |
| } >> "$GITHUB_OUTPUT" | |
| - name: Open a pull request | |
| if: steps.bump.outputs.changed == 'yes' | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| BEFORE: ${{ steps.bump.outputs.before }} | |
| AFTER: ${{ steps.bump.outputs.after }} | |
| run: | | |
| branch="chore/update-scribe-$AFTER" | |
| # A later run sees the same AFTER while the previous PR is still open, | |
| # and would push a branch that already exists. If a PR for it is open, | |
| # this run has nothing to add. If the branch exists with no open PR it | |
| # is stale (PR closed, or a run that died before opening one), so it is | |
| # safe to replace. | |
| if [ -n "$(gh pr list --head "$branch" --state open --json number --jq '.[].number')" ]; then | |
| echo "PR already open for $branch — nothing to do." | |
| exit 0 | |
| fi | |
| force="" | |
| if git ls-remote --exit-code --heads origin "$branch" >/dev/null 2>&1; then | |
| echo "Stale $branch with no open PR — replacing it." | |
| force="--force-with-lease" | |
| fi | |
| git config user.name "github-actions[bot]" | |
| git config user.email "41898282+github-actions[bot]@users.noreply.github.com" | |
| git checkout -b "$branch" | |
| git add lib/scribe | |
| git commit -m "chore(scribe): update lib/scribe to $AFTER" | |
| # shellcheck disable=SC2086 | |
| git push -u $force origin "$branch" | |
| { | |
| echo "Bumps the \`lib/scribe\` submodule from \`$BEFORE\` to \`$AFTER\`." | |
| echo | |
| echo "Scribe commits picked up:" | |
| echo | |
| echo '```' | |
| cat /tmp/scribe-log.txt | |
| echo '```' | |
| echo | |
| echo "Opened automatically by \`.github/workflows/update-scribe.yml\`." | |
| echo "Review Scribe's changes and run the Scriptorium suites before merging." | |
| } > /tmp/pr-body.md | |
| gh pr create \ | |
| --title "chore(scribe): update lib/scribe to $AFTER" \ | |
| --body-file /tmp/pr-body.md \ | |
| --base main \ | |
| --head "$branch" |