name: Build and Push Docker Images permissions: pull-requests: write contents: read on: push: branches: - main tags: - 'v*.*.*' pull_request: branches: - main jobs: test: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: Set up Go uses: actions/setup-go@v5 with: go-version: 1.22 - name: Install mupdf run: sudo apt-get install -y mupdf - name: Set library path run: echo "/usr/lib" | sudo tee -a /etc/ld.so.conf.d/mupdf.conf && sudo ldconfig - name: Install dependencies run: go mod download - name: Run Go tests run: go test ./... - name: Set up Node.js uses: actions/setup-node@v4 with: node-version: 20 - name: Cache npm dependencies uses: actions/cache@v4 with: path: ~/.npm key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} restore-keys: | ${{ runner.os }}-node- - name: Install frontend dependencies run: npm install working-directory: web-app - name: Run frontend tests run: npm test working-directory: web-app build-amd64: runs-on: ubuntu-latest needs: test outputs: digest: ${{ steps.build_amd64.outputs.digest }} image_tag: ${{ steps.set_image_tag.outputs.image_tag }} steps: - name: Checkout code uses: actions/checkout@v4 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Log in to Docker Hub uses: docker/login-action@v3 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} - name: Set Docker tags id: set_tags run: | if [[ "${GITHUB_EVENT_NAME}" == "pull_request" ]]; then echo "TAGS=icereed/paperless-gpt:pr-${GITHUB_SHA}-amd64" >> $GITHUB_ENV elif [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then VERSION=${GITHUB_REF#refs/tags/} echo "TAGS=icereed/paperless-gpt:${VERSION}-amd64" >> $GITHUB_ENV else echo "TAGS=icereed/paperless-gpt:unreleased-amd64" >> $GITHUB_ENV fi - name: Build and push AMD64 image id: build_amd64 uses: docker/build-push-action@v6 with: context: . platforms: linux/amd64 push: true cache-from: type=gha cache-to: type=gha,mode=max tags: ${{ env.TAGS }} build-args: | VERSION=${{ github.ref_type == 'tag' && github.ref_name || github.sha }} COMMIT=${{ github.sha }} BUILD_DATE=${{ github.event.repository.pushed_at }} - name: Set image tag output id: set_image_tag run: echo "image_tag=${TAGS}" >> $GITHUB_OUTPUT - name: Export digest for amd64 run: | mkdir -p ${{ runner.temp }}/digests echo "${{ steps.build_amd64.outputs.digest }}" | sed 's/^sha256://g' > ${{ runner.temp }}/digests/digest-amd64.txt - name: Upload amd64 digest uses: actions/upload-artifact@v4 with: name: digest-amd64 path: ${{ runner.temp }}/digests/digest-amd64.txt build-arm64: runs-on: ubuntu-24.04-arm needs: test outputs: digest: ${{ steps.build_arm64.outputs.digest }} steps: - name: Checkout code uses: actions/checkout@v4 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Log in to Docker Hub if: ${{ github.event_name != 'pull_request' }} uses: docker/login-action@v3 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} - name: Set Docker tags id: set_tags run: | if [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then VERSION=${GITHUB_REF#refs/tags/} echo "TAGS=icereed/paperless-gpt:${VERSION}-arm64" >> $GITHUB_ENV else echo "TAGS=icereed/paperless-gpt:unreleased-arm64" >> $GITHUB_ENV fi - name: Build and push ARM64 image id: build_arm64 uses: docker/build-push-action@v6 with: context: . platforms: linux/arm64 push: ${{ github.event_name != 'pull_request' }} cache-from: type=gha cache-to: type=gha,mode=max tags: ${{ env.TAGS }} build-args: | VERSION=${{ github.ref_type == 'tag' && github.ref_name || github.sha }} COMMIT=${{ github.sha }} BUILD_DATE=${{ github.event.repository.pushed_at }} - name: Export digest for arm64 run: | mkdir -p ${{ runner.temp }}/digests echo "${{ steps.build_arm64.outputs.digest }}" | sed 's/^sha256://g' > ${{ runner.temp }}/digests/digest-arm64.txt - name: Upload arm64 digest uses: actions/upload-artifact@v4 with: name: digest-arm64 path: ${{ runner.temp }}/digests/digest-arm64.txt merge-manifests: needs: [build-amd64, build-arm64] runs-on: ubuntu-latest if: github.event_name != 'pull_request' env: DOCKERHUB_REPO: icereed/paperless-gpt steps: - name: Download amd64 digest uses: actions/download-artifact@v4 with: name: digest-amd64 path: ${{ runner.temp }}/digests - name: Download arm64 digest uses: actions/download-artifact@v4 with: name: digest-arm64 path: ${{ runner.temp }}/digests - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Login to Docker Hub uses: docker/login-action@v3 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} - name: Determine version/tag id: get_version run: | if [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then VERSION=${GITHUB_REF#refs/tags/} echo "VERSION=${VERSION}" >> $GITHUB_ENV else echo "VERSION=unreleased" >> $GITHUB_ENV fi - name: Create and push manifest list run: | AMD64_DIGEST=$(cat ${{ runner.temp }}/digests/digest-amd64.txt) ARM64_DIGEST=$(cat ${{ runner.temp }}/digests/digest-arm64.txt) # Create manifest with the single-arch image digests docker buildx imagetools create -t ${DOCKERHUB_REPO}:${VERSION} \ ${DOCKERHUB_REPO}@sha256:${AMD64_DIGEST} ${DOCKERHUB_REPO}@sha256:${ARM64_DIGEST} # Also push "latest" tag when on a tag if [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then docker buildx imagetools create -t ${DOCKERHUB_REPO}:latest \ ${DOCKERHUB_REPO}@sha256:${AMD64_DIGEST} ${DOCKERHUB_REPO}@sha256:${ARM64_DIGEST} fi - name: Inspect manifest run: | docker buildx imagetools inspect ${DOCKERHUB_REPO}:${VERSION} if [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then docker buildx imagetools inspect ${DOCKERHUB_REPO}:latest fi e2e-tests: name: E2E Tests needs: build-amd64 runs-on: ubuntu-latest defaults: run: working-directory: ./web-app steps: - name: Checkout code uses: actions/checkout@v4 - name: Set PAPERLESS_GPT_IMAGE run: | if [ "${GITHUB_EVENT_NAME}" = "pull_request" ]; then IMAGE="icereed/paperless-gpt:pr-${GITHUB_SHA}-amd64" elif [ "${GITHUB_REF_TYPE}" = "tag" ]; then IMAGE="icereed/paperless-gpt:${GITHUB_REF_NAME}-amd64" else IMAGE="icereed/paperless-gpt:unreleased-amd64" fi echo "PAPERLESS_GPT_IMAGE=${IMAGE}" >> $GITHUB_ENV - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: '20' cache: 'npm' cache-dependency-path: './web-app/package-lock.json' - name: Install dependencies run: npm ci - name: Install Playwright browsers run: npx playwright install chromium --with-deps - name: Run Playwright tests run: npm run test:e2e env: CI: true OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} PAPERLESS_GPT_IMAGE: ${{ env.PAPERLESS_GPT_IMAGE }} - name: Upload Playwright Report if: always() uses: actions/upload-artifact@v4 with: name: playwright-report path: web-app/playwright-report/ retention-days: 30 - name: Upload test screenshots if: always() uses: actions/upload-artifact@v4 with: name: test-results path: web-app/test-results/ retention-days: 30