diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml index be674c3..954fa8f 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/deploy.yml @@ -8,8 +8,8 @@ on: jobs: # One file, two lifecycles. The app pair (frontend + backend) moves with # most commits; the lean image carries Mathlib and is heavy to build and - # push, so its job runs only when lean/** actually changed. This step reads - # the pushed diff and opens the gates for the jobs below. + # push, so its build runs only when lean/** actually changed. This step + # reads the pushed diff and opens the gates for the deploy job below. changes: runs-on: docker @@ -48,11 +48,15 @@ jobs: echo "lean=$lean" >> "$GITHUB_OUTPUT" echo "app=$app lean=$lean" - # The wiki app itself — its deploy step never touches the lean service. + # Both images deploy from here so the checkout, SSH setup and registry + # login happen once. The two builds stay gated on the pushed diff: a + # lean-only push skips every app step, and an app-only push skips lean — + # rebuilding Mathlib on a wiki commit would be pointless and slow. A lean + # change does not rebuild the app pair, and vice versa. deploy: runs-on: docker needs: changes - if: needs.changes.outputs.app == 'yes' + if: needs.changes.outputs.app == 'yes' || needs.changes.outputs.lean == 'yes' steps: - name: Checkout @@ -76,24 +80,27 @@ jobs: echo "${{ secrets.REGISTRY_PASSWORD }}" | docker login git.aranroig.com -u "${{ secrets.REGISTRY_USER }}" --password-stdin - name: Build frontend + if: needs.changes.outputs.app == 'yes' run: | docker build -t git.aranroig.com/${{ secrets.REGISTRY_USER }}/mathew-frontend:latest ./frontend docker push git.aranroig.com/${{ secrets.REGISTRY_USER }}/mathew-frontend:latest - name: Build backend + if: needs.changes.outputs.app == 'yes' run: | docker build -t git.aranroig.com/${{ secrets.REGISTRY_USER }}/mathew-backend:latest ./backend docker push git.aranroig.com/${{ secrets.REGISTRY_USER }}/mathew-backend:latest - name: Copy files + if: needs.changes.outputs.app == 'yes' run: | scp docker-compose.yml deploy@${{ secrets.DEPLOY_HOST }}:/var/www/app/ scp nginx.conf deploy@${{ secrets.DEPLOY_HOST }}:/var/www/app/nginx.conf - # Scoped to the services this job owns: never pulls/builds lean from - # here (that would need the lean tag or lean/ sources on the host). - # deploy-lean.yml owns the lean service's pull and up. - - name: Deploy + # Scoped to the services this step owns: never pulls/builds lean from + # here — the lean steps below do that, only when lean/** changed. + - name: Deploy app + if: needs.changes.outputs.app == 'yes' run: | ssh deploy@${{ secrets.DEPLOY_HOST }} << 'EOF' echo "${{ secrets.REGISTRY_PASSWORD }}" | docker login git.aranroig.com -u "${{ secrets.REGISTRY_USER }}" --password-stdin @@ -102,41 +109,17 @@ jobs: docker compose up -d frontend backend nginx EOF - # The Lean editor (lean4web): multi-stage, heavy by nature (it fetches - # Mathlib); expect a long build and a multi-GB push. Pin upstream with: - # docker build --build-arg LEAN4WEB_REF=v0.2.2 ... - deploy-lean: - runs-on: docker - needs: changes - if: needs.changes.outputs.lean == 'yes' - - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Install SSH client - run: | - apt-get update -y && apt-get install -y openssh-client - - - name: Setup SSH inside container - run: | - mkdir -p ~/.ssh - echo "${{ secrets.DEPLOY_KEY }}" > ~/.ssh/id_ed25519 - chmod 600 ~/.ssh/id_ed25519 - - # Add the container host to known_hosts - ssh-keyscan -H ${{ secrets.DEPLOY_HOST }} >> ~/.ssh/known_hosts - - - name: Log in to registry - run: | - echo "${{ secrets.REGISTRY_PASSWORD }}" | docker login git.aranroig.com -u "${{ secrets.REGISTRY_USER }}" --password-stdin - + # The Lean editor (lean4web): multi-stage, heavy by nature (it fetches + # Mathlib); expect a long build and a multi-GB push. Pin upstream with: + # docker build --build-arg LEAN4WEB_REF=v0.2.2 ... - name: Build lean editor server + if: needs.changes.outputs.lean == 'yes' run: | docker build -t git.aranroig.com/${{ secrets.REGISTRY_USER }}/mathew-lean:latest ./lean docker push git.aranroig.com/${{ secrets.REGISTRY_USER }}/mathew-lean:latest - - name: Deploy + - name: Deploy lean + if: needs.changes.outputs.lean == 'yes' run: | ssh deploy@${{ secrets.DEPLOY_HOST }} << 'EOF' echo "${{ secrets.REGISTRY_PASSWORD }}" | docker login git.aranroig.com -u "${{ secrets.REGISTRY_USER }}" --password-stdin diff --git a/AGENTS.md b/AGENTS.md index b3311fc..f9083fa 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -69,7 +69,7 @@ its theme (live, same page), and the Goals/Messages pane. `--build-arg LEAN4WEB_REF=` pins it) and runs its websocket server on port 8080; the compose `lean` service runs it (image `git.aranroig.com/syndria98/mathew-lean:latest` — CI pushes it, and deploys lean, only when `lean/**` changes: `.gitea/workflows/deploy.yml` -gates its `deploy-lean` job on the pushed diff; the app deploy just pulls the tag). Upstream +gates its lean build steps on the pushed diff, in the same job as the app deploy). Upstream asks for a dedicated machine, so the build is **multi-stage**: dev tooling stays in the builder, and the pushed image is a slim runtime of node + elan toolchain + built client + Mathlib's compiled cache (~11GB — the cache is the bulk; upstream's second demo project diff --git a/lean/README.md b/lean/README.md index bc3948a..4409b4b 100644 --- a/lean/README.md +++ b/lean/README.md @@ -161,10 +161,11 @@ and its cache re-downloads, so treat this like the heavy build it is (run it on the machine that hosts the editor; pin `LEAN4WEB_REF` for a build that stands still). -CI follows the same split inside one workflow: `.gitea/workflows/deploy.yml` gates a -`deploy-lean` job on the pushed diff — it rebuilds, pushes and redeploys the lean image -**only when `lean/**` changed** — while the app jobs run on every other change and just -pull whatever `mathew-lean:latest` the registry holds. (In volume mode the pushed image +CI follows the same split inside one workflow and one deploy job: +`.gitea/workflows/deploy.yml` gates the lean build steps on the pushed diff — it rebuilds, +pushes and redeploys the lean image **only when `lean/**` changed** — while an app change +skips them and just pulls whatever `mathew-lean:latest` the registry holds, and a lean-only +change skips the app builds. (In volume mode the pushed image is ~4GB and a lean rebuild doesn't fetch Mathlib at all.) ## Adding Lean projects