@teambit/ci 1.0.631 → 1.0.633
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ci.docs.mdx +8 -0
- package/dist/ci.docs.mdx +8 -0
- package/dist/ci.main.runtime.js +5 -1
- package/dist/ci.main.runtime.js.map +1 -1
- package/dist/{preview-1792165397198.js → preview-1792187617108.js} +1 -1
- package/dist/source-branch-detector.d.ts +4 -2
- package/dist/source-branch-detector.js +44 -30
- package/dist/source-branch-detector.js.map +1 -1
- package/dist/source-branch-detector.spec.d.ts +1 -0
- package/dist/source-branch-detector.spec.js +141 -0
- package/dist/source-branch-detector.spec.js.map +1 -0
- package/dist/sync/git-host-provider.spec.js +28 -0
- package/dist/sync/git-host-provider.spec.js.map +1 -1
- package/dist/sync/github-client.d.ts +41 -5
- package/dist/sync/github-client.js +131 -20
- package/dist/sync/github-client.js.map +1 -1
- package/dist/sync/github-client.spec.js +351 -0
- package/dist/sync/github-client.spec.js.map +1 -1
- package/dist/sync/init-scaffold.d.ts +2 -0
- package/dist/sync/init-scaffold.js +7 -4
- package/dist/sync/init-scaffold.js.map +1 -1
- package/dist/sync/init-scaffold.spec.js +56 -10
- package/dist/sync/init-scaffold.spec.js.map +1 -1
- package/package.json +13 -13
- package/sync/git-host-provider.spec.ts +29 -0
- package/sync/github-client.spec.ts +334 -1
- package/sync/github-client.ts +130 -26
- package/sync/init-scaffold.spec.ts +62 -5
- package/sync/init-scaffold.ts +9 -4
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
deriveOwnerRepo,
|
|
12
12
|
renderInitChecklist,
|
|
13
13
|
} from './init-scaffold';
|
|
14
|
+
import type { OwnerRepo } from './init-scaffold';
|
|
14
15
|
|
|
15
16
|
const yamlLoad = (src: string) => YAML.parse(src);
|
|
16
17
|
|
|
@@ -99,10 +100,11 @@ describe('init-scaffold', () => {
|
|
|
99
100
|
});
|
|
100
101
|
|
|
101
102
|
describe('deriveOwnerRepo', () => {
|
|
102
|
-
const
|
|
103
|
-
|
|
104
|
-
['
|
|
105
|
-
['https://github.com/acme/shop',
|
|
103
|
+
const SHOP = { owner: 'acme', repo: 'shop', host: 'github.com' };
|
|
104
|
+
const REMOTES: Array<[string | undefined, OwnerRepo | undefined]> = [
|
|
105
|
+
['git@github.com:acme/shop.git', SHOP],
|
|
106
|
+
['https://github.com/acme/shop.git', SHOP],
|
|
107
|
+
['https://github.com/acme/shop', SHOP],
|
|
106
108
|
['https://gitlab.com/acme/shop.git', undefined],
|
|
107
109
|
// a local/bare remote has no host at all
|
|
108
110
|
['/path/to/bare.git', undefined],
|
|
@@ -117,12 +119,67 @@ describe('init-scaffold', () => {
|
|
|
117
119
|
|
|
118
120
|
describe('renderInitChecklist', () => {
|
|
119
121
|
it('renders a real dispatch URL when owner/repo were derived, a placeholder when not', () => {
|
|
120
|
-
const derived = renderInitChecklist({ owner: 'acme', repo: 'shop' });
|
|
122
|
+
const derived = renderInitChecklist({ owner: 'acme', repo: 'shop', host: 'github.com' });
|
|
121
123
|
expect(derived).to.contain('https://api.github.com/repos/acme/shop/dispatches');
|
|
122
124
|
expect(derived).to.not.contain('<owner>/<repo>');
|
|
123
125
|
expect(renderInitChecklist(undefined)).to.contain('https://api.github.com/repos/<owner>/<repo>/dispatches');
|
|
124
126
|
});
|
|
125
127
|
|
|
128
|
+
it('derives the repository and the dispatch URL from a GitHub Enterprise Server remote', () => {
|
|
129
|
+
const saved = { api: process.env.GITHUB_API_URL, server: process.env.GITHUB_SERVER_URL };
|
|
130
|
+
process.env.GITHUB_API_URL = 'https://ghe.corp.example/api/v3';
|
|
131
|
+
process.env.GITHUB_SERVER_URL = 'https://ghe.corp.example';
|
|
132
|
+
try {
|
|
133
|
+
const ownerRepo = deriveOwnerRepo('git@ghe.corp.example:acme/store.git');
|
|
134
|
+
expect(ownerRepo).to.deep.equal({ owner: 'acme', repo: 'store', host: 'ghe.corp.example' });
|
|
135
|
+
expect(renderInitChecklist(ownerRepo)).to.contain(
|
|
136
|
+
'https://ghe.corp.example/api/v3/repos/acme/store/dispatches'
|
|
137
|
+
);
|
|
138
|
+
} finally {
|
|
139
|
+
if (saved.api === undefined) delete process.env.GITHUB_API_URL;
|
|
140
|
+
else process.env.GITHUB_API_URL = saved.api;
|
|
141
|
+
if (saved.server === undefined) delete process.env.GITHUB_SERVER_URL;
|
|
142
|
+
else process.env.GITHUB_SERVER_URL = saved.server;
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
describe('on a GHES-configured runner', () => {
|
|
147
|
+
const saved: Record<string, string | undefined> = {};
|
|
148
|
+
beforeEach(() => {
|
|
149
|
+
saved.api = process.env.GITHUB_API_URL;
|
|
150
|
+
saved.server = process.env.GITHUB_SERVER_URL;
|
|
151
|
+
process.env.GITHUB_SERVER_URL = 'https://ghe.corp.example';
|
|
152
|
+
});
|
|
153
|
+
afterEach(() => {
|
|
154
|
+
if (saved.api === undefined) delete process.env.GITHUB_API_URL;
|
|
155
|
+
else process.env.GITHUB_API_URL = saved.api;
|
|
156
|
+
if (saved.server === undefined) delete process.env.GITHUB_SERVER_URL;
|
|
157
|
+
else process.env.GITHUB_SERVER_URL = saved.server;
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
it('names api.github.com for a github.com origin', () => {
|
|
161
|
+
process.env.GITHUB_API_URL = 'https://ghe.corp.example/api/v3';
|
|
162
|
+
const checklist = renderInitChecklist(deriveOwnerRepo('git@github.com:acme/shop.git'));
|
|
163
|
+
expect(checklist).to.contain('https://api.github.com/repos/acme/shop/dispatches');
|
|
164
|
+
expect(checklist).to.not.contain('ghe.corp.example');
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
it('derives <server>/api/v3 for an enterprise origin when GITHUB_API_URL is unset', () => {
|
|
168
|
+
delete process.env.GITHUB_API_URL;
|
|
169
|
+
expect(renderInitChecklist(deriveOwnerRepo('https://ghe.corp.example/acme/store.git'))).to.contain(
|
|
170
|
+
'https://ghe.corp.example/api/v3/repos/acme/store/dispatches'
|
|
171
|
+
);
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
it('names no API for an enterprise origin whose GITHUB_API_URL is on another host', () => {
|
|
175
|
+
process.env.GITHUB_API_URL = 'https://api.github.com';
|
|
176
|
+
const checklist = renderInitChecklist(deriveOwnerRepo('https://ghe.corp.example/acme/store.git'));
|
|
177
|
+
expect(checklist).to.contain('<GitHub API URL>/repos/acme/store/dispatches');
|
|
178
|
+
expect(checklist).to.contain('GITHUB_API_URL "https://api.github.com"');
|
|
179
|
+
expect(checklist).to.not.contain('https://api.github.com/repos');
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
|
|
126
183
|
it('always includes the secrets, permissions, webhook and fetch-depth checklist items', () => {
|
|
127
184
|
const checklist = renderInitChecklist(undefined);
|
|
128
185
|
[
|
package/sync/init-scaffold.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
|
-
import { parseGitHubRepo, isGitHubRemote } from './github-client';
|
|
3
|
+
import { parseGitHubRepo, isGitHubRemote, gitHubApiUrl, remoteHost } from './github-client';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* `bit ci sync --init` — pure scaffolding logic, unit-testable without a live workspace/git checkout.
|
|
@@ -273,6 +273,8 @@ export function scaffoldWorkflowFiles(workspaceDir: string, defaultBranch: strin
|
|
|
273
273
|
export interface OwnerRepo {
|
|
274
274
|
owner: string;
|
|
275
275
|
repo: string;
|
|
276
|
+
/** The remote's host — github.com or the GITHUB_SERVER_URL one — which picks the API the checklist names. */
|
|
277
|
+
host: string;
|
|
276
278
|
}
|
|
277
279
|
|
|
278
280
|
/**
|
|
@@ -283,10 +285,11 @@ export interface OwnerRepo {
|
|
|
283
285
|
export function deriveOwnerRepo(remoteUrl: string | undefined): OwnerRepo | undefined {
|
|
284
286
|
if (!remoteUrl || !isGitHubRemote(remoteUrl)) return undefined;
|
|
285
287
|
const ownerSlashRepo = parseGitHubRepo(remoteUrl);
|
|
286
|
-
|
|
288
|
+
const host = remoteHost(remoteUrl);
|
|
289
|
+
if (!ownerSlashRepo || !host) return undefined;
|
|
287
290
|
const [owner, repo] = ownerSlashRepo.split('/');
|
|
288
291
|
if (!owner || !repo) return undefined;
|
|
289
|
-
return { owner, repo };
|
|
292
|
+
return { owner, repo, host };
|
|
290
293
|
}
|
|
291
294
|
|
|
292
295
|
/**
|
|
@@ -302,7 +305,8 @@ const WEBHOOK_PAYLOAD_TEMPLATE =
|
|
|
302
305
|
*/
|
|
303
306
|
export function renderInitChecklist(ownerRepo: OwnerRepo | undefined): string {
|
|
304
307
|
const repoSegment = ownerRepo ? `${ownerRepo.owner}/${ownerRepo.repo}` : '<owner>/<repo>';
|
|
305
|
-
const
|
|
308
|
+
const api = gitHubApiUrl(ownerRepo?.host);
|
|
309
|
+
const dispatchUrl = `${'error' in api ? '<GitHub API URL>' : api.url}/repos/${repoSegment}/dispatches`;
|
|
306
310
|
return [
|
|
307
311
|
'',
|
|
308
312
|
'Remaining manual steps (bit ci sync --init only scaffolds files -- these need a human):',
|
|
@@ -322,6 +326,7 @@ export function renderInitChecklist(ownerRepo: OwnerRepo | undefined): string {
|
|
|
322
326
|
'3. bit.cloud webhook -- create ONE webhook (org Settings > Webhooks) on the "Components > Export',
|
|
323
327
|
' succeeded" event:',
|
|
324
328
|
` URL: ${dispatchUrl}`,
|
|
329
|
+
...('error' in api ? [` (${api.error})`] : []),
|
|
325
330
|
' Headers: Authorization: Bearer <PAT>',
|
|
326
331
|
' Accept: application/vnd.github+json',
|
|
327
332
|
' Custom payload template:',
|