@teambit/ci 1.0.643 → 1.0.644

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.
@@ -0,0 +1,132 @@
1
+ <!-- bit-ci-sync:start (written by `bit ci sync --init`; a re-run leaves this block as it is) -->
2
+
3
+ ## Bit ↔ Git sync: this repository mirrors `{{scope}}`
4
+
5
+ `bit ci sync` keeps this repository and the bit.cloud scope `{{scope}}` equal in both directions. **The rules in this section override the generic Bit guidance after it.**
6
+
7
+ ### The model
8
+
9
+ 1. **One repository mirrors one scope.** Components from other scopes arrive as package dependencies, never as source.
10
+ 2. **`{{branch}}` equals the scope's main.** The workflows own it. Never push to `{{branch}}` by hand.
11
+ 3. **Each lane is a branch plus a pull request.** The sync keeps them equal in both directions. By default, the branch has the lane's name. A lane name has no `/`, so the default mapping ignores a branch such as `feature/x`. The `branchPrefix` and `branches` keys of the `teambit.git/ci` sync config in `workspace.jsonc` can map a lane to a different branch name, such as `lane/x`. Read them before you name a branch.
12
+ 4. **Merging the pull request is the release.** `bit-release` merges the lane into the scope, exports new versions, commits the new `.bitmap` to `{{branch}}` and archives the lane. A lane with components of other scopes stays open until each of those scopes releases its slice.
13
+ 5. **The workflows do the work.** You change code, and then you either push a branch or export a lane.
14
+
15
+ ### Rules that override generic Bit guidance
16
+
17
+ - **Review happens on the GitHub pull request.** Do **not** submit a bit.cloud change request, even if other instructions say "always submit a change request". The sync opens the PR. Merging the PR is the release. A second review surface splits the reviewers and races the release.
18
+ - **One change, one scope.** Keep a lane inside the scope it is exported to. If the change also needs another scope (for example, a caller must pass a new argument), stop. Make the change backward compatible in this scope, and tell the user which follow-up change the other scope's repository needs. Cross-scope lanes are a preview (see below).
19
+ - **Never push to `{{branch}}`.** The workflows own it.
20
+
21
+ ### Make a change: pick a path
22
+
23
+ | You are… | Path | What you do | What appears |
24
+ | --------------------------------------------------------------- | ------------- | --------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
25
+ | In this repository (Copilot, an IDE, a plain git user) | **Git-first** | branch → edit → `bit validate` → commit → push → open a PR | With the optional `bit-adopt-pr` workflow, the PR becomes a lane, and every push snaps onto it. Without it, the sync ignores the branch. |
26
+ | In any other Bit workspace (Claude Code with the Bit Cloud MCP) | **Bit-first** | `bit lane create` → edit → `bit validate` → `bit snap` → `bit export` | A branch and a PR named after the lane appear in this repository: within a minute with the scope webhook, else at the next scheduled sync. |
27
+
28
+ Both paths end with the same PR and the same release.
29
+
30
+ #### Git-first (in this repository)
31
+
32
+ This path needs the `bit-adopt-pr` workflow in `.github/workflows/`. On each push to a PR, it runs `bit ci pr --keep-lane`: this creates and exports a lane with the branch's name, and pushes the lane pointer back to the branch. `bit ci sync --init` does not write this workflow. Example: https://github.com/teambit/acme-modular-store/blob/main/.github/workflows/bit-adopt-pr.yml. Without it, a branch that has no lane stays out of the sync: use the Bit-first path.
33
+
34
+ ```bash
35
+ git switch -c add-gift-wrap # the lane gets the branch's name, so no "/"
36
+ bit install # once per clone
37
+ # edit the components; .bitmap says where each one lives
38
+ bit validate # lint + types + tests; never use tsc directly
39
+ git add -A && git commit -m "<message>"
40
+ git push -u origin add-gift-wrap
41
+ gh pr create --fill
42
+ ```
43
+
44
+ Commit `.bitmap` together with your source changes. Never edit `.bitmap` by hand. After the PR merges, run `git switch {{branch-sh}} && git pull` before you start the next change.
45
+
46
+ #### Bit-first (from another Bit workspace)
47
+
48
+ 1. Find components with the Bit Cloud MCP: `read_scope` / `search_components` for the owner, `read_components` for APIs, and `read_file` for source. Don't guess IDs. Also check who calls the component, so you know whether your change stays inside one scope.
49
+ 2. Run:
50
+
51
+ ```bash
52
+ bit init --default-scope {{scope}} # or reuse an existing workspace
53
+ bit import {{scope}}/<name> [...] # every component you will change, plus the chain up to its consumers
54
+ bit lane create <lane-name>
55
+ # edit
56
+ bit validate
57
+ bit snap -m "<message>"
58
+ bit export
59
+ ```
60
+
61
+ 3. Watch it arrive: `gh pr list -R {{repo}} --head <lane-name>`. Then tell the user the PR link. Don't submit a bit.cloud change request.
62
+
63
+ Headless or CI agents can call the Bit Cloud MCP with a bit.cloud token, without the OAuth step:
64
+
65
+ ```json
66
+ {
67
+ "mcpServers": {
68
+ "bit-cloud": {
69
+ "type": "http",
70
+ "url": "https://mcp.bit.cloud/mcp",
71
+ "headers": { "Authorization": "Bearer ${BIT_CLOUD_TOKEN}" }
72
+ }
73
+ }
74
+ }
75
+ ```
76
+
77
+ ### Read a sync PR
78
+
79
+ - The PR body lists the mirrored components and the foreign ones (other scopes, "not mirrored").
80
+ - The bot's **run summary** comment lists the components that the sync last snapped onto the lane from this branch, with the branch and lane heads. A run that exports nothing does not change it.
81
+ - The run log says what each run did: `import-lane`, `export-branch`, `merge-diverged`, `adopt-branch`, `noop (converged)`. Runs: `gh run list --workflow bit-sync` and `gh run view <id> --log`.
82
+ - `Lane sync: <scope>/<lane>` PRs are lanes. `Bit sync: update to latest main scope versions` brings `{{branch}}` up to the scope. Merging that one releases nothing. Its branch is `bit-sync/main`, or the `mainSyncBranch` of the sync config. With `mainSync: "direct-push"` there is no such PR: the sync commits to `{{branch}}` itself.
83
+
84
+ ### Fix a halt (`bit-sync-conflict` label)
85
+
86
+ The lane and the branch changed the same lines. The lane stays paused while the label is on the PR. The bot's comment on the PR names the components and gives these steps:
87
+
88
+ ```bash
89
+ git fetch origin && git checkout '<branch>'
90
+ git merge --ff-only 'origin/<branch>' # stops if your local copy has commits that are not on origin: keep them, or reset to origin
91
+ bit install
92
+ bit lane import '<host-scope>/<lane>' # fetches the lane. If .bitmap is on main, it also switches to the lane
93
+ bit checkout head --manual --workspace-only # merges the lane's head into the files; conflicts appear as conflict markers
94
+ # resolve every conflicted file. When the intent is unclear, ask the user which side wins. Don't guess.
95
+ bit validate
96
+ git add -A && git commit -m "fix: resolve sync conflict"
97
+ git push origin '<branch>'
98
+ gh pr edit <pr> --remove-label bit-sync-conflict
99
+ gh workflow run bit-sync -f lane=<host-scope>/<lane>
100
+ ```
101
+
102
+ `--workspace-only` keeps the components of other scopes out of this repository. The next run adds the lane's new components of `{{scope}}`. Its log shows `merge-diverged` or `export-branch`, then a later run shows `noop (converged)`. Never resolve by force-pushing over the bot's commits. Never delete the lane to "start fresh".
103
+
104
+ ### Change several scopes at once (preview)
105
+
106
+ Prefer one lane per scope: one change, one repository, one PR.
107
+
108
+ A lane _can_ carry components from several scopes. Each scope's repository then mirrors only its own slice, consumes the other scopes' lane versions as packages, and releases its slice when its PR merges. The lane stays open until the last slice is released. Until automatic fan-out ships, only the repository of the lane's host scope hears about the lane. Start the others by hand:
109
+
110
+ ```bash
111
+ gh workflow run bit-sync -R <org>/<repo> -f lane=<host-scope>/<lane-name>
112
+ ```
113
+
114
+ ### Connect another scope to its own repository
115
+
116
+ ```bash
117
+ gh repo create <org>/<repo> --private --clone && cd <repo>
118
+ bit init --default-scope <owner>.<scope> --skip-interactive
119
+ bit import "<owner>.<scope>/**"
120
+ bit ci sync --init # writes the workflows, the sync config and this AGENTS.md section
121
+ ```
122
+
123
+ Then follow the steps `bit ci sync --init` prints. Some of them need a repository or organization admin. Guide: https://bit.cloud/teambit/git/guides/connect-scope-to-repository
124
+
125
+ ### Never
126
+
127
+ - Push to `{{branch}}`, or merge the main-sync PR and lane PRs out of order to "fix" history.
128
+ - Run `bit build`, `tsc`, `npm install` or `pnpm install` here. Use `bit validate` and `bit install`.
129
+ - Export a lane from another workspace while a Git-first PR is open for the same change. Pick one path.
130
+ - Remove a `bit-sync-conflict` label without resolving the conflict.
131
+
132
+ <!-- bit-ci-sync:end -->
@@ -20,7 +20,10 @@ export declare function renderBitReleaseWorkflow(defaultBranch: string, wsDir?:
20
20
  export interface ScaffoldFileOutcome {
21
21
  /** relative to the workspace root, e.g. `.github/workflows/bit-sync.yml` */
22
22
  relativePath: string;
23
- status: 'written' | 'skipped';
23
+ /** `updated`: the file existed and `--init` added to it (the AGENTS.md sync section) */
24
+ status: 'written' | 'updated' | 'skipped';
25
+ /** what `--init` did, when the status alone does not say it */
26
+ note?: string;
24
27
  }
25
28
  /**
26
29
  * Scaffold both workflow files under `workspaceDir` (the repository root). `wsDir` is the bit workspace
@@ -61,7 +64,7 @@ export interface InitReportInput {
61
64
  repoHasCommits?: boolean;
62
65
  /** false when the workspace is not in a git repository yet: step 1 then starts with `git init` */
63
66
  inGitRepo?: boolean;
64
- /** scaffolded workflow files, with the path to show (relative to where the user stands) */
67
+ /** scaffolded files (the workflows, AGENTS.md), with the path to show (relative to where the user stands) */
65
68
  files: Array<ScaffoldFileOutcome & {
66
69
  displayPath: string;
67
70
  }>;
@@ -50,6 +50,13 @@ function _githubClient() {
50
50
  };
51
51
  return data;
52
52
  }
