@appshell/cli 1.0.0-alpha.106 → 1.0.0-alpha.108
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 +92 -26
- package/dist/main.js +5 -5
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -50,20 +50,21 @@ Commands:
|
|
|
50
50
|
appshell logout Discard the stored credential for a registry
|
|
51
51
|
appshell publish Publish a package to the appshell registry
|
|
52
52
|
appshell unpublish <name> <version> Remove a published package version
|
|
53
|
-
appshell trust Trust CI workflows to publish into a scope
|
|
54
|
-
without a
|
|
53
|
+
appshell trust Trust CI workflows to publish into a scope, or
|
|
54
|
+
workloads to apply its applications, without a
|
|
55
|
+
stored secret
|
|
55
56
|
appshell outdated Analyzes shared dependencies for outdated versions
|
|
56
57
|
```
|
|
57
58
|
|
|
58
59
|
These global options apply to every command:
|
|
59
60
|
|
|
60
|
-
| Option
|
|
61
|
-
|
|
|
62
|
-
| `-r, --registry`
|
|
63
|
-
| `-a, --application` | —
|
|
64
|
-
| `--scopeId`
|
|
65
|
-
| `-k, --apiKey`
|
|
66
|
-
| `-v, --verbose`
|
|
61
|
+
| Option | Default | Purpose |
|
|
62
|
+
| ------------------- | ----------------------- | -------------------------------------------------- |
|
|
63
|
+
| `-r, --registry` | `http://localhost:7070` | Registry to operate against |
|
|
64
|
+
| `-a, --application` | — | Application, as `name` or `scope/name` |
|
|
65
|
+
| `--scopeId` | `default` | Scope owning unqualified packages and applications |
|
|
66
|
+
| `-k, --apiKey` | `""` | Api key, when the registry expects one |
|
|
67
|
+
| `-v, --verbose` | `false` | Verbose output |
|
|
67
68
|
|
|
68
69
|
`--registry` and `--application` fall back to `APPSHELL_REGISTRY` /
|
|
69
70
|
`APPSHELL_APPLICATION`, then to `~/.appshell/config`. Set them once instead of
|
|
@@ -77,12 +78,12 @@ appshell config list
|
|
|
77
78
|
|
|
78
79
|
## Vocabulary
|
|
79
80
|
|
|
80
|
-
| Term
|
|
81
|
-
|
|
|
82
|
-
| **Scope**
|
|
83
|
-
| **Package**
|
|
84
|
-
| **Application** | `acme/storefront`
|
|
85
|
-
| **Remote**
|
|
81
|
+
| Term | Identity | What it is |
|
|
82
|
+
| --------------- | --------------------- | ---------------------------------------------- |
|
|
83
|
+
| **Scope** | `acme` | Namespace and permission boundary |
|
|
84
|
+
| **Package** | `acme/checkout@1.5.0` | What you publish. Immutable, digest-addressed |
|
|
85
|
+
| **Application** | `acme/storefront` | The composition the registry serves |
|
|
86
|
+
| **Remote** | `PingModule/Ping` | What the browser loads, over Module Federation |
|
|
86
87
|
|
|
87
88
|
## Authenticating
|
|
88
89
|
|
|
@@ -107,13 +108,13 @@ Publishing is idempotent: the same content under the same version is a no-op.
|
|
|
107
108
|
Different content under an existing version is rejected unless the registry allows
|
|
108
109
|
forcing. When `--application` resolves, publish also **activates** the version there.
|
|
109
110
|
|
|
110
|
-
| Option
|
|
111
|
-
|
|
|
112
|
-
| `-t, --template`
|
|
113
|
-
| `--name`
|
|
114
|
-
| `--package-version` | the `package.json` version
|
|
115
|
-
| `--visibility`
|
|
116
|
-
| `-w, --watch`
|
|
111
|
+
| Option | When omitted | Purpose |
|
|
112
|
+
| ------------------- | ---------------------------------- | --------------------------------------- |
|
|
113
|
+
| `-t, --template` | `appshell.template.json` | Template to process |
|
|
114
|
+
| `--name` | the unscoped `package.json` name | Package name |
|
|
115
|
+
| `--package-version` | the `package.json` version | Version to publish as |
|
|
116
|
+
| `--visibility` | the registry defaults to `private` | Whether other scopes may activate it |
|
|
117
|
+
| `-w, --watch` | `false` | Republish whenever the template changes |
|
|
117
118
|
|
|
118
119
|
```bash
|
|
119
120
|
appshell unpublish checkout 1.5.0
|
|
@@ -203,6 +204,71 @@ locally where the webpack plugin already publishes and activates on every build.
|
|
|
203
204
|
`${VAR}` placeholders expand from the environment exactly as they do in
|
|
204
205
|
`appshell.config.yaml`.
|
|
205
206
|
|
|
207
|
+
## Trusted deployment
|
|
208
|
+
|
|
209
|
+
A workload can apply an application with its own OIDC identity, so the job or controller
|
|
210
|
+
that keeps it at its declared state holds no secret either: a GitHub Actions workflow, or
|
|
211
|
+
a Kubernetes service account. The application's scope owner, or an organization admin,
|
|
212
|
+
records which workload may — the application must exist first:
|
|
213
|
+
|
|
214
|
+
```bash
|
|
215
|
+
# A GitHub Actions workflow, by repository ids as for publishing
|
|
216
|
+
appshell trust add acme --application storefront \
|
|
217
|
+
--github acme/deploy --workflow deploy.yml --environment production
|
|
218
|
+
|
|
219
|
+
# A Kubernetes service account, under its cluster's OIDC issuer
|
|
220
|
+
appshell trust add acme --application storefront \
|
|
221
|
+
--kubernetes https://oidc.eks.us-east-1.amazonaws.com/id/EXAMPLE \
|
|
222
|
+
--namespace appshell --service-account deployer
|
|
223
|
+
|
|
224
|
+
appshell trust list acme --application storefront
|
|
225
|
+
appshell trust remove acme 1b2c3d4e --application storefront
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
The cluster issuer is taken exactly as given and must be what the cluster's service
|
|
229
|
+
account tokens carry (`kubectl get --raw /.well-known/openid-configuration` prints it). The
|
|
230
|
+
registry fetches its keys from there, so the issuer's discovery document must be public:
|
|
231
|
+
EKS, GKE and AKS serve one, and a self-managed cluster needs its own published.
|
|
232
|
+
|
|
233
|
+
**From GitHub Actions**, with `id-token: write` and no `APPSHELL_TOKEN` or stored login,
|
|
234
|
+
`appshell app apply` asks the runner for a token for the registry's deploy audience — the
|
|
235
|
+
registry url with `/deploy`, or `APPSHELL_DEPLOY_AUDIENCE` when the registry's operator set
|
|
236
|
+
`TRUSTED_DEPLOYMENT_AUDIENCE` to something else — and applies with it:
|
|
237
|
+
|
|
238
|
+
```yaml
|
|
239
|
+
permissions: { id-token: write, contents: read }
|
|
240
|
+
jobs:
|
|
241
|
+
deploy:
|
|
242
|
+
runs-on: ubuntu-latest
|
|
243
|
+
environment: production
|
|
244
|
+
steps:
|
|
245
|
+
- uses: actions/checkout@v4
|
|
246
|
+
- run: npx appshell app apply -f appshell.app.yaml --registry https://registry.appshell.org
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
**From Kubernetes**, project a token for that audience and present it:
|
|
250
|
+
|
|
251
|
+
```yaml
|
|
252
|
+
volumes:
|
|
253
|
+
- name: appshell-token
|
|
254
|
+
projected:
|
|
255
|
+
sources:
|
|
256
|
+
- serviceAccountToken:
|
|
257
|
+
audience: https://registry.appshell.org/deploy
|
|
258
|
+
expirationSeconds: 3600 # at most an hour is accepted
|
|
259
|
+
path: token
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
```bash
|
|
263
|
+
APPSHELL_TOKEN=$(cat /var/run/appshell/token) appshell app apply -f appshell.app.yaml
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
A workload may only apply, only an application that already exists, and only one named as
|
|
267
|
+
`scope/name` in the resource, since it has no scope of its own. A refusal says what to
|
|
268
|
+
check: `appshell trust list <scope> --application <name>` against the job or account, or
|
|
269
|
+
the audience setting. Against a registry without trusted deployment enabled
|
|
270
|
+
(`AUTH_MODE=none`, every local one), apply retries once without a token.
|
|
271
|
+
|
|
206
272
|
## Inspecting an application
|
|
207
273
|
|
|
208
274
|
```bash
|
|
@@ -263,11 +329,11 @@ run it directly when you want the manifest as a build artifact.
|
|
|
263
329
|
appshell generate manifest --template dist/appshell.template.json
|
|
264
330
|
```
|
|
265
331
|
|
|
266
|
-
| Option
|
|
267
|
-
|
|
|
332
|
+
| Option | Default | Purpose |
|
|
333
|
+
| ---------------- | ------------------------ | ------------------- |
|
|
268
334
|
| `-t, --template` | `appshell.template.json` | Template to process |
|
|
269
|
-
| `-o, --outDir`
|
|
270
|
-
| `-f, --outFile`
|
|
335
|
+
| `-o, --outDir` | `dist` | Output location |
|
|
336
|
+
| `-f, --outFile` | `appshell.manifest.json` | Output filename |
|
|
271
337
|
|
|
272
338
|
**Where does the template come from?**
|
|
273
339
|
|