spec-up-t 1.6.12 → 1.6.13

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spec-up-t",
3
- "version": "1.6.12",
3
+ "version": "1.6.13",
4
4
  "description": "Technical specification drafting tool that generates rich specification documents from markdown. Forked from https://github.com/decentralized-identity/spec-up by Daniel Buchner (https://github.com/csuwildcat)",
5
5
  "main": "./index",
6
6
  "repository": {
@@ -16,7 +16,11 @@ const config = fs.readJsonSync('specs.json');
16
16
  const outputPath = config.specs[0].output_path;
17
17
 
18
18
  const sourceFile = path.join(outputPath, 'index.html');
19
- const destDir = path.join(outputPath, 'versions');
19
+
20
+ // spec-versions/ lives at the repo root and is committed to the main branch.
21
+ // This is the source of truth — it survives gh-pages resets and fresh CI checkouts.
22
+ // docs/versions/ is the derived, deployed copy and is always rebuilt from here.
23
+ const destDir = 'spec-versions';
20
24
 
21
25
  // A snapshot can only be created when the specification has been built at least once.
22
26
  // If index.html is missing, the user must run `npm run menu 1` (or `npm run menu 4`) first.
@@ -117,7 +121,11 @@ async function run() {
117
121
 
118
122
  Logger.success(`Created a freezed specification version in ${destFile}`);
119
123
 
120
- // Update the versions index.html to include the newly created version
124
+ // Sync spec-versions/ docs/versions/ so the local preview reflects the
125
+ // new snapshot immediately, then regenerate the versions index page.
126
+ const syncSpecVersions = require('./pipeline/configuration/sync-spec-versions.js');
127
+ syncSpecVersions(outputPath);
128
+
121
129
  const createVersionsIndex = require('./pipeline/configuration/create-versions-index.js');
122
130
  createVersionsIndex(outputPath);
123
131
  }
@@ -85,8 +85,13 @@ jobs:
85
85
  npm run todocx
86
86
  ;;
87
87
  freeze)
88
- # Pass the label to freeze-spec-data.js via environment variable.
89
- # If freeze_label is empty the script falls back to the auto-generated default.
88
+ # A fresh CI checkout has no docs/ (gitignored), so we must render
89
+ # first to give freeze-spec-data.js the docs/index.html it needs.
90
+ # freeze-spec-data.js then writes the snapshot to spec-versions/,
91
+ # which is tracked in git. The commit+push step below commits
92
+ # spec-versions/ to the main branch, which triggers
93
+ # render-and-deploy.yml to deploy the full spec (including versions).
94
+ npm run collectExternalReferences
90
95
  FREEZE_LABEL="${{ github.event.inputs.freeze_label }}" npm run freeze
91
96
  ;;
92
97
  custom-update)
@@ -126,6 +131,8 @@ jobs:
126
131
  git commit -m "Collect external references" || echo "No changes to commit"
127
132
  ;;
128
133
  freeze)
134
+ # spec-versions/ is tracked in git — committing it triggers
135
+ # render-and-deploy.yml, which deploys the full spec with versions.
129
136
  git commit -m "Freeze specification" || echo "No changes to commit"
130
137
  ;;
131
138
  custom-update)
@@ -61,9 +61,27 @@ jobs:
61
61
 
62
62
  # Collect external references — this also renders the specification and
63
63
  # writes output to the path defined in specs.json (output_path, typically ./docs/).
64
+ # The render pipeline (prepare-spec-configuration.js) automatically copies
65
+ # spec-versions/ → docs/versions/ so frozen snapshots are always included.
64
66
  - name: Collect external references and render
65
67
  run: npm run collectExternalReferences
66
68
 
69
+ # Preserve the CNAME file from gh-pages before deploying.
70
+ # peaceiris/actions-gh-pages replaces the entire gh-pages branch with the
71
+ # contents of ./docs. A fresh CI checkout of main never contains docs/CNAME
72
+ # (docs/ is gitignored), so without this step any previously committed CNAME
73
+ # would be silently deleted on every render.
74
+ - name: Preserve CNAME from gh-pages
75
+ run: |
76
+ git fetch origin gh-pages 2>/dev/null || true
77
+ CNAME_CONTENT=$(git show origin/gh-pages:CNAME 2>/dev/null || echo "")
78
+ if [ -n "$CNAME_CONTENT" ]; then
79
+ echo "$CNAME_CONTENT" > docs/CNAME
80
+ echo "CNAME preserved: $CNAME_CONTENT"
81
+ else
82
+ echo "No CNAME found on gh-pages — nothing to preserve"
83
+ fi
84
+
67
85
  # Push the rendered ./docs output to the gh-pages branch.
68
86
  # peaceiris/actions-gh-pages creates the branch on first run when it
69
87
  # does not yet exist — no manual branch setup is required.
@@ -1,3 +1,4 @@
1
+ const fs = require('fs-extra');
1
2
  const { configScriptsKeys } = require('./config-scripts-keys');
