feat: show dev-<sha> version string in nav for dev builds #6

Merged
josh merged 1 commits from feat/dev-version-string into dev 2026-03-28 13:03:23 -04:00
4 changed files with 45 additions and 3 deletions

View File

@@ -40,11 +40,15 @@ jobs:
username: ${{ gitea.actor }}
password: ${{ secrets.TOKEN }}
- name: Compute short SHA
run: echo "SHORT_SHA=${GITEA_SHA::7}" >> $GITEA_ENV
- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
push: true
build-args: BUILD_VERSION=dev-${{ env.SHORT_SHA }}
tags: |
${{ env.IMAGE }}:dev
${{ env.IMAGE }}:dev-${{ gitea.sha }}

View File

@@ -7,8 +7,13 @@ COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
RUN awk -F'"' '/"version"/{printf "const VERSION = \"%s\";\n", $4; exit}' \
package.json > js/version.js
ARG BUILD_VERSION=""
RUN if [ -n "$BUILD_VERSION" ]; then \
printf 'const VERSION = "%s";\n' "$BUILD_VERSION" > js/version.js; \
else \
awk -F'"' '/"version"/{printf "const VERSION = \"%s\";\n", $4; exit}' \
package.json > js/version.js; \
fi
RUN mkdir -p /app/data && chown -R app:app /app
USER app

View File

@@ -38,6 +38,9 @@ window.addEventListener('popstate', e => {
// ── Bootstrap ─────────────────────────────────────────────────────────────────
if (VERSION) document.getElementById('nav-version').textContent = `v${VERSION}`;
if (VERSION) {
const label = /^\d/.test(VERSION) ? `v${VERSION}` : VERSION;
document.getElementById('nav-version').textContent = label;
}
handleRoute();

View File

@@ -115,6 +115,24 @@ describe('fmtDateFull', () => {
})
})
// ── versionLabel() ───────────────────────────────────────────────────────────
// Mirrors the logic in app.js — semver strings get a v prefix, dev strings don't.
function versionLabel(v) {
return /^\d/.test(v) ? `v${v}` : v
}
describe('version label formatting', () => {
it('prepends v for semver strings', () => {
expect(versionLabel('1.1.2')).toBe('v1.1.2')
expect(versionLabel('2.0.0')).toBe('v2.0.0')
})
it('does not prepend v for dev build strings', () => {
expect(versionLabel('dev-abc1234')).toBe('dev-abc1234')
})
})
// ── CSS regressions ───────────────────────────────────────────────────────────
const css = readFileSync(join(__dirname, '../css/app.css'), 'utf8')
@@ -127,3 +145,15 @@ describe('CSS regressions', () => {
expect(css).toMatch(/\.badge\s*\{[^}]*text-align\s*:\s*center/s)
})
})
// ── CI workflow regressions ───────────────────────────────────────────────────
const ciYml = readFileSync(join(__dirname, '../.gitea/workflows/ci.yml'), 'utf8')
describe('CI workflow regressions', () => {
it('build-dev job passes BUILD_VERSION build arg', () => {
// Regression: dev image showed semver instead of dev-<sha> because
// BUILD_VERSION was never passed to docker build.
expect(ciYml).toContain('BUILD_VERSION')
})
})