Skip to content

feat: Add GitLab Autofix support and build infrastructure#1

Open
dnplkndll wants to merge 6 commits intomasterfrom
26.1.0-gitlab-seer
Open

feat: Add GitLab Autofix support and build infrastructure#1
dnplkndll wants to merge 6 commits intomasterfrom
26.1.0-gitlab-seer

Conversation

@dnplkndll
Copy link

@dnplkndll dnplkndll commented Jan 30, 2026

Summary

  • Add GitLab and integrations:gitlab to supportedProviders in autofix utils
  • Add build infrastructure for custom Kencove images

Changes

GitLab Autofix Support

  • Modified static/app/components/events/autofix/utils.tsx to include GitLab in supported providers

Build Infrastructure

  • cloudbuild.yaml - GCP Cloud Build configuration
  • self-hosted/Dockerfile.kencove - Multi-stage Dockerfile
  • build-and-push.sh - Convenience build script
  • .github/workflows/build-kencove.yml - GitHub Actions workflow

Test plan

  • Built and pushed image v26.1.0-gitlab to GCP Artifact Registry
  • Deployed to sentry-web in production
  • Test GitLab Autofix with a GitLab repository

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added GitLab as a supported autofix provider.
  • Chores

    • Added automated build-and-push CI workflow, local build script, and cloud build config for publishing a self-hosted image (multi-stage builds, tagging, and push).
    • Introduced self-hosted image build definitions and a patched runtime image for deployment.
    • Added environment-driven configuration and feature-flag defaults for SEER endpoints and shared secret handling.
  • Documentation

    • Added guidance for the Kencove fork and custom image build/sync workflows.

✏️ Tip: You can customize this high-level summary in your review settings.

dnplkndll and others added 2 commits January 29, 2026 09:46
Add 'gitlab' and 'integrations:gitlab' to supportedProviders array
to enable GitLab repositories for Seer Autofix feature.
- Add cloudbuild.yaml for GCP Cloud Build
- Add Dockerfile.kencove multi-stage build
- Add build-and-push.sh convenience script
- Add GitHub Actions workflow for CI/CD
- Update AGENTS.md with build instructions

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@github-actions
Copy link

🚨 Warning: This pull request contains Frontend and Backend changes!

It's discouraged to make changes to Sentry's Frontend and Backend in a single pull request. The Frontend and Backend are not atomically deployed. If the changes are interdependent of each other, they must be separated into two pull requests and be made forward or backwards compatible, such that the Backend or Frontend can be safely deployed independently.

Have questions? Please ask in the #discuss-dev-infra channel.

@coderabbitai
Copy link

coderabbitai bot commented Jan 30, 2026

📝 Walkthrough

Walkthrough

Adds CI/CD and image-build tooling and documentation for a Kencove Sentry fork: a GitHub Actions workflow, Cloud Build config, build-and-push script, two Dockerfiles (multi-stage + patch), a runtime pre-import config patch, a frontend autofix provider update (GitLab), and AGENTS.md docs.

Changes

Cohort / File(s) Summary
CI/CD workflow & scripts
​.github/workflows/build-kencove.yml, build-and-push.sh, cloudbuild.yaml
New GitHub Actions workflow and helper scripts to build and publish the Kencove Sentry image. Supports optional tag input, Workload Identity auth, Cloud Build or local Docker build, and pushes a tag + latest to Google Artifact Registry.
Docker build files
self-hosted/Dockerfile.kencove, self-hosted/Dockerfile.patch
Adds a multi-stage Dockerfile that builds frontend assets then assembles runtime image, and a patch Dockerfile that layers a modified utils file onto an existing Sentry base and adds build metadata.
Frontend autofix provider
static/app/components/events/autofix/utils.tsx
Adds gitlab and integrations:gitlab to supported autofix providers, enabling GitLab as a recognized provider.
Runtime config patch
self-hosted/sentry.conf.py
Pre-import patch to populate SEER_* URL variables and SEER_RPC_SHARED_SECRET from environment variables before importing sentry.conf.server; also disables the explorer-based Seer feature flag.
Documentation
AGENTS.md
Adds a "Kencove Fork" subsection describing the fork, the GitLab autofix change, image build instructions, sync guidance, and related repository notes.

Sequence Diagram(s)

