@jacebenson/jsn 4.3.12-dev.70 → 4.3.13-dev.71.1

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
@@ -13,6 +13,47 @@ jsn setup
13
13
 
14
14
  See the [setup guide](docs/docs-setup.md) to connect an instance safely.
15
15
 
16
+ ### Dev channel
17
+
18
+ For the newest changes from `main`, including changes that may be unstable:
19
+
20
+ ```bash
21
+ npm install -g @jacebenson/jsn@dev
22
+ ```
23
+
24
+ Dev builds check the dev channel for updates during normal use, at most once
25
+ per day. Run `jsn version --check` to check immediately. To install the newest
26
+ dev build, run `npm install -g @jacebenson/jsn@dev` again. Updates are manual.
27
+ Return to stable with `npm install -g @jacebenson/jsn@latest`.
28
+
29
+ Pushes to `main` promote the commit to `dev` and publish a tested prerelease
30
+ under npm's `dev` tag. Versions include the workflow run number and attempt
31
+ (for example, `4.3.9-dev.123.1`); they do not move npm's stable `latest` tag.
32
+ The npm trusted publisher for `publish-dev.yml` must authorize the repository's
33
+ `dev` GitHub environment, alongside the production publishing configuration.
34
+
35
+ ### Supported versions
36
+
37
+ Only the current release and the two preceding releases in each channel are
38
+ supported (three stable releases and three dev builds). For example, with
39
+ stable `4.3.11`, versions `4.3.11`, `4.3.10`, and `4.3.9` are supported.
40
+ Update to the newest version in your channel before reporting an issue.
41
+
42
+ After each successful npm publish, deployment deprecates older versions in that
43
+ channel. Deprecated versions remain installable and appear in history, but npm
44
+ prints an update warning on installation. Existing deprecation messages are
45
+ preserved. No versions are unpublished.
46
+
47
+ The deprecation step uses the repository's `NPM_TOKEN` secret with permission to
48
+ modify `@jacebenson/jsn` and noninteractive authentication (including bypass 2FA
49
+ where required). Publishing continues to use OIDC. A deprecation failure fails
50
+ the workflow after publishing; it does not roll back the published package.
51
+ To retry only deprecation after fixing authentication, use the matching release
52
+ checkout and run `node scripts/deprecate-old-versions.mjs latest --apply` (or
53
+ `dev --apply`) with npm authentication configured and `NODE_AUTH_TOKEN` set.
54
+ Omit `--apply` to preview the affected versions without changing npm. The script
55
+ requires the checkout's package version to match the channel's current npm tag.
56
+
16
57
  ## Try it
17
58
 
