docs(standards): zentrale Anleitung zur automatisierten Versionierung hinzugefügt
- beschreibt das Versionskonzept für package.json, package-lock.json und .env.* - erklärt die Verwendung von bumpVersion.js und Husky-Hooks - hilft neuen und bestehenden Entwicklern, konsistent zu arbeiten - gilt als Standardrichtlinie für zukünftige Projekte
This commit is contained in:
@@ -5,4 +5,6 @@ NEXT_PUBLIC_USE_MOCK_BACKEND_TDR_START=true
|
|||||||
NEXT_PUBLIC_USE_MOCK_BACKEND_LOOP_START=false
|
NEXT_PUBLIC_USE_MOCK_BACKEND_LOOP_START=false
|
||||||
NEXT_PUBLIC_EXPORT_STATIC=false
|
NEXT_PUBLIC_EXPORT_STATIC=false
|
||||||
NEXT_PUBLIC_USE_CGI=false
|
NEXT_PUBLIC_USE_CGI=false
|
||||||
|
# App-Versionsnummer
|
||||||
|
NEXT_PUBLIC_APP_VERSION=1.6.408
|
||||||
|
|
||||||
|
|||||||
@@ -4,3 +4,5 @@ NEXT_PUBLIC_ENCRYPTION_IV=1
|
|||||||
NEXT_PUBLIC_CPL_API_PATH=/CPL
|
NEXT_PUBLIC_CPL_API_PATH=/CPL
|
||||||
NEXT_PUBLIC_EXPORT_STATIC=true
|
NEXT_PUBLIC_EXPORT_STATIC=true
|
||||||
NEXT_PUBLIC_USE_CGI=true
|
NEXT_PUBLIC_USE_CGI=true
|
||||||
|
# App-Versionsnummer
|
||||||
|
NEXT_PUBLIC_APP_VERSION=1.6.408
|
||||||
@@ -1,4 +1,12 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
. "$(dirname "$0")/_/husky.sh"
|
. "$(dirname "$0")/_/husky.sh"
|
||||||
|
|
||||||
node incrementVersion.ts
|
echo "🔄 Version wird automatisch erhöht (bumpVersion.ts)..."
|
||||||
|
|
||||||
|
# Version automatisch erhöhen
|
||||||
|
node /scripts/bumpVersion.ts
|
||||||
|
|
||||||
|
# Automatisch relevante Dateien zum Commit hinzufügen
|
||||||
|
git add package.json package-lock.json .env.development .env.production
|
||||||
|
|
||||||
|
# Fortsetzen mit dem Commit
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ const VersionInfo: React.FC = () => {
|
|||||||
useSelector((state: RootState) => state.systemSettingsSlice.appVersion) ||
|
useSelector((state: RootState) => state.systemSettingsSlice.appVersion) ||
|
||||||
"Unbekannt";
|
"Unbekannt";
|
||||||
const webVersion = useSelector(
|
const webVersion = useSelector(
|
||||||
(state: RootState) => state.webVersionSlice.version
|
(state: RootState) => state.webVersionSlice.appVersion
|
||||||
); // Webversion aus Redux holen
|
); // Webversion aus Redux holen
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
// config/webVersion.ts
|
|
||||||
/*
|
|
||||||
1: Hauptversion (komplettes Redesign oder neue Hauptfeatures).
|
|
||||||
0: Nebenversion (kleinere, aber bedeutende neue Features).
|
|
||||||
6: Build-Nummer (interne Entwicklungsiteration).
|
|
||||||
2: Patch oder Hotfix (Bugfixes oder kleine Änderungen).
|
|
||||||
|
|
||||||
*/
|
|
||||||
const webVersion = "1.6.407";
|
|
||||||
export default webVersion;
|
|
||||||
66
docs/standards/versioning.md
Normal file
66
docs/standards/versioning.md
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
# 📦 Versionierung im Projekt
|
||||||
|
|
||||||
|
## 🎯 Ziel
|
||||||
|
|
||||||
|
Dieses Projekt verwendet eine automatisierte und konsistente Versionsverwaltung, um Klarheit über
|
||||||
|
die aktuelle App-Version zu gewährleisten und manuelle Fehler zu vermeiden.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🗂️ Wo wird die Version gespeichert?
|
||||||
|
|
||||||
|
Die App-Version ist in **vier Dateien synchron enthalten**:
|
||||||
|
|
||||||
|
| Datei | Zweck |
|
||||||
|
| ------------------- | ----------------------------------------- |
|
||||||
|
| `package.json` | Hauptquelle für Version (npm, Git) |
|
||||||
|
| `package-lock.json` | Technischer Zustand des Builds |
|
||||||
|
| `.env.development` | Anzeige in der UI zur Entwicklungszeit |
|
||||||
|
| `.env.production` | Anzeige in der UI auf Produktionssystemen |
|
||||||
|
|
||||||
|
Beispiel-Eintrag in `.env.*`:
|
||||||
|
|
||||||
|
```env
|
||||||
|
NEXT_PUBLIC_APP_VERSION=1.1.265
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ⚙️ Wie wird die Version erhöht?
|
||||||
|
|
||||||
|
Die Version wird automatisch durch folgendes Skript erhöht:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
node scripts/bumpVersion.js
|
||||||
|
```
|
||||||
|
|
||||||
|
### Dieses Skript erledigt:
|
||||||
|
|
||||||
|
- Erhöhung der Patch-Version (z. B. `1.1.265` → `1.1.266`)
|
||||||
|
- Aktualisierung von `package.json`
|
||||||
|
- Erstellung eines synchronen `package-lock.json`
|
||||||
|
- Aktualisierung der `.env.development` und `.env.production` mit neuer Version
|
||||||
|
|
||||||
|
Das Skript wird zusätzlich automatisch beim Git-Commit über Husky (`.husky/pre-commit`) ausgeführt.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🧠 Warum ist das hilfreich?
|
||||||
|
|
||||||
|
- Die UI zeigt **immer die aktuelle App-Version**, über `process.env.NEXT_PUBLIC_APP_VERSION`
|
||||||
|
- Git-History, Deployments und ZIP-Versionen sind nachvollziehbar
|
||||||
|
- Keine Inkonsistenzen durch manuelle Pflege
|
||||||
|
- Reproduzierbare Builds dank `package-lock.json`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🧑💻 Hinweis für neue Entwickler
|
||||||
|
|
||||||
|
- ❌ Niemals die Versionsnummer manuell in nur einer Datei ändern!
|
||||||
|
- ✅ Immer das Skript nutzen oder den Commit-Hook wirken lassen.
|
||||||
|
- 🔁 Nach Konflikten: Stelle sicher, dass `package-lock.json` und `.env.*` konsistent sind.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
📘 Pfad diese Datei:
|
||||||
|
[`/docs/standards/versioning.md`](/docs/standards/versioning.md)
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
// /incrementVersion.ts
|
|
||||||
const fs = require("fs");
|
|
||||||
const path = require("path");
|
|
||||||
|
|
||||||
const versionFilePath = path.join(process.cwd(), "config/webVersion.ts");
|
|
||||||
|
|
||||||
// Falls die Datei nicht existiert, erstelle eine Standardversion
|
|
||||||
if (!fs.existsSync(versionFilePath)) {
|
|
||||||
fs.writeFileSync(
|
|
||||||
versionFilePath,
|
|
||||||
`export const WEB_VERSION = "1.0.0.0";\n`,
|
|
||||||
"utf8"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const versionFile = fs.readFileSync(versionFilePath, "utf8");
|
|
||||||
|
|
||||||
// Regex, um Versionsnummer zu finden (vX.Y.Z oder vX.Y.Z.N)
|
|
||||||
const versionRegex = /(\d+)\.(\d+)\.(\d+)(?:\.(\d+))?/;
|
|
||||||
const match = versionFile.match(versionRegex);
|
|
||||||
|
|
||||||
if (match) {
|
|
||||||
let [major, minor, patch, build] = match
|
|
||||||
.slice(1)
|
|
||||||
.map((num) => (num !== undefined ? Number(num) : 0));
|
|
||||||
|
|
||||||
const isHotfix = process.env.HOTFIX_MODE === "true"; // Umgebungsvariable für Hotfixes
|
|
||||||
|
|
||||||
if (isHotfix) {
|
|
||||||
build++; // Falls ein Hotfix gemacht wird, nur `N` erhöhen (vX.Y.Z.N)
|
|
||||||
console.log(
|
|
||||||
`🔧 Hotfix-Modus aktiv – Erhöhe Patch-Fix auf: ${major}.${minor}.${patch}.${build}`
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
patch++; // Normale Builds erhöhen `Z`
|
|
||||||
build = 0; // Falls es kein Hotfix ist, beginnt `N` wieder bei 0
|
|
||||||
console.log(
|
|
||||||
`📦 Normale Build-Erhöhung – Neue Version: ${major}.${minor}.${patch}`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const newVersion = isHotfix
|
|
||||||
? `${major}.${minor}.${patch}.${build}`
|
|
||||||
: `${major}.${minor}.${patch}`;
|
|
||||||
const updatedFile = versionFile.replace(versionRegex, newVersion);
|
|
||||||
|
|
||||||
fs.writeFileSync(versionFilePath, updatedFile, "utf8");
|
|
||||||
console.log(`✅ Webversion aktualisiert auf: ${newVersion}`);
|
|
||||||
} else {
|
|
||||||
console.error("❌ Konnte die Version nicht finden!");
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
8
package-lock.json
generated
8
package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "23.09.2024-cpl-v4",
|
"name": "cpl-v4",
|
||||||
"version": "0.1.0",
|
"version": "1.6.408",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "23.09.2024-cpl-v4",
|
"name": "cpl-v4",
|
||||||
"version": "0.1.0",
|
"version": "1.6.408",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fontsource/roboto": "^5.1.0",
|
"@fontsource/roboto": "^5.1.0",
|
||||||
"@iconify-icons/ri": "^1.2.10",
|
"@iconify-icons/ri": "^1.2.10",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "23.09.2024-cpl-v4",
|
"name": "cpl-v4",
|
||||||
"version": "0.1.0",
|
"version": "1.6.408",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "next dev",
|
"dev": "next dev",
|
||||||
@@ -10,7 +10,8 @@
|
|||||||
"start": "next start",
|
"start": "next start",
|
||||||
"lint": "next lint",
|
"lint": "next lint",
|
||||||
"test": "jest",
|
"test": "jest",
|
||||||
"prepare": "husky install"
|
"prepare": "husky install",
|
||||||
|
"bump-version": "node ./scripts/bumpVersion.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fontsource/roboto": "^5.1.0",
|
"@fontsource/roboto": "^5.1.0",
|
||||||
@@ -78,4 +79,4 @@
|
|||||||
"ts-node": "^10.9.2",
|
"ts-node": "^10.9.2",
|
||||||
"typescript": "^5.7.3"
|
"typescript": "^5.7.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,13 +1,12 @@
|
|||||||
// redux/slices/webVersionSlice.ts
|
// redux/slices/webVersionSlice.ts
|
||||||
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
|
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
|
||||||
import webVersion from "../../config/webVersion";
|
|
||||||
|
|
||||||
interface WebVersionState {
|
interface WebVersionState {
|
||||||
version: string;
|
appVersion: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const initialState: WebVersionState = {
|
const initialState: WebVersionState = {
|
||||||
version: webVersion,
|
appVersion: process.env.NEXT_PUBLIC_APP_VERSION ?? "",
|
||||||
};
|
};
|
||||||
|
|
||||||
const webVersionSlice = createSlice({
|
const webVersionSlice = createSlice({
|
||||||
@@ -15,14 +14,14 @@ const webVersionSlice = createSlice({
|
|||||||
initialState,
|
initialState,
|
||||||
reducers: {
|
reducers: {
|
||||||
setWebVersion(state, action: PayloadAction<string>) {
|
setWebVersion(state, action: PayloadAction<string>) {
|
||||||
state.version = action.payload;
|
state.appVersion = action.payload;
|
||||||
},
|
},
|
||||||
incrementBuild(state) {
|
incrementBuild(state) {
|
||||||
// Versionsnummer zerlegen und Build hochzählen
|
// Versionsnummer zerlegen und Build hochzählen
|
||||||
const parts = state.version.split(".");
|
const parts = state.appVersion.split(".");
|
||||||
if (parts.length === 3) {
|
if (parts.length === 3) {
|
||||||
parts[2] = (parseInt(parts[2]) + 1).toString(); // Build hochzählen
|
parts[2] = (parseInt(parts[2]) + 1).toString(); // Build hochzählen
|
||||||
state.version = parts.join(".");
|
state.appVersion = parts.join(".");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
48
scripts/bumpVersion.ts
Normal file
48
scripts/bumpVersion.ts
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
// /bumpVersion.ts
|
||||||
|
const fs = require("fs");
|
||||||
|
const path = require("path");
|
||||||
|
const { execSync } = require("child_process");
|
||||||
|
|
||||||
|
const envPaths = [
|
||||||
|
path.join(__dirname, "../.env.development"),
|
||||||
|
path.join(__dirname, "../.env.production"),
|
||||||
|
];
|
||||||
|
const pkgPath = path.join(__dirname, "../package.json");
|
||||||
|
|
||||||
|
// 🟢 Versionsnummer aus package.json holen
|
||||||
|
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
|
||||||
|
const [major, minor, patch] = pkg.version.split(".").map(Number);
|
||||||
|
const newVersion = `${major}.${minor}.${patch + 1}`;
|
||||||
|
|
||||||
|
// 🟢 package.json aktualisieren
|
||||||
|
pkg.version = newVersion;
|
||||||
|
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2), "utf8");
|
||||||
|
|
||||||
|
// 🟢 .env Dateien aktualisieren
|
||||||
|
envPaths.forEach((envFile) => {
|
||||||
|
if (!fs.existsSync(envFile)) return;
|
||||||
|
|
||||||
|
let content = fs.readFileSync(envFile, "utf8");
|
||||||
|
const versionRegex = /^NEXT_PUBLIC_APP_VERSION=.*$/m;
|
||||||
|
|
||||||
|
if (versionRegex.test(content)) {
|
||||||
|
content = content.replace(
|
||||||
|
versionRegex,
|
||||||
|
`NEXT_PUBLIC_APP_VERSION=${newVersion}`
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
content += `\nNEXT_PUBLIC_APP_VERSION=${newVersion}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
fs.writeFileSync(envFile, content, "utf8");
|
||||||
|
});
|
||||||
|
|
||||||
|
// 🟢 package-lock.json aktualisieren
|
||||||
|
try {
|
||||||
|
execSync("npm install --package-lock-only", { stdio: "inherit" });
|
||||||
|
} catch (error) {
|
||||||
|
console.error("❌ Fehler beim Aktualisieren der package-lock.json:", error);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`✅ Version erhöht auf ${newVersion}`);
|
||||||
Reference in New Issue
Block a user