2
3
  const { configOverwriteScriptsKeys } = require('./config-scripts-keys');
3
4
  const addScriptsKeys = require('./add-scripts-keys');
@@ -5,6 +6,7 @@ const copySystemFiles = require('./copy-system-files');
5
6
  const { gitIgnoreEntries } = require('./config-gitignore-entries');
6
7
  const { updateGitignore } = require('./add-gitignore-entries');
7
8
  const updateDependencies = require('./update-dependencies');
9
+ const migrateVersionsToSpecVersions = require('./migrate-versions-to-spec-versions');
8
10
  const Logger = require('../utils/logger');
9
11
 
10
12
 
@@ -17,8 +19,18 @@ const customUpdate = () => {
17
19
  // Update dependencies based on package.spec-up-t.json
18
20
  updateDependencies();
19
21
 
20
- // Custom logic here
21
- // ...
22
+ // One-time migration: repos that stored snapshots in docs/versions/ (the old
23
+ // "commit docs/" regime) need their snapshots moved to spec-versions/ so they
24
+ // survive after docs/ is removed from git tracking. Safe to run on every
25
+ // custom-update — already-migrated versions are not overwritten.
26
+ try {
27
+ const config = fs.readJsonSync('specs.json');
28
+ const outputPath = config.specs[0].output_path;
29
+ migrateVersionsToSpecVersions(outputPath);
30
+ } catch (error) {
31
+ // specs.json missing or malformed — skip migration silently.
32
+ Logger.info('Skipping versions migration: could not read specs.json');
33
+ }
22
34
  }
23
35
 
24
36
  // Call custom update
