ras-stack 0.28.0 → 0.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -438,6 +438,29 @@ await reportPreviewStatus(
|
|
|
438
438
|
|
|
439
439
|
The reporter keeps one marked comment and one named check run, preserves the last ready commit while a replacement builds, bounds comment pagination, and validates repository, pull request, commit, marker, and URL inputs. Applications retain their preview hostname, access note, seed credentials, and product cleanup hooks.
|
|
440
440
|
|
|
441
|
+
Trusted preview wrappers can delegate each status transition to the reusable workflow instead of checking out and running a repository-owned comment script:
|
|
442
|
+
|
|
443
|
+
```yaml
|
|
444
|
+
mark-preview-ready:
|
|
445
|
+
permissions:
|
|
446
|
+
contents: read
|
|
447
|
+
checks: write
|
|
448
|
+
issues: write
|
|
449
|
+
uses: richardsolomou/ras-stack/.github/workflows/report-preview-status.yml@v0.29.0
|
|
450
|
+
with:
|
|
451
|
+
state: ready
|
|
452
|
+
pr-number: ${{ github.event.workflow_run.pull_requests[0].number }}
|
|
453
|
+
sha: ${{ github.event.workflow_run.head_sha }}
|
|
454
|
+
preview-url: https://pr-${{ github.event.workflow_run.pull_requests[0].number }}.example.com
|
|
455
|
+
run-url: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
|
456
|
+
marker: <!-- app-preview -->
|
|
457
|
+
note: Preview data is disposable.
|
|
458
|
+
secrets:
|
|
459
|
+
token: ${{ secrets.GITHUB_TOKEN }}
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
The workflow uses the `ras-stack-preview` CLI from the consuming repository's pinned package. It owns only GitHub check/comment reporting; the caller retains the trusted event conditions, permissions, deployment, deletion, secret mapping, and product verification.
|
|
463
|
+
|
|
441
464
|
The reusable `build-preview-image.yml` workflow publishes same-repository pull requests directly but turns fork builds into one-day artifacts without exposing a token or secret. A trusted `workflow_run` job can publish that artifact with `actions/publish-preview-image` before running its repository-owned deployment command. The event wrapper and secret-to-environment mapping remain in each application so the trust boundary is visible locally.
|
|
442
465
|
|
|
443
466
|
Self-hosted images that run the app, Centrifugo, and Caddy together can share the lifecycle without sharing a Dockerfile:
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { previewStatusFromEnvironment } from './environment.js';
|
|
3
|
+
import { reportPreviewStatus } from './github.js';
|
|
4
|
+
const { options, status } = previewStatusFromEnvironment(process.argv[2]);
|
|
5
|
+
await reportPreviewStatus(options, status);
|
|
6
|
+
console.log(`Preview status set to ${status.state}`);
|
|
7
|
+
//# sourceMappingURL=cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/preview/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,4BAA4B,EAAE,MAAM,kBAAkB,CAAA;AAC/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AAEjD,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,4BAA4B,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;AACzE,MAAM,mBAAmB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;AAC1C,OAAO,CAAC,GAAG,CAAC,yBAAyB,MAAM,CAAC,KAAK,EAAE,CAAC,CAAA","sourcesContent":["#!/usr/bin/env node\nimport { previewStatusFromEnvironment } from './environment.js'\nimport { reportPreviewStatus } from './github.js'\n\nconst { options, status } = previewStatusFromEnvironment(process.argv[2])\nawait reportPreviewStatus(options, status)\nconsole.log(`Preview status set to ${status.state}`)\n"]}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
const states = new Set(['awaiting', 'building', 'ready', 'failed', 'deleted']);
|
|
2
|
+
export function previewStatusFromEnvironment(stateValue, environment = process.env) {
|
|
3
|
+
if (!stateValue || !states.has(stateValue)) {
|
|
4
|
+
throw new Error('preview state must be awaiting, building, ready, failed, or deleted');
|
|
5
|
+
}
|
|
6
|
+
const state = stateValue;
|
|
7
|
+
const note = optionalEnvironment(environment, 'PREVIEW_NOTE');
|
|
8
|
+
const checkName = optionalEnvironment(environment, 'PREVIEW_CHECK_NAME');
|
|
9
|
+
const options = {
|
|
10
|
+
repository: requiredEnvironment(environment, 'GITHUB_REPOSITORY'),
|
|
11
|
+
token: requiredEnvironment(environment, 'GH_TOKEN'),
|
|
12
|
+
marker: requiredEnvironment(environment, 'PREVIEW_MARKER'),
|
|
13
|
+
...(note ? { note } : {}),
|
|
14
|
+
...(checkName ? { checkName } : {}),
|
|
15
|
+
};
|
|
16
|
+
const prNumber = requiredEnvironment(environment, 'PR_NUMBER');
|
|
17
|
+
const runUrl = optionalEnvironment(environment, 'RUN_URL');
|
|
18
|
+
const status = state === 'deleted'
|
|
19
|
+
? { state, prNumber }
|
|
20
|
+
: {
|
|
21
|
+
state,
|
|
22
|
+
prNumber,
|
|
23
|
+
sha: requiredEnvironment(environment, 'COMMIT_SHA'),
|
|
24
|
+
previewUrl: requiredEnvironment(environment, 'PREVIEW_URL'),
|
|
25
|
+
...(runUrl ? { runUrl } : {}),
|
|
26
|
+
};
|
|
27
|
+
return { options, status };
|
|
28
|
+
}
|
|
29
|
+
function requiredEnvironment(environment, name) {
|
|
30
|
+
const value = optionalEnvironment(environment, name);
|
|
31
|
+
if (!value)
|
|
32
|
+
throw new Error(`${name} is required`);
|
|
33
|
+
return value;
|
|
34
|
+
}
|
|
35
|
+
function optionalEnvironment(environment, name) {
|
|
36
|
+
return environment[name]?.trim() || undefined;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=environment.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"environment.js","sourceRoot":"","sources":["../../src/preview/environment.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,GAAG,IAAI,GAAG,CAAqB,CAAC,UAAU,EAAE,UAAU,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAA;AAElG,MAAM,UAAU,4BAA4B,CAAC,UAA8B,EAAE,WAAW,GAAsB,OAAO,CAAC,GAAG;IACvH,IAAI,CAAC,UAAU,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,UAAgC,CAAC,EAAE,CAAC;QACjE,MAAM,IAAI,KAAK,CAAC,qEAAqE,CAAC,CAAA;IACxF,CAAC;IACD,MAAM,KAAK,GAAG,UAAgC,CAAA;IAC9C,MAAM,IAAI,GAAG,mBAAmB,CAAC,WAAW,EAAE,cAAc,CAAC,CAAA;IAC7D,MAAM,SAAS,GAAG,mBAAmB,CAAC,WAAW,EAAE,oBAAoB,CAAC,CAAA;IACxE,MAAM,OAAO,GAAyB;QACpC,UAAU,EAAE,mBAAmB,CAAC,WAAW,EAAE,mBAAmB,CAAC;QACjE,KAAK,EAAE,mBAAmB,CAAC,WAAW,EAAE,UAAU,CAAC;QACnD,MAAM,EAAE,mBAAmB,CAAC,WAAW,EAAE,gBAAgB,CAAC;QAC1D,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzB,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACpC,CAAA;IACD,MAAM,QAAQ,GAAG,mBAAmB,CAAC,WAAW,EAAE,WAAW,CAAC,CAAA;IAC9D,MAAM,MAAM,GAAG,mBAAmB,CAAC,WAAW,EAAE,SAAS,CAAC,CAAA;IAC1D,MAAM,MAAM,GACV,KAAK,KAAK,SAAS;QACjB,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE;QACrB,CAAC,CAAC;YACE,KAAK;YACL,QAAQ;YACR,GAAG,EAAE,mBAAmB,CAAC,WAAW,EAAE,YAAY,CAAC;YACnD,UAAU,EAAE,mBAAmB,CAAC,WAAW,EAAE,aAAa,CAAC;YAC3D,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC9B,CAAA;IACP,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,CAAA;AAC5B,CAAC;AAED,SAAS,mBAAmB,CAAC,WAA8B,EAAE,IAAY;IACvE,MAAM,KAAK,GAAG,mBAAmB,CAAC,WAAW,EAAE,IAAI,CAAC,CAAA;IACpD,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,cAAc,CAAC,CAAA;IAClD,OAAO,KAAK,CAAA;AACd,CAAC;AAED,SAAS,mBAAmB,CAAC,WAA8B,EAAE,IAAY;IACvE,OAAO,WAAW,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,SAAS,CAAA;AAC/C,CAAC","sourcesContent":["import type { GitHubPreviewOptions, PreviewStatus, PreviewStatusState } from './github.js'\n\nconst states = new Set<PreviewStatusState>(['awaiting', 'building', 'ready', 'failed', 'deleted'])\n\nexport function previewStatusFromEnvironment(stateValue: string | undefined, environment: NodeJS.ProcessEnv = process.env) {\n if (!stateValue || !states.has(stateValue as PreviewStatusState)) {\n throw new Error('preview state must be awaiting, building, ready, failed, or deleted')\n }\n const state = stateValue as PreviewStatusState\n const note = optionalEnvironment(environment, 'PREVIEW_NOTE')\n const checkName = optionalEnvironment(environment, 'PREVIEW_CHECK_NAME')\n const options: GitHubPreviewOptions = {\n repository: requiredEnvironment(environment, 'GITHUB_REPOSITORY'),\n token: requiredEnvironment(environment, 'GH_TOKEN'),\n marker: requiredEnvironment(environment, 'PREVIEW_MARKER'),\n ...(note ? { note } : {}),\n ...(checkName ? { checkName } : {}),\n }\n const prNumber = requiredEnvironment(environment, 'PR_NUMBER')\n const runUrl = optionalEnvironment(environment, 'RUN_URL')\n const status: PreviewStatus =\n state === 'deleted'\n ? { state, prNumber }\n : {\n state,\n prNumber,\n sha: requiredEnvironment(environment, 'COMMIT_SHA'),\n previewUrl: requiredEnvironment(environment, 'PREVIEW_URL'),\n ...(runUrl ? { runUrl } : {}),\n }\n return { options, status }\n}\n\nfunction requiredEnvironment(environment: NodeJS.ProcessEnv, name: string) {\n const value = optionalEnvironment(environment, name)\n if (!value) throw new Error(`${name} is required`)\n return value\n}\n\nfunction optionalEnvironment(environment: NodeJS.ProcessEnv, name: string) {\n return environment[name]?.trim() || undefined\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ras-stack",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.29.0",
|
|
4
4
|
"description": "Composable full-stack primitives shared across Richard Solomou's applications.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"authentication",
|
|
@@ -18,7 +18,8 @@
|
|
|
18
18
|
},
|
|
19
19
|
"bin": {
|
|
20
20
|
"ras-stack-assets": "./dist/build/cli.js",
|
|
21
|
-
"ras-stack-policy": "./dist/policy/cli.js"
|
|
21
|
+
"ras-stack-policy": "./dist/policy/cli.js",
|
|
22
|
+
"ras-stack-preview": "./dist/preview/cli.js"
|
|
22
23
|
},
|
|
23
24
|
"files": [
|
|
24
25
|
"dist",
|