Files
betreuungs-cockpit/scripts/version.mjs
T
Florian Wilde b2ac13e128 feat: Versionierung mit Changelog, Version 1.0.0
Bis jetzt stand nirgends, welcher Stand laeuft. Beim Aktualisieren auf
einem Server ist das die erste Frage.

CHANGELOG.md nach Keep a Changelog, Versionsnummern nach SemVer. Der
Changelog sagt, was sich beim Arbeiten aendert - nicht, welche Datei
angefasst wurde. Dazu eine Tabelle, was Major, Minor und Patch fuer den
Betreiber praktisch bedeuten, und der Hinweis, dass sich eine
Datenbank-Migration nicht zurueckrollen laesst.

Die Version steht bewusst an zwei Stellen: package.json und
src/lib/version.ts. Ein Import der package.json waere im
Standalone-Build eine andere Datei als die des Projekts - die Zahl haenge
dann an der Laufzeit. Ein Test haelt beide zusammen, und
"npm run version" setzt sie gemeinsam samt Changelog-Abschnitt.

Committet und getaggt wird nicht automatisch. Ein Changelog-Eintrag, den
niemand gegengelesen hat, ist keinen Deut besser als keiner.

Sichtbar wird die Version unten in der Seitenleiste und unter
/api/gesundheit - dort mit Git-Stand, den der Docker-Build hineinreicht.
Auf der Anmeldeseite steht sie nicht: wer nicht angemeldet ist, muss
nicht wissen, welche Fassung hier laeuft.

Etappe: 8
Phase: Haertung
2026-08-22 10:41:33 +02:00

138 lines
4.1 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env node
/**
* Version anheben.
*
* npm run version -- patch 1.0.0 -> 1.0.1
* npm run version -- minor 1.0.0 -> 1.1.0
* npm run version -- major 1.0.0 -> 2.0.0
* npm run version -- 1.2.3 genau diese Version
*
* Was passiert:
* 1. package.json und src/lib/version.ts werden gesetzt - beide, damit
* sie nicht auseinanderlaufen.
* 2. Im CHANGELOG wird aus "## [Unveroeffentlicht]" ein Abschnitt mit
* Versionsnummer und heutigem Datum, darueber ein neuer leerer
* Abschnitt.
* 3. Der Vergleichslink am Dateiende wird nachgezogen.
*
* Was NICHT passiert: committen und taggen. Das machst du selbst, nachdem
* du den Changelog-Eintrag gegengelesen hast. Ein automatisch erzeugter
* Changelog, den niemand liest, ist keinen Deut besser als keiner.
*
* Danach:
* git add -A && git commit -m "chore: Version 1.0.1"
* git tag -a v1.0.1 -m "..." && git push --follow-tags
*/
import { readFileSync, writeFileSync } from 'node:fs'
const WURZEL = new URL('..', import.meta.url)
const pfad = (name) => new URL(name, WURZEL)
function lesen(name) {
return readFileSync(pfad(name), 'utf8')
}
function schreiben(name, inhalt) {
writeFileSync(pfad(name), inhalt, 'utf8')
console.log(` ${name}`)
}
// --- Ziel bestimmen ---------------------------------------------------------
const argument = process.argv[2]
if (!argument) {
console.error('Aufruf: npm run version -- <patch|minor|major|x.y.z>')
process.exit(1)
}
const paket = JSON.parse(lesen('package.json'))
const alt = paket.version
function naechste(aktuell, art) {
const treffer = aktuell.match(/^(\d+)\.(\d+)\.(\d+)$/)
if (!treffer) throw new Error(`Version "${aktuell}" ist kein x.y.z`)
const [haupt, neben, fehler] = treffer.slice(1).map(Number)
switch (art) {
case 'major':
return `${haupt + 1}.0.0`
case 'minor':
return `${haupt}.${neben + 1}.0`
case 'patch':
return `${haupt}.${neben}.${fehler + 1}`
default:
if (!/^\d+\.\d+\.\d+$/.test(art)) {
throw new Error(`"${art}" ist weder patch/minor/major noch x.y.z`)
}
return art
}
}
const neu = naechste(alt, argument)
if (neu === alt) {
console.error(`Version ist bereits ${alt}.`)
process.exit(1)
}
console.log(`\n${alt} -> ${neu}\n`)
console.log('Geaendert:')
// --- 1. package.json --------------------------------------------------------
paket.version = neu
schreiben('package.json', `${JSON.stringify(paket, null, 2)}\n`)
// --- 2. src/lib/version.ts --------------------------------------------------
const versionsdatei = lesen('src/lib/version.ts')
const ersetzt = versionsdatei.replace(
/export const VERSION = '[^']+'/,
`export const VERSION = '${neu}'`,
)
if (ersetzt === versionsdatei) {
console.error('FEHLER: VERSION in src/lib/version.ts nicht gefunden.')
process.exit(1)
}
schreiben('src/lib/version.ts', ersetzt)
// --- 3. CHANGELOG.md --------------------------------------------------------
const heute = new Date().toISOString().slice(0, 10)
let changelog = lesen('CHANGELOG.md')
const UNVEROEFFENTLICHT = '## [Unveröffentlicht]'
if (!changelog.includes(UNVEROEFFENTLICHT)) {
console.error(`FEHLER: "${UNVEROEFFENTLICHT}" steht nicht im CHANGELOG.`)
process.exit(1)
}
const leererAbschnitt = [
UNVEROEFFENTLICHT,
'',
'_Noch nichts._',
'',
`## [${neu}] – ${heute}`,
].join('\n')
changelog = changelog.replace(UNVEROEFFENTLICHT, leererAbschnitt)
// Vergleichslinks am Dateiende nachziehen.
const basis = 'https://git.wilde-server.de/florian.wilde/betreuungs-cockpit/compare'
changelog = changelog.replace(
/^\[Unveröffentlicht\]:.*$/m,
`[Unveröffentlicht]: ${basis}/v${neu}...HEAD\n[${neu}]: ${basis}/v${alt}...v${neu}`,
)
schreiben('CHANGELOG.md', changelog)
// --- Hinweis ----------------------------------------------------------------
console.log(`
Jetzt:
1. CHANGELOG.md gegenlesen - steht dort, was sich fuer den Nutzer
tatsaechlich aendert? Nicht, welche Datei angefasst wurde.
2. git add -A && git commit -m "chore: Version ${neu}"
3. git tag -a v${neu} -m "Version ${neu}"
4. git push --follow-tags
`)