From 7af21e079e72dac40d64670ff30e7464961b642a Mon Sep 17 00:00:00 2001 From: ACX <8075870+acx10@users.noreply.github.com> Date: Thu, 12 Feb 2026 00:11:18 -0700 Subject: [PATCH] ci: move Angular/Gradle builds to native CI steps to eliminate QEMU emulation bottleneck (#2705) --- .dockerignore | 15 ++++++ .github/workflows/develop-pipeline.yml | 66 +++++++++++++++++++++----- .github/workflows/master-pipeline.yml | 51 +++++++++++++++++++- Dockerfile.ci | 31 ++++++++++++ 4 files changed, 150 insertions(+), 13 deletions(-) create mode 100644 .dockerignore create mode 100644 Dockerfile.ci diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 000000000..9b684cfb2 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,15 @@ +.git +.github +.idea +.vscode +.angular + +booklore-ui/node_modules +booklore-ui/dist +booklore-ui/.angular +booklore-ui/test-results + +booklore-api/build/reports +booklore-api/build/test-results + +*.md diff --git a/.github/workflows/develop-pipeline.yml b/.github/workflows/develop-pipeline.yml index 31adc6624..e53e77acf 100644 --- a/.github/workflows/develop-pipeline.yml +++ b/.github/workflows/develop-pipeline.yml @@ -31,10 +31,10 @@ jobs: - name: Checkout Repository uses: actions/checkout@v6 - - name: Set Up JDK 21 + - name: Set Up JDK 25 uses: actions/setup-java@v5 with: - java-version: '21' + java-version: '25' distribution: 'temurin' cache: gradle @@ -140,15 +140,6 @@ jobs: with: fetch-depth: 0 - # ---------------------------------------- - # Environment setup - # ---------------------------------------- - - name: Set Up QEMU for Multi-Arch Builds - uses: docker/setup-qemu-action@v3 - - - name: Set Up Docker Buildx - uses: docker/setup-buildx-action@v3 - # ---------------------------------------- # Image tagging # ---------------------------------------- @@ -166,6 +157,58 @@ jobs: echo "image_tag=$image_tag" >> $GITHUB_ENV echo "Image tag: $image_tag" + # ---------------------------------------- + # Native Angular build + # ---------------------------------------- + - name: Set Up Node.js + uses: actions/setup-node@v6 + with: + node-version: '22' + cache: 'npm' + cache-dependency-path: booklore-ui/package-lock.json + + - name: Install Frontend Dependencies + working-directory: ./booklore-ui + run: npm ci --force + + - name: Build Angular App + working-directory: ./booklore-ui + run: npx ng build --configuration=production + + # ---------------------------------------- + # Native Gradle build + # ---------------------------------------- + - name: Set Up JDK 25 + uses: actions/setup-java@v5 + with: + java-version: '25' + distribution: 'temurin' + cache: gradle + + - name: Copy Angular Dist to Spring Boot Resources + run: cp -r booklore-ui/dist/booklore/browser/. booklore-api/src/main/resources/static/ + + - name: Inject Version into application.yaml + env: + APP_VERSION: ${{ env.image_tag }} + run: | + sudo wget -qO /usr/local/bin/yq https://github.com/mikefarah/yq/releases/download/v4.52.2/yq_linux_amd64 + sudo chmod +x /usr/local/bin/yq + yq eval '.app.version = strenv(APP_VERSION)' -i booklore-api/src/main/resources/application.yaml + + - name: Build Spring Boot JAR + working-directory: ./booklore-api + run: ./gradlew clean build -x test --no-daemon --parallel --build-cache + + # ---------------------------------------- + # Environment setup + # ---------------------------------------- + - name: Set Up QEMU for Multi-Arch Builds + uses: docker/setup-qemu-action@v3 + + - name: Set Up Docker Buildx + uses: docker/setup-buildx-action@v3 + # ---------------------------------------- # Docker login (pushes & internal PRs only) # ---------------------------------------- @@ -192,6 +235,7 @@ jobs: uses: docker/build-push-action@v6 with: context: . + file: Dockerfile.ci platforms: linux/amd64,linux/arm64 push: true tags: | diff --git a/.github/workflows/master-pipeline.yml b/.github/workflows/master-pipeline.yml index 8b7f51efe..82ed25c55 100644 --- a/.github/workflows/master-pipeline.yml +++ b/.github/workflows/master-pipeline.yml @@ -43,10 +43,10 @@ jobs: - name: Checkout Repository uses: actions/checkout@v6 - - name: Set Up JDK 21 + - name: Set Up JDK 25 uses: actions/setup-java@v5 with: - java-version: '21' + java-version: '25' distribution: 'temurin' cache: gradle @@ -234,10 +234,57 @@ jobs: echo "bump=$bump" >> $GITHUB_ENV echo "new_tag=$next_version" >> $GITHUB_ENV + # ---------------------------------------- + # Native Angular build + # ---------------------------------------- + - name: Set Up Node.js + uses: actions/setup-node@v6 + with: + node-version: '22' + cache: 'npm' + cache-dependency-path: booklore-ui/package-lock.json + + - name: Install Frontend Dependencies + working-directory: ./booklore-ui + run: npm ci --force + + - name: Build Angular App + working-directory: ./booklore-ui + run: npx ng build --configuration=production + + # ---------------------------------------- + # Native Gradle build + # ---------------------------------------- + - name: Set Up JDK 25 + uses: actions/setup-java@v5 + with: + java-version: '25' + distribution: 'temurin' + cache: gradle + + - name: Copy Angular Dist to Spring Boot Resources + run: cp -r booklore-ui/dist/booklore/browser/. booklore-api/src/main/resources/static/ + + - name: Inject Version into application.yaml + env: + APP_VERSION: ${{ env.new_tag }} + run: | + sudo wget -qO /usr/local/bin/yq https://github.com/mikefarah/yq/releases/download/v4.52.2/yq_linux_amd64 + sudo chmod +x /usr/local/bin/yq + yq eval '.app.version = strenv(APP_VERSION)' -i booklore-api/src/main/resources/application.yaml + + - name: Build Spring Boot JAR + working-directory: ./booklore-api + run: ./gradlew clean build -x test --no-daemon --parallel --build-cache + + # ---------------------------------------- + # Docker build & push + # ---------------------------------------- - name: Build and push Docker image uses: docker/build-push-action@v6 with: context: . + file: Dockerfile.ci platforms: linux/amd64,linux/arm64 push: true tags: | diff --git a/Dockerfile.ci b/Dockerfile.ci new file mode 100644 index 000000000..00a59cbed --- /dev/null +++ b/Dockerfile.ci @@ -0,0 +1,31 @@ +# Runtime-only Dockerfile for CI builds. +# Expects the pre-built JAR at booklore-api/build/libs/booklore-api-0.0.1-SNAPSHOT.jar +# and entrypoint.sh in the build context. +FROM eclipse-temurin:25-jre-alpine + +ARG APP_VERSION +ARG APP_REVISION + +LABEL org.opencontainers.image.title="BookLore" \ + org.opencontainers.image.description="BookLore: A self-hosted, multi-user digital library with smart shelves, auto metadata, Kobo & KOReader sync, BookDrop imports, OPDS support, and a built-in reader for EPUB, PDF, and comics." \ + org.opencontainers.image.source="https://github.com/booklore-app/booklore" \ + org.opencontainers.image.url="https://github.com/booklore-app/booklore" \ + org.opencontainers.image.documentation="https://booklore.org/docs/getting-started" \ + org.opencontainers.image.version=$APP_VERSION \ + org.opencontainers.image.revision=$APP_REVISION \ + org.opencontainers.image.licenses="GPL-3.0" \ + org.opencontainers.image.base.name="docker.io/library/eclipse-temurin:25-jre-alpine" + +ENV JAVA_TOOL_OPTIONS="-XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:+UseStringDeduplication -XX:+UseContainerSupport -XX:MaxRAMPercentage=75.0" + +RUN apk update && apk add --no-cache su-exec + +COPY entrypoint.sh /usr/local/bin/entrypoint.sh +RUN chmod +x /usr/local/bin/entrypoint.sh +COPY booklore-api/build/libs/booklore-api-0.0.1-SNAPSHOT.jar /app/app.jar + +ARG BOOKLORE_PORT=6060 +EXPOSE ${BOOKLORE_PORT} + +ENTRYPOINT ["entrypoint.sh"] +CMD ["java", "-jar", "/app/app.jar"]