@harperfast/template-react-ts-ssr-studio 1.13.3 → 1.13.5
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/.agents/skills/harper-best-practices/AGENTS.md +687 -453
- package/.agents/skills/harper-best-practices/SKILL.md +24 -21
- package/.agents/skills/harper-best-practices/rules/adding-tables-with-schemas.md +2 -0
- package/.agents/skills/harper-best-practices/rules/automatic-apis.md +2 -0
- package/.agents/skills/harper-best-practices/rules/caching.md +2 -0
- package/.agents/skills/harper-best-practices/rules/checking-authentication.md +2 -0
- package/.agents/skills/harper-best-practices/rules/custom-resources.md +2 -0
- package/.agents/skills/harper-best-practices/rules/defining-relationships.md +102 -40
- package/.agents/skills/harper-best-practices/rules/deploying-from-ci.md +121 -93
- package/.agents/skills/harper-best-practices/rules/deploying-to-harper-fabric.md +149 -103
- package/.agents/skills/harper-best-practices/rules/extending-tables.md +2 -0
- package/.agents/skills/harper-best-practices/rules/handling-binary-data.md +2 -0
- package/.agents/skills/harper-best-practices/rules/load-env.md +2 -0
- package/.agents/skills/harper-best-practices/rules/logging.md +2 -0
- package/.agents/skills/harper-best-practices/rules/programmatic-table-requests.md +124 -91
- package/.agents/skills/harper-best-practices/rules/querying-rest-apis.md +86 -82
- package/.agents/skills/harper-best-practices/rules/real-time-apps.md +2 -0
- package/.agents/skills/harper-best-practices/rules/schema-design-tooling.md +92 -59
- package/.agents/skills/harper-best-practices/rules/serving-web-content.md +2 -0
- package/.agents/skills/harper-best-practices/rules/typescript-type-stripping.md +2 -0
- package/.agents/skills/harper-best-practices/rules/using-blob-datatype.md +2 -0
- package/.agents/skills/harper-best-practices/rules/vector-indexing.md +2 -0
- package/.agents/skills/harper-best-practices/rules.manifest.yaml +44 -0
- package/agent/skills/harper-best-practices/AGENTS.md +687 -453
- package/agent/skills/harper-best-practices/SKILL.md +26 -21
- package/agent/skills/harper-best-practices/rules/adding-tables-with-schemas.md +2 -0
- package/agent/skills/harper-best-practices/rules/automatic-apis.md +2 -0
- package/agent/skills/harper-best-practices/rules/caching.md +2 -0
- package/agent/skills/harper-best-practices/rules/checking-authentication.md +2 -0
- package/agent/skills/harper-best-practices/rules/custom-resources.md +2 -0
- package/agent/skills/harper-best-practices/rules/defining-relationships.md +102 -40
- package/agent/skills/harper-best-practices/rules/deploying-from-ci.md +121 -93
- package/agent/skills/harper-best-practices/rules/deploying-to-harper-fabric.md +149 -103
- package/agent/skills/harper-best-practices/rules/extending-tables.md +2 -0
- package/agent/skills/harper-best-practices/rules/handling-binary-data.md +2 -0
- package/agent/skills/harper-best-practices/rules/load-env.md +2 -0
- package/agent/skills/harper-best-practices/rules/logging.md +2 -0
- package/agent/skills/harper-best-practices/rules/programmatic-table-requests.md +124 -91
- package/agent/skills/harper-best-practices/rules/querying-rest-apis.md +86 -82
- package/agent/skills/harper-best-practices/rules/real-time-apps.md +2 -0
- package/agent/skills/harper-best-practices/rules/schema-design-tooling.md +92 -59
- package/agent/skills/harper-best-practices/rules/serving-web-content.md +2 -0
- package/agent/skills/harper-best-practices/rules/typescript-type-stripping.md +2 -0
- package/agent/skills/harper-best-practices/rules/using-blob-datatype.md +2 -0
- package/agent/skills/harper-best-practices/rules/vector-indexing.md +2 -0
- package/agent/skills/harper-best-practices/rules.manifest.yaml +44 -0
- package/package.json +1 -1
- package/skills-lock.json +1 -1
|
@@ -23,17 +23,19 @@ metadata:
|
|
|
23
23
|
- reference/v5/operations-api/operations.md#Retrying an activation
|
|
24
24
|
- reference/v5/operations-api/operations.md#`list_deployments`
|
|
25
25
|
- reference/v5/operations-api/operations.md#`get_job`
|
|
26
|
-
sourceCommit:
|
|
27
|
-
inputHash:
|
|
26
|
+
sourceCommit: e69702c99845f2dd810cb32652d1a9e6b58c538b
|
|
27
|
+
inputHash: 44ee050eac4a5056
|
|
28
28
|
---
|
|
29
29
|
|
|
30
30
|
# Deploying to Harper Fabric
|
|
31
31
|
|
|
32
|
-
Instructions for the agent to
|
|
32
|
+
Instructions for the agent to deploy a Harper application to Harper Fabric using the CLI, verify certification, and roll back using a previous release's `deployment_id`.
|
|
33
|
+
|
|
34
|
+
**Instead of:** Docker Compose stacks; deploying several services separately. Use this rule rather than adding that service. See `harper-architecture`.
|
|
33
35
|
|
|
34
36
|
## When to Use
|
|
35
37
|
|
|
36
|
-
Apply this rule when deploying to a remote cluster,
|
|
38
|
+
Apply this rule when deploying a Harper application to a remote Harper Fabric cluster, checking whether a rolling deploy was certified on each node, or restoring a previous release without rebuilding. Also apply it when provisioning credentials for private-source deploys or staging a build for later activation.
|
|
37
39
|
|
|
38
40
|
## How It Works
|
|
39
41
|
|
|
@@ -44,10 +46,9 @@ Apply this rule when deploying to a remote cluster, choosing how it restarts, re
|
|
|
44
46
|
# Provide cluster username and password when prompted
|
|
45
47
|
```
|
|
46
48
|
|
|
47
|
-
|
|
48
|
-
- For a one-off command, `auth_username=` and `auth_password=` also work, and take precedence over environment variables and saved login tokens. Don't use them in production.
|
|
49
|
+
For CI/CD pipelines, use workload identity (OIDC) or a refresh token from `harper login --for-ci` instead of a password. See [deploying-from-ci.md](deploying-from-ci.md) for a complete GitHub Actions workflow. For a one-off command, `auth_username=` and `auth_password=` also work, and take precedence over environment variables and saved login tokens. Don't use them in production.
|
|
49
50
|
|
|
50
|
-
2. **Deploy
|
|
51
|
+
2. **Deploy the application**: Run `harper deploy` with the required parameters. Omit `package` to upload the current directory; supply a reference for npm, GitHub, or tarball sources.
|
|
51
52
|
|
|
52
53
|
```bash
|
|
53
54
|
harper deploy \
|
|
@@ -58,54 +59,38 @@ Apply this rule when deploying to a remote cluster, choosing how it restarts, re
|
|
|
58
59
|
replicated=true
|
|
59
60
|
```
|
|
60
61
|
|
|
61
|
-
|
|
62
|
-
- `project` defaults to the current directory's name for a directory deploy, or is derived from the package for a package deploy.
|
|
63
|
-
- A bare `target` host defaults to `https://<host>:9925`.
|
|
64
|
-
- Pass `json=true` to print the result as JSON instead of YAML.
|
|
65
|
-
- Every result carries a `deployment_id`, staged or not. It names this release when you go back to it later (step 4).
|
|
66
|
-
|
|
67
|
-
3. **Choose the restart, and read `certification`**: `restart=true` restarts Harper after deploying. On a cluster, use `restart=rolling`, the staggered, zero-downtime restart: the command exits `0` once the node you called has taken the release and started the rolling restart's job, and returns its `restartJobId`.
|
|
68
|
-
|
|
69
|
-
Both certify the release in a canary worker before rolling it out. The canary replaces worker 0 and loads every component, but is held out of traffic until it reports whether the deployed component loaded. Until then, the workers already running keep serving the previous release. A deploy that succeeds, and is not staged, reports the result in `certification`:
|
|
70
|
-
|
|
71
|
-
| `certification` | Meaning |
|
|
72
|
-
| --------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
73
|
-
| `certified` | The canary loaded the release, and the rollout went on. |
|
|
74
|
-
| `uncertified` | The rollout went on unchecked: the component ran nothing as it loaded (`loadComponent: dev-only`, an absent `if-installed` component, or safe mode), or no worker was replaced. |
|
|
75
|
-
| `unavailable` | The deploy restarted unchecked: no worker on this node loads the component, its `isolated` setting changed, it was already live, or it was deployed from a local directory (`package: file:<dir>`). |
|
|
76
|
-
| `not-requested` | The deploy did not restart. |
|
|
77
|
-
- **A rejected release fails the deploy.** If the canary throws while loading the component, exits, or doesn't report within a minute, the deploy fails with `400`. The release it replaced is made live again, and nothing is replicated to other nodes. The error's `certification` is an object whose `status` is `rejected`, or `interrupted` for a restart that stopped before the canary decided.
|
|
78
|
-
- **A release with nothing to go back to fails closed.** A rejected first deploy, or one whose previous release was not kept, stays on disk, but no worker on that node loads it, even after Harper restarts. `get_status` reports the component as failed. Deploy a fix, or once the cause is fixed, activate the same `deployment_id` again with `restart`.
|
|
79
|
-
- **A rolling deploy exits before every node has taken the release.** The other nodes stage it, and the job activates it on each in turn, each with a canary of its own. A node that rejects it keeps the previous release, or fails closed if it had none. Nothing is rolled back on the others, and the job fails naming each node that did not activate it. The deployment record reports `success` while the job runs and after it fails, so poll the job instead: `harper get_job id=<restartJobId>` ends `COMPLETE`, or `ERROR` with a `message` listing each node's outcome under `activated`.
|
|
80
|
-
- **Poll the node that received the deploy.** A job is recorded only on the node that ran it, so any other node answers `get_job` with an empty array. A role with an `operations` allowlist, or a token with an `operations` scope, must list `get_job` to poll it.
|
|
81
|
-
- Another deploy or `drop_component` of the component on that node is refused with `409` until the rollout has finished.
|
|
82
|
-
- A node running a version before v5.4.0 activates the release without a canary.
|
|
62
|
+
A bare `target` host defaults to `https://<host>:9925`. Use `restart=rolling` for a staggered, zero-downtime restart across the cluster. Pass `replicated=false` to deploy only to the node you called. Pass `json=true` to print the result as JSON instead of YAML.
|
|
83
63
|
|
|
84
|
-
|
|
64
|
+
3. **Choose a package source**: The `package` field accepts any valid npm dependency value.
|
|
65
|
+
|
|
66
|
+
| Source | Value |
|
|
67
|
+
| ------------------ | --------------------------------------------------------------------------------------------- |
|
|
68
|
+
| npm package | `package="@harperdb/status-check"` |
|
|
69
|
+
| GitHub (public) | `package="HarperFast/status-check"` or `package="https://github.com/HarperFast/status-check"` |
|
|
70
|
+
| Private repo (SSH) | `package="git+ssh://git@github.com:HarperDB/secret-app.git"` |
|
|
71
|
+
| Tarball | `package="https://example.com/application.tar.gz"` |
|
|
72
|
+
|
|
73
|
+
For git tags, use the `semver` directive: `HarperFast/application-template#semver:v1.0.0`. For an SSH-based private repo, register the key with `add_ssh_key` first.
|
|
74
|
+
|
|
75
|
+
4. **Provision credentials for private repositories**: Run `harper deploy setup=true` once per component and source. (With `provider=github-actions`, it sets up GitHub Actions OIDC deploys instead.) This requires `super_user` privileges and is interactive. It calls `get_secrets_public_key`, `set_secret`, and `grant_secret`. Run it with an administrative credential rather than the CI identity it provisions for:
|
|
85
76
|
|
|
86
77
|
```bash
|
|
87
|
-
harper
|
|
88
|
-
harper deploy project=my-app deployment_id=<id> restart=rolling
|
|
78
|
+
harper deploy setup=true
|
|
89
79
|
```
|
|
90
80
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
"restart": "rolling"
|
|
97
|
-
}
|
|
98
|
-
```
|
|
81
|
+
The command:
|
|
82
|
+
1. Fetches the cluster's public key with `get_secrets_public_key`.
|
|
83
|
+
2. Encrypts the token locally into an `enc:v1:` envelope.
|
|
84
|
+
3. Stores only the ciphertext with `set_secret`, scoped to the component, never in the global `processEnv` tier.
|
|
85
|
+
4. Grants the component permission to resolve it with `grant_secret`.
|
|
99
86
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
- A release made live before v5.3.0, or deployed from a `file:` directory, is not kept.
|
|
106
|
-
- Each node answers for itself. A node that never had the release, or no longer keeps it, answers `404`, which `deploy_component` reports as a failed peer. `409` means the build is there but can't be activated.
|
|
87
|
+
Use a **fine-grained** personal access token with **Contents: Read-only** on the target repository. Avoid broad tokens: the `gh` CLI session token typically carries `read:org`, `gist`, and `workflow` scopes across your whole account. Then deploy with `credential=true`:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
harper deploy by_ref=true credential=true restart=true replicated=true
|
|
91
|
+
```
|
|
107
92
|
|
|
108
|
-
5. **Stage a release to make live later**: `activate=false` (`activate: false` in the operation) builds and installs the release on each node without making it live, so the slow, fallible part happens when you choose and the cut-over is quick.
|
|
93
|
+
5. **Stage a release to make live later**: `activate=false` (`activate: false` in the operation) builds and installs the release on each node without making it live, so the slow, fallible part happens when you choose and the cut-over is quick. Cannot be combined with `restart`.
|
|
109
94
|
|
|
110
95
|
```json
|
|
111
96
|
{
|
|
@@ -116,6 +101,8 @@ Apply this rule when deploying to a remote cluster, choosing how it restarts, re
|
|
|
116
101
|
}
|
|
117
102
|
```
|
|
118
103
|
|
|
104
|
+
The response names the artifact waiting to be activated:
|
|
105
|
+
|
|
119
106
|
```json
|
|
120
107
|
{
|
|
121
108
|
"deployment_id": "a3f8c2d1-...",
|
|
@@ -123,99 +110,158 @@ Apply this rule when deploying to a remote cluster, choosing how it restarts, re
|
|
|
123
110
|
}
|
|
124
111
|
```
|
|
125
112
|
|
|
126
|
-
Make it live by deploying that `deployment_id`, as in step
|
|
127
|
-
- Pass `restart` on the activation, not the stage: `restart` is rejected alongside `activate: false`.
|
|
128
|
-
- The activation takes no `package`, `payload`, `credentials`, install options, or `urlPath`/`host`. They are rejected, because the staged build already decided them.
|
|
129
|
-
- Activating the release that is already live succeeds without a swap, so if an activation fails partway (a peer was unreachable, or the root config entry wasn't written), retry the same `deployment_id`. A node that already switched answers success, one still holding the build switches now, and one that holds neither answers `404`; the retry also finishes what the failed attempt left half done. With `restart`, a node where the release is already live still restarts every worker, isolated applications' included. Without it, the node marks the component as needing a restart.
|
|
130
|
-
- A staged build outlives later deploys: stage v2, deploy v3, and activating v2's id returns the component to v2.
|
|
131
|
-
- `file:` directory sources cannot be staged.
|
|
132
|
-
- Upgrade every node before staging. A node before v5.3.0 doesn't recognize `activate: false`, and serves the release immediately. A peer that doesn't confirm staging fails the operation with the node names.
|
|
113
|
+
Nothing about the running component changes, and `get_deployment` reports it as `staged`. Make it live by deploying that `deployment_id`, as in step 6. The activation takes no `package`, `payload`, `credentials`, install options, or `urlPath`/`host`. They are rejected, because the staged build already decided them.
|
|
133
114
|
|
|
134
|
-
6. **
|
|
115
|
+
6. **Activate a staged build or roll back**: Pass `deployment_id` with `restart` to make a staged build live, or to restore a release a later deploy replaced, with no rebuild or reinstall. Pass `restart` here rather than on the stage.
|
|
135
116
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
| npm package | `package="@harperdb/status-check"` |
|
|
140
|
-
| GitHub (public) | `package="HarperFast/status-check"` or `package="https://github.com/HarperFast/status-check"` |
|
|
141
|
-
| Private repo (SSH) | `package="git+ssh://git@github.com:HarperDB/secret-app.git"` |
|
|
142
|
-
| Tarball | `package="https://example.com/application.tar.gz"` |
|
|
117
|
+
```bash
|
|
118
|
+
harper deploy project=<name> deployment_id=<id> restart=true
|
|
119
|
+
```
|
|
143
120
|
|
|
144
|
-
|
|
121
|
+
Use `list_deployments` to find the `deployment_id` of the release to restore:
|
|
145
122
|
|
|
146
|
-
|
|
123
|
+
```json
|
|
124
|
+
{ "operation": "list_deployments", "project": "my-app", "status": "success", "limit": 20 }
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
- A `404` response means the id never existed on that node, was pruned, or the release was replaced and not kept. A `409` means the build exists but cannot be activated (e.g., belongs to another component, or files changed after staging).
|
|
128
|
+
- Kept releases and staged builds count against `deployment.stagingRetention.maxCount` (`stagingRetention` default: `5`). Each kept release is a full installed copy of the component, `node_modules` included, so budget disk for it. `0` keeps no replaced releases.
|
|
129
|
+
|
|
130
|
+
7. **Deploy by reference for a reproducible source**: `by_ref=true` sends a pinned git reference instead of uploading the working directory, and the cluster fetches and builds that exact commit. It resolves the repository's `origin` remote and the current commit, then deploys `package=git+https://github.com/<owner>/<repo>.git#<full commit SHA>`. Defaults to `HEAD`.
|
|
147
131
|
|
|
148
132
|
```bash
|
|
149
133
|
harper deploy by_ref=true restart=true replicated=true
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Deploy a specific tag or commit with `ref`:
|
|
137
|
+
|
|
138
|
+
```bash
|
|
150
139
|
harper deploy ref=v1.2.0 restart=true replicated=true
|
|
151
140
|
harper deploy ref=9f8c2a1 restart=true replicated=true
|
|
152
141
|
```
|
|
153
142
|
|
|
154
|
-
-
|
|
143
|
+
- Tags and branches are resolved to a full commit SHA before the deploy is sent. A `ref` that cannot be resolved stops the deploy — run `git fetch` and retry, or pass a full commit SHA.
|
|
155
144
|
- Any other `ref` must name something a clone can fetch: `refs/heads/*` or `refs/tags/*`, or a bare branch or tag name. A qualified ref outside those, such as `refs/pull/123/head`, is rejected up front.
|
|
156
|
-
- Commit and push first: the cluster clones from the remote. `by_ref` warns when the working tree is dirty, and when the commit isn't on any remote branch. The second check is skipped under GitHub Actions.
|
|
157
145
|
- On a GitHub Actions `pull_request` run, `by_ref` deploys the pull request's head commit. If the event payload isn't readable, the deploy stops; pass the commit explicitly.
|
|
158
|
-
-
|
|
146
|
+
- Commit and push first — the cluster clones from the remote and only sees pushed commits.
|
|
147
|
+
|
|
148
|
+
8. **Check certification after a rolling deploy**: A deploy with `restart=rolling` certifies the release in a canary worker before rolling it out. The deploy response includes a `certification` field:
|
|
149
|
+
|
|
150
|
+
| `certification` | Meaning |
|
|
151
|
+
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
152
|
+
| `certified` | The canary loaded the release; rollout proceeded. |
|
|
153
|
+
| `uncertified` | The rollout went on unchecked: the component ran nothing as it loaded (`loadComponent: dev-only`, an absent `if-installed` component, or safe mode), or no worker was replaced. |
|
|
154
|
+
| `unavailable` | Deploy restarted unchecked (no worker loads the component, `isolated` setting changed, already live, or `file:` directory source). |
|
|
155
|
+
| `not-requested` | The deploy did not restart. |
|
|
156
|
+
- **A rejected release fails the deploy.** If the canary throws while loading the component, exits, or doesn't report within a minute, the deploy fails with `400`. The release it replaced is made live again, and nothing is replicated to other nodes. The error carries the decision as an object in `certification` with `status` set to `rejected`, or to `interrupted` for a restart that stopped before the canary decided.
|
|
157
|
+
- **A release with nothing to go back to fails closed.** A rejected first deploy, or one whose previous release was not kept, stays on disk, but no worker on that node loads it, even after Harper restarts. `get_status` reports the component as failed and says why. Deploy a fix, or activate the same `deployment_id` again with `restart`.
|
|
158
|
+
- Another deploy or `drop_component` of the component on that node is refused with `409` until the rollout has finished.
|
|
159
159
|
|
|
160
|
-
|
|
160
|
+
9. **Wait for a rolling deploy to finish**: A `deploy_component` with `"restart": "rolling"` returns a `restartJobId`. Poll it with `get_job` to learn whether every node took the release.
|
|
161
161
|
|
|
162
|
-
```
|
|
163
|
-
|
|
162
|
+
```json
|
|
163
|
+
{ "operation": "get_job", "id": "4a982782-929a-4507-8794-26dae1132def" }
|
|
164
164
|
```
|
|
165
165
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
2. Encrypts the token locally into an `enc:v1:` envelope, so the plaintext never leaves your machine.
|
|
169
|
-
3. Stores only the ciphertext with `set_secret`, scoped to the component, never in the global `processEnv` tier.
|
|
170
|
-
4. Grants the component permission to resolve it with `grant_secret`.
|
|
171
|
-
5. Prints the `credentials` reference for the deploy to use.
|
|
172
|
-
|
|
173
|
-
Use a **fine-grained** personal access token with **Contents: Read-only** on that one repository. Avoid the `gh` CLI's session token: it typically carries `repo`, `read:org`, `gist`, and `workflow` scopes across your whole account. The sealed token is durable, and later deploys reuse it.
|
|
166
|
+
`get_job` returns status `COMPLETE`, `IN_PROGRESS`, or `ERROR`. It answers only on the node that ran the job. A deploy-only role that waits for rolling deploys must include `get_job` in its operations allowlist.
|
|
167
|
+
- `list_deployments` returns records newest first. Filter by `project` and `status`; omit `limit` to return every matching record. A deploy in progress reads `pending`, or `loading`, until its `completed_at` is set.
|
|
174
168
|
|
|
175
169
|
## Examples
|
|
176
170
|
|
|
177
|
-
|
|
171
|
+
### Full rolling deploy from a pinned tag
|
|
178
172
|
|
|
179
173
|
```bash
|
|
174
|
+
# Authenticate once
|
|
180
175
|
harper login https://my-cluster.harperdbcloud.com
|
|
176
|
+
|
|
177
|
+
# Deploy a pinned release with rolling restart
|
|
181
178
|
harper deploy \
|
|
182
179
|
project=my-app \
|
|
183
|
-
|
|
180
|
+
ref=v1.2.0 \
|
|
184
181
|
target=https://my-cluster.harperdbcloud.com \
|
|
185
182
|
restart=rolling \
|
|
186
|
-
|
|
187
|
-
# Poll the node that received the deploy until the job is COMPLETE or ERROR
|
|
188
|
-
harper get_job id=<restartJobId from deploy.json> json=true
|
|
183
|
+
replicated=true
|
|
189
184
|
```
|
|
190
185
|
|
|
191
|
-
|
|
186
|
+
### Stage a build, then activate in a maintenance window
|
|
192
187
|
|
|
193
|
-
```
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
188
|
+
```json
|
|
189
|
+
{
|
|
190
|
+
"operation": "deploy_component",
|
|
191
|
+
"project": "my-app",
|
|
192
|
+
"package": "npm:@my-org/my-app@1.2.3",
|
|
193
|
+
"activate": false
|
|
194
|
+
}
|
|
197
195
|
```
|
|
198
196
|
|
|
199
|
-
|
|
197
|
+
Response:
|
|
200
198
|
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
199
|
+
```json
|
|
200
|
+
{
|
|
201
|
+
"deployment_id": "a3f8c2d1-...",
|
|
202
|
+
"message": "Staged: my-app. Deploy it with deploy_component deployment_id=a3f8c2d1-..."
|
|
203
|
+
}
|
|
205
204
|
```
|
|
206
205
|
|
|
207
|
-
|
|
206
|
+
Activate later:
|
|
208
207
|
|
|
209
|
-
```
|
|
210
|
-
|
|
208
|
+
```json
|
|
209
|
+
{
|
|
210
|
+
"operation": "deploy_component",
|
|
211
|
+
"project": "my-app",
|
|
212
|
+
"deployment_id": "a3f8c2d1-...",
|
|
213
|
+
"restart": true
|
|
214
|
+
}
|
|
211
215
|
```
|
|
212
216
|
|
|
213
|
-
|
|
217
|
+
### Roll back to a previous release
|
|
214
218
|
|
|
215
|
-
```
|
|
216
|
-
|
|
217
|
-
|
|
219
|
+
```json
|
|
220
|
+
{
|
|
221
|
+
"operation": "list_deployments",
|
|
222
|
+
"project": "my-app"
|
|
223
|
+
}
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
Then:
|
|
218
227
|
|
|
219
|
-
|
|
220
|
-
|
|
228
|
+
```json
|
|
229
|
+
{
|
|
230
|
+
"operation": "deploy_component",
|
|
231
|
+
"project": "my-app",
|
|
232
|
+
"deployment_id": "<id of the deployment you want back>",
|
|
233
|
+
"restart": true
|
|
234
|
+
}
|
|
221
235
|
```
|
|
236
|
+
|
|
237
|
+
### Rejected canary — error response shape
|
|
238
|
+
|
|
239
|
+
```json
|
|
240
|
+
{
|
|
241
|
+
"error": "my-app was not deployed: release 9b2e... failed to load in its canary worker: my-app.jsResource: ... Deployment a3f8c2d1..., the release it replaced, is live again. No other node received it. Deploy a fix, or activate deployment 9b2e... again once the cause is fixed.",
|
|
242
|
+
"deployment_id": "9b2e...",
|
|
243
|
+
"certification": {
|
|
244
|
+
"status": "rejected",
|
|
245
|
+
"reason": "my-app.jsResource: ...",
|
|
246
|
+
"failures": [
|
|
247
|
+
{ "key": "my-app.jsResource", "name": "ResourceLoadError", "message": "...", "stack": "..." }
|
|
248
|
+
],
|
|
249
|
+
"restored": "a3f8c2d1...",
|
|
250
|
+
"failed_closed": false
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
## Notes
|
|
256
|
+
|
|
257
|
+
- `harper login` stores a token; subsequent `harper deploy` calls to the same target need no credentials. See [creating-a-fabric-account-and-cluster.md](creating-a-fabric-account-and-cluster.md) for cluster setup.
|
|
258
|
+
- For GitHub Actions, prefer OIDC workload identity over stored tokens. See [deploying-from-ci.md](deploying-from-ci.md).
|
|
259
|
+
- `restart=rolling` and `activate=false` cannot be combined.
|
|
260
|
+
- `deployment_id` activation takes no `package`, `payload`, `credentials`, install options, `urlPath`, or `host` — supplying them is rejected.
|
|
261
|
+
- `file:` directory sources (`package: file:<dir>`) cannot be staged and are not kept as rollback targets.
|
|
262
|
+
- `stagingRetention.maxCount` (default `5`) caps staged builds and kept replaced releases together per component.
|
|
263
|
+
- `get_job` on a `restartJobId` answers only on the node that received the deploy; any other node returns an empty array.
|
|
264
|
+
- A rolling deploy's record reads `rolling_out` until the job has visited every node; filter `list_deployments` without `status` and check each record's `status` for a finished value (`success`, `partial`, `failed`, `staged`). `completed_at` alone does not confirm a finished state, since a `rolling_out` record already has it.
|
|
265
|
+
- `enc:v1:` envelopes store only ciphertext — plaintext never leaves your machine and never appears in operation logs or replication.
|
|
266
|
+
- Tags used in `refs/tags` are resolved to a commit SHA before the deploy is sent; a tag that moves mid-deploy cannot cause nodes to run different code.
|
|
267
|
+
- `super_user` is required to run `harper deploy setup=true`.
|
|
@@ -14,6 +14,8 @@ metadata:
|
|
|
14
14
|
|
|
15
15
|
Instructions for the agent to follow when adding custom logic to automatically generated table resources in Harper.
|
|
16
16
|
|
|
17
|
+
**Instead of:** Middleware and controllers wrapped around CRUD routes. Use this rule rather than adding that service. See `harper-architecture`.
|
|
18
|
+
|
|
17
19
|
## When to Use
|
|
18
20
|
|
|
19
21
|
Apply this rule when you need to override or augment the default HTTP handler behavior (GET, POST, PUT, PATCH, DELETE) for a Harper table resource. Use it when a table needs computed properties, input transformation, authorization checks, or custom error responses.
|
|
@@ -15,6 +15,8 @@ metadata:
|
|
|
15
15
|
|
|
16
16
|
Instructions for the agent to follow when storing and serving binary data (images, audio, arbitrary content types) in Harper.
|
|
17
17
|
|
|
18
|
+
**Instead of:** S3 or GCS buckets for app-managed files. Use this rule rather than adding that service. See `harper-architecture`.
|
|
19
|
+
|
|
18
20
|
## When to Use
|
|
19
21
|
|
|
20
22
|
Apply this rule when a Harper resource needs to accept, store, or serve binary payloads such as images, audio files, or calendar data. Use it when clients send raw binary via `PUT`/`POST`, or when they send `base64`-encoded data inside a JSON body.
|
|
@@ -15,6 +15,8 @@ metadata:
|
|
|
15
15
|
|
|
16
16
|
Instructions for the agent to follow when loading environment variables from `.env` files into a Harper application using the `loadEnv` plugin.
|
|
17
17
|
|
|
18
|
+
**Instead of:** `dotenv`. Use this rule rather than adding that service. See `harper-architecture`.
|
|
19
|
+
|
|
18
20
|
## When to Use
|
|
19
21
|
|
|
20
22
|
Apply this rule when a Harper application needs to supply secrets, API endpoints, or other configuration values to component code via `process.env` without hardcoding them. Use this whenever a `.env` file must be loaded at application startup.
|
|
@@ -16,6 +16,8 @@ metadata:
|
|
|
16
16
|
|
|
17
17
|
Instructions for the agent to follow when implementing logging in Harper applications, including direct logger usage, tagged loggers, and console capture behavior.
|
|
18
18
|
|
|
19
|
+
**Instead of:** Separate log shippers for app logs (pino or winston transports). Use this rule rather than adding that service. See `harper-architecture`.
|
|
20
|
+
|
|
19
21
|
## When to Use
|
|
20
22
|
|
|
21
23
|
Apply this rule when writing any JavaScript component, plugin, or resource that needs to emit structured log entries, filter logs by component, or capture existing `console.log` output into Harper's log system. Use it whenever you need to understand log levels, log entry format, or the `logger` global API.
|