fix: emit_app_env writes single-quote values compose cannot parse #60
Labels
No labels
priority/P0
priority/P1
priority/P2
priority/P3
size/L
size/M
size/S
size/XL
size/XS
state/blocked
state/done
state/in-progress
state/in-review
state/needs-refinement
state/ready
type/bug
type/chore
type/feature
type/refactor
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
amtronics/platform-actions#60
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Context
deploy-vps's
emit_app_envescapes an embedded'the POSIX way ('\''), which the sourcing shell reads back byte-exactly — but docker compose's dotenv parser cannot read at all: a lineKEY='ab'\''cd'makesdocker compose configexit 1 withunexpected character "\" in variable nameand abandon the whole file, so every later line is lost and the deploy fails at compose pointing at the wrong place (measured on suhba/suhba-docs#11's review). Every other awkward byte round-trips through both parsers. Separately, now that every consumer passes raw values (census closed 2026-09-08), the consumer-quoting pass-through branch has no legitimate use left, and a raw value that happens to begin and end with a matching quote would be written unquoted.Scope
emit_app_envrefuses a value containing', failing the deploy naming only the key (like the malformed-line guard); decide-and-do on the pass-through branch — either delete it or leave it with the reason recorded in the action.'in values (would require compose-side quoting no shell can also read); consumer changes.Acceptance criteria
', when the env file is written, then the step fails naming the key and writes no partial file compose would reject.Plan. One step in deploy-vps/action.yml plus its input description and the README paragraph.
emit_app_envbecomes two passes: validate every line first (valid key, and now: no'anywhere in the value — the one byte the two parsers cannot agree on), then emit; a refusal names only the key and, being pre-emit, adds nothing from app-env to the file — and the failed step means nothing ships regardless. Pass-through decision: deleted. The census is closed, no consumer pre-quotes, the README has taught raw since #56, and the branch's raw-value-that-looks-quoted edge is a footgun with no remaining benefit; every value now goes throughsq()uniformly. The local matrix updates with the semantics: pre-quoted values are no longer honoured (a single-quoted one is refused — it contains'; a double-quoted one round-trips WITH its quotes as literal bytes), and two new kill cases assert the refusal names the key and never leaks the value. Residual noted for the PR: the action's own inputs (grafana token et al.) share the compose-side'exposure throughsq(); out of this issue's scope, will file separately if the review agrees it is real.