53
+ function _agentsMd() {
54
+ const data = require("./agents-md");
55
+ _agentsMd = function () {
56
+ return data;
57
+ };
58
+ return data;
59
+ }
53
60
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
54
61
  /**
55
62
  * `bit ci sync --init` — pure scaffolding logic, unit-testable without a live workspace/git checkout.
@@ -367,8 +374,17 @@ const SETUP_GUIDE_URL = 'https://github.com/teambit/acme-modular-store#set-it-up
367
374
  /** What each scaffolded file does, in the words the report shows next to it. */
368
375
  const FILE_PURPOSE = {
369
376
  [WORKFLOW_RELATIVE_PATHS.sync]: 'syncs lanes and branches: on export, on push, and every 30 minutes',
370
- [WORKFLOW_RELATIVE_PATHS.release]: 'releases the scope when a pull request merges'
377
+ [WORKFLOW_RELATIVE_PATHS.release]: 'releases the scope when a pull request merges',
378
+ [_agentsMd().AGENTS_MD_RELATIVE_PATH]: 'tells coding agents how the sync works in this repository'
371
379
  };
380
+
381
+ /** The note the report shows next to a file. */
382
+ function fileNote(file) {
383
+ if (file.note) return file.note;
384
+ if (file.status === 'written') return FILE_PURPOSE[file.relativePath] ?? '';
385
+ if (file.status === 'updated') return 'added the sync rules at the top';
386
+ return file.relativePath === _agentsMd().AGENTS_MD_RELATIVE_PATH ? 'already has the sync rules, left unchanged' : 'already exists, left unchanged';
387
+ }
372
388
  /**
373
389
  * A remote that is a path on this machine (a bare repository, a `file://` URL), not a server. It has
374
390
  * no host to suggest as a GitHub Enterprise Server. Git's own rule: a URL has a scheme, or is scp-like
@@ -458,7 +474,7 @@ function renderInitReport(input) {
458
474
  const header = [`${(0, _cli().successSymbol)()} ${(0, _cli().formatTitle)('Scaffolded bit ci sync')} for ${_chalk().default.cyan(scope)}, mirrored to ${target} ${(0, _cli().formatHint)(`(default branch: ${defaultBranch})`)}`];
459
475
  if (input.defaultBranchGuessed) {
460
476
  const why = input.originUrl ? "the remote didn't name its default branch" : 'no remote names the default branch';
461
- header.push((0, _cli().formatWarningSummary)(`${why}, so the workflows use "${defaultBranch}". If that's wrong,\n` + ` edit the branch filters in both workflow files.`));
477
+ header.push((0, _cli().formatWarningSummary)(`${why}, so the workflows and AGENTS.md use "${defaultBranch}". If that's wrong,\n` + ` edit the branch filters in both workflow files and the branch in the AGENTS.md sync section.`));
462
478
  }
463
479
  if (serverHost && unrecognizedOrigin) {
464
480
  header.push((0, _cli().formatWarningSummary)("origin isn't a GitHub remote bit recognizes. For GitHub Enterprise Server, run:"));
@@ -466,7 +482,7 @@ function renderInitReport(input) {
466
482
  }
467
483
  const width = Math.max(...input.files.map(f => f.displayPath.length), configDisplayPath.length) + 2;
468
484
  const fileItem = (displayPath, note) => (0, _cli().formatItem)(`${displayPath.padEnd(width)}${(0, _cli().formatHint)(note)}`);
469
- const files = [...input.files.map(file => fileItem(file.displayPath, file.status === 'written' ? FILE_PURPOSE[file.relativePath] ?? '' : 'already exists, left unchanged')), fileItem(configDisplayPath, input.configAdded ? 'added "teambit.git/ci": { "sync": {} }' : 'already configures sync, left unchanged')];
485
+ const files = [...input.files.map(file => fileItem(file.displayPath, fileNote(file))), fileItem(configDisplayPath, input.configAdded ? 'added "teambit.git/ci": { "sync": {} }' : 'already configures sync, left unchanged')];
470
486
  const step = (n, title, who, body) => [`${(0, _cli().formatTitle)(`${n}. ${title}`)} ${(0, _cli().formatHint)(`(${who})`)}`, ...body.map(line => ` ${line}`)].join('\n');
471
487
  const cmd = text => _chalk().default.cyan(text);
472
488
  // Stage and commit exactly what git shows as new or changed among the files `--init` handles, so
@@ -1 +1 @@
1
- {"version":3,"names":["_fs","data","_interopRequireDefault","require","_chalk","_cli","_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","WS_DIR_MARKER","substituteWsDir","wsDir","renderBitSyncWorkflow","renderBitReleaseWorkflow","writeIfAbsent","workspaceDir","relativePath","content","absPath","fs","existsSync","status","mkdirSync","dirname","recursive","writeFileSync","scaffoldWorkflowFiles","deriveOwnerRepo","remoteUrl","isGitHubRemote","undefined","ownerSlashRepo","parseGitHubRepo","host","remoteHost","owner","repo","split","WEBHOOK_PAYLOAD_TEMPLATE","BIT_GIT_SYNC_APP_URL","WEBHOOK_RELAY_SETUP_URL","SETUP_GUIDE_URL","FILE_PURPOSE","isLocalPathRemote","url","trim","test","redactRemoteUrl","escapeControlChars","c","charCodeAt","toString","padStart","shellQuote","chooseInitDefaultBranch","detected","current","suggestedServerUrl","URL","origin","renderInitReport","input","ownerRepo","scope","scopeId","redactedOrigin","originUrl","unrecognizedOrigin","serverHost","repoRootFromCwd","configDisplayPath","target","chalk","cyan","header","successSymbol","formatTitle","formatHint","defaultBranchGuessed","why","push","formatWarningSummary","width","Math","max","files","map","f","displayPath","length","fileItem","note","formatItem","padEnd","file","configAdded","step","n","title","who","body","line","cmd","text","firstCommit","repoHasCommits","toStage","ignored","quoted","paths","stage","gitInit","toCommit","nothingToCommit","commitMessage","commit","inGitRepo","steps","onGitHubCom","ghRepo","ghApi","api","gitHubApiUrl","dispatchUrl","yellow","error","footer","joinSections"],"sources":["init-scaffold.ts"],"sourcesContent":["import fs from 'fs';\nimport chalk from 'chalk';\nimport { formatHint, formatItem, formatTitle, formatWarningSummary, joinSections, successSymbol } from '@teambit/cli';\nimport path from 'path';\nimport { parseGitHubRepo, isGitHubRemote, gitHubApiUrl, remoteHost } 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 departures\n * are the two `DEFAULT_BRANCH_MARKER` substitution points and, for a workspace below the repository\n * root, the `WS_DIR_MARKER` line; everything else — CHANGE-ME comments, the placeholder action ref,\n * `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/** The commented-out `ws-dir` input, once in each template. */\nconst WS_DIR_MARKER = '# ws-dir: packages/my-workspace';\n\n/**\n * Set the action's `ws-dir` input when the workspace is below the repository root (`wsDir` is the\n * workspace directory relative to the root, `/`-separated). At the root, the line stays commented out.\n */\nfunction substituteWsDir(raw: string, wsDir: string | undefined): string {\n if (!wsDir || wsDir === '.') return raw;\n if (!raw.includes(WS_DIR_MARKER)) {\n throw new Error(`init-scaffold: expected marker \"${WS_DIR_MARKER}\" not found in its workflow template`);\n }\n return raw.replace(WS_DIR_MARKER, () => `ws-dir: ${yamlSingleQuoted(wsDir)}`);\n}\n\n/** Render `bit-sync.yml` with the repository's actual default branch, and `ws-dir` for a nested workspace. */\nexport function renderBitSyncWorkflow(defaultBranch: string, wsDir?: string): string {\n return substituteWsDir(\n substituteDefaultBranch(BIT_SYNC_WORKFLOW_RAW, DEFAULT_BRANCH_MARKER.sync, defaultBranch),\n wsDir\n );\n}\n\n/** Render `bit-release.yml` with the repository's actual default branch, and `ws-dir` for a nested workspace. */\nexport function renderBitReleaseWorkflow(defaultBranch: string, wsDir?: string): string {\n return substituteWsDir(\n substituteDefaultBranch(BIT_RELEASE_WORKFLOW_RAW, DEFAULT_BRANCH_MARKER.release, defaultBranch),\n wsDir\n );\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/**\n * Scaffold both workflow files under `workspaceDir` (the repository root). `wsDir` is the bit workspace\n * relative to it, when the workspace is a subdirectory. Never overwrites; creates `.github/workflows/`.\n */\nexport function scaffoldWorkflowFiles(\n workspaceDir: string,\n defaultBranch: string,\n wsDir?: string\n): ScaffoldFileOutcome[] {\n return [\n writeIfAbsent(workspaceDir, WORKFLOW_RELATIVE_PATHS.sync, renderBitSyncWorkflow(defaultBranch, wsDir)),\n writeIfAbsent(workspaceDir, WORKFLOW_RELATIVE_PATHS.release, renderBitReleaseWorkflow(defaultBranch, wsDir)),\n ];\n}\n\nexport interface OwnerRepo {\n owner: string;\n repo: string;\n /** The remote's host — github.com or the GITHUB_SERVER_URL one — which picks the API the checklist names. */\n host: 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 const host = remoteHost(remoteUrl);\n if (!ownerSlashRepo || !host) return undefined;\n const [owner, repo] = ownerSlashRepo.split('/');\n if (!owner || !repo) return undefined;\n return { owner, repo, host };\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. Used on GitHub Enterprise\n * Server, where the webhook posts straight to the repository's `dispatches` API with a token.\n */\nconst WEBHOOK_PAYLOAD_TEMPLATE =\n '{\"event_type\":\"bit-export\",\"client_payload\":{\"laneId\":\"{{laneId}}\",\"componentIds\":\"{{componentIds}}\",\"owner\":\"{{owner}}\",\"actor\":\"{{username}}\"}}';\n\n/**\n * On github.com, instant Bit -> Git goes through the hosted relay: the `bit-git-sync` GitHub App lets\n * it send `repository_dispatch` to the repositories it is installed on, and its setup page hands out\n * one webhook URL per repository. No personal token is involved.\n */\nconst BIT_GIT_SYNC_APP_URL = 'https://github.com/apps/bit-git-sync';\nconst WEBHOOK_RELAY_SETUP_URL = 'https://webhook-relay-gggmal.r2.composed.app/setup';\nconst SETUP_GUIDE_URL = 'https://github.com/teambit/acme-modular-store#set-it-up-for-your-own-scope';\n\n/** What each scaffolded file does, in the words the report shows next to it. */\nconst FILE_PURPOSE: Record<string, string> = {\n [WORKFLOW_RELATIVE_PATHS.sync]: 'syncs lanes and branches: on export, on push, and every 30 minutes',\n [WORKFLOW_RELATIVE_PATHS.release]: 'releases the scope when a pull request merges',\n};\n\nexport interface InitReportInput {\n /** the workspace's default scope, the one this repository mirrors */\n scopeId?: string;\n /** derived from the `origin` remote; undefined when there is none, or it isn't a recognized GitHub host */\n ownerRepo?: OwnerRepo;\n /** the raw `origin` URL, to name a remote that exists but isn't recognized as GitHub */\n originUrl?: string;\n defaultBranch: string;\n /** true when the remote didn't name its default branch and `defaultBranch` is a guess */\n defaultBranchGuessed?: boolean;\n /**\n * The repository root as seen from where the user stands (`.` when they stand in it). The workflows\n * live there, so the first commit and `gh repo create --source` must name it.\n */\n repoRootFromCwd?: string;\n /**\n * false when the repository has no commit yet. The first commit then takes the whole workspace;\n * after that, the commit takes only the files `--init` touched, never unrelated local changes.\n */\n repoHasCommits?: boolean;\n /** false when the workspace is not in a git repository yet: step 1 then starts with `git init` */\n inGitRepo?: boolean;\n /** scaffolded workflow files, with the path to show (relative to where the user stands) */\n files: Array<ScaffoldFileOutcome & { displayPath: string }>;\n /** workspace.jsonc, as seen from where the user stands */\n configDisplayPath?: string;\n /** whether `--init` added the sync block to workspace.jsonc, or found one already there */\n configAdded: boolean;\n /**\n * Of the workflow files and workspace.jsonc, the ones git shows as new or changed, as displayed.\n * Omitted: stage them all. Empty: nothing is left to commit (a re-run after the commit).\n */\n toStage?: string[];\n /**\n * Of those files, the untracked ones `.gitignore` matches, also before the first commit. `git add`\n * refuses them by name and `git add -A` skips them.\n */\n ignored?: string[];\n}\n\n/**\n * A remote that is a path on this machine (a bare repository, a `file://` URL), not a server. It has\n * no host to suggest as a GitHub Enterprise Server. Git's own rule: a URL has a scheme, or is scp-like\n * (`host:path`, with no slash before the first colon); anything else is a path, `remote.git` included.\n */\nexport function isLocalPathRemote(remoteUrl: string): boolean {\n const url = remoteUrl.trim();\n if (/^file:\\/\\//i.test(url)) return true;\n if (/^[a-z][a-z0-9+.-]*:\\/\\//i.test(url)) return false;\n // a Windows drive (`C:\\repos`) looks scp-like to the next check\n if (/^[a-z]:[/\\\\]/i.test(url)) return true;\n return !/^[^/\\\\]+:/.test(url);\n}\n\n/**\n * The remote URL without the credentials a URL can carry (`https://user:token@host/...`), so the\n * report never prints a token. An http(s) user name can itself be a token, so all of it goes; other\n * schemes keep the user name (`ssh://git@host`) and lose only a password.\n */\nexport function redactRemoteUrl(remoteUrl: string): string {\n const url = remoteUrl.trim();\n if (/^https?:\\/\\//i.test(url)) return url.replace(/^(https?:\\/\\/)[^@/]*@/i, '$1');\n return url.replace(/^([a-z][a-z0-9+.-]*:\\/\\/[^:@/]*):[^@/]*@/i, '$1@');\n}\n\n/** `value` with each control character written as `\\xNN`, so printing it cannot move or restyle the terminal. */\nexport function escapeControlChars(value: string): string {\n // eslint-disable-next-line no-control-regex\n return value.replace(/[\\u0000-\\u001f\\u007f-\\u009f]/g, (c) => `\\\\x${c.charCodeAt(0).toString(16).padStart(2, '0')}`);\n}\n\n/**\n * Quote a value for a POSIX shell, so a command the report prints runs as shown when pasted. Plain\n * names stay unquoted for readability; anything else is single-quoted. A git-valid branch such as\n * `$(id)` must not run as a command substitution.\n */\nexport function shellQuote(value: string): string {\n return /^[\\w./@:+-]+$/.test(value) ? value : `'${value.replace(/'/g, `'\\\\''`)}'`;\n}\n\n/**\n * The default branch `--init` writes into the workflows: the one the remote names, else a guess. The\n * guess is the checked-out branch only when it is `main` or `master`: a feature branch in the branch\n * filters would exclude itself from sync and point releases at the wrong base.\n */\nexport function chooseInitDefaultBranch(detected: string | undefined, current: string | undefined): string {\n if (detected) return detected;\n return current === 'main' || current === 'master' ? current : 'main';\n}\n\n/**\n * The `GITHUB_SERVER_URL` to suggest for a remote bit doesn't recognize: an http(s) remote's own origin,\n * port included, else https on the remote's host (an ssh port is not the web server's).\n */\nexport function suggestedServerUrl(remoteUrl: string): string {\n if (/^https?:\\/\\//i.test(remoteUrl.trim())) {\n try {\n return new URL(remoteUrl.trim()).origin;\n } catch {\n // fall through to the host\n }\n }\n return `https://${remoteHost(remoteUrl) ?? '<your-server>'}`;\n}\n\n/**\n * The report `bit ci sync --init` prints: what it changed, then the steps that need a person, as\n * commands to paste. Short by design; the setup guide carries the details. Commands are printed only\n * for a resolved repository: a placeholder would not run when pasted.\n */\nexport function renderInitReport(input: InitReportInput): string {\n const { ownerRepo, defaultBranch } = input;\n const scope = input.scopeId ?? '<scope>';\n // An origin that isn't recognized is most often a GitHub Enterprise Server the shell doesn't know about.\n const redactedOrigin = !ownerRepo && input.originUrl ? redactRemoteUrl(input.originUrl) : undefined;\n // Shown, so made inert: a control character (a newline, a terminal escape) must not reach the terminal.\n const unrecognizedOrigin = redactedOrigin && escapeControlChars(redactedOrigin);\n // Suggest a server only for a remote that names a host: a local path has none, and a URL with a\n // control character in it has no trustworthy one.\n const serverHost =\n redactedOrigin && redactedOrigin === unrecognizedOrigin && !isLocalPathRemote(redactedOrigin)\n ? remoteHost(redactedOrigin)\n : undefined;\n const repoRootFromCwd = input.repoRootFromCwd || '.';\n const configDisplayPath = input.configDisplayPath || 'workspace.jsonc';\n\n const target = ownerRepo\n ? chalk.cyan(\n ownerRepo.host === 'github.com'\n ? `${ownerRepo.owner}/${ownerRepo.repo}`\n : `${ownerRepo.host}/${ownerRepo.owner}/${ownerRepo.repo}`\n )\n : unrecognizedOrigin\n ? `origin ${unrecognizedOrigin}`\n : 'no GitHub remote yet';\n const header = [\n `${successSymbol()} ${formatTitle('Scaffolded bit ci sync')} for ${chalk.cyan(scope)}, mirrored to ${target} ${formatHint(\n `(default branch: ${defaultBranch})`\n )}`,\n ];\n if (input.defaultBranchGuessed) {\n const why = input.originUrl ? \"the remote didn't name its default branch\" : 'no remote names the default branch';\n header.push(\n formatWarningSummary(\n `${why}, so the workflows use \"${defaultBranch}\". If that's wrong,\\n` +\n ` edit the branch filters in both workflow files.`\n )\n );\n }\n if (serverHost && unrecognizedOrigin) {\n header.push(\n formatWarningSummary(\"origin isn't a GitHub remote bit recognizes. For GitHub Enterprise Server, run:\")\n );\n header.push(\n ` ${chalk.cyan(`GITHUB_SERVER_URL=${shellQuote(suggestedServerUrl(unrecognizedOrigin))} bit ci sync --init`)}`\n );\n }\n\n const width = Math.max(...input.files.map((f) => f.displayPath.length), configDisplayPath.length) + 2;\n const fileItem = (displayPath: string, note: string) => formatItem(`${displayPath.padEnd(width)}${formatHint(note)}`);\n const files = [\n ...input.files.map((file) =>\n fileItem(\n file.displayPath,\n file.status === 'written' ? (FILE_PURPOSE[file.relativePath] ?? '') : 'already exists, left unchanged'\n )\n ),\n fileItem(\n configDisplayPath,\n input.configAdded ? 'added \"teambit.git/ci\": { \"sync\": {} }' : 'already configures sync, left unchanged'\n ),\n ];\n\n const step = (n: number, title: string, who: string, body: string[]) =>\n [`${formatTitle(`${n}. ${title}`)} ${formatHint(`(${who})`)}`, ...body.map((line) => ` ${line}`)].join('\\n');\n const cmd = (text: string) => chalk.cyan(text);\n // Stage and commit exactly what git shows as new or changed among the files `--init` handles, so\n // unrelated local changes stay out: a re-run still stages files that were never committed, and a\n // file already committed is not named. The first commit of a new repository is the exception: it\n // must carry the whole workspace. `:/` stages from the repository root, where the workflows are,\n // when the workspace is a subdirectory.\n const firstCommit = input.repoHasCommits === false;\n const toStage = firstCommit ? [] : (input.toStage ?? [...input.files.map((f) => f.displayPath), configDisplayPath]);\n const ignored = input.ignored ?? [];\n const quoted = (paths: string[]) => paths.map(shellQuote).join(' ');\n const stage: string[] = [\n ...(firstCommit ? [cmd(repoRootFromCwd === '.' ? 'git add -A' : 'git add -A :/')] : []),\n ...(toStage.length ? [cmd(`git add -- ${quoted(toStage)}`)] : []),\n // `git add` skips or refuses a path that .gitignore matches, and GitHub runs only committed workflows\n ...(ignored.length\n ? [cmd(`git add -f -- ${quoted(ignored)}`), formatHint('.gitignore matches these; -f adds them anyway')]\n : []),\n ];\n // Commit and push are separate: on a re-run nothing may be left to commit, and the push must still run.\n // Naming the paths keeps changes the user staged before out of the commit.\n // `-b`: without init.defaultBranch, a bare `git init` makes `master`, a branch the workflows ignore\n const gitInit = `git init -b ${shellQuote(defaultBranch)}${repoRootFromCwd === '.' ? '' : ` ${shellQuote(repoRootFromCwd)}`}`;\n const toCommit = [...toStage, ...ignored];\n const nothingToCommit = !firstCommit && !toCommit.length;\n const commitMessage = `git commit -m ${shellQuote(`Mirror ${scope}`)}`;\n const commit = [\n ...(input.inGitRepo === false ? [cmd(gitInit)] : []),\n ...stage,\n ...(nothingToCommit\n ? [formatHint('nothing to commit: these files are already committed')]\n : firstCommit\n ? [cmd(commitMessage)]\n : // the paths go on a continuation line, as in the permissions command, to keep lines short\n [cmd(`${commitMessage} -- \\\\`), cmd(` ${quoted(toCommit)}`)]),\n ];\n\n const steps: string[] = [];\n if (!ownerRepo) {\n steps.push(\n unrecognizedOrigin\n ? step(1, 'Push it', 'you', [...commit, cmd('git push -u origin HEAD')])\n : step(1, 'Create the repository and push it', 'you', [\n ...commit,\n cmd(`gh repo create --private --source ${shellQuote(repoRootFromCwd)} --remote origin --push`),\n formatHint('names the repository after its root folder; add OWNER/NAME after \"create\" to choose'),\n ]),\n step(2, 'Run bit ci sync --init again', 'you', [\n 'Once origin is a GitHub remote bit recognizes, it prints the secret, permission and webhook',\n 'steps for your repository as commands.',\n ])\n );\n } else {\n const onGitHubCom = ownerRepo.host === 'github.com';\n const repo = `${ownerRepo.owner}/${ownerRepo.repo}`;\n // gh takes HOST/OWNER/REPO, or --hostname, for an enterprise server\n const ghRepo = shellQuote(onGitHubCom ? repo : `${ownerRepo.host}/${repo}`);\n const ghApi = onGitHubCom ? 'gh api' : `gh api --hostname ${shellQuote(ownerRepo.host)}`;\n steps.push(\n step(1, 'Push it', 'you', [...commit, cmd('git push -u origin HEAD')]),\n step(2, 'Let the workflows publish to bit.cloud and open pull requests', 'repository admin', [\n cmd(`gh secret set BIT_CONFIG_ACCESS_TOKEN -R ${ghRepo}`),\n formatHint(`a bit.cloud access token with Write permission on ${scope}. If your organization`),\n formatHint(\"requires change requests, exempt the token's account: it is the one that merges lanes.\"),\n cmd(`${ghApi} -X PUT ${shellQuote(`repos/${repo}/actions/permissions/workflow`)} \\\\`),\n cmd(' -f default_workflow_permissions=write -F can_approve_pull_request_reviews=true'),\n formatHint(\n 'turns on \"Read and write permissions\" and \"Allow GitHub Actions to create and approve pull requests\".'\n ),\n formatHint('If they are greyed out in the settings, an organization owner must allow them first.'),\n cmd(`gh secret set BIT_SYNC_GH_TOKEN -R ${ghRepo}`),\n formatHint('optional: a GitHub token, so the pushes the sync makes start your other workflows (CI checks)'),\n ])\n );\n if (onGitHubCom) {\n steps.push(\n step(3, 'Make Bit -> Git instant', 'organization admin, optional', [\n `Install ${chalk.cyan(BIT_GIT_SYNC_APP_URL)} on ${repo}.`,\n `Copy the repository's webhook URL from ${chalk.cyan(WEBHOOK_RELAY_SETUP_URL)}`,\n `and add it to ${scope} on bit.cloud as an \"Export succeeded\" webhook.`,\n ])\n );\n } else {\n const api = gitHubApiUrl(ownerRepo.host);\n const dispatchUrl = `${'error' in api ? '<GitHub API URL>' : api.url}/repos/${repo}/dispatches`;\n steps.push(\n step(3, 'Make Bit -> Git instant', 'optional', [\n `On bit.cloud, add an \"Export succeeded\" webhook to ${scope}:`,\n ` URL ${chalk.cyan(dispatchUrl)}`,\n ...('error' in api ? [chalk.yellow(` (${api.error})`)] : []),\n ' Headers Authorization: Bearer <token with access to this repository>',\n ' Accept: application/vnd.github+json',\n ` Payload ${WEBHOOK_PAYLOAD_TEMPLATE}`,\n formatHint('Create it fresh: editing a bit.cloud webhook drops its custom headers.'),\n ])\n );\n }\n }\n\n const footer = ownerRepo\n ? `After step 2 the sync runs on pushes to feature branches and every 30 minutes; step 3 adds instant Bit -> Git.\\nGuide: ${SETUP_GUIDE_URL}`\n : `Guide: ${SETUP_GUIDE_URL}`;\n return joinSections([\n header.join('\\n'),\n files.join('\\n'),\n [formatTitle(`Next: ${steps.length} steps to go live`), '', steps.join('\\n\\n')].join('\\n'),\n formatHint(footer),\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,OAAA;EAAA,MAAAH,IAAA,GAAAC,sBAAA,CAAAC,OAAA;EAAAC,MAAA,YAAAA,CAAA;IAAA,OAAAH,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AACA,SAAAI,KAAA;EAAA,MAAAJ,IAAA,GAAAE,OAAA;EAAAE,IAAA,YAAAA,CAAA;IAAA,OAAAJ,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AACA,SAAAK,MAAA;EAAA,MAAAL,IAAA,GAAAC,sBAAA,CAAAC,OAAA;EAAAG,KAAA,YAAAA,CAAA;IAAA,OAAAL,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AACA,SAAAM,cAAA;EAAA,MAAAN,IAAA,GAAAE,OAAA;EAAAI,aAAA,YAAAA,CAAA;IAAA,OAAAN,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAA4F,SAAAC,uBAAAM,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA;AAE5F;AACA;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,C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","ignoreList":[]}
1
+ {"version":3,"names":["_fs","data","_interopRequireDefault","require","_chalk","_cli","_path","_githubClient","_agentsMd","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","WS_DIR_MARKER","substituteWsDir","wsDir","renderBitSyncWorkflow","renderBitReleaseWorkflow","writeIfAbsent","workspaceDir","relativePath","content","absPath","fs","existsSync","status","mkdirSync","dirname","recursive","writeFileSync","scaffoldWorkflowFiles","deriveOwnerRepo","remoteUrl","isGitHubRemote","undefined","ownerSlashRepo","parseGitHubRepo","host","remoteHost","owner","repo","split","WEBHOOK_PAYLOAD_TEMPLATE","BIT_GIT_SYNC_APP_URL","WEBHOOK_RELAY_SETUP_URL","SETUP_GUIDE_URL","FILE_PURPOSE","AGENTS_MD_RELATIVE_PATH","fileNote","file","note","isLocalPathRemote","url","trim","test","redactRemoteUrl","escapeControlChars","c","charCodeAt","toString","padStart","shellQuote","chooseInitDefaultBranch","detected","current","suggestedServerUrl","URL","origin","renderInitReport","input","ownerRepo","scope","scopeId","redactedOrigin","originUrl","unrecognizedOrigin","serverHost","repoRootFromCwd","configDisplayPath","target","chalk","cyan","header","successSymbol","formatTitle","formatHint","defaultBranchGuessed","why","push","formatWarningSummary","width","Math","max","files","map","f","displayPath","length","fileItem","formatItem","padEnd","configAdded","step","n","title","who","body","line","cmd","text","firstCommit","repoHasCommits","toStage","ignored","quoted","paths","stage","gitInit","toCommit","nothingToCommit","commitMessage","commit","inGitRepo","steps","onGitHubCom","ghRepo","ghApi","api","gitHubApiUrl","dispatchUrl","yellow","error","footer","joinSections"],"sources":["init-scaffold.ts"],"sourcesContent":["import fs from 'fs';\nimport chalk from 'chalk';\nimport { formatHint, formatItem, formatTitle, formatWarningSummary, joinSections, successSymbol } from '@teambit/cli';\nimport path from 'path';\nimport { parseGitHubRepo, isGitHubRemote, gitHubApiUrl, remoteHost } from './github-client';\nimport { AGENTS_MD_RELATIVE_PATH } from './agents-md';\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 departures\n * are the two `DEFAULT_BRANCH_MARKER` substitution points and, for a workspace below the repository\n * root, the `WS_DIR_MARKER` line; everything else — CHANGE-ME comments, the placeholder action ref,\n * `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/** The commented-out `ws-dir` input, once in each template. */\nconst WS_DIR_MARKER = '# ws-dir: packages/my-workspace';\n\n/**\n * Set the action's `ws-dir` input when the workspace is below the repository root (`wsDir` is the\n * workspace directory relative to the root, `/`-separated). At the root, the line stays commented out.\n */\nfunction substituteWsDir(raw: string, wsDir: string | undefined): string {\n if (!wsDir || wsDir === '.') return raw;\n if (!raw.includes(WS_DIR_MARKER)) {\n throw new Error(`init-scaffold: expected marker \"${WS_DIR_MARKER}\" not found in its workflow template`);\n }\n return raw.replace(WS_DIR_MARKER, () => `ws-dir: ${yamlSingleQuoted(wsDir)}`);\n}\n\n/** Render `bit-sync.yml` with the repository's actual default branch, and `ws-dir` for a nested workspace. */\nexport function renderBitSyncWorkflow(defaultBranch: string, wsDir?: string): string {\n return substituteWsDir(\n substituteDefaultBranch(BIT_SYNC_WORKFLOW_RAW, DEFAULT_BRANCH_MARKER.sync, defaultBranch),\n wsDir\n );\n}\n\n/** Render `bit-release.yml` with the repository's actual default branch, and `ws-dir` for a nested workspace. */\nexport function renderBitReleaseWorkflow(defaultBranch: string, wsDir?: string): string {\n return substituteWsDir(\n substituteDefaultBranch(BIT_RELEASE_WORKFLOW_RAW, DEFAULT_BRANCH_MARKER.release, defaultBranch),\n wsDir\n );\n}\n\nexport interface ScaffoldFileOutcome {\n /** relative to the workspace root, e.g. `.github/workflows/bit-sync.yml` */\n relativePath: string;\n /** `updated`: the file existed and `--init` added to it (the AGENTS.md sync section) */\n status: 'written' | 'updated' | 'skipped';\n /** what `--init` did, when the status alone does not say it */\n note?: string;\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/**\n * Scaffold both workflow files under `workspaceDir` (the repository root). `wsDir` is the bit workspace\n * relative to it, when the workspace is a subdirectory. Never overwrites; creates `.github/workflows/`.\n */\nexport function scaffoldWorkflowFiles(\n workspaceDir: string,\n defaultBranch: string,\n wsDir?: string\n): ScaffoldFileOutcome[] {\n return [\n writeIfAbsent(workspaceDir, WORKFLOW_RELATIVE_PATHS.sync, renderBitSyncWorkflow(defaultBranch, wsDir)),\n writeIfAbsent(workspaceDir, WORKFLOW_RELATIVE_PATHS.release, renderBitReleaseWorkflow(defaultBranch, wsDir)),\n ];\n}\n\nexport interface OwnerRepo {\n owner: string;\n repo: string;\n /** The remote's host — github.com or the GITHUB_SERVER_URL one — which picks the API the checklist names. */\n host: 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 const host = remoteHost(remoteUrl);\n if (!ownerSlashRepo || !host) return undefined;\n const [owner, repo] = ownerSlashRepo.split('/');\n if (!owner || !repo) return undefined;\n return { owner, repo, host };\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. Used on GitHub Enterprise\n * Server, where the webhook posts straight to the repository's `dispatches` API with a token.\n */\nconst WEBHOOK_PAYLOAD_TEMPLATE =\n '{\"event_type\":\"bit-export\",\"client_payload\":{\"laneId\":\"{{laneId}}\",\"componentIds\":\"{{componentIds}}\",\"owner\":\"{{owner}}\",\"actor\":\"{{username}}\"}}';\n\n/**\n * On github.com, instant Bit -> Git goes through the hosted relay: the `bit-git-sync` GitHub App lets\n * it send `repository_dispatch` to the repositories it is installed on, and its setup page hands out\n * one webhook URL per repository. No personal token is involved.\n */\nconst BIT_GIT_SYNC_APP_URL = 'https://github.com/apps/bit-git-sync';\nconst WEBHOOK_RELAY_SETUP_URL = 'https://webhook-relay-gggmal.r2.composed.app/setup';\nconst SETUP_GUIDE_URL = 'https://github.com/teambit/acme-modular-store#set-it-up-for-your-own-scope';\n\n/** What each scaffolded file does, in the words the report shows next to it. */\nconst FILE_PURPOSE: Record<string, string> = {\n [WORKFLOW_RELATIVE_PATHS.sync]: 'syncs lanes and branches: on export, on push, and every 30 minutes',\n [WORKFLOW_RELATIVE_PATHS.release]: 'releases the scope when a pull request merges',\n [AGENTS_MD_RELATIVE_PATH]: 'tells coding agents how the sync works in this repository',\n};\n\n/** The note the report shows next to a file. */\nfunction fileNote(file: ScaffoldFileOutcome): string {\n if (file.note) return file.note;\n if (file.status === 'written') return FILE_PURPOSE[file.relativePath] ?? '';\n if (file.status === 'updated') return 'added the sync rules at the top';\n return file.relativePath === AGENTS_MD_RELATIVE_PATH\n ? 'already has the sync rules, left unchanged'\n : 'already exists, left unchanged';\n}\n\nexport interface InitReportInput {\n /** the workspace's default scope, the one this repository mirrors */\n scopeId?: string;\n /** derived from the `origin` remote; undefined when there is none, or it isn't a recognized GitHub host */\n ownerRepo?: OwnerRepo;\n /** the raw `origin` URL, to name a remote that exists but isn't recognized as GitHub */\n originUrl?: string;\n defaultBranch: string;\n /** true when the remote didn't name its default branch and `defaultBranch` is a guess */\n defaultBranchGuessed?: boolean;\n /**\n * The repository root as seen from where the user stands (`.` when they stand in it). The workflows\n * live there, so the first commit and `gh repo create --source` must name it.\n */\n repoRootFromCwd?: string;\n /**\n * false when the repository has no commit yet. The first commit then takes the whole workspace;\n * after that, the commit takes only the files `--init` touched, never unrelated local changes.\n */\n repoHasCommits?: boolean;\n /** false when the workspace is not in a git repository yet: step 1 then starts with `git init` */\n inGitRepo?: boolean;\n /** scaffolded files (the workflows, AGENTS.md), with the path to show (relative to where the user stands) */\n files: Array<ScaffoldFileOutcome & { displayPath: string }>;\n /** workspace.jsonc, as seen from where the user stands */\n configDisplayPath?: string;\n /** whether `--init` added the sync block to workspace.jsonc, or found one already there */\n configAdded: boolean;\n /**\n * Of the workflow files and workspace.jsonc, the ones git shows as new or changed, as displayed.\n * Omitted: stage them all. Empty: nothing is left to commit (a re-run after the commit).\n */\n toStage?: string[];\n /**\n * Of those files, the untracked ones `.gitignore` matches, also before the first commit. `git add`\n * refuses them by name and `git add -A` skips them.\n */\n ignored?: string[];\n}\n\n/**\n * A remote that is a path on this machine (a bare repository, a `file://` URL), not a server. It has\n * no host to suggest as a GitHub Enterprise Server. Git's own rule: a URL has a scheme, or is scp-like\n * (`host:path`, with no slash before the first colon); anything else is a path, `remote.git` included.\n */\nexport function isLocalPathRemote(remoteUrl: string): boolean {\n const url = remoteUrl.trim();\n if (/^file:\\/\\//i.test(url)) return true;\n if (/^[a-z][a-z0-9+.-]*:\\/\\//i.test(url)) return false;\n // a Windows drive (`C:\\repos`) looks scp-like to the next check\n if (/^[a-z]:[/\\\\]/i.test(url)) return true;\n return !/^[^/\\\\]+:/.test(url);\n}\n\n/**\n * The remote URL without the credentials a URL can carry (`https://user:token@host/...`), so the\n * report never prints a token. An http(s) user name can itself be a token, so all of it goes; other\n * schemes keep the user name (`ssh://git@host`) and lose only a password.\n */\nexport function redactRemoteUrl(remoteUrl: string): string {\n const url = remoteUrl.trim();\n if (/^https?:\\/\\//i.test(url)) return url.replace(/^(https?:\\/\\/)[^@/]*@/i, '$1');\n return url.replace(/^([a-z][a-z0-9+.-]*:\\/\\/[^:@/]*):[^@/]*@/i, '$1@');\n}\n\n/** `value` with each control character written as `\\xNN`, so printing it cannot move or restyle the terminal. */\nexport function escapeControlChars(value: string): string {\n // eslint-disable-next-line no-control-regex\n return value.replace(/[\\u0000-\\u001f\\u007f-\\u009f]/g, (c) => `\\\\x${c.charCodeAt(0).toString(16).padStart(2, '0')}`);\n}\n\n/**\n * Quote a value for a POSIX shell, so a command the report prints runs as shown when pasted. Plain\n * names stay unquoted for readability; anything else is single-quoted. A git-valid branch such as\n * `$(id)` must not run as a command substitution.\n */\nexport function shellQuote(value: string): string {\n return /^[\\w./@:+-]+$/.test(value) ? value : `'${value.replace(/'/g, `'\\\\''`)}'`;\n}\n\n/**\n * The default branch `--init` writes into the workflows: the one the remote names, else a guess. The\n * guess is the checked-out branch only when it is `main` or `master`: a feature branch in the branch\n * filters would exclude itself from sync and point releases at the wrong base.\n */\nexport function chooseInitDefaultBranch(detected: string | undefined, current: string | undefined): string {\n if (detected) return detected;\n return current === 'main' || current === 'master' ? current : 'main';\n}\n\n/**\n * The `GITHUB_SERVER_URL` to suggest for a remote bit doesn't recognize: an http(s) remote's own origin,\n * port included, else https on the remote's host (an ssh port is not the web server's).\n */\nexport function suggestedServerUrl(remoteUrl: string): string {\n if (/^https?:\\/\\//i.test(remoteUrl.trim())) {\n try {\n return new URL(remoteUrl.trim()).origin;\n } catch {\n // fall through to the host\n }\n }\n return `https://${remoteHost(remoteUrl) ?? '<your-server>'}`;\n}\n\n/**\n * The report `bit ci sync --init` prints: what it changed, then the steps that need a person, as\n * commands to paste. Short by design; the setup guide carries the details. Commands are printed only\n * for a resolved repository: a placeholder would not run when pasted.\n */\nexport function renderInitReport(input: InitReportInput): string {\n const { ownerRepo, defaultBranch } = input;\n const scope = input.scopeId ?? '<scope>';\n // An origin that isn't recognized is most often a GitHub Enterprise Server the shell doesn't know about.\n const redactedOrigin = !ownerRepo && input.originUrl ? redactRemoteUrl(input.originUrl) : undefined;\n // Shown, so made inert: a control character (a newline, a terminal escape) must not reach the terminal.\n const unrecognizedOrigin = redactedOrigin && escapeControlChars(redactedOrigin);\n // Suggest a server only for a remote that names a host: a local path has none, and a URL with a\n // control character in it has no trustworthy one.\n const serverHost =\n redactedOrigin && redactedOrigin === unrecognizedOrigin && !isLocalPathRemote(redactedOrigin)\n ? remoteHost(redactedOrigin)\n : undefined;\n const repoRootFromCwd = input.repoRootFromCwd || '.';\n const configDisplayPath = input.configDisplayPath || 'workspace.jsonc';\n\n const target = ownerRepo\n ? chalk.cyan(\n ownerRepo.host === 'github.com'\n ? `${ownerRepo.owner}/${ownerRepo.repo}`\n : `${ownerRepo.host}/${ownerRepo.owner}/${ownerRepo.repo}`\n )\n : unrecognizedOrigin\n ? `origin ${unrecognizedOrigin}`\n : 'no GitHub remote yet';\n const header = [\n `${successSymbol()} ${formatTitle('Scaffolded bit ci sync')} for ${chalk.cyan(scope)}, mirrored to ${target} ${formatHint(\n `(default branch: ${defaultBranch})`\n )}`,\n ];\n if (input.defaultBranchGuessed) {\n const why = input.originUrl ? \"the remote didn't name its default branch\" : 'no remote names the default branch';\n header.push(\n formatWarningSummary(\n `${why}, so the workflows and AGENTS.md use \"${defaultBranch}\". If that's wrong,\\n` +\n ` edit the branch filters in both workflow files and the branch in the AGENTS.md sync section.`\n )\n );\n }\n if (serverHost && unrecognizedOrigin) {\n header.push(\n formatWarningSummary(\"origin isn't a GitHub remote bit recognizes. For GitHub Enterprise Server, run:\")\n );\n header.push(\n ` ${chalk.cyan(`GITHUB_SERVER_URL=${shellQuote(suggestedServerUrl(unrecognizedOrigin))} bit ci sync --init`)}`\n );\n }\n\n const width = Math.max(...input.files.map((f) => f.displayPath.length), configDisplayPath.length) + 2;\n const fileItem = (displayPath: string, note: string) => formatItem(`${displayPath.padEnd(width)}${formatHint(note)}`);\n const files = [\n ...input.files.map((file) => fileItem(file.displayPath, fileNote(file))),\n fileItem(\n configDisplayPath,\n input.configAdded ? 'added \"teambit.git/ci\": { \"sync\": {} }' : 'already configures sync, left unchanged'\n ),\n ];\n\n const step = (n: number, title: string, who: string, body: string[]) =>\n [`${formatTitle(`${n}. ${title}`)} ${formatHint(`(${who})`)}`, ...body.map((line) => ` ${line}`)].join('\\n');\n const cmd = (text: string) => chalk.cyan(text);\n // Stage and commit exactly what git shows as new or changed among the files `--init` handles, so\n // unrelated local changes stay out: a re-run still stages files that were never committed, and a\n // file already committed is not named. The first commit of a new repository is the exception: it\n // must carry the whole workspace. `:/` stages from the repository root, where the workflows are,\n // when the workspace is a subdirectory.\n const firstCommit = input.repoHasCommits === false;\n const toStage = firstCommit ? [] : (input.toStage ?? [...input.files.map((f) => f.displayPath), configDisplayPath]);\n const ignored = input.ignored ?? [];\n const quoted = (paths: string[]) => paths.map(shellQuote).join(' ');\n const stage: string[] = [\n ...(firstCommit ? [cmd(repoRootFromCwd === '.' ? 'git add -A' : 'git add -A :/')] : []),\n ...(toStage.length ? [cmd(`git add -- ${quoted(toStage)}`)] : []),\n // `git add` skips or refuses a path that .gitignore matches, and GitHub runs only committed workflows\n ...(ignored.length\n ? [cmd(`git add -f -- ${quoted(ignored)}`), formatHint('.gitignore matches these; -f adds them anyway')]\n : []),\n ];\n // Commit and push are separate: on a re-run nothing may be left to commit, and the push must still run.\n // Naming the paths keeps changes the user staged before out of the commit.\n // `-b`: without init.defaultBranch, a bare `git init` makes `master`, a branch the workflows ignore\n const gitInit = `git init -b ${shellQuote(defaultBranch)}${repoRootFromCwd === '.' ? '' : ` ${shellQuote(repoRootFromCwd)}`}`;\n const toCommit = [...toStage, ...ignored];\n const nothingToCommit = !firstCommit && !toCommit.length;\n const commitMessage = `git commit -m ${shellQuote(`Mirror ${scope}`)}`;\n const commit = [\n ...(input.inGitRepo === false ? [cmd(gitInit)] : []),\n ...stage,\n ...(nothingToCommit\n ? [formatHint('nothing to commit: these files are already committed')]\n : firstCommit\n ? [cmd(commitMessage)]\n : // the paths go on a continuation line, as in the permissions command, to keep lines short\n [cmd(`${commitMessage} -- \\\\`), cmd(` ${quoted(toCommit)}`)]),\n ];\n\n const steps: string[] = [];\n if (!ownerRepo) {\n steps.push(\n unrecognizedOrigin\n ? step(1, 'Push it', 'you', [...commit, cmd('git push -u origin HEAD')])\n : step(1, 'Create the repository and push it', 'you', [\n ...commit,\n cmd(`gh repo create --private --source ${shellQuote(repoRootFromCwd)} --remote origin --push`),\n formatHint('names the repository after its root folder; add OWNER/NAME after \"create\" to choose'),\n ]),\n step(2, 'Run bit ci sync --init again', 'you', [\n 'Once origin is a GitHub remote bit recognizes, it prints the secret, permission and webhook',\n 'steps for your repository as commands.',\n ])\n );\n } else {\n const onGitHubCom = ownerRepo.host === 'github.com';\n const repo = `${ownerRepo.owner}/${ownerRepo.repo}`;\n // gh takes HOST/OWNER/REPO, or --hostname, for an enterprise server\n const ghRepo = shellQuote(onGitHubCom ? repo : `${ownerRepo.host}/${repo}`);\n const ghApi = onGitHubCom ? 'gh api' : `gh api --hostname ${shellQuote(ownerRepo.host)}`;\n steps.push(\n step(1, 'Push it', 'you', [...commit, cmd('git push -u origin HEAD')]),\n step(2, 'Let the workflows publish to bit.cloud and open pull requests', 'repository admin', [\n cmd(`gh secret set BIT_CONFIG_ACCESS_TOKEN -R ${ghRepo}`),\n formatHint(`a bit.cloud access token with Write permission on ${scope}. If your organization`),\n formatHint(\"requires change requests, exempt the token's account: it is the one that merges lanes.\"),\n cmd(`${ghApi} -X PUT ${shellQuote(`repos/${repo}/actions/permissions/workflow`)} \\\\`),\n cmd(' -f default_workflow_permissions=write -F can_approve_pull_request_reviews=true'),\n formatHint(\n 'turns on \"Read and write permissions\" and \"Allow GitHub Actions to create and approve pull requests\".'\n ),\n formatHint('If they are greyed out in the settings, an organization owner must allow them first.'),\n cmd(`gh secret set BIT_SYNC_GH_TOKEN -R ${ghRepo}`),\n formatHint('optional: a GitHub token, so the pushes the sync makes start your other workflows (CI checks)'),\n ])\n );\n if (onGitHubCom) {\n steps.push(\n step(3, 'Make Bit -> Git instant', 'organization admin, optional', [\n `Install ${chalk.cyan(BIT_GIT_SYNC_APP_URL)} on ${repo}.`,\n `Copy the repository's webhook URL from ${chalk.cyan(WEBHOOK_RELAY_SETUP_URL)}`,\n `and add it to ${scope} on bit.cloud as an \"Export succeeded\" webhook.`,\n ])\n );\n } else {\n const api = gitHubApiUrl(ownerRepo.host);\n const dispatchUrl = `${'error' in api ? '<GitHub API URL>' : api.url}/repos/${repo}/dispatches`;\n steps.push(\n step(3, 'Make Bit -> Git instant', 'optional', [\n `On bit.cloud, add an \"Export succeeded\" webhook to ${scope}:`,\n ` URL ${chalk.cyan(dispatchUrl)}`,\n ...('error' in api ? [chalk.yellow(` (${api.error})`)] : []),\n ' Headers Authorization: Bearer <token with access to this repository>',\n ' Accept: application/vnd.github+json',\n ` Payload ${WEBHOOK_PAYLOAD_TEMPLATE}`,\n formatHint('Create it fresh: editing a bit.cloud webhook drops its custom headers.'),\n ])\n );\n }\n }\n\n const footer = ownerRepo\n ? `After step 2 the sync runs on pushes to feature branches and every 30 minutes; step 3 adds instant Bit -> Git.\\nGuide: ${SETUP_GUIDE_URL}`\n : `Guide: ${SETUP_GUIDE_URL}`;\n return joinSections([\n header.join('\\n'),\n files.join('\\n'),\n [formatTitle(`Next: ${steps.length} steps to go live`), '', steps.join('\\n\\n')].join('\\n'),\n formatHint(footer),\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,OAAA;EAAA,MAAAH,IAAA,GAAAC,sBAAA,CAAAC,OAAA;EAAAC,MAAA,YAAAA,CAAA;IAAA,OAAAH,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AACA,SAAAI,KAAA;EAAA,MAAAJ,IAAA,GAAAE,OAAA;EAAAE,IAAA,YAAAA,CAAA;IAAA,OAAAJ,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AACA,SAAAK,MAAA;EAAA,MAAAL,IAAA,GAAAC,sBAAA,CAAAC,OAAA;EAAAG,KAAA,YAAAA,CAAA;IAAA,OAAAL,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AACA,SAAAM,cAAA;EAAA,MAAAN,IAAA,GAAAE,OAAA;EAAAI,aAAA,YAAAA,CAAA;IAAA,OAAAN,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AACA,SAAAO,UAAA;EAAA,MAAAP,IAAA,GAAAE,OAAA;EAAAK,SAAA,YAAAA,CAAA;IAAA,OAAAP,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAAsD,SAAAC,uBAAAO,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA;AAEtD;AACA;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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","ignoreList":[]}
@@ -1723,8 +1723,9 @@ function haltCommentBody({
1723
1723
  note
1724
1724
  }) {
1725
1725
  const resolution = note ?? `To resolve locally:
1726
- git fetch origin && git checkout ${shellQuote(branch)}
1726
+ git fetch origin && git checkout ${shellQuote(branch)} && git merge --ff-only ${shellQuote(`origin/${branch}`)}
1727
1727
  bit lane import ${shellQuote(laneId)}
1728
+ bit checkout head --manual --workspace-only # merges the lane's head into the files; conflicts get conflict markers
1728
1729
  # resolve conflicts, commit the result, then:
1729
1730
  git push origin ${shellQuote(branch)}`;
1730
1731
  return `bit-git-sync could not reconcile this branch automatically: ${reason}