@harperfast/template-vue-ts-studio 1.13.0 → 1.13.2
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 +553 -141
- package/.agents/skills/harper-best-practices/SKILL.md +2 -1
- package/.agents/skills/harper-best-practices/rules/creating-a-fabric-account-and-cluster.md +7 -4
- package/.agents/skills/harper-best-practices/rules/creating-harper-apps.md +71 -4
- package/.agents/skills/harper-best-practices/rules/deploying-from-ci.md +358 -0
- package/.agents/skills/harper-best-practices/rules/deploying-to-harper-fabric.md +135 -91
- package/.agents/skills/harper-best-practices/rules/load-env.md +37 -49
- package/.agents/skills/harper-best-practices/rules.manifest.yaml +184 -8
- package/agent/skills/harper-best-practices/AGENTS.md +553 -141
- package/agent/skills/harper-best-practices/SKILL.md +2 -1
- package/agent/skills/harper-best-practices/rules/creating-a-fabric-account-and-cluster.md +7 -4
- package/agent/skills/harper-best-practices/rules/creating-harper-apps.md +71 -4
- package/agent/skills/harper-best-practices/rules/deploying-from-ci.md +358 -0
- package/agent/skills/harper-best-practices/rules/deploying-to-harper-fabric.md +135 -91
- package/agent/skills/harper-best-practices/rules/load-env.md +37 -49
- package/agent/skills/harper-best-practices/rules.manifest.yaml +184 -8
- package/package.json +1 -1
- package/skills-lock.json +1 -1
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: deploying-to-harper-fabric
|
|
3
|
-
description:
|
|
3
|
+
description: >-
|
|
4
|
+
How to deploy a Harper application to Harper Fabric with the CLI, check that
|
|
5
|
+
the release was certified, and roll back by activating a previous release's
|
|
6
|
+
`deployment_id`.
|
|
4
7
|
metadata:
|
|
5
8
|
mode: generate
|
|
6
9
|
sources:
|
|
@@ -8,30 +11,43 @@ metadata:
|
|
|
8
11
|
- >-
|
|
9
12
|
fabric/cluster-creation-management.md#Connecting the Harper CLI to a
|
|
10
13
|
Cluster
|
|
11
|
-
|
|
12
|
-
|
|
14
|
+
- reference/v5/cli/commands.md#Parameters
|
|
15
|
+
- reference/v5/cli/operations-api-commands.md#General Syntax
|
|
16
|
+
- >-
|
|
17
|
+
reference/v5/operations-api/operations.md#Certifying a release in a canary
|
|
18
|
+
worker
|
|
19
|
+
- >-
|
|
20
|
+
reference/v5/operations-api/operations.md#Staging a build and activating
|
|
21
|
+
it later
|
|
22
|
+
- reference/v5/operations-api/operations.md#Going back to a previous release
|
|
23
|
+
- reference/v5/operations-api/operations.md#Retrying an activation
|
|
24
|
+
- reference/v5/operations-api/operations.md#`list_deployments`
|
|
25
|
+
- reference/v5/operations-api/operations.md#`get_job`
|
|
26
|
+
sourceCommit: 81c1b0e8ce8da147a662f2ead72ce0c8769d0177
|
|
27
|
+
inputHash: 899b47f26b8dca34
|
|
13
28
|
---
|
|
14
29
|
|
|
15
30
|
# Deploying to Harper Fabric
|
|
16
31
|
|
|
17
|
-
Instructions for the agent to follow when deploying a Harper application to a remote Harper
|
|
32
|
+
Instructions for the agent to follow when deploying a Harper application to a Harper Fabric cluster, or any remote Harper instance, with the `harper` CLI, and when checking, staging, or going back to a release.
|
|
18
33
|
|
|
19
34
|
## When to Use
|
|
20
35
|
|
|
21
|
-
Apply this rule when deploying
|
|
22
|
-
|
|
23
|
-
See [creating-a-fabric-account-and-cluster.md](creating-a-fabric-account-and-cluster.md) to set up a cluster before deploying.
|
|
36
|
+
Apply this rule when deploying to a remote cluster, choosing how it restarts, reading a deploy's `certification`, staging a release to make live later, or rolling back to a previous release. To deploy from CI with no stored credential, see [deploying-from-ci.md](deploying-from-ci.md). To set up the cluster first, see [creating-a-fabric-account-and-cluster.md](creating-a-fabric-account-and-cluster.md).
|
|
24
37
|
|
|
25
38
|
## How It Works
|
|
26
39
|
|
|
27
|
-
1. **
|
|
40
|
+
1. **Log in to the cluster once**: Pass the cluster's **Application URL**, from its **Config → Overview** page, to `harper login`. The CLI stores the token, so later commands don't repeat credentials. If the current directory already has a `.env` file that sets no target, it also appends `HARPER_CLI_TARGET` to it.
|
|
28
41
|
|
|
29
42
|
```bash
|
|
30
43
|
harper login <Application URL>
|
|
31
44
|
# Provide cluster username and password when prompted
|
|
32
45
|
```
|
|
33
46
|
|
|
34
|
-
|
|
47
|
+
- For CI/CD on GitHub Actions, use workload identity (OIDC) instead, so the pipeline stores no Harper credential. From v5.4.0, `harper deploy setup=true provider=github-actions` sets it up in one command: see [deploying-from-ci.md](deploying-from-ci.md). Elsewhere, give the pipeline a refresh token from `harper login --for-ci` rather than a password.
|
|
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
|
+
|
|
50
|
+
2. **Deploy with a restart**: Run `harper deploy`, with `restart=true` or `restart=rolling` so the release is certified before it serves (step 3).
|
|
35
51
|
|
|
36
52
|
```bash
|
|
37
53
|
harper deploy \
|
|
@@ -42,136 +58,164 @@ See [creating-a-fabric-account-and-cluster.md](creating-a-fabric-account-and-clu
|
|
|
42
58
|
replicated=true
|
|
43
59
|
```
|
|
44
60
|
|
|
45
|
-
|
|
61
|
+
- On Harper Pro and Fabric, a deploy goes to every node in the cluster unless you pass `replicated=false`. Harper core on its own does not replicate.
|
|
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).
|
|
46
66
|
|
|
47
|
-
|
|
48
|
-
| ------------------------------------------------------------ | ---------------------------------------------- |
|
|
49
|
-
| _(omit)_ | Package and deploy the current local directory |
|
|
50
|
-
| `package="@harperdb/status-check"` | npm package |
|
|
51
|
-
| `package="HarperFast/status-check"` | GitHub shorthand |
|
|
52
|
-
| `package="https://github.com/HarperFast/status-check"` | GitHub URL |
|
|
53
|
-
| `package="git+ssh://git@github.com:HarperDB/secret-app.git"` | Private repo (SSH) |
|
|
54
|
-
| `package="https://example.com/application.tar.gz"` | Tarball |
|
|
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`.
|
|
55
68
|
|
|
56
|
-
|
|
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`:
|
|
57
70
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
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.
|
|
61
83
|
|
|
62
|
-
4. **
|
|
84
|
+
4. **Go back to a previous release by its `deployment_id`**: When a deploy replaces the live release, Harper keeps the replaced one under the `deployment_id` that deployed it. Activating that id puts back the exact installed release with no fetch, rebuild, or reinstall, where deploying an older commit installs it again from source. Find the id with `list_deployments`, then deploy it. On a cluster, restart with `rolling` and poll its job (step 3):
|
|
63
85
|
|
|
64
86
|
```bash
|
|
65
|
-
harper
|
|
87
|
+
harper list_deployments project=my-app status=success
|
|
88
|
+
harper deploy project=my-app deployment_id=<id> restart=rolling
|
|
66
89
|
```
|
|
67
90
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
91
|
+
```json
|
|
92
|
+
{
|
|
93
|
+
"operation": "deploy_component",
|
|
94
|
+
"project": "my-app",
|
|
95
|
+
"deployment_id": "<id of the deployment you want back>",
|
|
96
|
+
"restart": "rolling"
|
|
97
|
+
}
|
|
98
|
+
```
|
|
71
99
|
|
|
72
|
-
|
|
100
|
+
- `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.
|
|
101
|
+
- The newest `success` is not necessarily the release every node is serving: a rolling deploy's record says `success` before the other nodes have taken the release, and keeps saying it if one rejects it.
|
|
102
|
+
- Redeploy an older commit by `ref` (step 7) only when the release is no longer kept.
|
|
103
|
+
- The activation restores the root config entry that deployment published. The release it replaces is kept in turn, so you can go forward again the same way.
|
|
104
|
+
- Kept releases and staged builds count against `deployment.stagingRetention.maxCount` (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 release.
|
|
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.
|
|
107
|
+
|
|
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. The result's `deployment_id` names the staged build:
|
|
109
|
+
|
|
110
|
+
```json
|
|
111
|
+
{
|
|
112
|
+
"operation": "deploy_component",
|
|
113
|
+
"project": "my-app",
|
|
114
|
+
"package": "npm:@my-org/my-app@1.2.3",
|
|
115
|
+
"activate": false
|
|
116
|
+
}
|
|
117
|
+
```
|
|
73
118
|
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
|
|
119
|
+
```json
|
|
120
|
+
{
|
|
121
|
+
"deployment_id": "a3f8c2d1-...",
|
|
122
|
+
"message": "Staged: my-app. Deploy it with deploy_component deployment_id=a3f8c2d1-..."
|
|
123
|
+
}
|
|
77
124
|
```
|
|
78
125
|
|
|
79
|
-
|
|
126
|
+
Make it live by deploying that `deployment_id`, as in step 4. Nothing changes until then, and `get_deployment` reports it as `staged`.
|
|
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.
|
|
80
133
|
|
|
81
|
-
|
|
134
|
+
6. **Choose a package source**: The `package` field accepts any valid npm dependency value:
|
|
82
135
|
|
|
83
|
-
|
|
136
|
+
| Source | `package` value |
|
|
137
|
+
| ----------------------- | --------------------------------------------------------------------------------------------- |
|
|
138
|
+
| Current local directory | Omit `package` |
|
|
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"` |
|
|
84
143
|
|
|
85
|
-
|
|
86
|
-
harper deploy project=<name> deployment_id=<id> restart=true
|
|
87
|
-
```
|
|
144
|
+
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.
|
|
88
145
|
|
|
89
|
-
|
|
146
|
+
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>`. Pass `ref` to deploy a specific tag or commit instead of `HEAD`; it implies `by_ref`.
|
|
90
147
|
|
|
91
148
|
```bash
|
|
92
|
-
harper deploy
|
|
149
|
+
harper deploy by_ref=true restart=true replicated=true
|
|
150
|
+
harper deploy ref=v1.2.0 restart=true replicated=true
|
|
151
|
+
harper deploy ref=9f8c2a1 restart=true replicated=true
|
|
93
152
|
```
|
|
94
153
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
5. Prints the `credentials` reference for the deploy to use.
|
|
101
|
-
|
|
102
|
-
The plaintext never leaves your machine. Prefer a **fine-grained** personal access token with **Contents: Read-only** on the target repository. Avoid broad session tokens — they typically carry `read:org`, `gist`, and `workflow` scopes across your whole account.
|
|
154
|
+
- A `ref` is resolved to a full commit SHA before the deploy is sent, from the local checkout or the remote. A full commit SHA is accepted directly. If a `ref` can't be resolved, the deploy stops: run `git fetch` and retry, or pass a full SHA.
|
|
155
|
+
- 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
|
+
- 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
|
+
- The cluster installs and builds from source on each node, so commit your lockfile if the build must be reproducible. If the build can't run on the node, deploy the built output as a payload instead.
|
|
103
159
|
|
|
104
|
-
|
|
160
|
+
8. **Deploy a private repository by reference**: Pass `credential=true` with `by_ref=true`. The CLI attaches a `credentials` reference, and the cluster resolves the secret in memory at clone time, so no token travels in the operation body or lands on disk.
|
|
105
161
|
|
|
106
162
|
```bash
|
|
107
163
|
harper deploy by_ref=true credential=true restart=true replicated=true
|
|
108
164
|
```
|
|
109
165
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
auth_username=<username> \
|
|
117
|
-
auth_password=<password> \
|
|
118
|
-
target=<remote> \
|
|
119
|
-
restart=true \
|
|
120
|
-
replicated=true
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
9. **Use CI/CD pipelines**: For GitHub Actions, use workload identity (OIDC) so no Harper credential is stored in the pipeline. Alternatively, supply a refresh token from `harper login --for-ci`. On a `pull_request` run, pass the head SHA explicitly:
|
|
166
|
+
Provision that credential once per component and source with `harper deploy setup=true`. (With `provider=github-actions`, it sets up GitHub Actions deploys instead: see [deploying-from-ci.md](deploying-from-ci.md).) It is interactive, and its operations require **super_user**, so run it with an administrative credential, not the CI identity it provisions for. It:
|
|
167
|
+
1. Fetches the cluster's public key with `get_secrets_public_key`.
|
|
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.
|
|
124
172
|
|
|
125
|
-
|
|
126
|
-
harper deploy ref=${{ github.event.pull_request.head.sha }} restart=true replicated=true
|
|
127
|
-
```
|
|
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.
|
|
128
174
|
|
|
129
175
|
## Examples
|
|
130
176
|
|
|
131
|
-
**
|
|
177
|
+
**Deploy after logging in, and wait for a rolling restart:**
|
|
132
178
|
|
|
133
179
|
```bash
|
|
134
180
|
harper login https://my-cluster.harperdbcloud.com
|
|
135
181
|
harper deploy \
|
|
136
182
|
project=my-app \
|
|
183
|
+
package="HarperFast/my-app" \
|
|
137
184
|
target=https://my-cluster.harperdbcloud.com \
|
|
138
|
-
restart=
|
|
139
|
-
|
|
185
|
+
restart=rolling \
|
|
186
|
+
json=true > deploy.json
|
|
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
|
|
140
189
|
```
|
|
141
190
|
|
|
142
|
-
**
|
|
191
|
+
**Roll back to the release a deploy replaced, node by node:**
|
|
143
192
|
|
|
144
193
|
```bash
|
|
145
|
-
harper
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
target=https://my-cluster.harperdbcloud.com \
|
|
149
|
-
restart=true \
|
|
150
|
-
replicated=true
|
|
194
|
+
harper list_deployments project=my-app status=success
|
|
195
|
+
harper deploy project=my-app deployment_id=<previous deployment_id> restart=rolling json=true
|
|
196
|
+
# Then poll its restartJobId with get_job, as above
|
|
151
197
|
```
|
|
152
198
|
|
|
153
|
-
**
|
|
199
|
+
**Stage a release now, and make it live in a maintenance window:**
|
|
154
200
|
|
|
155
201
|
```bash
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
# Deploy by reference with credential
|
|
160
|
-
harper deploy by_ref=true credential=true restart=true replicated=true
|
|
202
|
+
harper deploy project=my-app package=npm:@my-org/my-app@1.2.3 activate=false
|
|
203
|
+
# Later, with the deployment_id the stage returned
|
|
204
|
+
harper deploy project=my-app deployment_id=<staged deployment_id> restart=rolling
|
|
161
205
|
```
|
|
162
206
|
|
|
163
|
-
**
|
|
207
|
+
**Deploy a pull request's head commit by reference in GitHub Actions:**
|
|
164
208
|
|
|
165
209
|
```bash
|
|
166
|
-
harper deploy
|
|
210
|
+
harper deploy ref=${{ github.event.pull_request.head.sha }} restart=true replicated=true
|
|
167
211
|
```
|
|
168
212
|
|
|
169
|
-
|
|
213
|
+
**Deploy a private repository by reference:**
|
|
170
214
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
215
|
+
```bash
|
|
216
|
+
# Once, as super_user
|
|
217
|
+
harper deploy setup=true
|
|
218
|
+
|
|
219
|
+
# Every deploy
|
|
220
|
+
harper deploy by_ref=true credential=true restart=true replicated=true
|
|
221
|
+
```
|
|
@@ -7,8 +7,8 @@ metadata:
|
|
|
7
7
|
mode: generate
|
|
8
8
|
sources:
|
|
9
9
|
- reference/v5/environment-variables/overview.md
|
|
10
|
-
sourceCommit:
|
|
11
|
-
inputHash:
|
|
10
|
+
sourceCommit: 2dde0597443a13af0c753f2adbe528e8442d8ee4
|
|
11
|
+
inputHash: 51b7b4f21b275eec
|
|
12
12
|
---
|
|
13
13
|
|
|
14
14
|
# Load Environment Variables with loadEnv
|
|
@@ -17,55 +17,25 @@ Instructions for the agent to follow when loading environment variables from `.e
|
|
|
17
17
|
|
|
18
18
|
## When to Use
|
|
19
19
|
|
|
20
|
-
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
|
|
20
|
+
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.
|
|
21
21
|
|
|
22
22
|
## How It Works
|
|
23
23
|
|
|
24
|
-
1. **Declare `loadEnv` in `config.yaml`**:
|
|
25
|
-
|
|
26
|
-
```yaml
|
|
27
|
-
loadEnv:
|
|
28
|
-
files: '.env'
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
2. **Place `loadEnv` first**: Harper is a single-process application. List `loadEnv` before all other components so that environment variables are available on `process.env` before dependent components start.
|
|
24
|
+
1. **Declare `loadEnv` first in `config.yaml`**: Place `loadEnv` before all other components so environment variables are available when dependent components start.
|
|
32
25
|
|
|
33
26
|
```yaml
|
|
34
27
|
# config.yaml — loadEnv must come first
|
|
35
28
|
loadEnv:
|
|
36
29
|
files: '.env'
|
|
37
|
-
|
|
38
|
-
rest: true
|
|
39
|
-
|
|
40
|
-
myApp:
|
|
41
|
-
files: './src/*.js'
|
|
42
30
|
```
|
|
43
31
|
|
|
44
|
-
|
|
32
|
+
2. **Set the `files` option**: Provide one or more paths or glob patterns pointing to the env file(s) to load. This option is required.
|
|
45
33
|
|
|
46
|
-
|
|
34
|
+
3. **Access variables in component code**: After loading, all values from the specified files are available on `process.env` and shared across all components in the single Harper process.
|
|
47
35
|
|
|
48
|
-
|
|
49
|
-
loadEnv:
|
|
50
|
-
files: '.env'
|
|
51
|
-
override: true
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
5. **Load multiple files**: Pass an array of paths or a glob pattern to `files`. Files are loaded in the order specified.
|
|
55
|
-
|
|
56
|
-
```yaml
|
|
57
|
-
loadEnv:
|
|
58
|
-
files:
|
|
59
|
-
- '.env'
|
|
60
|
-
- '.env.local'
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
or with a glob:
|
|
36
|
+
4. **Control override behavior with `override`**: By default, existing environment variables take precedence over values in `.env` files. Set `override: true` to reverse this — loaded values will overwrite variables already present in the shell or container environment.
|
|
64
37
|
|
|
65
|
-
|
|
66
|
-
loadEnv:
|
|
67
|
-
files: 'env-vars/*'
|
|
68
|
-
```
|
|
38
|
+
5. **Load multiple files when needed**: Specify a list or a glob pattern under `files`. Files are loaded in the order specified.
|
|
69
39
|
|
|
70
40
|
### Configuration Options
|
|
71
41
|
|
|
@@ -76,10 +46,17 @@ Apply this rule when a Harper application needs to supply secrets, API endpoints
|
|
|
76
46
|
|
|
77
47
|
## Examples
|
|
78
48
|
|
|
79
|
-
**
|
|
49
|
+
**Basic usage — load a single `.env` file:**
|
|
80
50
|
|
|
81
51
|
```yaml
|
|
82
|
-
|
|
52
|
+
loadEnv:
|
|
53
|
+
files: '.env'
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
**Full `config.yaml` with `loadEnv` declared first:**
|
|
57
|
+
|
|
58
|
+
```yaml
|
|
59
|
+
# config.yaml — loadEnv must come first
|
|
83
60
|
loadEnv:
|
|
84
61
|
files: '.env'
|
|
85
62
|
|
|
@@ -89,24 +66,35 @@ myApp:
|
|
|
89
66
|
files: './src/*.js'
|
|
90
67
|
```
|
|
91
68
|
|
|
92
|
-
**
|
|
69
|
+
**Override existing environment variables:**
|
|
70
|
+
|
|
71
|
+
```yaml
|
|
72
|
+
loadEnv:
|
|
73
|
+
files: '.env'
|
|
74
|
+
override: true
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
**Load multiple files as a list:**
|
|
93
78
|
|
|
94
79
|
```yaml
|
|
95
|
-
# config.yaml
|
|
96
80
|
loadEnv:
|
|
97
81
|
files:
|
|
98
82
|
- '.env'
|
|
99
83
|
- '.env.local'
|
|
100
|
-
|
|
84
|
+
```
|
|
101
85
|
|
|
102
|
-
|
|
86
|
+
**Load multiple files using a glob pattern:**
|
|
103
87
|
|
|
104
|
-
|
|
105
|
-
|
|
88
|
+
```yaml
|
|
89
|
+
loadEnv:
|
|
90
|
+
files: 'env-vars/*'
|
|
106
91
|
```
|
|
107
92
|
|
|
108
93
|
## Notes
|
|
109
94
|
|
|
110
|
-
- `loadEnv`
|
|
111
|
-
-
|
|
112
|
-
-
|
|
95
|
+
- `loadEnv` is built into Harper — it does not need to be installed, only declared in `config.yaml`.
|
|
96
|
+
- Variables are loaded onto `process.env` and shared across all components. Declare `loadEnv` before any component that depends on those variables.
|
|
97
|
+
- `loadEnv` supplies **application** environment variables only. It does **not** configure Harper itself. Harper's own configuration is composed at startup before any `loadEnv` runs, so variables such as `HARPER_CONFIG`, `HARPER_SET_CONFIG`, and `HARPER_DEFAULT_CONFIG` delivered through a `.env` file are read too late and are ignored.
|
|
98
|
+
- To change Harper's own configuration, use the configuration file directly or export variables in the real process/container environment before Harper starts.
|
|
99
|
+
- For production credentials, prefer the encrypted secrets store over a committed `.env` file. Secrets are delivered to components via `process.env` and never appear in operation logs or replication payloads.
|
|
100
|
+
- Individual `.env` values can also be stored encrypted so plaintext never reaches the API, logs, or replication payload.
|