7 Commits
7 changed files with 323 additions and 84 deletions
+42 -17
View File
@@ -218,7 +218,8 @@ in, dan valt de push in stap 3 om. Loopt dat toch mis, dan is
```powershell ```powershell
# 1. Versienummer in package.json van "x.x.x-dev" naar "x.x.x" # 1. Versienummer in package.json van "x.x.x-dev" naar "x.x.x"
# 2. Changelog.md: kop van "Niet vrijgegeven" naar "[x.x.x] - datum" # 2. Wijzigingen in Changelog.md onder de kop "## [Niet vrijgegeven]"
# (de kop zelf omzetten hoeft niet — dat doet het script)
# 3. Token staat in .env.release (zie Tokens) — of eenmalig in de shell: # 3. Token staat in .env.release (zie Tokens) — of eenmalig in de shell:
$env:GITEA_TOKEN = "<vibefinance-workstation>" $env:GITEA_TOKEN = "<vibefinance-workstation>"
@@ -226,8 +227,9 @@ $env:GITEA_TOKEN = "<vibefinance-workstation>"
.\release.ps1 -DryRun # droogloop — toont alle stappen zonder uit te voeren .\release.ps1 -DryRun # droogloop — toont alle stappen zonder uit te voeren
.\release.ps1 -NoBuild # sla docker build over, alleen tag + release .\release.ps1 -NoBuild # sla docker build over, alleen tag + release
.\release.ps1 -SkipTests # sla de testsuite over (niet aanbevolen) .\release.ps1 -SkipTests # sla de testsuite over (niet aanbevolen)
.\release.ps1 -NoChangelog # publiceer bewust zonder release-notes
# 4. Versienummer in package.json naar "x.x.(x+1)-dev" voor volgende cyclus # Klaar. Het versienummer voor de volgende cyclus zet het script zelf.
``` ```
Het script bouwt één image voor `linux/amd64` en `linux/arm64`, zodat dezelfde Het script bouwt één image voor `linux/amd64` en `linux/arm64`, zodat dezelfde
@@ -235,22 +237,36 @@ tag op een Raspberry Pi en op een x86-server werkt.
**Wat het script zelf bijwerkt** — met de hand aanpassen is dus dubbel werk: **Wat het script zelf bijwerkt** — met de hand aanpassen is dus dubbel werk:
| Bestand | Wat | | Bestand | Wat | Wanneer |
|---|---| |---|---|---|
| `frontend/package.json` | versie gelijkgetrokken met de root `package.json` | | `Changelog.md` | kop `## [Niet vrijgegeven]` → `## [x.x.x] - datum` | vóór de build |
| `README.md` | de `versie-x.x.x`-badge bovenaan | | Git-tag | `vx.x.x` op `HEAD`, gepusht naar origin | stap 4 |
| `frontend/package.json` | versie gelijkgetrokken met de root `package.json` | vóór de build |
| `README.md` | de `versie-x.x.x`-badge bovenaan | vóór de build |
| `package.json` (root) | versie → `x.x.(x+1)-dev` voor de volgende cyclus | **ná** het publiceren |
Beide gebeuren vóór de build, en een `-DryRun` meldt ze zonder te schrijven. Ze Een `-DryRun` meldt alle vier zonder te schrijven. Ze blijven na een echte
blijven na een echte release als wijziging in je working tree staan; neem ze mee release als wijziging in je working tree staan; neem ze mee in de volgende
in de volgende commit. commit.
> **De changelog-kop moet exact `## [x.x.x]` zijn.** `release.ps1` zoekt die kop De laatste staat bewust ná het publiceren: breekt de release eerder af, dan
> om de release-notes te vullen. Staat je werk nog onder `## [Niet vrijgegeven]`, schuift het versienummer niet vooruit. Bijeffect dat je moet kennen — na een
> dan vindt het script niets en valt het terug op de tekst `"Release x.x.x"` — geslaagde release staat er een `-dev` nummer in `package.json`, en de controle
> dan staat er geen inhoudelijke release-notes in Gitea en ziet een gebruiker in bovenin het script weigert een `-dev` versie. Dat sluit een dubbele publicatie
> het belletje een placeholder. Dat overkwam 0.1.9. Achteraf repareren kan met uit, maar wil je dezelfde versie bewust opnieuw releasen (bijvoorbeeld omdat een
> een `PATCH` op `/repos/<org>/<repo>/releases/<id>`, maar vóór de release tag is verdwenen), zet het nummer dan eerst zelf terug naar `x.x.x`.
> omzetten is een stuk minder werk.
> **Zonder changelog-sectie breekt het script af.** De release-notes komen uit de
> sectie `## [x.x.x]` in `Changelog.md`. Vond het script daar niets, dan
> publiceerde het stil de tekst `"Release x.x.x"` — dat gebeurde bij 0.1.9 en
> 1.0.2. Nu zet het de kop `## [Niet vrijgegeven]` zelf om, en als er ook dán
> niets over deze versie in staat, stopt het vóór de build met de melding wat je
> moet toevoegen. Wil je bewust zonder notes publiceren, gebruik `-NoChangelog`.
>
> De controle staat vóór de drie auto-updates hierboven, zodat een afgebroken
> release geen gewijzigde bestanden achterlaat. Is een release toch al gepubliceerd
> met de placeholder, dan repareer je dat met een `PATCH` op
> `/repos/<org>/<repo>/releases/<id>` met de juiste `body`.
### `.env.release` — token niet elke sessie opnieuw zetten ### `.env.release` — token niet elke sessie opnieuw zetten
@@ -283,7 +299,12 @@ docker compose pull && docker compose up -d
docker compose down -v && docker compose up -d docker compose down -v && docker compose up -d
``` ```
Pullen vereist een registry-login op die host — zie Draai dit in de map met `docker-compose.yml` en `.env`. `docker compose` zoekt
dat bestand namelijk in de huidige map en kijkt niet omhoog; staat het er niet,
dan is het antwoord `no configuration file provided: not found`. Met
`docker compose -f /pad/naar/docker-compose.yml` kun je het expliciet meegeven.
Pullen zelf werkt anoniem zolang de organisatie public is — zie
[Pullen op een deploy-machine](#pullen-op-een-deploy-machine). [Pullen op een deploy-machine](#pullen-op-een-deploy-machine).
### PostgreSQL versie-upgrade ### PostgreSQL versie-upgrade
@@ -453,6 +474,10 @@ Tags:
x.x.x-dev development — specifieke dev versie x.x.x-dev development — specifieke dev versie
``` ```
> Image-tags hebben géén `v`-prefix (`1.0.4`), Git-tags wél (`v1.0.4`). Dat is
> geen inconsistentie maar de conventie aan beide kanten: container-registries
> taggen op het kale nummer, Git-releases met `v`.
Inloggen op de registry: Inloggen op de registry:
```bash ```bash
+57 -1
View File
@@ -1,6 +1,62 @@
# Changelog # Changelog
## [Niet vrijgegeven] ## [1.0.4] - 2026-09-10
### Gewijzigd
- Git-tags krijgen weer een `v`-prefix (`v1.0.4`), net als t/m `v1.0.0`. Sinds
1.0.1 was dat `1.0.1`, `1.0.2`, `1.0.3` — en omdat Gitea de tag op de
release-pagina toont, stond daar het kale nummer terwijl de release-naam wél
`v1.0.3` was. De image-tags in de registry houden bewust géén `v`; dat is de
conventie voor container-tags. De update-check verdraagt beide: backend en
frontend strippen een leidende `v` voordat ze versies vergelijken
### Opgelost
- Het omzetten van de changelog-kop slokte de lege regel eronder op, waardoor
`## [x.x.x] - datum` direct tegen `### Toegevoegd` aan kwam te staan. Oorzaak
was `\s*$` in het zoekpatroon: `\s` matcht ook newlines. Het patroon eindigt nu
op `[ \t]*(?=\r?$)` — een lookahead, want dit bestand heeft CRLF en met alleen
`[ \t]*$` matchte de kop helemaal niet meer (de `\r` zit ertussen). Zo blijft
de match binnen één regel én blijft het regeleinde ongemoeid
## [1.0.3] - 2026-09-10
### Toegevoegd
- `release.ps1` zet de changelog-kop `## [Niet vrijgegeven]` nu zelf om naar
`## [x.x.x] - datum`, net zoals het al deed met `frontend/package.json` en de
README-badge. Handmatig omzetten hoeft dus niet meer
- Staat er ook na die omzetting niets over deze versie in `Changelog.md`, dan
breekt het script af **vóór** de build met de melding wat je moet toevoegen.
Eerder viel het stil terug op de tekst `"Release x.x.x"` en meldde het
"Gepubliceerd" — dat overkwam 0.1.9 en 1.0.2, en is achteraf alleen met een
`PATCH` op de release te herstellen. Nieuwe switch `-NoChangelog` om bewust
zonder release-notes te publiceren
- `release.ps1` zet na een geslaagde release de versie in de root
`package.json` op `x.x.(x+1)-dev`. Dat was voorheen de laatste handmatige stap
van de release-workflow. Het staat bewust ná het publiceren, zodat een
afgebroken release het nummer niet vooruit schuift
### Opgelost
- **`-DryRun` in combinatie met `-Force` verwijderde écht de Git-tag.** De twee
commando's in stap 4 (`git tag -d` en `git push origin :refs/tags/x.x.x`)
liepen niet via `Invoke-Cmd` en hadden dus geen droogloop-controle. Gitea
ruimt de release op zodra de tag verdwijnt, dus een droogloop kon een
gepubliceerde release wissen — zo is de release van 1.0.2 verloren gegaan en
opnieuw aangemaakt. Onder `-DryRun` worden beide nu alleen gemeld
### Gewijzigd
- De changelog-controle staat vóór de drie auto-updates, zodat een afgebroken
release geen gewijzigde bestanden achterlaat terwijl hij "er is niets
gepubliceerd" meldt
- Stap 5 leest de release-notes uit het geheugen in plaats van opnieuw van
schijf. Een droogloop schrijft de kop niet, en toonde daardoor de placeholder
in de payload — precies wat je met een droogloop wilt uitsluiten
- De Quick Start in `README.md` begint nu met het ophalen van
`docker-compose.yml` (clone, of alleen die twee bestanden via `raw`). Zonder
dat bestand antwoordt `docker compose pull` met `no configuration file
provided: not found`, en die stap ontbrak. Beide foutmeldingen staan er nu bij
met hun oorzaak
## [1.0.2] - 2026-09-10
### Gewijzigd ### Gewijzigd
- De update-melding op het belletje toont alleen nog de kop, de versieregel en de - De update-melding op het belletje toont alleen nog de kop, de versieregel en de
+39 -8
View File
@@ -10,7 +10,7 @@ Eigen vermogen · Schulden · Voortgang · Gebruikersbeheer
![Node.js](https://img.shields.io/badge/Node.js_22-339933?style=flat&logo=node.js&logoColor=white) ![Node.js](https://img.shields.io/badge/Node.js_22-339933?style=flat&logo=node.js&logoColor=white)
![PostgreSQL](https://img.shields.io/badge/PostgreSQL_18-4169E1?style=flat&logo=postgresql&logoColor=white) ![PostgreSQL](https://img.shields.io/badge/PostgreSQL_18-4169E1?style=flat&logo=postgresql&logoColor=white)
![Docker](https://img.shields.io/badge/Docker_Compose-2496ED?style=flat&logo=docker&logoColor=white) ![Docker](https://img.shields.io/badge/Docker_Compose-2496ED?style=flat&logo=docker&logoColor=white)
![Version](https://img.shields.io/badge/versie-1.0.1-8b5cf6?style=flat) ![Version](https://img.shields.io/badge/versie-1.0.4-8b5cf6?style=flat)
![Built with Claude](https://img.shields.io/badge/Gebouwd_met-Claude.ai-8b5cf6?style=flat&logo=anthropic&logoColor=white) ![Built with Claude](https://img.shields.io/badge/Gebouwd_met-Claude.ai-8b5cf6?style=flat&logo=anthropic&logoColor=white)
<img src="docs/screenshot-dashboard.png" alt="VibeFinance dashboard" width="820"> <img src="docs/screenshot-dashboard.png" alt="VibeFinance dashboard" width="820">
@@ -32,7 +32,25 @@ Deze applicatie is volledig ontworpen en ontwikkeld met behulp van [Claude.ai](h
De app draait in **2 containers**: `app` (Express API + gebouwde frontend) en De app draait in **2 containers**: `app` (Express API + gebouwde frontend) en
`postgres` (database). `postgres` (database).
**`.env`** — kopieer `.env.example` en vul in: **1. De bestanden op de server zetten.** `docker compose` leest
`docker-compose.yml` uit de map waarin je het commando draait, dus dat bestand
moet er eerst staan. De organisatie in Gitea is publiek, dus dit kan anoniem:
```bash
git clone https://vibehoogie.duckdns.org/Vibe/VibeFinance.git
cd VibeFinance
```
Wil je de repo niet op je server, dan zijn deze twee bestanden genoeg:
```bash
mkdir -p vibefinance && cd vibefinance
base=https://vibehoogie.duckdns.org/Vibe/VibeFinance/raw/branch/main
curl -fsSLO $base/docker-compose.yml
curl -fsSL $base/.env.example -o .env.example
```
**2. `.env` aanmaken** — kopieer `.env.example` en vul in:
```env ```env
POSTGRES_USER=vibefinance POSTGRES_USER=vibefinance
@@ -46,19 +64,25 @@ APP_PORT=3400
openssl rand -hex 64 openssl rand -hex 64
``` ```
**3. Starten:**
```bash ```bash
cp .env.example .env # en vul de waarden in cp .env.example .env # en vul de waarden in
docker compose pull && docker compose up -d docker compose pull && docker compose up -d
``` ```
De `Vibe`-organisatie in Gitea is publiek, dus een pull werkt anoniem — geen Twee foutmeldingen en wat ze betekenen:
`docker login` nodig. Krijg je toch `401 Unauthorized` of "pull access denied",
dan staat de organisatie weer op privé:
```bash - **`no configuration file provided: not found`** — je staat in een map zonder
docker login vibehoogie.duckdns.org # wachtwoord = Gitea-token met read:package `docker-compose.yml`. Controleer met `ls docker-compose.yml`, of geef het
``` bestand expliciet mee: `docker compose -f /pad/naar/docker-compose.yml up -d`.
- **`401 Unauthorized`** of **"pull access denied"** — de organisatie staat niet
meer op publiek. Dan alsnog inloggen:
```bash
docker login vibehoogie.duckdns.org # wachtwoord = Gitea-token met read:package
```
Navigeer naar `http://<server-ip>:3400` en registreer je account. De **eerste** geregistreerde gebruiker krijgt automatisch de Admin-rol. Navigeer naar `http://<server-ip>:3400` en registreer je account. De **eerste** geregistreerde gebruiker krijgt automatisch de Admin-rol.
@@ -129,6 +153,13 @@ $env:GITEA_TOKEN = "<token met write:package + write:repository>"
Draait de tests, bouwt het app-image voor `amd64` + `arm64` (Raspberry Pi), Draait de tests, bouwt het app-image voor `amd64` + `arm64` (Raspberry Pi),
pusht naar de registry, zet de Git-tag en publiceert de Gitea-release. pusht naar de registry, zet de Git-tag en publiceert de Gitea-release.
Het script regelt ook het bijwerken eromheen: de changelog-kop
`## [Niet vrijgegeven]` wordt `## [x.x.x] - datum`, de versie in
`frontend/package.json` en de badge hierboven gaan mee, en ná het publiceren
zet het de root `package.json` op `x.x.(x+1)-dev` voor de volgende cyclus.
Beschrijft de changelog niets over deze versie, dan stopt het script vóór de
build — anders zou de release met een placeholder als notes online komen.
--- ---
## 🗂️ Functionaliteit ## 🗂️ Functionaliteit
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "vibefinance-frontend", "name": "vibefinance-frontend",
"version": "1.0.2-dev", "version": "1.0.4",
"private": true, "private": true,
"type": "module", "type": "module",
"scripts": { "scripts": {
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "vibefinance", "name": "vibefinance",
"version": "1.0.2", "version": "1.0.5",
"description": "VibeFinance — persoonlijk vermogensbeheer", "description": "VibeFinance — persoonlijk vermogensbeheer",
"private": true, "private": true,
"repository": "https://vibehoogie.duckdns.org/vibe/VibeFinance", "repository": "https://vibehoogie.duckdns.org/vibe/VibeFinance",
+170 -44
View File
@@ -9,6 +9,16 @@
# .\release.ps1 -SkipTests # sla de testsuite over (niet aanbevolen) # .\release.ps1 -SkipTests # sla de testsuite over (niet aanbevolen)
# .\release.ps1 -DryRun # toon alle commando's zonder iets uit te voeren # .\release.ps1 -DryRun # toon alle commando's zonder iets uit te voeren
# .\release.ps1 -Force # sla conflictcontrole over, overschrijf tags # .\release.ps1 -Force # sla conflictcontrole over, overschrijf tags
# .\release.ps1 -NoChangelog # publiceer bewust zonder release-notes
#
# Het script werkt zelf vier dingen bij, dus die hoef je niet met de hand te
# doen: de changelog-kop `## [Niet vrijgegeven]` -> `## [x.x.x] - datum`, de
# versie in frontend/package.json, de versiebadge in README.md, en ná het
# publiceren de versie in de root package.json -> `x.x.(x+1)-dev`.
#
# LET OP bij -Force: dat verwijdert de bestaande tag lokaal en op origin, en
# Gitea gooit de bijbehorende release daarmee weg. Onder -DryRun wordt dat
# alleen gemeld (dat was eerder niet zo — zie stap 4).
# #
# Vereisten: # Vereisten:
# - Docker Desktop actief # - Docker Desktop actief
@@ -16,6 +26,9 @@
# - docker buildx builder actief: docker buildx create --use # - docker buildx builder actief: docker buildx create --use
# - Git geinstalleerd en working directory is de repo root # - Git geinstalleerd en working directory is de repo root
# - root package.json bevat een schoon versienummer ZONDER -dev suffix # - root package.json bevat een schoon versienummer ZONDER -dev suffix
# - Changelog.md beschrijft deze versie, onder `## [Niet vrijgegeven]` of
# onder een kop `## [x.x.x]`; anders breekt het script af (-NoChangelog
# omzeilt dat)
# - GITEA_TOKEN in de omgeving (token met release-rechten) voor stap 5, # - GITEA_TOKEN in de omgeving (token met release-rechten) voor stap 5,
# de Gitea-release waar de update-melding in de app op afgaat # de Gitea-release waar de update-melding in de app op afgaat
@@ -23,7 +36,10 @@ param(
[switch]$NoBuild, [switch]$NoBuild,
[switch]$SkipTests, [switch]$SkipTests,
[switch]$DryRun, [switch]$DryRun,
[switch]$Force [switch]$Force,
# Releasen zonder inhoudelijke release-notes. Zonder deze switch breekt het
# script af wanneer de changelog niets over deze versie zegt.
[switch]$NoChangelog
) )
$ErrorActionPreference = "Stop" $ErrorActionPreference = "Stop"
@@ -75,42 +91,13 @@ if ($appVersion -match "-dev$") {
exit 1 exit 1
} }
# ── Versie synchroniseren naar frontend/package.json ────────────────────── # Git-tag met `v`-prefix, net als de release-naam hieronder en net als de tags
# Een droogloop schrijft hier niet: anders laat -DryRun een gewijzigd bestand # t/m v1.0.0. Gitea toont de tag op de release-pagina, dus zonder prefix stond
# achter, en tagt de echte release daarna een vervuilde working tree. # daar het kale nummer. De image-tags in de registry houden bewust géén `v`:
$frontendPkgPath = Join-Path $PSScriptRoot "frontend/package.json" # dat is de conventie voor container-tags.
$frontendPkg = Get-Content $frontendPkgPath -Raw | ConvertFrom-Json # De update-check verdraagt beide: zowel backend/src/routes/update.js als
if ($frontendPkg.version -ne $appVersion) { # useUpdateCheck.js strippen een leidende `v` voordat ze versies vergelijken.
if ($DryRun) { $gitTag = "v$appVersion"
Write-Host "[DRY-RUN] Versie naar frontend synchroniseren: $($frontendPkg.version) -> $appVersion" -ForegroundColor Yellow
} else {
$frontendPkg.version = $appVersion
[System.IO.File]::WriteAllText($frontendPkgPath, ($frontendPkg | ConvertTo-Json -Depth 10))
Write-Host "Versie gesynchroniseerd naar frontend: $appVersion" -ForegroundColor Green
}
}
# ── Versiebadge in README.md ──────────────────────────────────────────────
# Anders loopt die badge stil achter: hij stond drie releases achter voordat
# dit erin zat, en het script kent het nummer toch al. Zelfde regel als
# hierboven: een droogloop meldt het, maar schrijft niet.
$readmePath = Join-Path $PSScriptRoot "README.md"
if (Test-Path $readmePath) {
$readme = [System.IO.File]::ReadAllText($readmePath)
$patroon = "badge/versie-[^-]+-"
$nieuw = "badge/versie-$appVersion-"
$huidig = [regex]::Match($readme, $patroon)
if ($huidig.Success -and $huidig.Value -ne $nieuw) {
if ($DryRun) {
Write-Host "[DRY-RUN] Versiebadge in README.md: $($huidig.Value) -> $nieuw" -ForegroundColor Yellow
} else {
[System.IO.File]::WriteAllText($readmePath, ($readme -replace $patroon, $nieuw))
Write-Host "Versiebadge in README.md bijgewerkt: $appVersion" -ForegroundColor Green
}
}
}
$gitTag = "$appVersion"
# ── Registry tags (één image voor frontend + backend) ───────────────────── # ── Registry tags (één image voor frontend + backend) ─────────────────────
$appBase = "$registry/$appImage" $appBase = "$registry/$appImage"
@@ -151,12 +138,13 @@ function Write-Step {
Write-Host "── $Label" -ForegroundColor Cyan Write-Host "── $Label" -ForegroundColor Cyan
} }
# Haalt de sectie van deze versie uit Changelog.md als release-notes. # Haalt de sectie van deze versie uit changelog-tekst. Werkt op een string en
function Get-ChangelogSection { # niet op het bestand, zodat een droogloop kan valideren tegen de kop die hij
param([string]$Version) # zou schrijven zonder die daadwerkelijk te schrijven.
$path = Join-Path $PSScriptRoot "Changelog.md" function Get-ChangelogSectionFromText {
if (-not (Test-Path $path)) { return "" } param([string]$Text, [string]$Version)
$lines = Get-Content $path if (-not $Text) { return "" }
$lines = $Text -split "\r?\n"
$start = -1 $start = -1
$needle = "^##\s*\[" + [regex]::Escape($Version) + "\]" $needle = "^##\s*\[" + [regex]::Escape($Version) + "\]"
for ($i = 0; $i -lt $lines.Count; $i++) { for ($i = 0; $i -lt $lines.Count; $i++) {
@@ -172,6 +160,99 @@ function Get-ChangelogSection {
return (($out -join "`n").Trim()) return (($out -join "`n").Trim())
} }
# ── Changelog-kop vrijgeven ───────────────────────────────────────────────
# De release-notes komen uit de sectie `## [x.x.x]` in Changelog.md. Stond het
# werk nog onder `## [Niet vrijgegeven]`, dan vond het script niets en werd stil
# de placeholder "Release x.x.x" gepubliceerd — dat gebeurde bij 0.1.9 en 1.0.2,
# en is achteraf alleen met een PATCH op de release te herstellen. Daarom zet het
# script de kop nu zelf om, en breekt het af als er niets te melden valt.
# Zelfde regel als bij de andere auto-updates: een droogloop meldt, maar schrijft
# niet.
$changelogPath = Join-Path $PSScriptRoot "Changelog.md"
$nieuweKop = "## [$appVersion] - $(Get-Date -Format 'yyyy-MM-dd')"
$changelogTxt = if (Test-Path $changelogPath) { [System.IO.File]::ReadAllText($changelogPath) } else { "" }
$kopPatroon = "(?m)^##\s*\[" + [regex]::Escape($appVersion) + "\]"
# Niet `\s*$`: `\s` matcht ook newlines, en dan slokt de match de lege regel ná
# de kop op — die verdween daardoor bij het omzetten. En niet `[ \t]*$` alleen:
# dit bestand heeft CRLF (zie .gitattributes), dus `$` staat achter een `\r` die
# geen space of tab is. De lookahead laat het regeleinde buiten de match, zodat
# de CRLF intact blijft.
$onderwegPatroon = "(?m)^##[ \t]*\[[ \t]*Niet vrijgegeven[ \t]*\][ \t]*(?=\r?$)"
# Eerst alleen in het geheugen omzetten. Schrijven gebeurt na de controle
# hieronder: bij een lege `[Niet vrijgegeven]`-sectie zou de kop anders al
# vervangen zijn terwijl het script daarna afbreekt, en dan blijft er een
# aangepaste changelog achter bij een release die niet doorging.
$kopOmzetten = ($changelogTxt -notmatch $kopPatroon -and $changelogTxt -match $onderwegPatroon)
if ($kopOmzetten) {
# $nieuweKop bevat geen '$', dus veilig als vervangingstekst.
$changelogTxt = [regex]::Replace($changelogTxt, $onderwegPatroon, $nieuweKop)
}
if (-not (Get-ChangelogSectionFromText $changelogTxt $appVersion) -and -not $NoChangelog) {
Write-Host ""
Write-Host "Changelog.md zegt niets over $appVersion." -ForegroundColor Red
Write-Host ""
Write-Host "Zonder notes komt er alleen de tekst 'Release $appVersion' in de Gitea-release," -ForegroundColor Yellow
Write-Host "en dat is achteraf alleen met een PATCH op de release te herstellen." -ForegroundColor Yellow
Write-Host ""
Write-Host "Zet je wijzigingen in Changelog.md onder een kop:" -ForegroundColor White
Write-Host " ## [Niet vrijgegeven]" -ForegroundColor White
Write-Host "Die zet dit script bij de volgende run zelf om naar '$nieuweKop'." -ForegroundColor White
Write-Host ""
Write-Host "Bewust zonder release-notes publiceren? Draai met -NoChangelog." -ForegroundColor DarkGray
Write-Host ""
Write-Host "Er is niets gepubliceerd." -ForegroundColor DarkGray
exit 1
}
# De controle is doorstaan, dus nu pas schrijven.
if ($kopOmzetten) {
if ($DryRun) {
Write-Host "[DRY-RUN] Changelog-kop vrijgeven: '## [Niet vrijgegeven]' -> '$nieuweKop'" -ForegroundColor Yellow
} else {
[System.IO.File]::WriteAllText($changelogPath, $changelogTxt)
Write-Host "Changelog-kop vrijgegeven: $nieuweKop" -ForegroundColor Green
}
}
# ── Versie synchroniseren naar frontend/package.json ──────────────────────
# Staat na de changelog-controle: anders laat een afgebroken release wél een
# gewijzigde working tree achter terwijl hij "niets gepubliceerd" meldt.
# Een droogloop schrijft hier niet, om dezelfde reden.
$frontendPkgPath = Join-Path $PSScriptRoot "frontend/package.json"
$frontendPkg = Get-Content $frontendPkgPath -Raw | ConvertFrom-Json
if ($frontendPkg.version -ne $appVersion) {
if ($DryRun) {
Write-Host "[DRY-RUN] Versie naar frontend synchroniseren: $($frontendPkg.version) -> $appVersion" -ForegroundColor Yellow
} else {
$frontendPkg.version = $appVersion
[System.IO.File]::WriteAllText($frontendPkgPath, ($frontendPkg | ConvertTo-Json -Depth 10))
Write-Host "Versie gesynchroniseerd naar frontend: $appVersion" -ForegroundColor Green
}
}
# ── Versiebadge in README.md ──────────────────────────────────────────────
# Anders loopt die badge stil achter: hij stond drie releases achter voordat
# dit erin zat, en het script kent het nummer toch al. Zelfde regel als
# hierboven: een droogloop meldt het, maar schrijft niet.
$readmePath = Join-Path $PSScriptRoot "README.md"
if (Test-Path $readmePath) {
$readme = [System.IO.File]::ReadAllText($readmePath)
$patroon = "badge/versie-[^-]+-"
$nieuw = "badge/versie-$appVersion-"
$huidig = [regex]::Match($readme, $patroon)
if ($huidig.Success -and $huidig.Value -ne $nieuw) {
if ($DryRun) {
Write-Host "[DRY-RUN] Versiebadge in README.md: $($huidig.Value) -> $nieuw" -ForegroundColor Yellow
} else {
[System.IO.File]::WriteAllText($readmePath, ($readme -replace $patroon, $nieuw))
Write-Host "Versiebadge in README.md bijgewerkt: $appVersion" -ForegroundColor Green
}
}
}
# ── Samenvatting ─────────────────────────────────────────────────────────── # ── Samenvatting ───────────────────────────────────────────────────────────
Write-Host "" Write-Host ""
Write-Host "════════════════════════════════════════" -ForegroundColor Cyan Write-Host "════════════════════════════════════════" -ForegroundColor Cyan
@@ -365,14 +446,24 @@ if (-not $NoBuild) {
Write-Step "[4/5] Git-tag aanmaken en pushen" Write-Step "[4/5] Git-tag aanmaken en pushen"
if ($Force) { if ($Force) {
# LET OP: deze twee commando's gingen niet via Invoke-Cmd en hadden dus geen
# -DryRun-controle. Een `-DryRun -Force` verwijderde daardoor écht de tag,
# lokaal en op origin — en Gitea ruimt de release op zodra de tag verdwijnt.
# Zo is de release van 1.0.2 verloren gegaan.
if ($DryRun) {
Write-Host "[DRY-RUN] git tag -d $gitTag" -ForegroundColor Yellow
Write-Host "[DRY-RUN] git push origin :refs/tags/$gitTag" -ForegroundColor Yellow
} else {
Write-Host "Bestaande lokale tag verwijderen (indien aanwezig)..." -ForegroundColor Yellow Write-Host "Bestaande lokale tag verwijderen (indien aanwezig)..." -ForegroundColor Yellow
$ErrorActionPreference = "SilentlyContinue" $ErrorActionPreference = "SilentlyContinue"
git tag -d $gitTag 2>$null | Out-Null git tag -d $gitTag 2>$null | Out-Null
$ErrorActionPreference = "Stop" $ErrorActionPreference = "Stop"
Write-Host "Bestaande remote tag verwijderen (indien aanwezig)..." -ForegroundColor Yellow Write-Host "Bestaande remote tag verwijderen (indien aanwezig)..." -ForegroundColor Yellow
Write-Host " Gitea verwijdert de bijbehorende release mee." -ForegroundColor DarkGray
$ErrorActionPreference = "SilentlyContinue" $ErrorActionPreference = "SilentlyContinue"
git push origin ":refs/tags/$gitTag" 2>$null | Out-Null git push origin ":refs/tags/$gitTag" 2>$null | Out-Null
$ErrorActionPreference = "Stop" $ErrorActionPreference = "Stop"
}
} }
Write-Host "Git-tag aanmaken: $gitTag" -ForegroundColor White Write-Host "Git-tag aanmaken: $gitTag" -ForegroundColor White
@@ -405,7 +496,10 @@ if (-not $releaseApi) {
Write-Host "Geen GITEA_TOKEN in de omgeving — release overgeslagen." -ForegroundColor Yellow Write-Host "Geen GITEA_TOKEN in de omgeving — release overgeslagen." -ForegroundColor Yellow
Write-Host " Zonder release ziet de app geen update-melding voor $appVersion." -ForegroundColor DarkGray Write-Host " Zonder release ziet de app geen update-melding voor $appVersion." -ForegroundColor DarkGray
} else { } else {
$notes = Get-ChangelogSection $appVersion # Uit $changelogTxt en niet opnieuw van schijf: in een droogloop is de kop
# nog niet geschreven, en dan zou de payload hier de placeholder tonen —
# precies wat je met een droogloop wilt uitsluiten.
$notes = Get-ChangelogSectionFromText $changelogTxt $appVersion
if (-not $notes) { $notes = "Release $appVersion" } if (-not $notes) { $notes = "Release $appVersion" }
$payload = @{ $payload = @{
tag_name = $gitTag tag_name = $gitTag
@@ -451,6 +545,38 @@ Write-Host " Git-tag: $gitTag -> origin" -ForegroundColor Green
Write-Host "════════════════════════════════════════" -ForegroundColor Cyan Write-Host "════════════════════════════════════════" -ForegroundColor Cyan
Write-Host "" Write-Host ""
# ── Versie naar de volgende dev-cyclus ────────────────────────────────────
# Was voorheen stap 4 met de hand. Gebeurt hier, ná het publiceren, zodat een
# afgebroken release het versienummer niet vooruit zet. Bijkomend voordeel: de
# `-dev` suffix laat dezelfde release niet nog eens draaien (de controle boven
# in dit script weigert een `-dev` versie), dus een dubbele publicatie is
# meteen uitgesloten. Wil je bewust opnieuw releasen, zet het nummer dan zelf
# terug.
if ($appVersion -match '^(\d+)\.(\d+)\.(\d+)$') {
$volgende = "{0}.{1}.{2}-dev" -f $Matches[1], $Matches[2], ([int]$Matches[3] + 1)
$rootPkgPath = Join-Path $PSScriptRoot "package.json"
if ($DryRun) {
Write-Host "[DRY-RUN] Versie in package.json: $appVersion -> $volgende" -ForegroundColor Yellow
} else {
# Gerichte tekstvervanging in plaats van ConvertTo-Json: dat zou het hele
# bestand herschrijven en de opmaak van de andere velden aantasten.
$rootTxt = [System.IO.File]::ReadAllText($rootPkgPath)
$treffer = [regex]::Match($rootTxt, '"version"\s*:\s*"' + [regex]::Escape($appVersion) + '"')
if ($treffer.Success) {
$rootTxt = $rootTxt.Remove($treffer.Index, $treffer.Length).Insert($treffer.Index, '"version": "' + $volgende + '"')
[System.IO.File]::WriteAllText($rootPkgPath, $rootTxt)
Write-Host "Versie in package.json naar de volgende cyclus: $volgende" -ForegroundColor Green
Write-Host " Commit dit mee, samen met de changelog-kop en de README-badge." -ForegroundColor DarkGray
Write-Host ""
} else {
Write-Host "Kon '$appVersion' niet terugvinden in package.json — versie niet bijgewerkt." -ForegroundColor Yellow
}
}
} else {
Write-Host "Versie '$appVersion' is geen x.y.z — volgende dev-versie niet automatisch gezet." -ForegroundColor Yellow
}
# Expliciete 0: anders erft de caller de exitcode van het laatste # Expliciete 0: anders erft de caller de exitcode van het laatste
# docker-commando (bijv. de registry-check). # docker-commando (bijv. de registry-check).
exit 0 exit 0
+1
View File
@@ -9,6 +9,7 @@
# ./release.sh -SkipTests # sla de testsuite over (niet aanbevolen) # ./release.sh -SkipTests # sla de testsuite over (niet aanbevolen)
# ./release.sh -DryRun # toon alle commando's zonder iets uit te voeren # ./release.sh -DryRun # toon alle commando's zonder iets uit te voeren
# ./release.sh -Force # sla conflictcontrole over, overschrijf tags # ./release.sh -Force # sla conflictcontrole over, overschrijf tags
# ./release.sh -NoChangelog # publiceer bewust zonder release-notes
# #
# Combinaties: # Combinaties:
# ./release.sh -Force -NoBuild # ./release.sh -Force -NoBuild