name: Build and Deploy Verso on: push: branches: - main workflow_dispatch: env: SITE_URL: https://test.alocoq.fr jobs: deploy: runs-on: native timeout-minutes: 240 steps: - name: Build and push Verso images with BuildKit run: | kubectl -n ci delete job verso-buildkit --ignore-not-found=true --wait=true cat <<'EOF' | kubectl apply -f - apiVersion: batch/v1 kind: Job metadata: name: verso-buildkit namespace: ci spec: backoffLimit: 0 template: spec: restartPolicy: Never initContainers: - name: prepare image: alpine/git:latest command: ["sh", "-c"] args: - | set -eux git clone --depth 1 https://git.alocoq.fr/alois/verso.git /workspace/repo volumeMounts: - name: workspace mountPath: /workspace containers: - name: buildkit image: moby/buildkit:latest securityContext: privileged: true command: ["sh", "-c"] args: - | set -eux buildctl-daemonless.sh build \ --frontend=dockerfile.v0 \ --local context=/workspace/repo \ --local dockerfile=/workspace/repo/server-ce \ --opt filename=Dockerfile-base \ --output type=image,name=registry.alocoq.fr/verso-base:latest,push=true buildctl-daemonless.sh build \ --frontend=dockerfile.v0 \ --local context=/workspace/repo \ --local dockerfile=/workspace/repo/server-ce \ --opt filename=Dockerfile \ --opt build-arg:OVERLEAF_BASE_TAG=registry.alocoq.fr/verso-base:latest \ --output type=image,name=registry.alocoq.fr/verso:latest,push=true volumeMounts: - name: workspace mountPath: /workspace volumes: - name: workspace emptyDir: {} EOF - name: Wait for build run: | kubectl -n ci wait --for=condition=complete job/verso-buildkit --timeout=14400s - name: Show build logs if: always() run: | kubectl -n ci logs job/verso-buildkit -c prepare || true kubectl -n ci logs job/verso-buildkit -c buildkit || true - name: Recreate test dependencies run: | kubectl -n test delete deployment mongo redis --ignore-not-found=true --wait=true kubectl -n test delete service mongo redis --ignore-not-found=true --wait=true cat <<'EOF' | kubectl apply -f - apiVersion: apps/v1 kind: Deployment metadata: name: mongo namespace: test spec: replicas: 1 selector: matchLabels: app: mongo template: metadata: labels: app: mongo spec: containers: - name: mongo image: mongo:8 command: ["mongod", "--replSet", "rs0", "--bind_ip_all"] ports: - containerPort: 27017 volumeMounts: - name: mongo-data mountPath: /data/db volumes: - name: mongo-data emptyDir: {} --- apiVersion: v1 kind: Service metadata: name: mongo namespace: test spec: selector: app: mongo ports: - name: mongo port: 27017 targetPort: 27017 --- apiVersion: apps/v1 kind: Deployment metadata: name: redis namespace: test spec: replicas: 1 selector: matchLabels: app: redis template: metadata: labels: app: redis spec: containers: - name: redis image: redis:7 ports: - containerPort: 6379 volumeMounts: - name: redis-data mountPath: /data volumes: - name: redis-data emptyDir: {} --- apiVersion: v1 kind: Service metadata: name: redis namespace: test spec: selector: app: redis ports: - name: redis port: 6379 targetPort: 6379 EOF kubectl -n test rollout status deployment/mongo --timeout=180s kubectl -n test rollout status deployment/redis --timeout=180s sleep 5 kubectl -n test exec deploy/mongo -- mongosh --eval ' rs.initiate({ _id: "rs0", members: [{ _id: 0, host: "mongo:27017" }] }) ' kubectl -n test exec deploy/mongo -- mongosh --eval ' while (rs.status().myState !== 1) { sleep(1000) } print("Mongo replica set is PRIMARY") ' - name: Ensure Verso deployment exists run: | cat <<'EOF' | kubectl apply -f - apiVersion: apps/v1 kind: Deployment metadata: name: verso namespace: test spec: replicas: 1 selector: matchLabels: app: verso template: metadata: labels: app: verso spec: containers: - name: verso image: registry.alocoq.fr/verso:latest ports: - containerPort: 80 env: - name: OVERLEAF_MONGO_URL value: mongodb://mongo:27017/sharelatex?replicaSet=rs0 - name: OVERLEAF_REDIS_HOST value: redis - name: REDIS_HOST value: redis - name: OVERLEAF_APP_NAME value: Verso - name: OVERLEAF_SITE_URL value: https://test.alocoq.fr --- apiVersion: v1 kind: Service metadata: name: verso namespace: test spec: selector: app: verso ports: - name: http port: 80 targetPort: 80 EOF - name: Deploy Verso image run: | kubectl -n test set image deployment/verso \ verso=registry.alocoq.fr/verso:latest kubectl -n test rollout restart deployment/verso kubectl -n test rollout status deployment/verso --timeout=300s - name: Create admin user run: | sleep 20 kubectl -n test exec deploy/verso -- bash -lc ' cd /overleaf/services/web node modules/server-ce-scripts/scripts/create-user \ --admin \ --email=test@example.com || true ' - name: Cleanup if: always() run: | kubectl -n ci delete job verso-buildkit --ignore-not-found=true --wait=true