feat(sunrise): update an application in place with summercms.io/update

- new.sh gains --update, run inside one application directory (go.mod and
  summer.yaml required); it changes only that application
- the framework checkout is read from the app's go.mod replace (single-line
  or block form); module-version replaces, missing targets and foreign or
  dirty checkouts are refused through the shared check_framework_dir
- a detached checkout moves fast-forward only to the newest release (or
  SUMMERCMS_REF) through the shared move_detached; a branch checkout is
  pulled with git pull --no-rebase --ff-only, refusing a missing upstream
  or a diverged branch with the checkout unchanged
- other sm-*-app directories on the same checkout are named on one
  "not rebuilt" line and never built or written
- summer is reinstalled, a missing SUMMER_ADMIN__JWT__SECRET is appended to
  this app's .env (openssl, else head and base64; mode kept, never printed),
  then summer build runs and the script ends with the migrate and restart
  reminder and the shared path_hint
- sunrise.UpdateScript() serves the same script with its last line changed
  to main "$@" --update, so truncated downloads still run nothing
- check-phase14.3.sh --forbidden now allows only the literal
  SUMMER_ADMIN__JWT__SECRET in new.sh and still fails on any other
  SUMMER_ name or on a read or export of one; TestUpdateScript and
  TestUpdateScriptRoute are required tests
This commit is contained in:
Jakub Zych
2026-10-08 20:15:50 +02:00
parent 27f75308d7
commit 9b3803c098
8 changed files with 1292 additions and 108 deletions

View File

@@ -14,7 +14,11 @@
# generate and tests, and --forbidden.
#
# --forbidden scans for surfaces the phase must not add: a framework config
# variable (SUMMER_ prefix) in new.sh, a new require in go.mod since v0.1.12,
# variable (SUMMER_ prefix) in new.sh other than SUMMER_ADMIN__JWT__SECRET,
# which update mode appends to an application's .env, or any read
# ($SUMMER_..., ${SUMMER_...}) or export of a SUMMER_ variable in new.sh
# (D-26: the script's own overrides are SUMMERCMS_*), a new require in go.mod
# since v0.1.12,
# the stdlib plugin package or yaegi in the dependency graph, an absolute
# path in a golden go.mod/go.work, or a golden ignored by .gitignore.
#
@@ -92,11 +96,12 @@ REQUIRED_TESTS=(
TestScriptTruncationRunsNothing
TestScriptBehavior
TestScriptShellcheck
TestUpdateScript
TestDocsTree
TestDocsAIOutputsInSync
)
# Site tests that pin GET /new and the landing page commands.
SITE_PLUGIN_TESTS=(TestNewScriptRoute TestRoutesAssemble)
SITE_PLUGIN_TESTS=(TestNewScriptRoute TestUpdateScriptRoute TestRoutesAssemble)
SITE_APP_TESTS=(TestLoadTerminal TestTerminalScript TestTerminalEnv TestTerminalRunScript)
fail() {
@@ -385,8 +390,14 @@ stage_acceptance() {
stage_forbidden() {
cd "$ROOT"
echo "== forbidden surfaces"
if grep -nE 'SUMMER_' modules/sunrise/new.sh; then
fail "new.sh names a framework config variable (SUMMER_ prefix)"
local names
names="$(grep -noE 'SUMMER_[A-Z0-9_]*' modules/sunrise/new.sh | grep -v ':SUMMER_ADMIN__JWT__SECRET$' || true)"
if [ -n "$names" ]; then
printf '%s\n' "$names"
fail "new.sh names a framework config variable other than SUMMER_ADMIN__JWT__SECRET"
fi
if grep -nE '\$\{?SUMMER_|export[[:space:]]+SUMMER_' modules/sunrise/new.sh; then
fail "new.sh reads or exports a framework config variable"
fi
git rev-parse -q --verify 'refs/tags/v0.1.12^{commit}' >/dev/null || fail "tag v0.1.12 is missing; cannot compare go.mod"
local added