From 5f48903a731c91df09a2f44208396006a5c0d107 Mon Sep 17 00:00:00 2001 From: charlesgauthereau Date: Tue, 10 Feb 2026 20:25:54 +0100 Subject: [PATCH] chore(release): 1.2.5-rc.9 --- .github/workflows/docker.yml | 196 ++++++++++++++---- CITATION.cff | 4 +- app/api/agent/[agentId]/backup/route.ts | 34 ++- .../[agentId]/backup/upload/status/route.ts | 6 +- docker-compose.yml | 1 + next.config.ts | 13 ++ package.json | 2 +- 7 files changed, 206 insertions(+), 50 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 892d07fb..9ab2d8d2 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -34,64 +34,190 @@ on: required: true jobs: - build-and-push: - runs-on: ubuntu-latest - permissions: - packages: write - contents: read + + build: + name: Build and push Docker images (Portabase) + runs-on: ${{ matrix.platform == 'linux/amd64' && 'ubuntu-latest' || matrix.platform == 'linux/arm64' && 'ubuntu-24.04-arm' }} + strategy: + fail-fast: false + matrix: + platform: [ linux/amd64, linux/arm64 ] steps: - - name: Check out the repo + - name: Checkout uses: actions/checkout@v4 - with: - fetch-depth: 0 - - name: Set tags - id: set-tags - run: | - REF_NAME=${GITHUB_REF#refs/tags/} - TAGS="${{ inputs.image_name }}:$REF_NAME" - TAGS2="${{ inputs.image_name2 }}:$REF_NAME" - if [[ "${{ inputs.add_latest }}" == "true" ]]; then - TAGS="$TAGS,${{ inputs.image_name }}:latest" - TAGS2="$TAGS2,${{ inputs.image_name2 }}:latest" - fi - echo "tags=$TAGS" >> $GITHUB_OUTPUT - echo "tags2=$TAGS2" >> $GITHUB_OUTPUT - - - name: Set up QEMU (enables multi-arch emulation) - uses: docker/setup-qemu-action@v3 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Log in to Docker Hub account 1 + - name: Login to Docker uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} - - name: Build and push to solucetechnologies/portabase + - name: Set image tag + id: set-tags + run: | + REF_NAME=${GITHUB_REF#refs/tags/} + if [ "${{ matrix.platform }}" = "linux/amd64" ]; then + IMAGE="${{ inputs.image_name }}:$REF_NAME-amd64" + else + IMAGE="${{ inputs.image_name }}:$REF_NAME-arm64" + fi + echo "image=$IMAGE" >> $GITHUB_OUTPUT + + - name: Build and push image uses: docker/build-push-action@v6 with: context: . file: ${{ inputs.dockerfile }} - platforms: linux/amd64,linux/arm64 + platforms: ${{ matrix.platform }} push: true - tags: ${{ steps.set-tags.outputs.tags }} + tags: ${{ steps.set-tags.outputs.image }} target: ${{ inputs.target }} - - name: Log in to Docker Hub account 2 + - name: Prepare artifact name + id: artifact + run: | + platform=${{ matrix.platform }} + echo "safe_platform=${platform//\//-}" >> $GITHUB_OUTPUT + echo "${{ steps.set-tags.outputs.image }}" > image.txt + + - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f + with: + name: image-${{ steps.artifact.outputs.safe_platform }} + path: image.txt + if-no-files-found: warn + compression-level: 6 + overwrite: false + include-hidden-files: false + + create-manifest: + name: Create multi-arch Docker manifest (Portabase) + runs-on: ubuntu-latest + needs: build + steps: + - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 + with: + name: image-linux-amd64 + path: /tmp/digests/amd64 + + - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 + with: + name: image-linux-arm64 + path: /tmp/digests/arm64 + + - name: Login to Docker + uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Create and push manifest list + working-directory: /tmp/digests + run: | + DOCKER_IMAGES="$(cat amd64/image.txt) $(cat arm64/image.txt)" + REF_NAME=${GITHUB_REF#refs/tags/} + MANIFEST_IMAGE="${{ inputs.image_name }}:$REF_NAME" + + docker buildx imagetools create $DOCKER_IMAGES -t $MANIFEST_IMAGE + docker buildx imagetools inspect $MANIFEST_IMAGE + + if [ "${{ inputs.add_latest }}" = "true" ]; then + docker buildx imagetools create $DOCKER_IMAGES -t ${{ inputs.image_name }}:latest + docker buildx imagetools inspect ${{ inputs.image_name }}:latest + fi + + + build-2: + name: Build and push Docker images (Soluce Technologies) + runs-on: ${{ matrix.platform == 'linux/amd64' && 'ubuntu-latest' || matrix.platform == 'linux/arm64' && 'ubuntu-24.04-arm' }} + strategy: + fail-fast: false + matrix: + platform: [ linux/amd64, linux/arm64 ] + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Login to Docker uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a with: username: ${{ secrets.DOCKER_USERNAME_2 }} password: ${{ secrets.DOCKER_PASSWORD_2 }} - - name: Build and push to portabase/portabase + - name: Set image tag + id: set-tags + run: | + REF_NAME=${GITHUB_REF#refs/tags/} + if [ "${{ matrix.platform }}" = "linux/amd64" ]; then + IMAGE2="${{ inputs.image_name2 }}:$REF_NAME-amd64" + else + IMAGE2="${{ inputs.image_name2 }}:$REF_NAME-arm64" + fi + echo "image2=$IMAGE2" >> $GITHUB_OUTPUT + + - name: Build and push image uses: docker/build-push-action@v6 with: context: . file: ${{ inputs.dockerfile }} - platforms: linux/amd64,linux/arm64 + platforms: ${{ matrix.platform }} push: true - tags: ${{ steps.set-tags.outputs.tags2 }} + tags: ${{ steps.set-tags.outputs.image2 }} target: ${{ inputs.target }} + + - name: Prepare artifact name + id: artifact + run: | + platform=${{ matrix.platform }} + echo "safe_platform=${platform//\//-}" >> $GITHUB_OUTPUT + echo "${{ steps.set-tags.outputs.image2 }}" > image2.txt + + - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f + with: + name: image2-${{ steps.artifact.outputs.safe_platform }} + path: image2.txt + if-no-files-found: warn + compression-level: 6 + overwrite: false + include-hidden-files: false + + create-manifest-2: + name: Create multi-arch Docker manifest (Soluce Technologies) + runs-on: ubuntu-latest + needs: build-2 + steps: + - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 + with: + name: image-linux-amd64 + path: /tmp/digests/amd64 + + - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 + with: + name: image-linux-arm64 + path: /tmp/digests/arm64 + + - name: Login to Docker + uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a + with: + username: ${{ secrets.DOCKER_USERNAME_2 }} + password: ${{ secrets.DOCKER_PASSWORD_2 }} + + - name: Create and push manifest list + working-directory: /tmp/digests + run: | + DOCKER_IMAGES="$(cat amd64/image2.txt) $(cat arm64/image2.txt)" + REF_NAME=${GITHUB_REF#refs/tags/} + MANIFEST_IMAGE="${{ inputs.image_name2 }}:$REF_NAME" + + docker buildx imagetools create $DOCKER_IMAGES -t $MANIFEST_IMAGE + docker buildx imagetools inspect $MANIFEST_IMAGE + + if [ "${{ inputs.add_latest }}" = "true" ]; then + docker buildx imagetools create $DOCKER_IMAGES -t ${{ inputs.image_name2 }}:latest + docker buildx imagetools inspect ${{ inputs.image_name2 }}:latest + fi + + + + + + diff --git a/CITATION.cff b/CITATION.cff index 14030dbc..cd2a0022 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -26,5 +26,5 @@ keywords: - web-ui - agent license: Apache-2.0 -version: 1.2.5-rc.8 -date-released: "2026-02-01" +version: 1.2.5-rc.9 +date-released: "2026-02-10" diff --git a/app/api/agent/[agentId]/backup/route.ts b/app/api/agent/[agentId]/backup/route.ts index 9f89245f..3b6f296b 100644 --- a/app/api/agent/[agentId]/backup/route.ts +++ b/app/api/agent/[agentId]/backup/route.ts @@ -33,16 +33,31 @@ export const POST = withAgentCheck(async (request: Request, {params, agent}: { let backup: Backup | null | undefined = null; if (method === "automatic") { - [backup] = await db - .insert(drizzleDb.schemas.backup) - .values({ - status: 'ongoing', - databaseId: database.id, - }) - .returning(); - if (!backup) { + + const ongoingBackup = await db.query.backup.findFirst({ + where: and( + eq(drizzleDb.schemas.backup.status, 'ongoing'), + eq(drizzleDb.schemas.backup.databaseId, database.id), + ), + }); + + if (!ongoingBackup) { + [backup] = await db + .insert(drizzleDb.schemas.backup) + .values({ + status: 'ongoing', + databaseId: database.id, + }) + .returning(); + if (!backup) { + return NextResponse.json( + {error: "Unable to create an automatic backup"}, + {status: 500} + ); + } + } else { return NextResponse.json( - {error: "Unable to create an automatic backup"}, + {error: "A backup is already ongoing"}, {status: 500} ); } @@ -54,7 +69,6 @@ export const POST = withAgentCheck(async (request: Request, {params, agent}: { ), }); - if (!backup) { return NextResponse.json( {error: "Unable to find the corresponding backup"}, diff --git a/app/api/agent/[agentId]/backup/upload/status/route.ts b/app/api/agent/[agentId]/backup/upload/status/route.ts index 0b0031c5..55bbe0bc 100644 --- a/app/api/agent/[agentId]/backup/upload/status/route.ts +++ b/app/api/agent/[agentId]/backup/upload/status/route.ts @@ -68,14 +68,16 @@ export const PATCH = withAgentCheck(async (request: Request, {params, agent}: { if (hasSuccessfulStorage && backup.status !== "success") { await db .update(drizzleDb.schemas.backup) - .set({status: "success"}) + .set({ + status: "success", + fileSize: fileSize, + }) .where(eq(drizzleDb.schemas.backup.id, backup.id)); } } eventEmitter.emit('modification', {update: true}); - return NextResponse.json({ message: "Backup status successfully updated", backupStorage: backupStorage diff --git a/docker-compose.yml b/docker-compose.yml index 02ba5acd..b53988cf 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -25,6 +25,7 @@ services: -upload-dir /data/uploads/tmp -hooks-http http://localhost:8887/api/tus/hooks -max-size 21474836480 + -base-path /tus/files/ extra_hosts: - "localhost:host-gateway" volumes: diff --git a/next.config.ts b/next.config.ts index ffb58319..6c5a2a9f 100644 --- a/next.config.ts +++ b/next.config.ts @@ -1,6 +1,8 @@ import type {NextConfig} from "next"; import {PORTABASE_DEFAULT_SETTINGS} from "./portabase.config"; +const isDev = process.env.NODE_ENV === "development"; + function buildCSPHeader(): string { const {CSP} = PORTABASE_DEFAULT_SETTINGS.SECURITY; @@ -47,6 +49,17 @@ const nextConfig: NextConfig = { }, proxyClientMaxBodySize: '10gb', }, + async rewrites() { + if (!isDev) return []; + + return [ + { + source: "/tus/:path*", + destination: "http://localhost:1080/tus/:path*", + }, + ]; + }, + async headers() { return [ { diff --git a/package.json b/package.json index ecef4faf..1cebea89 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "portabase", - "version": "1.2.5-rc.8", + "version": "1.2.5-rc.9", "private": true, "scripts": { "dev": "next dev --turbopack -p 8887",