diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml new file mode 100644 index 000000000..da281cd04 --- /dev/null +++ b/.github/workflows/e2e.yml @@ -0,0 +1,145 @@ +name: E2E (overlay on nightly) + +# Builds the server binaries, overlays them onto the published +# ghcr.io/euro-office/documentserver:nightly image, and runs the DocumentServer +# Playwright e2e suite against it. Fast feedback on a server change against the +# full stack without rebuilding core/sdkjs/web-apps. +# +# Scope: overlays the four pkg binaries (docservice, fileconverter, metrics, +# adminpanel). The AdminPanel webpack client is intentionally NOT overlaid — +# the e2e suite never exercises the admin UI, so the nightly image's client +# build is left in place. +on: + push: + branches: + - fork + - develop + - 'release/**' + - 'hotfix/**' + pull_request: + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +env: + NIGHTLY_IMAGE: ghcr.io/euro-office/documentserver:nightly + OVERLAY_IMAGE: euro-office/documentserver:e2e-server + +jobs: + e2e: + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - name: Check out server + uses: actions/checkout@v4 + with: + path: server + + # The e2e suite lives in the DocumentServer repo. Prefer a same-named + # branch (so tests can be co-developed with the change), else main. + - name: Check out DocumentServer e2e (current branch) + id: docserver + uses: actions/checkout@v4 + continue-on-error: true + with: + repository: Euro-Office/DocumentServer + path: documentserver + ref: ${{ github.head_ref || github.ref_name }} + - name: Check out DocumentServer e2e (main) + if: steps.docserver.outcome != 'success' + uses: actions/checkout@v4 + with: + repository: Euro-Office/DocumentServer + path: documentserver + ref: main + + - name: Use Node.js 20 + uses: actions/setup-node@v4 + with: + node-version: 20 + + - name: Pull nightly image + run: docker pull ${{ env.NIGHTLY_IMAGE }} + + # docservice rejects an editor whose version differs from its own + # (services gate on an exact buildVersion match). The bake injects + # PRODUCT_VERSION into commondefines.js; replicate that with the version + # the nightly image was built with so the fresh docservice matches the + # nightly editor. Read it from the image so it tracks version bumps. + - name: Read nightly product version + id: ver + run: | + set -euo pipefail + VER=$(docker run --rm --entrypoint sh ${{ env.NIGHTLY_IMAGE }} -c \ + "grep -A2 'DocsAPI.DocEditor.version = function' \ + \$(find /var/www -maxdepth 8 -path '*api/documents/api.js' | head -n1) \ + | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -n1") + test -n "$VER" + echo "product_version=$VER" >> "$GITHUB_OUTPUT" + echo "nightly PRODUCT_VERSION=$VER" + + # Mirrors server.bake.Dockerfile: stamp buildVersion, install each package, + # then pkg the services into $BUILD_ROOT. + - name: Build server binaries + working-directory: server + env: + BUILD_ROOT: ${{ github.workspace }}/server/deploy + PRODUCT_VERSION: ${{ steps.ver.outputs.product_version }} + run: | + npm install -g @yao-pkg/pkg + sed -i "s|\(const buildVersion = \).*|\1'${PRODUCT_VERSION}';|" Common/sources/commondefines.js + for d in Common DocService FileConverter Metrics; do + ( cd "$d" && npm install ) + done + mkdir -p "$BUILD_ROOT" + ( cd DocService && pkg . -t linux-x64 --node-options="--max_old_space_size=4096" -o "$BUILD_ROOT/docservice" ) + ( cd FileConverter && pkg . -t linux-x64 --node-options="--max_old_space_size=4096" -o "$BUILD_ROOT/fileconverter" ) + ( cd Metrics && pkg . -t linux-x64 --node-options="--max_old_space_size=4096" -o "$BUILD_ROOT/metrics" ) + + - name: Build overlay image with fresh server binaries + run: | + set -euo pipefail + cat > overlay.Dockerfile <<'EOF' + ARG NIGHTLY_IMAGE + FROM ${NIGHTLY_IMAGE} + COPY docservice fileconverter metrics /tmp/srv/ + # The install path is brand-derived (/var/www//documentserver); + # locate it via the sdkjs dir, then replace the service binaries. + RUN set -eux; \ + root="$(dirname "$(find /var/www -maxdepth 5 -type d -name sdkjs -path '*documentserver*' | head -n1)")"; \ + test -n "$root"; \ + install -m0755 /tmp/srv/docservice "$root/server/DocService/docservice"; \ + install -m0755 /tmp/srv/fileconverter "$root/server/FileConverter/converter"; \ + install -m0755 /tmp/srv/metrics "$root/server/Metrics/metrics"; \ + rm -rf /tmp/srv + EOF + docker build \ + --build-arg NIGHTLY_IMAGE=${{ env.NIGHTLY_IMAGE }} \ + -t ${{ env.OVERLAY_IMAGE }} \ + -f overlay.Dockerfile \ + server/deploy + + - name: Install e2e dependencies + working-directory: documentserver/e2e + run: npm ci + + - name: Install Playwright browsers + working-directory: documentserver/e2e + run: npx playwright install chromium --with-deps + + - name: Run E2E tests + working-directory: documentserver/e2e + env: + E2E_IMAGE: ${{ env.OVERLAY_IMAGE }} + run: npm test + + - name: Upload Playwright report + if: always() + uses: actions/upload-artifact@v4 + with: + name: playwright-report-${{ github.sha }} + path: documentserver/e2e/playwright-report/ + retention-days: 14