Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions .env.development
Original file line numberDiff line numberDiff line change
Expand Up@@ -77,9 +77,6 @@ SOURCEBOT_TELEMETRY_DISABLED=true # Disables telemetry collection
# Controls the number of concurrent indexing jobs that can run at once
# INDEX_CONCURRENCY_MULTIPLE=

# Controls the version of the web app
# NEXT_PUBLIC_SOURCEBOT_VERSION=

# CONFIG_MAX_REPOS_NO_TOKEN=
NODE_ENV=development
# SOURCEBOT_TENANCY_MODE=single
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/_gcp-deploy.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -54,7 +54,6 @@ jobs:
${{ env.IMAGE_PATH }}:${{ github.sha }}
${{ env.IMAGE_PATH }}:latest
build-args: |
NEXT_PUBLIC_SOURCEBOT_VERSION=${{ github.ref_name }}
NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT=${{ vars.NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT }}
NEXT_PUBLIC_SENTRY_ENVIRONMENT=${{ vars.NEXT_PUBLIC_SENTRY_ENVIRONMENT }}
NEXT_PUBLIC_SENTRY_WEBAPP_DSN=${{ vars.NEXT_PUBLIC_SENTRY_WEBAPP_DSN }}
Expand All@@ -65,6 +64,7 @@ jobs:
SENTRY_ORG=${{ vars.SENTRY_ORG }}
SENTRY_WEBAPP_PROJECT=${{ vars.SENTRY_WEBAPP_PROJECT }}
SENTRY_BACKEND_PROJECT=${{ vars.SENTRY_BACKEND_PROJECT }}
SENTRY_RELEASE=${{ github.ref_name }}


- name: Deploy to GCP
Expand Down
9 changes: 7 additions & 2 deletions .github/workflows/ghcr-publish.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -7,6 +7,12 @@ on:
push:
branches: ["main"]
tags: ["v*.*.*"]
workflow_call:
inputs:
version:
description: 'Version tag (e.g., v4.10.5)'
required: false
type: string

env:
# Use docker.io for Docker Hub if empty
Expand DownExpand Up@@ -40,6 +46,7 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v4
with:
ref: ${{ inputs.version || github.ref_name }}
submodules: "true"

# Extract metadata (tags, labels) for Docker
Expand DownExpand Up@@ -77,8 +84,6 @@ jobs:
cache-to: type=gha,mode=max,scope=${{ env.PLATFORM_PAIR }}
platforms: ${{ matrix.platform }}
outputs: type=image,name=${{ env.REGISTRY_IMAGE }},push-by-digest=true,name-canonical=true,push=true,annotation.org.opencontainers.image.description=Blazingly fast code search
build-args: |
NEXT_PUBLIC_SOURCEBOT_VERSION=${{ github.ref_name }}

- name: Export digest
run: |
Expand Down
99 changes: 80 additions & 19 deletions .github/workflows/release-sourcebot.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -3,35 +3,82 @@ name: Release Sourcebot
on:
workflow_dispatch:
inputs:
version:
description: "Version to release (e.g., 4.10.5)"
bump_type:
description: "Type of version bump to apply"
required: true
type: string
type: choice
options:
- patch
- minor
- major

concurrency:
group: release-sourcebot
cancel-in-progress: false

jobs:
release:
runs-on: ubuntu-latest
permissions:
contents: write
outputs:
version: ${{ steps.calculate_version.outputs.version }}

steps:
- name: Validate version format
run: |
VERSION="${{ inputs.version }}"
if ! [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9._-]+)?(\+[a-zA-Z0-9._-]+)?$ ]]; then
echo "Error: Version must follow semantic versioning format (X.Y.Z)"
exit 1
fi

- name: Checkout repository
uses: actions/checkout@v4
with:
ref: main
fetch-depth: 0

- name: Calculate new version
id: calculate_version
run: |
# Extract current version from CHANGELOG.md
CURRENT_VERSION=$(grep -oP '## \[\K[0-9]+\.[0-9]+\.[0-9]+' CHANGELOG.md | head -n 1)

if [ -z "$CURRENT_VERSION" ]; then
echo "Error: Could not extract current version from CHANGELOG.md"
exit 1
fi

echo "Current version: $CURRENT_VERSION"

# Parse version components
IFS='.' read -r MAJOR MINOR PATCH <<< "$CURRENT_VERSION"

# Apply bump based on input
BUMP_TYPE="${{ inputs.bump_type }}"
case "$BUMP_TYPE" in
major)
MAJOR=$((MAJOR + 1))
MINOR=0
PATCH=0
;;
minor)
MINOR=$((MINOR + 1))
PATCH=0
;;
patch)
PATCH=$((PATCH + 1))
;;
*)
echo "Error: Invalid bump type: $BUMP_TYPE"
exit 1
;;
esac

NEW_VERSION="$MAJOR.$MINOR.$PATCH"
echo "New version: $NEW_VERSION"

# Export to GITHUB_ENV for use in subsequent steps within this job
echo "VERSION=$NEW_VERSION" >> $GITHUB_ENV

# Export to GITHUB_OUTPUT for use in other jobs
echo "version=$NEW_VERSION" >> $GITHUB_OUTPUT

- name: Check if version already exists
run: |
VERSION="${{ inputs.version }}"
if grep -q "## \[$VERSION\]" CHANGELOG.md; then
echo "Error: Version $VERSION already exists in CHANGELOG.md"
exit 1
Expand All@@ -41,9 +88,8 @@ jobs:
exit 1
fi

- name: Update CHANGELOG.md
- name: Update CHANGELOG.md and version.ts
run: |
VERSION="${{ inputs.version }}"
DATE=$(date +%Y-%m-%d)

# Insert the new version header after the [Unreleased] line
Expand All@@ -54,20 +100,26 @@ jobs:
echo "Updated CHANGELOG.md with version $VERSION"
cat CHANGELOG.md | head -n 15

# Update version.ts
cat > packages/shared/src/version.ts << EOF
// This file is auto-generated by .github/workflows/release-sourcebot.yml
export const SOURCEBOT_VERSION = "v$VERSION";
EOF
echo "Updated version.ts with version v$VERSION"
cat packages/shared/src/version.ts
Comment thread
brendan-kellam marked this conversation as resolved.

- name: Configure git
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"

- name: Commit CHANGELOG
- name: Commit changes
run: |
VERSION="${{ inputs.version }}"
git add CHANGELOG.md
git add CHANGELOG.md packages/shared/src/version.ts
git commit -m "Release v$VERSION"

- name: Create annotated tag
run: |
VERSION="${{ inputs.version }}"
git tag -a "v$VERSION" -m "sourcebot v$VERSION"

- name: Push changes
Expand All@@ -79,8 +131,17 @@ jobs:
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
VERSION="${{ inputs.version }}"
gh release create "v$VERSION" \
--verify-tag \
--generate-notes \
--latest

publish:
needs: release
uses: ./.github/workflows/ghcr-publish.yml
with:
version: v${{ needs.release.outputs.version }}
permissions:
contents: read
packages: write
id-token: write
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Changed
- Bake Sourcebot version into code rather than relying on build arg. [#680](https://github.com/sourcebot-dev/sourcebot/pull/680)

## [4.10.4] - 2025-12-18

### Fixed
Expand Down
20 changes: 7 additions & 13 deletions Dockerfile
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,7 +8,6 @@
# in the webapp.
# @see: https://docs.docker.com/build/building/variables/#scoping

ARG NEXT_PUBLIC_SOURCEBOT_VERSION
ARG NEXT_PUBLIC_SENTRY_ENVIRONMENT
ARG NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT
ARG NEXT_PUBLIC_SENTRY_WEBAPP_DSN
Expand DownExpand Up@@ -51,8 +50,6 @@ RUN yarn workspace @sourcebot/query-language install
FROM node-alpine AS web-builder
ENV SKIP_ENV_VALIDATION=1
# -----------
ARG NEXT_PUBLIC_SOURCEBOT_VERSION
ENV NEXT_PUBLIC_SOURCEBOT_VERSION=$NEXT_PUBLIC_SOURCEBOT_VERSION
ARG NEXT_PUBLIC_SENTRY_ENVIRONMENT
ENV NEXT_PUBLIC_SENTRY_ENVIRONMENT=$NEXT_PUBLIC_SENTRY_ENVIRONMENT
ARG NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT
Expand All@@ -72,7 +69,8 @@ ARG SENTRY_ORG
ENV SENTRY_ORG=$SENTRY_ORG
ARG SENTRY_WEBAPP_PROJECT
ENV SENTRY_WEBAPP_PROJECT=$SENTRY_WEBAPP_PROJECT
ENV SENTRY_RELEASE=$NEXT_PUBLIC_SOURCEBOT_VERSION
ARG SENTRY_RELEASE
ENV SENTRY_RELEASE=$SENTRY_RELEASE
# SMUAT = Source Map Upload Auth Token
ARG SENTRY_SMUAT
ENV SENTRY_SMUAT=$SENTRY_SMUAT
Expand DownExpand Up@@ -102,8 +100,6 @@ ENV SKIP_ENV_VALIDATION=0
FROM node-alpine AS backend-builder
ENV SKIP_ENV_VALIDATION=1
# -----------
ARG NEXT_PUBLIC_SOURCEBOT_VERSION
ENV NEXT_PUBLIC_SOURCEBOT_VERSION=$NEXT_PUBLIC_SOURCEBOT_VERSION

# To upload source maps to Sentry, we need to set the following build-time args.
# It's important that we don't set these for oss builds, otherwise the Sentry
Expand All@@ -115,6 +111,8 @@ ENV SENTRY_BACKEND_PROJECT=$SENTRY_BACKEND_PROJECT
# SMUAT = Source Map Upload Auth Token
ARG SENTRY_SMUAT
ENV SENTRY_SMUAT=$SENTRY_SMUAT
ARG SENTRY_RELEASE
ENV SENTRY_RELEASE=$SENTRY_RELEASE
# -----------

WORKDIR /app
Expand All@@ -132,12 +130,12 @@ RUN yarn workspace @sourcebot/backend install
RUN yarn workspace @sourcebot/backend build

# Upload source maps to Sentry if we have the necessary build-time args.
RUN if [ -n "$SENTRY_SMUAT" ] && [ -n "$SENTRY_ORG" ] && [ -n "$SENTRY_BACKEND_PROJECT" ] && [ -n "$NEXT_PUBLIC_SOURCEBOT_VERSION" ]; then \
RUN if [ -n "$SENTRY_SMUAT" ] && [ -n "$SENTRY_ORG" ] && [ -n "$SENTRY_BACKEND_PROJECT" ] && [ -n "$SENTRY_RELEASE" ]; then \
apk add --no-cache curl; \
curl -sL https://sentry.io/get-cli/ | sh; \
sentry-cli login --auth-token $SENTRY_SMUAT; \
sentry-cli sourcemaps inject --org $SENTRY_ORG --project $SENTRY_BACKEND_PROJECT --release $NEXT_PUBLIC_SOURCEBOT_VERSION ./packages/backend/dist; \
sentry-cli sourcemaps upload --org $SENTRY_ORG --project $SENTRY_BACKEND_PROJECT --release $NEXT_PUBLIC_SOURCEBOT_VERSION ./packages/backend/dist; \
sentry-cli sourcemaps inject --org $SENTRY_ORG --project $SENTRY_BACKEND_PROJECT --release $SENTRY_RELEASE ./packages/backend/dist; \
sentry-cli sourcemaps upload --org $SENTRY_ORG --project $SENTRY_BACKEND_PROJECT --release $SENTRY_RELEASE ./packages/backend/dist; \
fi

ENV SKIP_ENV_VALIDATION=0
Expand All@@ -146,8 +144,6 @@ ENV SKIP_ENV_VALIDATION=0
# ------ Runner ------
FROM node-alpine AS runner
# -----------
ARG NEXT_PUBLIC_SOURCEBOT_VERSION
ENV NEXT_PUBLIC_SOURCEBOT_VERSION=$NEXT_PUBLIC_SOURCEBOT_VERSION
ARG NEXT_PUBLIC_SENTRY_ENVIRONMENT
ENV NEXT_PUBLIC_SENTRY_ENVIRONMENT=$NEXT_PUBLIC_SENTRY_ENVIRONMENT
ARG NEXT_PUBLIC_SENTRY_WEBAPP_DSN
Expand All@@ -160,8 +156,6 @@ ARG NEXT_PUBLIC_LANGFUSE_BASE_URL
ENV NEXT_PUBLIC_LANGFUSE_BASE_URL=$NEXT_PUBLIC_LANGFUSE_BASE_URL
# -----------

RUN echo "Sourcebot Version: $NEXT_PUBLIC_SOURCEBOT_VERSION"

WORKDIR /app
ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1
Expand Down
24 changes: 18 additions & 6 deletions entrypoint.sh
Original file line numberDiff line numberDiff line change
Expand Up@@ -63,8 +63,20 @@ else
export REDIS_EMBEDDED="false"
fi

# Extract version from version.ts
VERSION_FILE="/app/packages/shared/src/version.ts"
if [ -f "$VERSION_FILE" ]; then
SOURCEBOT_VERSION=$(grep -o '"v[^"]*"' "$VERSION_FILE" | tr -d '"')
# Validate extraction succeeded
if [ -z "$SOURCEBOT_VERSION" ]; then
echo -e "\e[33m[Warning] Failed to extract version from $VERSION_FILE. Setting to 'unknown'.\e[0m" >&2
SOURCEBOT_VERSION="unknown"
fi
else
SOURCEBOT_VERSION="unknown"
fi
Comment thread
brendan-kellam marked this conversation as resolved.

echo -e "\e[34m[Info] Sourcebot version: $NEXT_PUBLIC_SOURCEBOT_VERSION\e[0m"
echo -e "\e[34m[Info] Sourcebot version: $SOURCEBOT_VERSION\e[0m"

if [ -n "$SOURCEBOT_TELEMETRY_DISABLED" ]; then
# Validate that SOURCEBOT_TELEMETRY_DISABLED is either "true" or "false"
Expand DownExpand Up@@ -157,7 +169,7 @@ if [ ! -f "$FIRST_RUN_FILE" ]; then
"event": "install",
"distinct_id": "'"$SOURCEBOT_INSTALL_ID"'",
"properties": {
"sourcebot_version": "'"$NEXT_PUBLIC_SOURCEBOT_VERSION"'"
"sourcebot_version": "'"$SOURCEBOT_VERSION"'"
}
}' https://us.i.posthog.com/capture/ ) then
echo -e "\e[33m[Warning] Failed to send install event.\e[0m"
Expand All@@ -168,8 +180,8 @@ else
PREVIOUS_VERSION=$(cat "$FIRST_RUN_FILE" | jq -r '.version')

# If the version has changed, we assume an upgrade has occurred.
if [ "$PREVIOUS_VERSION" != "$NEXT_PUBLIC_SOURCEBOT_VERSION" ]; then
echo -e "\e[34m[Info] Upgraded from version $PREVIOUS_VERSION to $NEXT_PUBLIC_SOURCEBOT_VERSION\e[0m"
if [ "$PREVIOUS_VERSION" != "$SOURCEBOT_VERSION" ]; then
echo -e "\e[34m[Info] Upgraded from version $PREVIOUS_VERSION to $SOURCEBOT_VERSION\e[0m"

if [ "$SOURCEBOT_TELEMETRY_DISABLED" = "false" ]; then
if ! ( curl -L --output /dev/null --silent --fail --header "Content-Type: application/json" -d '{
Expand All@@ -178,7 +190,7 @@ else
"distinct_id": "'"$SOURCEBOT_INSTALL_ID"'",
"properties": {
"from_version": "'"$PREVIOUS_VERSION"'",
"to_version": "'"$NEXT_PUBLIC_SOURCEBOT_VERSION"'"
"to_version": "'"$SOURCEBOT_VERSION"'"
}
}' https://us.i.posthog.com/capture/ ) then
echo -e "\e[33m[Warning] Failed to send upgrade event.\e[0m"
Expand All@@ -187,7 +199,7 @@ else
fi
fi

echo "{\"version\": \"$NEXT_PUBLIC_SOURCEBOT_VERSION\", \"install_id\": \"$SOURCEBOT_INSTALL_ID\"}" > "$FIRST_RUN_FILE"
echo "{\"version\": \"$SOURCEBOT_VERSION\", \"install_id\": \"$SOURCEBOT_INSTALL_ID\"}" > "$FIRST_RUN_FILE"

# Start the database and wait for it to be ready before starting any other service
if [ "$DATABASE_EMBEDDED" = "true" ]; then
Expand Down
4 changes: 2 additions & 2 deletions packages/backend/src/instrument.ts
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
import * as Sentry from "@sentry/node";
import { createLogger } from "@sourcebot/shared";
import { createLogger, SOURCEBOT_VERSION } from "@sourcebot/shared";
import { env } from "@sourcebot/shared/client";

const logger = createLogger('instrument');

if (!!env.NEXT_PUBLIC_SENTRY_BACKEND_DSN && !!env.NEXT_PUBLIC_SENTRY_ENVIRONMENT) {
Sentry.init({
dsn: env.NEXT_PUBLIC_SENTRY_BACKEND_DSN,
release: env.NEXT_PUBLIC_SOURCEBOT_VERSION,
release: SOURCEBOT_VERSION,
environment: env.NEXT_PUBLIC_SENTRY_ENVIRONMENT,
});
} else {
Expand Down
5 changes: 2 additions & 3 deletions packages/backend/src/posthog.ts
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
import { env as clientEnv } from "@sourcebot/shared/client";
import { env } from "@sourcebot/shared";
import { env, SOURCEBOT_VERSION } from "@sourcebot/shared";
import { PostHog } from 'posthog-node';
import { PosthogEvent, PosthogEventMap } from './posthogEvents.js';

Expand All@@ -24,7 +23,7 @@ export function captureEvent<E extends PosthogEvent>(event: E, properties: Posth
event: event,
properties: {
...properties,
sourcebot_version: clientEnv.NEXT_PUBLIC_SOURCEBOT_VERSION,
sourcebot_version: SOURCEBOT_VERSION,
},
});
}
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions .env.development
Original file line numberDiff line numberDiff line change
Expand Up@@ -77,9 +77,6 @@ SOURCEBOT_TELEMETRY_DISABLED=true # Disables telemetry collection
# Controls the number of concurrent indexing jobs that can run at once
# INDEX_CONCURRENCY_MULTIPLE=

# Controls the version of the web app
# NEXT_PUBLIC_SOURCEBOT_VERSION=

# CONFIG_MAX_REPOS_NO_TOKEN=
NODE_ENV=development
# SOURCEBOT_TENANCY_MODE=single
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/_gcp-deploy.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -54,7 +54,6 @@ jobs:
${{ env.IMAGE_PATH }}:${{ github.sha }}
${{ env.IMAGE_PATH }}:latest
build-args: |
NEXT_PUBLIC_SOURCEBOT_VERSION=${{ github.ref_name }}
NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT=${{ vars.NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT }}
NEXT_PUBLIC_SENTRY_ENVIRONMENT=${{ vars.NEXT_PUBLIC_SENTRY_ENVIRONMENT }}
NEXT_PUBLIC_SENTRY_WEBAPP_DSN=${{ vars.NEXT_PUBLIC_SENTRY_WEBAPP_DSN }}
Expand All@@ -65,6 +64,7 @@ jobs:
SENTRY_ORG=${{ vars.SENTRY_ORG }}
SENTRY_WEBAPP_PROJECT=${{ vars.SENTRY_WEBAPP_PROJECT }}
SENTRY_BACKEND_PROJECT=${{ vars.SENTRY_BACKEND_PROJECT }}
SENTRY_RELEASE=${{ github.ref_name }}


- name: Deploy to GCP
Expand Down
9 changes: 7 additions & 2 deletions .github/workflows/ghcr-publish.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -7,6 +7,12 @@ on:
push:
branches: ["main"]
tags: ["v*.*.*"]
workflow_call:
inputs:
version:
description: 'Version tag (e.g., v4.10.5)'
required: false
type: string

env:
# Use docker.io for Docker Hub if empty
Expand DownExpand Up@@ -40,6 +46,7 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v4
with:
ref: ${{ inputs.version || github.ref_name }}
submodules: "true"

# Extract metadata (tags, labels) for Docker
Expand DownExpand Up@@ -77,8 +84,6 @@ jobs:
cache-to: type=gha,mode=max,scope=${{ env.PLATFORM_PAIR }}
platforms: ${{ matrix.platform }}
outputs: type=image,name=${{ env.REGISTRY_IMAGE }},push-by-digest=true,name-canonical=true,push=true,annotation.org.opencontainers.image.description=Blazingly fast code search
build-args: |
NEXT_PUBLIC_SOURCEBOT_VERSION=${{ github.ref_name }}

- name: Export digest
run: |
Expand Down
99 changes: 80 additions & 19 deletions .github/workflows/release-sourcebot.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -3,35 +3,82 @@ name: Release Sourcebot
on:
workflow_dispatch:
inputs:
version:
description: "Version to release (e.g., 4.10.5)"
bump_type:
description: "Type of version bump to apply"
required: true
type: string
type: choice
options:
- patch
- minor
- major

concurrency:
group: release-sourcebot
cancel-in-progress: false

jobs:
release:
runs-on: ubuntu-latest
permissions:
contents: write
outputs:
version: ${{ steps.calculate_version.outputs.version }}

steps:
- name: Validate version format
run: |
VERSION="${{ inputs.version }}"
if ! [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9._-]+)?(\+[a-zA-Z0-9._-]+)?$ ]]; then
echo "Error: Version must follow semantic versioning format (X.Y.Z)"
exit 1
fi

- name: Checkout repository
uses: actions/checkout@v4
with:
ref: main
fetch-depth: 0

- name: Calculate new version
id: calculate_version
run: |
# Extract current version from CHANGELOG.md
CURRENT_VERSION=$(grep -oP '## \[\K[0-9]+\.[0-9]+\.[0-9]+' CHANGELOG.md | head -n 1)

if [ -z "$CURRENT_VERSION" ]; then
echo "Error: Could not extract current version from CHANGELOG.md"
exit 1
fi

echo "Current version: $CURRENT_VERSION"

# Parse version components
IFS='.' read -r MAJOR MINOR PATCH <<< "$CURRENT_VERSION"

# Apply bump based on input
BUMP_TYPE="${{ inputs.bump_type }}"
case "$BUMP_TYPE" in
major)
MAJOR=$((MAJOR + 1))
MINOR=0
PATCH=0
;;
minor)
MINOR=$((MINOR + 1))
PATCH=0
;;
patch)
PATCH=$((PATCH + 1))
;;
*)
echo "Error: Invalid bump type: $BUMP_TYPE"
exit 1
;;
esac

NEW_VERSION="$MAJOR.$MINOR.$PATCH"
echo "New version: $NEW_VERSION"

# Export to GITHUB_ENV for use in subsequent steps within this job
echo "VERSION=$NEW_VERSION" >> $GITHUB_ENV

# Export to GITHUB_OUTPUT for use in other jobs
echo "version=$NEW_VERSION" >> $GITHUB_OUTPUT

- name: Check if version already exists
run: |
VERSION="${{ inputs.version }}"
if grep -q "## \[$VERSION\]" CHANGELOG.md; then
echo "Error: Version $VERSION already exists in CHANGELOG.md"
exit 1
Expand All@@ -41,9 +88,8 @@ jobs:
exit 1
fi

- name: Update CHANGELOG.md
- name: Update CHANGELOG.md and version.ts
run: |
VERSION="${{ inputs.version }}"
DATE=$(date +%Y-%m-%d)

# Insert the new version header after the [Unreleased] line
Expand All@@ -54,20 +100,26 @@ jobs:
echo "Updated CHANGELOG.md with version $VERSION"
cat CHANGELOG.md | head -n 15

# Update version.ts
cat > packages/shared/src/version.ts << EOF
// This file is auto-generated by .github/workflows/release-sourcebot.yml
export const SOURCEBOT_VERSION = "v$VERSION";
EOF
echo "Updated version.ts with version v$VERSION"
cat packages/shared/src/version.ts
Comment thread
brendan-kellam marked this conversation as resolved.

- name: Configure git
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"

- name: Commit CHANGELOG
- name: Commit changes
run: |
VERSION="${{ inputs.version }}"
git add CHANGELOG.md
git add CHANGELOG.md packages/shared/src/version.ts
git commit -m "Release v$VERSION"

- name: Create annotated tag
run: |
VERSION="${{ inputs.version }}"
git tag -a "v$VERSION" -m "sourcebot v$VERSION"

- name: Push changes
Expand All@@ -79,8 +131,17 @@ jobs:
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
VERSION="${{ inputs.version }}"
gh release create "v$VERSION" \
--verify-tag \
--generate-notes \
--latest

publish:
needs: release
uses: ./.github/workflows/ghcr-publish.yml
with:
version: v${{ needs.release.outputs.version }}
permissions:
contents: read
packages: write
id-token: write
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Changed
- Bake Sourcebot version into code rather than relying on build arg. [#680](https://github.com/sourcebot-dev/sourcebot/pull/680)

## [4.10.4] - 2025-12-18

### Fixed
Expand Down
20 changes: 7 additions & 13 deletions Dockerfile
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,7 +8,6 @@
# in the webapp.
# @see: https://docs.docker.com/build/building/variables/#scoping

ARG NEXT_PUBLIC_SOURCEBOT_VERSION
ARG NEXT_PUBLIC_SENTRY_ENVIRONMENT
ARG NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT
ARG NEXT_PUBLIC_SENTRY_WEBAPP_DSN
Expand DownExpand Up@@ -51,8 +50,6 @@ RUN yarn workspace @sourcebot/query-language install
FROM node-alpine AS web-builder
ENV SKIP_ENV_VALIDATION=1
# -----------
ARG NEXT_PUBLIC_SOURCEBOT_VERSION
ENV NEXT_PUBLIC_SOURCEBOT_VERSION=$NEXT_PUBLIC_SOURCEBOT_VERSION
ARG NEXT_PUBLIC_SENTRY_ENVIRONMENT
ENV NEXT_PUBLIC_SENTRY_ENVIRONMENT=$NEXT_PUBLIC_SENTRY_ENVIRONMENT
ARG NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT
Expand All@@ -72,7 +69,8 @@ ARG SENTRY_ORG
ENV SENTRY_ORG=$SENTRY_ORG
ARG SENTRY_WEBAPP_PROJECT
ENV SENTRY_WEBAPP_PROJECT=$SENTRY_WEBAPP_PROJECT
ENV SENTRY_RELEASE=$NEXT_PUBLIC_SOURCEBOT_VERSION
ARG SENTRY_RELEASE
ENV SENTRY_RELEASE=$SENTRY_RELEASE
# SMUAT = Source Map Upload Auth Token
ARG SENTRY_SMUAT
ENV SENTRY_SMUAT=$SENTRY_SMUAT
Expand DownExpand Up@@ -102,8 +100,6 @@ ENV SKIP_ENV_VALIDATION=0
FROM node-alpine AS backend-builder
ENV SKIP_ENV_VALIDATION=1
# -----------
ARG NEXT_PUBLIC_SOURCEBOT_VERSION
ENV NEXT_PUBLIC_SOURCEBOT_VERSION=$NEXT_PUBLIC_SOURCEBOT_VERSION

# To upload source maps to Sentry, we need to set the following build-time args.
# It's important that we don't set these for oss builds, otherwise the Sentry
Expand All@@ -115,6 +111,8 @@ ENV SENTRY_BACKEND_PROJECT=$SENTRY_BACKEND_PROJECT
# SMUAT = Source Map Upload Auth Token
ARG SENTRY_SMUAT
ENV SENTRY_SMUAT=$SENTRY_SMUAT
ARG SENTRY_RELEASE
ENV SENTRY_RELEASE=$SENTRY_RELEASE
# -----------

WORKDIR /app
Expand All@@ -132,12 +130,12 @@ RUN yarn workspace @sourcebot/backend install
RUN yarn workspace @sourcebot/backend build

# Upload source maps to Sentry if we have the necessary build-time args.
RUN if [ -n "$SENTRY_SMUAT" ] && [ -n "$SENTRY_ORG" ] && [ -n "$SENTRY_BACKEND_PROJECT" ] && [ -n "$NEXT_PUBLIC_SOURCEBOT_VERSION" ]; then \
RUN if [ -n "$SENTRY_SMUAT" ] && [ -n "$SENTRY_ORG" ] && [ -n "$SENTRY_BACKEND_PROJECT" ] && [ -n "$SENTRY_RELEASE" ]; then \
apk add --no-cache curl; \
curl -sL https://sentry.io/get-cli/ | sh; \
sentry-cli login --auth-token $SENTRY_SMUAT; \
sentry-cli sourcemaps inject --org $SENTRY_ORG --project $SENTRY_BACKEND_PROJECT --release $NEXT_PUBLIC_SOURCEBOT_VERSION ./packages/backend/dist; \
sentry-cli sourcemaps upload --org $SENTRY_ORG --project $SENTRY_BACKEND_PROJECT --release $NEXT_PUBLIC_SOURCEBOT_VERSION ./packages/backend/dist; \
sentry-cli sourcemaps inject --org $SENTRY_ORG --project $SENTRY_BACKEND_PROJECT --release $SENTRY_RELEASE ./packages/backend/dist; \
sentry-cli sourcemaps upload --org $SENTRY_ORG --project $SENTRY_BACKEND_PROJECT --release $SENTRY_RELEASE ./packages/backend/dist; \
fi

ENV SKIP_ENV_VALIDATION=0
Expand All@@ -146,8 +144,6 @@ ENV SKIP_ENV_VALIDATION=0
# ------ Runner ------
FROM node-alpine AS runner
# -----------
ARG NEXT_PUBLIC_SOURCEBOT_VERSION
ENV NEXT_PUBLIC_SOURCEBOT_VERSION=$NEXT_PUBLIC_SOURCEBOT_VERSION
ARG NEXT_PUBLIC_SENTRY_ENVIRONMENT
ENV NEXT_PUBLIC_SENTRY_ENVIRONMENT=$NEXT_PUBLIC_SENTRY_ENVIRONMENT
ARG NEXT_PUBLIC_SENTRY_WEBAPP_DSN
Expand All@@ -160,8 +156,6 @@ ARG NEXT_PUBLIC_LANGFUSE_BASE_URL
ENV NEXT_PUBLIC_LANGFUSE_BASE_URL=$NEXT_PUBLIC_LANGFUSE_BASE_URL
# -----------

RUN echo "Sourcebot Version: $NEXT_PUBLIC_SOURCEBOT_VERSION"

WORKDIR /app
ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1
Expand Down
24 changes: 18 additions & 6 deletions entrypoint.sh
Original file line numberDiff line numberDiff line change
Expand Up@@ -63,8 +63,20 @@ else
export REDIS_EMBEDDED="false"
fi

# Extract version from version.ts
VERSION_FILE="/app/packages/shared/src/version.ts"
if [ -f "$VERSION_FILE" ]; then
SOURCEBOT_VERSION=$(grep -o '"v[^"]*"' "$VERSION_FILE" | tr -d '"')
# Validate extraction succeeded
if [ -z "$SOURCEBOT_VERSION" ]; then
echo -e "\e[33m[Warning] Failed to extract version from $VERSION_FILE. Setting to 'unknown'.\e[0m" >&2
SOURCEBOT_VERSION="unknown"
fi
else
SOURCEBOT_VERSION="unknown"
fi
Comment thread
brendan-kellam marked this conversation as resolved.

echo -e "\e[34m[Info] Sourcebot version: $NEXT_PUBLIC_SOURCEBOT_VERSION\e[0m"
echo -e "\e[34m[Info] Sourcebot version: $SOURCEBOT_VERSION\e[0m"

if [ -n "$SOURCEBOT_TELEMETRY_DISABLED" ]; then
# Validate that SOURCEBOT_TELEMETRY_DISABLED is either "true" or "false"
Expand DownExpand Up@@ -157,7 +169,7 @@ if [ ! -f "$FIRST_RUN_FILE" ]; then
"event": "install",
"distinct_id": "'"$SOURCEBOT_INSTALL_ID"'",
"properties": {
"sourcebot_version": "'"$NEXT_PUBLIC_SOURCEBOT_VERSION"'"
"sourcebot_version": "'"$SOURCEBOT_VERSION"'"
}
}' https://us.i.posthog.com/capture/ ) then
echo -e "\e[33m[Warning] Failed to send install event.\e[0m"
Expand All@@ -168,8 +180,8 @@ else
PREVIOUS_VERSION=$(cat "$FIRST_RUN_FILE" | jq -r '.version')

# If the version has changed, we assume an upgrade has occurred.
if [ "$PREVIOUS_VERSION" != "$NEXT_PUBLIC_SOURCEBOT_VERSION" ]; then
echo -e "\e[34m[Info] Upgraded from version $PREVIOUS_VERSION to $NEXT_PUBLIC_SOURCEBOT_VERSION\e[0m"
if [ "$PREVIOUS_VERSION" != "$SOURCEBOT_VERSION" ]; then
echo -e "\e[34m[Info] Upgraded from version $PREVIOUS_VERSION to $SOURCEBOT_VERSION\e[0m"

if [ "$SOURCEBOT_TELEMETRY_DISABLED" = "false" ]; then
if ! ( curl -L --output /dev/null --silent --fail --header "Content-Type: application/json" -d '{
Expand All@@ -178,7 +190,7 @@ else
"distinct_id": "'"$SOURCEBOT_INSTALL_ID"'",
"properties": {
"from_version": "'"$PREVIOUS_VERSION"'",
"to_version": "'"$NEXT_PUBLIC_SOURCEBOT_VERSION"'"
"to_version": "'"$SOURCEBOT_VERSION"'"
}
}' https://us.i.posthog.com/capture/ ) then
echo -e "\e[33m[Warning] Failed to send upgrade event.\e[0m"
Expand All@@ -187,7 +199,7 @@ else
fi
fi

echo "{\"version\": \"$NEXT_PUBLIC_SOURCEBOT_VERSION\", \"install_id\": \"$SOURCEBOT_INSTALL_ID\"}" > "$FIRST_RUN_FILE"
echo "{\"version\": \"$SOURCEBOT_VERSION\", \"install_id\": \"$SOURCEBOT_INSTALL_ID\"}" > "$FIRST_RUN_FILE"

# Start the database and wait for it to be ready before starting any other service
if [ "$DATABASE_EMBEDDED" = "true" ]; then
Expand Down
4 changes: 2 additions & 2 deletions packages/backend/src/instrument.ts
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
import * as Sentry from "@sentry/node";
import { createLogger } from "@sourcebot/shared";
import { createLogger, SOURCEBOT_VERSION } from "@sourcebot/shared";
import { env } from "@sourcebot/shared/client";

const logger = createLogger('instrument');

if (!!env.NEXT_PUBLIC_SENTRY_BACKEND_DSN && !!env.NEXT_PUBLIC_SENTRY_ENVIRONMENT) {
Sentry.init({
dsn: env.NEXT_PUBLIC_SENTRY_BACKEND_DSN,
release: env.NEXT_PUBLIC_SOURCEBOT_VERSION,
release: SOURCEBOT_VERSION,
environment: env.NEXT_PUBLIC_SENTRY_ENVIRONMENT,
});
} else {
Expand Down
5 changes: 2 additions & 3 deletions packages/backend/src/posthog.ts
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
import { env as clientEnv } from "@sourcebot/shared/client";
import { env } from "@sourcebot/shared";
import { env, SOURCEBOT_VERSION } from "@sourcebot/shared";
import { PostHog } from 'posthog-node';
import { PosthogEvent, PosthogEventMap } from './posthogEvents.js';

Expand All@@ -24,7 +23,7 @@ export function captureEvent<E extends PosthogEvent>(event: E, properties: Posth
event: event,
properties: {
...properties,
sourcebot_version: clientEnv.NEXT_PUBLIC_SOURCEBOT_VERSION,
sourcebot_version: SOURCEBOT_VERSION,
},
});
}
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions .env.development
Original file line numberDiff line numberDiff line change
Expand Up@@ -77,9 +77,6 @@ SOURCEBOT_TELEMETRY_DISABLED=true # Disables telemetry collection
# Controls the number of concurrent indexing jobs that can run at once
# INDEX_CONCURRENCY_MULTIPLE=

# Controls the version of the web app
# NEXT_PUBLIC_SOURCEBOT_VERSION=

# CONFIG_MAX_REPOS_NO_TOKEN=
NODE_ENV=development
# SOURCEBOT_TENANCY_MODE=single
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/_gcp-deploy.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -54,7 +54,6 @@ jobs:
${{ env.IMAGE_PATH }}:${{ github.sha }}
${{ env.IMAGE_PATH }}:latest
build-args: |
NEXT_PUBLIC_SOURCEBOT_VERSION=${{ github.ref_name }}
NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT=${{ vars.NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT }}
NEXT_PUBLIC_SENTRY_ENVIRONMENT=${{ vars.NEXT_PUBLIC_SENTRY_ENVIRONMENT }}
NEXT_PUBLIC_SENTRY_WEBAPP_DSN=${{ vars.NEXT_PUBLIC_SENTRY_WEBAPP_DSN }}
Expand All@@ -65,6 +64,7 @@ jobs:
SENTRY_ORG=${{ vars.SENTRY_ORG }}
SENTRY_WEBAPP_PROJECT=${{ vars.SENTRY_WEBAPP_PROJECT }}
SENTRY_BACKEND_PROJECT=${{ vars.SENTRY_BACKEND_PROJECT }}
SENTRY_RELEASE=${{ github.ref_name }}


- name: Deploy to GCP
Expand Down
9 changes: 7 additions & 2 deletions .github/workflows/ghcr-publish.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -7,6 +7,12 @@ on:
push:
branches: ["main"]
tags: ["v*.*.*"]
workflow_call:
inputs:
version:
description: 'Version tag (e.g., v4.10.5)'
required: false
type: string

env:
# Use docker.io for Docker Hub if empty
Expand DownExpand Up@@ -40,6 +46,7 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v4
with:
ref: ${{ inputs.version || github.ref_name }}
submodules: "true"

# Extract metadata (tags, labels) for Docker
Expand DownExpand Up@@ -77,8 +84,6 @@ jobs:
cache-to: type=gha,mode=max,scope=${{ env.PLATFORM_PAIR }}
platforms: ${{ matrix.platform }}
outputs: type=image,name=${{ env.REGISTRY_IMAGE }},push-by-digest=true,name-canonical=true,push=true,annotation.org.opencontainers.image.description=Blazingly fast code search
build-args: |
NEXT_PUBLIC_SOURCEBOT_VERSION=${{ github.ref_name }}

- name: Export digest
run: |
Expand Down
99 changes: 80 additions & 19 deletions .github/workflows/release-sourcebot.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -3,35 +3,82 @@ name: Release Sourcebot
on:
workflow_dispatch:
inputs:
version:
description: "Version to release (e.g., 4.10.5)"
bump_type:
description: "Type of version bump to apply"
required: true
type: string
type: choice
options:
- patch
- minor
- major

concurrency:
group: release-sourcebot
cancel-in-progress: false

jobs:
release:
runs-on: ubuntu-latest
permissions:
contents: write
outputs:
version: ${{ steps.calculate_version.outputs.version }}

steps:
- name: Validate version format
run: |
VERSION="${{ inputs.version }}"
if ! [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9._-]+)?(\+[a-zA-Z0-9._-]+)?$ ]]; then
echo "Error: Version must follow semantic versioning format (X.Y.Z)"
exit 1
fi

- name: Checkout repository
uses: actions/checkout@v4
with:
ref: main
fetch-depth: 0

- name: Calculate new version
id: calculate_version
run: |
# Extract current version from CHANGELOG.md
CURRENT_VERSION=$(grep -oP '## \[\K[0-9]+\.[0-9]+\.[0-9]+' CHANGELOG.md | head -n 1)

if [ -z "$CURRENT_VERSION" ]; then
echo "Error: Could not extract current version from CHANGELOG.md"
exit 1
fi

echo "Current version: $CURRENT_VERSION"

# Parse version components
IFS='.' read -r MAJOR MINOR PATCH <<< "$CURRENT_VERSION"

# Apply bump based on input
BUMP_TYPE="${{ inputs.bump_type }}"
case "$BUMP_TYPE" in
major)
MAJOR=$((MAJOR + 1))
MINOR=0
PATCH=0
;;
minor)
MINOR=$((MINOR + 1))
PATCH=0
;;
patch)
PATCH=$((PATCH + 1))
;;
*)
echo "Error: Invalid bump type: $BUMP_TYPE"
exit 1
;;
esac

NEW_VERSION="$MAJOR.$MINOR.$PATCH"
echo "New version: $NEW_VERSION"

# Export to GITHUB_ENV for use in subsequent steps within this job
echo "VERSION=$NEW_VERSION" >> $GITHUB_ENV

# Export to GITHUB_OUTPUT for use in other jobs
echo "version=$NEW_VERSION" >> $GITHUB_OUTPUT

- name: Check if version already exists
run: |
VERSION="${{ inputs.version }}"
if grep -q "## \[$VERSION\]" CHANGELOG.md; then
echo "Error: Version $VERSION already exists in CHANGELOG.md"
exit 1
Expand All@@ -41,9 +88,8 @@ jobs:
exit 1
fi

- name: Update CHANGELOG.md
- name: Update CHANGELOG.md and version.ts
run: |
VERSION="${{ inputs.version }}"
DATE=$(date +%Y-%m-%d)

# Insert the new version header after the [Unreleased] line
Expand All@@ -54,20 +100,26 @@ jobs:
echo "Updated CHANGELOG.md with version $VERSION"
cat CHANGELOG.md | head -n 15

# Update version.ts
cat > packages/shared/src/version.ts << EOF
// This file is auto-generated by .github/workflows/release-sourcebot.yml
export const SOURCEBOT_VERSION = "v$VERSION";
EOF
echo "Updated version.ts with version v$VERSION"
cat packages/shared/src/version.ts
Comment thread
brendan-kellam marked this conversation as resolved.

- name: Configure git
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"

- name: Commit CHANGELOG
- name: Commit changes
run: |
VERSION="${{ inputs.version }}"
git add CHANGELOG.md
git add CHANGELOG.md packages/shared/src/version.ts
git commit -m "Release v$VERSION"

- name: Create annotated tag
run: |
VERSION="${{ inputs.version }}"
git tag -a "v$VERSION" -m "sourcebot v$VERSION"

- name: Push changes
Expand All@@ -79,8 +131,17 @@ jobs:
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
VERSION="${{ inputs.version }}"
gh release create "v$VERSION" \
--verify-tag \
--generate-notes \
--latest

publish:
needs: release
uses: ./.github/workflows/ghcr-publish.yml
with:
version: v${{ needs.release.outputs.version }}
permissions:
contents: read
packages: write
id-token: write
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Changed
- Bake Sourcebot version into code rather than relying on build arg. [#680](https://github.com/sourcebot-dev/sourcebot/pull/680)

## [4.10.4] - 2025-12-18

### Fixed
Expand Down
20 changes: 7 additions & 13 deletions Dockerfile
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,7 +8,6 @@
# in the webapp.
# @see: https://docs.docker.com/build/building/variables/#scoping

ARG NEXT_PUBLIC_SOURCEBOT_VERSION
ARG NEXT_PUBLIC_SENTRY_ENVIRONMENT
ARG NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT
ARG NEXT_PUBLIC_SENTRY_WEBAPP_DSN
Expand DownExpand Up@@ -51,8 +50,6 @@ RUN yarn workspace @sourcebot/query-language install
FROM node-alpine AS web-builder
ENV SKIP_ENV_VALIDATION=1
# -----------
ARG NEXT_PUBLIC_SOURCEBOT_VERSION
ENV NEXT_PUBLIC_SOURCEBOT_VERSION=$NEXT_PUBLIC_SOURCEBOT_VERSION
ARG NEXT_PUBLIC_SENTRY_ENVIRONMENT
ENV NEXT_PUBLIC_SENTRY_ENVIRONMENT=$NEXT_PUBLIC_SENTRY_ENVIRONMENT
ARG NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT
Expand All@@ -72,7 +69,8 @@ ARG SENTRY_ORG
ENV SENTRY_ORG=$SENTRY_ORG
ARG SENTRY_WEBAPP_PROJECT
ENV SENTRY_WEBAPP_PROJECT=$SENTRY_WEBAPP_PROJECT
ENV SENTRY_RELEASE=$NEXT_PUBLIC_SOURCEBOT_VERSION
ARG SENTRY_RELEASE
ENV SENTRY_RELEASE=$SENTRY_RELEASE
# SMUAT = Source Map Upload Auth Token
ARG SENTRY_SMUAT
ENV SENTRY_SMUAT=$SENTRY_SMUAT
Expand DownExpand Up@@ -102,8 +100,6 @@ ENV SKIP_ENV_VALIDATION=0
FROM node-alpine AS backend-builder
ENV SKIP_ENV_VALIDATION=1
# -----------
ARG NEXT_PUBLIC_SOURCEBOT_VERSION
ENV NEXT_PUBLIC_SOURCEBOT_VERSION=$NEXT_PUBLIC_SOURCEBOT_VERSION

# To upload source maps to Sentry, we need to set the following build-time args.
# It's important that we don't set these for oss builds, otherwise the Sentry
Expand All@@ -115,6 +111,8 @@ ENV SENTRY_BACKEND_PROJECT=$SENTRY_BACKEND_PROJECT
# SMUAT = Source Map Upload Auth Token
ARG SENTRY_SMUAT
ENV SENTRY_SMUAT=$SENTRY_SMUAT
ARG SENTRY_RELEASE
ENV SENTRY_RELEASE=$SENTRY_RELEASE
# -----------

WORKDIR /app
Expand All@@ -132,12 +130,12 @@ RUN yarn workspace @sourcebot/backend install
RUN yarn workspace @sourcebot/backend build

# Upload source maps to Sentry if we have the necessary build-time args.
RUN if [ -n "$SENTRY_SMUAT" ] && [ -n "$SENTRY_ORG" ] && [ -n "$SENTRY_BACKEND_PROJECT" ] && [ -n "$NEXT_PUBLIC_SOURCEBOT_VERSION" ]; then \
RUN if [ -n "$SENTRY_SMUAT" ] && [ -n "$SENTRY_ORG" ] && [ -n "$SENTRY_BACKEND_PROJECT" ] && [ -n "$SENTRY_RELEASE" ]; then \
apk add --no-cache curl; \
curl -sL https://sentry.io/get-cli/ | sh; \
sentry-cli login --auth-token $SENTRY_SMUAT; \
sentry-cli sourcemaps inject --org $SENTRY_ORG --project $SENTRY_BACKEND_PROJECT --release $NEXT_PUBLIC_SOURCEBOT_VERSION ./packages/backend/dist; \
sentry-cli sourcemaps upload --org $SENTRY_ORG --project $SENTRY_BACKEND_PROJECT --release $NEXT_PUBLIC_SOURCEBOT_VERSION ./packages/backend/dist; \
sentry-cli sourcemaps inject --org $SENTRY_ORG --project $SENTRY_BACKEND_PROJECT --release $SENTRY_RELEASE ./packages/backend/dist; \
sentry-cli sourcemaps upload --org $SENTRY_ORG --project $SENTRY_BACKEND_PROJECT --release $SENTRY_RELEASE ./packages/backend/dist; \
fi

ENV SKIP_ENV_VALIDATION=0
Expand All@@ -146,8 +144,6 @@ ENV SKIP_ENV_VALIDATION=0
# ------ Runner ------
FROM node-alpine AS runner
# -----------
ARG NEXT_PUBLIC_SOURCEBOT_VERSION
ENV NEXT_PUBLIC_SOURCEBOT_VERSION=$NEXT_PUBLIC_SOURCEBOT_VERSION
ARG NEXT_PUBLIC_SENTRY_ENVIRONMENT
ENV NEXT_PUBLIC_SENTRY_ENVIRONMENT=$NEXT_PUBLIC_SENTRY_ENVIRONMENT
ARG NEXT_PUBLIC_SENTRY_WEBAPP_DSN
Expand All@@ -160,8 +156,6 @@ ARG NEXT_PUBLIC_LANGFUSE_BASE_URL
ENV NEXT_PUBLIC_LANGFUSE_BASE_URL=$NEXT_PUBLIC_LANGFUSE_BASE_URL
# -----------

RUN echo "Sourcebot Version: $NEXT_PUBLIC_SOURCEBOT_VERSION"

WORKDIR /app
ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1
Expand Down
24 changes: 18 additions & 6 deletions entrypoint.sh
Original file line numberDiff line numberDiff line change
Expand Up@@ -63,8 +63,20 @@ else
export REDIS_EMBEDDED="false"
fi

# Extract version from version.ts
VERSION_FILE="/app/packages/shared/src/version.ts"
if [ -f "$VERSION_FILE" ]; then
SOURCEBOT_VERSION=$(grep -o '"v[^"]*"' "$VERSION_FILE" | tr -d '"')
# Validate extraction succeeded
if [ -z "$SOURCEBOT_VERSION" ]; then
echo -e "\e[33m[Warning] Failed to extract version from $VERSION_FILE. Setting to 'unknown'.\e[0m" >&2
SOURCEBOT_VERSION="unknown"
fi
else
SOURCEBOT_VERSION="unknown"
fi
Comment thread
brendan-kellam marked this conversation as resolved.

echo -e "\e[34m[Info] Sourcebot version: $NEXT_PUBLIC_SOURCEBOT_VERSION\e[0m"
echo -e "\e[34m[Info] Sourcebot version: $SOURCEBOT_VERSION\e[0m"

if [ -n "$SOURCEBOT_TELEMETRY_DISABLED" ]; then
# Validate that SOURCEBOT_TELEMETRY_DISABLED is either "true" or "false"
Expand DownExpand Up@@ -157,7 +169,7 @@ if [ ! -f "$FIRST_RUN_FILE" ]; then
"event": "install",
"distinct_id": "'"$SOURCEBOT_INSTALL_ID"'",
"properties": {
"sourcebot_version": "'"$NEXT_PUBLIC_SOURCEBOT_VERSION"'"
"sourcebot_version": "'"$SOURCEBOT_VERSION"'"
}
}' https://us.i.posthog.com/capture/ ) then
echo -e "\e[33m[Warning] Failed to send install event.\e[0m"
Expand All@@ -168,8 +180,8 @@ else
PREVIOUS_VERSION=$(cat "$FIRST_RUN_FILE" | jq -r '.version')

# If the version has changed, we assume an upgrade has occurred.
if [ "$PREVIOUS_VERSION" != "$NEXT_PUBLIC_SOURCEBOT_VERSION" ]; then
echo -e "\e[34m[Info] Upgraded from version $PREVIOUS_VERSION to $NEXT_PUBLIC_SOURCEBOT_VERSION\e[0m"
if [ "$PREVIOUS_VERSION" != "$SOURCEBOT_VERSION" ]; then
echo -e "\e[34m[Info] Upgraded from version $PREVIOUS_VERSION to $SOURCEBOT_VERSION\e[0m"

if [ "$SOURCEBOT_TELEMETRY_DISABLED" = "false" ]; then
if ! ( curl -L --output /dev/null --silent --fail --header "Content-Type: application/json" -d '{
Expand All@@ -178,7 +190,7 @@ else
"distinct_id": "'"$SOURCEBOT_INSTALL_ID"'",
"properties": {
"from_version": "'"$PREVIOUS_VERSION"'",
"to_version": "'"$NEXT_PUBLIC_SOURCEBOT_VERSION"'"
"to_version": "'"$SOURCEBOT_VERSION"'"
}
}' https://us.i.posthog.com/capture/ ) then
echo -e "\e[33m[Warning] Failed to send upgrade event.\e[0m"
Expand All@@ -187,7 +199,7 @@ else
fi
fi

echo "{\"version\": \"$NEXT_PUBLIC_SOURCEBOT_VERSION\", \"install_id\": \"$SOURCEBOT_INSTALL_ID\"}" > "$FIRST_RUN_FILE"
echo "{\"version\": \"$SOURCEBOT_VERSION\", \"install_id\": \"$SOURCEBOT_INSTALL_ID\"}" > "$FIRST_RUN_FILE"

# Start the database and wait for it to be ready before starting any other service
if [ "$DATABASE_EMBEDDED" = "true" ]; then
Expand Down
4 changes: 2 additions & 2 deletions packages/backend/src/instrument.ts
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
import * as Sentry from "@sentry/node";
import { createLogger } from "@sourcebot/shared";
import { createLogger, SOURCEBOT_VERSION } from "@sourcebot/shared";
import { env } from "@sourcebot/shared/client";

const logger = createLogger('instrument');

if (!!env.NEXT_PUBLIC_SENTRY_BACKEND_DSN && !!env.NEXT_PUBLIC_SENTRY_ENVIRONMENT) {
Sentry.init({
dsn: env.NEXT_PUBLIC_SENTRY_BACKEND_DSN,
release: env.NEXT_PUBLIC_SOURCEBOT_VERSION,
release: SOURCEBOT_VERSION,
environment: env.NEXT_PUBLIC_SENTRY_ENVIRONMENT,
});
} else {
Expand Down
5 changes: 2 additions & 3 deletions packages/backend/src/posthog.ts
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
import { env as clientEnv } from "@sourcebot/shared/client";
import { env } from "@sourcebot/shared";
import { env, SOURCEBOT_VERSION } from "@sourcebot/shared";
import { PostHog } from 'posthog-node';
import { PosthogEvent, PosthogEventMap } from './posthogEvents.js';

Expand All@@ -24,7 +23,7 @@ export function captureEvent<E extends PosthogEvent>(event: E, properties: Posth
event: event,
properties: {
...properties,
sourcebot_version: clientEnv.NEXT_PUBLIC_SOURCEBOT_VERSION,
sourcebot_version: SOURCEBOT_VERSION,
},
});
}
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions .env.development
Original file line numberDiff line numberDiff line change
Expand Up@@ -77,9 +77,6 @@ SOURCEBOT_TELEMETRY_DISABLED=true # Disables telemetry collection
# Controls the number of concurrent indexing jobs that can run at once
# INDEX_CONCURRENCY_MULTIPLE=

# Controls the version of the web app
# NEXT_PUBLIC_SOURCEBOT_VERSION=

# CONFIG_MAX_REPOS_NO_TOKEN=
NODE_ENV=development
# SOURCEBOT_TENANCY_MODE=single
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/_gcp-deploy.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -54,7 +54,6 @@ jobs:
${{ env.IMAGE_PATH }}:${{ github.sha }}
${{ env.IMAGE_PATH }}:latest
build-args: |
NEXT_PUBLIC_SOURCEBOT_VERSION=${{ github.ref_name }}
NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT=${{ vars.NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT }}
NEXT_PUBLIC_SENTRY_ENVIRONMENT=${{ vars.NEXT_PUBLIC_SENTRY_ENVIRONMENT }}
NEXT_PUBLIC_SENTRY_WEBAPP_DSN=${{ vars.NEXT_PUBLIC_SENTRY_WEBAPP_DSN }}
Expand All@@ -65,6 +64,7 @@ jobs:
SENTRY_ORG=${{ vars.SENTRY_ORG }}
SENTRY_WEBAPP_PROJECT=${{ vars.SENTRY_WEBAPP_PROJECT }}
SENTRY_BACKEND_PROJECT=${{ vars.SENTRY_BACKEND_PROJECT }}
SENTRY_RELEASE=${{ github.ref_name }}


- name: Deploy to GCP
Expand Down
9 changes: 7 additions & 2 deletions .github/workflows/ghcr-publish.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -7,6 +7,12 @@ on:
push:
branches: ["main"]
tags: ["v*.*.*"]
workflow_call:
inputs:
version:
description: 'Version tag (e.g., v4.10.5)'
required: false
type: string

env:
# Use docker.io for Docker Hub if empty
Expand DownExpand Up@@ -40,6 +46,7 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v4
with:
ref: ${{ inputs.version || github.ref_name }}
submodules: "true"

# Extract metadata (tags, labels) for Docker
Expand DownExpand Up@@ -77,8 +84,6 @@ jobs:
cache-to: type=gha,mode=max,scope=${{ env.PLATFORM_PAIR }}
platforms: ${{ matrix.platform }}
outputs: type=image,name=${{ env.REGISTRY_IMAGE }},push-by-digest=true,name-canonical=true,push=true,annotation.org.opencontainers.image.description=Blazingly fast code search
build-args: |
NEXT_PUBLIC_SOURCEBOT_VERSION=${{ github.ref_name }}

- name: Export digest
run: |
Expand Down
99 changes: 80 additions & 19 deletions .github/workflows/release-sourcebot.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -3,35 +3,82 @@ name: Release Sourcebot
on:
workflow_dispatch:
inputs:
version:
description: "Version to release (e.g., 4.10.5)"
bump_type:
description: "Type of version bump to apply"
required: true
type: string
type: choice
options:
- patch
- minor
- major

concurrency:
group: release-sourcebot
cancel-in-progress: false

jobs:
release:
runs-on: ubuntu-latest
permissions:
contents: write
outputs:
version: ${{ steps.calculate_version.outputs.version }}

steps:
- name: Validate version format
run: |
VERSION="${{ inputs.version }}"
if ! [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9._-]+)?(\+[a-zA-Z0-9._-]+)?$ ]]; then
echo "Error: Version must follow semantic versioning format (X.Y.Z)"
exit 1
fi

- name: Checkout repository
uses: actions/checkout@v4
with:
ref: main
fetch-depth: 0

- name: Calculate new version
id: calculate_version
run: |
# Extract current version from CHANGELOG.md
CURRENT_VERSION=$(grep -oP '## \[\K[0-9]+\.[0-9]+\.[0-9]+' CHANGELOG.md | head -n 1)

if [ -z "$CURRENT_VERSION" ]; then
echo "Error: Could not extract current version from CHANGELOG.md"
exit 1
fi

echo "Current version: $CURRENT_VERSION"

# Parse version components
IFS='.' read -r MAJOR MINOR PATCH <<< "$CURRENT_VERSION"

# Apply bump based on input
BUMP_TYPE="${{ inputs.bump_type }}"
case "$BUMP_TYPE" in
major)
MAJOR=$((MAJOR + 1))
MINOR=0
PATCH=0
;;
minor)
MINOR=$((MINOR + 1))
PATCH=0
;;
patch)
PATCH=$((PATCH + 1))
;;
*)
echo "Error: Invalid bump type: $BUMP_TYPE"
exit 1
;;
esac

NEW_VERSION="$MAJOR.$MINOR.$PATCH"
echo "New version: $NEW_VERSION"

# Export to GITHUB_ENV for use in subsequent steps within this job
echo "VERSION=$NEW_VERSION" >> $GITHUB_ENV

# Export to GITHUB_OUTPUT for use in other jobs
echo "version=$NEW_VERSION" >> $GITHUB_OUTPUT

- name: Check if version already exists
run: |
VERSION="${{ inputs.version }}"
if grep -q "## \[$VERSION\]" CHANGELOG.md; then
echo "Error: Version $VERSION already exists in CHANGELOG.md"
exit 1
Expand All@@ -41,9 +88,8 @@ jobs:
exit 1
fi

- name: Update CHANGELOG.md
- name: Update CHANGELOG.md and version.ts
run: |
VERSION="${{ inputs.version }}"
DATE=$(date +%Y-%m-%d)

# Insert the new version header after the [Unreleased] line
Expand All@@ -54,20 +100,26 @@ jobs:
echo "Updated CHANGELOG.md with version $VERSION"
cat CHANGELOG.md | head -n 15

# Update version.ts
cat > packages/shared/src/version.ts << EOF
// This file is auto-generated by .github/workflows/release-sourcebot.yml
export const SOURCEBOT_VERSION = "v$VERSION";
EOF
echo "Updated version.ts with version v$VERSION"
cat packages/shared/src/version.ts
Comment thread
brendan-kellam marked this conversation as resolved.

- name: Configure git
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"

- name: Commit CHANGELOG
- name: Commit changes
run: |
VERSION="${{ inputs.version }}"
git add CHANGELOG.md
git add CHANGELOG.md packages/shared/src/version.ts
git commit -m "Release v$VERSION"

- name: Create annotated tag
run: |
VERSION="${{ inputs.version }}"
git tag -a "v$VERSION" -m "sourcebot v$VERSION"

- name: Push changes
Expand All@@ -79,8 +131,17 @@ jobs:
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
VERSION="${{ inputs.version }}"
gh release create "v$VERSION" \
--verify-tag \
--generate-notes \
--latest

publish:
needs: release
uses: ./.github/workflows/ghcr-publish.yml
with:
version: v${{ needs.release.outputs.version }}
permissions:
contents: read
packages: write
id-token: write
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Changed
- Bake Sourcebot version into code rather than relying on build arg. [#680](https://github.com/sourcebot-dev/sourcebot/pull/680)

## [4.10.4] - 2025-12-18

### Fixed
Expand Down
20 changes: 7 additions & 13 deletions Dockerfile
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,7 +8,6 @@
# in the webapp.
# @see: https://docs.docker.com/build/building/variables/#scoping

ARG NEXT_PUBLIC_SOURCEBOT_VERSION
ARG NEXT_PUBLIC_SENTRY_ENVIRONMENT
ARG NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT
ARG NEXT_PUBLIC_SENTRY_WEBAPP_DSN
Expand DownExpand Up@@ -51,8 +50,6 @@ RUN yarn workspace @sourcebot/query-language install
FROM node-alpine AS web-builder
ENV SKIP_ENV_VALIDATION=1
# -----------
ARG NEXT_PUBLIC_SOURCEBOT_VERSION
ENV NEXT_PUBLIC_SOURCEBOT_VERSION=$NEXT_PUBLIC_SOURCEBOT_VERSION
ARG NEXT_PUBLIC_SENTRY_ENVIRONMENT
ENV NEXT_PUBLIC_SENTRY_ENVIRONMENT=$NEXT_PUBLIC_SENTRY_ENVIRONMENT
ARG NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT
Expand All@@ -72,7 +69,8 @@ ARG SENTRY_ORG
ENV SENTRY_ORG=$SENTRY_ORG
ARG SENTRY_WEBAPP_PROJECT
ENV SENTRY_WEBAPP_PROJECT=$SENTRY_WEBAPP_PROJECT
ENV SENTRY_RELEASE=$NEXT_PUBLIC_SOURCEBOT_VERSION
ARG SENTRY_RELEASE
ENV SENTRY_RELEASE=$SENTRY_RELEASE
# SMUAT = Source Map Upload Auth Token
ARG SENTRY_SMUAT
ENV SENTRY_SMUAT=$SENTRY_SMUAT
Expand DownExpand Up@@ -102,8 +100,6 @@ ENV SKIP_ENV_VALIDATION=0
FROM node-alpine AS backend-builder
ENV SKIP_ENV_VALIDATION=1
# -----------
ARG NEXT_PUBLIC_SOURCEBOT_VERSION
ENV NEXT_PUBLIC_SOURCEBOT_VERSION=$NEXT_PUBLIC_SOURCEBOT_VERSION

# To upload source maps to Sentry, we need to set the following build-time args.
# It's important that we don't set these for oss builds, otherwise the Sentry
Expand All@@ -115,6 +111,8 @@ ENV SENTRY_BACKEND_PROJECT=$SENTRY_BACKEND_PROJECT
# SMUAT = Source Map Upload Auth Token
ARG SENTRY_SMUAT
ENV SENTRY_SMUAT=$SENTRY_SMUAT
ARG SENTRY_RELEASE
ENV SENTRY_RELEASE=$SENTRY_RELEASE
# -----------

WORKDIR /app
Expand All@@ -132,12 +130,12 @@ RUN yarn workspace @sourcebot/backend install
RUN yarn workspace @sourcebot/backend build

# Upload source maps to Sentry if we have the necessary build-time args.
RUN if [ -n "$SENTRY_SMUAT" ] && [ -n "$SENTRY_ORG" ] && [ -n "$SENTRY_BACKEND_PROJECT" ] && [ -n "$NEXT_PUBLIC_SOURCEBOT_VERSION" ]; then \
RUN if [ -n "$SENTRY_SMUAT" ] && [ -n "$SENTRY_ORG" ] && [ -n "$SENTRY_BACKEND_PROJECT" ] && [ -n "$SENTRY_RELEASE" ]; then \
apk add --no-cache curl; \
curl -sL https://sentry.io/get-cli/ | sh; \
sentry-cli login --auth-token $SENTRY_SMUAT; \
sentry-cli sourcemaps inject --org $SENTRY_ORG --project $SENTRY_BACKEND_PROJECT --release $NEXT_PUBLIC_SOURCEBOT_VERSION ./packages/backend/dist; \
sentry-cli sourcemaps upload --org $SENTRY_ORG --project $SENTRY_BACKEND_PROJECT --release $NEXT_PUBLIC_SOURCEBOT_VERSION ./packages/backend/dist; \
sentry-cli sourcemaps inject --org $SENTRY_ORG --project $SENTRY_BACKEND_PROJECT --release $SENTRY_RELEASE ./packages/backend/dist; \
sentry-cli sourcemaps upload --org $SENTRY_ORG --project $SENTRY_BACKEND_PROJECT --release $SENTRY_RELEASE ./packages/backend/dist; \
fi

ENV SKIP_ENV_VALIDATION=0
Expand All@@ -146,8 +144,6 @@ ENV SKIP_ENV_VALIDATION=0
# ------ Runner ------
FROM node-alpine AS runner
# -----------
ARG NEXT_PUBLIC_SOURCEBOT_VERSION
ENV NEXT_PUBLIC_SOURCEBOT_VERSION=$NEXT_PUBLIC_SOURCEBOT_VERSION
ARG NEXT_PUBLIC_SENTRY_ENVIRONMENT
ENV NEXT_PUBLIC_SENTRY_ENVIRONMENT=$NEXT_PUBLIC_SENTRY_ENVIRONMENT
ARG NEXT_PUBLIC_SENTRY_WEBAPP_DSN
Expand All@@ -160,8 +156,6 @@ ARG NEXT_PUBLIC_LANGFUSE_BASE_URL
ENV NEXT_PUBLIC_LANGFUSE_BASE_URL=$NEXT_PUBLIC_LANGFUSE_BASE_URL
# -----------

RUN echo "Sourcebot Version: $NEXT_PUBLIC_SOURCEBOT_VERSION"

WORKDIR /app
ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1
Expand Down
24 changes: 18 additions & 6 deletions entrypoint.sh
Original file line numberDiff line numberDiff line change
Expand Up@@ -63,8 +63,20 @@ else
export REDIS_EMBEDDED="false"
fi

# Extract version from version.ts
VERSION_FILE="/app/packages/shared/src/version.ts"
if [ -f "$VERSION_FILE" ]; then
SOURCEBOT_VERSION=$(grep -o '"v[^"]*"' "$VERSION_FILE" | tr -d '"')
# Validate extraction succeeded
if [ -z "$SOURCEBOT_VERSION" ]; then
echo -e "\e[33m[Warning] Failed to extract version from $VERSION_FILE. Setting to 'unknown'.\e[0m" >&2
SOURCEBOT_VERSION="unknown"
fi
else
SOURCEBOT_VERSION="unknown"
fi
Comment thread
brendan-kellam marked this conversation as resolved.

echo -e "\e[34m[Info] Sourcebot version: $NEXT_PUBLIC_SOURCEBOT_VERSION\e[0m"
echo -e "\e[34m[Info] Sourcebot version: $SOURCEBOT_VERSION\e[0m"

if [ -n "$SOURCEBOT_TELEMETRY_DISABLED" ]; then
# Validate that SOURCEBOT_TELEMETRY_DISABLED is either "true" or "false"
Expand DownExpand Up@@ -157,7 +169,7 @@ if [ ! -f "$FIRST_RUN_FILE" ]; then
"event": "install",
"distinct_id": "'"$SOURCEBOT_INSTALL_ID"'",
"properties": {
"sourcebot_version": "'"$NEXT_PUBLIC_SOURCEBOT_VERSION"'"
"sourcebot_version": "'"$SOURCEBOT_VERSION"'"
}
}' https://us.i.posthog.com/capture/ ) then
echo -e "\e[33m[Warning] Failed to send install event.\e[0m"
Expand All@@ -168,8 +180,8 @@ else
PREVIOUS_VERSION=$(cat "$FIRST_RUN_FILE" | jq -r '.version')

# If the version has changed, we assume an upgrade has occurred.
if [ "$PREVIOUS_VERSION" != "$NEXT_PUBLIC_SOURCEBOT_VERSION" ]; then
echo -e "\e[34m[Info] Upgraded from version $PREVIOUS_VERSION to $NEXT_PUBLIC_SOURCEBOT_VERSION\e[0m"
if [ "$PREVIOUS_VERSION" != "$SOURCEBOT_VERSION" ]; then
echo -e "\e[34m[Info] Upgraded from version $PREVIOUS_VERSION to $SOURCEBOT_VERSION\e[0m"

if [ "$SOURCEBOT_TELEMETRY_DISABLED" = "false" ]; then
if ! ( curl -L --output /dev/null --silent --fail --header "Content-Type: application/json" -d '{
Expand All@@ -178,7 +190,7 @@ else
"distinct_id": "'"$SOURCEBOT_INSTALL_ID"'",
"properties": {
"from_version": "'"$PREVIOUS_VERSION"'",
"to_version": "'"$NEXT_PUBLIC_SOURCEBOT_VERSION"'"
"to_version": "'"$SOURCEBOT_VERSION"'"
}
}' https://us.i.posthog.com/capture/ ) then
echo -e "\e[33m[Warning] Failed to send upgrade event.\e[0m"
Expand All@@ -187,7 +199,7 @@ else
fi
fi

echo "{\"version\": \"$NEXT_PUBLIC_SOURCEBOT_VERSION\", \"install_id\": \"$SOURCEBOT_INSTALL_ID\"}" > "$FIRST_RUN_FILE"
echo "{\"version\": \"$SOURCEBOT_VERSION\", \"install_id\": \"$SOURCEBOT_INSTALL_ID\"}" > "$FIRST_RUN_FILE"

# Start the database and wait for it to be ready before starting any other service
if [ "$DATABASE_EMBEDDED" = "true" ]; then
Expand Down
4 changes: 2 additions & 2 deletions packages/backend/src/instrument.ts
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
import * as Sentry from "@sentry/node";
import { createLogger } from "@sourcebot/shared";
import { createLogger, SOURCEBOT_VERSION } from "@sourcebot/shared";
import { env } from "@sourcebot/shared/client";

const logger = createLogger('instrument');

if (!!env.NEXT_PUBLIC_SENTRY_BACKEND_DSN && !!env.NEXT_PUBLIC_SENTRY_ENVIRONMENT) {
Sentry.init({
dsn: env.NEXT_PUBLIC_SENTRY_BACKEND_DSN,
release: env.NEXT_PUBLIC_SOURCEBOT_VERSION,
release: SOURCEBOT_VERSION,
environment: env.NEXT_PUBLIC_SENTRY_ENVIRONMENT,
});
} else {
Expand Down
5 changes: 2 additions & 3 deletions packages/backend/src/posthog.ts
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
import { env as clientEnv } from "@sourcebot/shared/client";
import { env } from "@sourcebot/shared";
import { env, SOURCEBOT_VERSION } from "@sourcebot/shared";
import { PostHog } from 'posthog-node';
import { PosthogEvent, PosthogEventMap } from './posthogEvents.js';

Expand All@@ -24,7 +23,7 @@ export function captureEvent<E extends PosthogEvent>(event: E, properties: Posth
event: event,
properties: {
...properties,
sourcebot_version: clientEnv.NEXT_PUBLIC_SOURCEBOT_VERSION,
sourcebot_version: SOURCEBOT_VERSION,
},
});
}
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions .env.development
Original file line numberDiff line numberDiff line change
Expand Up@@ -77,9 +77,6 @@ SOURCEBOT_TELEMETRY_DISABLED=true # Disables telemetry collection
# Controls the number of concurrent indexing jobs that can run at once
# INDEX_CONCURRENCY_MULTIPLE=

# Controls the version of the web app
# NEXT_PUBLIC_SOURCEBOT_VERSION=

# CONFIG_MAX_REPOS_NO_TOKEN=
NODE_ENV=development
# SOURCEBOT_TENANCY_MODE=single
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/_gcp-deploy.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -54,7 +54,6 @@ jobs:
${{ env.IMAGE_PATH }}:${{ github.sha }}
${{ env.IMAGE_PATH }}:latest
build-args: |
NEXT_PUBLIC_SOURCEBOT_VERSION=${{ github.ref_name }}
NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT=${{ vars.NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT }}
NEXT_PUBLIC_SENTRY_ENVIRONMENT=${{ vars.NEXT_PUBLIC_SENTRY_ENVIRONMENT }}
NEXT_PUBLIC_SENTRY_WEBAPP_DSN=${{ vars.NEXT_PUBLIC_SENTRY_WEBAPP_DSN }}
Expand All@@ -65,6 +64,7 @@ jobs:
SENTRY_ORG=${{ vars.SENTRY_ORG }}
SENTRY_WEBAPP_PROJECT=${{ vars.SENTRY_WEBAPP_PROJECT }}
SENTRY_BACKEND_PROJECT=${{ vars.SENTRY_BACKEND_PROJECT }}
SENTRY_RELEASE=${{ github.ref_name }}


- name: Deploy to GCP
Expand Down
9 changes: 7 additions & 2 deletions .github/workflows/ghcr-publish.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -7,6 +7,12 @@ on:
push:
branches: ["main"]
tags: ["v*.*.*"]
workflow_call:
inputs:
version:
description: 'Version tag (e.g., v4.10.5)'
required: false
type: string

env:
# Use docker.io for Docker Hub if empty
Expand DownExpand Up@@ -40,6 +46,7 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v4
with:
ref: ${{ inputs.version || github.ref_name }}
submodules: "true"

# Extract metadata (tags, labels) for Docker
Expand DownExpand Up@@ -77,8 +84,6 @@ jobs:
cache-to: type=gha,mode=max,scope=${{ env.PLATFORM_PAIR }}
platforms: ${{ matrix.platform }}
outputs: type=image,name=${{ env.REGISTRY_IMAGE }},push-by-digest=true,name-canonical=true,push=true,annotation.org.opencontainers.image.description=Blazingly fast code search
build-args: |
NEXT_PUBLIC_SOURCEBOT_VERSION=${{ github.ref_name }}

- name: Export digest
run: |
Expand Down
99 changes: 80 additions & 19 deletions .github/workflows/release-sourcebot.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -3,35 +3,82 @@ name: Release Sourcebot
on:
workflow_dispatch:
inputs:
version:
description: "Version to release (e.g., 4.10.5)"
bump_type:
description: "Type of version bump to apply"
required: true
type: string
type: choice
options:
- patch
- minor
- major

concurrency:
group: release-sourcebot
cancel-in-progress: false

jobs:
release:
runs-on: ubuntu-latest
permissions:
contents: write
outputs:
version: ${{ steps.calculate_version.outputs.version }}

steps:
- name: Validate version format
run: |
VERSION="${{ inputs.version }}"
if ! [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9._-]+)?(\+[a-zA-Z0-9._-]+)?$ ]]; then
echo "Error: Version must follow semantic versioning format (X.Y.Z)"
exit 1
fi

- name: Checkout repository
uses: actions/checkout@v4
with:
ref: main
fetch-depth: 0

- name: Calculate new version
id: calculate_version
run: |
# Extract current version from CHANGELOG.md
CURRENT_VERSION=$(grep -oP '## \[\K[0-9]+\.[0-9]+\.[0-9]+' CHANGELOG.md | head -n 1)

if [ -z "$CURRENT_VERSION" ]; then
echo "Error: Could not extract current version from CHANGELOG.md"
exit 1
fi

echo "Current version: $CURRENT_VERSION"

# Parse version components
IFS='.' read -r MAJOR MINOR PATCH <<< "$CURRENT_VERSION"

# Apply bump based on input
BUMP_TYPE="${{ inputs.bump_type }}"
case "$BUMP_TYPE" in
major)
MAJOR=$((MAJOR + 1))
MINOR=0
PATCH=0
;;
minor)
MINOR=$((MINOR + 1))
PATCH=0
;;
patch)
PATCH=$((PATCH + 1))
;;
*)
echo "Error: Invalid bump type: $BUMP_TYPE"
exit 1
;;
esac

NEW_VERSION="$MAJOR.$MINOR.$PATCH"
echo "New version: $NEW_VERSION"

# Export to GITHUB_ENV for use in subsequent steps within this job
echo "VERSION=$NEW_VERSION" >> $GITHUB_ENV

# Export to GITHUB_OUTPUT for use in other jobs
echo "version=$NEW_VERSION" >> $GITHUB_OUTPUT

- name: Check if version already exists
run: |
VERSION="${{ inputs.version }}"
if grep -q "## \[$VERSION\]" CHANGELOG.md; then
echo "Error: Version $VERSION already exists in CHANGELOG.md"
exit 1
Expand All@@ -41,9 +88,8 @@ jobs:
exit 1
fi

- name: Update CHANGELOG.md
- name: Update CHANGELOG.md and version.ts
run: |
VERSION="${{ inputs.version }}"
DATE=$(date +%Y-%m-%d)

# Insert the new version header after the [Unreleased] line
Expand All@@ -54,20 +100,26 @@ jobs:
echo "Updated CHANGELOG.md with version $VERSION"
cat CHANGELOG.md | head -n 15

# Update version.ts
cat > packages/shared/src/version.ts << EOF
// This file is auto-generated by .github/workflows/release-sourcebot.yml
export const SOURCEBOT_VERSION = "v$VERSION";
EOF
echo "Updated version.ts with version v$VERSION"
cat packages/shared/src/version.ts
Comment thread
brendan-kellam marked this conversation as resolved.

- name: Configure git
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"

- name: Commit CHANGELOG
- name: Commit changes
run: |
VERSION="${{ inputs.version }}"
git add CHANGELOG.md
git add CHANGELOG.md packages/shared/src/version.ts
git commit -m "Release v$VERSION"

- name: Create annotated tag
run: |
VERSION="${{ inputs.version }}"
git tag -a "v$VERSION" -m "sourcebot v$VERSION"

- name: Push changes
Expand All@@ -79,8 +131,17 @@ jobs:
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
VERSION="${{ inputs.version }}"
gh release create "v$VERSION" \
--verify-tag \
--generate-notes \
--latest

publish:
needs: release
uses: ./.github/workflows/ghcr-publish.yml
with:
version: v${{ needs.release.outputs.version }}
permissions:
contents: read
packages: write
id-token: write
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Changed
- Bake Sourcebot version into code rather than relying on build arg. [#680](https://github.com/sourcebot-dev/sourcebot/pull/680)

## [4.10.4] - 2025-12-18

### Fixed
Expand Down
20 changes: 7 additions & 13 deletions Dockerfile
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,7 +8,6 @@
# in the webapp.
# @see: https://docs.docker.com/build/building/variables/#scoping

ARG NEXT_PUBLIC_SOURCEBOT_VERSION
ARG NEXT_PUBLIC_SENTRY_ENVIRONMENT
ARG NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT
ARG NEXT_PUBLIC_SENTRY_WEBAPP_DSN
Expand DownExpand Up@@ -51,8 +50,6 @@ RUN yarn workspace @sourcebot/query-language install
FROM node-alpine AS web-builder
ENV SKIP_ENV_VALIDATION=1
# -----------
ARG NEXT_PUBLIC_SOURCEBOT_VERSION
ENV NEXT_PUBLIC_SOURCEBOT_VERSION=$NEXT_PUBLIC_SOURCEBOT_VERSION
ARG NEXT_PUBLIC_SENTRY_ENVIRONMENT
ENV NEXT_PUBLIC_SENTRY_ENVIRONMENT=$NEXT_PUBLIC_SENTRY_ENVIRONMENT
ARG NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT
Expand All@@ -72,7 +69,8 @@ ARG SENTRY_ORG
ENV SENTRY_ORG=$SENTRY_ORG
ARG SENTRY_WEBAPP_PROJECT
ENV SENTRY_WEBAPP_PROJECT=$SENTRY_WEBAPP_PROJECT
ENV SENTRY_RELEASE=$NEXT_PUBLIC_SOURCEBOT_VERSION
ARG SENTRY_RELEASE
ENV SENTRY_RELEASE=$SENTRY_RELEASE
# SMUAT = Source Map Upload Auth Token
ARG SENTRY_SMUAT
ENV SENTRY_SMUAT=$SENTRY_SMUAT
Expand DownExpand Up@@ -102,8 +100,6 @@ ENV SKIP_ENV_VALIDATION=0
FROM node-alpine AS backend-builder
ENV SKIP_ENV_VALIDATION=1
# -----------
ARG NEXT_PUBLIC_SOURCEBOT_VERSION
ENV NEXT_PUBLIC_SOURCEBOT_VERSION=$NEXT_PUBLIC_SOURCEBOT_VERSION

# To upload source maps to Sentry, we need to set the following build-time args.
# It's important that we don't set these for oss builds, otherwise the Sentry
Expand All@@ -115,6 +111,8 @@ ENV SENTRY_BACKEND_PROJECT=$SENTRY_BACKEND_PROJECT
# SMUAT = Source Map Upload Auth Token
ARG SENTRY_SMUAT
ENV SENTRY_SMUAT=$SENTRY_SMUAT
ARG SENTRY_RELEASE
ENV SENTRY_RELEASE=$SENTRY_RELEASE
# -----------

WORKDIR /app
Expand All@@ -132,12 +130,12 @@ RUN yarn workspace @sourcebot/backend install
RUN yarn workspace @sourcebot/backend build

# Upload source maps to Sentry if we have the necessary build-time args.
RUN if [ -n "$SENTRY_SMUAT" ] && [ -n "$SENTRY_ORG" ] && [ -n "$SENTRY_BACKEND_PROJECT" ] && [ -n "$NEXT_PUBLIC_SOURCEBOT_VERSION" ]; then \
RUN if [ -n "$SENTRY_SMUAT" ] && [ -n "$SENTRY_ORG" ] && [ -n "$SENTRY_BACKEND_PROJECT" ] && [ -n "$SENTRY_RELEASE" ]; then \
apk add --no-cache curl; \
curl -sL https://sentry.io/get-cli/ | sh; \
sentry-cli login --auth-token $SENTRY_SMUAT; \
sentry-cli sourcemaps inject --org $SENTRY_ORG --project $SENTRY_BACKEND_PROJECT --release $NEXT_PUBLIC_SOURCEBOT_VERSION ./packages/backend/dist; \
sentry-cli sourcemaps upload --org $SENTRY_ORG --project $SENTRY_BACKEND_PROJECT --release $NEXT_PUBLIC_SOURCEBOT_VERSION ./packages/backend/dist; \
sentry-cli sourcemaps inject --org $SENTRY_ORG --project $SENTRY_BACKEND_PROJECT --release $SENTRY_RELEASE ./packages/backend/dist; \
sentry-cli sourcemaps upload --org $SENTRY_ORG --project $SENTRY_BACKEND_PROJECT --release $SENTRY_RELEASE ./packages/backend/dist; \
fi

ENV SKIP_ENV_VALIDATION=0
Expand All@@ -146,8 +144,6 @@ ENV SKIP_ENV_VALIDATION=0
# ------ Runner ------
FROM node-alpine AS runner
# -----------
ARG NEXT_PUBLIC_SOURCEBOT_VERSION
ENV NEXT_PUBLIC_SOURCEBOT_VERSION=$NEXT_PUBLIC_SOURCEBOT_VERSION
ARG NEXT_PUBLIC_SENTRY_ENVIRONMENT
ENV NEXT_PUBLIC_SENTRY_ENVIRONMENT=$NEXT_PUBLIC_SENTRY_ENVIRONMENT
ARG NEXT_PUBLIC_SENTRY_WEBAPP_DSN
Expand All@@ -160,8 +156,6 @@ ARG NEXT_PUBLIC_LANGFUSE_BASE_URL
ENV NEXT_PUBLIC_LANGFUSE_BASE_URL=$NEXT_PUBLIC_LANGFUSE_BASE_URL
# -----------

RUN echo "Sourcebot Version: $NEXT_PUBLIC_SOURCEBOT_VERSION"

WORKDIR /app
ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1
Expand Down
24 changes: 18 additions & 6 deletions entrypoint.sh
Original file line numberDiff line numberDiff line change
Expand Up@@ -63,8 +63,20 @@ else
export REDIS_EMBEDDED="false"
fi

# Extract version from version.ts
VERSION_FILE="/app/packages/shared/src/version.ts"
if [ -f "$VERSION_FILE" ]; then
SOURCEBOT_VERSION=$(grep -o '"v[^"]*"' "$VERSION_FILE" | tr -d '"')
# Validate extraction succeeded
if [ -z "$SOURCEBOT_VERSION" ]; then
echo -e "\e[33m[Warning] Failed to extract version from $VERSION_FILE. Setting to 'unknown'.\e[0m" >&2
SOURCEBOT_VERSION="unknown"
fi
else
SOURCEBOT_VERSION="unknown"
fi
Comment thread
brendan-kellam marked this conversation as resolved.

echo -e "\e[34m[Info] Sourcebot version: $NEXT_PUBLIC_SOURCEBOT_VERSION\e[0m"
echo -e "\e[34m[Info] Sourcebot version: $SOURCEBOT_VERSION\e[0m"

if [ -n "$SOURCEBOT_TELEMETRY_DISABLED" ]; then
# Validate that SOURCEBOT_TELEMETRY_DISABLED is either "true" or "false"
Expand DownExpand Up@@ -157,7 +169,7 @@ if [ ! -f "$FIRST_RUN_FILE" ]; then
"event": "install",
"distinct_id": "'"$SOURCEBOT_INSTALL_ID"'",
"properties": {
"sourcebot_version": "'"$NEXT_PUBLIC_SOURCEBOT_VERSION"'"
"sourcebot_version": "'"$SOURCEBOT_VERSION"'"
}
}' https://us.i.posthog.com/capture/ ) then
echo -e "\e[33m[Warning] Failed to send install event.\e[0m"
Expand All@@ -168,8 +180,8 @@ else
PREVIOUS_VERSION=$(cat "$FIRST_RUN_FILE" | jq -r '.version')

# If the version has changed, we assume an upgrade has occurred.
if [ "$PREVIOUS_VERSION" != "$NEXT_PUBLIC_SOURCEBOT_VERSION" ]; then
echo -e "\e[34m[Info] Upgraded from version $PREVIOUS_VERSION to $NEXT_PUBLIC_SOURCEBOT_VERSION\e[0m"
if [ "$PREVIOUS_VERSION" != "$SOURCEBOT_VERSION" ]; then
echo -e "\e[34m[Info] Upgraded from version $PREVIOUS_VERSION to $SOURCEBOT_VERSION\e[0m"

if [ "$SOURCEBOT_TELEMETRY_DISABLED" = "false" ]; then
if ! ( curl -L --output /dev/null --silent --fail --header "Content-Type: application/json" -d '{
Expand All@@ -178,7 +190,7 @@ else
"distinct_id": "'"$SOURCEBOT_INSTALL_ID"'",
"properties": {
"from_version": "'"$PREVIOUS_VERSION"'",
"to_version": "'"$NEXT_PUBLIC_SOURCEBOT_VERSION"'"
"to_version": "'"$SOURCEBOT_VERSION"'"
}
}' https://us.i.posthog.com/capture/ ) then
echo -e "\e[33m[Warning] Failed to send upgrade event.\e[0m"
Expand All@@ -187,7 +199,7 @@ else
fi
fi

echo "{\"version\": \"$NEXT_PUBLIC_SOURCEBOT_VERSION\", \"install_id\": \"$SOURCEBOT_INSTALL_ID\"}" > "$FIRST_RUN_FILE"
echo "{\"version\": \"$SOURCEBOT_VERSION\", \"install_id\": \"$SOURCEBOT_INSTALL_ID\"}" > "$FIRST_RUN_FILE"

# Start the database and wait for it to be ready before starting any other service
if [ "$DATABASE_EMBEDDED" = "true" ]; then
Expand Down
4 changes: 2 additions & 2 deletions packages/backend/src/instrument.ts
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
import * as Sentry from "@sentry/node";
import { createLogger } from "@sourcebot/shared";
import { createLogger, SOURCEBOT_VERSION } from "@sourcebot/shared";
import { env } from "@sourcebot/shared/client";

const logger = createLogger('instrument');

if (!!env.NEXT_PUBLIC_SENTRY_BACKEND_DSN && !!env.NEXT_PUBLIC_SENTRY_ENVIRONMENT) {
Sentry.init({
dsn: env.NEXT_PUBLIC_SENTRY_BACKEND_DSN,
release: env.NEXT_PUBLIC_SOURCEBOT_VERSION,
release: SOURCEBOT_VERSION,
environment: env.NEXT_PUBLIC_SENTRY_ENVIRONMENT,
});
} else {
Expand Down
5 changes: 2 additions & 3 deletions packages/backend/src/posthog.ts
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
import { env as clientEnv } from "@sourcebot/shared/client";
import { env } from "@sourcebot/shared";
import { env, SOURCEBOT_VERSION } from "@sourcebot/shared";
import { PostHog } from 'posthog-node';
import { PosthogEvent, PosthogEventMap } from './posthogEvents.js';

Expand All@@ -24,7 +23,7 @@ export function captureEvent<E extends PosthogEvent>(event: E, properties: Posth
event: event,
properties: {
...properties,
sourcebot_version: clientEnv.NEXT_PUBLIC_SOURCEBOT_VERSION,
sourcebot_version: SOURCEBOT_VERSION,
},
});
}
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions .env.development
Original file line numberDiff line numberDiff line change
Expand Up@@ -77,9 +77,6 @@ SOURCEBOT_TELEMETRY_DISABLED=true # Disables telemetry collection
# Controls the number of concurrent indexing jobs that can run at once
# INDEX_CONCURRENCY_MULTIPLE=

# Controls the version of the web app
# NEXT_PUBLIC_SOURCEBOT_VERSION=

# CONFIG_MAX_REPOS_NO_TOKEN=
NODE_ENV=development
# SOURCEBOT_TENANCY_MODE=single
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/_gcp-deploy.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -54,7 +54,6 @@ jobs:
${{ env.IMAGE_PATH }}:${{ github.sha }}
${{ env.IMAGE_PATH }}:latest
build-args: |
NEXT_PUBLIC_SOURCEBOT_VERSION=${{ github.ref_name }}
NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT=${{ vars.NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT }}
NEXT_PUBLIC_SENTRY_ENVIRONMENT=${{ vars.NEXT_PUBLIC_SENTRY_ENVIRONMENT }}
NEXT_PUBLIC_SENTRY_WEBAPP_DSN=${{ vars.NEXT_PUBLIC_SENTRY_WEBAPP_DSN }}
Expand All@@ -65,6 +64,7 @@ jobs:
SENTRY_ORG=${{ vars.SENTRY_ORG }}
SENTRY_WEBAPP_PROJECT=${{ vars.SENTRY_WEBAPP_PROJECT }}
SENTRY_BACKEND_PROJECT=${{ vars.SENTRY_BACKEND_PROJECT }}
SENTRY_RELEASE=${{ github.ref_name }}


- name: Deploy to GCP
Expand Down
9 changes: 7 additions & 2 deletions .github/workflows/ghcr-publish.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -7,6 +7,12 @@ on:
push:
branches: ["main"]
tags: ["v*.*.*"]
workflow_call:
inputs:
version:
description: 'Version tag (e.g., v4.10.5)'
required: false
type: string

env:
# Use docker.io for Docker Hub if empty
Expand DownExpand Up@@ -40,6 +46,7 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v4
with:
ref: ${{ inputs.version || github.ref_name }}
submodules: "true"

# Extract metadata (tags, labels) for Docker
Expand DownExpand Up@@ -77,8 +84,6 @@ jobs:
cache-to: type=gha,mode=max,scope=${{ env.PLATFORM_PAIR }}
platforms: ${{ matrix.platform }}
outputs: type=image,name=${{ env.REGISTRY_IMAGE }},push-by-digest=true,name-canonical=true,push=true,annotation.org.opencontainers.image.description=Blazingly fast code search
build-args: |
NEXT_PUBLIC_SOURCEBOT_VERSION=${{ github.ref_name }}

- name: Export digest
run: |
Expand Down
99 changes: 80 additions & 19 deletions .github/workflows/release-sourcebot.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -3,35 +3,82 @@ name: Release Sourcebot
on:
workflow_dispatch:
inputs:
version:
description: "Version to release (e.g., 4.10.5)"
bump_type:
description: "Type of version bump to apply"
required: true
type: string
type: choice
options:
- patch
- minor
- major

concurrency:
group: release-sourcebot
cancel-in-progress: false

jobs:
release:
runs-on: ubuntu-latest
permissions:
contents: write
outputs:
version: ${{ steps.calculate_version.outputs.version }}

steps:
- name: Validate version format
run: |
VERSION="${{ inputs.version }}"
if ! [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9._-]+)?(\+[a-zA-Z0-9._-]+)?$ ]]; then
echo "Error: Version must follow semantic versioning format (X.Y.Z)"
exit 1
fi

- name: Checkout repository
uses: actions/checkout@v4
with:
ref: main
fetch-depth: 0

- name: Calculate new version
id: calculate_version
run: |
# Extract current version from CHANGELOG.md
CURRENT_VERSION=$(grep -oP '## \[\K[0-9]+\.[0-9]+\.[0-9]+' CHANGELOG.md | head -n 1)

if [ -z "$CURRENT_VERSION" ]; then
echo "Error: Could not extract current version from CHANGELOG.md"
exit 1
fi

echo "Current version: $CURRENT_VERSION"

# Parse version components
IFS='.' read -r MAJOR MINOR PATCH <<< "$CURRENT_VERSION"

# Apply bump based on input
BUMP_TYPE="${{ inputs.bump_type }}"
case "$BUMP_TYPE" in
major)
MAJOR=$((MAJOR + 1))
MINOR=0
PATCH=0
;;
minor)
MINOR=$((MINOR + 1))
PATCH=0
;;
patch)
PATCH=$((PATCH + 1))
;;
*)
echo "Error: Invalid bump type: $BUMP_TYPE"
exit 1
;;
esac

NEW_VERSION="$MAJOR.$MINOR.$PATCH"
echo "New version: $NEW_VERSION"

# Export to GITHUB_ENV for use in subsequent steps within this job
echo "VERSION=$NEW_VERSION" >> $GITHUB_ENV

# Export to GITHUB_OUTPUT for use in other jobs
echo "version=$NEW_VERSION" >> $GITHUB_OUTPUT

- name: Check if version already exists
run: |
VERSION="${{ inputs.version }}"
if grep -q "## \[$VERSION\]" CHANGELOG.md; then
echo "Error: Version $VERSION already exists in CHANGELOG.md"
exit 1
Expand All@@ -41,9 +88,8 @@ jobs:
exit 1
fi

- name: Update CHANGELOG.md
- name: Update CHANGELOG.md and version.ts
run: |
VERSION="${{ inputs.version }}"
DATE=$(date +%Y-%m-%d)

# Insert the new version header after the [Unreleased] line
Expand All@@ -54,20 +100,26 @@ jobs:
echo "Updated CHANGELOG.md with version $VERSION"
cat CHANGELOG.md | head -n 15

# Update version.ts
cat > packages/shared/src/version.ts << EOF
// This file is auto-generated by .github/workflows/release-sourcebot.yml
export const SOURCEBOT_VERSION = "v$VERSION";
EOF
echo "Updated version.ts with version v$VERSION"
cat packages/shared/src/version.ts
Comment thread
brendan-kellam marked this conversation as resolved.

- name: Configure git
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"

- name: Commit CHANGELOG
- name: Commit changes
run: |
VERSION="${{ inputs.version }}"
git add CHANGELOG.md
git add CHANGELOG.md packages/shared/src/version.ts
git commit -m "Release v$VERSION"

- name: Create annotated tag
run: |
VERSION="${{ inputs.version }}"
git tag -a "v$VERSION" -m "sourcebot v$VERSION"

- name: Push changes
Expand All@@ -79,8 +131,17 @@ jobs:
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
VERSION="${{ inputs.version }}"
gh release create "v$VERSION" \
--verify-tag \
--generate-notes \
--latest

publish:
needs: release
uses: ./.github/workflows/ghcr-publish.yml
with:
version: v${{ needs.release.outputs.version }}
permissions:
contents: read
packages: write
id-token: write
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Changed
- Bake Sourcebot version into code rather than relying on build arg. [#680](https://github.com/sourcebot-dev/sourcebot/pull/680)

## [4.10.4] - 2025-12-18

### Fixed
Expand Down
20 changes: 7 additions & 13 deletions Dockerfile
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,7 +8,6 @@
# in the webapp.
# @see: https://docs.docker.com/build/building/variables/#scoping

ARG NEXT_PUBLIC_SOURCEBOT_VERSION
ARG NEXT_PUBLIC_SENTRY_ENVIRONMENT
ARG NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT
ARG NEXT_PUBLIC_SENTRY_WEBAPP_DSN
Expand DownExpand Up@@ -51,8 +50,6 @@ RUN yarn workspace @sourcebot/query-language install
FROM node-alpine AS web-builder
ENV SKIP_ENV_VALIDATION=1
# -----------
ARG NEXT_PUBLIC_SOURCEBOT_VERSION
ENV NEXT_PUBLIC_SOURCEBOT_VERSION=$NEXT_PUBLIC_SOURCEBOT_VERSION
ARG NEXT_PUBLIC_SENTRY_ENVIRONMENT
ENV NEXT_PUBLIC_SENTRY_ENVIRONMENT=$NEXT_PUBLIC_SENTRY_ENVIRONMENT
ARG NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT
Expand All@@ -72,7 +69,8 @@ ARG SENTRY_ORG
ENV SENTRY_ORG=$SENTRY_ORG
ARG SENTRY_WEBAPP_PROJECT
ENV SENTRY_WEBAPP_PROJECT=$SENTRY_WEBAPP_PROJECT
ENV SENTRY_RELEASE=$NEXT_PUBLIC_SOURCEBOT_VERSION
ARG SENTRY_RELEASE
ENV SENTRY_RELEASE=$SENTRY_RELEASE
# SMUAT = Source Map Upload Auth Token
ARG SENTRY_SMUAT
ENV SENTRY_SMUAT=$SENTRY_SMUAT
Expand DownExpand Up@@ -102,8 +100,6 @@ ENV SKIP_ENV_VALIDATION=0
FROM node-alpine AS backend-builder
ENV SKIP_ENV_VALIDATION=1
# -----------
ARG NEXT_PUBLIC_SOURCEBOT_VERSION
ENV NEXT_PUBLIC_SOURCEBOT_VERSION=$NEXT_PUBLIC_SOURCEBOT_VERSION

# To upload source maps to Sentry, we need to set the following build-time args.
# It's important that we don't set these for oss builds, otherwise the Sentry
Expand All@@ -115,6 +111,8 @@ ENV SENTRY_BACKEND_PROJECT=$SENTRY_BACKEND_PROJECT
# SMUAT = Source Map Upload Auth Token
ARG SENTRY_SMUAT
ENV SENTRY_SMUAT=$SENTRY_SMUAT
ARG SENTRY_RELEASE
ENV SENTRY_RELEASE=$SENTRY_RELEASE
# -----------

WORKDIR /app
Expand All@@ -132,12 +130,12 @@ RUN yarn workspace @sourcebot/backend install
RUN yarn workspace @sourcebot/backend build

# Upload source maps to Sentry if we have the necessary build-time args.
RUN if [ -n "$SENTRY_SMUAT" ] && [ -n "$SENTRY_ORG" ] && [ -n "$SENTRY_BACKEND_PROJECT" ] && [ -n "$NEXT_PUBLIC_SOURCEBOT_VERSION" ]; then \
RUN if [ -n "$SENTRY_SMUAT" ] && [ -n "$SENTRY_ORG" ] && [ -n "$SENTRY_BACKEND_PROJECT" ] && [ -n "$SENTRY_RELEASE" ]; then \
apk add --no-cache curl; \
curl -sL https://sentry.io/get-cli/ | sh; \
sentry-cli login --auth-token $SENTRY_SMUAT; \
sentry-cli sourcemaps inject --org $SENTRY_ORG --project $SENTRY_BACKEND_PROJECT --release $NEXT_PUBLIC_SOURCEBOT_VERSION ./packages/backend/dist; \
sentry-cli sourcemaps upload --org $SENTRY_ORG --project $SENTRY_BACKEND_PROJECT --release $NEXT_PUBLIC_SOURCEBOT_VERSION ./packages/backend/dist; \
sentry-cli sourcemaps inject --org $SENTRY_ORG --project $SENTRY_BACKEND_PROJECT --release $SENTRY_RELEASE ./packages/backend/dist; \
sentry-cli sourcemaps upload --org $SENTRY_ORG --project $SENTRY_BACKEND_PROJECT --release $SENTRY_RELEASE ./packages/backend/dist; \
fi

ENV SKIP_ENV_VALIDATION=0
Expand All@@ -146,8 +144,6 @@ ENV SKIP_ENV_VALIDATION=0
# ------ Runner ------
FROM node-alpine AS runner
# -----------
ARG NEXT_PUBLIC_SOURCEBOT_VERSION
ENV NEXT_PUBLIC_SOURCEBOT_VERSION=$NEXT_PUBLIC_SOURCEBOT_VERSION
ARG NEXT_PUBLIC_SENTRY_ENVIRONMENT
ENV NEXT_PUBLIC_SENTRY_ENVIRONMENT=$NEXT_PUBLIC_SENTRY_ENVIRONMENT
ARG NEXT_PUBLIC_SENTRY_WEBAPP_DSN
Expand All@@ -160,8 +156,6 @@ ARG NEXT_PUBLIC_LANGFUSE_BASE_URL
ENV NEXT_PUBLIC_LANGFUSE_BASE_URL=$NEXT_PUBLIC_LANGFUSE_BASE_URL
# -----------

RUN echo "Sourcebot Version: $NEXT_PUBLIC_SOURCEBOT_VERSION"

WORKDIR /app
ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1
Expand Down
24 changes: 18 additions & 6 deletions entrypoint.sh
Original file line numberDiff line numberDiff line change
Expand Up@@ -63,8 +63,20 @@ else
export REDIS_EMBEDDED="false"
fi

# Extract version from version.ts
VERSION_FILE="/app/packages/shared/src/version.ts"
if [ -f "$VERSION_FILE" ]; then
SOURCEBOT_VERSION=$(grep -o '"v[^"]*"' "$VERSION_FILE" | tr -d '"')
# Validate extraction succeeded
if [ -z "$SOURCEBOT_VERSION" ]; then
echo -e "\e[33m[Warning] Failed to extract version from $VERSION_FILE. Setting to 'unknown'.\e[0m" >&2
SOURCEBOT_VERSION="unknown"
fi
else
SOURCEBOT_VERSION="unknown"
fi
Comment thread
brendan-kellam marked this conversation as resolved.

echo -e "\e[34m[Info] Sourcebot version: $NEXT_PUBLIC_SOURCEBOT_VERSION\e[0m"
echo -e "\e[34m[Info] Sourcebot version: $SOURCEBOT_VERSION\e[0m"

if [ -n "$SOURCEBOT_TELEMETRY_DISABLED" ]; then
# Validate that SOURCEBOT_TELEMETRY_DISABLED is either "true" or "false"
Expand DownExpand Up@@ -157,7 +169,7 @@ if [ ! -f "$FIRST_RUN_FILE" ]; then
"event": "install",
"distinct_id": "'"$SOURCEBOT_INSTALL_ID"'",
"properties": {
"sourcebot_version": "'"$NEXT_PUBLIC_SOURCEBOT_VERSION"'"
"sourcebot_version": "'"$SOURCEBOT_VERSION"'"
}
}' https://us.i.posthog.com/capture/ ) then
echo -e "\e[33m[Warning] Failed to send install event.\e[0m"
Expand All@@ -168,8 +180,8 @@ else
PREVIOUS_VERSION=$(cat "$FIRST_RUN_FILE" | jq -r '.version')

# If the version has changed, we assume an upgrade has occurred.
if [ "$PREVIOUS_VERSION" != "$NEXT_PUBLIC_SOURCEBOT_VERSION" ]; then
echo -e "\e[34m[Info] Upgraded from version $PREVIOUS_VERSION to $NEXT_PUBLIC_SOURCEBOT_VERSION\e[0m"
if [ "$PREVIOUS_VERSION" != "$SOURCEBOT_VERSION" ]; then
echo -e "\e[34m[Info] Upgraded from version $PREVIOUS_VERSION to $SOURCEBOT_VERSION\e[0m"

if [ "$SOURCEBOT_TELEMETRY_DISABLED" = "false" ]; then
if ! ( curl -L --output /dev/null --silent --fail --header "Content-Type: application/json" -d '{
Expand All@@ -178,7 +190,7 @@ else
"distinct_id": "'"$SOURCEBOT_INSTALL_ID"'",
"properties": {
"from_version": "'"$PREVIOUS_VERSION"'",
"to_version": "'"$NEXT_PUBLIC_SOURCEBOT_VERSION"'"
"to_version": "'"$SOURCEBOT_VERSION"'"
}
}' https://us.i.posthog.com/capture/ ) then
echo -e "\e[33m[Warning] Failed to send upgrade event.\e[0m"
Expand All@@ -187,7 +199,7 @@ else
fi
fi

echo "{\"version\": \"$NEXT_PUBLIC_SOURCEBOT_VERSION\", \"install_id\": \"$SOURCEBOT_INSTALL_ID\"}" > "$FIRST_RUN_FILE"
echo "{\"version\": \"$SOURCEBOT_VERSION\", \"install_id\": \"$SOURCEBOT_INSTALL_ID\"}" > "$FIRST_RUN_FILE"

# Start the database and wait for it to be ready before starting any other service
if [ "$DATABASE_EMBEDDED" = "true" ]; then
Expand Down
4 changes: 2 additions & 2 deletions packages/backend/src/instrument.ts
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
import * as Sentry from "@sentry/node";
import { createLogger } from "@sourcebot/shared";
import { createLogger, SOURCEBOT_VERSION } from "@sourcebot/shared";
import { env } from "@sourcebot/shared/client";

const logger = createLogger('instrument');

if (!!env.NEXT_PUBLIC_SENTRY_BACKEND_DSN && !!env.NEXT_PUBLIC_SENTRY_ENVIRONMENT) {
Sentry.init({
dsn: env.NEXT_PUBLIC_SENTRY_BACKEND_DSN,
release: env.NEXT_PUBLIC_SOURCEBOT_VERSION,
release: SOURCEBOT_VERSION,
environment: env.NEXT_PUBLIC_SENTRY_ENVIRONMENT,
});
} else {
Expand Down
5 changes: 2 additions & 3 deletions packages/backend/src/posthog.ts
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
import { env as clientEnv } from "@sourcebot/shared/client";
import { env } from "@sourcebot/shared";
import { env, SOURCEBOT_VERSION } from "@sourcebot/shared";
import { PostHog } from 'posthog-node';
import { PosthogEvent, PosthogEventMap } from './posthogEvents.js';

Expand All@@ -24,7 +23,7 @@ export function captureEvent<E extends PosthogEvent>(event: E, properties: Posth
event: event,
properties: {
...properties,
sourcebot_version: clientEnv.NEXT_PUBLIC_SOURCEBOT_VERSION,
sourcebot_version: SOURCEBOT_VERSION,
},
});
}
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions .env.development
Original file line numberDiff line numberDiff line change
Expand Up@@ -77,9 +77,6 @@ SOURCEBOT_TELEMETRY_DISABLED=true # Disables telemetry collection
# Controls the number of concurrent indexing jobs that can run at once
# INDEX_CONCURRENCY_MULTIPLE=

# Controls the version of the web app
# NEXT_PUBLIC_SOURCEBOT_VERSION=

# CONFIG_MAX_REPOS_NO_TOKEN=
NODE_ENV=development
# SOURCEBOT_TENANCY_MODE=single
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/_gcp-deploy.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -54,7 +54,6 @@ jobs:
${{ env.IMAGE_PATH }}:${{ github.sha }}
${{ env.IMAGE_PATH }}:latest
build-args: |
NEXT_PUBLIC_SOURCEBOT_VERSION=${{ github.ref_name }}
NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT=${{ vars.NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT }}
NEXT_PUBLIC_SENTRY_ENVIRONMENT=${{ vars.NEXT_PUBLIC_SENTRY_ENVIRONMENT }}
NEXT_PUBLIC_SENTRY_WEBAPP_DSN=${{ vars.NEXT_PUBLIC_SENTRY_WEBAPP_DSN }}
Expand All@@ -65,6 +64,7 @@ jobs:
SENTRY_ORG=${{ vars.SENTRY_ORG }}
SENTRY_WEBAPP_PROJECT=${{ vars.SENTRY_WEBAPP_PROJECT }}
SENTRY_BACKEND_PROJECT=${{ vars.SENTRY_BACKEND_PROJECT }}
SENTRY_RELEASE=${{ github.ref_name }}


- name: Deploy to GCP
Expand Down
9 changes: 7 additions & 2 deletions .github/workflows/ghcr-publish.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -7,6 +7,12 @@ on:
push:
branches: ["main"]
tags: ["v*.*.*"]
workflow_call:
inputs:
version:
description: 'Version tag (e.g., v4.10.5)'
required: false
type: string

env:
# Use docker.io for Docker Hub if empty
Expand DownExpand Up@@ -40,6 +46,7 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v4
with:
ref: ${{ inputs.version || github.ref_name }}
submodules: "true"

# Extract metadata (tags, labels) for Docker
Expand DownExpand Up@@ -77,8 +84,6 @@ jobs:
cache-to: type=gha,mode=max,scope=${{ env.PLATFORM_PAIR }}
platforms: ${{ matrix.platform }}
outputs: type=image,name=${{ env.REGISTRY_IMAGE }},push-by-digest=true,name-canonical=true,push=true,annotation.org.opencontainers.image.description=Blazingly fast code search
build-args: |
NEXT_PUBLIC_SOURCEBOT_VERSION=${{ github.ref_name }}

- name: Export digest
run: |
Expand Down
99 changes: 80 additions & 19 deletions .github/workflows/release-sourcebot.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -3,35 +3,82 @@ name: Release Sourcebot
on:
workflow_dispatch:
inputs:
version:
description: "Version to release (e.g., 4.10.5)"
bump_type:
description: "Type of version bump to apply"
required: true
type: string
type: choice
options:
- patch
- minor
- major

concurrency:
group: release-sourcebot
cancel-in-progress: false

jobs:
release:
runs-on: ubuntu-latest
permissions:
contents: write
outputs:
version: ${{ steps.calculate_version.outputs.version }}

steps:
- name: Validate version format
run: |
VERSION="${{ inputs.version }}"
if ! [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9._-]+)?(\+[a-zA-Z0-9._-]+)?$ ]]; then
echo "Error: Version must follow semantic versioning format (X.Y.Z)"
exit 1
fi

- name: Checkout repository
uses: actions/checkout@v4
with:
ref: main
fetch-depth: 0

- name: Calculate new version
id: calculate_version
run: |
# Extract current version from CHANGELOG.md
CURRENT_VERSION=$(grep -oP '## \[\K[0-9]+\.[0-9]+\.[0-9]+' CHANGELOG.md | head -n 1)

if [ -z "$CURRENT_VERSION" ]; then
echo "Error: Could not extract current version from CHANGELOG.md"
exit 1
fi

echo "Current version: $CURRENT_VERSION"

# Parse version components
IFS='.' read -r MAJOR MINOR PATCH <<< "$CURRENT_VERSION"

# Apply bump based on input
BUMP_TYPE="${{ inputs.bump_type }}"
case "$BUMP_TYPE" in
major)
MAJOR=$((MAJOR + 1))
MINOR=0
PATCH=0
;;
minor)
MINOR=$((MINOR + 1))
PATCH=0
;;
patch)
PATCH=$((PATCH + 1))
;;
*)
echo "Error: Invalid bump type: $BUMP_TYPE"
exit 1
;;
esac

NEW_VERSION="$MAJOR.$MINOR.$PATCH"
echo "New version: $NEW_VERSION"

# Export to GITHUB_ENV for use in subsequent steps within this job
echo "VERSION=$NEW_VERSION" >> $GITHUB_ENV

# Export to GITHUB_OUTPUT for use in other jobs
echo "version=$NEW_VERSION" >> $GITHUB_OUTPUT

- name: Check if version already exists
run: |
VERSION="${{ inputs.version }}"
if grep -q "## \[$VERSION\]" CHANGELOG.md; then
echo "Error: Version $VERSION already exists in CHANGELOG.md"
exit 1
Expand All@@ -41,9 +88,8 @@ jobs:
exit 1
fi

- name: Update CHANGELOG.md
- name: Update CHANGELOG.md and version.ts
run: |
VERSION="${{ inputs.version }}"
DATE=$(date +%Y-%m-%d)

# Insert the new version header after the [Unreleased] line
Expand All@@ -54,20 +100,26 @@ jobs:
echo "Updated CHANGELOG.md with version $VERSION"
cat CHANGELOG.md | head -n 15

# Update version.ts
cat > packages/shared/src/version.ts << EOF
// This file is auto-generated by .github/workflows/release-sourcebot.yml
export const SOURCEBOT_VERSION = "v$VERSION";
EOF
echo "Updated version.ts with version v$VERSION"
cat packages/shared/src/version.ts
Comment thread
brendan-kellam marked this conversation as resolved.

- name: Configure git
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"

- name: Commit CHANGELOG
- name: Commit changes
run: |
VERSION="${{ inputs.version }}"
git add CHANGELOG.md
git add CHANGELOG.md packages/shared/src/version.ts
git commit -m "Release v$VERSION"

- name: Create annotated tag
run: |
VERSION="${{ inputs.version }}"
git tag -a "v$VERSION" -m "sourcebot v$VERSION"

- name: Push changes
Expand All@@ -79,8 +131,17 @@ jobs:
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
VERSION="${{ inputs.version }}"
gh release create "v$VERSION" \
--verify-tag \
--generate-notes \
--latest

publish:
needs: release
uses: ./.github/workflows/ghcr-publish.yml
with:
version: v${{ needs.release.outputs.version }}
permissions:
contents: read
packages: write
id-token: write
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Changed
- Bake Sourcebot version into code rather than relying on build arg. [#680](https://github.com/sourcebot-dev/sourcebot/pull/680)

## [4.10.4] - 2025-12-18

### Fixed
Expand Down
20 changes: 7 additions & 13 deletions Dockerfile
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,7 +8,6 @@
# in the webapp.
# @see: https://docs.docker.com/build/building/variables/#scoping

ARG NEXT_PUBLIC_SOURCEBOT_VERSION
ARG NEXT_PUBLIC_SENTRY_ENVIRONMENT
ARG NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT
ARG NEXT_PUBLIC_SENTRY_WEBAPP_DSN
Expand DownExpand Up@@ -51,8 +50,6 @@ RUN yarn workspace @sourcebot/query-language install
FROM node-alpine AS web-builder
ENV SKIP_ENV_VALIDATION=1
# -----------
ARG NEXT_PUBLIC_SOURCEBOT_VERSION
ENV NEXT_PUBLIC_SOURCEBOT_VERSION=$NEXT_PUBLIC_SOURCEBOT_VERSION
ARG NEXT_PUBLIC_SENTRY_ENVIRONMENT
ENV NEXT_PUBLIC_SENTRY_ENVIRONMENT=$NEXT_PUBLIC_SENTRY_ENVIRONMENT
ARG NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT
Expand All@@ -72,7 +69,8 @@ ARG SENTRY_ORG
ENV SENTRY_ORG=$SENTRY_ORG
ARG SENTRY_WEBAPP_PROJECT
ENV SENTRY_WEBAPP_PROJECT=$SENTRY_WEBAPP_PROJECT
ENV SENTRY_RELEASE=$NEXT_PUBLIC_SOURCEBOT_VERSION
ARG SENTRY_RELEASE
ENV SENTRY_RELEASE=$SENTRY_RELEASE
# SMUAT = Source Map Upload Auth Token
ARG SENTRY_SMUAT
ENV SENTRY_SMUAT=$SENTRY_SMUAT
Expand DownExpand Up@@ -102,8 +100,6 @@ ENV SKIP_ENV_VALIDATION=0
FROM node-alpine AS backend-builder
ENV SKIP_ENV_VALIDATION=1
# -----------
ARG NEXT_PUBLIC_SOURCEBOT_VERSION
ENV NEXT_PUBLIC_SOURCEBOT_VERSION=$NEXT_PUBLIC_SOURCEBOT_VERSION

# To upload source maps to Sentry, we need to set the following build-time args.
# It's important that we don't set these for oss builds, otherwise the Sentry
Expand All@@ -115,6 +111,8 @@ ENV SENTRY_BACKEND_PROJECT=$SENTRY_BACKEND_PROJECT
# SMUAT = Source Map Upload Auth Token
ARG SENTRY_SMUAT
ENV SENTRY_SMUAT=$SENTRY_SMUAT
ARG SENTRY_RELEASE
ENV SENTRY_RELEASE=$SENTRY_RELEASE
# -----------

WORKDIR /app
Expand All@@ -132,12 +130,12 @@ RUN yarn workspace @sourcebot/backend install
RUN yarn workspace @sourcebot/backend build

# Upload source maps to Sentry if we have the necessary build-time args.
RUN if [ -n "$SENTRY_SMUAT" ] && [ -n "$SENTRY_ORG" ] && [ -n "$SENTRY_BACKEND_PROJECT" ] && [ -n "$NEXT_PUBLIC_SOURCEBOT_VERSION" ]; then \
RUN if [ -n "$SENTRY_SMUAT" ] && [ -n "$SENTRY_ORG" ] && [ -n "$SENTRY_BACKEND_PROJECT" ] && [ -n "$SENTRY_RELEASE" ]; then \
apk add --no-cache curl; \
curl -sL https://sentry.io/get-cli/ | sh; \
sentry-cli login --auth-token $SENTRY_SMUAT; \
sentry-cli sourcemaps inject --org $SENTRY_ORG --project $SENTRY_BACKEND_PROJECT --release $NEXT_PUBLIC_SOURCEBOT_VERSION ./packages/backend/dist; \
sentry-cli sourcemaps upload --org $SENTRY_ORG --project $SENTRY_BACKEND_PROJECT --release $NEXT_PUBLIC_SOURCEBOT_VERSION ./packages/backend/dist; \
sentry-cli sourcemaps inject --org $SENTRY_ORG --project $SENTRY_BACKEND_PROJECT --release $SENTRY_RELEASE ./packages/backend/dist; \
sentry-cli sourcemaps upload --org $SENTRY_ORG --project $SENTRY_BACKEND_PROJECT --release $SENTRY_RELEASE ./packages/backend/dist; \
fi

ENV SKIP_ENV_VALIDATION=0
Expand All@@ -146,8 +144,6 @@ ENV SKIP_ENV_VALIDATION=0
# ------ Runner ------
FROM node-alpine AS runner
# -----------
ARG NEXT_PUBLIC_SOURCEBOT_VERSION
ENV NEXT_PUBLIC_SOURCEBOT_VERSION=$NEXT_PUBLIC_SOURCEBOT_VERSION
ARG NEXT_PUBLIC_SENTRY_ENVIRONMENT
ENV NEXT_PUBLIC_SENTRY_ENVIRONMENT=$NEXT_PUBLIC_SENTRY_ENVIRONMENT
ARG NEXT_PUBLIC_SENTRY_WEBAPP_DSN
Expand All@@ -160,8 +156,6 @@ ARG NEXT_PUBLIC_LANGFUSE_BASE_URL
ENV NEXT_PUBLIC_LANGFUSE_BASE_URL=$NEXT_PUBLIC_LANGFUSE_BASE_URL
# -----------

RUN echo "Sourcebot Version: $NEXT_PUBLIC_SOURCEBOT_VERSION"

WORKDIR /app
ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1
Expand Down
24 changes: 18 additions & 6 deletions entrypoint.sh
Original file line numberDiff line numberDiff line change
Expand Up@@ -63,8 +63,20 @@ else
export REDIS_EMBEDDED="false"
fi

# Extract version from version.ts
VERSION_FILE="/app/packages/shared/src/version.ts"
if [ -f "$VERSION_FILE" ]; then
SOURCEBOT_VERSION=$(grep -o '"v[^"]*"' "$VERSION_FILE" | tr -d '"')
# Validate extraction succeeded
if [ -z "$SOURCEBOT_VERSION" ]; then
echo -e "\e[33m[Warning] Failed to extract version from $VERSION_FILE. Setting to 'unknown'.\e[0m" >&2
SOURCEBOT_VERSION="unknown"
fi
else
SOURCEBOT_VERSION="unknown"
fi
Comment thread
brendan-kellam marked this conversation as resolved.

echo -e "\e[34m[Info] Sourcebot version: $NEXT_PUBLIC_SOURCEBOT_VERSION\e[0m"
echo -e "\e[34m[Info] Sourcebot version: $SOURCEBOT_VERSION\e[0m"

if [ -n "$SOURCEBOT_TELEMETRY_DISABLED" ]; then
# Validate that SOURCEBOT_TELEMETRY_DISABLED is either "true" or "false"
Expand DownExpand Up@@ -157,7 +169,7 @@ if [ ! -f "$FIRST_RUN_FILE" ]; then
"event": "install",
"distinct_id": "'"$SOURCEBOT_INSTALL_ID"'",
"properties": {
"sourcebot_version": "'"$NEXT_PUBLIC_SOURCEBOT_VERSION"'"
"sourcebot_version": "'"$SOURCEBOT_VERSION"'"
}
}' https://us.i.posthog.com/capture/ ) then
echo -e "\e[33m[Warning] Failed to send install event.\e[0m"
Expand All@@ -168,8 +180,8 @@ else
PREVIOUS_VERSION=$(cat "$FIRST_RUN_FILE" | jq -r '.version')

# If the version has changed, we assume an upgrade has occurred.
if [ "$PREVIOUS_VERSION" != "$NEXT_PUBLIC_SOURCEBOT_VERSION" ]; then
echo -e "\e[34m[Info] Upgraded from version $PREVIOUS_VERSION to $NEXT_PUBLIC_SOURCEBOT_VERSION\e[0m"
if [ "$PREVIOUS_VERSION" != "$SOURCEBOT_VERSION" ]; then
echo -e "\e[34m[Info] Upgraded from version $PREVIOUS_VERSION to $SOURCEBOT_VERSION\e[0m"

if [ "$SOURCEBOT_TELEMETRY_DISABLED" = "false" ]; then
if ! ( curl -L --output /dev/null --silent --fail --header "Content-Type: application/json" -d '{
Expand All@@ -178,7 +190,7 @@ else
"distinct_id": "'"$SOURCEBOT_INSTALL_ID"'",
"properties": {
"from_version": "'"$PREVIOUS_VERSION"'",
"to_version": "'"$NEXT_PUBLIC_SOURCEBOT_VERSION"'"
"to_version": "'"$SOURCEBOT_VERSION"'"
}
}' https://us.i.posthog.com/capture/ ) then
echo -e "\e[33m[Warning] Failed to send upgrade event.\e[0m"
Expand All@@ -187,7 +199,7 @@ else
fi
fi

echo "{\"version\": \"$NEXT_PUBLIC_SOURCEBOT_VERSION\", \"install_id\": \"$SOURCEBOT_INSTALL_ID\"}" > "$FIRST_RUN_FILE"
echo "{\"version\": \"$SOURCEBOT_VERSION\", \"install_id\": \"$SOURCEBOT_INSTALL_ID\"}" > "$FIRST_RUN_FILE"

# Start the database and wait for it to be ready before starting any other service
if [ "$DATABASE_EMBEDDED" = "true" ]; then
Expand Down
4 changes: 2 additions & 2 deletions packages/backend/src/instrument.ts
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
import * as Sentry from "@sentry/node";
import { createLogger } from "@sourcebot/shared";
import { createLogger, SOURCEBOT_VERSION } from "@sourcebot/shared";
import { env } from "@sourcebot/shared/client";

const logger = createLogger('instrument');

if (!!env.NEXT_PUBLIC_SENTRY_BACKEND_DSN && !!env.NEXT_PUBLIC_SENTRY_ENVIRONMENT) {
Sentry.init({
dsn: env.NEXT_PUBLIC_SENTRY_BACKEND_DSN,
release: env.NEXT_PUBLIC_SOURCEBOT_VERSION,
release: SOURCEBOT_VERSION,
environment: env.NEXT_PUBLIC_SENTRY_ENVIRONMENT,
});
} else {
Expand Down
5 changes: 2 additions & 3 deletions packages/backend/src/posthog.ts
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
import { env as clientEnv } from "@sourcebot/shared/client";
import { env } from "@sourcebot/shared";
import { env, SOURCEBOT_VERSION } from "@sourcebot/shared";
import { PostHog } from 'posthog-node';
import { PosthogEvent, PosthogEventMap } from './posthogEvents.js';

Expand All@@ -24,7 +23,7 @@ export function captureEvent<E extends PosthogEvent>(event: E, properties: Posth
event: event,
properties: {
...properties,
sourcebot_version: clientEnv.NEXT_PUBLIC_SOURCEBOT_VERSION,
sourcebot_version: SOURCEBOT_VERSION,
},
});
}
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions .env.development
Original file line numberDiff line numberDiff line change
Expand Up@@ -77,9 +77,6 @@ SOURCEBOT_TELEMETRY_DISABLED=true # Disables telemetry collection
# Controls the number of concurrent indexing jobs that can run at once
# INDEX_CONCURRENCY_MULTIPLE=

# Controls the version of the web app
# NEXT_PUBLIC_SOURCEBOT_VERSION=

# CONFIG_MAX_REPOS_NO_TOKEN=
NODE_ENV=development
# SOURCEBOT_TENANCY_MODE=single
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/_gcp-deploy.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -54,7 +54,6 @@ jobs:
${{ env.IMAGE_PATH }}:${{ github.sha }}
${{ env.IMAGE_PATH }}:latest
build-args: |
NEXT_PUBLIC_SOURCEBOT_VERSION=${{ github.ref_name }}
NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT=${{ vars.NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT }}
NEXT_PUBLIC_SENTRY_ENVIRONMENT=${{ vars.NEXT_PUBLIC_SENTRY_ENVIRONMENT }}
NEXT_PUBLIC_SENTRY_WEBAPP_DSN=${{ vars.NEXT_PUBLIC_SENTRY_WEBAPP_DSN }}
Expand All@@ -65,6 +64,7 @@ jobs:
SENTRY_ORG=${{ vars.SENTRY_ORG }}
SENTRY_WEBAPP_PROJECT=${{ vars.SENTRY_WEBAPP_PROJECT }}
SENTRY_BACKEND_PROJECT=${{ vars.SENTRY_BACKEND_PROJECT }}
SENTRY_RELEASE=${{ github.ref_name }}


- name: Deploy to GCP
Expand Down
9 changes: 7 additions & 2 deletions .github/workflows/ghcr-publish.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -7,6 +7,12 @@ on:
push:
branches: ["main"]
tags: ["v*.*.*"]
workflow_call:
inputs:
version:
description: 'Version tag (e.g., v4.10.5)'
required: false
type: string

env:
# Use docker.io for Docker Hub if empty
Expand DownExpand Up@@ -40,6 +46,7 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v4
with:
ref: ${{ inputs.version || github.ref_name }}
submodules: "true"

# Extract metadata (tags, labels) for Docker
Expand DownExpand Up@@ -77,8 +84,6 @@ jobs:
cache-to: type=gha,mode=max,scope=${{ env.PLATFORM_PAIR }}
platforms: ${{ matrix.platform }}
outputs: type=image,name=${{ env.REGISTRY_IMAGE }},push-by-digest=true,name-canonical=true,push=true,annotation.org.opencontainers.image.description=Blazingly fast code search
build-args: |
NEXT_PUBLIC_SOURCEBOT_VERSION=${{ github.ref_name }}

- name: Export digest
run: |
Expand Down
99 changes: 80 additions & 19 deletions .github/workflows/release-sourcebot.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -3,35 +3,82 @@ name: Release Sourcebot
on:
workflow_dispatch:
inputs:
version:
description: "Version to release (e.g., 4.10.5)"
bump_type:
description: "Type of version bump to apply"
required: true
type: string
type: choice
options:
- patch
- minor
- major

concurrency:
group: release-sourcebot
cancel-in-progress: false

jobs:
release:
runs-on: ubuntu-latest
permissions:
contents: write
outputs:
version: ${{ steps.calculate_version.outputs.version }}

steps:
- name: Validate version format
run: |
VERSION="${{ inputs.version }}"
if ! [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9._-]+)?(\+[a-zA-Z0-9._-]+)?$ ]]; then
echo "Error: Version must follow semantic versioning format (X.Y.Z)"
exit 1
fi

- name: Checkout repository
uses: actions/checkout@v4
with:
ref: main
fetch-depth: 0

- name: Calculate new version
id: calculate_version
run: |
# Extract current version from CHANGELOG.md
CURRENT_VERSION=$(grep -oP '## \[\K[0-9]+\.[0-9]+\.[0-9]+' CHANGELOG.md | head -n 1)

if [ -z "$CURRENT_VERSION" ]; then
echo "Error: Could not extract current version from CHANGELOG.md"
exit 1
fi

echo "Current version: $CURRENT_VERSION"

# Parse version components
IFS='.' read -r MAJOR MINOR PATCH <<< "$CURRENT_VERSION"

# Apply bump based on input
BUMP_TYPE="${{ inputs.bump_type }}"
case "$BUMP_TYPE" in
major)
MAJOR=$((MAJOR + 1))
MINOR=0
PATCH=0
;;
minor)
MINOR=$((MINOR + 1))
PATCH=0
;;
patch)
PATCH=$((PATCH + 1))
;;
*)
echo "Error: Invalid bump type: $BUMP_TYPE"
exit 1
;;
esac

NEW_VERSION="$MAJOR.$MINOR.$PATCH"
echo "New version: $NEW_VERSION"

# Export to GITHUB_ENV for use in subsequent steps within this job
echo "VERSION=$NEW_VERSION" >> $GITHUB_ENV

# Export to GITHUB_OUTPUT for use in other jobs
echo "version=$NEW_VERSION" >> $GITHUB_OUTPUT

- name: Check if version already exists
run: |
VERSION="${{ inputs.version }}"
if grep -q "## \[$VERSION\]" CHANGELOG.md; then
echo "Error: Version $VERSION already exists in CHANGELOG.md"
exit 1
Expand All@@ -41,9 +88,8 @@ jobs:
exit 1
fi

- name: Update CHANGELOG.md
- name: Update CHANGELOG.md and version.ts
run: |
VERSION="${{ inputs.version }}"
DATE=$(date +%Y-%m-%d)

# Insert the new version header after the [Unreleased] line
Expand All@@ -54,20 +100,26 @@ jobs:
echo "Updated CHANGELOG.md with version $VERSION"
cat CHANGELOG.md | head -n 15

# Update version.ts
cat > packages/shared/src/version.ts << EOF
// This file is auto-generated by .github/workflows/release-sourcebot.yml
export const SOURCEBOT_VERSION = "v$VERSION";
EOF
echo "Updated version.ts with version v$VERSION"
cat packages/shared/src/version.ts
Comment thread
brendan-kellam marked this conversation as resolved.

- name: Configure git
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"

- name: Commit CHANGELOG
- name: Commit changes
run: |
VERSION="${{ inputs.version }}"
git add CHANGELOG.md
git add CHANGELOG.md packages/shared/src/version.ts
git commit -m "Release v$VERSION"

- name: Create annotated tag
run: |
VERSION="${{ inputs.version }}"
git tag -a "v$VERSION" -m "sourcebot v$VERSION"

- name: Push changes
Expand All@@ -79,8 +131,17 @@ jobs:
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
VERSION="${{ inputs.version }}"
gh release create "v$VERSION" \
--verify-tag \
--generate-notes \
--latest

publish:
needs: release
uses: ./.github/workflows/ghcr-publish.yml
with:
version: v${{ needs.release.outputs.version }}
permissions:
contents: read
packages: write
id-token: write
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Changed
- Bake Sourcebot version into code rather than relying on build arg. [#680](https://github.com/sourcebot-dev/sourcebot/pull/680)

## [4.10.4] - 2025-12-18

### Fixed
Expand Down
20 changes: 7 additions & 13 deletions Dockerfile
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,7 +8,6 @@
# in the webapp.
# @see: https://docs.docker.com/build/building/variables/#scoping

ARG NEXT_PUBLIC_SOURCEBOT_VERSION
ARG NEXT_PUBLIC_SENTRY_ENVIRONMENT
ARG NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT
ARG NEXT_PUBLIC_SENTRY_WEBAPP_DSN
Expand DownExpand Up@@ -51,8 +50,6 @@ RUN yarn workspace @sourcebot/query-language install
FROM node-alpine AS web-builder
ENV SKIP_ENV_VALIDATION=1
# -----------
ARG NEXT_PUBLIC_SOURCEBOT_VERSION
ENV NEXT_PUBLIC_SOURCEBOT_VERSION=$NEXT_PUBLIC_SOURCEBOT_VERSION
ARG NEXT_PUBLIC_SENTRY_ENVIRONMENT
ENV NEXT_PUBLIC_SENTRY_ENVIRONMENT=$NEXT_PUBLIC_SENTRY_ENVIRONMENT
ARG NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT
Expand All@@ -72,7 +69,8 @@ ARG SENTRY_ORG
ENV SENTRY_ORG=$SENTRY_ORG
ARG SENTRY_WEBAPP_PROJECT
ENV SENTRY_WEBAPP_PROJECT=$SENTRY_WEBAPP_PROJECT
ENV SENTRY_RELEASE=$NEXT_PUBLIC_SOURCEBOT_VERSION
ARG SENTRY_RELEASE
ENV SENTRY_RELEASE=$SENTRY_RELEASE
# SMUAT = Source Map Upload Auth Token
ARG SENTRY_SMUAT
ENV SENTRY_SMUAT=$SENTRY_SMUAT
Expand DownExpand Up@@ -102,8 +100,6 @@ ENV SKIP_ENV_VALIDATION=0
FROM node-alpine AS backend-builder
ENV SKIP_ENV_VALIDATION=1
# -----------
ARG NEXT_PUBLIC_SOURCEBOT_VERSION
ENV NEXT_PUBLIC_SOURCEBOT_VERSION=$NEXT_PUBLIC_SOURCEBOT_VERSION

# To upload source maps to Sentry, we need to set the following build-time args.
# It's important that we don't set these for oss builds, otherwise the Sentry
Expand All@@ -115,6 +111,8 @@ ENV SENTRY_BACKEND_PROJECT=$SENTRY_BACKEND_PROJECT
# SMUAT = Source Map Upload Auth Token
ARG SENTRY_SMUAT
ENV SENTRY_SMUAT=$SENTRY_SMUAT
ARG SENTRY_RELEASE
ENV SENTRY_RELEASE=$SENTRY_RELEASE
# -----------

WORKDIR /app
Expand All@@ -132,12 +130,12 @@ RUN yarn workspace @sourcebot/backend install
RUN yarn workspace @sourcebot/backend build

# Upload source maps to Sentry if we have the necessary build-time args.
RUN if [ -n "$SENTRY_SMUAT" ] && [ -n "$SENTRY_ORG" ] && [ -n "$SENTRY_BACKEND_PROJECT" ] && [ -n "$NEXT_PUBLIC_SOURCEBOT_VERSION" ]; then \
RUN if [ -n "$SENTRY_SMUAT" ] && [ -n "$SENTRY_ORG" ] && [ -n "$SENTRY_BACKEND_PROJECT" ] && [ -n "$SENTRY_RELEASE" ]; then \
apk add --no-cache curl; \
curl -sL https://sentry.io/get-cli/ | sh; \
sentry-cli login --auth-token $SENTRY_SMUAT; \
sentry-cli sourcemaps inject --org $SENTRY_ORG --project $SENTRY_BACKEND_PROJECT --release $NEXT_PUBLIC_SOURCEBOT_VERSION ./packages/backend/dist; \
sentry-cli sourcemaps upload --org $SENTRY_ORG --project $SENTRY_BACKEND_PROJECT --release $NEXT_PUBLIC_SOURCEBOT_VERSION ./packages/backend/dist; \
sentry-cli sourcemaps inject --org $SENTRY_ORG --project $SENTRY_BACKEND_PROJECT --release $SENTRY_RELEASE ./packages/backend/dist; \
sentry-cli sourcemaps upload --org $SENTRY_ORG --project $SENTRY_BACKEND_PROJECT --release $SENTRY_RELEASE ./packages/backend/dist; \
fi

ENV SKIP_ENV_VALIDATION=0
Expand All@@ -146,8 +144,6 @@ ENV SKIP_ENV_VALIDATION=0
# ------ Runner ------
FROM node-alpine AS runner
# -----------
ARG NEXT_PUBLIC_SOURCEBOT_VERSION
ENV NEXT_PUBLIC_SOURCEBOT_VERSION=$NEXT_PUBLIC_SOURCEBOT_VERSION
ARG NEXT_PUBLIC_SENTRY_ENVIRONMENT
ENV NEXT_PUBLIC_SENTRY_ENVIRONMENT=$NEXT_PUBLIC_SENTRY_ENVIRONMENT
ARG NEXT_PUBLIC_SENTRY_WEBAPP_DSN
Expand All@@ -160,8 +156,6 @@ ARG NEXT_PUBLIC_LANGFUSE_BASE_URL
ENV NEXT_PUBLIC_LANGFUSE_BASE_URL=$NEXT_PUBLIC_LANGFUSE_BASE_URL
# -----------

RUN echo "Sourcebot Version: $NEXT_PUBLIC_SOURCEBOT_VERSION"

WORKDIR /app
ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1
Expand Down
24 changes: 18 additions & 6 deletions entrypoint.sh
Original file line numberDiff line numberDiff line change
Expand Up@@ -63,8 +63,20 @@ else
export REDIS_EMBEDDED="false"
fi

# Extract version from version.ts
VERSION_FILE="/app/packages/shared/src/version.ts"
if [ -f "$VERSION_FILE" ]; then
SOURCEBOT_VERSION=$(grep -o '"v[^"]*"' "$VERSION_FILE" | tr -d '"')
# Validate extraction succeeded
if [ -z "$SOURCEBOT_VERSION" ]; then
echo -e "\e[33m[Warning] Failed to extract version from $VERSION_FILE. Setting to 'unknown'.\e[0m" >&2
SOURCEBOT_VERSION="unknown"
fi
else
SOURCEBOT_VERSION="unknown"
fi
Comment thread
brendan-kellam marked this conversation as resolved.

echo -e "\e[34m[Info] Sourcebot version: $NEXT_PUBLIC_SOURCEBOT_VERSION\e[0m"
echo -e "\e[34m[Info] Sourcebot version: $SOURCEBOT_VERSION\e[0m"

if [ -n "$SOURCEBOT_TELEMETRY_DISABLED" ]; then
# Validate that SOURCEBOT_TELEMETRY_DISABLED is either "true" or "false"
Expand DownExpand Up@@ -157,7 +169,7 @@ if [ ! -f "$FIRST_RUN_FILE" ]; then
"event": "install",
"distinct_id": "'"$SOURCEBOT_INSTALL_ID"'",
"properties": {
"sourcebot_version": "'"$NEXT_PUBLIC_SOURCEBOT_VERSION"'"
"sourcebot_version": "'"$SOURCEBOT_VERSION"'"
}
}' https://us.i.posthog.com/capture/ ) then
echo -e "\e[33m[Warning] Failed to send install event.\e[0m"
Expand All@@ -168,8 +180,8 @@ else
PREVIOUS_VERSION=$(cat "$FIRST_RUN_FILE" | jq -r '.version')

# If the version has changed, we assume an upgrade has occurred.
if [ "$PREVIOUS_VERSION" != "$NEXT_PUBLIC_SOURCEBOT_VERSION" ]; then
echo -e "\e[34m[Info] Upgraded from version $PREVIOUS_VERSION to $NEXT_PUBLIC_SOURCEBOT_VERSION\e[0m"
if [ "$PREVIOUS_VERSION" != "$SOURCEBOT_VERSION" ]; then
echo -e "\e[34m[Info] Upgraded from version $PREVIOUS_VERSION to $SOURCEBOT_VERSION\e[0m"

if [ "$SOURCEBOT_TELEMETRY_DISABLED" = "false" ]; then
if ! ( curl -L --output /dev/null --silent --fail --header "Content-Type: application/json" -d '{
Expand All@@ -178,7 +190,7 @@ else
"distinct_id": "'"$SOURCEBOT_INSTALL_ID"'",
"properties": {
"from_version": "'"$PREVIOUS_VERSION"'",
"to_version": "'"$NEXT_PUBLIC_SOURCEBOT_VERSION"'"
"to_version": "'"$SOURCEBOT_VERSION"'"
}
}' https://us.i.posthog.com/capture/ ) then
echo -e "\e[33m[Warning] Failed to send upgrade event.\e[0m"
Expand All@@ -187,7 +199,7 @@ else
fi
fi

echo "{\"version\": \"$NEXT_PUBLIC_SOURCEBOT_VERSION\", \"install_id\": \"$SOURCEBOT_INSTALL_ID\"}" > "$FIRST_RUN_FILE"
echo "{\"version\": \"$SOURCEBOT_VERSION\", \"install_id\": \"$SOURCEBOT_INSTALL_ID\"}" > "$FIRST_RUN_FILE"

# Start the database and wait for it to be ready before starting any other service
if [ "$DATABASE_EMBEDDED" = "true" ]; then
Expand Down
4 changes: 2 additions & 2 deletions packages/backend/src/instrument.ts
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
import * as Sentry from "@sentry/node";
import { createLogger } from "@sourcebot/shared";
import { createLogger, SOURCEBOT_VERSION } from "@sourcebot/shared";
import { env } from "@sourcebot/shared/client";

const logger = createLogger('instrument');

if (!!env.NEXT_PUBLIC_SENTRY_BACKEND_DSN && !!env.NEXT_PUBLIC_SENTRY_ENVIRONMENT) {
Sentry.init({
dsn: env.NEXT_PUBLIC_SENTRY_BACKEND_DSN,
release: env.NEXT_PUBLIC_SOURCEBOT_VERSION,
release: SOURCEBOT_VERSION,
environment: env.NEXT_PUBLIC_SENTRY_ENVIRONMENT,
});
} else {
Expand Down
5 changes: 2 additions & 3 deletions packages/backend/src/posthog.ts
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
import { env as clientEnv } from "@sourcebot/shared/client";
import { env } from "@sourcebot/shared";
import { env, SOURCEBOT_VERSION } from "@sourcebot/shared";
import { PostHog } from 'posthog-node';
import { PosthogEvent, PosthogEventMap } from './posthogEvents.js';

Expand All@@ -24,7 +23,7 @@ export function captureEvent<E extends PosthogEvent>(event: E, properties: Posth
event: event,
properties: {
...properties,
sourcebot_version: clientEnv.NEXT_PUBLIC_SOURCEBOT_VERSION,
sourcebot_version: SOURCEBOT_VERSION,
},
});
}
Expand Down
Loading