9 Commits

Author SHA1 Message Date
f1e192c5d4 Merge pull request 'v1.2.0' (#10) from dev into main
Some checks failed
CI / test (push) Successful in 13s
Release / release (push) Failing after 5m14s
CI / build-dev (push) Has been skipped
Reviewed-on: #10
2026-03-28 13:24:34 -04:00
3037381084 Merge pull request 'chore: bump version to 1.2.0' (#9) from chore/bump-v1.2.0 into dev
All checks were successful
CI / test (push) Successful in 13s
CI / build-dev (push) Successful in 26s
CI / test (pull_request) Successful in 13s
CI / build-dev (pull_request) Has been skipped
Reviewed-on: #9
2026-03-28 13:22:15 -04:00
e54c1d4848 chore: bump version to 1.2.0
All checks were successful
CI / test (pull_request) Successful in 13s
CI / build-dev (pull_request) Has been skipped
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-28 13:21:18 -04:00
3ae3f98df5 Merge pull request 'fix: use git rev-parse for short SHA in build-dev' (#8) from fix/ci-short-sha into dev
All checks were successful
CI / test (push) Successful in 12s
CI / build-dev (push) Successful in 20s
Reviewed-on: #8
2026-03-28 13:19:23 -04:00
65d6514603 fix: use git rev-parse for short SHA in build-dev
All checks were successful
CI / test (pull_request) Successful in 12s
CI / build-dev (pull_request) Has been skipped
$GITEA_SHA is unset on Gitea runners — the nav showed "dev-" with an
empty SHA. git rev-parse --short HEAD works regardless of runner env vars.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-28 13:18:47 -04:00
bc44bcbde9 Merge pull request 'fix: remove npm cache from setup-node' (#7) from fix/ci-remove-npm-cache into dev
All checks were successful
CI / test (push) Successful in 12s
CI / build-dev (push) Successful in 13s
Reviewed-on: #7
2026-03-28 13:16:33 -04:00
cae0f2222a fix: remove npm cache from setup-node
All checks were successful
CI / test (pull_request) Successful in 13s
CI / build-dev (pull_request) Has been skipped
The Gitea runner's cache service is unreachable, causing a ~4 minute
ETIMEDOUT on every run before falling back to a cold install anyway.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-28 13:11:05 -04:00
28833a7ec6 Merge pull request 'feat: show dev-<sha> version string in nav for dev builds' (#6) from feat/dev-version-string into dev
All checks were successful
CI / test (push) Successful in 9m33s
CI / build-dev (push) Successful in 22s
Reviewed-on: #6
2026-03-28 13:03:23 -04:00
6ba02bf17d feat: show dev-<sha> version string in nav for dev builds
All checks were successful
CI / test (pull_request) Successful in 9m31s
CI / build-dev (pull_request) Has been skipped
Production images continue to display the semver (v1.x.x). Dev images
built by CI now receive BUILD_VERSION=dev-<7-char-sha> via a Docker ARG,
and app.js skips the v prefix for non-semver strings.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-28 12:52:15 -04:00
5 changed files with 53 additions and 5 deletions

View File

@@ -19,7 +19,6 @@ jobs:
- uses: actions/setup-node@v4 - uses: actions/setup-node@v4
with: with:
node-version: 'lts/*' node-version: 'lts/*'
cache: npm
- run: npm ci - run: npm ci
@@ -40,11 +39,15 @@ jobs:
username: ${{ gitea.actor }} username: ${{ gitea.actor }}
password: ${{ secrets.TOKEN }} password: ${{ secrets.TOKEN }}
- name: Compute short SHA
run: echo "SHORT_SHA=$(git rev-parse --short HEAD)" >> $GITEA_ENV
- name: Build and push - name: Build and push
uses: docker/build-push-action@v5 uses: docker/build-push-action@v5
with: with:
context: . context: .
push: true push: true
build-args: BUILD_VERSION=dev-${{ env.SHORT_SHA }}
tags: | tags: |
${{ env.IMAGE }}:dev ${{ env.IMAGE }}:dev
${{ env.IMAGE }}:dev-${{ gitea.sha }} ${{ env.IMAGE }}:dev-${{ gitea.sha }}

View File

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

View File

@@ -38,6 +38,9 @@ window.addEventListener('popstate', e => {
// ── Bootstrap ───────────────────────────────────────────────────────────────── // ── 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(); handleRoute();

View File

@@ -1,6 +1,6 @@
{ {
"name": "catalyst", "name": "catalyst",
"version": "1.1.2", "version": "1.2.0",
"type": "module", "type": "module",
"scripts": { "scripts": {
"start": "node server/server.js", "start": "node server/server.js",

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 ─────────────────────────────────────────────────────────── // ── CSS regressions ───────────────────────────────────────────────────────────
const css = readFileSync(join(__dirname, '../css/app.css'), 'utf8') const css = readFileSync(join(__dirname, '../css/app.css'), 'utf8')
@@ -127,3 +145,22 @@ describe('CSS regressions', () => {
expect(css).toMatch(/\.badge\s*\{[^}]*text-align\s*:\s*center/s) 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')
})
it('short SHA is computed with git rev-parse, not $GITEA_SHA (which is empty)', () => {
// Regression: ${GITEA_SHA::7} expands to "" on Gitea runners — nav showed "dev-".
// git rev-parse --short HEAD works regardless of which env vars the runner sets.
expect(ciYml).toContain('git rev-parse --short HEAD')
expect(ciYml).not.toContain('GITEA_SHA')
})
})