@harperfast/template-react-ts-ssr-studio 1.13.4 → 1.13.6
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
|
@@ -28,54 +28,62 @@ metadata:
|
|
|
28
28
|
Actions
|
|
29
29
|
- reference/v5/operations-api/operations.md#`list_oidc_trust`
|
|
30
30
|
- reference/v5/operations-api/operations.md#`drop_oidc_trust`
|
|
31
|
-
sourceCommit:
|
|
32
|
-
inputHash:
|
|
31
|
+
sourceCommit: e69702c99845f2dd810cb32652d1a9e6b58c538b
|
|
32
|
+
inputHash: 91e58cd0833af162
|
|
33
33
|
---
|
|
34
34
|
|
|
35
35
|
# Deploying a Harper Application from GitHub Actions with OIDC
|
|
36
36
|
|
|
37
|
-
Instructions for the agent to configure and
|
|
37
|
+
Instructions for the agent to configure and use OIDC trusted publishing so a GitHub Actions workflow can deploy to Harper with no stored credential.
|
|
38
38
|
|
|
39
39
|
## When to Use
|
|
40
40
|
|
|
41
|
-
Apply this rule when
|
|
41
|
+
Apply this rule when wiring up a GitHub Actions workflow to deploy a Harper application without storing a `HARPER_CLI_REFRESH_TOKEN` or any other durable credential in CI. Use it both for the one-command setup path (branch-triggered deploys) and for the manual policy path (tag-triggered releases). Also apply it when diagnosing a rejected OIDC exchange or revoking pipeline access.
|
|
42
42
|
|
|
43
43
|
## How It Works
|
|
44
44
|
|
|
45
|
-
### One-Command Setup (
|
|
45
|
+
### One-Command Setup (branch-triggered deploys)
|
|
46
46
|
|
|
47
|
-
1. **Run setup once** from the project checkout, signed in as a `super_user`:
|
|
47
|
+
1. **Run setup once** from the project's checkout, signed in as a `super_user`:
|
|
48
48
|
|
|
49
49
|
```bash
|
|
50
|
-
harper login https://my-cluster.example.com:9925
|
|
51
50
|
harper deploy setup=true provider=github-actions project=my-app
|
|
52
51
|
```
|
|
53
52
|
|
|
54
|
-
If your workflow file is not `.github/workflows/deploy.yaml`, pass `workflow
|
|
53
|
+
If your workflow file is not `.github/workflows/deploy.yaml`, pass `workflow=`:
|
|
55
54
|
|
|
56
55
|
```bash
|
|
57
56
|
harper deploy setup=true provider=github-actions project=my-app workflow=.github/workflows/deploy.yml
|
|
58
57
|
```
|
|
59
58
|
|
|
60
|
-
2. **Understand what setup does** —
|
|
61
|
-
- Resolves the GitHub repository's numeric
|
|
62
|
-
-
|
|
63
|
-
- Creates a role and a user named `<project>-ci-deploy` with permissions limited to `deploy_component`, `get_job`, and `registration_info`,
|
|
64
|
-
- Reads the policy back and compares it claim by claim
|
|
65
|
-
- Sets the repository's `HARPER_CLI_TARGET`
|
|
59
|
+
2. **Understand what setup does** — it executes these steps automatically:
|
|
60
|
+
- Resolves the GitHub repository's numeric `repository_id` from the `origin` remote (or `repo=<owner>/<name>`). Pass `repository_id=<id>` explicitly for private repos without `gh`.
|
|
61
|
+
- Validates the workflow file: it must be able to run on `main` (or `branch=`), run a job in the `production` environment (`environment=`), and grant `id-token: write`. Setup stops before writing anything if the workflow could never match or never request a token.
|
|
62
|
+
- Creates a role and a user named `<project>-ci-deploy` with permissions limited to `deploy_component`, `get_deployment`, `get_job`, and `registration_info`, plus the trust policy `github-actions-<project>`.
|
|
63
|
+
- Reads the policy back and compares it claim by claim.
|
|
64
|
+
- Sets the repository's `HARPER_CLI_TARGET` variable via `gh` if one does not already exist.
|
|
66
65
|
|
|
67
|
-
3. **Handle idempotency**: setup only creates — it never
|
|
66
|
+
3. **Handle idempotency**: setup only creates — it never overwrites. A role, user, or policy that already exists but differs stops setup before writing. To replace a policy:
|
|
68
67
|
|
|
69
68
|
```bash
|
|
70
69
|
harper drop_oidc_trust id=github-actions-<project>
|
|
71
|
-
harper deploy setup=true provider=github-actions project=my-app
|
|
72
70
|
```
|
|
73
71
|
|
|
74
|
-
|
|
72
|
+
Then run setup again.
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
### Manual Setup (tag-triggered deploys)
|
|
75
77
|
|
|
76
|
-
Use this path when
|
|
78
|
+
Use this path when the workflow deploys on version tags, because a branch pin cannot match a tag ref.
|
|
77
79
|
|
|
78
|
-
1. **
|
|
80
|
+
1. **Log in as `super_user`**:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
harper login https://my-cluster.example.com:9925
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
2. **Create a deploy-only role and user** named `<project>-ci-deploy`:
|
|
79
87
|
|
|
80
88
|
```bash
|
|
81
89
|
harper add_role role=ci_deploy permission='{"operations":["deploy_component","get_job","get_deployment","registration_info"]}'
|
|
@@ -83,12 +91,12 @@ Use this path when deploying on version tags, because a branch-pinned policy can
|
|
|
83
91
|
```
|
|
84
92
|
|
|
85
93
|
- `deploy_component` — the deploy itself.
|
|
86
|
-
- `
|
|
87
|
-
- `
|
|
88
|
-
- `registration_info` — version check
|
|
94
|
+
- `get_deployment` — required for `harper deploy restart=rolling` to wait on every node; without it that wait fails with `403`.
|
|
95
|
+
- `get_job` — required for the wait step; without it the wait step fails with `403`.
|
|
96
|
+
- `registration_info` — version check before upload; omitting it logs a refused operation on every run.
|
|
89
97
|
- `restart_service` is not needed: Harper starts the rolling restart's job itself. The password is required to create the user but a GitHub Actions pipeline never uses it, so this command discards it.
|
|
90
98
|
|
|
91
|
-
|
|
99
|
+
3. **Add a trust policy** pinning `repository_id`, `workflow_path`, and `environment` (use this shape for tag-triggered workflows where `workflow_ref` cannot be pinned):
|
|
92
100
|
|
|
93
101
|
```bash
|
|
94
102
|
harper add_oidc_trust \
|
|
@@ -100,45 +108,40 @@ Use this path when deploying on version tags, because a branch-pinned policy can
|
|
|
100
108
|
```
|
|
101
109
|
|
|
102
110
|
Key claim rules:
|
|
103
|
-
- `repository_id` is immutable
|
|
104
|
-
- `workflow_path`
|
|
111
|
+
- `repository_id` is immutable and survives renames. Look it up with `gh api repos/my-org/my-app --jq .id`.
|
|
112
|
+
- `workflow_path` is derived from `workflow_ref` by removing the `@<ref>` suffix; format is `<owner>/<repo>/<path>`.
|
|
105
113
|
- `environment` is the ref gate. Without it, anyone who can push a branch can mint a token.
|
|
106
114
|
- `audience` must be the exact target URL with its port and a **trailing slash**.
|
|
107
115
|
- A workflow that deploys on a push to `main` can pin `workflow_ref` (`my-org/my-app/.github/workflows/deploy.yml@refs/heads/main`) instead, which gates the ref by itself.
|
|
108
116
|
|
|
109
|
-
|
|
117
|
+
4. **Configure the GitHub environment**: in **Settings → Environments → production**, set **Deployment branches and tags** to the `v*` tag pattern. Add required reviewers if a release needs approval.
|
|
110
118
|
|
|
111
|
-
|
|
119
|
+
5. **Store the target as a repository variable** (not a secret):
|
|
112
120
|
|
|
113
121
|
```bash
|
|
114
122
|
gh variable set HARPER_CLI_TARGET --repo my-org/my-app --body https://my-cluster.example.com:9925/
|
|
115
123
|
```
|
|
116
124
|
|
|
125
|
+
---
|
|
126
|
+
|
|
117
127
|
### How OIDC Authentication Works in the Workflow
|
|
118
128
|
|
|
119
|
-
|
|
129
|
+
A job authenticates automatically when all four conditions hold:
|
|
120
130
|
|
|
121
|
-
1. **The job
|
|
122
|
-
2. **`HARPER_CLI_TARGET` is the policy's `audience`.** The CLI requests its token for the target it connects to, so the target must be the URL the policy names, with its port and trailing slash.
|
|
123
|
-
3. **The run matches the policy's claims**: its
|
|
131
|
+
1. **The job declares `permissions: id-token: write`.**
|
|
132
|
+
2. **`HARPER_CLI_TARGET` is the policy's `audience`.** The CLI requests its token for the target it connects to, so the target must be the URL the policy names, with its port and trailing slash. It is not sensitive, so use `vars.HARPER_CLI_TARGET` rather than a secret.
|
|
133
|
+
3. **The run matches the policy's claims**: its `repository_id`, `workflow_path`/`workflow_ref`, and `environment`.
|
|
124
134
|
4. **Nothing else is configured to authenticate.** `auth_username=`/`auth_password=`, credentials in the target URL, `HARPER_CLI_USERNAME`/`HARPER_CLI_PASSWORD`, `HARPER_CLI_REFRESH_TOKEN` or `HARPER_CLI_OPERATION_TOKEN`, and a saved `harper login` all outrank the exchange.
|
|
125
135
|
|
|
126
|
-
|
|
136
|
+
Nothing in the workflow names the policy. Every `harper` command in the job (`harper deploy`, `harper get_job`, etc.) authenticates through it automatically.
|
|
127
137
|
|
|
128
138
|
The exchange runs only when GitHub sets `ACTIONS_ID_TOKEN_REQUEST_URL` and `ACTIONS_ID_TOKEN_REQUEST_TOKEN`, which it does for a job that declares `permissions: id-token: write`. Without them, the CLI falls through to its other credential sources rather than reporting a failure.
|
|
129
139
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
```
|
|
133
|
-
Requesting a GitHub Actions identity token for https://my-instance.harperdb.io:9925/...
|
|
134
|
-
Authenticated as 'ci-deploy' via OIDC trust policy 'my-app-prod'.
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
Diagnose a rejected exchange with `list_oidc_trust` (check for `invalid_reason` on each entry) and the instance's `oidc-trust` log. The server deliberately does not report which check failed.
|
|
140
|
+
---
|
|
138
141
|
|
|
139
142
|
### Policy Specificity for GitHub Actions
|
|
140
143
|
|
|
141
|
-
For `https://token.actions.githubusercontent.com`,
|
|
144
|
+
For `issuer=https://token.actions.githubusercontent.com`, every policy must satisfy all three requirements:
|
|
142
145
|
|
|
143
146
|
| Requirement | Satisfied by one of | Left open otherwise |
|
|
144
147
|
| ---------------------- | ------------------------------------------------------------------------ | ----------------------------------------------- |
|
|
@@ -148,21 +151,68 @@ For `https://token.actions.githubusercontent.com`, a policy must satisfy all thr
|
|
|
148
151
|
|
|
149
152
|
Additional constraints:
|
|
150
153
|
|
|
151
|
-
- `repository_id` is preferred over `repository` — it is immutable and survives renames.
|
|
152
|
-
- A tag-triggered release cannot pin `workflow_ref` since the tag is unknown when the policy is written. Pin `workflow_path` and gate on `environment`.
|
|
153
154
|
- `ref_type: tag` is not accepted as a ref gate, `sub` is not accepted as a pin, and `job_workflow_ref` pins the workflow without gating the ref. `pull_request_target` runs are denied unless the policy constrains `event_name`.
|
|
154
155
|
|
|
155
|
-
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
### Diagnosing a Rejected Exchange
|
|
159
|
+
|
|
160
|
+
Run `list_oidc_trust` (requires `super_user`) to list all policies including disabled ones:
|
|
161
|
+
|
|
162
|
+
```json
|
|
163
|
+
{ "operation": "list_oidc_trust" }
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
`list_oidc_trust` returns `{ "policies": [ ... ] }`. Each entry includes `id`, `issuer`, `audience`, `claims`, `user`, `enabled`, and optionally `invalid_reason`. Check `invalid_reason` first when diagnosing a rejected exchange — it is set when the policy is malformed or its user was deleted or deactivated after the policy was written. The exchange itself will not report what failed.
|
|
167
|
+
|
|
168
|
+
Check the instance's `oidc-trust` log for server-side detail.
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
### Revoking Pipeline Access
|
|
173
|
+
|
|
174
|
+
- **Stop future runs** — drop the policy:
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
harper drop_oidc_trust id=github-actions-<project>
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
This does not revoke tokens already issued (they are stateless JWTs valid for one hour).
|
|
181
|
+
|
|
182
|
+
- **Stop a token already in circulation** — deactivate the user:
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
harper alter_user username=<project>-ci-deploy active=false
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Use both together when responding to a suspected compromise.
|
|
156
189
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
### Providing a Durable Credential for a Private Source
|
|
193
|
+
|
|
194
|
+
Do not use the workflow's ephemeral `GITHUB_TOKEN` for Harper's stored credential — it expires when the job ends, and later installs (a new node joining, a reinstall after restore) would fail. Instead use a durable token:
|
|
195
|
+
|
|
196
|
+
- For a private repository: a fine-grained personal access token with **Contents: read-only** scoped to the application repository.
|
|
197
|
+
- For GitHub Packages: a token with the `read:packages` scope.
|
|
198
|
+
|
|
199
|
+
Store it in Harper once from your machine:
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
# Private git repository
|
|
203
|
+
harper deploy setup=true provider=github project=my-app
|
|
204
|
+
|
|
205
|
+
# GitHub Packages
|
|
206
|
+
harper deploy setup=true provider=npm project=my-app registry=https://npm.pkg.github.com scope=@my-org
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
The name is derived from the component and the host: `deploy.my-app.git.github.com` for the repository, and `deploy.my-app.npm.pkg.github.com` for GitHub Packages. Reference it by that name in the workflow — the token never appears in your pipeline.
|
|
160
210
|
|
|
161
211
|
## Examples
|
|
162
212
|
|
|
163
213
|
### Path A: Deploy a Tagged Release (`v1.2.3`) from the Repository
|
|
164
214
|
|
|
165
|
-
Push a semver tag (`v1.2.3`), and every node clones and installs that commit. `by_ref=true` deploys `git+https://github.com/<owner>/<repo>.git#<sha>`, where the SHA is the commit the tag points to (`GITHUB_SHA`), and every node clones that exact commit even if the tag
|
|
215
|
+
Push a semver tag (`v1.2.3`), and every node clones and installs that commit. `by_ref=true` deploys `git+https://github.com/<owner>/<repo>.git#<sha>`, where the SHA is the commit the tag points to (`GITHUB_SHA`), and every node clones that exact commit even if the tag is moved later. If this repository needs a build step to be runnable, do not reach for `install_allow_scripts` — use Path B instead.
|
|
166
216
|
|
|
167
217
|
```yaml
|
|
168
218
|
# .github/workflows/deploy.yml
|
|
@@ -192,6 +242,8 @@ jobs:
|
|
|
192
242
|
run: harper deploy project=my-app by_ref=true restart=rolling json=true > deploy.json
|
|
193
243
|
- name: Wait for every node to take the release
|
|
194
244
|
run: |
|
|
245
|
+
# From v5.4.0 a certified rolling deploy waited for every node itself.
|
|
246
|
+
[ "$(jq -r '.rollout.status // empty' deploy.json)" != success ] || exit 0
|
|
195
247
|
JOB_ID=$(jq -r '.restartJobId // empty' deploy.json)
|
|
196
248
|
[ -n "$JOB_ID" ] || { echo "The rolling deploy returned no restartJobId"; exit 1; }
|
|
197
249
|
LAST="could not be read"
|
|
@@ -212,14 +264,17 @@ jobs:
|
|
|
212
264
|
Key details:
|
|
213
265
|
|
|
214
266
|
- **No secrets.** `HARPER_CLI_TARGET` is the only thing the workflow is given. `id-token: write` lets the CLI request an identity token, and `environment: production` puts the `environment` claim the trust policy requires into it.
|
|
215
|
-
- **`persist-credentials: false`** keeps the job's `GITHUB_TOKEN` out of `.git/config
|
|
267
|
+
- **`persist-credentials: false`** keeps the job's `GITHUB_TOKEN` out of `.git/config`, where `actions/checkout` otherwise leaves it for every later step.
|
|
216
268
|
- **`harper@^5.3`** pins the CLI's major version. 5.3 is the first CLI that authenticates with the identity token.
|
|
217
269
|
- **`replicated` isn't needed.** On Harper Fabric and Harper Pro, a deploy goes to every node unless you pass `replicated=false`. Each node fetches and installs the package itself.
|
|
218
|
-
- **`restart=rolling`** restarts nodes one at a time. Use `restart=true` for a single-node or dev instance.
|
|
219
|
-
- **`
|
|
220
|
-
-
|
|
221
|
-
-
|
|
222
|
-
|
|
270
|
+
- **`restart=rolling`** restarts nodes one at a time so the cluster keeps serving throughout. Use `restart=true` for a single-node or dev instance.
|
|
271
|
+
- **`certification`**: on v5.4.0 and later, `restart=rolling` loads the release in a canary worker on each node before that node serves it, so a release that fails to load is rejected. The `certification` field in the deploy result reflects whether this ran.
|
|
272
|
+
- **`restartJobId`**: present in the deploy JSON when a rolling job was started but the deploy did not wait for it itself. The wait step polls `.[0].status` from `get_job` until `COMPLETE` or `ERROR`.
|
|
273
|
+
- **Load-balanced clusters**: the deployment record wait works through a load-balanced URL (the record replicates), but `get_job` polls do not — Harper does not replicate jobs. If your load balancer never routes back to the node that received the deploy, use one node's direct URL for both the deploy and the wait, and as the trust policy's `audience`.
|
|
274
|
+
|
|
275
|
+
For a private repository, add `credential=true` to the deploy command.
|
|
276
|
+
|
|
277
|
+
---
|
|
223
278
|
|
|
224
279
|
### Path B: Build in CI, Publish to GitHub Packages, Deploy the Artifact
|
|
225
280
|
|
|
@@ -288,6 +343,7 @@ jobs:
|
|
|
288
343
|
restart=rolling json=true > deploy.json
|
|
289
344
|
- name: Wait for every node to take the release
|
|
290
345
|
run: |
|
|
346
|
+
[ "$(jq -r '.rollout.status // empty' deploy.json)" != success ] || exit 0
|
|
291
347
|
JOB_ID=$(jq -r '.restartJobId // empty' deploy.json)
|
|
292
348
|
[ -n "$JOB_ID" ] || { echo "The rolling deploy returned no restartJobId"; exit 1; }
|
|
293
349
|
LAST="could not be read"
|
|
@@ -305,54 +361,26 @@ jobs:
|
|
|
305
361
|
exit 1
|
|
306
362
|
```
|
|
307
363
|
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
Credential roles:
|
|
311
|
-
|
|
312
|
-
- **Publishing** and installing private `@my-org` dependencies use the workflow's ephemeral `GITHUB_TOKEN` (`packages: write` includes read). Both happen entirely inside `publish`.
|
|
313
|
-
- **Installing on Harper nodes** uses the durable `read:packages` token stored as `deploy.my-app.npm.pkg.github.com` — because installs can happen long after this workflow ends.
|
|
364
|
+
Split into two jobs so the job with `id-token: write` runs none of your build code. Only the `deploy` job names `environment: production`, so only its token carries the `environment` claim the trust policy requires.
|
|
314
365
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
```bash
|
|
318
|
-
harper deploy setup=true provider=github project=my-app
|
|
319
|
-
# or for GitHub Packages:
|
|
320
|
-
harper deploy setup=true provider=npm project=my-app registry=https://npm.pkg.github.com scope=@my-org
|
|
321
|
-
```
|
|
322
|
-
|
|
323
|
-
For a private repository, use a GitHub fine-grained personal access token with **Contents: read-only** scoped to the application repository. For GitHub Packages, use a token with the `read:packages` scope. Do not use the workflow's ephemeral `GITHUB_TOKEN` for the durable credential — it expires when the job ends.
|
|
366
|
+
---
|
|
324
367
|
|
|
325
|
-
###
|
|
368
|
+
### Checking the Deployment Record
|
|
326
369
|
|
|
327
370
|
```bash
|
|
328
371
|
harper get_deployment deployment_id="$(jq -r .deployment_id deploy.json)" json=true
|
|
329
372
|
```
|
|
330
373
|
|
|
331
|
-
|
|
374
|
+
Use `list_deployments` to see the history of what was deployed and when, and filter by commit with `sha`.
|
|
332
375
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
```bash
|
|
336
|
-
harper list_oidc_trust
|
|
337
|
-
```
|
|
338
|
-
|
|
339
|
-
Returns `{ "policies": [ ... ] }`. Each entry includes `id`, `issuer`, `audience`, `claims`, `user`, `enabled`, and optionally `invalid_reason`. Check `invalid_reason` first when diagnosing a rejected exchange — it is set when the policy is malformed or its user was deleted or deactivated.
|
|
340
|
-
|
|
341
|
-
### Drop a Trust Policy
|
|
342
|
-
|
|
343
|
-
```bash
|
|
344
|
-
harper drop_oidc_trust id=github-actions-<project>
|
|
345
|
-
```
|
|
376
|
+
- **Go back to a previous release** by activating its `deployment_id`, with no rebuild or reinstall: `harper deploy project=my-app deployment_id=<id> restart=rolling`. To deploy a release that is no longer kept, re-run the deploy with its tag or version.
|
|
346
377
|
|
|
347
378
|
## Notes
|
|
348
379
|
|
|
349
|
-
- `
|
|
350
|
-
-
|
|
351
|
-
-
|
|
352
|
-
-
|
|
353
|
-
-
|
|
354
|
-
-
|
|
355
|
-
- For tag-triggered workflows, `provider=github-actions` setup is not sufficient — it pins a branch. Write the policy manually using `add_oidc_trust` with `workflow_path` and `environment` claims.
|
|
356
|
-
- `token.actions.githubusercontent.com` is the required `issuer` value for GitHub Actions OIDC policies.
|
|
357
|
-
- Git-host credentials require git ≥ 2.31 on the Harper nodes and are not supported on Windows nodes. Registry credentials have no such constraints.
|
|
380
|
+
- `audience` in `add_oidc_trust` must include the port and a **trailing slash** — e.g., `https://my-cluster.example.com:9925/`. A URL without the trailing slash will not match.
|
|
381
|
+
- `HARPER_CLI_REFRESH_TOKEN` and any other configured credential (`auth_username=`/`auth_password=`, `HARPER_CLI_USERNAME`/`HARPER_CLI_PASSWORD`, `HARPER_CLI_OPERATION_TOKEN`, a saved `harper login`) outrank the OIDC exchange. Remove stored credentials from the runner before enabling OIDC.
|
|
382
|
+
- `list_oidc_trust`, `drop_oidc_trust`, and `alter_user` all require `super_user`.
|
|
383
|
+
- `drop_oidc_trust` does not revoke already-issued operation tokens (one-hour JWTs). Pair it with `alter_user username=<project>-ci-deploy active=false` to stop tokens already in circulation.
|
|
384
|
+
- `ref_type: tag` is not accepted as a ref gate. Gate tag-triggered workflows with `environment` instead, and set **Deployment branches and tags** to `v*` in the environment's settings.
|
|
385
|
+
- Every step in a job with `id-token: write` can request an identity token — GitHub gives each one `ACTIONS_ID_TOKEN_REQUEST_URL` and `ACTIONS_ID_TOKEN_REQUEST_TOKEN`. Run none of the repository's code in that job.
|
|
358
386
|
- See [deploying-to-harper-fabric.md](deploying-to-harper-fabric.md) for cluster-level deployment context.
|