From 3081397fc155d3780709862cf1778b4e4e8e566c Mon Sep 17 00:00:00 2001 From: Sandro Date: Sat, 24 Oct 2026 17:30:05 +0200 Subject: [PATCH] ci: run only lint and tests on main, build images on tags and test branches --- .gitea/workflows/build-and-publish.yaml | 33 ++++++++++++++----------- BRAIN.md | 14 +++++++++++ Dockerfile | 12 +++++---- 3 files changed, 40 insertions(+), 19 deletions(-) diff --git a/.gitea/workflows/build-and-publish.yaml b/.gitea/workflows/build-and-publish.yaml index e525187..11c5fd0 100644 --- a/.gitea/workflows/build-and-publish.yaml +++ b/.gitea/workflows/build-and-publish.yaml @@ -1,11 +1,11 @@ -name: MindSift Multi-Arch Docker Build +name: MindSift CI & Docker Release on: push: branches: - - main + - '**' tags: - - 'v*' + - '*' pull_request: branches: - main @@ -23,7 +23,7 @@ jobs: with: go-version: '1.23' - - name: Run Backend Tests + - name: Run Backend Lint & Unit Tests run: | go mod tidy go vet ./... @@ -34,31 +34,37 @@ jobs: with: node-version: '22' - - name: Build & Verify Frontend + - name: Typecheck & Build Frontend run: | cd frontend npm install --no-audit --no-fund + npx tsc --noEmit npm run build build-docker: name: Build & Push Docker Image needs: test runs-on: ubuntu-latest - if: github.event_name == 'push' + # Auf 'main' werden nur Tests ausgeführt — gebaut & gepusht wird nur bei Tags oder Test-/RC-Branches + if: github.event_name == 'push' && github.ref != 'refs/heads/main' steps: - name: Checkout Code uses: actions/checkout@v4 - - name: Prepare Registry Hostname + - name: Determine Registry & Docker Tag id: prep run: | REGISTRY_HOST=$(echo "${{ gitea.server_url }}" | sed -E 's#^https?://##' | sed 's#/$##') IMAGE_NAME=$(echo "${REGISTRY_HOST}/${{ gitea.repository }}" | tr '[:upper:]' '[:lower:]') + REF_NAME="${GITHUB_REF_NAME}" + + # Ersetze evtl. Slashes in Branch-Namen (z.B. rc/1.1 -> rc-1.1) für valide Docker-Tags + DOCKER_TAG=$(echo "${REF_NAME}" | sed 's#/#-#g' | tr '[:upper:]' '[:lower:]') + echo "registry=${REGISTRY_HOST}" >> $GITHUB_OUTPUT echo "image=${IMAGE_NAME}" >> $GITHUB_OUTPUT - - - name: Set up QEMU (Multi-Arch) - uses: docker/setup-qemu-action@v3 + echo "tag=${DOCKER_TAG}" >> $GITHUB_OUTPUT + echo "Building Docker image: ${IMAGE_NAME}:${DOCKER_TAG} (from ref: ${REF_NAME})" - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 @@ -68,14 +74,13 @@ jobs: with: registry: ${{ steps.prep.outputs.registry }} username: ${{ gitea.actor }} - password: ${{ secrets.GITEA_TOKEN }} + password: ${{ secrets.PUSH_TOKEN || secrets.GITEA_TOKEN || gitea.token }} - - name: Build and Push + - name: Build and Push Multi-Arch Image uses: docker/build-push-action@v6 with: context: . platforms: linux/amd64,linux/arm64 push: true tags: | - ${{ steps.prep.outputs.image }}:latest - ${{ steps.prep.outputs.image }}:${{ gitea.sha }} + ${{ steps.prep.outputs.image }}:${{ steps.prep.outputs.tag }} diff --git a/BRAIN.md b/BRAIN.md index c22addc..0fe9498 100644 --- a/BRAIN.md +++ b/BRAIN.md @@ -167,3 +167,17 @@ docker run -p 8080:8080 -v $(pwd)/dev-data:/data -e JWT_SECRET="dev-secret-12345 # 5. SQLite DB direkt per CLI inspizieren sqlite3 ./dev-data/mindsift.db ".tables" "SELECT * FROM thoughts LIMIT 5;" ``` + +--- + +## 🚀 7. Gitea CI/CD & Docker Tagging-Strategie + +* **Registry:** `git.dsit.me/sandrodach/mindsift` +* **Gitea Secret für Registry-Login:** `secrets.PUSH_TOKEN` +* **API-Endpunkt zum Auslesen der Pipeline:** `https://git.dsit.me/api/v1/repos/sandrodach/MindSift/actions/tasks` +* **Branch- & Release-Regeln ([`.gitea/workflows/build-and-publish.yaml`](file:///home/sandro/Dokumente/git/MindSift/.gitea/workflows/build-and-publish.yaml)):** + * **Push auf `main`:** Führt **nur** Linter, TypeScript-Checks (`tsc --noEmit`) und Unit-Tests aus. **Kein Docker-Build/Push** (hält die Registry sauber). + * **Push auf Test-/RC-Branch (z. B. `1.1-rc`, `latest`, `test-feature`):** Führt Tests aus **und** baut/pusht das Image mit dem Branch-Namen (`:1.1-rc`, `:latest`). + * **Git-Tag / Release (z. B. `v1.0`, `1.1`):** Führt Tests aus **und** baut/pusht das Release-Image (`:v1.0`, `:1.1`). +* **Cross-Compile Speedup:** `Dockerfile` nutzt `FROM --platform=$BUILDPLATFORM` für Node & Go und kompiliert `amd64` + `arm64` nativ über `GOOS=${TARGETOS} GOARCH=${TARGETARCH}` ohne langsames QEMU. + diff --git a/Dockerfile b/Dockerfile index 5801dea..df2d024 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ # ============================================================================== -# Stage 1: Frontend Build (React + TypeScript + Vite + Tailwind CSS) +# Stage 1: Frontend Build (Runs natively on $BUILDPLATFORM — zero QEMU overhead) # ============================================================================== -FROM node:22-alpine AS frontend-builder +FROM --platform=$BUILDPLATFORM node:22-alpine AS frontend-builder WORKDIR /app/frontend COPY frontend/package*.json ./ RUN npm install --no-audit --no-fund @@ -9,9 +9,11 @@ COPY frontend/ ./ RUN npm run build # ============================================================================== -# Stage 2: Go Backend Build (Single Static Binary with embed.FS) +# Stage 2: Go Backend Build (Native Cross-Compile via TARGETOS / TARGETARCH) # ============================================================================== -FROM golang:1.23-alpine AS backend-builder +FROM --platform=$BUILDPLATFORM golang:1.23-alpine AS backend-builder +ARG TARGETOS=linux +ARG TARGETARCH=amd64 WORKDIR /app RUN apk add --no-cache git ca-certificates COPY go.mod ./ @@ -21,7 +23,7 @@ COPY migrations/ ./migrations/ # Copy compiled frontend SPA assets into cmd/server/dist for go:embed COPY --from=frontend-builder /app/frontend/dist ./cmd/server/dist RUN go mod tidy -RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w" -o /app/mindsift ./cmd/server +RUN CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build -ldflags="-s -w" -o /app/mindsift ./cmd/server # ============================================================================== # Stage 3: Minimal Production Runtime (< 35 MB)