From 3dd402d53a6c460334854f3ab33bf525c1bcfdcd Mon Sep 17 00:00:00 2001 From: Joe Politz Date: Thu, 25 Jun 2026 12:04:45 -0700 Subject: [PATCH 1/2] Add monorepo-mirror Action: subtree-split code.pyret.org from pyret-lang Generates a flat, history-preserving mirror of the code.pyret.org/ subfolder of the brownplt/pyret-lang monorepo onto a new `monorepo-mirror` branch of this repo, so downstream forks (e.g. Bootstrap) can keep their pull/push/Deploy workflow once code.pyret.org moves into the monorepo. Manual-only (workflow_dispatch) to start; pushes via the built-in GITHUB_TOKEN, so no new secret is required. Co-Authored-By: Claude Opus 4.8 --- .github/workflows/monorepo-mirror.yml | 59 +++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 .github/workflows/monorepo-mirror.yml diff --git a/.github/workflows/monorepo-mirror.yml b/.github/workflows/monorepo-mirror.yml new file mode 100644 index 00000000..ba6cae64 --- /dev/null +++ b/.github/workflows/monorepo-mirror.yml @@ -0,0 +1,59 @@ +name: Mirror monorepo code.pyret.org subtree + +# Generates a flat, deployable mirror of the code.pyret.org/ subfolder of the +# brownplt/pyret-lang monorepo, with history preserved, on the +# `monorepo-mirror` branch of THIS repo. +# +# Runs in brownplt/code.pyret.org so it can push to a branch here using the +# built-in GITHUB_TOKEN -- no PAT or deploy key needed. The monorepo is public, +# so it is checked out read-only with that same token. +# +# Manual-only for now: trigger from the Actions tab and pick the source ref. +# Uncomment the `schedule` block below to run it automatically once this is +# trusted. + +on: + workflow_dispatch: + inputs: + source_ref: + description: "Branch/ref of brownplt/pyret-lang to mirror" + required: true + default: mainmast + # schedule: + # - cron: "0 7 * * *" # daily at 07:00 UTC + +permissions: + contents: write + +concurrency: + group: monorepo-mirror + cancel-in-progress: false + +jobs: + mirror: + runs-on: ubuntu-latest + steps: + - name: Checkout monorepo (full history) + uses: actions/checkout@v4 + with: + repository: brownplt/pyret-lang + ref: ${{ github.event.inputs.source_ref || 'mainmast' }} + fetch-depth: 0 + path: monorepo + + - name: Split code.pyret.org subtree (preserves history) + working-directory: monorepo + run: | + git subtree split --prefix=code.pyret.org -b mirror-split + echo "Split tip: $(git rev-parse mirror-split)" + git log --oneline -5 mirror-split + + - name: Push to monorepo-mirror branch of this repo + working-directory: monorepo + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + git push --force \ + "https://x-access-token:${GH_TOKEN}@github.com/${{ github.repository }}.git" \ + mirror-split:monorepo-mirror + echo "Pushed mirror-split -> monorepo-mirror" From 48ae6513db806eb41fdec9493e34b8a8faa3f451 Mon Sep 17 00:00:00 2001 From: Joe Politz Date: Thu, 25 Jun 2026 14:28:05 -0700 Subject: [PATCH 2/2] Mirror: source from drydock, use filter-repo, materialize mode/ - Default source ref mainmast -> drydock (mainmast held for team review). - Extract via `git filter-repo` (~1s) instead of `git subtree split`, which re-walks all ~12k monorepo commits and takes ~an hour for the same result. - After extraction, copy the shared codemirror-mode sibling in as a real `mode/` dir (force-added past .gitignore) so the mirror is a self-contained, Heroku-deployable slice -- matching the horizon deploy's slice fix. Co-Authored-By: Claude Opus 4.8 --- .github/workflows/monorepo-mirror.yml | 58 +++++++++++++++++++-------- 1 file changed, 42 insertions(+), 16 deletions(-) diff --git a/.github/workflows/monorepo-mirror.yml b/.github/workflows/monorepo-mirror.yml index ba6cae64..6d71789f 100644 --- a/.github/workflows/monorepo-mirror.yml +++ b/.github/workflows/monorepo-mirror.yml @@ -1,16 +1,24 @@ name: Mirror monorepo code.pyret.org subtree -# Generates a flat, deployable mirror of the code.pyret.org/ subfolder of the -# brownplt/pyret-lang monorepo, with history preserved, on the -# `monorepo-mirror` branch of THIS repo. +# Generates a deployable, history-preserving mirror of the code.pyret.org/ +# subfolder of the brownplt/pyret-lang monorepo on the `monorepo-mirror` branch +# of THIS repo, so downstream forks (e.g. Bootstrap/PBO) can keep their +# pull -> push -> Heroku "Deploy" workflow once CPO lives in the monorepo. # -# Runs in brownplt/code.pyret.org so it can push to a branch here using the +# Runs in brownplt/code.pyret.org so it can push to a branch here with the # built-in GITHUB_TOKEN -- no PAT or deploy key needed. The monorepo is public, -# so it is checked out read-only with that same token. +# so it's checked out read-only with that same token. # -# Manual-only for now: trigger from the Actions tab and pick the source ref. -# Uncomment the `schedule` block below to run it automatically once this is -# trusted. +# Extraction uses `git filter-repo` (sub-second). `git subtree split` produces +# the same result but re-walks all ~12k monorepo commits and takes ~an hour, so +# it's not viable here. The mirror is the history of code.pyret.org/ rewritten to +# the repo root, plus one commit that copies the shared ../codemirror-mode +# sibling in as a real `mode/` directory: CPO's Makefile reads the CodeMirror +# mode from a local `mode/` (a gitignored symlink in the monorepo), so the slice +# must ship it as a real dir for `make web` to build standalone on Heroku. (The +# brand images the build needs are already vendored into src/web/img.) +# +# Manual-only for now; uncomment `schedule` to run automatically once trusted. on: workflow_dispatch: @@ -18,7 +26,7 @@ on: source_ref: description: "Branch/ref of brownplt/pyret-lang to mirror" required: true - default: mainmast + default: drydock # schedule: # - cron: "0 7 * * *" # daily at 07:00 UTC @@ -37,16 +45,34 @@ jobs: uses: actions/checkout@v4 with: repository: brownplt/pyret-lang - ref: ${{ github.event.inputs.source_ref || 'mainmast' }} + ref: ${{ github.event.inputs.source_ref || 'drydock' }} fetch-depth: 0 path: monorepo - - name: Split code.pyret.org subtree (preserves history) + - name: Install git-filter-repo + run: | + sudo apt-get update -qq + sudo apt-get install -y git-filter-repo + git filter-repo --version + + - name: Extract code.pyret.org (history-preserving) + materialize mode/ working-directory: monorepo run: | - git subtree split --prefix=code.pyret.org -b mirror-split - echo "Split tip: $(git rev-parse mirror-split)" - git log --oneline -5 mirror-split + set -euo pipefail + # Stash the shared codemirror-mode sibling before filter-repo prunes it. + cp -r codemirror-mode /tmp/codemirror-mode + # Rewrite history so code.pyret.org/ becomes the repo root. + git filter-repo --subdirectory-filter code.pyret.org --force + # CPO reads the CodeMirror mode from a local `mode/` (a gitignored + # symlink in the monorepo). Ship a real copy so a downstream Heroku + # build of this mirror is self-contained. + rm -rf mode + cp -r /tmp/codemirror-mode mode + git config user.name "pyret-mirror bot" + git config user.email "119891+jpolitz@users.noreply.github.com" + git add -f mode + git commit -m "Materialize codemirror-mode for standalone deploy" + git log --oneline -5 - name: Push to monorepo-mirror branch of this repo working-directory: monorepo @@ -55,5 +81,5 @@ jobs: run: | git push --force \ "https://x-access-token:${GH_TOKEN}@github.com/${{ github.repository }}.git" \ - mirror-split:monorepo-mirror - echo "Pushed mirror-split -> monorepo-mirror" + HEAD:monorepo-mirror + echo "Pushed HEAD -> monorepo-mirror"