18
59
  ```bash
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jacebenson/jsn",
3
- "version": "4.3.12-dev.70",
3
+ "version": "4.3.13-dev.71.1",
4
4
  "description": "A command-line interface for ServiceNow that follows the Unix philosophy: simple, composable, and scriptable.",
5
5
  "type": "module",
6
6
  "bin": {
package/src/cli.js CHANGED
@@ -36,7 +36,7 @@ import { platformCmd } from './commands/platform.js';
36
36
  import { codesearchCmd } from './commands/codesearch.js';
37
37
  import { versionCmd } from './commands/version.js';
38
38
  import { skillCmd, checkSkill } from './commands/skill.js';
39
- import { getVersion, checkLatest } from './commands/version.js';
39
+ import { getVersion, checkLatest, getReleaseChannel, getInstallCommand } from './commands/version.js';
40
40
  import { docsCmd } from './commands/docs/docs.js';
41
41
 
42
42
  // Table and platform commands registered at root level for progressive disclosure
@@ -290,7 +290,7 @@ export function buildCLI() {
290
290
  }
291
291
  }
292
292
  if (!skipNpmCheck) {
293
- const cacheFile = path.join(globalConfigDir(), '.last-npm-check');
293
+ const cacheFile = path.join(globalConfigDir(), `.last-npm-check-${getReleaseChannel()}`);
294
294
  let shouldCheck = true;
295
295
  try {
296
296
  const mtime = fs.statSync(cacheFile).mtimeMs;
@@ -303,9 +303,9 @@ export function buildCLI() {
303
303
 
304
304
  if (shouldCheck) {
305
305
  const version = getVersion();
306
- checkLatest({ background: true }).then(latest => {
306
+ checkLatest({ background: true, version }).then(latest => {
307
307
  if (latest && version !== latest) {
308
- process.stderr.write(`\n⚠ jsn ${latest} available (you have ${version}) — run "npm install -g @jacebenson/jsn" to update\n\n`);
308
+ process.stderr.write(`\n⚠ jsn ${latest} available (you have ${version}) — run "${getInstallCommand(version)}" to update\n\n`);
309
309
  }
310
310
  }).catch(() => {});
311
311
 
@@ -6,7 +6,13 @@ import { declareCapabilities } from '../capabilities.js';
6
6
  declareCapabilities('version', { noInstance: true, skipDailyChecks: true });
7
7
 
8
8
  const NPM_PKG = '@jacebenson/jsn';
9
- const NPM_REGISTRY = `https://registry.npmjs.org/${NPM_PKG}/latest`;
9
+ export function getReleaseChannel(version = getVersion()) {
10
+ return /^\d+\.\d+\.\d+-dev\./.test(version) ? 'dev' : 'latest';
11
+ }
12
+
13
+ export function getInstallCommand(version = getVersion()) {
14
+ return `npm install -g ${NPM_PKG}${getReleaseChannel(version) === 'dev' ? '@dev' : ''}`;
15
+ }
10
16
 
11
17
  export function getVersion() {
12
18
  try {
@@ -26,16 +32,16 @@ export function cancelBackgroundChecks() {
26
32
  backgroundChecks.clear();
27
33
  }
28
34
 
29
- export async function checkLatest({ timeout = 1500, background = false } = {}) {
35
+ export async function checkLatest({ timeout = 1500, background = false, version = getVersion() } = {}) {
30
36
  const controller = new AbortController();
31
37
  const timer = setTimeout(() => controller.abort(), timeout);
32
38
  timer.unref();
33
39
  if (background) backgroundChecks.add(controller);
34
40
  try {
35
- const res = await fetch(NPM_REGISTRY, { signal: controller.signal });
41
+ const res = await fetch(`https://registry.npmjs.org/${NPM_PKG}/${getReleaseChannel(version)}`, { signal: controller.signal });
36
42
  if (!res.ok) return null;
37
43
  const data = await res.json();
38
- return data.version;
44
+ return typeof data.version === 'string' ? data.version : null;
39
45
  } catch {
40
46
  return null;
41
47
  } finally {
@@ -58,11 +64,11 @@ export function versionCmd(wrap) {
58
64
  const version = getVersion();
59
65
 
60
66
  if (argv.check) {
61
- const latest = await checkLatest();
67
+ const latest = await checkLatest({ version });
62
68
  if (!latest) {
63
69
  app.ok({ version }, {
64
70
  summary: `jsn ${version} (could not reach npm registry to check for updates)`,
65
- notice: `Run \`npm view ${NPM_PKG}\` directly to check manually`,
71
+ notice: `Run \`npm view ${NPM_PKG}@${getReleaseChannel(version)} version\` directly to check manually`,
66
72
  });
67
73
  return;
68
74
  }
@@ -82,11 +88,11 @@ export function versionCmd(wrap) {
82
88
  version,
83
89
  latest,
84
90
  upToDate: false,
85
- installCmd: `npm install -g ${NPM_PKG}`,
91
+ installCmd: getInstallCommand(version),
86
92
  }, {
87
93
  summary: `jsn ${version} — newer version ${latest} available`,
88
94
  breadcrumbs: [
89
- { action: 'update', cmd: `npm install -g ${NPM_PKG}`, description: `Update jsn from ${version} to ${latest}` },
95
+ { action: 'update', cmd: getInstallCommand(version), description: `Update jsn from ${version} to ${latest}` },
90
96
  ],
91
97
  });
92
98
  }