@aspruyt/json-config-sync 3.3.0 → 3.4.0

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
@@ -3,6 +3,7 @@
3
3
  [![CI](https://github.com/anthony-spruyt/json-config-sync/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/anthony-spruyt/json-config-sync/actions/workflows/ci.yml)
4
4
  [![npm version](https://img.shields.io/npm/v/@aspruyt/json-config-sync.svg)](https://www.npmjs.com/package/@aspruyt/json-config-sync)
5
5
  [![npm downloads](https://img.shields.io/npm/dw/@aspruyt/json-config-sync.svg)](https://www.npmjs.com/package/@aspruyt/json-config-sync)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
6
7
 
7
8
  A CLI tool that syncs JSON, YAML, or text configuration files across multiple GitHub and Azure DevOps repositories by creating pull requests. Output format is automatically detected from the target filename extension (`.json` → JSON, `.yaml`/`.yml` → YAML, other → text).
8
9
 
@@ -61,6 +62,7 @@ json-config-sync --config ./config.yaml
61
62
 
62
63
  - **Multi-File Sync** - Sync multiple config files in a single run
63
64
  - **Multi-Format Output** - JSON, YAML, or plain text based on filename extension
65
+ - **Subdirectory Support** - Sync files to any path (e.g., `.github/workflows/ci.yml`)
64
66
  - **Text Files** - Sync `.gitignore`, `.markdownlintignore`, etc. with string or lines array
65
67
  - **Content Inheritance** - Define base config once, override per-repo as needed
66
68
  - **Multi-Repo Targeting** - Apply same config to multiple repos with array syntax
@@ -486,6 +488,37 @@ repos:
486
488
 
487
489
  **Validation:** JSON/YAML file extensions (`.json`, `.yaml`, `.yml`) require object content. Other extensions require string or string[] content.
488
490
 
491
+ ### Subdirectory Paths
492
+
493
+ Sync files to any subdirectory path - parent directories are created automatically:
494
+
495
+ ```yaml
496
+ files:
497
+ # GitHub Actions workflow
498
+ ".github/workflows/ci.yml":
499
+ content:
500
+ name: CI
501
+ on: [push, pull_request]
502
+ jobs:
503
+ build:
504
+ runs-on: ubuntu-latest
505
+ steps:
506
+ - uses: actions/checkout@v4
507
+
508
+ # Nested config directory
509
+ "config/settings/app.json":
510
+ content:
511
+ environment: production
512
+ debug: false
513
+
514
+ repos:
515
+ - git:
516
+ - git@github.com:org/frontend.git
517
+ - git@github.com:org/backend.git
518
+ ```
519
+
520
+ **Note:** Quote file paths containing `/` in YAML keys. Parent directories are created if they don't exist.
521
+
489
522
  ## Supported Git URL Formats
490
523
 
491
524
  ### GitHub
package/dist/git-ops.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { rmSync, existsSync, mkdirSync, writeFileSync, readFileSync, } from "node:fs";
2
- import { join, resolve, relative, isAbsolute } from "node:path";
2
+ import { join, resolve, relative, isAbsolute, dirname } from "node:path";
3
3
  import { escapeShellArg } from "./shell-utils.js";
4
4
  import { defaultExecutor } from "./command-executor.js";
5
5
  import { withRetry } from "./retry-utils.js";
@@ -97,6 +97,8 @@ export class GitOps {
97
97
  return;
98
98
  }
99
99
  const filePath = this.validatePath(fileName);
100
+ // Create parent directories if they don't exist
101
+ mkdirSync(dirname(filePath), { recursive: true });
100
102
  // Normalize trailing newline - ensure exactly one
101
103
  const normalized = content.endsWith("\n") ? content : content + "\n";
102
104
  writeFileSync(filePath, normalized, "utf-8");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aspruyt/json-config-sync",
3
- "version": "3.3.0",
3
+ "version": "3.4.0",
4
4
  "description": "CLI tool to sync JSON or YAML configuration files across multiple GitHub and Azure DevOps repositories",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",