mermaid
sequenceDiagram
rect rgba(63,123,255,0.5)
participant GH as GitHub Actions
end
rect rgba(40,167,69,0.5)
participant Repo as Source Repo
end
rect rgba(255,193,7,0.5)
participant CB as Cloud Build
end
rect rgba(220,53,69,0.5)
participant Docker as Local Docker
end
rect rgba(102,16,242,0.5)
participant GAR as Artifact Registry
end

GH->>Repo: checkout + setup Node/PNPM/Python
GH->>GH: build frontend assets
alt Cloud Build path
GH->>CB: submit cloudbuild.yaml (TAG, COMMIT_SHA)
CB->>GAR: push images (tag, latest)
else Local Docker path
GH->>Docker: docker build using Dockerfile.self-hosted (build-args)
Docker->>GAR: push images (tag, latest)
end
GAR-->>GH: return image refs
GH->>GH: output build summary

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐇 I hopped through builds and stitched a thread,

Frontend baked and Docker fed,
GitLab now hops into the fix,
Images sailing off in clicks,
A tiny rabbit CI-fed quidditch.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the two main changes: adding GitLab Autofix support and build infrastructure for Kencove custom images.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 26.1.0-gitlab-seer

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In @.github/workflows/build-kencove.yml:
- Around line 92-102: The workflow is referencing the wrong Dockerfile: update
the docker build invocation in the "Build and push Docker image" step to use
self-hosted/Dockerfile.kencove (instead of self-hosted/Dockerfile) so it matches
the PR's new Dockerfile.kencove; also remove or skip the earlier frontend build
steps that produce assets (the steps building frontend assets before the docker
build) since Dockerfile.kencove includes a frontend-builder stage, or
alternatively keep the frontend steps only if you intentionally want to feed
prebuilt assets into a Dockerfile that expects them—ensure consistency between
the docker build command and the Dockerfile used.

In `@build-and-push.sh`:
- Around line 16-37: The script assigns TAG from the first arg (TAG="${1:-$(git
rev-parse --short HEAD)}") so passing "--local" sets TAG to "--local"; move
argument parsing ahead of TAG assignment or detect the "--local" flag first:
check the condition used (if [[ "${1:-}" == "--local" ]]) before computing TAG,
and when building locally ensure the docker -t uses a real tag computed from
commit (or default to $(git rev-parse --short HEAD)) rather than "${1:-}".
Update references to TAG and the local-build docker -t flags so TAG is not set
to the literal "--local" (affecting variables TAG, the if-check, and the docker
build -t invocations).

In `@self-hosted/Dockerfile.patch`:
- Around line 13-19: The Dockerfile is copying a TypeScript source file using
the COPY instruction into the dist/ bundle path (COPY
static/app/components/events/autofix/utils.tsx -> /usr/src/sentry/.../dist/...),
which won't affect the bundled frontend because the image contains compiled JS;
either remove this Dockerfile (if Dockerfile.kencove is the correct build path)
or update the file to clearly mark it as non-functional/experimental and remove
the failing COPY of static/app/components/events/autofix/utils.tsx (or change
the build to patch the actual compiled JS bundle instead), and add a README
comment referencing Dockerfile.kencove as the supported path.
🧹 Nitpick comments (3)
.github/workflows/build-kencove.yml (3)

40-44: Address static analysis warning: quote the variable.

Shellcheck SC2086 warns about unquoted variable expansion on line 44. While $PWD is unlikely to contain spaces in this context, quoting is safer.

Proposed fix
       - name: Setup Python venv
         run: |
           uv venv
           source .venv/bin/activate
-          echo "PATH=$PWD/.venv/bin:$PATH" >> $GITHUB_ENV
+          echo "PATH=$PWD/.venv/bin:$PATH" >> "$GITHUB_ENV"

83-90: Address static analysis warnings: quote variables.

Shellcheck SC2086 warns about unquoted variable expansion. While GitHub Actions contexts are generally safe, quoting improves robustness.

Proposed fix
       - name: Determine image tag
         id: tag
         run: |
-          if [ -n "${{ github.event.inputs.tag }}" ]; then
-            echo "tag=${{ github.event.inputs.tag }}" >> $GITHUB_OUTPUT
+          if [ -n "${{ github.event.inputs.tag }}" ]; then
+            echo "tag=${{ github.event.inputs.tag }}" >> "$GITHUB_OUTPUT"
           else
-            echo "tag=${{ github.sha }}" >> $GITHUB_OUTPUT
+            echo "tag=${{ github.sha }}" >> "$GITHUB_OUTPUT"
           fi

104-107: Address static analysis warning: quote variable.

