@teambit/ci 1.0.485 → 1.0.487

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.
Files changed (97) hide show
  1. package/ci.docs.mdx +344 -83
  2. package/commands/sync.cmd.ts +77 -0
  3. package/dist/ci.docs.mdx +344 -83
  4. package/dist/ci.main.runtime.d.ts +67 -6
  5. package/dist/ci.main.runtime.js +152 -25
  6. package/dist/ci.main.runtime.js.map +1 -1
  7. package/dist/commands/sync.cmd.d.ts +34 -0
  8. package/dist/commands/sync.cmd.js +57 -0
  9. package/dist/commands/sync.cmd.js.map +1 -0
  10. package/dist/git.d.ts +11 -1
  11. package/dist/git.js +11 -1
  12. package/dist/git.js.map +1 -1
  13. package/dist/index.d.ts +4 -0
  14. package/dist/index.js +26 -1
  15. package/dist/index.js.map +1 -1
  16. package/dist/{preview-1785858957533.js → preview-1785883495880.js} +1 -1
  17. package/dist/sync/git-host-provider.d.ts +47 -0
  18. package/dist/sync/git-host-provider.js +54 -0
  19. package/dist/sync/git-host-provider.js.map +1 -0
  20. package/dist/sync/git-host-provider.spec.d.ts +1 -0
  21. package/dist/sync/git-host-provider.spec.js +171 -0
  22. package/dist/sync/git-host-provider.spec.js.map +1 -0
  23. package/dist/sync/git-ops.d.ts +171 -0
  24. package/dist/sync/git-ops.js +354 -0
  25. package/dist/sync/git-ops.js.map +1 -0
  26. package/dist/sync/git-ops.spec.d.ts +1 -0
  27. package/dist/sync/git-ops.spec.js +476 -0
  28. package/dist/sync/git-ops.spec.js.map +1 -0
  29. package/dist/sync/github-client.d.ts +79 -0
  30. package/dist/sync/github-client.js +198 -0
  31. package/dist/sync/github-client.js.map +1 -0
  32. package/dist/sync/github-client.spec.d.ts +1 -0
  33. package/dist/sync/github-client.spec.js +205 -0
  34. package/dist/sync/github-client.spec.js.map +1 -0
  35. package/dist/sync/init-scaffold.d.ts +40 -0
  36. package/dist/sync/init-scaffold.js +326 -0
  37. package/dist/sync/init-scaffold.js.map +1 -0
  38. package/dist/sync/init-scaffold.spec.d.ts +1 -0
  39. package/dist/sync/init-scaffold.spec.js +169 -0
  40. package/dist/sync/init-scaffold.spec.js.map +1 -0
  41. package/dist/sync/lane-sync-executor.d.ts +256 -0
  42. package/dist/sync/lane-sync-executor.js +1249 -0
  43. package/dist/sync/lane-sync-executor.js.map +1 -0
  44. package/dist/sync/lane-sync-executor.spec.d.ts +1 -0
  45. package/dist/sync/lane-sync-executor.spec.js +416 -0
  46. package/dist/sync/lane-sync-executor.spec.js.map +1 -0
  47. package/dist/sync/main-sync-executor.d.ts +62 -0
  48. package/dist/sync/main-sync-executor.js +305 -0
  49. package/dist/sync/main-sync-executor.js.map +1 -0
  50. package/dist/sync/sync-config.d.ts +83 -0
  51. package/dist/sync/sync-config.js +187 -0
  52. package/dist/sync/sync-config.js.map +1 -0
  53. package/dist/sync/sync-config.spec.d.ts +1 -0
  54. package/dist/sync/sync-config.spec.js +254 -0
  55. package/dist/sync/sync-config.spec.js.map +1 -0
  56. package/dist/sync/sync-orchestrator.d.ts +76 -0
  57. package/dist/sync/sync-orchestrator.js +396 -0
  58. package/dist/sync/sync-orchestrator.js.map +1 -0
  59. package/dist/sync/sync-orchestrator.spec.d.ts +1 -0
  60. package/dist/sync/sync-orchestrator.spec.js +155 -0
  61. package/dist/sync/sync-orchestrator.spec.js.map +1 -0
  62. package/dist/sync/sync-planner.d.ts +60 -0
  63. package/dist/sync/sync-planner.js +114 -0
  64. package/dist/sync/sync-planner.js.map +1 -0
  65. package/dist/sync/sync-planner.spec.d.ts +1 -0
  66. package/dist/sync/sync-planner.spec.js +210 -0
  67. package/dist/sync/sync-planner.spec.js.map +1 -0
  68. package/dist/sync/sync-state.d.ts +94 -0
  69. package/dist/sync/sync-state.js +178 -0
  70. package/dist/sync/sync-state.js.map +1 -0
  71. package/dist/sync/sync-state.spec.d.ts +1 -0
  72. package/dist/sync/sync-state.spec.js +271 -0
  73. package/dist/sync/sync-state.spec.js.map +1 -0
  74. package/dist/sync/workspace-lane.d.ts +13 -0
  75. package/dist/sync/workspace-lane.js +27 -0
  76. package/dist/sync/workspace-lane.js.map +1 -0
  77. package/package.json +20 -15
  78. package/sync/git-host-provider.spec.ts +197 -0
  79. package/sync/git-host-provider.ts +89 -0
  80. package/sync/git-ops.spec.ts +506 -0
  81. package/sync/git-ops.ts +334 -0
  82. package/sync/github-client.spec.ts +174 -0
  83. package/sync/github-client.ts +209 -0
  84. package/sync/init-scaffold.spec.ts +142 -0
  85. package/sync/init-scaffold.ts +340 -0
  86. package/sync/lane-sync-executor.spec.ts +389 -0
  87. package/sync/lane-sync-executor.ts +1363 -0
  88. package/sync/main-sync-executor.ts +321 -0
  89. package/sync/sync-config.spec.ts +283 -0
  90. package/sync/sync-config.ts +214 -0
  91. package/sync/sync-orchestrator.spec.ts +120 -0
  92. package/sync/sync-orchestrator.ts +386 -0
  93. package/sync/sync-planner.spec.ts +126 -0
  94. package/sync/sync-planner.ts +99 -0
  95. package/sync/sync-state.spec.ts +263 -0
  96. package/sync/sync-state.ts +176 -0
  97. package/sync/workspace-lane.ts +20 -0
