diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..5ace4600 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,6 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" diff --git a/.github/workflows/ci-alerter.yml b/.github/workflows/ci-alerter.yml index b2c983ef..3190f777 100644 --- a/.github/workflows/ci-alerter.yml +++ b/.github/workflows/ci-alerter.yml @@ -18,7 +18,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - go-version: ['1.26'] + go-version: ['1.26.2'] postgres-version: ['14', '15', '16', '17', '18'] fail-fast: false @@ -38,16 +38,16 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - name: Set up Go ${{ matrix.go-version }} - uses: actions/setup-go@v6 + uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 with: go-version: ${{ matrix.go-version }} cache: false - name: Cache Go modules - uses: actions/cache@v5 + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 with: path: | ~/go/pkg/mod @@ -65,7 +65,7 @@ jobs: run: go mod download - name: Lint alerter code - if: matrix.go-version == '1.26' && matrix.postgres-version == '18' + if: matrix.go-version == '1.26.2' && matrix.postgres-version == '18' working-directory: alerter run: | go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest @@ -73,12 +73,12 @@ jobs: make lint - name: Run go vet - if: matrix.go-version == '1.26' && matrix.postgres-version == '18' + if: matrix.go-version == '1.26.2' && matrix.postgres-version == '18' working-directory: alerter/src run: go vet ./... - name: Check formatting - if: matrix.go-version == '1.26' && matrix.postgres-version == '18' + if: matrix.go-version == '1.26.2' && matrix.postgres-version == '18' working-directory: alerter run: | gofmt -l ./src > /tmp/gofmt.out @@ -111,22 +111,22 @@ jobs: run: make coverage - name: Generate coverage report - if: matrix.go-version == '1.26' && matrix.postgres-version == '18' + if: matrix.go-version == '1.26.2' && matrix.postgres-version == '18' working-directory: alerter/src run: | go tool cover -func=coverage.out - name: Upload build artifact - if: matrix.go-version == '1.26' && matrix.postgres-version == '18' - uses: actions/upload-artifact@v7 + if: matrix.go-version == '1.26.2' && matrix.postgres-version == '18' + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: name: ai-dba-alerter-linux-amd64 path: alerter/ai-dba-alerter retention-days: 7 - name: Upload coverage artifact - if: matrix.go-version == '1.26' && matrix.postgres-version == '18' - uses: actions/upload-artifact@v7 + if: matrix.go-version == '1.26.2' && matrix.postgres-version == '18' + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: name: alerter-coverage path: | diff --git a/.github/workflows/ci-client.yml b/.github/workflows/ci-client.yml index f1b77d94..3eb33a71 100644 --- a/.github/workflows/ci-client.yml +++ b/.github/workflows/ci-client.yml @@ -27,10 +27,10 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - name: Set up Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v6 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 with: node-version: ${{ matrix.node-version }} cache: 'npm' @@ -56,7 +56,7 @@ jobs: - name: Upload build artifact if: matrix.node-version == '20' - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: name: ai-dba-client-dist path: client/dist/ @@ -64,7 +64,7 @@ jobs: - name: Upload coverage artifact if: matrix.node-version == '20' - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: name: client-coverage path: client/coverage/ diff --git a/.github/workflows/ci-collector.yml b/.github/workflows/ci-collector.yml index 817304cd..f9252a67 100644 --- a/.github/workflows/ci-collector.yml +++ b/.github/workflows/ci-collector.yml @@ -18,7 +18,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - go-version: ['1.26'] + go-version: ['1.26.2'] postgres-version: ['14', '15', '16', '17', '18'] fail-fast: false @@ -38,16 +38,16 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - name: Set up Go ${{ matrix.go-version }} - uses: actions/setup-go@v6 + uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 with: go-version: ${{ matrix.go-version }} cache: false - name: Cache Go modules - uses: actions/cache@v5 + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 with: path: | ~/go/pkg/mod @@ -65,7 +65,7 @@ jobs: run: go mod download - name: Lint collector code - if: matrix.go-version == '1.26' && matrix.postgres-version == '18' + if: matrix.go-version == '1.26.2' && matrix.postgres-version == '18' working-directory: collector run: | go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest @@ -73,12 +73,12 @@ jobs: make lint - name: Run go vet - if: matrix.go-version == '1.26' && matrix.postgres-version == '18' + if: matrix.go-version == '1.26.2' && matrix.postgres-version == '18' working-directory: collector run: go vet ./... - name: Check formatting - if: matrix.go-version == '1.26' && matrix.postgres-version == '18' + if: matrix.go-version == '1.26.2' && matrix.postgres-version == '18' working-directory: collector run: | gofmt -l ./src > /tmp/gofmt.out @@ -111,22 +111,22 @@ jobs: run: make coverage - name: Generate coverage report - if: matrix.go-version == '1.26' && matrix.postgres-version == '18' + if: matrix.go-version == '1.26.2' && matrix.postgres-version == '18' working-directory: collector run: | go tool cover -func=src/coverage.out - name: Upload build artifact - if: matrix.go-version == '1.26' && matrix.postgres-version == '18' - uses: actions/upload-artifact@v7 + if: matrix.go-version == '1.26.2' && matrix.postgres-version == '18' + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: name: ai-dba-collector-linux-amd64 path: collector/ai-dba-collector retention-days: 7 - name: Upload coverage artifact - if: matrix.go-version == '1.26' && matrix.postgres-version == '18' - uses: actions/upload-artifact@v7 + if: matrix.go-version == '1.26.2' && matrix.postgres-version == '18' + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: name: collector-coverage path: | diff --git a/.github/workflows/ci-docker.yml b/.github/workflows/ci-docker.yml index c1073b07..02ea889b 100644 --- a/.github/workflows/ci-docker.yml +++ b/.github/workflows/ci-docker.yml @@ -39,10 +39,10 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3 - name: Create secret files run: | diff --git a/.github/workflows/ci-docs.yml b/.github/workflows/ci-docs.yml index ce0f95cf..d977e7eb 100644 --- a/.github/workflows/ci-docs.yml +++ b/.github/workflows/ci-docs.yml @@ -28,10 +28,10 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - name: Set up Python - uses: actions/setup-python@v6 + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 with: python-version: '3.11' cache: 'pip' @@ -48,7 +48,7 @@ jobs: mkdocs build -v - name: Upload documentation artifact - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: if-no-files-found: error name: ai-workbench-docs-site diff --git a/.github/workflows/ci-server.yml b/.github/workflows/ci-server.yml index f03dd585..5c6af0b7 100644 --- a/.github/workflows/ci-server.yml +++ b/.github/workflows/ci-server.yml @@ -18,7 +18,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - go-version: ['1.26'] + go-version: ['1.26.2'] postgres-version: ['14', '15', '16', '17', '18'] fail-fast: false @@ -38,16 +38,16 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - name: Set up Go ${{ matrix.go-version }} - uses: actions/setup-go@v6 + uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 with: go-version: ${{ matrix.go-version }} cache: false - name: Cache Go modules - uses: actions/cache@v5 + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 with: path: | ~/go/pkg/mod @@ -65,7 +65,7 @@ jobs: run: go mod download - name: Lint server code - if: matrix.go-version == '1.26' && matrix.postgres-version == '18' + if: matrix.go-version == '1.26.2' && matrix.postgres-version == '18' working-directory: server run: | go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest @@ -73,12 +73,12 @@ jobs: make lint - name: Run go vet - if: matrix.go-version == '1.26' && matrix.postgres-version == '18' + if: matrix.go-version == '1.26.2' && matrix.postgres-version == '18' working-directory: server/src run: go vet ./... - name: Check formatting - if: matrix.go-version == '1.26' && matrix.postgres-version == '18' + if: matrix.go-version == '1.26.2' && matrix.postgres-version == '18' working-directory: server run: | gofmt -l ./src > /tmp/gofmt.out @@ -111,22 +111,22 @@ jobs: run: make coverage - name: Generate coverage report - if: matrix.go-version == '1.26' && matrix.postgres-version == '18' + if: matrix.go-version == '1.26.2' && matrix.postgres-version == '18' working-directory: server/src run: | go tool cover -func=coverage.out - name: Upload build artifact - if: matrix.go-version == '1.26' && matrix.postgres-version == '18' - uses: actions/upload-artifact@v7 + if: matrix.go-version == '1.26.2' && matrix.postgres-version == '18' + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: name: ai-dba-server-linux-amd64 path: server/ai-dba-server retention-days: 7 - name: Upload coverage artifact - if: matrix.go-version == '1.26' && matrix.postgres-version == '18' - uses: actions/upload-artifact@v7 + if: matrix.go-version == '1.26.2' && matrix.postgres-version == '18' + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: name: server-coverage path: | diff --git a/.github/workflows/ci-walkthrough.yml b/.github/workflows/ci-walkthrough.yml index 9ce7e527..d98e1282 100644 --- a/.github/workflows/ci-walkthrough.yml +++ b/.github/workflows/ci-walkthrough.yml @@ -24,7 +24,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - name: Validate Docker Compose run: docker compose -f examples/walkthrough/docker-compose.yml config --quiet @@ -40,7 +40,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - name: Log in to GHCR uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3 diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index 809b95c2..958d2921 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -51,17 +51,17 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - name: Set up QEMU - uses: docker/setup-qemu-action@v3 + uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3 - name: Log in to GHCR if: github.event_name != 'pull_request' - uses: docker/login-action@v3 + uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} @@ -69,7 +69,7 @@ jobs: - name: Extract metadata id: meta - uses: docker/metadata-action@v5 + uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5 with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_SERVER }} tags: | @@ -82,7 +82,7 @@ jobs: type=raw,value=edge,enable=${{ github.ref == 'refs/heads/main' }} - name: Build and push - uses: docker/build-push-action@v5 + uses: docker/build-push-action@ca052bb54ab0790a636c9b5f226502c73d547a25 # v5 with: context: . file: server/Dockerfile @@ -105,17 +105,17 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - name: Set up QEMU - uses: docker/setup-qemu-action@v3 + uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3 - name: Log in to GHCR if: github.event_name != 'pull_request' - uses: docker/login-action@v3 + uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} @@ -123,7 +123,7 @@ jobs: - name: Extract metadata id: meta - uses: docker/metadata-action@v5 + uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5 with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_COLLECTOR }} tags: | @@ -136,7 +136,7 @@ jobs: type=raw,value=edge,enable=${{ github.ref == 'refs/heads/main' }} - name: Build and push - uses: docker/build-push-action@v5 + uses: docker/build-push-action@ca052bb54ab0790a636c9b5f226502c73d547a25 # v5 with: context: . file: collector/Dockerfile @@ -159,17 +159,17 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - name: Set up QEMU - uses: docker/setup-qemu-action@v3 + uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3 - name: Log in to GHCR if: github.event_name != 'pull_request' - uses: docker/login-action@v3 + uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} @@ -177,7 +177,7 @@ jobs: - name: Extract metadata id: meta - uses: docker/metadata-action@v5 + uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5 with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_ALERTER }} tags: | @@ -190,7 +190,7 @@ jobs: type=raw,value=edge,enable=${{ github.ref == 'refs/heads/main' }} - name: Build and push - uses: docker/build-push-action@v5 + uses: docker/build-push-action@ca052bb54ab0790a636c9b5f226502c73d547a25 # v5 with: context: . file: alerter/Dockerfile @@ -213,17 +213,17 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - name: Set up QEMU - uses: docker/setup-qemu-action@v3 + uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3 - name: Log in to GHCR if: github.event_name != 'pull_request' - uses: docker/login-action@v3 + uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} @@ -231,7 +231,7 @@ jobs: - name: Extract metadata id: meta - uses: docker/metadata-action@v5 + uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5 with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_CLIENT }} tags: | @@ -244,7 +244,7 @@ jobs: type=raw,value=edge,enable=${{ github.ref == 'refs/heads/main' }} - name: Build and push - uses: docker/build-push-action@v5 + uses: docker/build-push-action@ca052bb54ab0790a636c9b5f226502c73d547a25 # v5 with: context: . file: client/Dockerfile diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6c3b17bc..dfd5337b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -36,10 +36,10 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - name: Set up Node.js 20 - uses: actions/setup-node@v6 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 with: node-version: '20' cache: 'npm' @@ -52,7 +52,7 @@ jobs: run: npm run build - name: Upload client artifact - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: name: ai-dba-client-dist path: client/dist/ @@ -67,10 +67,10 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - name: Set up Python 3.11 - uses: actions/setup-python@v6 + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 with: python-version: '3.11' cache: 'pip' @@ -87,7 +87,7 @@ jobs: mkdocs build -v - name: Upload documentation artifact - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: name: ai-workbench-docs-site path: site/ @@ -107,16 +107,16 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - name: Set up Go 1.26 - uses: actions/setup-go@v6 + uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 with: - go-version: '1.26' + go-version: '1.26.2' cache: false - name: Cache Go modules (server) - uses: actions/cache@v5 + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 with: path: | ~/go/pkg/mod @@ -126,7 +126,7 @@ jobs: ${{ runner.os }}-go-1.26-release-server- - name: Cache Go modules (collector) - uses: actions/cache@v5 + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 with: path: | ~/go/pkg/mod @@ -136,7 +136,7 @@ jobs: ${{ runner.os }}-go-1.26-release-collector- - name: Cache Go modules (alerter) - uses: actions/cache@v5 + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 with: path: | ~/go/pkg/mod @@ -176,21 +176,21 @@ jobs: tar czf ai-dba-alerter-${{ matrix.goos }}-${{ matrix.goarch }}.tar.gz ai-dba-alerter - name: Upload server archive - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: name: ai-dba-server-${{ matrix.goos }}-${{ matrix.goarch }} path: ai-dba-server-${{ matrix.goos }}-${{ matrix.goarch }}.tar.gz retention-days: 1 - name: Upload collector archive - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: name: ai-dba-collector-${{ matrix.goos }}-${{ matrix.goarch }} path: ai-dba-collector-${{ matrix.goos }}-${{ matrix.goarch }}.tar.gz retention-days: 1 - name: Upload alerter archive - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: name: ai-dba-alerter-${{ matrix.goos }}-${{ matrix.goarch }} path: ai-dba-alerter-${{ matrix.goos }}-${{ matrix.goarch }}.tar.gz @@ -206,7 +206,7 @@ jobs: steps: - name: Download all artifacts - uses: actions/download-artifact@v8 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 with: path: artifacts @@ -238,7 +238,7 @@ jobs: cat release/checksums.txt - name: Create GitHub release - uses: softprops/action-gh-release@v2 + uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65 # v2 with: name: ${{ github.ref_name }} draft: false diff --git a/alerter/Dockerfile b/alerter/Dockerfile index fdaaf30b..25a15a0a 100644 --- a/alerter/Dockerfile +++ b/alerter/Dockerfile @@ -8,7 +8,7 @@ #-------------------------------------------------------------------------- # Stage 1: Build the alerter binary -FROM golang:1.26 AS builder +FROM golang:1.26.2 AS builder WORKDIR /build @@ -33,5 +33,9 @@ RUN mkdir -p /etc/pgedge COPY --from=builder /build/ai-dba-alerter /usr/local/bin/ai-dba-alerter +RUN groupadd -r appuser && useradd -r -g appuser -d /nonexistent -s /usr/sbin/nologin appuser && \ + chown -R appuser:appuser /etc/pgedge +USER appuser + ENTRYPOINT ["/usr/local/bin/ai-dba-alerter"] CMD ["--config", "/etc/pgedge/ai-dba-alerter.yaml"] diff --git a/client/Dockerfile b/client/Dockerfile index 63d8bfb7..9434bb35 100644 --- a/client/Dockerfile +++ b/client/Dockerfile @@ -28,4 +28,6 @@ COPY docker/nginx.conf /etc/nginx/conf.d/default.conf EXPOSE 80 +# nginx starts as root to bind port 80, then drops to the +# nginx user for worker processes via its own configuration. CMD ["nginx", "-g", "daemon off;"] diff --git a/client/src/components/Chart/Chart.tsx b/client/src/components/Chart/Chart.tsx index 6688b112..597481a9 100644 --- a/client/src/components/Chart/Chart.tsx +++ b/client/src/components/Chart/Chart.tsx @@ -252,19 +252,31 @@ export function Chart(props: ChartProps) { return options; }, [themedOptions, colorPalette, echartsOptions]); + /* Shared callback that fetches fresh chart data and updates + local state. Used by both the periodic timer and the manual + refresh toolbar button. */ + const refreshData = useCallback(() => { + if (!onDataRefresh) { + return; + } + onDataRefresh() + .then((refreshed) => { + setLiveData(refreshed); + }) + .catch((err: unknown) => { + console.error('Chart refresh failed:', err); + }); + }, [onDataRefresh]); + useEffect(() => { if (!liveUpdate || !onDataRefresh) { return; } - const id = setInterval(() => { - onDataRefresh().then((refreshed) => { - setLiveData(refreshed); - }); - }, updateInterval); + const id = setInterval(refreshData, updateInterval); return () => clearInterval(id); - }, [liveUpdate, onDataRefresh, updateInterval]); + }, [liveUpdate, onDataRefresh, updateInterval, refreshData]); const handleChartReady = useCallback( (instance: EChartsInstance) => { @@ -280,14 +292,6 @@ export function Chart(props: ChartProps) { } }, [exportFilename]); - const handleRefresh = useCallback(() => { - if (onDataRefresh) { - onDataRefresh().then((refreshed) => { - setLiveData(refreshed); - }); - } - }, [onDataRefresh]); - const handleAnalyze = useCallback(() => setAnalysisOpen(true), []); const handleAnalysisClose = useCallback(() => setAnalysisOpen(false), []); @@ -319,7 +323,7 @@ export function Chart(props: ChartProps) { showRefresh={liveUpdate} onAnalyze={handleAnalyze} onExport={handleExport} - onRefresh={handleRefresh} + onRefresh={refreshData} /> )} = ({ code, theme }) => { const [copied, setCopied] = useState(false); - const handleCopy = useCallback(() => { - navigator.clipboard.writeText(code).then(() => { + const handleCopy = useCallback(async () => { + try { + await navigator.clipboard.writeText(code); setCopied(true); setTimeout(() => setCopied(false), 2000); - }); + } catch (err) { + console.error('Failed to copy code:', err); + } }, [code]); return ( diff --git a/collector/Dockerfile b/collector/Dockerfile index 02399e30..e005551d 100644 --- a/collector/Dockerfile +++ b/collector/Dockerfile @@ -8,7 +8,7 @@ #-------------------------------------------------------------------------- # Stage 1: Build the collector binary -FROM golang:1.26 AS builder +FROM golang:1.26.2 AS builder WORKDIR /build @@ -33,5 +33,9 @@ RUN mkdir -p /etc/pgedge COPY --from=builder /build/ai-dba-collector /usr/local/bin/ai-dba-collector +RUN groupadd -r appuser && useradd -r -g appuser -d /nonexistent -s /usr/sbin/nologin appuser && \ + chown -R appuser:appuser /etc/pgedge +USER appuser + ENTRYPOINT ["/usr/local/bin/ai-dba-collector"] CMD ["--config", "/etc/pgedge/ai-dba-collector.yaml"] diff --git a/requirements.txt b/requirements.txt index 1886fa79..02bfdb22 100644 --- a/requirements.txt +++ b/requirements.txt @@ -23,17 +23,17 @@ packaging==25.0 paginate==0.5.7 pathspec==0.12.1 platformdirs==4.3.8 -Pygments==2.19.2 +Pygments==2.20.0 pymdown-extensions==10.16.1 python-dateutil==2.9.0.post0 python-slugify==8.0.4 PyYAML==6.0.2 pyyaml_env_tag==1.1 -requests==2.32.5 +requests==2.33.1 six==1.17.0 soupsieve==2.8 text-unidecode==1.3 typing-inspect==0.8.0 typing_extensions==4.14.1 -urllib3==2.5.0 +urllib3==2.6.3 watchdog==6.0.0 diff --git a/server/Dockerfile b/server/Dockerfile index f6b2bb45..46de0a5a 100644 --- a/server/Dockerfile +++ b/server/Dockerfile @@ -8,7 +8,7 @@ #-------------------------------------------------------------------------- # Stage 1: Build the server binary -FROM golang:1.26 AS builder +FROM golang:1.26.2 AS builder WORKDIR /build @@ -29,6 +29,7 @@ RUN CGO_ENABLED=0 go build -ldflags="-s -w" -o /build/ai-dba-server ./cmd/mcp-se # Stage 2: Runtime image FROM debian:bookworm-slim +# hadolint ignore=DL3008 RUN apt-get update && \ apt-get install -y --no-install-recommends ca-certificates && \ rm -rf /var/lib/apt/lists/* @@ -37,8 +38,13 @@ RUN mkdir -p /etc/pgedge /data COPY --from=builder /build/ai-dba-server /usr/local/bin/ai-dba-server +RUN mkdir -p /usr/local/bin/data && \ + groupadd -r appuser && useradd -r -g appuser -d /nonexistent -s /usr/sbin/nologin appuser && \ + chown -R appuser:appuser /etc/pgedge /data /usr/local/bin/data +USER appuser + EXPOSE 8080 VOLUME /data ENTRYPOINT ["/usr/local/bin/ai-dba-server"] -CMD ["--config", "/etc/pgedge/ai-dba-server.yaml"] +CMD ["--config", "/etc/pgedge/ai-dba-server.yaml", "--data-dir", "/data"] diff --git a/tools/webhook_listener.py b/tools/webhook_listener.py index 4bcc1d32..f0f35d66 100755 --- a/tools/webhook_listener.py +++ b/tools/webhook_listener.py @@ -60,7 +60,7 @@ def log_message(self, format, *args): def main(): port = int(sys.argv[1]) if len(sys.argv) > 1 else 9999 - server = HTTPServer(("0.0.0.0", port), WebhookHandler) + server = HTTPServer(("127.0.0.1", port), WebhookHandler) print(f"Webhook listener running on http://localhost:{port}") print("Press Ctrl+C to stop.\n") try: