diff --git a/CHANGELOG.md b/CHANGELOG.md index 40c34cb..df425d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -51,7 +51,7 @@ Notable changes to the Evomedia.net Token Savers. ### Added - **Versioned releases: `zversion`, `zrelease`, `releases/`** — the toolkit now - carries one version in the SmartPlant 5-segment scheme, + carries one version in a 5-segment scheme, `v{major}.{rc}.{beta}.{alpha}.{build}`. `zversion bump` (one per PR / defect fix) and `zversion bump-stage release|rc|beta|alpha` (zeroes every lower segment) rewrite `build-version.json`, stamp `# Version:` into every script diff --git a/CHANGELOG.txt b/CHANGELOG.txt new file mode 100644 index 0000000..5a4bd0e --- /dev/null +++ b/CHANGELOG.txt @@ -0,0 +1,150 @@ +Evomedia.net Token Savers — https://github.com/evomedia-net/evo.zscripts +Created by Kelly Michels · dev@evomedia.net +Licensed under the MIT License. See LICENSE. + +Changelog +========= + +Notable changes to the Evomedia.net Token Savers. + +Unreleased +---------- + +Fixed +----- +- Deploys can no longer hang forever on an ssh prompt — every + deploy-path ssh/scp now carries BatchMode=yes plus connect and + keepalive timeouts (Get-Ec2SshOpts in ZHelpers.ps1). Without + BatchMode, ssh prompts for a passphrase or password and waits + indefinitely; because the deploy pipes stderr through the pipeline, the + prompt never reaches the screen and the run just stops under whatever + step label printed last, with no explanation. Now it fails immediately — + there is no prompt on this path worth answering. ServerAlive* bounds a + session that dies mid-command (dropped VPN, sleeping laptop, rebooting + host) to about a minute instead of hanging. +- Vendored archives survive the archive filter — files under a + vendor/ directory are exempt from the "no archives in the zip" rule. + A project that vendors a dependency as vendor/*.tgz needs it in the + deploy zip; dropping it makes a Dockerfile's COPY vendor ./vendor + fail at image build, a confusing way to learn the filter ate a build + input. +- unzip install is idempotent — the remote step ran + apt-get update && apt-get install -y unzip on every deploy; it now + checks command -v unzip first and skips the apt round-trip when the + binary is already there. +- zdeploy edge kind now ships asset subdirectories (#42) — the edge + deploy uploaded top-level files only, so a project self-hosting assets + in folders (fonts/, vendor/) lost them on every deploy: docker + created empty root-owned mount points and nginx served 404s from them, + which shows up as fonts silently falling back and vendored JS never + loading. Every subdirectory except nginx-logs/ and .git/ now ships + recursively, and the ensure edge dir chown is recursive so scp into + docker-created root-owned dirs cannot fail. +- zdeploy no longer deletes operator-managed files on deploy (#2) — + the project-directory replacement preserved only ./.env, silently + destroying every other server-side file (.env.db, staged signing + keys, certs) on every deploy. All .env* files at the project root are + now preserved by default, plus anything listed in the new + deploy.preserve array (files or directories); the vite kind, which + previously preserved nothing, gets the same protection. Found the hard + way: a first production deploy of an auth service wiped its staged DB + credentials and RSA signing keys. + +Added +----- +- Versioned releases: zversion, zrelease, releases/ — the toolkit now + carries one version in a 5-segment scheme, + v{major}.{rc}.{beta}.{alpha}.{build}. zversion bump (one per PR / defect + fix) and zversion bump-stage release|rc|beta|alpha (zeroes every lower + segment) rewrite build-version.json, stamp # Version: into every script + header — so a lone copied script still says which release it came from — and + regenerate CHECKSUMS.txt in the same step. zrelease packages the current + version as releases/zscripts-.zip with a .sha256 beside it: one + hash verifies the download, the bundled CHECKSUMS.txt verifies the + extracted contents, so nobody needs to clone the repo to get a verifiable + copy. Released zips are immutable — zrelease refuses to overwrite one. +- zchecksums + CHECKSUMS.txt — a SHA-256 manifest covering every .ps1 + and .cmd, so a download can be verified before anything is run. zchecksums + checks them; zchecksums -Update regenerates after an intentional edit. The + manifest is sha256sum format, so sha256sum -c CHECKSUMS.txt works on + Linux/macOS/WSL too, and the hashes match on every platform because + .gitattributes pins these files to CRLF everywhere. Flags changed files, + missing files, and scripts present on disk but absent from the manifest. + It's an integrity check, not a signature — the manifest sits in the same repo + as the code, so it catches corruption and accidental drift, not a compromised + repo. A Pester test fails if the manifest ever goes stale. +- Test suite (Pester) — the toolkit now has automated coverage of its own + pure logic: Get-ArchiveExcludes (including the deploy-vs-backup rule that + keeps .env/uploads out of deploys but in backups), config and project + lookups, remote.composeDir fallback, EC2 target composition, and build-label + formatting. Run with Invoke-Pester .\tests (Pester 5+). Verified by mutation + testing — reintroducing each historical bug turns the suite red. +- ZCONFIG environment variable — overrides the path to zconfig.json, so + a run can target an alternate config. Also gives the test suite a seam for + injecting a fixture. +- zec2_rotatekeys — safely rotate/reset server-side secrets — a new + tool for when a secret leaks or a deploy overwrites a production .env + with dev values. -Rotate KEY regenerates a key on the server + (openssl rand -hex 32) so the new value never leaves the box; -Set KEY + takes an operator-known value (e.g. DATABASE_URL, ADMIN_EMAIL) from a + masked prompt and streams it over SSH stdin — never a command argument, + never echoed. Backs the server .env up to a timestamped .bak first, + updates the key atomically (matches or appends), auto-detects + backend/.env from deploy.preserve, and with -Restart recreates + the container (up -d --force-recreate, so the new values actually load — + a plain restart keeps the old environment). -WhatIf previews the plan + without touching anything. +- zkill all — zkill now accepts all, stopping the dev server of + every project that has a ports.dev (edge/docker stacks with no local dev + server are skipped). Brings it in line with zdeploy all / zbackup all; + the one-shot "stop everything I've got running locally". +- zdeploy server-side health verification (verify block) — projects + not published through the edge proxy can declare + "verify": { "port": ..., "path": "/health", "expect": "..." } and the + deploy is checked from the server itself (curl localhost: + over SSH) instead of hitting the public IP. Fixes a false PASS where the + proxy's default vhost answered for apps that never started; projects + with neither domain nor verify are now reported as NOT verified. +- zdeploy optional deploy.gitPull — git pull --ff-only in the + project root before zipping. zdeploy zips the working tree and doesn't + otherwise pull, so a checkout left behind origin after a merged PR would + deploy stale code while still bumping the build number — success that + changes nothing. A failed pull aborts the deploy instead. +- Per-project start config block — zstart honors optional pre-start + steps from zconfig.json: "gitPull": true runs git pull --ff-only in + the project root before starting (never boot a stale checkout), and + "env": { ... } sets environment variables for the dev-server process. + Example added to zconfig.example.json. +- Switch-style argument tolerance — a leading dash on a project key is + ignored everywhere (zdeploy -myapp == zdeploy myapp), for hands that + grew up on per-project switches. + +Changed +------- +- zbackup / zbackup_and_sync require an explicit target — running + them bare now shows usage instead of quietly backing up every project; + all does what bare invocation used to (matching zdeploy). The + scheduled task created by setup_backup_schedule.ps1 passes all — + re-run it if your task was registered before this change. +- zbackup parses more DATABASE_URL styles — double/single-quoted + values (Prisma convention), postgres:// and postgresql+driver:// + schemes, and URLs without an explicit port (defaults to 5432) all work; + previously these skipped the Postgres dump with "Could not parse + DATABASE_URL". +- zkill / port cleanup kills the whole process tree — listeners on a + project's port are now terminated children-first. Auto-reloading servers + (uvicorn/watchfiles, nodemon) spawn workers that inherit the listening + socket; killing only the parent left orphans serving stale code. +- zbackup finds DATABASE_URL in backend\.env too — projects with a + frontend/backend split get their Postgres dump bundled without needing a + root-level .env. + +1.0.0 +----- + +Initial public release: zstart / zkill / zrestart (local dev servers), +zdeploy (zip → upload → compose build → live build-version verification, +with handlers for python / vite / nextjs / edge / docker project kinds), +zec2 / zec2online / zrepair (health checks and recovery), zbackup / +zbackup_ec2 / zsync (local, server-side, and offsite backups), all driven +by a single gitignored zconfig.json.