Shellcheck SC2086 warns about unquoted $GITHUB_STEP_SUMMARY.

Proposed fix
       - name: Output image info
         run: |
-          echo "## Build Complete" >> $GITHUB_STEP_SUMMARY
-          echo "Image: \`${{ env.REGION }}-docker.pkg.dev/${{ env.PROJECT_ID }}/${{ env.REPOSITORY }}/${{ env.IMAGE_NAME }}:${{ steps.tag.outputs.tag }}\`" >> $GITHUB_STEP_SUMMARY
+          echo "## Build Complete" >> "$GITHUB_STEP_SUMMARY"
+          echo "Image: \`${{ env.REGION }}-docker.pkg.dev/${{ env.PROJECT_ID }}/${{ env.REPOSITORY }}/${{ env.IMAGE_NAME }}:${{ steps.tag.outputs.tag }}\`" >> "$GITHUB_STEP_SUMMARY"

Comment on lines +92 to +102
- name: Build and push Docker image
run: |
docker build \
-t ${{ env.REGION }}-docker.pkg.dev/${{ env.PROJECT_ID }}/${{ env.REPOSITORY }}/${{ env.IMAGE_NAME }}:${{ steps.tag.outputs.tag }} \
-t ${{ env.REGION }}-docker.pkg.dev/${{ env.PROJECT_ID }}/${{ env.REPOSITORY }}/${{ env.IMAGE_NAME }}:latest \
-f self-hosted/Dockerfile \
--build-arg SOURCE_COMMIT=${{ github.sha }} \
.

docker push ${{ env.REGION }}-docker.pkg.dev/${{ env.PROJECT_ID }}/${{ env.REPOSITORY }}/${{ env.IMAGE_NAME }}:${{ steps.tag.outputs.tag }}
docker push ${{ env.REGION }}-docker.pkg.dev/${{ env.PROJECT_ID }}/${{ env.REPOSITORY }}/${{ env.IMAGE_NAME }}:latest
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Incorrect Dockerfile path: should be Dockerfile.kencove.

Line 97 references self-hosted/Dockerfile, but the PR introduces self-hosted/Dockerfile.kencove for building the Kencove image. The workflow also builds frontend assets (lines 63-69), but Dockerfile.kencove has its own frontend-builder stage—leading to redundant builds or inconsistency.

Proposed fix

Either use Dockerfile.kencove (and remove the frontend build steps since it builds internally):

           docker build \
             -t ${{ env.REGION }}-docker.pkg.dev/${{ env.PROJECT_ID }}/${{ env.REPOSITORY }}/${{ env.IMAGE_NAME }}:${{ steps.tag.outputs.tag }} \
             -t ${{ env.REGION }}-docker.pkg.dev/${{ env.PROJECT_ID }}/${{ env.REPOSITORY }}/${{ env.IMAGE_NAME }}:latest \
-            -f self-hosted/Dockerfile \
+            -f self-hosted/Dockerfile.kencove \
             --build-arg SOURCE_COMMIT=${{ github.sha }} \
             .

Or verify that self-hosted/Dockerfile exists and expects the pre-built frontend from the workflow steps.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- name: Build and push Docker image
run: |
docker build \
-t ${{ env.REGION }}-docker.pkg.dev/${{ env.PROJECT_ID }}/${{ env.REPOSITORY }}/${{ env.IMAGE_NAME }}:${{ steps.tag.outputs.tag }} \
-t ${{ env.REGION }}-docker.pkg.dev/${{ env.PROJECT_ID }}/${{ env.REPOSITORY }}/${{ env.IMAGE_NAME }}:latest \
-f self-hosted/Dockerfile \
--build-arg SOURCE_COMMIT=${{ github.sha }} \
.
docker push ${{ env.REGION }}-docker.pkg.dev/${{ env.PROJECT_ID }}/${{ env.REPOSITORY }}/${{ env.IMAGE_NAME }}:${{ steps.tag.outputs.tag }}
docker push ${{ env.REGION }}-docker.pkg.dev/${{ env.PROJECT_ID }}/${{ env.REPOSITORY }}/${{ env.IMAGE_NAME }}:latest
- name: Build and push Docker image
run: |
docker build \
-t ${{ env.REGION }}-docker.pkg.dev/${{ env.PROJECT_ID }}/${{ env.REPOSITORY }}/${{ env.IMAGE_NAME }}:${{ steps.tag.outputs.tag }} \
-t ${{ env.REGION }}-docker.pkg.dev/${{ env.PROJECT_ID }}/${{ env.REPOSITORY }}/${{ env.IMAGE_NAME }}:latest \
-f self-hosted/Dockerfile.kencove \
--build-arg SOURCE_COMMIT=${{ github.sha }} \
.
docker push ${{ env.REGION }}-docker.pkg.dev/${{ env.PROJECT_ID }}/${{ env.REPOSITORY }}/${{ env.IMAGE_NAME }}:${{ steps.tag.outputs.tag }}
docker push ${{ env.REGION }}-docker.pkg.dev/${{ env.PROJECT_ID }}/${{ env.REPOSITORY }}/${{ env.IMAGE_NAME }}:latest
🤖 Prompt for AI Agents
In @.github/workflows/build-kencove.yml around lines 92 - 102, The workflow is
referencing the wrong Dockerfile: update the docker build invocation in the
"Build and push Docker image" step to use self-hosted/Dockerfile.kencove
(instead of self-hosted/Dockerfile) so it matches the PR's new
Dockerfile.kencove; also remove or skip the earlier frontend build steps that
produce assets (the steps building frontend assets before the docker build)
since Dockerfile.kencove includes a frontend-builder stage, or alternatively
keep the frontend steps only if you intentionally want to feed prebuilt assets
into a Dockerfile that expects them—ensure consistency between the docker build
command and the Dockerfile used.

