feat: Git-Tag-basierte Versionierung (Alpha/Beta/Release statt Commit-Hash)
This commit is contained in:
@@ -32,7 +32,8 @@ COPY static/ ./static/
|
|||||||
ARG GIT_COMMIT=unknown
|
ARG GIT_COMMIT=unknown
|
||||||
ARG GIT_BRANCH=unknown
|
ARG GIT_BRANCH=unknown
|
||||||
ARG GIT_COMMIT_DATE=unknown
|
ARG GIT_COMMIT_DATE=unknown
|
||||||
RUN echo "{\"commit\": \"$GIT_COMMIT\", \"branch\": \"$GIT_BRANCH\", \"date\": \"$GIT_COMMIT_DATE\"}" > /app/version.json
|
ARG GIT_TAG=unknown
|
||||||
|
RUN echo "{\"tag\": \"$GIT_TAG\", \"commit\": \"$GIT_COMMIT\", \"branch\": \"$GIT_BRANCH\", \"date\": \"$GIT_COMMIT_DATE\"}" > /app/version.json
|
||||||
|
|
||||||
# Allow git to operate in the /app-source volume (owner may differ from container user)
|
# Allow git to operate in the /app-source volume (owner may differ from container user)
|
||||||
RUN git config --global --add safe.directory /app-source
|
RUN git config --global --add safe.directory /app-source
|
||||||
|
|||||||
@@ -22,21 +22,23 @@ def get_current_version() -> dict:
|
|||||||
try:
|
try:
|
||||||
data = json.loads(Path(VERSION_FILE).read_text())
|
data = json.loads(Path(VERSION_FILE).read_text())
|
||||||
return {
|
return {
|
||||||
|
"tag": data.get("tag", "unknown"),
|
||||||
"commit": data.get("commit", "unknown"),
|
"commit": data.get("commit", "unknown"),
|
||||||
"branch": data.get("branch", "unknown"),
|
"branch": data.get("branch", "unknown"),
|
||||||
"date": data.get("date", "unknown"),
|
"date": data.get("date", "unknown"),
|
||||||
}
|
}
|
||||||
except Exception:
|
except Exception:
|
||||||
return {"commit": "unknown", "branch": "unknown", "date": "unknown"}
|
return {"tag": "unknown", "commit": "unknown", "branch": "unknown", "date": "unknown"}
|
||||||
|
|
||||||
|
|
||||||
async def check_for_updates(config: Any) -> dict:
|
async def check_for_updates(config: Any) -> dict:
|
||||||
"""Query the Gitea API for the latest commit on the configured branch.
|
"""Query the Gitea API for the latest tag and commit on the configured branch.
|
||||||
|
|
||||||
Parses the repo URL to build the Gitea API endpoint:
|
Parses the repo URL to build the Gitea API endpoint:
|
||||||
https://git.example.com/owner/repo
|
https://git.example.com/owner/repo
|
||||||
→ https://git.example.com/api/v1/repos/owner/repo/branches/{branch}
|
→ https://git.example.com/api/v1/repos/owner/repo/...
|
||||||
|
|
||||||
|
Uses tags for version comparison when available, falls back to commit SHAs.
|
||||||
Returns dict with current, latest, needs_update, and optional error.
|
Returns dict with current, latest, needs_update, and optional error.
|
||||||
"""
|
"""
|
||||||
current = get_current_version()
|
current = get_current_version()
|
||||||
@@ -62,7 +64,8 @@ async def check_for_updates(config: Any) -> dict:
|
|||||||
owner = parts[-2]
|
owner = parts[-2]
|
||||||
repo = parts[-1]
|
repo = parts[-1]
|
||||||
branch = config.git_branch or "main"
|
branch = config.git_branch or "main"
|
||||||
api_url = f"{base_url}/api/v1/repos/{owner}/{repo}/branches/{branch}"
|
branch_api = f"{base_url}/api/v1/repos/{owner}/{repo}/branches/{branch}"
|
||||||
|
tags_api = f"{base_url}/api/v1/repos/{owner}/{repo}/tags?limit=1"
|
||||||
|
|
||||||
headers = {}
|
headers = {}
|
||||||
if config.git_token:
|
if config.git_token:
|
||||||
@@ -70,7 +73,8 @@ async def check_for_updates(config: Any) -> dict:
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
async with httpx.AsyncClient(timeout=10) as client:
|
async with httpx.AsyncClient(timeout=10) as client:
|
||||||
resp = await client.get(api_url, headers=headers)
|
# Fetch branch info (latest commit)
|
||||||
|
resp = await client.get(branch_api, headers=headers)
|
||||||
if resp.status_code != 200:
|
if resp.status_code != 200:
|
||||||
return {
|
return {
|
||||||
"current": current,
|
"current": current,
|
||||||
@@ -82,20 +86,39 @@ async def check_for_updates(config: Any) -> dict:
|
|||||||
latest_commit = data.get("commit", {})
|
latest_commit = data.get("commit", {})
|
||||||
full_sha = latest_commit.get("id", "unknown")
|
full_sha = latest_commit.get("id", "unknown")
|
||||||
short_sha = full_sha[:8] if full_sha != "unknown" else "unknown"
|
short_sha = full_sha[:8] if full_sha != "unknown" else "unknown"
|
||||||
|
|
||||||
|
# Fetch latest tag
|
||||||
|
latest_tag = "unknown"
|
||||||
|
try:
|
||||||
|
tag_resp = await client.get(tags_api, headers=headers)
|
||||||
|
if tag_resp.status_code == 200:
|
||||||
|
tags = tag_resp.json()
|
||||||
|
if tags and len(tags) > 0:
|
||||||
|
latest_tag = tags[0].get("name", "unknown")
|
||||||
|
except Exception:
|
||||||
|
pass # Tag fetch is best-effort
|
||||||
|
|
||||||
latest = {
|
latest = {
|
||||||
|
"tag": latest_tag,
|
||||||
"commit": short_sha,
|
"commit": short_sha,
|
||||||
"commit_full": full_sha,
|
"commit_full": full_sha,
|
||||||
"message": latest_commit.get("commit", {}).get("message", "").split("\n")[0],
|
"message": latest_commit.get("commit", {}).get("message", "").split("\n")[0],
|
||||||
"date": latest_commit.get("commit", {}).get("committer", {}).get("date", ""),
|
"date": latest_commit.get("commit", {}).get("committer", {}).get("date", ""),
|
||||||
"branch": branch,
|
"branch": branch,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Determine if update is needed: prefer tag comparison, fallback to commit
|
||||||
|
current_tag = current.get("tag", "unknown")
|
||||||
current_sha = current.get("commit", "unknown")
|
current_sha = current.get("commit", "unknown")
|
||||||
needs_update = (
|
if current_tag != "unknown" and latest_tag != "unknown":
|
||||||
current_sha != "unknown"
|
needs_update = current_tag != latest_tag
|
||||||
and short_sha != "unknown"
|
else:
|
||||||
and current_sha != short_sha
|
needs_update = (
|
||||||
and not full_sha.startswith(current_sha)
|
current_sha != "unknown"
|
||||||
)
|
and short_sha != "unknown"
|
||||||
|
and current_sha != short_sha
|
||||||
|
and not full_sha.startswith(current_sha)
|
||||||
|
)
|
||||||
return {"current": current, "latest": latest, "needs_update": needs_update}
|
return {"current": current, "latest": latest, "needs_update": needs_update}
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ services:
|
|||||||
GIT_COMMIT: ${GIT_COMMIT:-unknown}
|
GIT_COMMIT: ${GIT_COMMIT:-unknown}
|
||||||
GIT_BRANCH: ${GIT_BRANCH:-unknown}
|
GIT_BRANCH: ${GIT_BRANCH:-unknown}
|
||||||
GIT_COMMIT_DATE: ${GIT_COMMIT_DATE:-unknown}
|
GIT_COMMIT_DATE: ${GIT_COMMIT_DATE:-unknown}
|
||||||
|
GIT_TAG: ${GIT_TAG:-unknown}
|
||||||
container_name: netbird-msp-appliance
|
container_name: netbird-msp-appliance
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
security_opt:
|
security_opt:
|
||||||
@@ -71,7 +72,7 @@ services:
|
|||||||
networks:
|
networks:
|
||||||
- npm-network
|
- npm-network
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD", "curl", "-f", "http://localhost:8000/api/health"]
|
test: [ "CMD", "curl", "-f", "http://localhost:8000/api/health" ]
|
||||||
interval: 30s
|
interval: 30s
|
||||||
timeout: 10s
|
timeout: 10s
|
||||||
retries: 3
|
retries: 3
|
||||||
|
|||||||
@@ -1214,24 +1214,31 @@ async function loadVersionInfo() {
|
|||||||
const latest = data.latest;
|
const latest = data.latest;
|
||||||
const needsUpdate = data.needs_update;
|
const needsUpdate = data.needs_update;
|
||||||
|
|
||||||
|
const currentTag = current.tag && current.tag !== 'unknown' ? current.tag : null;
|
||||||
|
const currentCommit = current.commit || 'unknown';
|
||||||
|
|
||||||
let html = `<div class="row g-3">
|
let html = `<div class="row g-3">
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<div class="border rounded p-3">
|
<div class="border rounded p-3">
|
||||||
<div class="text-muted small mb-1">${t('settings.currentVersion')}</div>
|
<div class="text-muted small mb-1">${t('settings.currentVersion')}</div>
|
||||||
<div class="fw-bold font-monospace">${esc(current.commit || 'unknown')}</div>
|
<div class="fw-bold fs-5">${esc(currentTag || currentCommit)}</div>
|
||||||
|
${currentTag ? `<div class="text-muted small font-monospace">${t('settings.commitHash')}: ${esc(currentCommit)}</div>` : ''}
|
||||||
<div class="text-muted small">${t('settings.branch')}: <strong>${esc(current.branch || 'unknown')}</strong></div>
|
<div class="text-muted small">${t('settings.branch')}: <strong>${esc(current.branch || 'unknown')}</strong></div>
|
||||||
<div class="text-muted small">${esc(current.date || '')}</div>
|
<div class="text-muted small">${esc(current.date || '')}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>`;
|
</div>`;
|
||||||
|
|
||||||
if (latest) {
|
if (latest) {
|
||||||
|
const latestTag = latest.tag && latest.tag !== 'unknown' ? latest.tag : null;
|
||||||
|
const latestCommit = latest.commit || 'unknown';
|
||||||
const badge = needsUpdate
|
const badge = needsUpdate
|
||||||
? `<span class="badge bg-warning text-dark ms-1">${t('settings.updateAvailable')}</span>`
|
? `<span class="badge bg-warning text-dark ms-1">${t('settings.updateAvailable')}</span>`
|
||||||
: `<span class="badge bg-success ms-1">${t('settings.upToDate')}</span>`;
|
: `<span class="badge bg-success ms-1">${t('settings.upToDate')}</span>`;
|
||||||
html += `<div class="col-md-6">
|
html += `<div class="col-md-6">
|
||||||
<div class="border rounded p-3 ${needsUpdate ? 'border-warning' : ''}">
|
<div class="border rounded p-3 ${needsUpdate ? 'border-warning' : ''}">
|
||||||
<div class="text-muted small mb-1">${t('settings.latestVersion')} ${badge}</div>
|
<div class="text-muted small mb-1">${t('settings.latestVersion')} ${badge}</div>
|
||||||
<div class="fw-bold font-monospace">${esc(latest.commit || 'unknown')}</div>
|
<div class="fw-bold fs-5">${esc(latestTag || latestCommit)}</div>
|
||||||
|
${latestTag ? `<div class="text-muted small font-monospace">${t('settings.commitHash')}: ${esc(latestCommit)}</div>` : ''}
|
||||||
<div class="text-muted small">${t('settings.branch')}: <strong>${esc(latest.branch || 'unknown')}</strong></div>
|
<div class="text-muted small">${t('settings.branch')}: <strong>${esc(latest.branch || 'unknown')}</strong></div>
|
||||||
<div class="text-muted small">${esc(latest.message || '')}</div>
|
<div class="text-muted small">${esc(latest.message || '')}</div>
|
||||||
<div class="text-muted small">${esc(latest.date || '')}</div>
|
<div class="text-muted small">${esc(latest.date || '')}</div>
|
||||||
|
|||||||
@@ -214,6 +214,7 @@
|
|||||||
"currentVersion": "Installierte Version",
|
"currentVersion": "Installierte Version",
|
||||||
"latestVersion": "Neueste verfügbare Version",
|
"latestVersion": "Neueste verfügbare Version",
|
||||||
"branch": "Branch",
|
"branch": "Branch",
|
||||||
|
"commitHash": "Commit",
|
||||||
"updateAvailable": "Update verfügbar",
|
"updateAvailable": "Update verfügbar",
|
||||||
"upToDate": "Aktuell",
|
"upToDate": "Aktuell",
|
||||||
"triggerUpdate": "Update starten",
|
"triggerUpdate": "Update starten",
|
||||||
|
|||||||
@@ -235,6 +235,7 @@
|
|||||||
"currentVersion": "Installed Version",
|
"currentVersion": "Installed Version",
|
||||||
"latestVersion": "Latest Available",
|
"latestVersion": "Latest Available",
|
||||||
"branch": "Branch",
|
"branch": "Branch",
|
||||||
|
"commitHash": "Commit",
|
||||||
"updateAvailable": "Update Available",
|
"updateAvailable": "Update Available",
|
||||||
"upToDate": "Up to date",
|
"upToDate": "Up to date",
|
||||||
"triggerUpdate": "Start Update",
|
"triggerUpdate": "Start Update",
|
||||||
|
|||||||
@@ -38,9 +38,11 @@ echo "✓ Code updated to: $(git log --oneline -1)"
|
|||||||
export GIT_COMMIT=$(git rev-parse HEAD)
|
export GIT_COMMIT=$(git rev-parse HEAD)
|
||||||
export GIT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
|
export GIT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
|
||||||
export GIT_COMMIT_DATE=$(git log -1 --format=%cI)
|
export GIT_COMMIT_DATE=$(git log -1 --format=%cI)
|
||||||
|
export GIT_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "unknown")
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "Building with:"
|
echo "Building with:"
|
||||||
|
echo " GIT_TAG = $GIT_TAG"
|
||||||
echo " GIT_COMMIT = $GIT_COMMIT"
|
echo " GIT_COMMIT = $GIT_COMMIT"
|
||||||
echo " GIT_BRANCH = $GIT_BRANCH"
|
echo " GIT_BRANCH = $GIT_BRANCH"
|
||||||
echo " GIT_COMMIT_DATE = $GIT_COMMIT_DATE"
|
echo " GIT_COMMIT_DATE = $GIT_COMMIT_DATE"
|
||||||
|
|||||||
Reference in New Issue
Block a user