Files
What config.json, the keyring entry, hotcodepush.json, the resource file and the private key file hold, where each lives per OS and who writes it.
The CLI keeps five things on disk, listed below with where each one lives.
Nothing else: no .hotcodepush directory in the project and no private key the CLI keeps for itself.
| File | Holds | Where |
|---|---|---|
config.json | Holds the API URL, the session id, the update-check fields, a pending login, the telemetry-notice timestamp, and the token only where no keyring works. | the user's config directory |
| the keyring entry | Holds the session token login stored. | the OS secure storage |
hotcodepush.json | Holds the app id, the channel by name, the public keys, the SDK options and extraFingerprintPaths. | the project root, committed |
| the resource file | Holds hotcodepush.json minus the CLI's keys, plus the build-time facts. | the built app, written by every build, never committed |
| the private key file | Holds the RSA private key of a signing key pair, PEM, PKCS #8. | where signing-key create wrote it, out of version control |
config.json
The user's config directory is ~/.config/hotcodepush on macOS and Linux, $XDG_CONFIG_HOME/hotcodepush when that variable is set, and %APPDATA%\hotcodepush on Windows.
The file is written with mode 0600 on macOS and Linux, since it can hold the token. One that does not parse is invalid_json.
| Key | Written by | Holds |
|---|---|---|
apiUrl | login --api-url | Names the API every command talks to. Defaults to production. |
lastUpdateCheckAt, latestKnownVersion | the daily update check | Hold when the npm registry was last asked and what it answered. |
pending* | a login that could not wait | Hold the device authorization the next login redeems or shows again. |
sessionExpiresAt | login, renewed when a command finds it passed and the API still knows the session | Holds when the session ends, the hint that makes a command ask to log in again. |
sessionId | login | Holds the session's non-secret id, which logout deletes. |
telemetryNoticeShownAt | the first command on the machine | Records that the telemetry notice was printed. |
token | login, only where no keyring backend works | Holds the session token, the fallback for headless machines. |
The keyring entry
The session token lives in the OS secure storage: the macOS Keychain, the Windows Credential Manager or the Secret Service on Linux.
The entry is under the service hotcodepush-cli and the account token.
Where no keyring backend works, headless CI the usual case, the token goes into config.json instead.
The HOTCODEPUSH_TOKEN variable wins over both, and logout deletes the entry and the fallback while leaving the variable alone.
hotcodepush.json
hotcodepush.json is the project's configuration, next to package.json, written by init and read by every command. --config <path> names it when it lies elsewhere.
Running init writes appId and channel. Every command finds the file walking up from the working directory, so the CLI runs from any folder of the repository.
Every other key is an SDK option, listed on the configuration pages for React Native, Expo, Capacitor and Cordova.
{
"appId": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"channel": "production"
}| Key | Written by | Read by |
|---|---|---|
appId | init | Every command reads it, as the default for --app. |
channel | init, the app's default channel by name | release create, the build steps and every verb that takes --channel read it, as the default. Defaults to production when absent. |
extraFingerprintPaths | you | The fingerprint reads it and hashes the files under these paths beside the native packages. It is the one key that never reaches a device. |
publicKeys | signing-key create and signing-key add append, signing-key delete removes | An upload reads it and signs when the list is not empty, and the build steps write the keys into the resource file. |
The CLI keeps the file's indentation when it edits it, and doctor reports a file that does not parse as a failed configuration check.
The resource file
The resource file is what the SDK reads at runtime: hotcodepush.json without channel and extraFingerprintPaths, plus what only a build can know.
The SDK package's Xcode phase and Gradle task write it into every native build: binary create in a store build, resource-file write in every other build.
It describes one build, so it is never committed.
| Key | Holds |
|---|---|
appId, publicKeys, the SDK options | Come from hotcodepush.json, the public keys re-encoded as { "der", "keyId" } in the form the platform's own API imports, PKCS #1 on iOS and SPKI on Android. |
builtAt | Holds the build's time. No release older than it is applied. |
channelId | Holds the channel resolved to its id through the API, or null when the build ran offline or without a token and the project names the channel by name. |
embeddedBundleId | Holds the bundle's id once a store build created its binary, or null from resource-file write. |
embeddedBundleManifest | Holds the embedded bundle's files with path, hash and size, or null for a React Native or Expo debug build that bundled nothing. |
filesBaseUrl, updatesBaseUrl | Hold the hosts the device reads from, written only when they differ from production's. HOTCODEPUSH_FILES_BASE_URL and HOTCODEPUSH_UPDATES_BASE_URL set them. |
fingerprint | Holds the native fingerprint the build was made on. |
How an update reaches a device explains what the SDK does with the file.
The private key file
signing-key create writes the private key of a new pair to hotcodepush-private-key.pem in the working directory, or to --private-key-path, with mode 0600 on macOS and Linux.
The CLI never prints the key, never keeps a copy and never looks for the file.
An upload gets the key through --private-key-path, or from HOTCODEPUSH_SIGNING_KEY in CI.
Keep the file out of version control. Sign your bundles covers the rotation.
Temporary files
An upload writes its gzip copies and the full pack under a hotcodepush- directory in the system's temporary folder, removed when the command ends.
The file hotcodepush fingerprint --json > <file> writes is one you keep, the input of fingerprint diff.
Last updated on
Global options
The nine options every hotcodepush command accepts, from --json, --no-input and --yes to --config, --app and --organization, with the environment variables beside them.
Exit codes
The five exit codes of the hotcodepush CLI, from 0 for success to 4 for a confirmation that needs --yes, and how a script reads them.