niklaspor / nx-remotecache-custom Goto Github PK
View Code? Open in Web Editor NEWBuild custom caching for @nrwl/nx in a few lines of code
License: MIT License
Build custom caching for @nrwl/nx in a few lines of code
License: MIT License
Can we expect some support for the nx v18 shortly, since there are no breaking changes in v18 compared to v17?
Hey,
Given a 33MB output in the dist folder, I receive the following error from adm-zip:
Unexpected error:
RangeError [ERR_OUT_OF_RANGE]: The value of "value" is out of range. It must be >= 0 and <= 4294967295. Received -333381632
at new NodeError (node:internal/errors:371:5)
at checkInt (node:internal/buffer:72:11)
at writeU_Int32LE (node:internal/buffer:692:3)
at Buffer.writeUInt32LE (node:internal/buffer:705:10)
at Object.dataHeaderToBinary (/build/node_modules/adm-zip/headers/entryHeader.js:255:18)
at Object.compressToBuffer (/build/node_modules/adm-zip/zipFile.js:257:49)
at Object.toBuffer (/build/node_modules/adm-zip/adm-zip.js:780:25)
at zipFolder (/build/node_modules/nx-remotecache-custom/create-remote-cache-store.js:12:16)
at Object.store (/build/node_modules/nx-remotecache-custom/create-remote-cache-store.js:21:20) {
code: 'ERR_OUT_OF_RANGE'
}
within zipFolder()
return zip.toBuffer();
causes this thrown error,
The out of range error is also documented here: cthackers/adm-zip#375
Imho there are two options two "solve" this:
a) make the remote cache more stable against this error to at least make sure it is not exiting unexpectedly
b) use a different zip library
https://github.com/NiklasPor/nx-remotecache-minio/blob/main/lib/index.ts#L55 outputs Minio Storage
to the build logs.
In my situation it is advantageous to be able to override this name for CI/CD pipelines (connecting to a different Minio instance) using an ENV var such as NX_CACHE_MINIO_NAME
, so that it's clearer to the users which cache is being used.
Nu hurry. Just a "nice to have".
Hi!
As a result from the issue #26, I always see this problem, but only on Windows. The source
file is not filtered, because the tar
lib use only paths with slash, and the path.join
function is dependant of the OS (and so, backslash for Windows). The source filenames can't be equal so.
Maybe we can use path.normalize(path)
inside the filter function to be sure that we have the same system (join
use the normalize function inside).
Hi, We're facing intermittent issues where sometimes an application is built and transpiled (using webpack) with an older version of a library. The library itself is built and uses the latest code, but the application uses old code. If we inspect the /dist/ folder we see that the source code of the lib is what we expect, but that the application uses the previous version (sometimes!!).
Any idea what could be causing this?
I saw somewhere that the cached library doesn't get added to the /dist
folder?
nx run my-library:build
Compiling TypeScript files for project "my-library"...
Done compiling TypeScript files for project "my-library".
------------------------------------------------------------------------------
Stored output to remote cache: @zackarydev/nx-remotecache-gcs
File: afilehash.tar.gz
------------------------------------------------------------------------------
Hi,
While trying the nx-remotecache-azure library, it failed with 'Cannot find module 'fs/promises'. I traced the issue to this repo. I'll submit a PR to fix it.
Thanks in advance
Are there any plans to support NX 19 in the near future?
I've noticed that my processes stopped reacting on ctrl + c. Actually no other keys are propagated to the program anymore.
To reproduce:
nx lint myapp --skip-nx-cache
. Try to type something while the command executes or exit it using "ctrl + c". Notice it works finenx-remotecache-azure
task runner"tasksRunnerOptions": {
"default": {
"runner": "nx-remotecache-azure",
"options": {
"container": "nx-cache"
}
}
},
nx lint myapp --skip-nx-cache
again. Notice commands stdin stopped working and processes are not cancellable anymore@dmitry-stepanenko ➜ npx nx report
> NX Report complete - copy this into the issue template
Node : 20.11.0
OS : linux-x64
npm : 10.2.4
nx : 17.3.2
@nx/js : 17.3.2
@nx/jest : 17.3.2
@nx/linter : 17.3.2
@nx/eslint : 17.3.2
@nx/workspace : 17.3.2
@nx/angular : 17.3.2
@nx/cypress : 17.3.2
@nx/devkit : 17.3.2
@nx/eslint-plugin : 17.3.2
@nrwl/tao : 17.3.2
@nx/web : 17.3.2
@nx/webpack : 17.3.2
typescript : 5.3.3
@dmitry-stepanenko ➜ npm list nx-remotecache-azure
└── [email protected]
Hi, while using this lib at one of the projects at work i encountered an issue when cached standalone build of nextjs app wrapped with sentry throws an error in docker, my investigation lead to the conclusion that cached build was missing files for [email protected]
because it has source
dir which was missing in cached build.
The issue i think is with this function but i haven't really understood what it filters overall
For reproduction of this problem i've made an example repo
https://github.com/EvgeniyKumachev/nx-cache-repro
If an error is generated while downloading a file, https://github.com/NiklasPor/nx-remotecache-custom/blob/main/lib/get-safe-remote-cache-implementation.ts does not catch it.
IE an error that happens mid-stream. Like a timeout or something.
It escapes and kills nx.
Hi,
NX has the feature of allowing developers to create .env files specific to different targets and configurations:
https://nx.dev/recipes/environment-variables/define-environment-variables
E.g. having a baseline .env
file and .env.serve
with overrides
Under the hood, they parse each file and layer them according to the rules mentioned in the docs, and then override those with process.env
, e.g.
// Start With Dotenv Variables
...this.getDotenvVariablesForTask(task),
// User Process Env Variables override Dotenv Variables
...process.env,
Which makes sense, since user provided environment variables should override environment files.
The issues is, this library uses dotenv
to parse and configure relevant variables from .env file, during which this line is executed:
if (!processEnv[key]) {
processEnv[key] = parsed[key]
}
This means that process.env
is populated by dotenv with the values from .env if they aren't already present, which prevents NX from properly layering the environment files, because process.env will always override everything with the values from .env (the code from this library is executed earlier than NX's internal loading code).
My suggestion would be to read the .env file manually and parse it using dotenv.parse(dotenvFileContent)
instead of calling dotenv.config()
.
For us, since we're not using dotenv, we disabled this option anyway.
(moved from NiklasPor/nx-remotecache-azure#22)
Hello,
I don't know if I mis understood something, but I'm having troubles to configure the custom cache (using azure in my case).
When I run pnpm nx run "@myorg/myproject:build" --verbose
from the root of the workspace, I can see cache populated.
But if I run cd packages/myproject
then pnpm nx build --verbose
, the cache does not works.
I get this error:
Warning: Failed to store cache to Azure Blob Storage
File: 12345658363156603647.tar.gz
Error: Did not pass valid container. Supply the container either via env or nx.json.
To setup the cache, I configured my root nx.json
file like this:
{
"tasksRunnerOptions": {
"default": {
"runner": "nx-remotecache-azure",
"options": {
"maxParallel": 4,
"dotenvPath": ".env.secrets",
"cacheableOperations": ["build", "test", "lint", "e2e", "release"]
}
}
},
....
}
And I created a file .env.secrets
sibling to the nx.json
file which contains:
# Chaine de connexion du blob storage stockant le cache de Nx
NXCACHE_AZURE_SAS_URL=https://mystorageaccount.blob.core.windows.net/nx-cache?sp=racwdli&st=2024-03-26T07:59:15Z&se=2028-03-26T14:59:15Z&spr=https&sv=2022-11-02&sr=c&sig=abcabcabcabcabc%3D
The full error is:
------------------------------------------------------------------------------
Warning: Failed to store cache to Azure Blob Storage
File: 12482558363156603647.tar.gz
Error: Did not pass valid container. Supply the container either via env or nx.json.
------------------------------------------------------------------------------
Error: Did not pass valid container. Supply the container either via env or nx.json.
at getBlockBlobClient (C:\path\to\node_modules\.pnpm\[email protected][email protected]\node_modules\nx-remotecache-azure\index.js:26:15)
at blob (C:\path\to\node_modules\.pnpm\[email protected][email protected]\node_modules\nx-remotecache-azure\index.js:49:32)
at storeFile (C:\path\to\node_modules\.pnpm\[email protected][email protected]\node_modules\nx-remotecache-azure\index.js:54:42)
at C:\path\to\node_modules\.pnpm\[email protected][email protected]\node_modules\nx-remotecache-custom\get-safe-remote-cache-implementation.js:30:30
at Object.store (C:\path\to\node_modules\.pnpm\[email protected][email protected]\node_modules\nx-remotecache-custom\create-remote-cache-store.js:17:11)
at async C:\path\to\node_modules\.pnpm\[email protected]\node_modules\nx\src\tasks-runner\cache.js:99:17
at async _try (C:\path\to\node_modules\.pnpm\[email protected]\node_modules\nx\src\tasks-runner\cache.js:222:24)
at async Promise.all (index 0)
at async TaskOrchestrator.postRunSteps (C:\path\to\node_modules\.pnpm\[email protected]\node_modules\nx\src\tasks-runner\task-orchestrator.js:261:13)
at async TaskOrchestrator.applyFromCacheOrRunTask (C:\path\to\node_modules\.pnpm\[email protected]\node_modules\nx\src\tasks-runner\task-orchestrator.js:216:9)
When running from the workspace root, I get, in the output
Stored output to remote cache: Azure Blob Storage
File: 14400678733458654225.tar.gz
If I set up manually the env variable using
$env:NXCACHE_AZURE_SAS_URL="https://mystorageaccount.blob.core.windows.net/nx-cache?sp=racwdli&st=2024-03-26T07:59:15Z&se=2028-03-26T14:59:15Z&spr=https&sv=2022-11-02&sr=c&sig=abcabcabcabcabc%3D"
The cache always works, so I guess there's something wrong with the way the local .env.secrets
file is read.
I tried to explicitely targets the env file at workspace root using "dotenvPath": "{workspaceroot}/.env.secrets"
, but there's no more success.
If it matters, pnpm why nx*
give:
devDependencies:
nx 18.0.8
└─┬ @nrwl/tao 18.0.8
└── nx 18.0.8
nx-remotecache-azure 18.0.0
├─┬ nx 18.0.8 peer
│ └─┬ @nrwl/tao 18.0.8
│ └── nx 18.0.8
└─┬ nx-remotecache-custom 18.0.0
└─┬ nx 18.0.8 peer
└─┬ @nrwl/tao 18.0.8
└── nx 18.0.8
And my node version is 16.20.2
Thanks
Hi, I'm not quite sure what the point of this library is, but it seems like it might be what I need. Adding a better description in the README would be nice.
My Q though: this essentially allows offloading the Nx cache to a third party? I.e. instead of using a local folder say within node_modules you can upload/download it from a HotStorage container somewhere?
What are the performance impacts of this library?
NX Invalid Cache Directory for Task "*-e2e:e2e"
The local cache artifact in "*" was not been generated on this machine.
As a result, the cache's content integrity cannot be confirmed, which may make cache restoration potentially unsafe.
If your machine ID has changed since the artifact was cached, run "nx reset" to fix this issue.
Read about the error and how to address it here: https://nx.dev/recipes/troubleshooting/unknown-local-cache
Pass --verbose to see the stacktrace.
Reproduction steps:
Dont have a local cache, but a remote available. Run the task so it retrieves from cache. Run the task again and you get invalid cache dir.
"nx": "16.10.0",
"@nx/workspace": "16.10.0",
```
at Cache.assertLocalCacheValidity (/node_modules/.pnpm/nx@16.10.0_@swc-node+register@1.6.8_@swc[email protected]/node_modules/nx/src/tasks-runner/cache.js:203:23)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async Cache.get (/node_modules/.pnpm/nx@16.10.0_@swc-node+register@1.6.8_@swc[email protected]/node_modules/nx/src/tasks-runner/cache.js:58:13)
at async TaskOrchestrator.applyCachedResult (s/node_modules/.pnpm/nx@16.10.0_@swc-node+register@1.6.8_@swc[email protected]/node_modules/nx/src/tasks-runner/task-orchestrator.js:79:30)
at async Promise.all (index 0)
at async TaskOrchestrator.applyCachedResults /node_modules/.pnpm/nx@16.10.0_@swc-node+register@1.6.8_@swc[email protected]/node_modules/nx/src/tasks-runner/task-orchestrator.js:74:21)
at async TaskOrchestrator.applyFromCacheOrRunTask (/node_modules/.pnpm/nx@16.10.0_@swc-node+register@1.6.8_@swc[email protected]/node_modules/nx/src/tasks-runner/task-orchestrator.js:153:40)
at async TaskOrchestrator.executeNextBatchOfTasksUsingTaskSchedule (/node_modules/.pnpm/nx@16.10.0_@swc-node+register@1.6.8_@swc[email protected]/node_modules/nx/src/tasks-runner/task-orchestrator.js:64:13)
at async Promise.all (index 0)
at async TaskOrchestrator.run (*/node_modules/.pnpm/nx@16.10.0_@swc-node+register@1.6.8_@swc[email protected]/node_modules/nx/src/tasks-runner/task-orchestrator.js:41:9)
note: the cache needs to be created on another machine
Hi Niklas,
Awesome project. I'll definitely use this!
My question to you is: if you know of any ready-made self-hosted remote-cache service implementations (or if you have one of your own which you would like to share)?
I'm very new to Nx, and in my searches the closest thing I could find is https://github.com/gilsdav/nx-cloud-onprem-runner/tree/master/apps/nx-cloud-onprem/src
Which still seems to work (just tested it), but appears to be abandoned. A shame, because it really is quite simple in its setup.
That project appears to provide both the client-side runner, as well as a simple remote-cache service implementation.
I'm very interested in this, because that would basically transform your project into a full Nx Private Cloud alternative :)
If you don't know any, I think I'll fork the project mentioned above and try to get it up to date and compatible with your nx-remotecache-custom runner.
When I install @nx/workspace
in the root of my Monorepo repository I get the below error. There a several packages in the Monorepo but only the packages that uses nx-remotecache-custom
fails to build because of the below error. Has anyone experienced a similar issue?
[!] Error: Could not resolve './nx.android-arm64.node' from ./nx.android-arm64.node?commonjs-external
Error: Could not resolve './nx.android-arm64.node' from ./nx.android-arm64.node?commonjs-external
at error (/usr/src/libs/node_modules/rollup/dist/shared/rollup.js:151:30)
at ModuleLoader.handleResolveId (/usr/src/libs/node_modules/rollup/dist/shared/rollup.js:19817:24)
at /usr/src/libs/node_modules/rollup/dist/shared/rollup.js:19766:22
at async Promise.all (index 0)
at ModuleLoader.fetchStaticDependencies (/usr/src/libs/node_modules/rollup/dist/shared/rollup.js:19764:34)
at async Promise.all (index 0)
at ModuleLoader.fetchModule (/usr/src/libs/node_modules/rollup/dist/shared/rollup.js:19740:9)
at async Promise.all (index 34)
at ModuleLoader.fetchStaticDependencies (/usr/src/libs/node_modules/rollup/dist/shared/rollup.js:19764:34)
at async Promise.all (index 0)
npm ERR! Lifecycle script `build:prod` failed with error:
npm ERR! Error: command failed
There is also another variant of this issue which is shown below
[!] Error: Could not resolve './nx.darwin-x64.node' from ./nx.darwin-x64.node?commonjs-external
Error: Could not resolve './nx.darwin-x64.node' from ./nx.darwin-x64.node?commonjs-external
at error (/usr/src/libs/node_modules/rollup/dist/shared/rollup.js:151:30)
at ModuleLoader.handleResolveId (/usr/src/libs/node_modules/rollup/dist/shared/rollup.js:19817:24)
at /usr/src/libs/node_modules/rollup/dist/shared/rollup.js:19766:22
at async Promise.all (index 0)
at ModuleLoader.fetchStaticDependencies (/usr/src/libs/node_modules/rollup/dist/shared/rollup.js:19764:34)
at async Promise.all (index 0)
at ModuleLoader.fetchModule (/usr/src/libs/node_modules/rollup/dist/shared/rollup.js:19740:9)
at async Promise.all (index 46)
at ModuleLoader.fetchStaticDependencies (/usr/src/libs/node_modules/rollup/dist/shared/rollup.js:19764:34)
at async Promise.all (index 0)
npm ERR! Lifecycle script `build:prod` failed with error:
npm ERR! Error: command failed
We run the build in a docket container that uses node 16 and NPM 9.
@nx/[email protected]
[email protected]
NX Remotecache currently builds the cache locally, hashes and stores it remotely (into the various options provided). This seems to be a personal hash, as neither CI nor other developers cache will be shown as cache you can retrieve.
NX' implementation of the remote cache shares the cache amongst others.
This can help when sharing a monorepo situation amongst developers.
Or when a new developer joins the team, they don't have to run all the things locally, where a version is already available remotely
Or when a developer has a new environment.
This does help various situations:
To use nx-cloud
itself. This can have impact as it's closed source, and only has a limited amount of free executions.
This library currently depends on @nrwl/workspace
which has been deprecated in Nx 16 in favor of @nx/workspace
.
The tasks-runners/default
is available in the core nx
package, there is no need to import it from an additional package.
This is a follow-up on a bug report for the package @pellegrims/nx-remotecache-s3, which is depending on this awesome library.
The issue is about the console output with the custom task runner not appending succesful job results to previous results as is the case for the default task runner in nx > v14.
I was wondering if you encounter the same issue on other packages depending on nx-remotecache-custom? Any clue what causes this behavior?
Today both store and retrieve operations read stream of archive and fully buffer it before archiving/extracting. Buffering means that whole file is read into memory. Having such implementation will produce uneven (spiky) memory consumption with upper limit way higher comparing to what it could be when working with stream directly.
This might be ok (not noticeable) for runners with only console output (lint/test), but it could quickly become an issue for caches of build runner where whole output directory is kept in cache (sometimes tens or hundreds on megabytes).
It would be great to update implementation so it would be capable working with streams of archives without buffering them. npm/node-tar (as a replacement for current adm-zip
package) seems to support streams well.
I would be happy to contribute if no issues with this solution (or usage of node-tar
) are seen.
I use a (very common) dark theme for my terminal. "Standard" Nx output works fine even for text that's lighter.
However, the output of nx-remotecache-custom
isn't readable except for the name of the cache store or when there's a warning. I have to select the text for it to show.
As you can see, the lighter text from Nx output shows just fine.
I have some problems with libraries based on nx-remotecache-custom
We have a big project. And when I try to build I see this output:
(node:25020) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 Symbol(destroyed) listeners added to [Pack]. Use emitter.setMaxListeners() to increase limit
(Use `node --trace-warnings ...` to show where the warning was created)
Tried to use 2 custom libs, and write my own interpretation, but no luck.
Think this is something with "stream"'s
Relates to vercel/remote-cache#17
To properly report on time saved in Vercel Remote Cache, we need to know how long the cache artifact took to generate (the time the task took).
Is this something that is already provided by NX and could be passed through? Or does this require upstream changes in NX?
When using a custom nx:run-commands operation and add it to the cacheableOperations
in nx.json, the command hangs up and never starts.
Can be reproduced by adding a custom command to any project.json and add it to the cacheableOperations in nx.json like this:
project.json
"targets": {
"custom": {
"executor": "nx:run-commands",
"options": {
"command": "echo hello-world"
}
},
}
nx.json
"tasksRunnerOptions": {
"default": {
"runner": "nx-remotecache-minio",
"options": {
"accessKey": "...",
"secretKey": "...",
"url": "...",
"bucket": "nx-cache",
"cacheableOperations": ["build", "lint", "test", "e2e", "custom"]
}
}
},
Using the default nx caching with runner nx/tasks-runners/default
works fine though for local caching.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.