@monoai/nscloud-nx-cache-action 0.0.0-stage → 0.1.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/LICENSE +21 -0
- package/NOTICE +21 -0
- package/README.md +119 -2
- package/THIRD_PARTY_LICENSES.txt +467 -0
- package/dist/nscloud-nx-cache-action.mjs +12 -0
- package/dist/token.mjs +8 -0
- package/docs/benchmarking.md +151 -0
- package/docs/configuration.md +60 -0
- package/docs/operations.md +168 -0
- package/docs/vercel.md +187 -0
- package/package.json +76 -4
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Configuration
|
|
2
|
+
|
|
3
|
+
## GitHub Action inputs
|
|
4
|
+
|
|
5
|
+
| Input | Default | Meaning |
|
|
6
|
+
| --- | --- | --- |
|
|
7
|
+
| `archive-directory` | `~/.cache/nx-namespace` | Existing archive directory; mount it before using the action. |
|
|
8
|
+
| `artifact-prefix` | Required | Repository and protocol prefix in Namespace Artifact Storage. |
|
|
9
|
+
| `artifact-region` | `ord` | Namespace storage region. |
|
|
10
|
+
| `access` | `read-only` | `read-only` rejects all uploads; `read-write` enables them. |
|
|
11
|
+
|
|
12
|
+
The action sets `NX_CACHE_FAILURE_MODE=fail-open` and exposes `nscloud-nx-cache-action`
|
|
13
|
+
and `nx-namespace-token` on PATH. Override environment variables on the wrapped
|
|
14
|
+
command step when needed. Node 24 must already be installed.
|
|
15
|
+
|
|
16
|
+
## Environment variables
|
|
17
|
+
|
|
18
|
+
These settings apply when invoking the standalone executable or action launcher.
|
|
19
|
+
|
|
20
|
+
| Variable | Default | Meaning |
|
|
21
|
+
| --- | --- | --- |
|
|
22
|
+
| `NX_ARCHIVE_DIRECTORY` | Required | Persistent local archive directory. |
|
|
23
|
+
| `NX_ARTIFACT_PREFIX` | Unset | Enables Artifact Storage; unset means local-only. |
|
|
24
|
+
| `NX_ARTIFACT_REGION` | `ord` | Artifact Storage region. |
|
|
25
|
+
| `NX_NAMESPACE_TOKEN` | Unset | Explicit Namespace bearer token; otherwise use workload/default SDK credentials. |
|
|
26
|
+
| `NX_CACHE_ACCESS` | `read-write` | `read-only` rejects every PUT, including local writes. The action sets `read-only` by default. |
|
|
27
|
+
| `NX_CACHE_REMOTE_ACCESS` | `read-write` | `read-only` allows local writes and Artifact reads, but skips remote publication. |
|
|
28
|
+
| `NX_CACHE_FAILURE_MODE` | `fail-open` | `strict` reports cache startup, request and publication failures. |
|
|
29
|
+
| `NX_CACHE_DISK_BYTES` | `10737418240` (10 GiB) | Combined archive and extraction allowance. |
|
|
30
|
+
| `NX_CACHE_EXTRACTION_BYTES` | `2147483648` (2 GiB) | Nx extraction-cache cleanup threshold, subtracted from the combined allowance. |
|
|
31
|
+
| `NX_CACHE_ARCHIVE_BYTES` | `536870912` (512 MiB) | Maximum individual archive size. |
|
|
32
|
+
| `NX_CACHE_RETENTION_HOURS` | `168` | Local archive retention. |
|
|
33
|
+
| `NX_CACHE_TRACE` | Unset | Set exactly `1` to emit request-scoped diagnostic spans. |
|
|
34
|
+
|
|
35
|
+
Numeric settings must be positive safe integers. The archive allowance must exceed
|
|
36
|
+
the maximum individual archive size by at least 4096 bytes. Cleanup thresholds do
|
|
37
|
+
not impose filesystem quotas on arbitrary build outputs.
|
|
38
|
+
|
|
39
|
+
Credential discovery uses `NX_NAMESPACE_TOKEN` first, then a Namespace workload
|
|
40
|
+
token at `/var/run/nsc/token.json`, then SDK defaults such as `NSC_TOKEN_FILE`.
|
|
41
|
+
Tokens must remain in the process environment or credential file, outside logs.
|
|
42
|
+
|
|
43
|
+
## Command behavior
|
|
44
|
+
|
|
45
|
+
```sh
|
|
46
|
+
NX_ARCHIVE_DIRECTORY="$HOME/.cache/nx-namespace" \
|
|
47
|
+
NX_ARTIFACT_PREFIX="nx/v1/owner/repository" \
|
|
48
|
+
NX_CACHE_REMOTE_ACCESS=read-only \
|
|
49
|
+
node ./nscloud-nx-cache-action.mjs pnpm exec nx run-many -t build
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Each invocation starts an authenticated IPv4 loopback listener and sets Nx's
|
|
53
|
+
`NX_SELF_HOSTED_REMOTE_CACHE_SERVER` and access token for the child. The wrapper
|
|
54
|
+
disables the Nx daemon and gives the child fresh workspace metadata and extraction
|
|
55
|
+
directories. It removes these directories after the child and publication drain
|
|
56
|
+
finish; archives in `NX_ARCHIVE_DIRECTORY` persist.
|
|
57
|
+
|
|
58
|
+
Use one connector process per archive directory. Concurrent Nx tasks within that
|
|
59
|
+
command share the listener. Access flags are client policy; they do not restrict
|
|
60
|
+
what the underlying Namespace identity or mounted filesystem can do.
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
# Operations
|
|
2
|
+
|
|
3
|
+
## Storage
|
|
4
|
+
|
|
5
|
+
Mount persistent archives with [Namespace Cache Volumes](https://namespace.so/docs/architecture/storage/cache-volumes).
|
|
6
|
+
Volumes are forked snapshots; concurrent jobs do not merge every writer's changes.
|
|
7
|
+
[Artifact Storage](https://namespace.so/docs/architecture/storage/artifact-storage)
|
|
8
|
+
supplies immutable shared entries when a local snapshot misses. A successful job
|
|
9
|
+
does not guarantee a later job receives that archive through its volume snapshot.
|
|
10
|
+
|
|
11
|
+
Use a prefix such as `nx/v1/owner/repository` to separate repositories and protocol
|
|
12
|
+
versions. Prefixes are addresses, rather than authorization boundaries. Provider
|
|
13
|
+
permissions and volume commit restrictions must control which workloads can write.
|
|
14
|
+
|
|
15
|
+
Local archives use `entries-v1/<task-hash>/` with size, SHA-256 digest and timestamp
|
|
16
|
+
metadata. Writes flush both files before atomic directory publication; reads verify
|
|
17
|
+
regular files, size and digest. Admission reserves space before writing and evicts
|
|
18
|
+
least recently used archives. It inspects at most 16 inventory entries concurrently
|
|
19
|
+
while serializing admission. Abandoned partials older than one hour are removed.
|
|
20
|
+
|
|
21
|
+
HTTP PUT success acknowledges local admission and queued publication. The command
|
|
22
|
+
drains up to ten concurrent publications before exiting. Only successful completion
|
|
23
|
+
of that drain establishes shared durability. Task failure or cancellation retains
|
|
24
|
+
its exit status while accepted publications drain.
|
|
25
|
+
|
|
26
|
+
## Credentials and hosted builds
|
|
27
|
+
|
|
28
|
+
On Namespace runners, the SDK can use the workload credential. Elsewhere, provide
|
|
29
|
+
an Artifact credential through `NX_NAMESPACE_TOKEN` or the SDK's credential file.
|
|
30
|
+
Local-only builds can omit `NX_ARTIFACT_PREFIX` and credentials.
|
|
31
|
+
|
|
32
|
+
`token.mjs` runs a child with a one-hour Artifact-only credential and revokes it
|
|
33
|
+
after the child exits:
|
|
34
|
+
|
|
35
|
+
```sh
|
|
36
|
+
NSC_TOKEN_FILE="$HOME/.config/ns/token.json" \
|
|
37
|
+
node ./token.mjs read-write <deploy-command> <arguments...>
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
The action exposes the same command as `nx-namespace-token`. The parent credential
|
|
41
|
+
must be authorized to issue and revoke tokens. `read-only` grants Artifact resolve;
|
|
42
|
+
`read-write` grants resolve and create. Grants apply across Artifact Storage in the
|
|
43
|
+
workspace; repository-path grants are unavailable. No compute or IAM grants are
|
|
44
|
+
added to the child token.
|
|
45
|
+
|
|
46
|
+
For GitHub OIDC, configure the Namespace Cloud GitHub app and exchange the GitHub
|
|
47
|
+
token with `nsc auth exchange-github-token` before running the token wrapper. For
|
|
48
|
+
hosted builds, forward the issued token only to the build environment. For example,
|
|
49
|
+
Vercel deployments can pass it as a build-only variable; keep it out of runtime and
|
|
50
|
+
persistent project environments. Carry the reviewed bundle and license files in
|
|
51
|
+
the deployed source when the build cannot download the release.
|
|
52
|
+
|
|
53
|
+
See the [Vercel integration guide](vercel.md) for a complete source-deployment
|
|
54
|
+
recipe, including the hosted build command, build-only token forwarding and
|
|
55
|
+
waiting for the build before revocation.
|
|
56
|
+
|
|
57
|
+
Cache permissions must be enforced by the provider. An HTTP read-only setting
|
|
58
|
+
cannot remove write permission from a runner identity or mounted volume.
|
|
59
|
+
|
|
60
|
+
## Failures and diagnostics
|
|
61
|
+
|
|
62
|
+
Fail-open is the default. Startup failure runs the child once with Nx caching
|
|
63
|
+
disabled; optional Artifact setup failure keeps local caching active. Failed GETs
|
|
64
|
+
become misses, failed PUTs can be acknowledged without storage, and publication
|
|
65
|
+
failure preserves a successful task status. A task is never rerun after it starts.
|
|
66
|
+
Use `NX_CACHE_FAILURE_MODE=strict` for validation and durability-sensitive callers.
|
|
67
|
+
|
|
68
|
+
Token issuance failure also defaults to fail-open, running the child with an empty
|
|
69
|
+
cache token. Revocation failure preserves the child status while the credential
|
|
70
|
+
expires. Strict mode reports either failure.
|
|
71
|
+
|
|
72
|
+
The listener admits 32 active requests and 128 queued requests. Queue and active
|
|
73
|
+
request deadlines are 120 seconds. Overload returns 503 in strict mode, or a miss
|
|
74
|
+
for GET / discarded-write acknowledgment for PUT in fail-open mode. Deadlines and
|
|
75
|
+
disconnects cancel incomplete input and remote reads.
|
|
76
|
+
|
|
77
|
+
| Symptom | Check |
|
|
78
|
+
| --- | --- |
|
|
79
|
+
| No adapter events | Confirm the command is wrapped, Nx supports the HTTP protocol, and target caching is enabled. |
|
|
80
|
+
| Repeated misses | Check Nx inputs/outputs, prefix, credentials, region and archive retention. |
|
|
81
|
+
| Expected volume hit uses Artifact Storage | A snapshot may lack the entry; inspect the recorded tier. |
|
|
82
|
+
| Corruption | The invalid local entry is removed; Artifact recovery is attempted. Repeated failure needs storage investigation. |
|
|
83
|
+
| Disk admission failure | Check available space, archive/extraction allowances and maximum archive size. |
|
|
84
|
+
| Successful task with publication errors | Fail-open preserves task success. Reproduce with strict mode. |
|
|
85
|
+
|
|
86
|
+
Structured events on stderr identify operation, tier, hash, bytes, duration and
|
|
87
|
+
sanitized error codes. The GitHub step summary reports operation counts and I/O
|
|
88
|
+
totals after publication drain. These are neither Nx task counts nor workflow wall
|
|
89
|
+
time. Credentials, signed URLs, archive contents and raw errors must stay out of
|
|
90
|
+
logs. Optional tracing is described in [benchmarking](benchmarking.md).
|
|
91
|
+
|
|
92
|
+
## Releases
|
|
93
|
+
|
|
94
|
+
Build and check with the pinned toolchain described in [Contributing](../CONTRIBUTING.md).
|
|
95
|
+
Commit reproducibly generated `dist/` files and qualify the commit on Namespace.
|
|
96
|
+
Run the release workflow manually from main with a new `vMAJOR.MINOR.PATCH` tag
|
|
97
|
+
matching `package.json`. It checks the committed distribution and prepares a draft
|
|
98
|
+
release with executables, checksums and license notices.
|
|
99
|
+
Publish the draft after verifying its assets and qualifying the commit on Namespace.
|
|
100
|
+
Existing tags must remain immutable. Consumers pin a reviewed commit or verify a
|
|
101
|
+
pinned release's checksums.
|
|
102
|
+
|
|
103
|
+
Publishing a release also triggers this workflow. It checks out the tagged commit,
|
|
104
|
+
requires that commit to be in main's history, verifies the version and committed
|
|
105
|
+
bundles, and uploads any missing release files. Existing files must match the
|
|
106
|
+
reviewed build byte for byte; retries do not replace them. Wait for the workflow
|
|
107
|
+
to finish before using standalone downloads when creating a release without
|
|
108
|
+
prepared assets. The GitHub Action itself uses the committed `dist/` files.
|
|
109
|
+
|
|
110
|
+
Draft creation does not trigger GitHub Actions. Prefer the manual draft flow when
|
|
111
|
+
all downloads must be present at publication, including when GitHub release
|
|
112
|
+
immutability is enabled. The automatic workflow packages assets; it does not
|
|
113
|
+
change repository visibility, move version tags or create a Marketplace listing.
|
|
114
|
+
|
|
115
|
+
### First public publication
|
|
116
|
+
|
|
117
|
+
Keep the source import's fresh history. Do not push refs from a private predecessor
|
|
118
|
+
or copy measured workload profiles, archives or results into this repository.
|
|
119
|
+
Review every exposed branch and tag, release asset, issue and workflow artifact
|
|
120
|
+
before changing visibility; scan the Git history and distributed files for secrets.
|
|
121
|
+
|
|
122
|
+
Prepare a new patch release from the qualified main commit when metadata or docs
|
|
123
|
+
change. Verify the draft's checksums, license files and executable bytes against
|
|
124
|
+
the reviewed build. Record the Namespace and separate-repository consumer checks;
|
|
125
|
+
offline checks do not establish runner storage behavior. Keep existing releases
|
|
126
|
+
and tags unchanged.
|
|
127
|
+
|
|
128
|
+
After approval to publish, make this repository public and publish the reviewed
|
|
129
|
+
draft. Public workflows can then use `monoai-labs/nscloud-nx-cache-action@<tag>`
|
|
130
|
+
without private-repository sharing. Prefer a full commit SHA in usage examples.
|
|
131
|
+
Check access from an unauthenticated session and a separate consumer repository.
|
|
132
|
+
|
|
133
|
+
GitHub Marketplace is a separate listing step. Use the release page's **Publish
|
|
134
|
+
this Action to the GitHub Marketplace** option, with **Continuous integration**
|
|
135
|
+
as the primary category. The root `action.yml` supplies the name, description and
|
|
136
|
+
branding. GitHub validates name availability there; do not claim a listing until
|
|
137
|
+
that check passes. An organization owner must accept the Marketplace Developer
|
|
138
|
+
Agreement, and publishing requires two-factor authentication. Follow
|
|
139
|
+
[GitHub's publication instructions](https://docs.github.com/en/actions/how-tos/create-and-publish-actions/publish-in-github-marketplace).
|
|
140
|
+
|
|
141
|
+
The repository description should describe local archives and Namespace Artifact
|
|
142
|
+
Storage; avoid latency or performance claims without published measurements.
|
|
143
|
+
|
|
144
|
+
### npm publishing
|
|
145
|
+
|
|
146
|
+
The CLI package is `@monoai/nscloud-nx-cache-action`. Stable release publication
|
|
147
|
+
also packs and publishes that version to npm after the audit, tests, reproducible
|
|
148
|
+
build and release-asset checks pass. The manual draft flow prepares the package
|
|
149
|
+
without publishing it. A retry verifies the existing npm tarball integrity and
|
|
150
|
+
skips publication only when the bytes match; lookup failures and conflicts fail.
|
|
151
|
+
|
|
152
|
+
Configure the package's npm trusted publisher for GitHub owner `monoai-labs`,
|
|
153
|
+
repository `nscloud-nx-cache-action`, workflow `release.yml`, with direct
|
|
154
|
+
`npm publish` allowed. The workflow uses a GitHub-hosted runner and `id-token: write`;
|
|
155
|
+
it needs no npm token secret. The pinned Node distribution includes npm 11.19.0,
|
|
156
|
+
which supports OIDC. npm automatically adds provenance for the public package.
|
|
157
|
+
See [npm's trusted publisher instructions](https://docs.npmjs.com/trusted-publishers/).
|
|
158
|
+
|
|
159
|
+
If the package is not yet present on npm, its owner must complete the initial
|
|
160
|
+
publication and publisher setup before automated release publishing can succeed.
|
|
161
|
+
Configure the publisher close to the release: npm requires its first successful
|
|
162
|
+
publish within two days. Keep npm versions immutable, just like release tags.
|
|
163
|
+
|
|
164
|
+
Verify packaging locally with `pnpm build` and `pnpm package:pack`. The package test
|
|
165
|
+
installs the actual tarball into an isolated workspace and exercises both binaries.
|
|
166
|
+
Only the two executables, public guides, package metadata and license notices ship.
|
|
167
|
+
TypeScript remains strictly checked; there is no importable library API or fabricated
|
|
168
|
+
declaration file. Minification preserves function/class names and legal comments.
|
package/docs/vercel.md
ADDED
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
# Using the cache with Vercel
|
|
2
|
+
|
|
3
|
+
For a source deployment, GitHub runs the deployment command and Vercel runs the
|
|
4
|
+
application build. The cache executable must run around Nx **inside that build**.
|
|
5
|
+
The GitHub Action's PATH and environment changes stay in the GitHub job.
|
|
6
|
+
|
|
7
|
+
This guide uses an existing Nx/pnpm workspace, an application at `apps/web`, and
|
|
8
|
+
an Nx target named `web:build`. Substitute your application's path and target.
|
|
9
|
+
Use Node 24.x on Vercel; the connector is tested with Nx 23.3.0. Pin pnpm through
|
|
10
|
+
your root `packageManager` field and commit its lockfile. Configure Vercel's
|
|
11
|
+
[package-manager selection](https://vercel.com/docs/package-managers) to use that pin.
|
|
12
|
+
|
|
13
|
+
## Put the release files in the deployed source
|
|
14
|
+
|
|
15
|
+
Download the executables and notices from a reviewed
|
|
16
|
+
[release](https://github.com/monoai-labs/nscloud-nx-cache-action/releases), such as
|
|
17
|
+
v0.1.0. Keep the complete set together in your repository:
|
|
18
|
+
|
|
19
|
+
```text
|
|
20
|
+
tools/nx-cache/
|
|
21
|
+
nscloud-nx-cache-action.mjs
|
|
22
|
+
token.mjs
|
|
23
|
+
SHA256SUMS
|
|
24
|
+
LICENSE
|
|
25
|
+
NOTICE
|
|
26
|
+
THIRD_PARTY_LICENSES.txt
|
|
27
|
+
vercel-build.sh
|
|
28
|
+
apps/web/vercel.json
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Before committing the release files, verify them from `tools/nx-cache` with
|
|
32
|
+
`sha256sum --check SHA256SUMS`, or `shasum -a 256 --check SHA256SUMS` on macOS.
|
|
33
|
+
Copying the files also supports private releases that a hosted builder cannot
|
|
34
|
+
download. Keep a record of the reviewed release and commit when updating them.
|
|
35
|
+
|
|
36
|
+
Set the Vercel project's Root Directory to `apps/web` and enable
|
|
37
|
+
[source files outside the Root Directory](https://vercel.com/docs/monorepos/monorepo-faq).
|
|
38
|
+
Submit source from the workspace root so the lockfile, shared packages and cache
|
|
39
|
+
files are included. Check `.vercelignore` and Git ignore rules: if they exclude
|
|
40
|
+
your chosen bundle directory or `*.mjs`, add exceptions for these release files.
|
|
41
|
+
|
|
42
|
+
## Wrap the Nx build in Vercel
|
|
43
|
+
|
|
44
|
+
Create `tools/nx-cache/vercel-build.sh`:
|
|
45
|
+
|
|
46
|
+
```sh
|
|
47
|
+
#!/usr/bin/env sh
|
|
48
|
+
set -eu
|
|
49
|
+
|
|
50
|
+
cache_script_directory=$(CDPATH='' cd -- "$(dirname -- "$0")" && pwd)
|
|
51
|
+
cache_workspace_root=$(CDPATH='' cd -- "$cache_script_directory/../.." && pwd)
|
|
52
|
+
cd "$cache_workspace_root"
|
|
53
|
+
|
|
54
|
+
export NX_ARCHIVE_DIRECTORY="$cache_workspace_root/node_modules/.cache/nx-namespace"
|
|
55
|
+
export NX_ARTIFACT_PREFIX="${NX_ARTIFACT_PREFIX:-nx/v1/your-org/your-repo}"
|
|
56
|
+
|
|
57
|
+
if [ -z "${NX_NAMESPACE_TOKEN:-}" ]; then
|
|
58
|
+
unset NX_ARTIFACT_PREFIX
|
|
59
|
+
fi
|
|
60
|
+
|
|
61
|
+
exec node "$cache_script_directory/nscloud-nx-cache-action.mjs" \
|
|
62
|
+
corepack pnpm exec nx "$@"
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Replace `nx/v1/your-org/your-repo` with your repository's cache prefix. Use the
|
|
66
|
+
**same prefix and Artifact region** for CI and Vercel when they should share
|
|
67
|
+
entries. The region defaults to `ord`; use `NX_ARTIFACT_REGION` to override it.
|
|
68
|
+
Prefixes partition entries, while provider permissions enforce access.
|
|
69
|
+
|
|
70
|
+
The wrapper uses a workspace-local archive directory. Vercel does not mount a
|
|
71
|
+
Namespace NVMe Cache Volume; Artifact Storage supplies the shared tier. The
|
|
72
|
+
tokenless branch explicitly selects local-only caching, including Git-triggered
|
|
73
|
+
builds that have no issued credential.
|
|
74
|
+
|
|
75
|
+
Merge these commands into `apps/web/vercel.json`, retaining your framework,
|
|
76
|
+
output and other application settings:
|
|
77
|
+
|
|
78
|
+
```json
|
|
79
|
+
{
|
|
80
|
+
"$schema": "https://openapi.vercel.sh/vercel.json",
|
|
81
|
+
"installCommand": "cd ../.. && corepack pnpm install --frozen-lockfile",
|
|
82
|
+
"buildCommand": "sh ../../tools/nx-cache/vercel-build.sh run web:build"
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
This wrapper calls the Nx executable directly. If your existing `pnpm nx` script
|
|
87
|
+
already starts the connector, keep one wrapper rather than nesting them. Nx still
|
|
88
|
+
owns dependency builds and task selection. Only cache deterministic targets with
|
|
89
|
+
correct inputs and outputs; migrations and deployment side effects must execute
|
|
90
|
+
normally. An application build can remain uncached while reusing package builds.
|
|
91
|
+
|
|
92
|
+
## Send a short-lived credential with the source deployment
|
|
93
|
+
|
|
94
|
+
Connect the Namespace Cloud GitHub app for the deploying repository. The GitHub
|
|
95
|
+
OIDC identity must be allowed to issue and revoke Artifact credentials. Configure
|
|
96
|
+
Vercel's token and the IDs of an existing Vercel project in GitHub; pin the Vercel
|
|
97
|
+
CLI in your workspace's development dependencies.
|
|
98
|
+
|
|
99
|
+
This example runs from the workspace root on trusted main pushes. It uses the
|
|
100
|
+
copied token helper, so it does not require installing this GitHub Action or
|
|
101
|
+
mounting a Namespace volume in the deployment job:
|
|
102
|
+
|
|
103
|
+
```yaml
|
|
104
|
+
name: Deploy web
|
|
105
|
+
on:
|
|
106
|
+
push:
|
|
107
|
+
branches: [main]
|
|
108
|
+
permissions:
|
|
109
|
+
contents: read
|
|
110
|
+
id-token: write
|
|
111
|
+
jobs:
|
|
112
|
+
deploy:
|
|
113
|
+
runs-on: ubuntu-latest
|
|
114
|
+
env:
|
|
115
|
+
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
|
|
116
|
+
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
|
|
117
|
+
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
|
|
118
|
+
NX_CACHE_FAILURE_MODE: strict
|
|
119
|
+
steps:
|
|
120
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
121
|
+
- uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
|
|
122
|
+
with:
|
|
123
|
+
node-version: 24.21.0
|
|
124
|
+
package-manager-cache: false
|
|
125
|
+
- run: corepack enable
|
|
126
|
+
- run: corepack pnpm install --frozen-lockfile
|
|
127
|
+
- uses: namespacelabs/nscloud-setup@df198f982fcecfb8264bea3f1274b56a61b6dfdc # v0.0.12
|
|
128
|
+
- run: nsc auth exchange-github-token
|
|
129
|
+
- name: Deploy source and wait for its build
|
|
130
|
+
run: |
|
|
131
|
+
NSC_TOKEN_FILE="$HOME/.config/ns/token.json" \
|
|
132
|
+
node tools/nx-cache/token.mjs read-write \
|
|
133
|
+
corepack pnpm exec vercel deploy --yes --prod \
|
|
134
|
+
--build-env NX_NAMESPACE_TOKEN \
|
|
135
|
+
--build-env NX_CACHE_FAILURE_MODE=strict
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
`--build-env NX_NAMESPACE_TOKEN` forwards the credential from the token helper's
|
|
139
|
+
child environment to Vercel's build. Do not use `--env` or persist this token in
|
|
140
|
+
Vercel project settings. Vercel distinguishes
|
|
141
|
+
[build variables from runtime variables](https://vercel.com/docs/cli/deploy#build-env).
|
|
142
|
+
The example uses strict mode for both issuance and the hosted cache, so an access
|
|
143
|
+
failure cannot look like successful cache qualification. After qualification,
|
|
144
|
+
choose fail-open if builds should proceed when caching is unavailable.
|
|
145
|
+
|
|
146
|
+
The helper revokes the credential when its child exits, and its maximum lifetime
|
|
147
|
+
is one hour. Keep that child running until the remote build finishes. Do not add
|
|
148
|
+
[`--no-wait`](https://vercel.com/docs/cli/deploy#no-wait); an API-based deployment
|
|
149
|
+
client must poll for build completion before returning too. Build queue time
|
|
150
|
+
counts toward the credential lifetime. Do not print the token or enable shell
|
|
151
|
+
tracing around credential handling.
|
|
152
|
+
|
|
153
|
+
For trusted previews, remove `--prod` and deliberately choose the preview's
|
|
154
|
+
publication policy. To prevent shared publication, issue a `read-only` token and
|
|
155
|
+
pass `--build-env NX_CACHE_REMOTE_ACCESS=read-only`; this retains local writes.
|
|
156
|
+
Setting `NX_CACHE_ACCESS=read-only` also disables local archive writes. Use your
|
|
157
|
+
existing deployment admission rules for untrusted branches and forks. Choose
|
|
158
|
+
which deployment system owns each environment to avoid duplicate CLI and native
|
|
159
|
+
Git builds.
|
|
160
|
+
|
|
161
|
+
## Validate the hosted path
|
|
162
|
+
|
|
163
|
+
First qualify a non-production deployment with strict cache failure mode:
|
|
164
|
+
|
|
165
|
+
1. Confirm the uploaded source contains the reviewed executable and that the
|
|
166
|
+
build log shows the wrapper invoking your intended Nx target.
|
|
167
|
+
2. Check for successful Artifact publications from eligible cacheable targets.
|
|
168
|
+
3. Start a fresh source deployment with unchanged task inputs. Confirm Artifact
|
|
169
|
+
hits, matching restored outputs, and no executor runs for those targets. A
|
|
170
|
+
framework build or unrelated uncached task may still run.
|
|
171
|
+
4. Change a declared input and confirm the affected task executes again.
|
|
172
|
+
5. Confirm the deployment request has a build-only cache credential, and that
|
|
173
|
+
the deployment client waits through the build before the helper exits.
|
|
174
|
+
|
|
175
|
+
Successful deployment alone is not evidence of caching: fail-open mode can build
|
|
176
|
+
everything normally after a cache failure. The connector writes structured
|
|
177
|
+
events to build stderr; Vercel does not provide GitHub step summaries. Keep the
|
|
178
|
+
prefix and region consistent and check that every intended task declares caching.
|
|
179
|
+
|
|
180
|
+
For `vercel build` followed by `vercel deploy --prebuilt`, the build runs in your
|
|
181
|
+
CI environment instead. `vercel build` executes the configured build command,
|
|
182
|
+
which starts the Nx wrapper there. Give the build process its cache credential
|
|
183
|
+
and hold that credential until the local build finishes; do not add another cache
|
|
184
|
+
wrapper around `vercel build`. The prebuilt upload performs no remote Nx build
|
|
185
|
+
and needs no cache credential. Fetch the project's settings with `vercel pull`
|
|
186
|
+
before building, as described in
|
|
187
|
+
[Vercel's local build documentation](https://vercel.com/docs/cli/build).
|
package/package.json
CHANGED
|
@@ -1,6 +1,78 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@monoai/nscloud-nx-cache-action",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.1.2",
|
|
4
|
+
"description": "CLI tools for Nx HTTP caching across local development, Namespace runners and hosted builds, with local archives, shared Artifact Storage and short-lived build credentials.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"bin": {
|
|
8
|
+
"nscloud-nx-cache-action": "dist/nscloud-nx-cache-action.mjs",
|
|
9
|
+
"nx-namespace-token": "dist/token.mjs"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"dist/nscloud-nx-cache-action.mjs",
|
|
13
|
+
"dist/token.mjs",
|
|
14
|
+
"docs/configuration.md",
|
|
15
|
+
"docs/operations.md",
|
|
16
|
+
"docs/vercel.md",
|
|
17
|
+
"docs/benchmarking.md",
|
|
18
|
+
"LICENSE",
|
|
19
|
+
"NOTICE",
|
|
20
|
+
"THIRD_PARTY_LICENSES.txt"
|
|
21
|
+
],
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "https://github.com/monoai-labs/nscloud-nx-cache-action.git"
|
|
25
|
+
},
|
|
26
|
+
"homepage": "https://github.com/monoai-labs/nscloud-nx-cache-action#readme",
|
|
27
|
+
"bugs": {
|
|
28
|
+
"url": "https://github.com/monoai-labs/nscloud-nx-cache-action/issues"
|
|
29
|
+
},
|
|
30
|
+
"keywords": [
|
|
31
|
+
"nx",
|
|
32
|
+
"namespace",
|
|
33
|
+
"cache",
|
|
34
|
+
"cli",
|
|
35
|
+
"github-actions"
|
|
36
|
+
],
|
|
37
|
+
"publishConfig": {
|
|
38
|
+
"access": "public",
|
|
39
|
+
"registry": "https://registry.npmjs.org"
|
|
40
|
+
},
|
|
41
|
+
"packageManager": "pnpm@11.22.0",
|
|
42
|
+
"engines": {
|
|
43
|
+
"node": "24.x"
|
|
44
|
+
},
|
|
45
|
+
"scripts": {
|
|
46
|
+
"check": "pnpm run config:check && pnpm run format:check && pnpm run lint && pnpm run typecheck && pnpm test",
|
|
47
|
+
"config:check": "tsx scripts/validate-config.ts",
|
|
48
|
+
"format": "oxfmt --write src scripts tests bench package.json tsconfig.json .oxlintrc.json .oxfmtrc.json",
|
|
49
|
+
"format:check": "oxfmt --check src scripts tests bench package.json tsconfig.json .oxlintrc.json .oxfmtrc.json",
|
|
50
|
+
"lint": "oxlint --deny-warnings src scripts tests bench",
|
|
51
|
+
"lint:fix": "pnpm run lint --fix",
|
|
52
|
+
"typecheck": "tsc --noEmit",
|
|
53
|
+
"test": "tsx --test tests/*.test.ts",
|
|
54
|
+
"fixture": "tsx scripts/generate-fixture.ts",
|
|
55
|
+
"integration:restoration": "tsx scripts/integration-restoration.ts",
|
|
56
|
+
"integration:contracts": "tsx scripts/contract-check.ts",
|
|
57
|
+
"build": "tsx scripts/build.ts",
|
|
58
|
+
"package:pack": "npm pack --pack-destination .output/npm",
|
|
59
|
+
"publish:npm": "tsx scripts/publish-npm.ts",
|
|
60
|
+
"bench:restoration:offline": "tsx bench/restoration/offline.ts",
|
|
61
|
+
"bench:restoration:live": "tsx bench/restoration/run.ts",
|
|
62
|
+
"bench:restoration:analyze": "tsx bench/restoration/analyze.ts"
|
|
63
|
+
},
|
|
64
|
+
"devDependencies": {
|
|
65
|
+
"@bufbuild/protobuf": "2.14.1",
|
|
66
|
+
"@connectrpc/connect": "2.2.0",
|
|
67
|
+
"@namespacelabs/sdk": "1.0.0",
|
|
68
|
+
"@types/node": "^24.19.2",
|
|
69
|
+
"ajv": "8.20.0",
|
|
70
|
+
"esbuild": "0.28.2",
|
|
71
|
+
"nx": "23.3.0",
|
|
72
|
+
"oxfmt": "0.71.0",
|
|
73
|
+
"oxlint": "1.86.0",
|
|
74
|
+
"tsx": "4.23.13",
|
|
75
|
+
"typescript": "5.9.3",
|
|
76
|
+
"yaml": "2.9.0"
|
|
77
|
+
}
|
|
78
|
+
}
|