From 3bc3e09467d06137fbc18da69408a33b1655b65f Mon Sep 17 00:00:00 2001 From: Kostiantyn <32730812+kkovaletp@users.noreply.github.com> Date: Tue, 8 Jul 2025 17:13:20 +0300 Subject: [PATCH] Fix GitHub commit passing, UI build and cache for different purposes (#1239) * Fix GitHub commit passing, UI build and cache for different purposes * a logging for transparency and easy debug * Fix var expanding with quotes and add intermediate verification commands * split verification commands * fix joining commands * Ecplicitly pull latest deps image * properly set arg default values and try to fix preparation step * another try to build the image with the correct deps tag * Revert the dynamic deps tag discovery, as it doesn't work and the actual `latest` image is pulled implicitly anyway * Final optimizations * "NoCommit" placeholder, indent fix, var rename --------- Co-authored-by: Konstantin Koval --- .github/workflows/build.yml | 13 ++++++--- .github/workflows/tests.yml | 1 + Dockerfile | 54 ++++++++++++++++++++++--------------- 3 files changed, 43 insertions(+), 25 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3e83dede..85cbd1be 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -80,7 +80,12 @@ jobs: ref: ${{ matrix.tags.ref }} - name: Fetch branches - run: git fetch --all + id: git + shell: bash + run: | + set -euo pipefail + git fetch --all + echo "COMMIT_SHORT_SHA=$(git rev-parse --short HEAD)" | tee -a $GITHUB_OUTPUT - name: Set up QEMU uses: docker/setup-qemu-action@v3 @@ -121,6 +126,7 @@ jobs: uses: docker/build-push-action@v6 with: context: . + target: release sbom: true provenance: mode=max platforms: ${{ env.PLATFORMS }} @@ -130,14 +136,15 @@ jobs: labels: ${{ steps.docker_meta.outputs.labels }} annotations: ${{ steps.docker_meta.outputs.annotations }} cache-from: | - type=gha,scope=test-ui-${{ hashFiles('ui/package-lock.json') }} + type=gha,scope=ui-${{ hashFiles('ui/package-lock.json') }} type=gha,scope=test-api-${{ hashFiles('api/go.sum', 'scripts/install_*.sh', 'dependencies/*') }} cache-to: | - type=gha,mode=max,scope=test-ui-${{ hashFiles('ui/package-lock.json') }} + type=gha,mode=max,scope=ui-${{ hashFiles('ui/package-lock.json') }} type=gha,mode=max,scope=test-api-${{ hashFiles('api/go.sum', 'scripts/install_*.sh', 'dependencies/*') }} build-args: | NODE_ENV=production VERSION=${{ github.ref_name }} + COMMIT_SHA=${{ steps.git.outputs.COMMIT_SHORT_SHA }} dockle: name: Dockle Container Analysis diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 54681e46..04c767b5 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -112,6 +112,7 @@ jobs: target: ui tags: photoview/ui cache-from: type=gha,scope=test-ui-${{ hashFiles('ui/package-lock.json') }} + cache-to: type=gha,mode=max,scope=test-ui-${{ hashFiles('ui/package-lock.json') }} build-args: | NODE_ENV=testing diff --git a/Dockerfile b/Dockerfile index e64f729a..e0239c16 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,35 +1,40 @@ ### Build UI ### FROM --platform=${BUILDPLATFORM:-linux/amd64} node:18 AS ui -ARG TARGETARCH -ARG GITHUB_SHA -ARG VERSION - # See for details: https://github.com/hadolint/hadolint/wiki/DL4006 SHELL ["/bin/bash", "-euo", "pipefail", "-c"] -ARG NODE_ENV -ENV NODE_ENV=${NODE_ENV:-production} +ARG NODE_ENV=production +ENV NODE_ENV=${NODE_ENV} + +WORKDIR /app/ui + +COPY ui/package.json ui/package-lock.json /app/ui/ +RUN if [ "$NODE_ENV" = "production" ]; then \ + echo "Installing production dependencies only..."; \ + npm ci --omit=dev; \ + else \ + echo "Installing all dependencies..."; \ + npm ci; \ + fi + +COPY ui/ /app/ui # Set environment variable REACT_APP_API_ENDPOINT from build args, uses "/api" as default ARG REACT_APP_API_ENDPOINT ENV REACT_APP_API_ENDPOINT=${REACT_APP_API_ENDPOINT} # Set environment variable UI_PUBLIC_URL from build args, uses "/" as default -ARG UI_PUBLIC_URL -ENV UI_PUBLIC_URL=${UI_PUBLIC_URL:-/} +ARG UI_PUBLIC_URL=/ +ENV UI_PUBLIC_URL=${UI_PUBLIC_URL} -WORKDIR /app/ui - -COPY ui/package.json ui/package-lock.json /app/ui/ -RUN npm ci - -COPY ui/ /app/ui +ARG VERSION=unknown-branch +ARG TARGETARCH # hadolint ignore=SC2155 -RUN export BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ'); \ +RUN export BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%S+00:00(UTC)'); \ export REACT_APP_BUILD_DATE=${BUILD_DATE}; \ - export COMMIT_SHA=${GITHUB_SHA:-$(git rev-parse --short HEAD || echo 000000)}; \ + export COMMIT_SHA="-==-"; \ export REACT_APP_BUILD_COMMIT_SHA=${COMMIT_SHA}; \ - export VERSION="${VERSION:-$(git rev-parse --abbrev-ref HEAD || echo unknown-branch)}-${TARGETARCH}"; \ + export VERSION="${VERSION}-${TARGETARCH}"; \ export REACT_APP_BUILD_VERSION=${VERSION}; \ npm run build -- --base="${UI_PUBLIC_URL}" @@ -59,7 +64,7 @@ RUN chmod +x /app/scripts/*.sh \ && /app/scripts/install_build_dependencies.sh \ && /app/scripts/install_runtime_dependencies.sh -COPY --from=photoview/dependencies /artifacts.tar.gz /dependencies/ +COPY --from=photoview/dependencies:latest /artifacts.tar.gz /dependencies/ # Split values in `/env` # hadolint ignore=SC2046 RUN export $(cat /env) \ @@ -82,8 +87,8 @@ RUN export $(cat /env) \ && sed -i 's/-march=native//g' ${GOPATH}/pkg/mod/github.com/!kagami/go-face*/face.go \ # Build dependencies that use CGO && go install \ - github.com/mattn/go-sqlite3 \ - github.com/Kagami/go-face + github.com/mattn/go-sqlite3 \ + github.com/Kagami/go-face COPY api /app/api # Split values in `/env` @@ -122,6 +127,11 @@ RUN --mount=type=bind,from=api,source=/dependencies/,target=/dependencies/ \ COPY api/data /app/data COPY --from=ui /app/ui/dist /app/ui COPY --from=api /app/api/photoview /app/photoview +# This is a w/a for letting the UI build stage to be cached +# and not rebuilt every new commit because of the build_arg value change. +ARG COMMIT_SHA=NoCommit +RUN find /app/ui/assets -type f -name "SettingsPage.*.js" \ + -exec sed -i "s/=\"-==-\";/=\"${COMMIT_SHA}\";/g" {} \; WORKDIR /home/photoview @@ -137,8 +147,8 @@ EXPOSE ${PHOTOVIEW_LISTEN_PORT} HEALTHCHECK --interval=60s --timeout=10s \ CMD curl --fail http://localhost:${PHOTOVIEW_LISTEN_PORT}/api/graphql \ - -X POST -H 'Content-Type: application/json' \ - --data-raw '{"operationName":"CheckInitialSetup","variables":{},"query":"query CheckInitialSetup { siteInfo { initialSetup }}"}' \ + -X POST -H 'Content-Type: application/json' \ + --data-raw '{"operationName":"CheckInitialSetup","variables":{},"query":"query CheckInitialSetup { siteInfo { initialSetup }}"}' \ || exit 1 USER photoview