@@ -0,0 +1,85 @@
1
+ /**
2
+ * @file migrate-versions-to-spec-versions.js
3
+ * @description One-time migration helper for repositories that were created under the
4
+ * old "commit docs/" regime. Those repos store frozen snapshots inside docs/versions/.
5
+ *
6
+ * Starting with the issue270 changes, snapshots are stored in spec-versions/ (tracked,
7
+ * at the repo root) instead of docs/versions/ (gitignored, ephemeral). This migration
8
+ * copies any snapshots found in docs/versions/ into spec-versions/ so they are not
9
+ * lost when the user eventually removes docs/ from git tracking.
10
+ *
11
+ * - Safe to run more than once: already-migrated versions are not overwritten.
12
+ * - Does nothing when docs/versions/ does not exist (new repos or repos that never froze).
13
+ * - Does not delete docs/versions/ — git history is preserved; the user decides when
14
+ * to run `git rm -r --cached docs/`.
15
+ */
16
+
17
+ const fs = require('fs-extra');
18
+ const path = require('path');
19
+ const Logger = require('../utils/logger');
20
+
21
+ /**
22
+ * Migrates frozen snapshots from docs/versions/ to spec-versions/.
23
+ * @param {string} outputPath - The output directory defined in specs.json (e.g. './docs').
24
+ */
25
+ function migrateVersionsToSpecVersions(outputPath) {
26
+ const src = path.join(outputPath, 'versions');
27
+ const dest = 'spec-versions';
28
+
29
+ if (!fs.existsSync(src)) {
30
+ // No old snapshots to migrate — nothing to do.
31
+ return;
32
+ }
33
+
34
+ // Check whether there are any version subdirectories (v1, v2, …) to migrate.
35
+ // We skip labels.json and index.html — those are regenerated automatically.
36
+ const versionDirs = fs.readdirSync(src).filter(entry =>
37
+ fs.statSync(path.join(src, entry)).isDirectory()
38
+ );
39
+
40
+ if (versionDirs.length === 0) {
41
+ return;
42
+ }
43
+
44
+ fs.ensureDirSync(dest);
45
+
46
+ let migratedCount = 0;
47
+
48
+ // Copy each version directory that does not already exist in spec-versions/.
49
+ versionDirs.forEach(dir => {
50
+ const srcDir = path.join(src, dir);
51
+ const destDir = path.join(dest, dir);
52
+
53
+ if (!fs.existsSync(destDir)) {
54
+ fs.copySync(srcDir, destDir);
55
+ migratedCount++;
56
+ }
57
+ });
58
+
59
+ // Always keep labels.json up to date in spec-versions/.
60
+ const srcLabels = path.join(src, 'labels.json');
61
+ const destLabels = path.join(dest, 'labels.json');
62
+
63
+ if (fs.existsSync(srcLabels)) {
64
+ if (!fs.existsSync(destLabels)) {
65
+ // No labels.json in spec-versions/ yet — copy the whole file.
66
+ fs.copySync(srcLabels, destLabels);
67
+ } else {
68
+ // Merge: preserve any entries already in spec-versions/labels.json
69
+ // and add any entries from docs/versions/labels.json that are missing.
70
+ const existing = fs.readJsonSync(destLabels);
71
+ const legacy = fs.readJsonSync(srcLabels);
72
+ const merged = { ...legacy, ...existing }; // spec-versions wins on conflict
73
+ fs.writeJsonSync(destLabels, merged, { spaces: 2 });
74
+ }
75
+ }
76
+
77
+ if (migratedCount > 0) {
78
+ Logger.success(
79
+ `Migrated ${migratedCount} snapshot(s) from ${src} to ${dest}/. ` +
80
+ `You can now safely run: git rm -r --cached ${outputPath}`
81
+ );
82
+ }
83
+ }
84
+
85
+ module.exports = migrateVersionsToSpecVersions;
@@ -34,6 +34,12 @@ async function initializeConfig(options = {}) {
34
34
  const createExternalSpecsList = require('./create-external-specs-list.js');
35
35
  const externalSpecsList = createExternalSpecsList(config);
36
36
 
37
+ // Copy any frozen snapshots from the tracked spec-versions/ directory into
38
+ // the output path before regenerating the versions index. This is what makes
39
+ // locally-created or CI-created freezes survive a fresh checkout and redeploy.
40
+ const syncSpecVersions = require('./sync-spec-versions.js');
41
+ syncSpecVersions(config.specs[0].output_path);
42
+
37
43
  const createVersionsIndex = require('./create-versions-index.js');
38
44
  createVersionsIndex(config.specs[0].output_path);
39
45
 
@@ -0,0 +1,38 @@
1
+ /**
2
+ * @file sync-spec-versions.js
3
+ * @description Copies the tracked spec-versions/ directory (at the consuming repo's
4
+ * root) into the output path's versions/ folder before the spec is rendered and
5
+ * deployed. This ensures that snapshots committed to the main branch are always
6
+ * included in the deployed specification, even after a completely fresh CI checkout
7
+ * where docs/ does not yet exist.
8
+ *
9
+ * spec-versions/ is the source of truth for frozen snapshots.
10
+ * docs/versions/ is the derived, deployable copy (gitignored, rebuilt every render).
11
+ *
12
+ * Does nothing when spec-versions/ does not exist — so repositories that have
13
+ * never run `npm run freeze` are not affected.
14
+ */
15
+
16
+ const fs = require('fs-extra');
17
+ const path = require('path');
18
+ const Logger = require('../../utils/logger.js');
19
+
20
+ /**
21
+ * Copies all contents of spec-versions/ into outputPath/versions/.
22
+ * The destination is created if it does not already exist.
23
+ * @param {string} outputPath - The output directory defined in specs.json (e.g. './docs').
24
+ */
25
+ function syncSpecVersions(outputPath) {
26
+ const src = 'spec-versions';
27
+ const dest = path.join(outputPath, 'versions');
28
+
29
+ if (!fs.existsSync(src)) {
30
+ // No snapshots have been created yet — nothing to sync.
31
+ return;
32
+ }
33
+
34
+ fs.copySync(src, dest);
35
+ Logger.info(`Synced spec-versions/ → ${dest}`);
36
+ }
37
+
38
+ module.exports = syncSpecVersions;
@@ -40,6 +40,12 @@ async function render(spec, assets, sharedVars, config, template, assetsGlobal,
40
40
  // Get the branch name from which the index.html was generated
41
41
  const buildBranch = getCurrentBranch();
42
42
 
43
+ // Read spec-up-t version from its own package.json for build info display
44
+ const specUpTVersion = require('../../../package.json').version;
45
+
46
+ // Capture Node.js runtime version for build info display
47
+ const nodeVersion = process.version;
48
+
43
49
  // Read all markdown files into an array
44
50
  const docs = await Promise.all(
45
51
  (spec.markdown_paths || ['spec.md']).map(_path =>
@@ -166,6 +172,8 @@ async function render(spec, assets, sharedVars, config, template, assetsGlobal,
166
172
  currentDate: currentDate,
167
173
  universalTimestamp: universalTimestamp,
168
174
  buildBranch: buildBranch,
175
+ specUpTVersion: specUpTVersion,
176
+ nodeVersion: nodeVersion,
169
177
  githubRepoInfo: getGithubRepoInfo(spec)
170
178
  });
171
179
 
@@ -325,6 +325,14 @@
325
325
  <i class="bi bi-signpost-split me-2"></i>
326
326
  <span>Source branch: <strong>${buildBranch}</strong></span>
327
327
  </div>
328
+ <div class="d-flex align-items-center mb-1">
329
+ <i class="bi bi-box me-2"></i>
330
+ <span>spec-up-t: <strong>v${specUpTVersion}</strong></span>
331
+ </div>
332
+ <div class="d-flex align-items-center mb-1">
333
+ <i class="bi bi-cpu me-2"></i>
334
+ <span>Node.js: <strong>${nodeVersion}</strong></span>
335
+ </div>
328
336
  </div>
329
337
  </div>
330
338
  <hr>