mirror of
https://github.com/kellymichels/zscripts-token-savers
synced 2026-10-07 07:18:18 +00:00
- Get-Ec2SshOpts: every deploy-path ssh/scp now carries BatchMode=yes plus connect/keepalive timeouts. Without BatchMode ssh prompts and waits forever, and because the deploy pipes stderr through the pipeline the prompt never reaches the screen - the run just stops under the last step label with no explanation. - Archive filter exempts files under vendor/: a vendored *.tgz is a build input, and dropping it fails a Dockerfile COPY at image build. - unzip install checks command -v first instead of an apt round-trip on every deploy. Ported from the private script; three tests cover the vendor/ exemption.
147 lines
8.8 KiB
Markdown
147 lines
8.8 KiB
Markdown
<!--
|
|
Evomedia.net Token Savers — https://github.com/kellymichels/zscripts-token-savers
|
|
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 the SmartPlant 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-<version>.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:<port><path>`
|
|
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`.
|