Add --staging as an endpoint alias for the hosted staging platform #16

Merged
geusebio merged 1 commit from feature/staging-endpoint-flag into main 2026-08-06 23:57:55 +00:00
Owner

--staging is a persistent bool on the root command — same reach as
--endpoint, so it applies to every subcommand — resolving to
https://staging.someones.computer.

Tracked by Grey.ooo/someones.computer#212.
That index lives in the platform repo, which only records this repo's pinned
SHA; the change itself belongs here.

The precedence question

--endpoint already sits in a four-level chain, and applyProjectDefaults
uses f.Changed("endpoint") to tell the user passed it from the default
filled it in
. An alias that simply assigns flagEndpoint leaves that flag
false, so a .sc.yml carrying endpoint: would quietly outrank the
--staging the user just typed — the deploy would land somewhere else and say
nothing. It is applied inside applyProjectDefaults instead, as one switch
that states the whole ladder in the order it runs:

Precedence Source
1 (wins) --endpoint
2 --staging
3 $SC_ENDPOINT
4 endpoint: in .sc.yml
5 defaultEndpoint()

--staging outranks the environment and the project file on purpose: a repo
pinned elsewhere must not pull a --staging deploy back off staging.
--staging with --endpoint is an error rather than a defined winner — for
a flag whose entire job is "not production", silently resolving the conflict is
the failure mode worth designing out. applyProjectDefaults returns an error
now so PersistentPreRunE surfaces it.

The two endpoint URLs are named constants (productionEndpoint,
stagingEndpoint); defaultEndpoint() uses the former rather than repeating
the literal.

Two things that came out of building it

  • The deploy summary now names the resolved endpoint. A --dry-run that
    can't answer "am I about to deploy to staging?" isn't much of a rehearsal,
    and it's how a user confirms the flag did what they asked. One line, above
    Compose:.
  • No backticks in the usage string. cobra reads the first backticked word
    as the flag's value placeholder, so an aside about `sc login`
    rendered the bool as --staging sc login in --help. Caught by running the
    binary, fixed, and pinned by TestStagingRendersAsABoolFlagInHelp so it
    can't come back.

Tokens remain keyed per endpoint, so staging needs its own sc login --staging. The flag's help text and the README both say so — unmentioned, it
reads as broken auth rather than as designed.

Verified

go vet, go test ./... and the workflow's six-target cross-compile all pass
locally. Beyond the tests, against the built binary in a project whose
.sc.yml names http://from-file:7500:

$ sc deploy --dry-run
Endpoint:     http://from-file:7500

$ sc deploy --dry-run --staging
Endpoint:     https://staging.someones.computer

$ SC_ENDPOINT=http://from-env:7500 sc deploy --dry-run --staging
Endpoint:     https://staging.someones.computer

$ sc deploy --dry-run --staging --endpoint http://from-flag:7500
sc: --staging and --endpoint both set an endpoint; pass one or the other

and the help line renders as a bool:

      --endpoint string   platform API base URL (default "https://someones.computer")
      --staging           target https://staging.someones.computer (tokens are per endpoint, so this needs its own sc login)

New tests: TestStagingBeatsTheEnvironmentAndTheProjectFile,
TestStagingWithAnExplicitEndpointIsAnError,
TestStagingRendersAsABoolFlagInHelp — the first two sit alongside the
existing precedence table in internal/cli/project_test.go.

Deliberately not in scope

  • --production / a general --env <name>. The tracking issue's scoping
    raised it. One
    bool is the smallest thing that closes the issue, and the constants plus the
    single switch are where a table would go if a third environment ever earns
    one. Not worth a lookup table for one alias.
  • Bumping the platform repo's submodule pin. That's a separate commit over
    there, once this merges and tags.