Comment on lines +16 to +37
TAG="${1:-$(git rev-parse --short HEAD)}"

FULL_IMAGE="${REGION}-docker.pkg.dev/${PROJECT_ID}/${REPOSITORY}/${IMAGE_NAME}"

echo "=== Kencove Sentry Build ==="
echo "Image: ${FULL_IMAGE}:${TAG}"
echo "Commit: $(git rev-parse HEAD)"
echo ""

if [[ "${1:-}" == "--local" ]]; then
echo "Building locally (not pushing)..."
docker build \
-t "${IMAGE_NAME}:${TAG}" \
-t "${IMAGE_NAME}:latest" \
-f self-hosted/Dockerfile.kencove \
--build-arg SOURCE_COMMIT="$(git rev-parse HEAD)" \
--progress=plain \
.
echo ""
echo "Local build complete: ${IMAGE_NAME}:${TAG}"
exit 0
fi
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Bug: --local flag is incorrectly assigned as the image tag.

When the user runs ./build-and-push.sh --local, Line 16 sets TAG="--local" before the check on Line 25. The local build then tags the image as sentry:--local, which is likely unintended.

Proposed fix
-TAG="${1:-$(git rev-parse --short HEAD)}"
+# Handle --local flag first, then determine tag
+LOCAL_BUILD=false
+if [[ "${1:-}" == "--local" ]]; then
+    LOCAL_BUILD=true
+    TAG="${2:-$(git rev-parse --short HEAD)}"
+else
+    TAG="${1:-$(git rev-parse --short HEAD)}"
+fi

 FULL_IMAGE="${REGION}-docker.pkg.dev/${PROJECT_ID}/${REPOSITORY}/${IMAGE_NAME}"

 echo "=== Kencove Sentry Build ==="
 echo "Image: ${FULL_IMAGE}:${TAG}"
 echo "Commit: $(git rev-parse HEAD)"
 echo ""

