# Cockpit Javascript Dependencies

For included Javascript libraries, and build processes
Cockpit uses Node.js dependencies to process its code. The required Node.JS
javascript code is packaged in the `node_modules/` directory when distributed.

Cockpit does not use Node.js or any npm packages code at runtime. In addition
when building straight from a tarball it is also not necessary to have Node.js
installed.

## Git builds

When building from Git, the `node_modules/` directory is managed as a git
submodule from the `node-cache` repository in the same project as the main
repository (ie: `cockpit-project/node-cache`).  That means that normal builds
won't need to run `npm install`.  Checking out the correct version of the
`node_modules` directory is managed by the script `tools/node-modules`, which
is automatically invoked from the build system on an as-needed basis, and has
good caching.  You can also do a recursive git checkout, if you'd prefer to
build in a no-network environment, but you'll lose the caching benefits.

The gitlink for `node_modules/` is always kept in sync with the `package.json`
file used to fetch that set of modules with `npm install`.

## Making changes

In the event that you need to modify `package.json`, the `node_modules` will
need to be regenerated, and a new commit recorded.  That can be managed locally
by running

```
tools/node_modules rebuild
```

which will produce a commit which is available for local testing.

When you are ready to open a pull request with your changes, it's not possible
to push your local `node_modules` commit.  For security and reproducability
reasons, the commits used in the main branch of the project are always
generated by a script running in a controlled environment under GitHub Actions
as part of the CI setup of Cockpit.

You should push your changes with your updated `node_modules/` gitlink, but
without the locally-generated `node_modules` commit that it refers to.  The CI
build will fail due to the broken reference.  At this point, someone with write
access to the repository must write a comment into the PR:

```
/npm install
```

which will trigger a build of a new `node_modules` commit.  The commit is
pushed as a tag to the `node-cache` repository.  The bot will reply with a
command that you can run locally to make use of this "official" commit in your
new branch, and you'll have to rebase and force push.

## GitHub setup notes (documentation for project admins)

This section documents the way to setup the `node-cache` repository on GitHub,
from scratch.  This could potentially be automated, but it doesn't need to
happen regularly, so it's not a high priority.  These instructions may also be
useful for other projects or for forks.

On the GitHub side, the workflow is driven from the `npm-install.yml` script,
and makes use of the `node-cache upload` environment, which needs to be
configured with a `NODE_CACHE_DEPLOY_KEY` secret.  The exact steps:

 - create the `node-cache` repository under the same project as the main
   repository (or fork it)
 - add a commit to that repository with a `README`.  At least one commit on a
   named branch needs to be present in order for the GitHub web UI to function
   properly (eg: generate diffs, show tree contents, etc.)
 - generate an SSH key locally, without a passphrase, without touching the disk:
   `ssh-keygen -t ed25519 -C 'node-cache deploy' -f "${XDG_RUNTIME_DIR}/deploy-key" -N ''`
 - create an environment called `node-cache upload` in the settings of the
   primary repository:
   https://github.com/cockpit-project/cockpit/settings/environments/new
 - add the content of the private key `deploy-key` to the `node-cache upload`
   environment as a secret with the name `NODE_CACHE_DEPLOY_KEY`
 - upload the public key `deploy-key.pub` as a deploy key to `node-cache` with
   write access enabled:
   https://github.com/cockpit-project/node-cache/settings/keys/new
 - destroy the local copy: `rm ${XDG_RUNTIME_DIR}/deploy-key*`
