project-roadmap-tracking 0.2.6 → 0.2.7

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
@@ -160,6 +160,10 @@ IDs are auto-generated sequentially per task type.
160
160
  * [Run a specific test file](#run-a-specific-test-file)
161
161
  * [Generate coverage report](#generate-coverage-report)
162
162
  * [View coverage summary](#view-coverage-summary)
163
+ * [1. Update version](#1-update-version)
164
+ * [2. Build and package](#2-build-and-package)
165
+ * [3. Publish to npm](#3-publish-to-npm)
166
+ * [4. Create GitHub release](#4-create-github-release)
163
167
  <!-- tocstop -->
164
168
 
165
169
  # Usage
@@ -170,7 +174,7 @@ $ npm install -g project-roadmap-tracking
170
174
  $ prt COMMAND
171
175
  running command...
172
176
  $ prt (--version)
173
- project-roadmap-tracking/0.2.6 linux-x64 node-v25.4.0
177
+ project-roadmap-tracking/0.2.7 linux-x64 node-v25.4.0
174
178
  $ prt --help [COMMAND]
175
179
  USAGE
176
180
  $ prt COMMAND
@@ -232,7 +236,7 @@ EXAMPLES
232
236
  $ prt add
233
237
  ```
234
238
 
235
- _See code: [src/commands/add.ts](https://github.com/ZacharyEggert/project-roadmap-tracking/blob/v0.2.6/src/commands/add.ts)_
239
+ _See code: [src/commands/add.ts](https://github.com/ZacharyEggert/project-roadmap-tracking/blob/v0.2.7/src/commands/add.ts)_
236
240
 
237
241
  ## `prt complete TASKID`
238
242
 
@@ -257,7 +261,7 @@ EXAMPLES
257
261
  $ prt complete F-001 --tests
258
262
  ```
259
263
 
260
- _See code: [src/commands/complete.ts](https://github.com/ZacharyEggert/project-roadmap-tracking/blob/v0.2.6/src/commands/complete.ts)_
264
+ _See code: [src/commands/complete.ts](https://github.com/ZacharyEggert/project-roadmap-tracking/blob/v0.2.7/src/commands/complete.ts)_
261
265
 
262
266
  ## `prt help [COMMAND]`
263
267
 
@@ -304,7 +308,7 @@ EXAMPLES
304
308
  $ prt init [path/to/directory]
305
309
  ```
306
310
 
307
- _See code: [src/commands/init.ts](https://github.com/ZacharyEggert/project-roadmap-tracking/blob/v0.2.6/src/commands/init.ts)_
311
+ _See code: [src/commands/init.ts](https://github.com/ZacharyEggert/project-roadmap-tracking/blob/v0.2.7/src/commands/init.ts)_
308
312
 
309
313
  ## `prt list`
310
314
 
@@ -333,7 +337,7 @@ EXAMPLES
333
337
  $ prt list -p=h --incomplete --sort=createdAt
334
338
  ```
335
339
 
336
- _See code: [src/commands/list.ts](https://github.com/ZacharyEggert/project-roadmap-tracking/blob/v0.2.6/src/commands/list.ts)_
340
+ _See code: [src/commands/list.ts](https://github.com/ZacharyEggert/project-roadmap-tracking/blob/v0.2.7/src/commands/list.ts)_
337
341
 
338
342
  ## `prt pass-test TASKID`
339
343
 
@@ -357,7 +361,7 @@ EXAMPLES
357
361
  $ prt pass-test F-001
358
362
  ```
359
363
 
360
- _See code: [src/commands/pass-test.ts](https://github.com/ZacharyEggert/project-roadmap-tracking/blob/v0.2.6/src/commands/pass-test.ts)_
364
+ _See code: [src/commands/pass-test.ts](https://github.com/ZacharyEggert/project-roadmap-tracking/blob/v0.2.7/src/commands/pass-test.ts)_
361
365
 
362
366
  ## `prt plugins`
363
367
 
@@ -672,7 +676,7 @@ EXAMPLES
672
676
  $ prt show F-001
673
677
  ```
674
678
 
675
- _See code: [src/commands/show.ts](https://github.com/ZacharyEggert/project-roadmap-tracking/blob/v0.2.6/src/commands/show.ts)_
679
+ _See code: [src/commands/show.ts](https://github.com/ZacharyEggert/project-roadmap-tracking/blob/v0.2.7/src/commands/show.ts)_
676
680
 
677
681
  ## `prt update TASKID`
678
682
 
@@ -708,7 +712,7 @@ EXAMPLES
708
712
  $ prt update F-002 --deps="F-001" --clear-notes
709
713
  ```
710
714
 
711
- _See code: [src/commands/update.ts](https://github.com/ZacharyEggert/project-roadmap-tracking/blob/v0.2.6/src/commands/update.ts)_
715
+ _See code: [src/commands/update.ts](https://github.com/ZacharyEggert/project-roadmap-tracking/blob/v0.2.7/src/commands/update.ts)_
712
716
 
713
717
  ## `prt validate`
714
718
 
@@ -729,7 +733,7 @@ EXAMPLES
729
733
  $ prt validate
730
734
  ```
731
735
 
732
- _See code: [src/commands/validate.ts](https://github.com/ZacharyEggert/project-roadmap-tracking/blob/v0.2.6/src/commands/validate.ts)_
736
+ _See code: [src/commands/validate.ts](https://github.com/ZacharyEggert/project-roadmap-tracking/blob/v0.2.7/src/commands/validate.ts)_
733
737
  <!-- commandsstop -->
734
738
 
735
739
  ## Development
@@ -814,11 +818,92 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for contribution guidelines.
814
818
 
815
819
  ### Release Process
816
820
 
817
- 1. Update version in `package.json`
818
- 2. Run `yarn prepack` (generates manifest and updates README)
819
- 3. Commit changes
820
- 4. Run `yarn pack` to create tarball
821
- 5. Run `npm publish` to publish to npm registry
821
+ PRT uses a fully automated CI/CD pipeline powered by GitHub Actions. Releases are created automatically when code is pushed to the `master` branch.
822
+
823
+ #### Automated Release (Standard Process)
824
+
825
+ 1. **Update version** in `package.json`:
826
+ ```bash
827
+ # Example: 0.2.6 → 0.2.7
828
+ npm version patch # or minor, or major
829
+ ```
830
+
831
+ 2. **Commit and push** to `master`:
832
+ ```bash
833
+ git add package.json
834
+ git commit -m "chore: bump version to 0.2.7"
835
+ git push origin master
836
+ ```
837
+
838
+ 3. **GitHub Actions automatically**:
839
+ - ✅ Runs test suite (944 tests must pass)
840
+ - ✅ Validates build and linting
841
+ - ✅ Creates GitHub release (only if tests pass)
842
+ - ✅ Publishes to npm registry
843
+ - ⏱️ Total time: ~4-6 minutes
844
+
845
+ **Quality Gate:** If tests fail, no release is created. Fix the issues and push again.
846
+
847
+ #### Manual Release (Fallback)
848
+
849
+ For emergency releases or when automation is unavailable:
850
+
851
+ ```bash
852
+ # 1. Update version
853
+ npm version patch
854
+
855
+ # 2. Build and package
856
+ yarn prepack # generates manifest, updates README
857
+ yarn pack # creates tarball
858
+
859
+ # 3. Publish to npm
860
+ npm publish
861
+
862
+ # 4. Create GitHub release
863
+ gh release create v$(node -p "require('./package.json').version") --generate-notes
864
+ ```
865
+
866
+ #### Required GitHub Secrets
867
+
868
+ For automated releases, configure these secrets in your GitHub repository:
869
+
870
+ | Secret | Purpose |
871
+ |--------|---------|
872
+ | `GH_TOKEN` | GitHub API access (repo + workflow scopes) |
873
+ | `GH_EMAIL` | Git commit author email |
874
+ | `GH_USERNAME` | Git commit author name |
875
+ | `NPM_TOKEN` | npm authentication (optional with Trusted Publishing) |
876
+
877
+ #### npm Authentication
878
+
879
+ **Option A: Trusted Publishing (Recommended)**
880
+ - More secure (OIDC-based, no long-lived tokens)
881
+ - Configure at: https://www.npmjs.com/settings/project-roadmap-tracking/packages/project-roadmap-tracking/access
882
+ - No `NPM_TOKEN` secret needed
883
+
884
+ **Option B: Granular Access Token**
885
+ - Generate at: https://www.npmjs.com/settings/~/tokens
886
+ - Permissions: Read and write for `project-roadmap-tracking` package
887
+ - Store as `NPM_TOKEN` GitHub secret
888
+
889
+ #### CI/CD Workflows
890
+
891
+ The project uses three GitHub Actions workflows:
892
+
893
+ 1. **`test.yml`** - Runs on feature branches
894
+ - Tests across Ubuntu/Windows
895
+ - Tests across Node LTS versions
896
+ - Fast feedback during development
897
+
898
+ 2. **`onPushToMaster.yml`** - Runs on master push
899
+ - Test job (build + tests + lint) ← **Quality gate**
900
+ - Release job (create GitHub release) ← **Only runs if tests pass**
901
+
902
+ 3. **`onRelease.yml`** - Runs when release created
903
+ - Builds package
904
+ - Publishes to npm with provenance
905
+
906
+ For detailed CI/CD architecture, see [ARCHITECTURE.md - CI/CD Pipeline](ARCHITECTURE.md#cicd-pipeline)
822
907
 
823
908
  ## License
824
909
 
@@ -1,5 +1,14 @@
1
1
  import { watch } from 'chokidar';
2
2
  import { readFile, stat, writeFile } from 'node:fs/promises';
3
+ /**
4
+ * Detect if we're running in a test environment
5
+ */
6
+ function isTestEnvironment() {
7
+ return (process.env.NODE_ENV === 'test' ||
8
+ process.env.MOCHA === 'true' ||
9
+ typeof globalThis.describe === 'function' ||
10
+ typeof globalThis.it === 'function');
11
+ }
3
12
  /**
4
13
  * RoadmapRepository provides caching and file watching for roadmap data.
5
14
  * Features:
@@ -13,20 +22,24 @@ export class RoadmapRepository {
13
22
  config;
14
23
  watchers = new Map();
15
24
  constructor(config) {
25
+ // Disable file watching in test environments by default
26
+ const defaultWatchFiles = !isTestEnvironment();
16
27
  this.config = {
17
28
  cacheEnabled: config?.cacheEnabled ?? true,
18
29
  maxCacheSize: config?.maxCacheSize ?? 10,
19
- watchFiles: config?.watchFiles ?? true,
30
+ watchFiles: config?.watchFiles ?? defaultWatchFiles,
20
31
  };
21
32
  }
22
33
  /**
23
34
  * Create a repository instance from a Config object
24
35
  */
25
36
  static fromConfig(config) {
37
+ // Respect explicit watchFiles setting in config, but default based on environment
38
+ const defaultWatchFiles = !isTestEnvironment();
26
39
  return new RoadmapRepository({
27
40
  cacheEnabled: config.cache?.enabled ?? true,
28
41
  maxCacheSize: config.cache?.maxSize ?? 10,
29
- watchFiles: config.cache?.watchFiles ?? true,
42
+ watchFiles: config.cache?.watchFiles ?? defaultWatchFiles,
30
43
  });
31
44
  }
32
45
  /**
@@ -153,27 +166,46 @@ export class RoadmapRepository {
153
166
  * Set up file watcher for a path
154
167
  */
155
168
  setupWatcher(path) {
156
- const watcher = watch(path, {
157
- awaitWriteFinish: {
158
- pollInterval: 100,
159
- stabilityThreshold: 250,
160
- },
161
- persistent: false,
162
- });
163
- watcher.on('change', () => {
164
- this.invalidate(path);
165
- });
166
- watcher.on('unlink', () => {
167
- this.invalidate(path);
168
- this.watchers
169
- .get(path)
170
- ?.close()
171
- .catch(() => {
172
- /* ignore close errors */
169
+ try {
170
+ const watcher = watch(path, {
171
+ awaitWriteFinish: {
172
+ pollInterval: 100,
173
+ stabilityThreshold: 250,
174
+ },
175
+ persistent: false,
173
176
  });
174
- this.watchers.delete(path);
175
- });
176
- this.watchers.set(path, watcher);
177
+ watcher.on('change', () => {
178
+ this.invalidate(path);
179
+ });
180
+ watcher.on('unlink', () => {
181
+ this.invalidate(path);
182
+ this.watchers
183
+ .get(path)
184
+ ?.close()
185
+ .catch(() => {
186
+ /* ignore close errors */
187
+ });
188
+ this.watchers.delete(path);
189
+ });
190
+ watcher.on('error', (error) => {
191
+ // Log error but don't crash - especially important for Windows EPERM errors
192
+ if (process.env.NODE_ENV !== 'production') {
193
+ console.warn(`File watcher error for ${path}:`, error.message);
194
+ }
195
+ // Clean up the watcher on error
196
+ this.watchers.get(path)?.close().catch(() => {
197
+ /* ignore close errors */
198
+ });
199
+ this.watchers.delete(path);
200
+ });
201
+ this.watchers.set(path, watcher);
202
+ }
203
+ catch (error) {
204
+ // If watcher setup fails (e.g., permission issues), log and continue
205
+ if (process.env.NODE_ENV !== 'production') {
206
+ console.warn(`Failed to set up file watcher for ${path}:`, error.message);
207
+ }
208
+ }
177
209
  }
178
210
  }
179
211
  // Singleton instance with default configuration
@@ -552,5 +552,5 @@
552
552
  ]
553
553
  }
554
554
  },
555
- "version": "0.2.6"
555
+ "version": "0.2.7"
556
556
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "project-roadmap-tracking",
3
3
  "description": "CLI based project task tracking",
4
- "version": "0.2.6",
4
+ "version": "0.2.7",
5
5
  "author": "ZacharyEggert",
6
6
  "bin": {
7
7
  "prt": "./bin/run.js"
@@ -23,6 +23,7 @@
23
23
  "@types/node": "^18",
24
24
  "c8": "^10.1.3",
25
25
  "chai": "^4",
26
+ "cross-env": "^10.1.0",
26
27
  "eslint": "^9",
27
28
  "eslint-config-oclif": "^6",
28
29
  "eslint-config-prettier": "^10",
@@ -45,14 +46,14 @@
45
46
  "homepage": "https://github.com/ZacharyEggert/project-roadmap-tracking",
46
47
  "keywords": [
47
48
  "oclif",
48
- "cli",
49
- "project",
50
- "roadmap",
51
- "tracking",
52
- "tasks",
53
- "productivity",
54
- "management",
55
- "prt"
49
+ "cli",
50
+ "project",
51
+ "roadmap",
52
+ "tracking",
53
+ "tasks",
54
+ "productivity",
55
+ "management",
56
+ "prt"
56
57
  ],
57
58
  "license": "MIT",
58
59
  "main": "dist/index.js",
@@ -81,7 +82,7 @@
81
82
  "postpack": "shx rm -f oclif.manifest.json",
82
83
  "posttest": "yarn lint",
83
84
  "prepack": "oclif manifest && oclif readme",
84
- "test": "c8 mocha --loader=tsx/esm --forbid-only 'test/**/*.test.ts'",
85
+ "test": "cross-env NODE_ENV=test c8 mocha --loader=tsx/esm --forbid-only 'test/**/*.test.ts'",
85
86
  "test:coverage": "c8 report",
86
87
  "test:coverage:summary": "c8 report --reporter=text",
87
88
  "version": "oclif readme && git add README.md"