`--staging` is a persistent bool on the root command — same reach as `--endpoint`, so it applies to every subcommand — resolving to `https://staging.someones.computer`. Tracked by [Grey.ooo/someones.computer#212](https://git.grey.ooo/Grey.ooo/someones.computer/issues/212). That index lives in the platform repo, which only records this repo's pinned SHA; the change itself belongs here. ## The precedence question `--endpoint` already sits in a four-level chain, and `applyProjectDefaults` uses `f.Changed("endpoint")` to tell *the user passed it* from *the default filled it in*. An alias that simply assigns `flagEndpoint` leaves that flag false, so a `.sc.yml` carrying `endpoint:` would quietly outrank the `--staging` the user just typed — the deploy would land somewhere else and say nothing. It is applied inside `applyProjectDefaults` instead, as one switch that states the whole ladder in the order it runs: | Precedence | Source | | --- | --- | | 1 (wins) | `--endpoint` | | 2 | `--staging` | | 3 | `$SC_ENDPOINT` | | 4 | `endpoint:` in `.sc.yml` | | 5 | `defaultEndpoint()` | `--staging` outranks the environment and the project file on purpose: a repo pinned elsewhere must not pull a `--staging` deploy back off staging. `--staging` *with* `--endpoint` is an error rather than a defined winner — for a flag whose entire job is "not production", silently resolving the conflict is the failure mode worth designing out. `applyProjectDefaults` returns an `error` now so `PersistentPreRunE` surfaces it. The two endpoint URLs are named constants (`productionEndpoint`, `stagingEndpoint`); `defaultEndpoint()` uses the former rather than repeating the literal. ## Two things that came out of building it - **The `deploy` summary now names the resolved endpoint.** A `--dry-run` that can't answer "am I about to deploy to staging?" isn't much of a rehearsal, and it's how a user confirms the flag did what they asked. One line, above `Compose:`. - **No backticks in the usage string.** cobra reads the first backticked word as the flag's *value placeholder*, so an aside about `` `sc login` `` rendered the bool as `--staging sc login` in `--help`. Caught by running the binary, fixed, and pinned by `TestStagingRendersAsABoolFlagInHelp` so it can't come back. Tokens remain keyed per endpoint, so staging needs its own `sc login --staging`. The flag's help text and the README both say so — unmentioned, it reads as broken auth rather than as designed. ## Verified `go vet`, `go test ./...` and the workflow's six-target cross-compile all pass locally. Beyond the tests, against the built binary in a project whose `.sc.yml` names `http://from-file:7500`: ``` $ sc deploy --dry-run Endpoint: http://from-file:7500 $ sc deploy --dry-run --staging Endpoint: https://staging.someones.computer $ SC_ENDPOINT=http://from-env:7500 sc deploy --dry-run --staging Endpoint: https://staging.someones.computer $ sc deploy --dry-run --staging --endpoint http://from-flag:7500 sc: --staging and --endpoint both set an endpoint; pass one or the other ``` and the help line renders as a bool: ``` --endpoint string platform API base URL (default "https://someones.computer") --staging target https://staging.someones.computer (tokens are per endpoint, so this needs its own sc login) ``` New tests: `TestStagingBeatsTheEnvironmentAndTheProjectFile`, `TestStagingWithAnExplicitEndpointIsAnError`, `TestStagingRendersAsABoolFlagInHelp` — the first two sit alongside the existing precedence table in `internal/cli/project_test.go`. ## Deliberately not in scope - **`--production` / a general `--env <name>`.** The tracking issue's scoping raised it. One bool is the smallest thing that closes the issue, and the constants plus the single switch are where a table would go if a third environment ever earns one. Not worth a lookup table for one alias. - **Bumping the platform repo's submodule pin.** That's a separate commit over there, once this merges and tags.
Add --staging as an endpoint alias for the hosted staging platform
All checks were successful
CI / build (pull_request) Successful in 4m39s
c2728fb1a1
`--staging` is a persistent bool on the root command, so it reaches every
subcommand the way `--endpoint` already does, and resolves to
https://staging.someones.computer.

The part that needed deciding was precedence. `--endpoint` sits in a four-level
chain and `applyProjectDefaults` uses `Changed("endpoint")` to tell "the user
passed it" from "the default filled it in" — so an alias that just writes
`flagEndpoint` leaves that false and lets a `.sc.yml` `endpoint:` quietly
outrank the flag the user just passed. It is applied inside
`applyProjectDefaults` instead, in one switch that states the whole ladder:

    --endpoint  >  --staging  >  $SC_ENDPOINT  >  .sc.yml  >  the default

`--staging` deliberately beats the environment and the project file: a repo
pinned elsewhere must not pull a `--staging` deploy back off staging. Passing
both `--staging` and `--endpoint` is an error rather than a silent winner —
for a flag whose entire job is "not production", picking one quietly is the
failure mode worth designing out. `applyProjectDefaults` returns an error now
so `PersistentPreRunE` can surface it.

Two things came out of building it:

- The `deploy` summary now names the resolved endpoint. A `--dry-run` that
  can't answer "am I pointed at staging?" is a poor rehearsal, and it is how a
  user checks the flag did what they asked.
- The usage string carries no backticks. cobra reads the first backticked word
  as a flag's value placeholder, which rendered the bool as `--staging sc
  login` in `--help`. Pinned by a test.

Tokens stay keyed per endpoint, so staging needs its own `sc login --staging`;
the flag's help text and the README say so, since otherwise it reads as broken
auth rather than as intended.

Verified against the built binary: `--staging` over a `.sc.yml` naming another
endpoint, over `$SC_ENDPOINT`, and the conflict error.
geusebio changed title from WIP: Add --staging as an endpoint alias for the hosted staging platform to Add --staging as an endpoint alias for the hosted staging platform 2026-08-06 23:42:26 +00:00
Sign in to join this conversation.
No reviewers
No labels
in-progress
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Grey.ooo/someones.computer_agent!16
No description provided.