-if [[ "${1:-}" == "--local" ]]; then
+if [[ "$LOCAL_BUILD" == "true" ]]; then
     echo "Building locally (not pushing)..."
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
TAG="${1:-$(git rev-parse --short HEAD)}"
FULL_IMAGE="${REGION}-docker.pkg.dev/${PROJECT_ID}/${REPOSITORY}/${IMAGE_NAME}"
echo "=== Kencove Sentry Build ==="
echo "Image: ${FULL_IMAGE}:${TAG}"
echo "Commit: $(git rev-parse HEAD)"
echo ""
if [[ "${1:-}" == "--local" ]]; then
echo "Building locally (not pushing)..."
docker build \
-t "${IMAGE_NAME}:${TAG}" \
-t "${IMAGE_NAME}:latest" \
-f self-hosted/Dockerfile.kencove \
--build-arg SOURCE_COMMIT="$(git rev-parse HEAD)" \
--progress=plain \
.
echo ""
echo "Local build complete: ${IMAGE_NAME}:${TAG}"
exit 0
fi
# Handle --local flag first, then determine tag
LOCAL_BUILD=false
if [[ "${1:-}" == "--local" ]]; then
LOCAL_BUILD=true
TAG="${2:-$(git rev-parse --short HEAD)}"
else
TAG="${1:-$(git rev-parse --short HEAD)}"
fi
FULL_IMAGE="${REGION}-docker.pkg.dev/${PROJECT_ID}/${REPOSITORY}/${IMAGE_NAME}"
echo "=== Kencove Sentry Build ==="
echo "Image: ${FULL_IMAGE}:${TAG}"
echo "Commit: $(git rev-parse HEAD)"
echo ""
if [[ "$LOCAL_BUILD" == "true" ]]; then
echo "Building locally (not pushing)..."
docker build \
-t "${IMAGE_NAME}:${TAG}" \
-t "${IMAGE_NAME}:latest" \
-f self-hosted/Dockerfile.kencove \
--build-arg SOURCE_COMMIT="$(git rev-parse HEAD)" \
--progress=plain \
.
echo ""
echo "Local build complete: ${IMAGE_NAME}:${TAG}"
exit 0
fi
🤖 Prompt for AI Agents
In `@build-and-push.sh` around lines 16 - 37, The script assigns TAG from the
first arg (TAG="${1:-$(git rev-parse --short HEAD)}") so passing "--local" sets
TAG to "--local"; move argument parsing ahead of TAG assignment or detect the
"--local" flag first: check the condition used (if [[ "${1:-}" == "--local" ]])
before computing TAG, and when building locally ensure the docker -t uses a real
tag computed from commit (or default to $(git rev-parse --short HEAD)) rather
than "${1:-}". Update references to TAG and the local-build docker -t flags so
TAG is not set to the literal "--local" (affecting variables TAG, the if-check,
and the docker build -t invocations).

Comment on lines +13 to +19
# Copy patched autofix utils with GitLab support
# The change adds 'gitlab' and 'integrations:gitlab' to supportedProviders
COPY static/app/components/events/autofix/utils.tsx \
/usr/src/sentry/src/sentry/static/sentry/dist/app/components/events/autofix/utils.tsx

# Note: The above path may need adjustment - the built JS is in dist/
# Let's find the actual location and patch the compiled JS instead
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Copying TypeScript source to dist/ directory will not work.

The official Sentry image contains compiled/bundled JavaScript assets, not TypeScript sources. The frontend is bundled by webpack/rspack into JS bundles during build time. Copying a .tsx file into the dist/ directory will have no effect—the application loads the bundled JavaScript, not individual source files.

The comment on lines 18-19 acknowledges this uncertainty. This approach cannot work as intended. Use Dockerfile.kencove (which builds from source) instead, or consider this Dockerfile deprecated/non-functional.

Suggested action

Either:

  1. Remove this Dockerfile if Dockerfile.kencove is the intended build path
  2. Or add a note marking this as non-functional/experimental:
 # Dockerfile that patches the official Sentry image with GitLab Autofix support
-# Much faster than rebuilding from source (~2 minutes vs ~45 minutes)
+# WARNING: This approach does NOT work - TSX files cannot be patched into compiled bundles
+# Use Dockerfile.kencove instead which builds from source
 #
 # Build: docker build -f self-hosted/Dockerfile.patch -t sentry:kencove .
🤖 Prompt for AI Agents
In `@self-hosted/Dockerfile.patch` around lines 13 - 19, The Dockerfile is copying
a TypeScript source file using the COPY instruction into the dist/ bundle path
(COPY static/app/components/events/autofix/utils.tsx ->
/usr/src/sentry/.../dist/...), which won't affect the bundled frontend because
the image contains compiled JS; either remove this Dockerfile (if
Dockerfile.kencove is the correct build path) or update the file to clearly mark
it as non-functional/experimental and remove the failing COPY of
static/app/components/events/autofix/utils.tsx (or change the build to patch the
actual compiled JS bundle instead), and add a README comment referencing
Dockerfile.kencove as the supported path.

Modifies sentry.conf.py to patch sentry.conf.server module attributes
BEFORE the wildcard import. This ensures all code that imports Seer
URLs from the server module sees the correct service URLs.

