naro-cli 0.17.0 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +384 -24
- package/dist/{chunk-PYRN5XR6.js → chunk-DEEFHVDZ.js} +1616 -230
- package/dist/deploy.d.ts +38 -1
- package/dist/deploy.js +8 -4
- package/dist/env-consent.d.ts +9 -1
- package/dist/env-surface.d.ts +12 -0
- package/dist/index.js +782 -237
- package/dist/prompt.d.ts +16 -2
- package/dist/working-tree.d.ts +74 -0
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -58,15 +58,20 @@ naro link | init Link this directory to a Naro project
|
|
|
58
58
|
naro unlink Remove the link
|
|
59
59
|
naro projects [--team <slug>] List projects
|
|
60
60
|
naro project inspect Show the linked project
|
|
61
|
+
naro usage Team usage this month: requests, builds and custom domains against the plan, then by project
|
|
62
|
+
naro usage --month 2026-09 --team acme Another UTC month, another team
|
|
61
63
|
|
|
62
64
|
naro deploy [--prod] Build locally and deploy
|
|
65
|
+
naro deploy --env qa Deploy to a named environment (<subdomain>--qa) instead of the preview; not with --prod
|
|
63
66
|
naro deployments List deployments
|
|
64
67
|
naro inspect <deployment-id> One deployment + build logs
|
|
65
68
|
naro cancel <deployment-id> Stop a build that is still running
|
|
69
|
+
naro git connect [owner/repo] Deploy on every push (installs the GitHub App if needed)
|
|
70
|
+
naro git disconnect Stop deploying on push
|
|
66
71
|
|
|
67
72
|
naro logs Runtime logs (production)
|
|
68
73
|
naro logs <deployment-id> Build logs of a deployment
|
|
69
|
-
naro logs --type build --follow Stream build logs until
|
|
74
|
+
naro logs --type build --follow Stream the latest deployment's build logs until it ends (exit 1 on FAILED)
|
|
70
75
|
naro logs --env preview Preview-surface runtime logs
|
|
71
76
|
|
|
72
77
|
naro analytics Web Analytics: visitors, page views, top pages, referrers, countries, devices, browsers, operating systems (--range 7d)
|
|
@@ -82,10 +87,24 @@ naro protection Preview protection: on or off, and whether a
|
|
|
82
87
|
naro protection enable | disable Protect the preview URL (members only) or open it to anyone with the link (disable asks first; --yes in CI)
|
|
83
88
|
naro protection bypass [remove] Create (shown once) or remove the secret automation sends as x-naro-protection-bypass (replacing or removing asks first; --yes in CI)
|
|
84
89
|
|
|
85
|
-
naro env list [--reveal] Secrets masked unless --reveal
|
|
90
|
+
naro env list [--reveal] Secrets masked unless --reveal; an environment's value shows its name
|
|
86
91
|
naro env add DATABASE_URL production
|
|
87
|
-
|
|
88
|
-
naro env
|
|
92
|
+
Target: production, preview, all (the default) or an environment name (qa)
|
|
93
|
+
naro env remove DATABASE_URL The production, preview and all values; an environment's only with its name
|
|
94
|
+
(naro env remove DATABASE_URL qa)
|
|
95
|
+
naro env pull [.env.local] Preview's values by default; --env production, or --env qa for an environment
|
|
96
|
+
(its own value wins over all; an unknown name fails before anything is written)
|
|
97
|
+
naro env import .env.qa qa Upload every variable in a dotenv file to one target (all by default; asks first,
|
|
98
|
+
--yes in CI; invalid keys or values over 5 KB stop it before any request)
|
|
99
|
+
|
|
100
|
+
naro environments List the project's environments: address, branch, protection, and how many the plan allows
|
|
101
|
+
naro environments create qa --branch qa
|
|
102
|
+
A QA or staging surface served at <subdomain>--qa; --copy-env preview|production|none
|
|
103
|
+
picks where its variables start, --database schema|empty how its database does
|
|
104
|
+
naro environments set qa --no-branch --protection off
|
|
105
|
+
Change the branch whose pushes deploy here (--branch <b>, or --no-branch for none)
|
|
106
|
+
and who can open it (--protection on|off; off asks first, --yes in CI)
|
|
107
|
+
naro environments delete qa Delete it with its worker and protection key (asks first; --yes in CI)
|
|
89
108
|
|
|
90
109
|
naro domains list
|
|
91
110
|
naro domains add www.example.com Prints the CNAME to create; naro connects
|
|
@@ -180,7 +199,7 @@ naro storage bucket create avatars --public --file-size-limit 5MiB --allowed-mim
|
|
|
180
199
|
naro storage bucket update avatars --private | --file-size-limit none | --allowed-mime-types any
|
|
181
200
|
naro storage bucket update docs --public (asks first: anyone with an object's URL can download it)
|
|
182
201
|
naro storage bucket list | empty <name> | remove <name> [--empty] (empty and remove ask first)
|
|
183
|
-
naro storage ls naro://avatars/u1 [--recursive]
|
|
202
|
+
naro storage ls naro://avatars/u1 [--recursive] [--search <text>] Names that start with <text>, ASCII case ignored
|
|
184
203
|
naro storage cp ./me.png naro://avatars/u1/me.png [--upsert] Up to the object limit, under 4 GiB (over 50 MiB in parts), with the service key
|
|
185
204
|
naro storage cp naro://docs/team-1/plan.pdf ./ Replaces a local file of the same name
|
|
186
205
|
naro storage rm naro://avatars/u1/old.png [--recursive] (asks first)
|
|
@@ -306,16 +325,14 @@ point at its table's primary key or a unique column. `--owner user_id` adds
|
|
|
306
325
|
four actions; any other new table is closed to the Data API until you give it
|
|
307
326
|
a policy (`CREATE POLICY` in a migration, or `naro policy create` or
|
|
308
327
|
`naro policy set`; the command says so).
|
|
309
|
-
Policies
|
|
310
|
-
the
|
|
311
|
-
them
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
neither does a table made by `naro db push` or `naro db query`. Whatever a command removes it prints
|
|
318
|
-
so it can be made again: as `CREATE POLICY` statements, which
|
|
328
|
+
Policies go with their table, as in Postgres and as `naro db push` does it,
|
|
329
|
+
in the same migration: a drop removes the table's policies, and a rename
|
|
330
|
+
moves them to the new name and rewrites the policies of other tables that
|
|
331
|
+
read it (the command says which). A rename such a policy cannot follow is
|
|
332
|
+
refused before anything runs. A table the command creates, or renames onto a
|
|
333
|
+
name, never inherits what an earlier table of that name left there: that is
|
|
334
|
+
removed first. A change that fails changes no policy. Whatever a command
|
|
335
|
+
removes it prints so it can be made again: as `CREATE POLICY` statements, which
|
|
319
336
|
`naro policy create` takes back, and — for owner rules, whose owner column
|
|
320
337
|
`CREATE POLICY` cannot say — as the `naro policy set <table> … --owner <column>`
|
|
321
338
|
command that sets them again. A statement that cannot be shown as it is (a
|
|
@@ -581,8 +598,10 @@ SQLite changes a column by building the table again — `CREATE TABLE
|
|
|
581
598
|
__new_x`, copy the rows, `DROP TABLE x`, `ALTER TABLE __new_x RENAME TO x` — so
|
|
582
599
|
the drop removes `x`'s policies and the rename does not bring them back. Write
|
|
583
600
|
the `CREATE POLICY` statements again after the rename, in the same migration.
|
|
584
|
-
A plain `ALTER TABLE a RENAME TO b`
|
|
585
|
-
|
|
601
|
+
A plain `ALTER TABLE a RENAME TO b` in a migration moves `a`'s policies to `b`,
|
|
602
|
+
and a policy of another table that reads `a` is written to read `b` — do not
|
|
603
|
+
create them again on `b`: a policy of the same name already there is refused.
|
|
604
|
+
`naro db table`, the table editor and MCP do the same.
|
|
586
605
|
The answer's `warnings` lists the policies a migration removed, with SQL you
|
|
587
606
|
can paste; it also says when the project has no backend yet (the policies are
|
|
588
607
|
saved and apply once `naro backend enable` turns it on) and when a policy was
|
|
@@ -739,7 +758,10 @@ into named policies; it also turns a backend that is off back on, so run
|
|
|
739
758
|
`naro backend disable` again afterwards if it should stay off. `naro policy
|
|
740
759
|
list` and `naro policy remove` work in the meantime. A migration or a query
|
|
741
760
|
that holds a `CREATE POLICY` or `DROP POLICY` gets the same answer before
|
|
742
|
-
anything runs
|
|
761
|
+
anything runs, and so does any change that creates, drops or renames a table —
|
|
762
|
+
in SQL, `naro db table`, the table editor or MCP, with the backend on or off:
|
|
763
|
+
the stored rules apply by table name, and only `naro backend enable` clears
|
|
764
|
+
them. Other SQL runs as before.
|
|
743
765
|
|
|
744
766
|
`naro policy set` refuses with `409 POLICY_EXISTS` when the table's `naro_<action>` policy is not one it wrote (for example one made with `naro policy create`): `Policy <name> on <table> is not one naro policy set wrote. Change it with naro policy create, or drop it first: naro policy drop <name> --table <table>.` A `naro_<action>` policy that cannot be read as stored (the table answers `500 POLICY_INVALID`) is not refused: setting a rule replaces it, and `none` drops it.
|
|
745
767
|
|
|
@@ -804,6 +826,325 @@ An `--update-check` you give replaces the default: without
|
|
|
804
826
|
|
|
805
827
|
## Release notes
|
|
806
828
|
|
|
829
|
+
### 0.19.0
|
|
830
|
+
|
|
831
|
+
- `naro environments` manages a project's named environments, QA or staging
|
|
832
|
+
surfaces served at `https://<subdomain>--<slug>.naro.sh` beside production
|
|
833
|
+
and the preview. While the control plane has them switched off, every
|
|
834
|
+
sub-command fails with the server's `404 NOT_FOUND "Not found."`.
|
|
835
|
+
- `naro environments` (also `list`, `ls`) prints
|
|
836
|
+
`slug url branch protection` and one row per environment (`—` when no
|
|
837
|
+
branch deploys there, protection `on` or `off`), then
|
|
838
|
+
`2 of 3 environments`, or `2 environments` (`1 environment`) on a plan
|
|
839
|
+
with no limit. With none it prints
|
|
840
|
+
``No environments. Create one with `naro environments create qa`.``
|
|
841
|
+
first. `--json` prints `{ projectId, environments, limit }`.
|
|
842
|
+
- `naro environments create qa [--branch qa] [--copy-env preview|production|none] [--database schema|empty]`
|
|
843
|
+
prints `✅ Created environment qa → https://<subdomain>--qa.naro.sh`. A
|
|
844
|
+
flag left out leaves the server's default: no branch, the preview's
|
|
845
|
+
variables, the database seeded with the schema. `--copy-env none` copies
|
|
846
|
+
nothing. Other values fail before any request with
|
|
847
|
+
`--copy-env must be preview, production or none.` and
|
|
848
|
+
`--database must be schema or empty.`
|
|
849
|
+
- `naro environments set qa [--branch <b> | --no-branch] [--protection on|off]`
|
|
850
|
+
prints `✅ Updated environment qa`. Before any request it refuses
|
|
851
|
+
`--branch and --no-branch cannot be used together.`,
|
|
852
|
+
`--protection must be on or off.` and
|
|
853
|
+
`Nothing to change: pass --branch, --no-branch or --protection.`
|
|
854
|
+
`--protection off` asks
|
|
855
|
+
`Turn off protection for qa? Anyone with the link can open it.` first,
|
|
856
|
+
like `naro protection disable`; with `--json` or without a terminal it
|
|
857
|
+
needs `--yes` (`CONFIRMATION_REQUIRED`).
|
|
858
|
+
- `naro environments delete qa` asks
|
|
859
|
+
`Delete environment qa? Its worker and protection key are removed.`,
|
|
860
|
+
then prints `✅ Deleted environment qa` (`--json`:
|
|
861
|
+
`{ projectId, slug, deleted: true }`).
|
|
862
|
+
- A slug the project does not have fails `ENVIRONMENT_NOT_FOUND`
|
|
863
|
+
`Environment not found.` and changes nothing. The server's refusals
|
|
864
|
+
come through with their code and message, such as `ENVIRONMENT_EXISTS`
|
|
865
|
+
`An environment with this name already exists.` and
|
|
866
|
+
`ENVIRONMENT_BRANCH_TAKEN`
|
|
867
|
+
`Another environment already deploys this branch.`
|
|
868
|
+
- New options `--no-branch`, `--copy-env <source>`, `--database <seed>`
|
|
869
|
+
and `--protection <on|off>`. `--branch <b>` is in `naro help` now, and
|
|
870
|
+
says what it does: for `naro environments create` and `set`, the branch
|
|
871
|
+
whose pushes deploy to that environment; for `naro deploy`, the default
|
|
872
|
+
branch of a project the deploy creates or updates. A deploy's own branch
|
|
873
|
+
follows where it goes.
|
|
874
|
+
- `naro deploy --env qa` deploys to a named environment instead of the
|
|
875
|
+
preview. It prints `✅ Deployment ready (qa)`, and `--json` has
|
|
876
|
+
`"target": "qa"` and `"environment": "qa"` (`null` for production and
|
|
877
|
+
preview). When the server gives no URL the CLI builds
|
|
878
|
+
`https://<subdomain>--qa.<host>`. `--env production` is `--prod` (and asks
|
|
879
|
+
`Deploy to production?` in a terminal the same way); `--env preview` is a
|
|
880
|
+
plain deploy. `--env` with `--prod` fails before anything is asked or sent:
|
|
881
|
+
`VALIDATION_FAILED` `--env and --prod cannot be used together.`, and
|
|
882
|
+
`--env ""` with `--env must be production, preview or an environment name.`
|
|
883
|
+
In a linked directory the environment is looked up before a missing key is
|
|
884
|
+
read, asked for or sent, and nothing is asked, sent or built when that
|
|
885
|
+
fails: a name the project has no environment for fails
|
|
886
|
+
`ENVIRONMENT_NOT_FOUND` `Environment not found.`, and while the control
|
|
887
|
+
plane has named environments switched off the deploy fails with their
|
|
888
|
+
`404 NOT_FOUND "Not found."`. Not yet linked, an environment deploy asks
|
|
889
|
+
for no missing value and sends none (the hint names the environment), and
|
|
890
|
+
the server answers `404 ENVIRONMENT_NOT_FOUND "Environment not found."`
|
|
891
|
+
for a name the project does not have.
|
|
892
|
+
- Release order: deploy web with named environments 1b-2 before relying on
|
|
893
|
+
`naro deploy --env`. The deploy route of an older control plane ignores
|
|
894
|
+
the name and deploys a preview (the result says `(preview)`), saving the
|
|
895
|
+
values sent with it for `all`, which production builds read. In a linked
|
|
896
|
+
directory the environments route's 404 stops the deploy before that, and
|
|
897
|
+
an unlinked one sends no values.
|
|
898
|
+
- `deployDirectory`, the library export the MCP server uses, refuses
|
|
899
|
+
`environment: "production"` and `environment: "preview"` (without
|
|
900
|
+
`production: true`) with `VALIDATION_FAILED`
|
|
901
|
+
`Pass production: true for production; preview is the default.` With
|
|
902
|
+
`production: true` the control plane answers
|
|
903
|
+
`environment and production cannot be used together.`
|
|
904
|
+
- `naro deploy` counts the env vars a deploy is missing from the values that
|
|
905
|
+
deploy gets. A production deploy now lists a key set only for preview as
|
|
906
|
+
missing, and a preview deploy one set only for production; an environment
|
|
907
|
+
deploy counts the `all` values and that environment's own. On an
|
|
908
|
+
environment deploy, the values typed at the env prompt are saved for that
|
|
909
|
+
environment alone, so a developer, who cannot change `all`, has them saved
|
|
910
|
+
instead of listed under `⚠ skipped env:`. Production and preview deploys
|
|
911
|
+
still save them for `all`. The hint names the environment too:
|
|
912
|
+
`npx naro-cli env add DATABASE_URL qa`.
|
|
913
|
+
- `naro env add` and `naro env remove` take an environment's slug as the
|
|
914
|
+
target: `naro env add DATABASE_URL qa`. A target that is none of
|
|
915
|
+
`production`, `preview`, `all` or a slug fails with
|
|
916
|
+
`Target must be production, preview, all or an environment name.` (it was
|
|
917
|
+
`Environment must be production, preview or all.`), and the usage reads
|
|
918
|
+
`Usage: naro env add KEY [production|preview|all|<environment>]`.
|
|
919
|
+
`naro env list` shows an environment's value under its slug.
|
|
920
|
+
- `naro env remove KEY` with no target removes the `production`, `preview`
|
|
921
|
+
and `all` values and leaves every environment's alone; remove one with
|
|
922
|
+
`naro env remove KEY qa` (`Remove KEY (qa) from this project?`). A key
|
|
923
|
+
that only environments hold fails `ENV_NOT_FOUND` `No KEY variable found.`
|
|
924
|
+
and nothing is removed.
|
|
925
|
+
- `naro env pull --env qa` writes an environment's values. A surface's own
|
|
926
|
+
value now wins over the `all` one whatever order the server lists them in
|
|
927
|
+
(before, the last row won), and preview's values never reach an
|
|
928
|
+
environment, as in the deploy. An environment the project does not have
|
|
929
|
+
fails `ENVIRONMENT_NOT_FOUND` `Environment not found.` before anything is
|
|
930
|
+
written. `--env` takes `production`, `preview` or a slug; anything else,
|
|
931
|
+
`""` included, fails with
|
|
932
|
+
`--env must be production, preview or an environment name.` (it was
|
|
933
|
+
`--env must be production or preview.`, and `--env ""` pulled preview).
|
|
934
|
+
The count in `✅ Pulled N variable(s)` and `--json` is the keys written,
|
|
935
|
+
so a key held by `all` and the surface counts once.
|
|
936
|
+
- `naro env import <file> [target]` uploads every variable in a dotenv file
|
|
937
|
+
to one target, `all` by default. It lists the keys on stdout (stderr with
|
|
938
|
+
`--json`), every value masked but a `NEXT_PUBLIC_` one: the others,
|
|
939
|
+
`VITE_`, `REACT_APP_` and `PUBLIC_` included, are uploaded as secrets. It
|
|
940
|
+
asks `Upload 3 variables to qa?` (`1 variable`; `--yes` in CI),
|
|
941
|
+
and prints `✅ Imported 3 variables (qa)` (`--json`:
|
|
942
|
+
`{ projectId, file, target, count }`). Before any request it fails with
|
|
943
|
+
`Cannot read <file>.`, `No variables found in <file>.`,
|
|
944
|
+
`Invalid keys in <file>: A-B, 1X.` or
|
|
945
|
+
`Values over 5 KB in <file>: BIG.` (5,120 UTF-8 bytes, the limit the
|
|
946
|
+
server keeps). It uploads 100 variables per request, so a refusal of a
|
|
947
|
+
later request leaves the earlier ones saved. A line `export KEY=value`
|
|
948
|
+
reads as `KEY`. Values with `\"` or `\\` inside double quotes are read as
|
|
949
|
+
written, not unescaped, so a file `naro env pull` wrote with such a value
|
|
950
|
+
does not import back as it was (known-issues #224).
|
|
951
|
+
- `naro env add` with a value typed at the prompt no longer loses it to a
|
|
952
|
+
refusal. It reads the project first, so a `--project` of another team or
|
|
953
|
+
of a deleted project fails `404 NOT_FOUND "Project not found."` before the
|
|
954
|
+
value is asked for. For an environment target it looks the environment up
|
|
955
|
+
too: a slug the project does not have fails `ENVIRONMENT_NOT_FOUND`
|
|
956
|
+
`Environment not found.` before the value is asked for, and while
|
|
957
|
+
environments are switched off `404 NOT_FOUND "Not found."` does. When the
|
|
958
|
+
role cannot write `all` (the default, or typed out), it asks
|
|
959
|
+
`You do not have permission to change production environment variables on this project. Save KEY for preview only?`
|
|
960
|
+
and on yes saves the same value for preview (`✅ Added KEY (preview, secret)`).
|
|
961
|
+
A named `production`, `preview` or environment target is not offered
|
|
962
|
+
another. A piped value works as before.
|
|
963
|
+
- `naro usage` names a project that has moved to another team
|
|
964
|
+
`Moved to another team <id>`. Before, it read `Deleted project <id>`.
|
|
965
|
+
- `naro db reset` reads the migration files the way the control plane now
|
|
966
|
+
runs them: `ALTER TABLE a RENAME TO b` moves `a`'s policies to `b`
|
|
967
|
+
(known-issues #87), so a policy a renamed table took along is no longer
|
|
968
|
+
listed as gone after the reset. A file that creates one of them again on
|
|
969
|
+
`b`, as the old advice said, would now stop the re-apply, and is named
|
|
970
|
+
before the schema is dropped:
|
|
971
|
+
`⚠ <file> would be refused: statement <n> of <m> failed and the migration was rolled back: policy "<name>" for table "b" already exists`.
|
|
972
|
+
- `naro db table rename` moves the table's Data API policies to the new name
|
|
973
|
+
and rewrites the policies of other tables that read it, in the same
|
|
974
|
+
migration, as `naro db push` does (known-issues #87): the command prints
|
|
975
|
+
`⚠ Moved 1 Data API policy with posts to articles: own.` and
|
|
976
|
+
`⚠ Rewrote 1 policy that read posts to read articles: docs.team.`. A rename
|
|
977
|
+
a policy cannot follow is refused before anything runs. Before, the
|
|
978
|
+
policies stayed under the old name and the table was closed. Renaming the
|
|
979
|
+
table back brings them back.
|
|
980
|
+
- `naro db table create`, `drop` and `rename` no longer print policies
|
|
981
|
+
"removed before the change ran" when the change fails: a change that fails
|
|
982
|
+
changes no policy now.
|
|
983
|
+
- On a backend from before named policies, creating, dropping or renaming a
|
|
984
|
+
table answers `409 BACKEND_OUTDATED` until `naro backend enable` runs —
|
|
985
|
+
through `naro db table`, `naro db push` and `naro db query` alike.
|
|
986
|
+
|
|
987
|
+
### 0.18.0
|
|
988
|
+
|
|
989
|
+
- `naro usage` shows a team's usage for a UTC month from the terminal:
|
|
990
|
+
requests (blocked ones left out), builds and custom domains against what
|
|
991
|
+
the plan includes, a `✗`/`⚠` line when a Hobby team's sites are paused,
|
|
992
|
+
past the limit or at 80% of its requests, then a table by project.
|
|
993
|
+
`--month 2026-09` reads another month (the server checks the form and
|
|
994
|
+
answers `400 VALIDATION_FAILED "month must be YYYY-MM."`), `--team` picks
|
|
995
|
+
the team as `naro projects` does, and `--json` prints the whole report with
|
|
996
|
+
`summary`. Owners, billing members and enterprise viewers can read it;
|
|
997
|
+
other roles get `403 FORBIDDEN "Your role cannot read this team's usage."`.
|
|
998
|
+
A control plane from before `limits` prints `—` for what the plan includes.
|
|
999
|
+
- `naro deploy` no longer copies env files from the working tree into the
|
|
1000
|
+
build. The env files in the commit go in with their committed content, the
|
|
1001
|
+
same files a git deploy of that commit builds with. An untracked
|
|
1002
|
+
`.env.local`, a local edit to a committed `.env` and a change that is only
|
|
1003
|
+
staged stay on the machine. Before, all of them were copied: `next build`
|
|
1004
|
+
inlined their `NEXT_PUBLIC_*` values into the bundle and OpenNext bundled
|
|
1005
|
+
every value into the Worker, including values declined at the env prompt.
|
|
1006
|
+
Local values now reach a build only through the env prompt or
|
|
1007
|
+
`naro env add`. Env file names match in any case: on macOS `.ENV.LOCAL`
|
|
1008
|
+
opens as `.env.local`. `.env.example`, `.env.sample` and `.env.template` are
|
|
1009
|
+
copied as before. The terminal says what was left out or replaced:
|
|
1010
|
+
``⚠ Left out of the build because they are not committed: .env.local. Local values reach a build only through the env prompt or `naro env add`.``
|
|
1011
|
+
and `▸ Built with the committed version of .env; the local edits stay on this machine.`
|
|
1012
|
+
The build log gets the same lines without the `⚠`/`▸`, as a warning and a
|
|
1013
|
+
note. Without git the first line reads
|
|
1014
|
+
`Left out of the build because git could not be run to read the commit: …`.
|
|
1015
|
+
- `naro deploy` no longer copies a symbolic link whose target is absolute or
|
|
1016
|
+
leads out of the folder being deployed. Copied as it was, it led the build
|
|
1017
|
+
to the developer's own files: whatever the app imported through it was
|
|
1018
|
+
bundled, and an app folder linked from elsewhere had its `.env.local` read
|
|
1019
|
+
by `next build`. Whether a link leads out is judged on its real path, from
|
|
1020
|
+
the folder and again from the build's copy, so neither `self -> .` tricks
|
|
1021
|
+
nor `..` up to `/` and back down the folder's own path get one through; a
|
|
1022
|
+
link whose target cannot be
|
|
1023
|
+
found is copied only when it points down the folder (no `..`), and a loop
|
|
1024
|
+
is left out:
|
|
1025
|
+
`⚠ Left out of the build because they are symbolic links that lead out of this folder on disk, or to a place that could not be found: config. Copy what the build needs into the project.` A folder passed as a link
|
|
1026
|
+
(`naro deploy --cwd <link>`, the MCP `deploy` tool's `directory`) is copied
|
|
1027
|
+
from the folder it points to; before, the build ran in the developer's
|
|
1028
|
+
folder itself and wrote the committed `.env` over theirs. An absolute link
|
|
1029
|
+
cannot be followed by a git deploy of the commit either:
|
|
1030
|
+
`⚠ Left out of the build because they are symbolic links to an absolute path: config. A git deploy of this commit cannot follow them either; copy what the build needs into the project.`
|
|
1031
|
+
A relative link out of the folder is one a git deploy, which clones the
|
|
1032
|
+
whole repository, can follow. Deploy from the repository root with
|
|
1033
|
+
`--root <app folder>` to keep it:
|
|
1034
|
+
`⚠ Left out of the build because they are symbolic links to outside this folder: up. To keep links between a repository's folders, deploy from the repository root with --root <app folder>.`
|
|
1035
|
+
A relative link between the folder's own subfolders is copied as before.
|
|
1036
|
+
- When the local build or the upload in `naro deploy` fails, the deployment
|
|
1037
|
+
is marked `FAILED` at once, with the error's code and message, on the
|
|
1038
|
+
dashboard and in `naro deployments`. Before, it stayed building until the
|
|
1039
|
+
control plane's sweep about 10 minutes later. An upload that already
|
|
1040
|
+
finished is left to the control plane, which is putting it live.
|
|
1041
|
+
- A failed local build's `--json` keeps `"code": "BUILD_FAILED"` and adds
|
|
1042
|
+
`buildCode`, the code the dashboard shows. It is a deployment error code,
|
|
1043
|
+
such as `NEXT_VERSION_UNSUPPORTED`, `INSTALL_FAILED`, `BUILD_FAILED`,
|
|
1044
|
+
`ARTIFACT_INVALID` (static output a deploy cannot take, like a symbolic
|
|
1045
|
+
link), `FRAMEWORK_DETECTION_FAILED`, or `NO_DEPLOYMENT_STRATEGY` when a
|
|
1046
|
+
Next.js app's own build did not fail but no deployment strategy could ship
|
|
1047
|
+
it (its own `next build` failing is `BUILD_FAILED`). Before, the stage's code was
|
|
1048
|
+
only in the message. A failed upload still fails with its own error and no
|
|
1049
|
+
`buildCode`; the dashboard shows its deployment code, or `DEPLOY_FAILED`.
|
|
1050
|
+
- `naro storage ls naro://<bucket>[/<prefix>] --search <text>` lists only the
|
|
1051
|
+
names directly below the prefix that start with `<text>`, ignoring ASCII
|
|
1052
|
+
case; `%` and `_` are plain characters (Storage 3-1g). With `--recursive`
|
|
1053
|
+
the search applies on every level, folders included, so it does not find
|
|
1054
|
+
a name deep below. A project backend from before this release answers it
|
|
1055
|
+
with `BACKEND_OUTDATED`:
|
|
1056
|
+
``The project backend is older than this Storage command. Run `naro backend enable` to update it, then try again.``
|
|
1057
|
+
- `naro db lint` measures a `storage.objects` listing with a search too
|
|
1058
|
+
(Storage 3-1g): its SELECT policies may bind 43 values in one statement,
|
|
1059
|
+
not 44. A set that used exactly 44 is now an error before it is pushed;
|
|
1060
|
+
the backend would answer a listing with a search `500 POLICY_INVALID`.
|
|
1061
|
+
- `naro logs --type build` without an id shows the newest deployment,
|
|
1062
|
+
whatever its status, and names it first:
|
|
1063
|
+
`Build logs of the latest deployment, <id>`. Before, it took the newest
|
|
1064
|
+
`READY` one, so `--follow` passed over the build under way and ended at
|
|
1065
|
+
once on an old deployment. `--follow` gives up after 30 minutes
|
|
1066
|
+
(`TIMEOUT`, `Deployment <id> did not finish within 1800s.`), and a build
|
|
1067
|
+
that ends `FAILED` ends the command with exit 1 and the deployment's error
|
|
1068
|
+
code and message. Before, it printed `— deployment FAILED —` and exited 0.
|
|
1069
|
+
A deployment with no build logs yet says so instead of printing nothing:
|
|
1070
|
+
`(no build logs yet — <id> is QUEUED; add --follow to stream)`. `--json`
|
|
1071
|
+
adds `status`.
|
|
1072
|
+
- `naro logs` refuses two flag pairs with `VALIDATION_FAILED`: `--follow`
|
|
1073
|
+
with `--json` for runtime logs, which streamed until Ctrl-C and never
|
|
1074
|
+
printed its JSON, and `--env` with build logs, which ignored it — so
|
|
1075
|
+
`--type build --env production` could show a preview build.
|
|
1076
|
+
- `naro whoami` uses the token every other command sends: `--token`, then
|
|
1077
|
+
`NARO_TOKEN`, then the stored session. In CI it names the account
|
|
1078
|
+
`NARO_TOKEN` belongs to, `Logged in as <email> (<github>) — from NARO_TOKEN`,
|
|
1079
|
+
with `"tokenSource": "env"` in `--json` (`"flag"`, or `"session"` for the
|
|
1080
|
+
stored one). Before, it answered ``Not logged in. Run `naro login`.`` while
|
|
1081
|
+
`naro deploy` worked. A token that no longer works gets `NOT_LOGGED_IN`
|
|
1082
|
+
``The access token is invalid or has expired. Generate a new one with `naro token`, or run `naro login`.``;
|
|
1083
|
+
a sign-in service out of reach gets `NETWORK_ERROR` instead, and a rate
|
|
1084
|
+
limit `RATE_LIMITED`.
|
|
1085
|
+
- `naro token` still mints only from the `naro login` session. With no
|
|
1086
|
+
session and a token in `--token` or `NARO_TOKEN`, it fails with
|
|
1087
|
+
`NOT_LOGGED_IN` and says why:
|
|
1088
|
+
`` `naro token` makes a token from a `naro login` session, and there is none here. NARO_TOKEN is already a token: the other commands use it as is. ``
|
|
1089
|
+
(`--token is already a token` when the token came from `--token`).
|
|
1090
|
+
- `naro login` that nobody finishes in the browser ends after 120 seconds
|
|
1091
|
+
with `TIMEOUT`:
|
|
1092
|
+
``Sign-in timed out after 120s waiting for the browser. Run `naro login` again, or set NARO_TOKEN.``
|
|
1093
|
+
Before, it failed as `INTERNAL_ERROR` with
|
|
1094
|
+
`Timed out waiting for GitHub callback.`
|
|
1095
|
+
- `naro env add` checks the link and the sign-in before it asks for the
|
|
1096
|
+
value, so a typed value is no longer thrown away by `PROJECT_NOT_LINKED`.
|
|
1097
|
+
`naro env pull /tmp/x.env` writes that file; before, it wrote
|
|
1098
|
+
`<cwd>/tmp/x.env`. A file it overwrites is set to 0600 as well. Before,
|
|
1099
|
+
only a new file was, and an existing 0644 `.env.local` kept 0644 with the
|
|
1100
|
+
secrets in it.
|
|
1101
|
+
- `naro git connect` with `--json` or without a terminal no longer opens a
|
|
1102
|
+
browser and waits three minutes when the Naro GitHub App cannot reach the
|
|
1103
|
+
repository. It fails at once with `REPOSITORY_NOT_ACCESSIBLE`
|
|
1104
|
+
(`Naro cannot reach <owner/repo> yet. Install the Naro GitHub App at <url>, then run: naro git connect`),
|
|
1105
|
+
and `--json` carries the link as `installUrl`. Before, the wait ended with
|
|
1106
|
+
`▸ Still waiting on access to <owner/repo>.` and exit 0.
|
|
1107
|
+
- A first `naro deploy` with one team asks
|
|
1108
|
+
`Deploy to this account and team? (Y/n)`, and Enter answers yes. Before,
|
|
1109
|
+
the hint was `(y/N)` and Enter went on to sign in with another account.
|
|
1110
|
+
Only `n` or `no` declines now; any other answer asks again.
|
|
1111
|
+
- naro-cli now ships `@opennextjs/cloudflare` 1.20.12 (was 1.20.2) and
|
|
1112
|
+
`wrangler` 4.148.0 (was 4.124.0). A Next.js 16.4 app that falls back from
|
|
1113
|
+
vinext to OpenNext now serves; before, it failed the smoke check on `/`
|
|
1114
|
+
with a 500. A `proxy.ts` is still rewritten to Edge middleware for that
|
|
1115
|
+
build. A Node.js-runtime middleware with no proxy file to rewrite is not
|
|
1116
|
+
deployed:
|
|
1117
|
+
`Node.js-runtime middleware (runtime: "nodejs") is only an experiment in OpenNext Cloudflare, and Naro does not deploy it. Remove runtime: "nodejs" to build it as Edge middleware`.
|
|
1118
|
+
The Next.js version checks keep their range and name Naro, not the
|
|
1119
|
+
adapter:
|
|
1120
|
+
`Next.js <version> is outside the range Naro verifies deploys on (>=15.5.21 <16 || >=16.2.11). The build may fail in ways Naro cannot explain.`
|
|
1121
|
+
and `Next.js <version> is too old to deploy. Naro deploys Next.js 15 or newer. Upgrade to Next.js 16.`
|
|
1122
|
+
- A Next.js app built with vinext reads its bindings with
|
|
1123
|
+
`getCloudflareContext().env`, as under OpenNext. Before, `env` was missing
|
|
1124
|
+
there, so `env.MY_BUCKET` was `undefined` and nothing was thrown. naro
|
|
1125
|
+
writes this Worker entry as `naro-worker.js`, so a project with its own
|
|
1126
|
+
file of that name is not built with vinext.
|
|
1127
|
+
- Build logs hide more secrets: upper-case names that end in `TOKEN`,
|
|
1128
|
+
`SECRET`, `PASSWORD`, `PASSWD` or `_KEY`, in `NAME=value` and
|
|
1129
|
+
`NAME: value` form; the credentials of any `Authorization` header (the
|
|
1130
|
+
scheme word stays); GitHub tokens; JWTs; PEM private keys; and credentials
|
|
1131
|
+
in any URL (`postgres://`, `redis://` and others). Before, only `Bearer`
|
|
1132
|
+
tokens, credentials in `http(s)://` URLs and three fixed names in
|
|
1133
|
+
`NAME=value` form were hidden.
|
|
1134
|
+
- `naro deploy` uploads the build output 24 files at a time instead of 8,
|
|
1135
|
+
with at most 16 MiB in flight, so a deploy of many small files reaches
|
|
1136
|
+
`READY` sooner.
|
|
1137
|
+
- The install of an npm or Yarn project during `naro deploy` no longer warns
|
|
1138
|
+
`npm warn Unknown env config "store-dir".` The pnpm store setting now goes
|
|
1139
|
+
to pnpm only.
|
|
1140
|
+
- Deployments in `--json` output (`naro deployments`, `naro inspect`) carry
|
|
1141
|
+
`environment`: the named environment the deployment went to, `null` for
|
|
1142
|
+
production and preview. `naro rollback` passes over deployments to a named
|
|
1143
|
+
environment.
|
|
1144
|
+
- `naro storage bucket update <name> --private` says that copies Naro's edge
|
|
1145
|
+
already holds can be served for up to 5 minutes (Storage 3-1h: the
|
|
1146
|
+
dispatcher keeps public downloads at the edge for up to 300 seconds).
|
|
1147
|
+
|
|
807
1148
|
### 0.17.0
|
|
808
1149
|
|
|
809
1150
|
- `naro domains add` prints one CNAME record and no TXT records. naro
|
|
@@ -1010,12 +1351,25 @@ command run non-interactively without `--yes` fails with
|
|
|
1010
1351
|
"success": false,
|
|
1011
1352
|
"code": "BUILD_FAILED",
|
|
1012
1353
|
"message": "…",
|
|
1013
|
-
"deploymentId": "…"
|
|
1354
|
+
"deploymentId": "…",
|
|
1355
|
+
"buildCode": "INSTALL_FAILED"
|
|
1014
1356
|
}
|
|
1015
1357
|
```
|
|
1016
1358
|
|
|
1359
|
+
A failed local build keeps the stable `BUILD_FAILED` code and adds
|
|
1360
|
+
`buildCode`, the code the dashboard shows for the deployment. It can be any
|
|
1361
|
+
deployment error code; the common ones are `NEXT_VERSION_UNSUPPORTED` (upgrade
|
|
1362
|
+
Next.js), `INSTALL_FAILED` (the dependency install), `ARTIFACT_INVALID` (static
|
|
1363
|
+
output a deploy cannot take, like a symbolic link), `FRAMEWORK_DETECTION_FAILED`
|
|
1364
|
+
(no framework found, or an Angular app without an output path) and
|
|
1365
|
+
`BUILD_FAILED` (the app's own build, or a failure that carried no code). A
|
|
1366
|
+
Next.js app is built by trying deployment strategies in turn: when the app's
|
|
1367
|
+
own `next build` fails, `buildCode` is `BUILD_FAILED`; when its own build did
|
|
1368
|
+
not fail but no strategy can ship it, `NO_DEPLOYMENT_STRATEGY`. Either way the message says
|
|
1369
|
+
what each strategy failed at.
|
|
1370
|
+
|
|
1017
1371
|
`--yes` (or `-y`) suppresses every prompt — destructive actions
|
|
1018
|
-
(production rollback/promote, env/domain removal, database reset, backend key
|
|
1372
|
+
(production rollback/promote, env/domain/environment removal, `naro env import`, turning off an environment's protection, database reset, backend key
|
|
1019
1373
|
rotation, policy removal and drop, opening the preview with
|
|
1020
1374
|
`naro protection disable`, replacing or removing the bypass secret) run
|
|
1021
1375
|
unconfirmed, so use it deliberately in
|
|
@@ -1028,16 +1382,22 @@ NARO_TOKEN=$(naro token) npx naro-cli deploy --prod --yes --json
|
|
|
1028
1382
|
```
|
|
1029
1383
|
|
|
1030
1384
|
`naro token` prints a short-lived (~1h) access token; generate one per run.
|
|
1031
|
-
`--token <t>` works too.
|
|
1032
|
-
|
|
1385
|
+
`--token <t>` works too. Every command picks its token the same way:
|
|
1386
|
+
`--token`, then `NARO_TOKEN`, then the stored session — so `naro whoami` in CI
|
|
1387
|
+
names the account `NARO_TOKEN` belongs to (`"tokenSource": "env"`).
|
|
1388
|
+
`naro token` is the exception: it always mints from the `naro login` session,
|
|
1389
|
+
so an expired `NARO_TOKEN` in the shell never comes back out of it. Locally,
|
|
1390
|
+
credentials live in `~/.naro/credentials.json` (0600).
|
|
1033
1391
|
|
|
1034
1392
|
## Environment variables
|
|
1035
1393
|
|
|
1036
1394
|
- Values are entered via hidden prompt or stdin — never as an argument:
|
|
1037
1395
|
`echo "$DATABASE_URL" | naro env add DATABASE_URL production --yes`
|
|
1038
|
-
- Targets: `production`, `preview`, `all` (default)
|
|
1396
|
+
- Targets: `production`, `preview`, `all` (default), or a named
|
|
1397
|
+
environment's slug: `naro env add DATABASE_URL qa`.
|
|
1039
1398
|
- `naro env pull` writes `.env.local` (preview + all vars by default,
|
|
1040
|
-
`--env production` for production values
|
|
1399
|
+
`--env production` for production values, `--env <name>` for an
|
|
1400
|
+
environment's).
|
|
1041
1401
|
|
|
1042
1402
|
## Configuration
|
|
1043
1403
|
|