@@ -0,0 +1,326 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.WORKFLOW_RELATIVE_PATHS = void 0;
7
+ exports.deriveOwnerRepo = deriveOwnerRepo;
8
+ exports.renderBitReleaseWorkflow = renderBitReleaseWorkflow;
9
+ exports.renderBitSyncWorkflow = renderBitSyncWorkflow;
10
+ exports.renderInitChecklist = renderInitChecklist;
11
+ exports.scaffoldWorkflowFiles = scaffoldWorkflowFiles;
12
+ function _fs() {
13
+ const data = _interopRequireDefault(require("fs"));
14
+ _fs = function () {
15
+ return data;
16
+ };
17
+ return data;
18
+ }
19
+ function _path() {
20
+ const data = _interopRequireDefault(require("path"));
21
+ _path = function () {
22
+ return data;
23
+ };
24
+ return data;
25
+ }
26
+ function _githubClient() {
27
+ const data = require("./github-client");
28
+ _githubClient = function () {
29
+ return data;
30
+ };
31
+ return data;
32
+ }
33
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
34
+ /**
35
+ * `bit ci sync --init` — pure scaffolding logic, unit-testable without a live workspace/git checkout.
36
+ *
37
+ * TEMPLATE SOURCE OF TRUTH: `BIT_SYNC_WORKFLOW_RAW` / `BIT_RELEASE_WORKFLOW_RAW` are byte-for-byte
38
+ * copies of the canonical templates in the `bit-git-sync` action workspace
39
+ * (git-sync/git-sync/workflows/templates/) and MUST be kept in sync with them. The ONLY departure is
40
+ * the two `DEFAULT_BRANCH_MARKER` substitution points; everything else — CHANGE-ME comments, the
41
+ * placeholder action ref, `bit-sync/main` config defaults — stays untouched.
42
+ */
43
+
44
+ /** Where `scaffoldWorkflowFiles` writes each file, relative to the workspace root. */
45
+ const WORKFLOW_RELATIVE_PATHS = exports.WORKFLOW_RELATIVE_PATHS = {
46
+ sync: _path().default.join('.github', 'workflows', 'bit-sync.yml'),
47
+ release: _path().default.join('.github', 'workflows', 'bit-release.yml')
48
+ };
49
+ const BIT_SYNC_WORKFLOW_RAW = `# Copy this file into your repository at \`.github/workflows/bit-sync.yml\`,
50
+ # then review every line marked \`CHANGE-ME\` below -- the defaults assume a
51
+ # repository whose default branch is \`main\` and a workspace at the repo root.
52
+ #
53
+ # See the \`workflows.docs.mdx\` customer setup guide (component
54
+ # bitdev.git-sync/git-sync/workflows) for the full walk-through: the
55
+ # bit.cloud webhook wiring that drives \`repository_dispatch\`, the required
56
+ # secrets, and the \`teambit.git/ci\`.\`sync\` workspace config this workflow
57
+ # acts on.
58
+ name: bit-sync
59
+ on:
60
+ repository_dispatch:
61
+ # 'bit-export' is the real, empirically-verified bit.cloud webhook
62
+ # contract: a single dispatch type discriminated by
63
+ # client_payload.laneId (non-empty 'scope/lane' -> lane export, empty ->
64
+ # main export). The other three types are forward-compat aliases the
65
+ # event router also accepts, in case a webhook is configured to send the
66
+ # originally-assumed, more granular dispatch types instead.
67
+ types: [bit-export, bit-lane-export, bit-main-export, bit-lane-removed]
68
+ schedule:
69
+ # Scheduled reconcile. This is also the ONLY mechanism that picks up
70
+ # lane deletions -- bit.cloud has no "lane removed" webhook event.
71
+ - cron: '*/30 * * * *'
72
+ push:
73
+ # CHANGE-ME: \`main\` must be your repository's DEFAULT branch, and
74
+ # \`bit-sync/**\` must cover your configured \`sync.mainSyncBranch\`. Pushes
75
+ # to either are bit-sync's own output and must not re-trigger a sync.
76
+ branches-ignore: [main, 'bit-sync/**']
77
+ workflow_dispatch:
78
+ inputs:
79
+ lane: { description: Lane to sync (empty = all), required: false }
80
+
81
+ # The default GITHUB_TOKEN is READ-ONLY on repositories and organizations
82
+ # created after Feb 2023, and anywhere the org/repo default is set to
83
+ # "Read repository contents permission". Sync pushes branches and
84
+ # opens/updates PRs, so both scopes must be declared explicitly -- without
85
+ # this block the sync fails with a 403 on its first write.
86
+ permissions:
87
+ contents: write
88
+ pull-requests: write
89
+
90
+ concurrency:
91
+ # Serializes one lane's syncs so two runs never race on the same branch/PR.
92
+ #
93
+ # Each trigger needs a different expression, because the lane identity
94
+ # arrives in a different place every time:
95
+ # - repository_dispatch -> client_payload.laneId ('scope/lane'), or
96
+ # client_payload.lane for the alias types
97
+ # - push -> github.ref_name (the branch)
98
+ # - workflow_dispatch -> the \`lane\` input
99
+ # - schedule -> nothing lane-shaped; it reconciles everything
100
+ #
101
+ # github.ref_name is populated on schedule runs too (it is the default
102
+ # branch there), so it may only be consulted AFTER the event name has been
103
+ # checked. Reading it first -- as a bare \`... || github.ref_name || 'all'\`
104
+ # chain does -- makes the final fallback unreachable and lumps every cron
105
+ # run into the same group as pushes to the default branch.
106
+ #
107
+ # RESIDUAL RACE (accepted, by design): a webhook run groups as
108
+ # 'scope/my-lane' while a push to that lane's branch groups as 'my-lane', so
109
+ # two runs for the same lane can still overlap across those two triggers.
110
+ # GitHub expressions have no substring/split function, and bit.cloud's
111
+ # webhook payload template exposes only the full laneId, so the two keys
112
+ # cannot be normalized into one here. This is safe rather than merely
113
+ # tolerated: the reconciler is idempotent and the sync executor diffs
114
+ # against converged state, so a second overlapping run finds nothing left to
115
+ # do and no-ops. The concurrency group is an efficiency measure; it is not
116
+ # what makes the sync correct.
117
+ group: >-
118
+ bit-sync-\${{
119
+ github.event_name == 'repository_dispatch' && (github.event.client_payload.laneId || github.event.client_payload.lane || 'main-export')
120
+ || github.event_name == 'push' && github.ref_name
121
+ || github.event_name == 'workflow_dispatch' && (github.event.inputs.lane || 'reconcile-all')
122
+ || 'reconcile-all' }}
123
+ # Never cancel a sync mid-flight: it may already have pushed a branch and be
124
+ # partway through opening or updating its PR.
125
+ cancel-in-progress: false
126
+
127
+ jobs:
128
+ sync:
129
+ runs-on: ubuntu-latest
130
+ steps:
131
+ - uses: actions/checkout@v4
132
+ with:
133
+ fetch-depth: 0
134
+ # A PAT/App token so that pushes this workflow makes (e.g. a sync
135
+ # PR branch) can themselves trigger CI. Pushes authenticated with
136
+ # the default GITHUB_TOKEN do NOT trigger other workflow runs.
137
+ token: \${{ secrets.BIT_SYNC_GH_TOKEN || secrets.GITHUB_TOKEN }}
138
+ - uses: bit-tasks/init@v2
139
+ # Pinned to a commit SHA on purpose: this job holds write permission, and
140
+ # a tag can move. Bump the SHA to take a new version of the action.
141
+ - uses: teambit/bit-git-sync@66c0fdf9e34e45f70b4f397b38b2b01f79dd1f41
142
+ with:
143
+ # CHANGE-ME: keep this in sync with
144
+ # \`teambit.git/ci\`.\`sync.mainSyncBranch\` in your workspace.jsonc
145
+ # (the action's own default is shown here).
146
+ main-sync-branch: bit-sync/main
147
+ # Uncomment if your workspace.jsonc is NOT at the repository root --
148
+ # the action chdirs here before running anything.
149
+ # ws-dir: packages/my-workspace
150
+ env:
151
+ # Service account token. This account must be EXEMPT from the
152
+ # org's change-request/merge block, or bit.cloud rejects the
153
+ # sync-driven writes.
154
+ BIT_CONFIG_ACCESS_TOKEN: \${{ secrets.BIT_CONFIG_ACCESS_TOKEN }}
155
+ GITHUB_TOKEN: \${{ secrets.BIT_SYNC_GH_TOKEN || secrets.GITHUB_TOKEN }}
156
+ # Optional: git identity for the commits the sync creates. Defaults
157
+ # to bit-sync[bot] / bit-sync[bot]@users.noreply.github.com.
158
+ # GIT_USER_NAME: bit-sync[bot]
159
+ # GIT_USER_EMAIL: bit-sync[bot]@users.noreply.github.com
160
+ `;
161
+ const BIT_RELEASE_WORKFLOW_RAW = `# Copy this file into your repository at \`.github/workflows/bit-release.yml\`,
162
+ # then review every line marked \`CHANGE-ME\` below.
163
+ #
164
+ # See the \`workflows.docs.mdx\` customer setup guide (component
165
+ # bitdev.git-sync/git-sync/workflows) for the full walk-through.
166
+ name: bit-release
167
+ on:
168
+ pull_request:
169
+ types: [closed]
170
+ # CHANGE-ME: your repository's DEFAULT branch. \`bit ci merge\` releases
171
+ # from the default branch, so only PRs merged INTO it should trigger a
172
+ # release -- a stacked PR landing on another feature branch has not
173
+ # reached the default branch yet. The action's event router enforces the
174
+ # same rule from \`pull_request.base.ref\`; this filter means a run is never
175
+ # even queued for a non-default base.
176
+ branches: [main]
177
+
178
+ # The default GITHUB_TOKEN is READ-ONLY on repositories and organizations
179
+ # created after Feb 2023, and anywhere the org/repo default is set to
180
+ # "Read repository contents permission". The release run pushes commits/tags
181
+ # and updates PRs, so both scopes must be declared explicitly.
182
+ permissions:
183
+ contents: write
184
+ pull-requests: write
185
+
186
+ concurrency:
187
+ group: bit-release-\${{ github.event.pull_request.number }}
188
+ # Never cancel a release mid-flight.
189
+ cancel-in-progress: false
190
+
191
+ jobs:
192
+ release:
193
+ runs-on: ubuntu-latest
194
+ # Merged main-sync PRs must NOT trigger a release: the scope is already
195
+ # ahead of this merge, there is nothing new to release. The event
196
+ # router also skips this case (routePullRequest checks
197
+ # prHeadRef === mainSyncBranch) -- this \`if:\` is defense in depth so the
198
+ # job doesn't even start.
199
+ # CHANGE-ME: the branch literal below MUST match your workspace's
200
+ # configured \`teambit.git/ci\`.\`sync.mainSyncBranch\`.
201
+ if: github.event.pull_request.merged == true && github.event.pull_request.head.ref != 'bit-sync/main'
202
+ steps:
203
+ - uses: actions/checkout@v4
204
+ with:
205
+ fetch-depth: 0
206
+ token: \${{ secrets.BIT_SYNC_GH_TOKEN || secrets.GITHUB_TOKEN }}
207
+ - uses: bit-tasks/init@v2
208
+ # Pinned to a commit SHA on purpose: this job holds write permission, and
209
+ # a tag can move. Bump the SHA to take a new version of the action.
210
+ - uses: teambit/bit-git-sync@66c0fdf9e34e45f70b4f397b38b2b01f79dd1f41
211
+ with:
212
+ # CHANGE-ME: keep this in sync with
213
+ # \`teambit.git/ci\`.\`sync.mainSyncBranch\` AND with the \`if:\`
214
+ # condition above.
215
+ main-sync-branch: bit-sync/main
216
+ # Uncomment if your workspace.jsonc is NOT at the repository root --
217
+ # the action chdirs here before running anything.
218
+ # ws-dir: packages/my-workspace
219
+ env:
220
+ BIT_CONFIG_ACCESS_TOKEN: \${{ secrets.BIT_CONFIG_ACCESS_TOKEN }}
221
+ GITHUB_TOKEN: \${{ secrets.BIT_SYNC_GH_TOKEN || secrets.GITHUB_TOKEN }}
222
+ # Optional: git identity for the commits the release creates.
223
+ # Defaults to bit-sync[bot] / bit-sync[bot]@users.noreply.github.com.
224
+ # GIT_USER_NAME: bit-sync[bot]
225
+ # GIT_USER_EMAIL: bit-sync[bot]@users.noreply.github.com
226
+ `;
227
+
228
+ /**
229
+ * The exact substring in each template that encodes the repository's default branch. Exact substring,
230
+ * never a blanket `main` regex — that would also corrupt `bit-main-export` and `bit-sync/main`.
231
+ */
232
+ const DEFAULT_BRANCH_MARKER = {
233
+ sync: "branches-ignore: [main, 'bit-sync/**']",
234
+ release: 'branches: [main]'
235
+ };
236
+
237
+ /**
238
+ * A YAML single-quoted scalar of `value` (the only escape inside single quotes is a doubled `''`).
239
+ * Both substitution points land inside a YAML flow sequence, where `,` and `]` are structural — and a
240
+ * branch name may legally contain both, so quoting is unconditional.
241
+ */
242
+ function yamlSingleQuoted(value) {
243
+ return `'${value.replace(/'/g, "''")}'`;
244
+ }
245
+
246
+ /**
247
+ * Replace the default-branch literal inside `marker` with `defaultBranch`, inside `raw`. Throws when
248
+ * the marker has drifted out of the template — a reworded canonical workflow must fail loudly, not
249
+ * ship a scaffold that still says `main`.
250
+ */
251
+ function substituteDefaultBranch(raw, marker, defaultBranch) {
252
+ if (!raw.includes(marker)) {
253
+ throw new Error(`init-scaffold: expected marker "${marker}" not found in its workflow template — the canonical ` + `template (bitdev.git-sync/git-sync/workflows) has drifted from BIT_SYNC_WORKFLOW_RAW / ` + `BIT_RELEASE_WORKFLOW_RAW; update the copy and this substitution point together`);
254
+ }
255
+ // Function replacements, not strings: `$&`/`$'`/`$$` are special in string replacements and `$` is
256
+ // git-legal in a branch name. A function replacement is inserted verbatim.
257
+ const substitutedMarker = marker.replace('main', () => yamlSingleQuoted(defaultBranch));
258
+ return raw.replace(marker, () => substitutedMarker);
259
+ }
260
+
261
+ /** Render `bit-sync.yml` with the repository's actual default branch substituted. */
262
+ function renderBitSyncWorkflow(defaultBranch) {
263
+ return substituteDefaultBranch(BIT_SYNC_WORKFLOW_RAW, DEFAULT_BRANCH_MARKER.sync, defaultBranch);
264
+ }
265
+
266
+ /** Render `bit-release.yml` with the repository's actual default branch substituted. */
267
+ function renderBitReleaseWorkflow(defaultBranch) {
268
+ return substituteDefaultBranch(BIT_RELEASE_WORKFLOW_RAW, DEFAULT_BRANCH_MARKER.release, defaultBranch);
269
+ }
270
+ // Never overwrites an existing file — `--init` must be safe to re-run after hand-edits.
271
+ function writeIfAbsent(workspaceDir, relativePath, content) {
272
+ const absPath = _path().default.join(workspaceDir, relativePath);
273
+ if (_fs().default.existsSync(absPath)) {
274
+ return {
275
+ relativePath,
276
+ status: 'skipped'
277
+ };
278
+ }
279
+ _fs().default.mkdirSync(_path().default.dirname(absPath), {
280
+ recursive: true
281
+ });
282
+ _fs().default.writeFileSync(absPath, content);
283
+ return {
284
+ relativePath,
285
+ status: 'written'
286
+ };
287
+ }
288
+
289
+ /** Scaffold both workflow files under `workspaceDir`. Never overwrites; creates `.github/workflows/` as needed. */
290
+ function scaffoldWorkflowFiles(workspaceDir, defaultBranch) {
291
+ return [writeIfAbsent(workspaceDir, WORKFLOW_RELATIVE_PATHS.sync, renderBitSyncWorkflow(defaultBranch)), writeIfAbsent(workspaceDir, WORKFLOW_RELATIVE_PATHS.release, renderBitReleaseWorkflow(defaultBranch))];
292
+ }
293
+ /**
294
+ * Derive `{owner, repo}` from the `origin` remote when it is a parseable GitHub remote, else
295
+ * undefined (the checklist falls back to a placeholder). Reuses `github-client.ts`'s parsing so the
296
+ * two never disagree.
297
+ */
298
+ function deriveOwnerRepo(remoteUrl) {
299
+ if (!remoteUrl || !(0, _githubClient().isGitHubRemote)(remoteUrl)) return undefined;
300
+ const ownerSlashRepo = (0, _githubClient().parseGitHubRepo)(remoteUrl);
301
+ if (!ownerSlashRepo) return undefined;
302
+ const [owner, repo] = ownerSlashRepo.split('/');
303
+ if (!owner || !repo) return undefined;
304
+ return {
305
+ owner,
306
+ repo
307
+ };
308
+ }
309
+
310
+ /**
311
+ * The bit.cloud custom webhook payload template, verified byte-perfect against a live delivery.
312
+ * Lane vs. main export is discriminated by whether `laneId` is empty.
313
+ */
314
+ const WEBHOOK_PAYLOAD_TEMPLATE = '{"event_type":"bit-export","client_payload":{"laneId":"{{laneId}}","componentIds":"{{componentIds}}","owner":"{{owner}}","actor":"{{username}}"}}';
315
+
316
+ /**
317
+ * The manual-steps checklist `bit ci sync --init` prints: everything the command itself cannot do
318
+ * (secrets live in GitHub settings; the webhook lives on bit.cloud).
319
+ */
320
+ function renderInitChecklist(ownerRepo) {
321
+ const repoSegment = ownerRepo ? `${ownerRepo.owner}/${ownerRepo.repo}` : '<owner>/<repo>';
322
+ const dispatchUrl = `https://api.github.com/repos/${repoSegment}/dispatches`;
323
+ return ['', 'Remaining manual steps (bit ci sync --init only scaffolds files -- these need a human):', '', '1. Secrets -- add in the repository (or org) Settings > Secrets and variables > Actions:', ' - BIT_CONFIG_ACCESS_TOKEN (required): a bit.cloud service-account token with export rights on', " this scope. This account must also be exempt from the org's", ' change-request/merge block -- it is the only identity that merges lanes.', ' - BIT_SYNC_GH_TOKEN (optional): a GitHub PAT or App token. Without it, sync pushes/PRs use the', ' default GITHUB_TOKEN, which does NOT trigger downstream workflow runs (loop-safe, but the', ' sync PR then gets no CI checks).', '', '2. Permissions -- both scaffolded workflows already declare `contents: write` and', ' `pull-requests: write`. Nothing to change unless an org-wide policy overrides workflow-level', ' permissions (e.g. a default of "Read repository contents permission" for the GITHUB_TOKEN).', '', '3. bit.cloud webhook -- create ONE webhook (org Settings > Webhooks) on the "Components > Export', ' succeeded" event:', ` URL: ${dispatchUrl}`, ' Headers: Authorization: Bearer <PAT>', ' Accept: application/vnd.github+json', ' Custom payload template:', ` ${WEBHOOK_PAYLOAD_TEMPLATE}`, ' WARNING: create this webhook fresh -- editing an existing webhook drops its custom headers', ' (known bit.cloud platform bug, verified 2026-07-29). If the URL, headers or template need to', ' change later, delete the webhook and create a new one rather than editing it.', '', '4. Checkout depth -- both scaffolded workflows already check out with `fetch-depth: 0`. This is', ' required: the reconciler reads full git history, and a shallow (--depth=1) clone fails sync', ' safely but uselessly (HALTED, no writes). Keep `fetch-depth: 0` if you customize the workflow.', ' Narrowing the REFSPEC is fine, though -- a single-branch clone is supported, because every', ' fetch sync performs names +refs/heads/*:refs/remotes/origin/* explicitly.', ''].join('\n');
324
+ }
325
+
326
+ //# sourceMappingURL=init-scaffold.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_fs","data","_interopRequireDefault","require","_path","_githubClient","e","__esModule","default","WORKFLOW_RELATIVE_PATHS","exports","sync","path","join","release","BIT_SYNC_WORKFLOW_RAW","BIT_RELEASE_WORKFLOW_RAW","DEFAULT_BRANCH_MARKER","yamlSingleQuoted","value","replace","substituteDefaultBranch","raw","marker","defaultBranch","includes","Error","substitutedMarker","renderBitSyncWorkflow","renderBitReleaseWorkflow","writeIfAbsent","workspaceDir","relativePath","content","absPath","fs","existsSync","status","mkdirSync","dirname","recursive","writeFileSync","scaffoldWorkflowFiles","deriveOwnerRepo","remoteUrl","isGitHubRemote","undefined","ownerSlashRepo","parseGitHubRepo","owner","repo","split","WEBHOOK_PAYLOAD_TEMPLATE","renderInitChecklist","ownerRepo","repoSegment","dispatchUrl"],"sources":["init-scaffold.ts"],"sourcesContent":["import fs from 'fs';\nimport path from 'path';\nimport { parseGitHubRepo, isGitHubRemote } from './github-client';\n\n/**\n * `bit ci sync --init` — pure scaffolding logic, unit-testable without a live workspace/git checkout.\n *\n * TEMPLATE SOURCE OF TRUTH: `BIT_SYNC_WORKFLOW_RAW` / `BIT_RELEASE_WORKFLOW_RAW` are byte-for-byte\n * copies of the canonical templates in the `bit-git-sync` action workspace\n * (git-sync/git-sync/workflows/templates/) and MUST be kept in sync with them. The ONLY departure is\n * the two `DEFAULT_BRANCH_MARKER` substitution points; everything else — CHANGE-ME comments, the\n * placeholder action ref, `bit-sync/main` config defaults — stays untouched.\n */\n\n/** Where `scaffoldWorkflowFiles` writes each file, relative to the workspace root. */\nexport const WORKFLOW_RELATIVE_PATHS = {\n sync: path.join('.github', 'workflows', 'bit-sync.yml'),\n release: path.join('.github', 'workflows', 'bit-release.yml'),\n} as const;\n\nconst BIT_SYNC_WORKFLOW_RAW = `# Copy this file into your repository at \\`.github/workflows/bit-sync.yml\\`,\n# then review every line marked \\`CHANGE-ME\\` below -- the defaults assume a\n# repository whose default branch is \\`main\\` and a workspace at the repo root.\n#\n# See the \\`workflows.docs.mdx\\` customer setup guide (component\n# bitdev.git-sync/git-sync/workflows) for the full walk-through: the\n# bit.cloud webhook wiring that drives \\`repository_dispatch\\`, the required\n# secrets, and the \\`teambit.git/ci\\`.\\`sync\\` workspace config this workflow\n# acts on.\nname: bit-sync\non:\n repository_dispatch:\n # 'bit-export' is the real, empirically-verified bit.cloud webhook\n # contract: a single dispatch type discriminated by\n # client_payload.laneId (non-empty 'scope/lane' -> lane export, empty ->\n # main export). The other three types are forward-compat aliases the\n # event router also accepts, in case a webhook is configured to send the\n # originally-assumed, more granular dispatch types instead.\n types: [bit-export, bit-lane-export, bit-main-export, bit-lane-removed]\n schedule:\n # Scheduled reconcile. This is also the ONLY mechanism that picks up\n # lane deletions -- bit.cloud has no \"lane removed\" webhook event.\n - cron: '*/30 * * * *'\n push:\n # CHANGE-ME: \\`main\\` must be your repository's DEFAULT branch, and\n # \\`bit-sync/**\\` must cover your configured \\`sync.mainSyncBranch\\`. Pushes\n # to either are bit-sync's own output and must not re-trigger a sync.\n branches-ignore: [main, 'bit-sync/**']\n workflow_dispatch:\n inputs:\n lane: { description: Lane to sync (empty = all), required: false }\n\n# The default GITHUB_TOKEN is READ-ONLY on repositories and organizations\n# created after Feb 2023, and anywhere the org/repo default is set to\n# \"Read repository contents permission\". Sync pushes branches and\n# opens/updates PRs, so both scopes must be declared explicitly -- without\n# this block the sync fails with a 403 on its first write.\npermissions:\n contents: write\n pull-requests: write\n\nconcurrency:\n # Serializes one lane's syncs so two runs never race on the same branch/PR.\n #\n # Each trigger needs a different expression, because the lane identity\n # arrives in a different place every time:\n # - repository_dispatch -> client_payload.laneId ('scope/lane'), or\n # client_payload.lane for the alias types\n # - push -> github.ref_name (the branch)\n # - workflow_dispatch -> the \\`lane\\` input\n # - schedule -> nothing lane-shaped; it reconciles everything\n #\n # github.ref_name is populated on schedule runs too (it is the default\n # branch there), so it may only be consulted AFTER the event name has been\n # checked. Reading it first -- as a bare \\`... || github.ref_name || 'all'\\`\n # chain does -- makes the final fallback unreachable and lumps every cron\n # run into the same group as pushes to the default branch.\n #\n # RESIDUAL RACE (accepted, by design): a webhook run groups as\n # 'scope/my-lane' while a push to that lane's branch groups as 'my-lane', so\n # two runs for the same lane can still overlap across those two triggers.\n # GitHub expressions have no substring/split function, and bit.cloud's\n # webhook payload template exposes only the full laneId, so the two keys\n # cannot be normalized into one here. This is safe rather than merely\n # tolerated: the reconciler is idempotent and the sync executor diffs\n # against converged state, so a second overlapping run finds nothing left to\n # do and no-ops. The concurrency group is an efficiency measure; it is not\n # what makes the sync correct.\n group: >-\n bit-sync-\\${{\n github.event_name == 'repository_dispatch' && (github.event.client_payload.laneId || github.event.client_payload.lane || 'main-export')\n || github.event_name == 'push' && github.ref_name\n || github.event_name == 'workflow_dispatch' && (github.event.inputs.lane || 'reconcile-all')\n || 'reconcile-all' }}\n # Never cancel a sync mid-flight: it may already have pushed a branch and be\n # partway through opening or updating its PR.\n cancel-in-progress: false\n\njobs:\n sync:\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@v4\n with:\n fetch-depth: 0\n # A PAT/App token so that pushes this workflow makes (e.g. a sync\n # PR branch) can themselves trigger CI. Pushes authenticated with\n # the default GITHUB_TOKEN do NOT trigger other workflow runs.\n token: \\${{ secrets.BIT_SYNC_GH_TOKEN || secrets.GITHUB_TOKEN }}\n - uses: bit-tasks/init@v2\n # Pinned to a commit SHA on purpose: this job holds write permission, and\n # a tag can move. Bump the SHA to take a new version of the action.\n - uses: teambit/bit-git-sync@66c0fdf9e34e45f70b4f397b38b2b01f79dd1f41\n with:\n # CHANGE-ME: keep this in sync with\n # \\`teambit.git/ci\\`.\\`sync.mainSyncBranch\\` in your workspace.jsonc\n # (the action's own default is shown here).\n main-sync-branch: bit-sync/main\n # Uncomment if your workspace.jsonc is NOT at the repository root --\n # the action chdirs here before running anything.\n # ws-dir: packages/my-workspace\n env:\n # Service account token. This account must be EXEMPT from the\n # org's change-request/merge block, or bit.cloud rejects the\n # sync-driven writes.\n BIT_CONFIG_ACCESS_TOKEN: \\${{ secrets.BIT_CONFIG_ACCESS_TOKEN }}\n GITHUB_TOKEN: \\${{ secrets.BIT_SYNC_GH_TOKEN || secrets.GITHUB_TOKEN }}\n # Optional: git identity for the commits the sync creates. Defaults\n # to bit-sync[bot] / bit-sync[bot]@users.noreply.github.com.\n # GIT_USER_NAME: bit-sync[bot]\n # GIT_USER_EMAIL: bit-sync[bot]@users.noreply.github.com\n`;\n\nconst BIT_RELEASE_WORKFLOW_RAW = `# Copy this file into your repository at \\`.github/workflows/bit-release.yml\\`,\n# then review every line marked \\`CHANGE-ME\\` below.\n#\n# See the \\`workflows.docs.mdx\\` customer setup guide (component\n# bitdev.git-sync/git-sync/workflows) for the full walk-through.\nname: bit-release\non:\n pull_request:\n types: [closed]\n # CHANGE-ME: your repository's DEFAULT branch. \\`bit ci merge\\` releases\n # from the default branch, so only PRs merged INTO it should trigger a\n # release -- a stacked PR landing on another feature branch has not\n # reached the default branch yet. The action's event router enforces the\n # same rule from \\`pull_request.base.ref\\`; this filter means a run is never\n # even queued for a non-default base.\n branches: [main]\n\n# The default GITHUB_TOKEN is READ-ONLY on repositories and organizations\n# created after Feb 2023, and anywhere the org/repo default is set to\n# \"Read repository contents permission\". The release run pushes commits/tags\n# and updates PRs, so both scopes must be declared explicitly.\npermissions:\n contents: write\n pull-requests: write\n\nconcurrency:\n group: bit-release-\\${{ github.event.pull_request.number }}\n # Never cancel a release mid-flight.\n cancel-in-progress: false\n\njobs:\n release:\n runs-on: ubuntu-latest\n # Merged main-sync PRs must NOT trigger a release: the scope is already\n # ahead of this merge, there is nothing new to release. The event\n # router also skips this case (routePullRequest checks\n # prHeadRef === mainSyncBranch) -- this \\`if:\\` is defense in depth so the\n # job doesn't even start.\n # CHANGE-ME: the branch literal below MUST match your workspace's\n # configured \\`teambit.git/ci\\`.\\`sync.mainSyncBranch\\`.\n if: github.event.pull_request.merged == true && github.event.pull_request.head.ref != 'bit-sync/main'\n steps:\n - uses: actions/checkout@v4\n with:\n fetch-depth: 0\n token: \\${{ secrets.BIT_SYNC_GH_TOKEN || secrets.GITHUB_TOKEN }}\n - uses: bit-tasks/init@v2\n # Pinned to a commit SHA on purpose: this job holds write permission, and\n # a tag can move. Bump the SHA to take a new version of the action.\n - uses: teambit/bit-git-sync@66c0fdf9e34e45f70b4f397b38b2b01f79dd1f41\n with:\n # CHANGE-ME: keep this in sync with\n # \\`teambit.git/ci\\`.\\`sync.mainSyncBranch\\` AND with the \\`if:\\`\n # condition above.\n main-sync-branch: bit-sync/main\n # Uncomment if your workspace.jsonc is NOT at the repository root --\n # the action chdirs here before running anything.\n # ws-dir: packages/my-workspace\n env:\n BIT_CONFIG_ACCESS_TOKEN: \\${{ secrets.BIT_CONFIG_ACCESS_TOKEN }}\n GITHUB_TOKEN: \\${{ secrets.BIT_SYNC_GH_TOKEN || secrets.GITHUB_TOKEN }}\n # Optional: git identity for the commits the release creates.\n # Defaults to bit-sync[bot] / bit-sync[bot]@users.noreply.github.com.\n # GIT_USER_NAME: bit-sync[bot]\n # GIT_USER_EMAIL: bit-sync[bot]@users.noreply.github.com\n`;\n\n/**\n * The exact substring in each template that encodes the repository's default branch. Exact substring,\n * never a blanket `main` regex — that would also corrupt `bit-main-export` and `bit-sync/main`.\n */\nconst DEFAULT_BRANCH_MARKER = {\n sync: \"branches-ignore: [main, 'bit-sync/**']\",\n release: 'branches: [main]',\n} as const;\n\n/**\n * A YAML single-quoted scalar of `value` (the only escape inside single quotes is a doubled `''`).\n * Both substitution points land inside a YAML flow sequence, where `,` and `]` are structural — and a\n * branch name may legally contain both, so quoting is unconditional.\n */\nfunction yamlSingleQuoted(value: string): string {\n return `'${value.replace(/'/g, \"''\")}'`;\n}\n\n/**\n * Replace the default-branch literal inside `marker` with `defaultBranch`, inside `raw`. Throws when\n * the marker has drifted out of the template — a reworded canonical workflow must fail loudly, not\n * ship a scaffold that still says `main`.\n */\nfunction substituteDefaultBranch(raw: string, marker: string, defaultBranch: string): string {\n if (!raw.includes(marker)) {\n throw new Error(\n `init-scaffold: expected marker \"${marker}\" not found in its workflow template — the canonical ` +\n `template (bitdev.git-sync/git-sync/workflows) has drifted from BIT_SYNC_WORKFLOW_RAW / ` +\n `BIT_RELEASE_WORKFLOW_RAW; update the copy and this substitution point together`\n );\n }\n // Function replacements, not strings: `$&`/`$'`/`$$` are special in string replacements and `$` is\n // git-legal in a branch name. A function replacement is inserted verbatim.\n const substitutedMarker = marker.replace('main', () => yamlSingleQuoted(defaultBranch));\n return raw.replace(marker, () => substitutedMarker);\n}\n\n/** Render `bit-sync.yml` with the repository's actual default branch substituted. */\nexport function renderBitSyncWorkflow(defaultBranch: string): string {\n return substituteDefaultBranch(BIT_SYNC_WORKFLOW_RAW, DEFAULT_BRANCH_MARKER.sync, defaultBranch);\n}\n\n/** Render `bit-release.yml` with the repository's actual default branch substituted. */\nexport function renderBitReleaseWorkflow(defaultBranch: string): string {\n return substituteDefaultBranch(BIT_RELEASE_WORKFLOW_RAW, DEFAULT_BRANCH_MARKER.release, defaultBranch);\n}\n\nexport interface ScaffoldFileOutcome {\n /** relative to the workspace root, e.g. `.github/workflows/bit-sync.yml` */\n relativePath: string;\n status: 'written' | 'skipped';\n}\n\n// Never overwrites an existing file — `--init` must be safe to re-run after hand-edits.\nfunction writeIfAbsent(workspaceDir: string, relativePath: string, content: string): ScaffoldFileOutcome {\n const absPath = path.join(workspaceDir, relativePath);\n if (fs.existsSync(absPath)) {\n return { relativePath, status: 'skipped' };\n }\n fs.mkdirSync(path.dirname(absPath), { recursive: true });\n fs.writeFileSync(absPath, content);\n return { relativePath, status: 'written' };\n}\n\n/** Scaffold both workflow files under `workspaceDir`. Never overwrites; creates `.github/workflows/` as needed. */\nexport function scaffoldWorkflowFiles(workspaceDir: string, defaultBranch: string): ScaffoldFileOutcome[] {\n return [\n writeIfAbsent(workspaceDir, WORKFLOW_RELATIVE_PATHS.sync, renderBitSyncWorkflow(defaultBranch)),\n writeIfAbsent(workspaceDir, WORKFLOW_RELATIVE_PATHS.release, renderBitReleaseWorkflow(defaultBranch)),\n ];\n}\n\nexport interface OwnerRepo {\n owner: string;\n repo: string;\n}\n\n/**\n * Derive `{owner, repo}` from the `origin` remote when it is a parseable GitHub remote, else\n * undefined (the checklist falls back to a placeholder). Reuses `github-client.ts`'s parsing so the\n * two never disagree.\n */\nexport function deriveOwnerRepo(remoteUrl: string | undefined): OwnerRepo | undefined {\n if (!remoteUrl || !isGitHubRemote(remoteUrl)) return undefined;\n const ownerSlashRepo = parseGitHubRepo(remoteUrl);\n if (!ownerSlashRepo) return undefined;\n const [owner, repo] = ownerSlashRepo.split('/');\n if (!owner || !repo) return undefined;\n return { owner, repo };\n}\n\n/**\n * The bit.cloud custom webhook payload template, verified byte-perfect against a live delivery.\n * Lane vs. main export is discriminated by whether `laneId` is empty.\n */\nconst WEBHOOK_PAYLOAD_TEMPLATE =\n '{\"event_type\":\"bit-export\",\"client_payload\":{\"laneId\":\"{{laneId}}\",\"componentIds\":\"{{componentIds}}\",\"owner\":\"{{owner}}\",\"actor\":\"{{username}}\"}}';\n\n/**\n * The manual-steps checklist `bit ci sync --init` prints: everything the command itself cannot do\n * (secrets live in GitHub settings; the webhook lives on bit.cloud).\n */\nexport function renderInitChecklist(ownerRepo: OwnerRepo | undefined): string {\n const repoSegment = ownerRepo ? `${ownerRepo.owner}/${ownerRepo.repo}` : '<owner>/<repo>';\n const dispatchUrl = `https://api.github.com/repos/${repoSegment}/dispatches`;\n return [\n '',\n 'Remaining manual steps (bit ci sync --init only scaffolds files -- these need a human):',\n '',\n '1. Secrets -- add in the repository (or org) Settings > Secrets and variables > Actions:',\n ' - BIT_CONFIG_ACCESS_TOKEN (required): a bit.cloud service-account token with export rights on',\n \" this scope. This account must also be exempt from the org's\",\n ' change-request/merge block -- it is the only identity that merges lanes.',\n ' - BIT_SYNC_GH_TOKEN (optional): a GitHub PAT or App token. Without it, sync pushes/PRs use the',\n ' default GITHUB_TOKEN, which does NOT trigger downstream workflow runs (loop-safe, but the',\n ' sync PR then gets no CI checks).',\n '',\n '2. Permissions -- both scaffolded workflows already declare `contents: write` and',\n ' `pull-requests: write`. Nothing to change unless an org-wide policy overrides workflow-level',\n ' permissions (e.g. a default of \"Read repository contents permission\" for the GITHUB_TOKEN).',\n '',\n '3. bit.cloud webhook -- create ONE webhook (org Settings > Webhooks) on the \"Components > Export',\n ' succeeded\" event:',\n ` URL: ${dispatchUrl}`,\n ' Headers: Authorization: Bearer <PAT>',\n ' Accept: application/vnd.github+json',\n ' Custom payload template:',\n ` ${WEBHOOK_PAYLOAD_TEMPLATE}`,\n ' WARNING: create this webhook fresh -- editing an existing webhook drops its custom headers',\n ' (known bit.cloud platform bug, verified 2026-07-29). If the URL, headers or template need to',\n ' change later, delete the webhook and create a new one rather than editing it.',\n '',\n '4. Checkout depth -- both scaffolded workflows already check out with `fetch-depth: 0`. This is',\n ' required: the reconciler reads full git history, and a shallow (--depth=1) clone fails sync',\n ' safely but uselessly (HALTED, no writes). Keep `fetch-depth: 0` if you customize the workflow.',\n ' Narrowing the REFSPEC is fine, though -- a single-branch clone is supported, because every',\n ' fetch sync performs names +refs/heads/*:refs/remotes/origin/* explicitly.',\n '',\n ].join('\\n');\n}\n"],"mappings":";;;;;;;;;;;AAAA,SAAAA,IAAA;EAAA,MAAAC,IAAA,GAAAC,sBAAA,CAAAC,OAAA;EAAAH,GAAA,YAAAA,CAAA;IAAA,OAAAC,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AACA,SAAAG,MAAA;EAAA,MAAAH,IAAA,GAAAC,sBAAA,CAAAC,OAAA;EAAAC,KAAA,YAAAA,CAAA;IAAA,OAAAH,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AACA,SAAAI,cAAA;EAAA,MAAAJ,IAAA,GAAAE,OAAA;EAAAE,aAAA,YAAAA,CAAA;IAAA,OAAAJ,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAAkE,SAAAC,uBAAAI,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA;AAElE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACO,MAAMG,uBAAuB,GAAAC,OAAA,CAAAD,uBAAA,GAAG;EACrCE,IAAI,EAAEC,eAAI,CAACC,IAAI,CAAC,SAAS,EAAE,WAAW,EAAE,cAAc,CAAC;EACvDC,OAAO,EAAEF,eAAI,CAACC,IAAI,CAAC,SAAS,EAAE,WAAW,EAAE,iBAAiB;AAC9D,CAAU;AAEV,MAAME,qBAAqB,GAAG;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AAED,MAAMC,wBAAwB,GAAG;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA,MAAMC,qBAAqB,GAAG;EAC5BN,IAAI,EAAE,wCAAwC;EAC9CG,OAAO,EAAE;AACX,CAAU;;AAEV;AACA;AACA;AACA;AACA;AACA,SAASI,gBAAgBA,CAACC,KAAa,EAAU;EAC/C,OAAO,IAAIA,KAAK,CAACC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG;AACzC;;AAEA;AACA;AACA;AACA;AACA;AACA,SAASC,uBAAuBA,CAACC,GAAW,EAAEC,MAAc,EAAEC,aAAqB,EAAU;EAC3F,IAAI,CAACF,GAAG,CAACG,QAAQ,CAACF,MAAM,CAAC,EAAE;IACzB,MAAM,IAAIG,KAAK,CACb,mCAAmCH,MAAM,uDAAuD,GAC9F,yFAAyF,GACzF,gFACJ,CAAC;EACH;EACA;EACA;EACA,MAAMI,iBAAiB,GAAGJ,MAAM,CAACH,OAAO,CAAC,MAAM,EAAE,MAAMF,gBAAgB,CAACM,aAAa,CAAC,CAAC;EACvF,OAAOF,GAAG,CAACF,OAAO,CAACG,MAAM,EAAE,MAAMI,iBAAiB,CAAC;AACrD;;AAEA;AACO,SAASC,qBAAqBA,CAACJ,aAAqB,EAAU;EACnE,OAAOH,uBAAuB,CAACN,qBAAqB,EAAEE,qBAAqB,CAACN,IAAI,EAAEa,aAAa,CAAC;AAClG;;AAEA;AACO,SAASK,wBAAwBA,CAACL,aAAqB,EAAU;EACtE,OAAOH,uBAAuB,CAACL,wBAAwB,EAAEC,qBAAqB,CAACH,OAAO,EAAEU,aAAa,CAAC;AACxG;AAQA;AACA,SAASM,aAAaA,CAACC,YAAoB,EAAEC,YAAoB,EAAEC,OAAe,EAAuB;EACvG,MAAMC,OAAO,GAAGtB,eAAI,CAACC,IAAI,CAACkB,YAAY,EAAEC,YAAY,CAAC;EACrD,IAAIG,aAAE,CAACC,UAAU,CAACF,OAAO,CAAC,EAAE;IAC1B,OAAO;MAAEF,YAAY;MAAEK,MAAM,EAAE;IAAU,CAAC;EAC5C;EACAF,aAAE,CAACG,SAAS,CAAC1B,eAAI,CAAC2B,OAAO,CAACL,OAAO,CAAC,EAAE;IAAEM,SAAS,EAAE;EAAK,CAAC,CAAC;EACxDL,aAAE,CAACM,aAAa,CAACP,OAAO,EAAED,OAAO,CAAC;EAClC,OAAO;IAAED,YAAY;IAAEK,MAAM,EAAE;EAAU,CAAC;AAC5C;;AAEA;AACO,SAASK,qBAAqBA,CAACX,YAAoB,EAAEP,aAAqB,EAAyB;EACxG,OAAO,CACLM,aAAa,CAACC,YAAY,EAAEtB,uBAAuB,CAACE,IAAI,EAAEiB,qBAAqB,CAACJ,aAAa,CAAC,CAAC,EAC/FM,aAAa,CAACC,YAAY,EAAEtB,uBAAuB,CAACK,OAAO,EAAEe,wBAAwB,CAACL,aAAa,CAAC,CAAC,CACtG;AACH;AAOA;AACA;AACA;AACA;AACA;AACO,SAASmB,eAAeA,CAACC,SAA6B,EAAyB;EACpF,IAAI,CAACA,SAAS,IAAI,CAAC,IAAAC,8BAAc,EAACD,SAAS,CAAC,EAAE,OAAOE,SAAS;EAC9D,MAAMC,cAAc,GAAG,IAAAC,+BAAe,EAACJ,SAAS,CAAC;EACjD,IAAI,CAACG,cAAc,EAAE,OAAOD,SAAS;EACrC,MAAM,CAACG,KAAK,EAAEC,IAAI,CAAC,GAAGH,cAAc,CAACI,KAAK,CAAC,GAAG,CAAC;EAC/C,IAAI,CAACF,KAAK,IAAI,CAACC,IAAI,EAAE,OAAOJ,SAAS;EACrC,OAAO;IAAEG,KAAK;IAAEC;EAAK,CAAC;AACxB;;AAEA;AACA;AACA;AACA;AACA,MAAME,wBAAwB,GAC5B,mJAAmJ;;AAErJ;AACA;AACA;AACA;AACO,SAASC,mBAAmBA,CAACC,SAAgC,EAAU;EAC5E,MAAMC,WAAW,GAAGD,SAAS,GAAG,GAAGA,SAAS,CAACL,KAAK,IAAIK,SAAS,CAACJ,IAAI,EAAE,GAAG,gBAAgB;EACzF,MAAMM,WAAW,GAAG,gCAAgCD,WAAW,aAAa;EAC5E,OAAO,CACL,EAAE,EACF,yFAAyF,EACzF,EAAE,EACF,0FAA0F,EAC1F,kGAAkG,EAClG,kEAAkE,EAClE,+EAA+E,EAC/E,mGAAmG,EACnG,gGAAgG,EAChG,uCAAuC,EACvC,EAAE,EACF,mFAAmF,EACnF,iGAAiG,EACjG,gGAAgG,EAChG,EAAE,EACF,kGAAkG,EAClG,sBAAsB,EACtB,eAAeC,WAAW,EAAE,EAC5B,yCAAyC,EACzC,iDAAiD,EACjD,6BAA6B,EAC7B,MAAMJ,wBAAwB,EAAE,EAChC,+FAA+F,EAC/F,iGAAiG,EACjG,kFAAkF,EAClF,EAAE,EACF,iGAAiG,EACjG,gGAAgG,EAChG,mGAAmG,EACnG,+FAA+F,EAC/F,8EAA8E,EAC9E,EAAE,CACH,CAACvC,IAAI,CAAC,IAAI,CAAC;AACd","ignoreList":[]}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,169 @@
1
+ "use strict";
2
+
3
+ function _chai() {
4
+ const data = require("chai");
5
+ _chai = function () {
6
+ return data;
7
+ };
8
+ return data;
9
+ }
10
+ function _fs() {
11
+ const data = _interopRequireDefault(require("fs"));
12
+ _fs = function () {
13
+ return data;
14
+ };
15
+ return data;
16
+ }
17
+ function _os() {
18
+ const data = _interopRequireDefault(require("os"));
19
+ _os = function () {
20
+ return data;
21
+ };
22
+ return data;
23
+ }
24
+ function _path() {
25
+ const data = _interopRequireDefault(require("path"));
26
+ _path = function () {
27
+ return data;
28
+ };
29
+ return data;
30
+ }
31
+ function _yaml() {
32
+ const data = _interopRequireDefault(require("yaml"));
33
+ _yaml = function () {
34
+ return data;
35
+ };
36
+ return data;
37
+ }
38
+ function _initScaffold() {
39
+ const data = require("./init-scaffold");
40
+ _initScaffold = function () {
41
+ return data;
42
+ };
43
+ return data;
44
+ }
45
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
46
+ const yamlLoad = src => _yaml().default.parse(src);
47
+
48
+ /** YAML 1.1-schema parsers resolve the plain scalar key `on` to `true`, so accept either key. */
49
+ function onSection(rendered) {
50
+ const doc = yamlLoad(rendered);
51
+ return doc.on ?? doc[true];
52
+ }
53
+
54
+ /**
55
+ * Parsed, not substring-matched: the substitution point sits inside a YAML flow sequence, where `,` and
56
+ * `]` are structural and a substring match is blind to exactly the damage an unquoted value does. `$` is
57
+ * git-legal and `$&`/`$'`/`$$` are special in a string replacement, so those must arrive verbatim too.
58
+ */
59
+ const BRANCHES = ['main', 'develop', 'release/2026', 'release/main', 'a,b]c', "it's/a-branch", "a$'b", 'a$&b', 'a$$b', 'a$`b']; // prettier-ignore
60
+
61
+ describe('init-scaffold', () => {
62
+ describe('the rendered workflows', () => {
63
+ it('put the default branch in as exactly one element of each template’s branch filter', () => {
64
+ BRANCHES.forEach(branch => {
65
+ (0, _chai().expect)(onSection((0, _initScaffold().renderBitSyncWorkflow)(branch)).push['branches-ignore'], branch).to.deep.equal([branch, 'bit-sync/**']);
66
+ (0, _chai().expect)(onSection((0, _initScaffold().renderBitReleaseWorkflow)(branch)).pull_request.branches, branch).to.deep.equal([branch]);
67
+ });
68
+ });
69
+ it('quote the value rather than escape it, and touch nothing else in the document', () => {
70
+ const sync = (0, _initScaffold().renderBitSyncWorkflow)('develop');
71
+ const release = (0, _initScaffold().renderBitReleaseWorkflow)('develop');
72
+ (0, _chai().expect)(sync).to.contain("branches-ignore: ['develop', 'bit-sync/**']");
73
+ (0, _chai().expect)(release).to.contain("branches: ['develop']");
74
+ // a naive replace-all of "main" would rewrite every one of these
75
+ (0, _chai().expect)(sync).to.contain('main-sync-branch: bit-sync/main');
76
+ (0, _chai().expect)(sync).to.contain('bit-main-export');
77
+ (0, _chai().expect)(sync).to.contain('main export)');
78
+ (0, _chai().expect)(sync).to.contain('${{ secrets.BIT_CONFIG_ACCESS_TOKEN }}');
79
+ (0, _chai().expect)(release).to.contain("github.event.pull_request.head.ref != 'bit-sync/main'");
80
+ (0, _chai().expect)(release).to.contain('main-sync-branch: bit-sync/main');
81
+ // YAML single-quote escaping, and the rest of the document intact
82
+ (0, _chai().expect)((0, _initScaffold().renderBitSyncWorkflow)("it's/a-branch")).to.contain("'it''s/a-branch'");
83
+ (0, _chai().expect)(yamlLoad((0, _initScaffold().renderBitSyncWorkflow)('release/main')).jobs).to.be.an('object');
84
+ });
85
+ });
86
+ describe('scaffoldWorkflowFiles', () => {
87
+ let workspaceDir;
88
+ beforeEach(() => {
89
+ workspaceDir = _fs().default.mkdtempSync(_path().default.join(_os().default.tmpdir(), 'init-scaffold-'));
90
+ });
91
+ afterEach(() => {
92
+ _fs().default.rmSync(workspaceDir, {
93
+ recursive: true,
94
+ force: true
95
+ });
96
+ });
97
+ it('writes both workflow files with the default branch substituted, creating .github/workflows/', () => {
98
+ (0, _chai().expect)((0, _initScaffold().scaffoldWorkflowFiles)(workspaceDir, 'develop')).to.deep.equal([{
99
+ relativePath: _initScaffold().WORKFLOW_RELATIVE_PATHS.sync,
100
+ status: 'written'
101
+ }, {
102
+ relativePath: _initScaffold().WORKFLOW_RELATIVE_PATHS.release,
103
+ status: 'written'
104
+ }]);
105
+ const read = rel => _fs().default.readFileSync(_path().default.join(workspaceDir, rel), 'utf8');
106
+ (0, _chai().expect)(read(_initScaffold().WORKFLOW_RELATIVE_PATHS.sync)).to.contain("branches-ignore: ['develop', 'bit-sync/**']");
107
+ (0, _chai().expect)(read(_initScaffold().WORKFLOW_RELATIVE_PATHS.release)).to.contain("branches: ['develop']");
108
+ });
109
+ it('is idempotent: a second run skips both files rather than overwriting them', () => {
110
+ (0, _initScaffold().scaffoldWorkflowFiles)(workspaceDir, 'develop');
111
+ (0, _chai().expect)((0, _initScaffold().scaffoldWorkflowFiles)(workspaceDir, 'develop')).to.deep.equal([{
112
+ relativePath: _initScaffold().WORKFLOW_RELATIVE_PATHS.sync,
113
+ status: 'skipped'
114
+ }, {
115
+ relativePath: _initScaffold().WORKFLOW_RELATIVE_PATHS.release,
116
+ status: 'skipped'
117
+ }]);
118
+ });
119
+ it('skips only the file that already exists, writing the other one', () => {
120
+ const syncAbsPath = _path().default.join(workspaceDir, _initScaffold().WORKFLOW_RELATIVE_PATHS.sync);
121
+ _fs().default.mkdirSync(_path().default.dirname(syncAbsPath), {
122
+ recursive: true
123
+ });
124
+ _fs().default.writeFileSync(syncAbsPath, 'hand-edited content, do not touch\n');
125
+ (0, _chai().expect)((0, _initScaffold().scaffoldWorkflowFiles)(workspaceDir, 'develop')).to.deep.equal([{
126
+ relativePath: _initScaffold().WORKFLOW_RELATIVE_PATHS.sync,
127
+ status: 'skipped'
128
+ }, {
129
+ relativePath: _initScaffold().WORKFLOW_RELATIVE_PATHS.release,
130
+ status: 'written'
131
+ }]);
132
+ (0, _chai().expect)(_fs().default.readFileSync(syncAbsPath, 'utf8')).to.equal('hand-edited content, do not touch\n');
133
+ });
134
+ });
135
+ describe('deriveOwnerRepo', () => {
136
+ const REMOTES = [['git@github.com:acme/shop.git', {
137
+ owner: 'acme',
138
+ repo: 'shop'
139
+ }], ['https://github.com/acme/shop.git', {
140
+ owner: 'acme',
141
+ repo: 'shop'
142
+ }], ['https://github.com/acme/shop', {
143
+ owner: 'acme',
144
+ repo: 'shop'
145
+ }], ['https://gitlab.com/acme/shop.git', undefined],
146
+ // a local/bare remote has no host at all
147
+ ['/path/to/bare.git', undefined], ['file:///path/to/bare.git', undefined], [undefined, undefined]];
148
+ it('parses a GitHub remote in either form, and nothing else', () => {
149
+ REMOTES.forEach(([remote, expected]) => (0, _chai().expect)((0, _initScaffold().deriveOwnerRepo)(remote), String(remote)).to.deep.equal(expected));
150
+ });
151
+ });
152
+ describe('renderInitChecklist', () => {
153
+ it('renders a real dispatch URL when owner/repo were derived, a placeholder when not', () => {
154
+ const derived = (0, _initScaffold().renderInitChecklist)({
155
+ owner: 'acme',
156
+ repo: 'shop'
157
+ });
158
+ (0, _chai().expect)(derived).to.contain('https://api.github.com/repos/acme/shop/dispatches');
159
+ (0, _chai().expect)(derived).to.not.contain('<owner>/<repo>');
160
+ (0, _chai().expect)((0, _initScaffold().renderInitChecklist)(undefined)).to.contain('https://api.github.com/repos/<owner>/<repo>/dispatches');
161
+ });
162
+ it('always includes the secrets, permissions, webhook and fetch-depth checklist items', () => {
163
+ const checklist = (0, _initScaffold().renderInitChecklist)(undefined);
164
+ ['BIT_CONFIG_ACCESS_TOKEN', 'BIT_SYNC_GH_TOKEN', 'contents: write', 'Components > Export', 'Authorization: Bearer <PAT>', 'Accept: application/vnd.github+json', '"event_type":"bit-export"', '{{laneId}}', 'drops its custom headers', 'fetch-depth: 0'].forEach(item => (0, _chai().expect)(checklist, item).to.contain(item));
165
+ });
166
+ });
167
+ });
168
+
169
+ //# sourceMappingURL=init-scaffold.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_chai","data","require","_fs","_interopRequireDefault","_os","_path","_yaml","_initScaffold","e","__esModule","default","yamlLoad","src","YAML","parse","onSection","rendered","doc","on","BRANCHES","describe","it","forEach","branch","expect","renderBitSyncWorkflow","push","to","deep","equal","renderBitReleaseWorkflow","pull_request","branches","sync","release","contain","jobs","be","an","workspaceDir","beforeEach","fs","mkdtempSync","path","join","os","tmpdir","afterEach","rmSync","recursive","force","scaffoldWorkflowFiles","relativePath","WORKFLOW_RELATIVE_PATHS","status","read","rel","readFileSync","syncAbsPath","mkdirSync","dirname","writeFileSync","REMOTES","owner","repo","undefined","remote","expected","deriveOwnerRepo","String","derived","renderInitChecklist","not","checklist","item"],"sources":["init-scaffold.spec.ts"],"sourcesContent":["import { expect } from 'chai';\nimport fs from 'fs';\nimport os from 'os';\nimport path from 'path';\nimport YAML from 'yaml';\nimport {\n WORKFLOW_RELATIVE_PATHS,\n renderBitSyncWorkflow,\n renderBitReleaseWorkflow,\n scaffoldWorkflowFiles,\n deriveOwnerRepo,\n renderInitChecklist,\n} from './init-scaffold';\n\nconst yamlLoad = (src: string) => YAML.parse(src);\n\n/** YAML 1.1-schema parsers resolve the plain scalar key `on` to `true`, so accept either key. */\nfunction onSection(rendered: string): any {\n const doc = yamlLoad(rendered) as any;\n return doc.on ?? doc[true as any];\n}\n\n/**\n * Parsed, not substring-matched: the substitution point sits inside a YAML flow sequence, where `,` and\n * `]` are structural and a substring match is blind to exactly the damage an unquoted value does. `$` is\n * git-legal and `$&`/`$'`/`$$` are special in a string replacement, so those must arrive verbatim too.\n */\nconst BRANCHES = ['main', 'develop', 'release/2026', 'release/main', 'a,b]c', \"it's/a-branch\", \"a$'b\", 'a$&b', 'a$$b', 'a$`b']; // prettier-ignore\n\ndescribe('init-scaffold', () => {\n describe('the rendered workflows', () => {\n it('put the default branch in as exactly one element of each template’s branch filter', () => {\n BRANCHES.forEach((branch) => {\n expect(onSection(renderBitSyncWorkflow(branch)).push['branches-ignore'], branch).to.deep.equal([\n branch,\n 'bit-sync/**',\n ]);\n expect(onSection(renderBitReleaseWorkflow(branch)).pull_request.branches, branch).to.deep.equal([branch]);\n });\n });\n\n it('quote the value rather than escape it, and touch nothing else in the document', () => {\n const sync = renderBitSyncWorkflow('develop');\n const release = renderBitReleaseWorkflow('develop');\n expect(sync).to.contain(\"branches-ignore: ['develop', 'bit-sync/**']\");\n expect(release).to.contain(\"branches: ['develop']\");\n // a naive replace-all of \"main\" would rewrite every one of these\n expect(sync).to.contain('main-sync-branch: bit-sync/main');\n expect(sync).to.contain('bit-main-export');\n expect(sync).to.contain('main export)');\n expect(sync).to.contain('${{ secrets.BIT_CONFIG_ACCESS_TOKEN }}');\n expect(release).to.contain(\"github.event.pull_request.head.ref != 'bit-sync/main'\");\n expect(release).to.contain('main-sync-branch: bit-sync/main');\n // YAML single-quote escaping, and the rest of the document intact\n expect(renderBitSyncWorkflow(\"it's/a-branch\")).to.contain(\"'it''s/a-branch'\");\n expect(yamlLoad(renderBitSyncWorkflow('release/main')).jobs).to.be.an('object');\n });\n });\n\n describe('scaffoldWorkflowFiles', () => {\n let workspaceDir: string;\n\n beforeEach(() => {\n workspaceDir = fs.mkdtempSync(path.join(os.tmpdir(), 'init-scaffold-'));\n });\n\n afterEach(() => {\n fs.rmSync(workspaceDir, { recursive: true, force: true });\n });\n\n it('writes both workflow files with the default branch substituted, creating .github/workflows/', () => {\n expect(scaffoldWorkflowFiles(workspaceDir, 'develop')).to.deep.equal([\n { relativePath: WORKFLOW_RELATIVE_PATHS.sync, status: 'written' },\n { relativePath: WORKFLOW_RELATIVE_PATHS.release, status: 'written' },\n ]);\n const read = (rel: string) => fs.readFileSync(path.join(workspaceDir, rel), 'utf8');\n expect(read(WORKFLOW_RELATIVE_PATHS.sync)).to.contain(\"branches-ignore: ['develop', 'bit-sync/**']\");\n expect(read(WORKFLOW_RELATIVE_PATHS.release)).to.contain(\"branches: ['develop']\");\n });\n\n it('is idempotent: a second run skips both files rather than overwriting them', () => {\n scaffoldWorkflowFiles(workspaceDir, 'develop');\n expect(scaffoldWorkflowFiles(workspaceDir, 'develop')).to.deep.equal([\n { relativePath: WORKFLOW_RELATIVE_PATHS.sync, status: 'skipped' },\n { relativePath: WORKFLOW_RELATIVE_PATHS.release, status: 'skipped' },\n ]);\n });\n\n it('skips only the file that already exists, writing the other one', () => {\n const syncAbsPath = path.join(workspaceDir, WORKFLOW_RELATIVE_PATHS.sync);\n fs.mkdirSync(path.dirname(syncAbsPath), { recursive: true });\n fs.writeFileSync(syncAbsPath, 'hand-edited content, do not touch\\n');\n expect(scaffoldWorkflowFiles(workspaceDir, 'develop')).to.deep.equal([\n { relativePath: WORKFLOW_RELATIVE_PATHS.sync, status: 'skipped' },\n { relativePath: WORKFLOW_RELATIVE_PATHS.release, status: 'written' },\n ]);\n expect(fs.readFileSync(syncAbsPath, 'utf8')).to.equal('hand-edited content, do not touch\\n');\n });\n });\n\n describe('deriveOwnerRepo', () => {\n const REMOTES: Array<[string | undefined, { owner: string; repo: string } | undefined]> = [\n ['git@github.com:acme/shop.git', { owner: 'acme', repo: 'shop' }],\n ['https://github.com/acme/shop.git', { owner: 'acme', repo: 'shop' }],\n ['https://github.com/acme/shop', { owner: 'acme', repo: 'shop' }],\n ['https://gitlab.com/acme/shop.git', undefined],\n // a local/bare remote has no host at all\n ['/path/to/bare.git', undefined],\n ['file:///path/to/bare.git', undefined],\n [undefined, undefined],\n ];\n\n it('parses a GitHub remote in either form, and nothing else', () => {\n REMOTES.forEach(([remote, expected]) => expect(deriveOwnerRepo(remote), String(remote)).to.deep.equal(expected));\n });\n });\n\n describe('renderInitChecklist', () => {\n it('renders a real dispatch URL when owner/repo were derived, a placeholder when not', () => {\n const derived = renderInitChecklist({ owner: 'acme', repo: 'shop' });\n expect(derived).to.contain('https://api.github.com/repos/acme/shop/dispatches');\n expect(derived).to.not.contain('<owner>/<repo>');\n expect(renderInitChecklist(undefined)).to.contain('https://api.github.com/repos/<owner>/<repo>/dispatches');\n });\n\n it('always includes the secrets, permissions, webhook and fetch-depth checklist items', () => {\n const checklist = renderInitChecklist(undefined);\n [\n 'BIT_CONFIG_ACCESS_TOKEN',\n 'BIT_SYNC_GH_TOKEN',\n 'contents: write',\n 'Components > Export',\n 'Authorization: Bearer <PAT>',\n 'Accept: application/vnd.github+json',\n '\"event_type\":\"bit-export\"',\n '{{laneId}}',\n 'drops its custom headers',\n 'fetch-depth: 0',\n ].forEach((item) => expect(checklist, item).to.contain(item));\n });\n });\n});\n"],"mappings":"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","ignoreList":[]}