Adds SEER_URL and SEER_RPC_SHARED_SECRET environment variable support.
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@self-hosted/sentry.conf.py`:
- Around line 14-22: The patch introduces two non-existent attributes on
sentry.conf.server—SEER_SIMILARITY_URL and SEER_SEVERITY_URL—so update the
changes to either remove those two assignments or replace them with the real
upstream symbols: use SEER_SIMILAR_ISSUES_URL for the similarity endpoint and do
not create a SEER_SEVERITY_URL; instead ensure any severity-related
configuration sets SEER_SEVERITY_TIMEOUT and/or SEER_SEVERITY_RETRIES as
appropriate (adjust the assignments around
_sentry_server.SEER_SIMILAR_ISSUES_URL, _sentry_server.SEER_SEVERITY_TIMEOUT,
and _sentry_server.SEER_SEVERITY_RETRIES or simply drop the invalid lines).
🧹 Nitpick comments (1)
self-hosted/sentry.conf.py (1)

23-23: Simplify duplicate environment variable lookup.

The SEER_RPC_SHARED_SECRET line calls os.environ.get() twice for the same key. This can be consolidated for clarity and minor efficiency.

♻️ Suggested simplification
-_sentry_server.SEER_RPC_SHARED_SECRET = os.environ.get("SEER_RPC_SHARED_SECRET", "").split(",") if os.environ.get("SEER_RPC_SHARED_SECRET") else None
+_seer_secret = os.environ.get("SEER_RPC_SHARED_SECRET")
+_sentry_server.SEER_RPC_SHARED_SECRET = _seer_secret.split(",") if _seer_secret else None

Comment on lines +14 to +22
import sentry.conf.server as _sentry_server
_sentry_server.SEER_DEFAULT_URL = os.environ.get("SEER_URL", "http://seer:9091")
_sentry_server.SEER_AUTOFIX_URL = _sentry_server.SEER_DEFAULT_URL
_sentry_server.SEER_SIMILARITY_URL = _sentry_server.SEER_DEFAULT_URL
_sentry_server.SEER_ANOMALY_DETECTION_URL = _sentry_server.SEER_DEFAULT_URL
_sentry_server.SEER_SEVERITY_URL = _sentry_server.SEER_DEFAULT_URL
_sentry_server.SEER_BREAKPOINT_DETECTION_URL = _sentry_server.SEER_DEFAULT_URL
_sentry_server.SEER_GROUPING_URL = _sentry_server.SEER_DEFAULT_URL
_sentry_server.SEER_SUMMARIZATION_URL = _sentry_server.SEER_DEFAULT_URL
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, let's find the sentry.conf.server module
find . -path './self-hosted' -prune -o -type f -name "server.py" -print | grep -E "conf|sentry" | head -20

Repository: kencove/sentry

Length of output: 85


🏁 Script executed:

# Also check the structure of the sentry directory
git ls-files | grep -E "^sentry/conf" | head -20

Repository: kencove/sentry

Length of output: 40


🏁 Script executed:

# Search for SEER_DEFAULT_URL definition in the codebase (excluding self-hosted)
rg -n "SEER_DEFAULT_URL\s*=" --type py | grep -v "self-hosted"

Repository: kencove/sentry

Length of output: 156


🏁 Script executed:

# Check if sentry.conf.server exists and list its structure
git ls-files | grep "conf/server.py"

Repository: kencove/sentry

Length of output: 83


🏁 Script executed:

# Search for all SEER_* attributes in server.py
rg "SEER_" src/sentry/conf/server.py -n

Repository: kencove/sentry

Length of output: 2743


🏁 Script executed:

# Check if __all__ is defined in server.py and what it contains
rg "__all__" src/sentry/conf/server.py -A 30

Repository: kencove/sentry

Length of output: 40


🏁 Script executed:

# Look at the section around SEER_DEFAULT_URL to understand context
sed -n '2810,2830p' src/sentry/conf/server.py

Repository: kencove/sentry

Length of output: 994


🏁 Script executed:

# Check if __all__ exists at the beginning of the file
head -100 src/sentry/conf/server.py | rg "__all__"

Repository: kencove/sentry

Length of output: 40


🏁 Script executed:

# Specifically search for SEER_SIMILARITY_URL and SEER_SEVERITY_URL
rg "SEER_SIMILARITY_URL|SEER_SEVERITY_URL" src/sentry/conf/server.py

Repository: kencove/sentry

Length of output: 40


🏁 Script executed:

# Check what is actually being imported/used in the self-hosted config file
cat -n self-hosted/sentry.conf.py | head -30

Repository: kencove/sentry

Length of output: 1660


🏁 Script executed:

# Let's check the exact list of SEER_* attributes that are actually defined
# versus those being set in the self-hosted config
rg "^SEER_\w+" src/sentry/conf/server.py -o | sort | uniq

Repository: kencove/sentry

Length of output: 1032


🏁 Script executed:

# Double-check for SEER_SIMILARITY_URL and SEER_SEVERITY_URL variations
rg "SEER.*SIMILARITY|SEER.*SEVERITY" src/sentry/conf/server.py -i

Repository: kencove/sentry

Length of output: 653


🏁 Script executed:

# Check if __all__ is defined anywhere in server.py
rg "^__all__" src/sentry/conf/server.py

Repository: kencove/sentry

Length of output: 40


🏁 Script executed:

# Check if there are any imports using SEER_SIMILARITY_URL or SEER_SEVERITY_URL
rg "from sentry.conf.server import|SEER_SIMILARITY_URL|SEER_SEVERITY_URL" --type py | grep -v "self-hosted"

Repository: kencove/sentry

Length of output: 5176


🏁 Script executed:

# Check if SEER_SIMILARITY_URL or SEER_SEVERITY_URL are used anywhere in the codebase
rg "SEER_SIMILARITY_URL|SEER_SEVERITY_URL" src/

Repository: kencove/sentry

Length of output: 40


🏁 Script executed:

# Check what's actually imported from server in the similar_issues and grouping modules
cat -n src/sentry/seer/similarity/similar_issues.py | head -40

Repository: kencove/sentry

Length of output: 1560


🏁 Script executed:

# Check the exact attributes being used in similarity and anomaly detection modules
cat -n src/sentry/seer/similarity/grouping_records.py | head -40

Repository: kencove/sentry

Length of output: 1366


🏁 Script executed:

# Check what similarity-related attributes are imported and used
rg "from sentry.conf.server import" src/sentry/seer/ -A 10

Repository: kencove/sentry

Length of output: 7115


🏁 Script executed:

# Check if SEER_SEVERITY_URL is used anywhere or if severity settings are different
rg "SEER_SEVERITY" src/sentry/ --type py | head -20

Repository: kencove/sentry

Length of output: 439


🏁 Script executed:

# Final check: verify if SEER_SIMILARITY_URL or SEER_SEVERITY_URL are actually used anywhere
rg "settings\.SEER_SIMILARITY_URL|settings\.SEER_SEVERITY_URL|django\.conf\.settings\.SEER_SIMILARITY|django\.conf\.settings\.SEER_SEVERITY" src/ --type py

Repository: kencove/sentry

Length of output: 40


🏁 Script executed:

# Check what URL constants are actually used for similarity features
rg "SEER.*URL.*SIMILAR|SIMILAR.*URL" src/sentry/seer/ --type py

Repository: kencove/sentry

Length of output: 598


🏁 Script executed:

# Final verification: check if SEER_SIMILAR_ISSUES_URL depends on SEER_DEFAULT_URL
sed -n '3137,3150p' src/sentry/conf/server.py

Repository: kencove/sentry

Length of output: 736


Two of the patched attributes do not exist in sentry.conf.server.

SEER_SIMILARITY_URL and SEER_SEVERITY_URL are not defined in the upstream module. The actual similarity endpoint is SEER_SIMILAR_ISSUES_URL (a constructed URL path), and severity configuration uses SEER_SEVERITY_TIMEOUT and SEER_SEVERITY_RETRIES constants instead of a URL. These non-existent attributes will be created dynamically on the module, but dynamically patching undefined attributes is unreliable and indicates the patch is incomplete. Either remove these two lines or correct them to patch the actual attributes used by the codebase.

🤖 Prompt for AI Agents
In `@self-hosted/sentry.conf.py` around lines 14 - 22, The patch introduces two
non-existent attributes on sentry.conf.server—SEER_SIMILARITY_URL and
SEER_SEVERITY_URL—so update the changes to either remove those two assignments
or replace them with the real upstream symbols: use SEER_SIMILAR_ISSUES_URL for
the similarity endpoint and do not create a SEER_SEVERITY_URL; instead ensure
any severity-related configuration sets SEER_SEVERITY_TIMEOUT and/or
SEER_SEVERITY_RETRIES as appropriate (adjust the assignments around
_sentry_server.SEER_SIMILAR_ISSUES_URL, _sentry_server.SEER_SEVERITY_TIMEOUT,
and _sentry_server.SEER_SEVERITY_RETRIES or simply drop the invalid lines).

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@self-hosted/Dockerfile.kencove`:
- Around line 145-148: The sed expression that replaces the
SEER_RPC_SHARED_SECRET line uses | as delimiter but the replacement pattern
contains | characters (the type union), causing sed to misparse and fail; update
the sed command that targets SEER_RPC_SHARED_SECRET so it uses a different
delimiter (e.g., @ or #) or properly escapes the pipe characters in the pattern,
keeping the intended replacement logic (set SEER_RPC_SHARED_SECRET =
os.environ.get("SEER_RPC_SHARED_SECRET", "").split(",") if
os.environ.get("SEER_RPC_SHARED_SECRET") else None) and similarly ensure the
SEER_DEFAULT_URL replacement delimiter is consistent and safe for the string
being replaced.

Comment on lines 145 to 148
RUN sed -i 's|SEER_DEFAULT_URL = "http://127.0.0.1:9091"|SEER_DEFAULT_URL = os.environ.get("SEER_URL", "http://seer:9091")|' \
/usr/src/sentry/src/sentry/conf/server.py && \
sed -i 's|SEER_RPC_SHARED_SECRET: list\[str\] | None = None|SEER_RPC_SHARED_SECRET = os.environ.get("SEER_RPC_SHARED_SECRET", "").split(",") if os.environ.get("SEER_RPC_SHARED_SECRET") else None|' \
/usr/src/sentry/src/sentry/conf/server.py && \
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Fix the sed expression; it will fail to run.

Line 147 uses | as the sed delimiter while the pattern itself contains | (the type union), so sed terminates the pattern early and treats the rest as flags, which will error and fail the build. Use a different delimiter or escape the pipe.

🛠️ Minimal fix (switch delimiter)
-    sed -i 's|SEER_RPC_SHARED_SECRET: list\[str\] | None = None|SEER_RPC_SHARED_SECRET = os.environ.get("SEER_RPC_SHARED_SECRET", "").split(",") if os.environ.get("SEER_RPC_SHARED_SECRET") else None|' \
+    sed -i 's#SEER_RPC_SHARED_SECRET: list\[str\] | None = None#SEER_RPC_SHARED_SECRET = os.environ.get("SEER_RPC_SHARED_SECRET", "").split(",") if os.environ.get("SEER_RPC_SHARED_SECRET") else None#' \
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
RUN sed -i 's|SEER_DEFAULT_URL = "http://127.0.0.1:9091"|SEER_DEFAULT_URL = os.environ.get("SEER_URL", "http://seer:9091")|' \
/usr/src/sentry/src/sentry/conf/server.py && \
sed -i 's|SEER_RPC_SHARED_SECRET: list\[str\] | None = None|SEER_RPC_SHARED_SECRET = os.environ.get("SEER_RPC_SHARED_SECRET", "").split(",") if os.environ.get("SEER_RPC_SHARED_SECRET") else None|' \
/usr/src/sentry/src/sentry/conf/server.py && \
RUN sed -i 's|SEER_DEFAULT_URL = "http://127.0.0.1:9091"|SEER_DEFAULT_URL = os.environ.get("SEER_URL", "http://seer:9091")|' \
/usr/src/sentry/src/sentry/conf/server.py && \
sed -i 's#SEER_RPC_SHARED_SECRET: list\[str\] | None = None#SEER_RPC_SHARED_SECRET = os.environ.get("SEER_RPC_SHARED_SECRET", "").split(",") if os.environ.get("SEER_RPC_SHARED_SECRET") else None#' \
/usr/src/sentry/src/sentry/conf/server.py && \
🤖 Prompt for AI Agents
In `@self-hosted/Dockerfile.kencove` around lines 145 - 148, The sed expression
that replaces the SEER_RPC_SHARED_SECRET line uses | as delimiter but the
replacement pattern contains | characters (the type union), causing sed to
misparse and fail; update the sed command that targets SEER_RPC_SHARED_SECRET so
it uses a different delimiter (e.g., @ or #) or properly escapes the pipe
characters in the pattern, keeping the intended replacement logic (set
SEER_RPC_SHARED_SECRET = os.environ.get("SEER_RPC_SHARED_SECRET", "").split(",")
if os.environ.get("SEER_RPC_SHARED_SECRET") else None) and similarly ensure the
SEER_DEFAULT_URL replacement delimiter is consistent and safe for the string
being replaced.

dnplkndll and others added 2 commits January 30, 2026 16:36
The Explorer-based autofix requires additional endpoints not yet
fully implemented in self-hosted Seer. Disable the feature flag
to use the legacy /v1/automation/autofix/start endpoint instead.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant