automatic versioning on tags

This commit is contained in:
lowcarbdev
2025-11-22 17:03:01 -07:00
parent 4dcac1fdfb
commit b6d63fc2d2
7 changed files with 56 additions and 20 deletions
+16
View File
@@ -57,6 +57,20 @@ jobs:
flavor: |
latest=false
- name: Determine version for build
id: version
run: |
if [[ "${{ github.ref }}" == refs/tags/v* ]]; then
# For tags, strip the 'v' prefix
VERSION="${{ github.ref_name }}"
VERSION="${VERSION#v}"
else
# For non-tags, use git commit hash with dirty flag
VERSION=$(git describe --always --dirty)
fi
echo "version=git-${VERSION}" >> $GITHUB_OUTPUT
echo "Building with version: git-${VERSION}"
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
@@ -65,5 +79,7 @@ jobs:
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
build-args: |
VERSION=${{ steps.version.outputs.version }}
cache-from: type=gha
cache-to: type=gha,mode=max
+5
View File
@@ -69,6 +69,11 @@ RUN chmod +x /usr/local/bin/docker-entrypoint.sh
# Create data directory for database
RUN mkdir -p /data
# Accept version as build argument and generate version.json
# This is done late in the build to maximize cache layer reuse
ARG VERSION=dev
RUN echo "{\"version\":\"${VERSION}\"}" > /app/version.json
# Set environment variables
ENV PORT=8081 \
DB_PATH_PREFIX=/data \
+14 -2
View File
@@ -28,6 +28,7 @@ function App() {
const [showUpload, setShowUpload] = useState(false)
const [showPasswordModal, setShowPasswordModal] = useState(false)
const [searchFilter, setSearchFilter] = useState('')
const [version, setVersion] = useState('...')
// Mobile sidebar state
const [showSidebar, setShowSidebar] = useState(true)
@@ -51,8 +52,19 @@ function App() {
useEffect(() => {
fetchDateRange()
fetchConversations()
fetchVersion()
}, [])
const fetchVersion = async () => {
try {
const response = await axios.get(`${API_BASE}/version`)
setVersion(response.data.version || 'unknown')
} catch (error) {
console.error('Failed to fetch version:', error)
setVersion('unknown')
}
}
useEffect(() => {
fetchConversations()
}, [startDate, endDate])
@@ -177,10 +189,10 @@ function App() {
</Dropdown.Toggle>
<Dropdown.Menu>
<Dropdown.ItemText className="fw-semibold">
User: {user?.username}
{user?.username}
</Dropdown.ItemText>
<Dropdown.ItemText className="small text-muted">
Version {__APP_VERSION__}
Version {version}
</Dropdown.ItemText>
<Dropdown.Divider />
<Dropdown.Item onClick={() => setShowPasswordModal(true)}>
-3
View File
@@ -1,3 +0,0 @@
{
"version": "0.1.5-dev"
}
-15
View File
@@ -1,22 +1,7 @@
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { readFileSync } from 'fs'
import { resolve } from 'path'
// Read version from version.json
let version = 'unknown'
try {
const versionFile = readFileSync(resolve(__dirname, 'version.json'), 'utf-8')
const versionData = JSON.parse(versionFile)
version = versionData.version
} catch (error) {
console.warn('Warning: Could not read version.json, using default version')
}
// https://vite.dev/config/
export default defineConfig({
plugins: [react()],
define: {
__APP_VERSION__: JSON.stringify(version),
},
})
+18
View File
@@ -2,9 +2,11 @@ package internal
import (
"database/sql"
"encoding/json"
"fmt"
"log/slog"
"net/http"
"os"
"strconv"
"time"
@@ -422,3 +424,19 @@ func HandleSearch(c echo.Context) error {
return c.JSON(http.StatusOK, results)
}
// HandleVersion returns the application version
func HandleVersion(c echo.Context) error {
// Try to read version from version.json file first (Docker builds)
versionFile := "/app/version.json"
if data, err := os.ReadFile(versionFile); err == nil {
var versionData map[string]string
if err := json.Unmarshal(data, &versionData); err == nil {
return c.JSON(http.StatusOK, versionData)
}
}
return c.JSON(http.StatusOK, map[string]string{
"version": "dev",
})
}
+3
View File
@@ -80,6 +80,9 @@ func main() {
return c.String(http.StatusOK, "OK")
})
// Version endpoint (public, no authentication required)
e.GET("/api/version", internal.HandleVersion)
// Serve static files from frontend/dist if it exists (for production/Docker)
if _, err := os.Stat("./frontend/dist"); err == nil {
// Serve static assets (JS, CSS, images, etc.)