diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml new file mode 100644 index 0000000..2a13073 --- /dev/null +++ b/.gitea/workflows/ci.yml @@ -0,0 +1,21 @@ +name: CI + +on: + push: + pull_request: + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-go@v5 + with: + go-version-file: go.mod + cache: true + - run: go build ./... + - run: go test ./... + - uses: golangci/golangci-lint-action@v7 + with: + version: v2.4 + args: --config .golangci.yml ./... diff --git a/.gitea/workflows/deploy.yaml b/.gitea/workflows/deploy.yaml new file mode 100644 index 0000000..dabdefe --- /dev/null +++ b/.gitea/workflows/deploy.yaml @@ -0,0 +1,58 @@ +name: Build and Deploy + +on: + push: + branches: [main] + +env: + INTERNAL_REGISTRY: gitea-http.gitea.svc.cluster.local:3000 + NODE_REGISTRY: localhost:30300 + +jobs: + build-and-deploy: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install Docker CLI + run: | + curl -fsSL https://download.docker.com/linux/static/stable/x86_64/docker-27.5.1.tgz \ + | tar xz --strip-components=1 -C /usr/local/bin docker/docker + docker version + + - name: Install kubectl + run: | + curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" + chmod +x kubectl + mv kubectl /usr/local/bin/ + kubectl version --client + + - name: Login to Gitea Registry + run: | + echo "${{ secrets.REGISTRY_PASSWORD }}" | \ + docker login ${{ env.INTERNAL_REGISTRY }} \ + -u ${{ secrets.REGISTRY_USERNAME }} --password-stdin + + - name: Build and push image + run: | + docker build -f Dockerfile \ + -t ${{ env.INTERNAL_REGISTRY }}/admin/ai-service:${{ github.sha }} \ + -t ${{ env.INTERNAL_REGISTRY }}/admin/ai-service:latest \ + . + docker push ${{ env.INTERNAL_REGISTRY }}/admin/ai-service:${{ github.sha }} + docker push ${{ env.INTERNAL_REGISTRY }}/admin/ai-service:latest + + - name: Deploy to Kubernetes + env: + KUBECONFIG: /kubeconfig/config + run: | + kubectl apply -f k8s/namespace.yaml + kubectl apply -f k8s/secrets.yaml + kubectl apply -f k8s/configmap.yaml + kubectl apply -f k8s/postgres.yaml + kubectl apply -f k8s/server-deployment.yaml + kubectl apply -f k8s/server-service.yaml + kubectl -n ai-service set image deployment/ai-service \ + server=${{ env.NODE_REGISTRY }}/admin/ai-service:${{ github.sha }} + kubectl -n ai-service rollout status deployment/ai-service --timeout=180s diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 0000000..5dda72d --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,36 @@ +version: "2" + +run: + timeout: 3m + +linters: + default: none + enable: + - errcheck + - govet + - ineffassign + - staticcheck + - unused + settings: + errcheck: + check-type-assertions: true + check-blank: false + exclude-functions: + - (io.Closer).Close + - (net/http.ResponseWriter).Write + - (*encoding/json.Encoder).Encode + - io.Copy + - fmt.Fprintf + - (github.com/jackc/pgx/v5.Tx).Rollback + - os.RemoveAll + staticcheck: + checks: ["all", "-SA1019", "-ST1000", "-ST1005", "-ST1020", "-ST1021", "-ST1022"] + exclusions: + rules: + - path: _test\.go + linters: + - errcheck + +issues: + max-issues-per-linter: 0 + max-same-issues: 0 diff --git a/k8s/kustomization.yaml b/k8s/kustomization.yaml index 945ba89..2ae615a 100644 --- a/k8s/kustomization.yaml +++ b/k8s/kustomization.yaml @@ -7,5 +7,6 @@ resources: - namespace.yaml - configmap.yaml - secrets.yaml + - postgres.yaml - server-deployment.yaml - server-service.yaml diff --git a/k8s/postgres.yaml b/k8s/postgres.yaml new file mode 100644 index 0000000..e1b644d --- /dev/null +++ b/k8s/postgres.yaml @@ -0,0 +1,65 @@ +apiVersion: v1 +kind: Service +metadata: + name: postgres + namespace: ai-service +spec: + selector: + app: postgres + ports: + - port: 5432 + targetPort: 5432 +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: postgres + namespace: ai-service +spec: + serviceName: postgres + replicas: 1 + selector: + matchLabels: + app: postgres + template: + metadata: + labels: + app: postgres + spec: + containers: + - name: postgres + image: postgres:16-alpine + ports: + - containerPort: 5432 + envFrom: + - secretRef: + name: postgres-secret + volumeMounts: + - name: pgdata + mountPath: /var/lib/postgresql/data + resources: + requests: + cpu: 50m + memory: 128Mi + limits: + cpu: 500m + memory: 512Mi + livenessProbe: + exec: + command: ["pg_isready", "-U", "ai_service", "-d", "ai_service"] + initialDelaySeconds: 10 + periodSeconds: 10 + readinessProbe: + exec: + command: ["pg_isready", "-U", "ai_service", "-d", "ai_service"] + initialDelaySeconds: 5 + periodSeconds: 5 + volumeClaimTemplates: + - metadata: + name: pgdata + spec: + accessModes: ["ReadWriteOnce"] + storageClassName: local-path + resources: + requests: + storage: 10Gi diff --git a/k8s/secrets.yaml b/k8s/secrets.yaml index 140dd9c..9de00a2 100644 --- a/k8s/secrets.yaml +++ b/k8s/secrets.yaml @@ -1,8 +1,19 @@ apiVersion: v1 kind: Secret +metadata: + name: postgres-secret + namespace: ai-service +type: Opaque +stringData: + POSTGRES_USER: "ai_service" + POSTGRES_PASSWORD: "ai_service" + POSTGRES_DB: "ai_service" +--- +apiVersion: v1 +kind: Secret metadata: name: ai-service-secrets namespace: ai-service type: Opaque stringData: - DATABASE_URL: "postgres://ai_service:CHANGE_ME@postgres:5432/ai_service?sslmode=disable" + DATABASE_URL: "postgres://ai_service:ai_service@postgres:5432/ai_service?sslmode=disable"