From eec197130244ad62f5ab0872094d10fac4906d15 Mon Sep 17 00:00:00 2001 From: harald Date: Mon, 7 Sep 2026 16:32:41 +0200 Subject: [PATCH] feat(release): setup release management with SemVer, packaging script, and Gitea CI/CD --- .gitea/workflows/release.yaml | 66 ++++++++++++++++++++++++ .gitignore | 1 + CHANGELOG.md | 34 +++++++++++++ Cargo.toml | 8 ++- LICENSE | 21 ++++++++ README.md | 21 ++++++++ scripts/package-release.ps1 | 95 +++++++++++++++++++++++++++++++++++ 7 files changed, 245 insertions(+), 1 deletion(-) create mode 100644 .gitea/workflows/release.yaml create mode 100644 CHANGELOG.md create mode 100644 LICENSE create mode 100644 scripts/package-release.ps1 diff --git a/.gitea/workflows/release.yaml b/.gitea/workflows/release.yaml new file mode 100644 index 0000000..f33430a --- /dev/null +++ b/.gitea/workflows/release.yaml @@ -0,0 +1,66 @@ +name: Sanctum Release + +on: + push: + tags: + - 'v*' + +jobs: + build: + name: Build & Release (Windows x86_64) + runs-on: windows-latest + steps: + - name: Checkout Code + uses: actions/checkout@v4 + + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@stable + with: + targets: x86_64-pc-windows-msvc + + - name: Run Tests + run: cargo test --all --verbose + + - name: Build Release Binary + run: cargo build --release + + - name: Package Artifacts + id: package + shell: pwsh + run: | + $Tag = "${{ gitea.ref_name }}" + $DistDir = "dist" + $PackageName = "sanctum-${Tag}-windows-x86_64" + $StagingDir = "${DistDir}/${PackageName}" + $ZipFile = "${DistDir}/${PackageName}.zip" + + New-Item -ItemType Directory -Path $StagingDir -Force | Out-Null + Copy-Item "target/release/sanctum.exe" "$StagingDir/" + Copy-Item "README.md" "$StagingDir/" + Copy-Item "LICENSE" "$StagingDir/" + Copy-Item "CHANGELOG.md" "$StagingDir/" + + Compress-Archive -Path "$StagingDir/*" -DestinationPath $ZipFile -Force + + $ZipHash = (Get-FileHash -Path $ZipFile -Algorithm SHA256).Hash.ToLower() + $ExeHash = (Get-FileHash -Path "target/release/sanctum.exe" -Algorithm SHA256).Hash.ToLower() + + @("$ZipHash ${PackageName}.zip", "$ExeHash sanctum.exe") | Set-Content -Path "${DistDir}/SHA256SUMS.txt" -Encoding utf8 + + + echo "ZIP_FILE=$ZipFile" >> $env:GITHUB_OUTPUT + echo "PACKAGE_NAME=$PackageName" >> $env:GITHUB_OUTPUT + + - name: Create Gitea Release + uses: softprops/action-gh-release@v2 + if: startsWith(github.ref, 'refs/tags/') + with: + files: | + dist/*.zip + dist/SHA256SUMS.txt + target/release/sanctum.exe + body_path: CHANGELOG.md + draft: false + prerelease: false + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index 72342f4..3043383 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /target +/dist *.sanctum *.log diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..072e165 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,34 @@ +# Changelog + +Alle nennenswerten Änderungen an diesem Projekt werden in dieser Datei dokumentiert. + +Das Format basiert auf [Keep a Changelog](https://keepachangelog.com/de/1.1.0/) +und dieses Projekt folgt den Richtlinien von [Semantic Versioning](https://semver.org/lang/de/). + +## [Unreleased] + +## [0.1.0] - 2026-09-07 + +### Added +- **Sanctum CLI (`sanctum.exe`)**: Eigenständige, hochperformante Userland-Anwendung zur Verwaltung verschlüsselter Ein-Datei-Container unter Windows 10/11. +- **Kryptografie & Schlüsselableitung**: + - Argon2id KDF ($M=64\,\text{MB}, T=3, P=4$) zur Ableitung des KEK aus dem Master-Passwort. + - AES-256-GCM DEK-Wrapping mit Nonce und Authentifizierungs-Tag. + - 1-MB Chunk AEAD-Verschlüsselung mit AAD (`node_id || chunk_index`) zum vollständigen Schutz gegen Swap- und Block-Vertauschungsangriffe. + - Speichersicherheit: Verwendung von `zeroize::Zeroizing` für sensible kryptografische Schlüssel im RAM. +- **Speicherschicht**: + - SQLite3-Container im WAL-Modus (`PRAGMA journal_mode = WAL;`, `PRAGMA synchronous = NORMAL;`, `PRAGMA page_size = 8192;`). + - Automatische Checkpoints (`PRAGMA wal_checkpoint(TRUNCATE)`). + - Dynamisches Wachstum bis über 100 GB in exakt einer Host-Datei (`.sanctum`). +- **WebDAV & Windows Explorer Integration**: + - Eingebetteter WebDAV-Server auf `127.0.0.1` (`dav-server` + `hyper`). + - Automatisches Einhängen über Windows-Bordmittel (`net use : http://127.0.0.1:/ /persistent:no`) ohne Administratorrechte und ohne Treiber (kein WinFsp, kein Dokan). + - Volle Unterstützung für `DavFileSystem`, `DavFile`, Metadaten und `symlink_metadata` für WebDAV MOVE/Rename-Operationen im Explorer. + - Saubere URL-Decodierung bei Pfaden mit Leerzeichen, Kommas und Umlauten. +- **CLI & UX**: + - Automatische Windows-Konsolen-Initialisierung auf UTF-8 (`CP 65001`) und Virtual Terminal Processing. + - Strukturierte Statusausgabe (`init`, `mount`, `unmount`) mit Status-Boxen und Fortschrittsanzeige. + - Automatischer Shutdown-Handler (`Ctrl+C`) mit sicherem Aushängen des Netzlaufwerks und WAL-Checkpointing. +- **Release Management**: + - Automatisches Packaging-Skript `scripts/package-release.ps1` mit SHA-256 Checksummen. + - Gitea Actions CI/CD Pipeline (`.gitea/workflows/release.yaml`). diff --git a/Cargo.toml b/Cargo.toml index 4d3a9be..9253af1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,8 +2,14 @@ name = "sanctum" version = "0.1.0" edition = "2021" -authors = ["Sanctum Engineering Team"] +authors = ["Harald Pansi ", "Sanctum Engineering Team"] description = "Verschlüsselter Ein-Datei-Container unter Windows im reinen Userland via WebDAV" +license = "MIT" +repository = "https://gitea.pansi.eu/harald/sanctum" +homepage = "https://gitea.pansi.eu/harald/sanctum" +readme = "README.md" +keywords = ["encryption", "container", "windows", "webdav", "security"] +categories = ["cryptography", "command-line-utilities", "filesystem"] [dependencies] clap = { version = "4.5", features = ["derive"] } diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..8aa6f4e --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Harald Pansi + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index 0c2face..f4db56a 100644 --- a/README.md +++ b/README.md @@ -70,3 +70,24 @@ Zum Beenden und sicheren Trennen einfach `Ctrl+C` im Terminal drücken. ```powershell sanctum.exe unmount --drive S ``` + +--- + +## 📦 Release Packaging + +Um ein vollständiges Release-Paket mit Tests, komprimiertem ZIP-Archiv und SHA-256 Prüfsummen zu erstellen: + +```powershell +powershell -ExecutionPolicy Bypass -File .\scripts\package-release.ps1 +``` + +Das fertige Paket liegt in `dist/` bereit: +- `dist/sanctum-v0.1.0-windows-x86_64.zip` +- `dist/SHA256SUMS.txt` + +--- + +## 📄 Lizenz & Changelog + +- Lizenziert unter der [MIT License](LICENSE). +- Details zu allen Versionen und Änderungen findest du im [CHANGELOG.md](CHANGELOG.md). diff --git a/scripts/package-release.ps1 b/scripts/package-release.ps1 new file mode 100644 index 0000000..327894b --- /dev/null +++ b/scripts/package-release.ps1 @@ -0,0 +1,95 @@ +param ( + [switch]$SkipTests = $false +) + +$ErrorActionPreference = "Stop" + +# Repository-Wurzelverzeichnis ermitteln +$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path +$ProjectRoot = Split-Path -Parent $ScriptDir +Set-Location $ProjectRoot + +# Toolchain-Pfade sicherstellen (WinLibs GCC + Cargo) +$env:PATH = "C:\Users\pansih\AppData\Local\Microsoft\WinGet\Packages\BrechtSanders.WinLibs.POSIX.UCRT_Microsoft.Winget.Source_8wekyb3d8bbwe\mingw64\bin;C:\Users\pansih\.cargo\bin;C:\Program Files\Git\cmd;C:\Users\pansih\AppData\Local\Microsoft\WinGet\Links;" + $env:PATH + +# Version aus Cargo.toml auslesen +$CargoToml = Get-Content (Join-Path $ProjectRoot "Cargo.toml") -Raw +if ($CargoToml -match 'version\s*=\s*"([^"]+)"') { + $Version = $matches[1] +} else { + Write-Error "Konnte Versionsnummer nicht aus Cargo.toml ermitteln." + exit 1 +} + +Write-Host "============================================================" -ForegroundColor Cyan +Write-Host " Sanctum Release Packaging v$Version (Windows x86_64)" -ForegroundColor Cyan +Write-Host "============================================================" -ForegroundColor Cyan + +# 1. Tests ausfuehren +if (-not $SkipTests) { + Write-Host "`n[1/4] Fuehre Testsuite aus (cargo test --all)..." -ForegroundColor Yellow + cargo test --all + if ($LASTEXITCODE -ne 0) { + Write-Error "Tests fehlgeschlagen! Release-Erstellung abgebrochen." + exit $LASTEXITCODE + } + Write-Host "[OK] Alle Tests erfolgreich bestanden." -ForegroundColor Green +} else { + Write-Host "`n[1/4] Tests uebersprungen (-SkipTests)." -ForegroundColor DarkYellow +} + +# 2. Release-Binary bauen +Write-Host "`n[2/4] Kompiliere Release-Binary mit LTO (cargo build --release)..." -ForegroundColor Yellow +cargo build --release +if ($LASTEXITCODE -ne 0) { + Write-Error "Release-Build fehlgeschlagen!" + exit $LASTEXITCODE +} +Write-Host "[OK] Release-Binary erfolgreich gebaut." -ForegroundColor Green + +# 3. Release-Verzeichnisstruktur vorbereiten +Write-Host "`n[3/4] Erstelle Distributionspaket..." -ForegroundColor Yellow + +$DistDir = Join-Path $ProjectRoot "dist" +$PackageName = "sanctum-v$Version-windows-x86_64" +$StagingDir = Join-Path $DistDir $PackageName +$ZipFile = Join-Path $DistDir "$PackageName.zip" + +if (Test-Path $DistDir) { + Remove-Item $DistDir -Recurse -Force +} +New-Item -ItemType Directory -Path $StagingDir -Force | Out-Null + +$ExeSource = Join-Path $ProjectRoot "target\release\sanctum.exe" +Copy-Item $ExeSource (Join-Path $StagingDir "sanctum.exe") +Copy-Item (Join-Path $ProjectRoot "README.md") (Join-Path $StagingDir "README.md") +Copy-Item (Join-Path $ProjectRoot "LICENSE") (Join-Path $StagingDir "LICENSE") +Copy-Item (Join-Path $ProjectRoot "CHANGELOG.md") (Join-Path $StagingDir "CHANGELOG.md") + +# ZIP-Archiv schnueren +Compress-Archive -Path "$StagingDir\*" -DestinationPath $ZipFile -Force +Remove-Item $StagingDir -Recurse -Force + +Write-Host "[OK] Archiv erstellt: $ZipFile" -ForegroundColor Green + +# 4. SHA-256 Pruefsummen generieren +Write-Host "`n[4/4] Generiere SHA-256 Pruefsummen..." -ForegroundColor Yellow + +$ZipHash = (Get-FileHash -Path $ZipFile -Algorithm SHA256).Hash.ToLower() +$ExeHash = (Get-FileHash -Path $ExeSource -Algorithm SHA256).Hash.ToLower() + +$ChecksumFile = Join-Path $DistDir "SHA256SUMS.txt" +@("$ZipHash $PackageName.zip", "$ExeHash sanctum.exe") | Set-Content -Path $ChecksumFile -Encoding utf8 + +Write-Host "[OK] Pruefsummen in SHA256SUMS.txt gespeichert." -ForegroundColor Green + +# Abschluss-Zusammenfassung +$ZipSize = (Get-Item $ZipFile).Length / 1MB +Write-Host "`n============================================================" -ForegroundColor Green +Write-Host " Sanctum Release v$Version erfolgreich gepackt!" -ForegroundColor Green +Write-Host "============================================================" -ForegroundColor Green +Write-Host " Archiv: dist\$PackageName.zip ($([math]::Round($ZipSize, 2)) MB)" +Write-Host " ZIP SHA-256: $ZipHash" +Write-Host " EXE SHA-256: $ExeHash" +Write-Host " Checksum-File: dist\SHA256SUMS.txt" +Write-Host "`nBereit fuer Gitea Release / Verteilung.`n"