release-it 19.0.0-next.4 → 19.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/test/npm.js CHANGED
@@ -9,19 +9,19 @@ import { mkTmpDir, getArgs } from './util/helpers.js';
9
9
  describe('npm', async () => {
10
10
  test('should return npm package url', async () => {
11
11
  const options = { npm: { name: 'my-cool-package' } };
12
- const npmClient = factory(npm, { options });
12
+ const npmClient = await factory(npm, { options });
13
13
  assert.equal(npmClient.getPackageUrl(), 'https://www.npmjs.com/package/my-cool-package');
14
14
  });
15
15
 
16
16
  test('should return npm package url (custom registry)', async () => {
17
17
  const options = { npm: { name: 'my-cool-package', publishConfig: { registry: 'https://registry.example.org/' } } };
18
- const npmClient = factory(npm, { options });
18
+ const npmClient = await factory(npm, { options });
19
19
  assert.equal(npmClient.getPackageUrl(), 'https://registry.example.org/package/my-cool-package');
20
20
  });
21
21
 
22
22
  test('should return npm package url (custom publicPath)', async () => {
23
23
  const options = { npm: { name: 'my-cool-package', publishConfig: { publicPath: '/custom/public-path' } } };
24
- const npmClient = factory(npm, { options });
24
+ const npmClient = await factory(npm, { options });
25
25
  assert.equal(npmClient.getPackageUrl(), 'https://www.npmjs.com/custom/public-path/my-cool-package');
26
26
  });
27
27
 
@@ -32,46 +32,46 @@ describe('npm', async () => {
32
32
  publishConfig: { registry: 'https://registry.example.org/', publicPath: '/custom/public-path' }
33
33
  }
34
34
  };
35
- const npmClient = factory(npm, { options });
35
+ const npmClient = await factory(npm, { options });
36
36
  assert.equal(npmClient.getPackageUrl(), 'https://registry.example.org/custom/public-path/my-cool-package');
37
37
  });
38
38
 
39
39
  test('should return default tag', async () => {
40
- const npmClient = factory(npm);
40
+ const npmClient = await factory(npm);
41
41
  const tag = await npmClient.resolveTag();
42
42
  assert.equal(tag, 'latest');
43
43
  });
44
44
 
45
45
  test('should resolve default tag for pre-release', async t => {
46
- const npmClient = factory(npm);
46
+ const npmClient = await factory(npm);
47
47
  t.mock.method(npmClient, 'getRegistryPreReleaseTags', () => []);
48
48
  const tag = await npmClient.resolveTag('1.0.0-0');
49
49
  assert.equal(tag, 'next');
50
50
  });
51
51
 
52
52
  test('should guess tag from registry for pre-release', async t => {
53
- const npmClient = factory(npm);
53
+ const npmClient = await factory(npm);
54
54
  t.mock.method(npmClient, 'getRegistryPreReleaseTags', () => ['alpha']);
55
55
  const tag = await npmClient.resolveTag('1.0.0-0');
56
56
  assert.equal(tag, 'alpha');
57
57
  });
58
58
 
59
59
  test('should derive tag from pre-release version', async () => {
60
- const npmClient = factory(npm);
60
+ const npmClient = await factory(npm);
61
61
  const tag = await npmClient.resolveTag('1.0.2-alpha.3');
62
62
  assert.equal(tag, 'alpha');
63
63
  });
64
64
 
65
65
  test('should use provided (default) tag even for pre-release', async t => {
66
66
  const options = { npm: { tag: 'latest' } };
67
- const npmClient = factory(npm, { options });
67
+ const npmClient = await factory(npm, { options });
68
68
  t.mock.method(npmClient.shell, 'exec', () => Promise.resolve());
69
69
  await npmClient.bump('1.0.0-next.0');
70
70
  assert.equal(npmClient.getContext('tag'), 'latest');
71
71
  });
72
72
 
73
73
  test('should throw when `npm version` fails', async t => {
74
- const npmClient = factory(npm);
74
+ const npmClient = await factory(npm);
75
75
  t.mock.method(npmClient.shell, 'exec', () =>
76
76
  Promise.reject(new Error('npm ERR! Version not changed, might want --allow-same-version'))
77
77
  );
@@ -79,14 +79,14 @@ describe('npm', async () => {
79
79
  });
80
80
 
81
81
  test('should return first pre-release tag from package in registry when resolving tag without pre-id', async t => {
82
- const npmClient = factory(npm);
82
+ const npmClient = await factory(npm);
83
83
  const response = { latest: '1.4.1', alpha: '2.0.0-alpha.1', beta: '2.0.0-beta.3' };
84
84
  t.mock.method(npmClient.shell, 'exec', () => Promise.resolve(JSON.stringify(response)));
85
85
  assert.equal(await npmClient.resolveTag('2.0.0-5'), 'alpha');
86
86
  });
87
87
 
88
88
  test('should return default pre-release tag when resolving tag without pre-id', async t => {
89
- const npmClient = factory(npm);
89
+ const npmClient = await factory(npm);
90
90
  const response = {
91
91
  latest: '1.4.1'
92
92
  };
@@ -95,19 +95,19 @@ describe('npm', async () => {
95
95
  });
96
96
 
97
97
  test('should handle erroneous output when resolving tag without pre-id', async t => {
98
- const npmClient = factory(npm);
98
+ const npmClient = await factory(npm);
99
99
  t.mock.method(npmClient.shell, 'exec', () => Promise.resolve(''));
100
100
  assert.equal(await npmClient.resolveTag('2.0.0-0'), 'next');
101
101
  });
102
102
 
103
103
  test('should handle errored request when resolving tag without pre-id', async t => {
104
- const npmClient = factory(npm);
104
+ const npmClient = await factory(npm);
105
105
  t.mock.method(npmClient.shell, 'exec', () => Promise.resolve());
106
106
  assert.equal(await npmClient.resolveTag('2.0.0-0'), 'next');
107
107
  });
108
108
 
109
109
  test('should add registry to commands when specified', async t => {
110
- const npmClient = factory(npm);
110
+ const npmClient = await factory(npm);
111
111
  npmClient.setContext({ publishConfig: { registry: 'registry.example.org' } });
112
112
  const exec = t.mock.method(npmClient.shell, 'exec', command => {
113
113
  if (command === 'npm whoami --registry registry.example.org') return Promise.resolve('john');
@@ -126,7 +126,7 @@ describe('npm', async () => {
126
126
  });
127
127
 
128
128
  test('should not throw when executing tasks', async t => {
129
- const npmClient = factory(npm);
129
+ const npmClient = await factory(npm);
130
130
  t.mock.method(npmClient.shell, 'exec', command => {
131
131
  if (command === 'npm whoami') return Promise.resolve('john');
132
132
  const re = /npm access (list collaborators --json|ls-collaborators) release-it/;
@@ -137,7 +137,7 @@ describe('npm', async () => {
137
137
  });
138
138
 
139
139
  test('should throw if npm is down', async t => {
140
- const npmClient = factory(npm);
140
+ const npmClient = await factory(npm);
141
141
  t.mock.method(npmClient.shell, 'exec', command => {
142
142
  if (command === 'npm ping') return Promise.reject();
143
143
  return Promise.resolve();
@@ -146,7 +146,7 @@ describe('npm', async () => {
146
146
  });
147
147
 
148
148
  test('should not throw if npm returns 400/404 for unsupported ping/whoami/access', async t => {
149
- const npmClient = factory(npm);
149
+ const npmClient = await factory(npm);
150
150
  const exec = t.mock.method(npmClient.shell, 'exec', () => Promise.resolve());
151
151
  const pingError = "npm ERR! code E404\nnpm ERR! 404 Package '--ping' not found : ping";
152
152
  const whoamiError = "npm ERR! code E404\nnpm ERR! 404 Package '--whoami' not found : whoami";
@@ -159,7 +159,7 @@ describe('npm', async () => {
159
159
  });
160
160
 
161
161
  test('should not throw if npm returns 400 for unsupported ping/whoami/access', async t => {
162
- const npmClient = factory(npm);
162
+ const npmClient = await factory(npm);
163
163
  const exec = t.mock.method(npmClient.shell, 'exec', () => Promise.resolve());
164
164
  const pingError = 'npm ERR! code E400\nnpm ERR! 400 Bad Request - GET https://npm.example.org/-/ping?write=true';
165
165
  const whoamiError = 'npm ERR! code E400\nnpm ERR! 400 Bad Request - GET https://npm.example.org/-/whoami';
@@ -172,14 +172,14 @@ describe('npm', async () => {
172
172
  });
173
173
 
174
174
  test('should throw if user is not authenticated', async t => {
175
- const npmClient = factory(npm);
175
+ const npmClient = await factory(npm);
176
176
  const exec = t.mock.method(npmClient.shell, 'exec', () => Promise.resolve());
177
177
  exec.mock.mockImplementationOnce(() => Promise.reject(), 1);
178
178
  await assert.rejects(runTasks(npmClient), { message: /^Not authenticated with npm/ });
179
179
  });
180
180
 
181
181
  test('should throw if user is not a collaborator (v9)', async t => {
182
- const npmClient = factory(npm);
182
+ const npmClient = await factory(npm);
183
183
  t.mock.method(npmClient.shell, 'exec', command => {
184
184
  if (command === 'npm whoami') return Promise.resolve('ada');
185
185
  if (command === 'npm --version') return Promise.resolve('9.2.0');
@@ -191,7 +191,7 @@ describe('npm', async () => {
191
191
  });
192
192
 
193
193
  test('should throw if user is not a collaborator (v8)', async t => {
194
- const npmClient = factory(npm);
194
+ const npmClient = await factory(npm);
195
195
 
196
196
  t.mock.method(npmClient.shell, 'exec', command => {
197
197
  if (command === 'npm whoami') return Promise.resolve('ada');
@@ -205,7 +205,7 @@ describe('npm', async () => {
205
205
  });
206
206
 
207
207
  test('should not throw if user is not a collaborator on a new package', async t => {
208
- const npmClient = factory(npm);
208
+ const npmClient = await factory(npm);
209
209
 
210
210
  t.mock.method(npmClient.shell, 'exec', command => {
211
211
  if (command === 'npm whoami') return Promise.resolve('ada');
@@ -220,7 +220,7 @@ describe('npm', async () => {
220
220
  });
221
221
 
222
222
  test('should handle 2FA and publish with OTP', async t => {
223
- const npmClient = factory(npm);
223
+ const npmClient = await factory(npm);
224
224
  npmClient.setContext({ name: 'pkg' });
225
225
 
226
226
  const exec = t.mock.method(npmClient.shell, 'exec');
@@ -247,7 +247,7 @@ describe('npm', async () => {
247
247
  });
248
248
 
249
249
  test('should publish', async t => {
250
- const npmClient = factory(npm);
250
+ const npmClient = await factory(npm);
251
251
  const exec = t.mock.method(npmClient.shell, 'exec', command => {
252
252
  if (command === 'npm whoami') return Promise.resolve('john');
253
253
  const re = /npm access (list collaborators --json|ls-collaborators) release-it/;
@@ -260,7 +260,7 @@ describe('npm', async () => {
260
260
 
261
261
  test('should use extra publish arguments', async t => {
262
262
  const options = { npm: { skipChecks: true, publishArgs: '--registry=http://my-internal-registry.local' } };
263
- const npmClient = factory(npm, { options });
263
+ const npmClient = await factory(npm, { options });
264
264
  const exec = t.mock.method(npmClient.shell, 'exec', () => Promise.resolve());
265
265
  await runTasks(npmClient);
266
266
  assert.equal(
@@ -271,7 +271,7 @@ describe('npm', async () => {
271
271
 
272
272
  test('should skip checks', async () => {
273
273
  const options = { npm: { skipChecks: true } };
274
- const npmClient = factory(npm, { options });
274
+ const npmClient = await factory(npm, { options });
275
275
  await assert.doesNotReject(npmClient.init());
276
276
  });
277
277
 
@@ -290,7 +290,7 @@ describe('npm', async () => {
290
290
  })
291
291
  );
292
292
  const options = { npm };
293
- const npmClient = factory(npm, { options });
293
+ const npmClient = await factory(npm, { options });
294
294
  const exec = t.mock.method(npmClient.shell, 'exec', command => {
295
295
  const cmd = 'npm whoami --registry https://gitlab.com/api/v4/projects/my-scope%2Fmy-pkg/packages/npm/';
296
296
  if (command === cmd) return Promise.resolve('john');
@@ -316,7 +316,7 @@ describe('npm', async () => {
316
316
  process.chdir(tmp);
317
317
  writeFileSync(join(tmp, 'package.json'), JSON.stringify({ name: '@my-scope/my-pkg', version: '1.0.0' }));
318
318
  const options = { npm };
319
- const npmClient = factory(npm, { options });
319
+ const npmClient = await factory(npm, { options });
320
320
 
321
321
  const exec = t.mock.method(npmClient.shell, 'exec', command => {
322
322
  if (command === 'npm whoami') return Promise.resolve('john');
@@ -340,7 +340,7 @@ describe('npm', async () => {
340
340
 
341
341
  test('should add allow-same-version argument', async t => {
342
342
  const options = { npm: { skipChecks: true, allowSameVersion: true } };
343
- const npmClient = factory(npm, { options });
343
+ const npmClient = await factory(npm, { options });
344
344
 
345
345
  const exec = t.mock.method(npmClient.shell, 'exec', () => Promise.resolve());
346
346
 
@@ -351,7 +351,7 @@ describe('npm', async () => {
351
351
 
352
352
  test('should add version arguments', async t => {
353
353
  const options = { npm: { skipChecks: true, versionArgs: ['--workspaces-update=false', '--allow-same-version'] } };
354
- const npmClient = factory(npm, { options });
354
+ const npmClient = await factory(npm, { options });
355
355
  const exec = t.mock.method(npmClient.shell, 'exec', () => Promise.resolve());
356
356
  await runTasks(npmClient);
357
357
  const versionArgs = getArgs(exec, 'npm version');
package/test/prompt.js CHANGED
@@ -17,7 +17,7 @@ test('should not create prompt if disabled', async t => {
17
17
  const task = t.mock.fn();
18
18
  const promptMock = t.mock.fn(yes);
19
19
  const inquirer = { prompt: promptMock };
20
- const prompt = factory(Prompt, { container: { inquirer } });
20
+ const prompt = await factory(Prompt, { container: { inquirer } });
21
21
  prompt.register(prompts.git);
22
22
  await prompt.show({ enabled: false, prompt: 'push', task });
23
23
  assert.equal(promptMock.mock.callCount(), 0);
@@ -27,7 +27,7 @@ test('should not create prompt if disabled', async t => {
27
27
  test('should create prompt', async t => {
28
28
  const promptMock = t.mock.fn(yes);
29
29
  const inquirer = { prompt: promptMock };
30
- const prompt = factory(Prompt, { container: { inquirer } });
30
+ const prompt = await factory(Prompt, { container: { inquirer } });
31
31
  prompt.register(prompts.git);
32
32
  await prompt.show({ prompt: 'push' });
33
33
  assert.equal(promptMock.mock.callCount(), 1);
@@ -57,9 +57,10 @@ test('should create prompt', async t => {
57
57
  git: { tagName: 'v${version}' },
58
58
  npm: { name: 'my-pkg', tag: 'next' }
59
59
  });
60
+ await config.init();
60
61
  config.setContext({ version: '1.0.0', tagName: '1.0.0' });
61
62
  const inquirer = { prompt: promptMock };
62
- const p = factory(Prompt, { container: { inquirer } });
63
+ const p = await factory(Prompt, { container: { inquirer } });
63
64
  p.register(prompts[namespace], namespace);
64
65
  await p.show({ namespace, prompt, context: config.getContext() });
65
66
  assert.equal(promptMock.mock.callCount(), 1);
@@ -71,7 +72,7 @@ test('should execute task after positive answer', async t => {
71
72
  const task = t.mock.fn();
72
73
  const promptMock = t.mock.fn(yes);
73
74
  const inquirer = { prompt: promptMock };
74
- const prompt = factory(Prompt, { container: { inquirer } });
75
+ const prompt = await factory(Prompt, { container: { inquirer } });
75
76
  prompt.register(prompts.git);
76
77
  await prompt.show({ prompt: 'push', task });
77
78
  assert.equal(promptMock.mock.callCount(), 1);
@@ -83,7 +84,7 @@ test('should not execute task after negative answer', async t => {
83
84
  const task = t.mock.fn();
84
85
  const promptMock = t.mock.fn(no);
85
86
  const inquirer = { prompt: promptMock };
86
- const prompt = factory(Prompt, { container: { inquirer } });
87
+ const prompt = await factory(Prompt, { container: { inquirer } });
87
88
  prompt.register(prompts.git);
88
89
  await prompt.show({ prompt: 'push', task });
89
90
  assert.equal(promptMock.mock.callCount(), 1);
package/test/shell.js CHANGED
@@ -4,10 +4,10 @@ import assert from 'node:assert/strict';
4
4
  import Shell from '../lib/shell.js';
5
5
  import { factory } from './util/index.js';
6
6
 
7
- describe('shell', () => {
7
+ describe('shell', async () => {
8
8
  const cwd = childProcess.execSync('pwd', { encoding: 'utf8' }).trim();
9
9
 
10
- const shell = factory(Shell);
10
+ const shell = await factory(Shell);
11
11
 
12
12
  test('exec', async () => {
13
13
  assert.equal(await shell.exec('echo bar'), 'bar');
@@ -29,7 +29,7 @@ describe('shell', () => {
29
29
  });
30
30
 
31
31
  test('exec (dry-run/read-only)', async () => {
32
- const shell = factory(Shell, { options: { 'dry-run': true } });
32
+ const shell = await factory(Shell, { options: { 'dry-run': true } });
33
33
  {
34
34
  const actual = await shell.exec('pwd', { write: false });
35
35
  assert.equal(actual, cwd);
@@ -46,7 +46,7 @@ describe('shell', () => {
46
46
  });
47
47
 
48
48
  test('exec (verbose)', async () => {
49
- const shell = factory(Shell, { options: { verbose: true } });
49
+ const shell = await factory(Shell, { options: { verbose: true } });
50
50
  const actual = await shell.exec('echo foo');
51
51
  assert.equal(shell.log.exec.mock.calls[0].arguments[0], 'echo foo');
52
52
  assert.equal(shell.log.exec.mock.callCount(), 1);
@@ -56,7 +56,7 @@ describe('shell', () => {
56
56
  });
57
57
 
58
58
  test('should cache results of command execution', async () => {
59
- const shell = factory(Shell);
59
+ const shell = await factory(Shell);
60
60
  const result1 = await shell.exec('echo foo');
61
61
  const result2 = await shell.exec('echo foo');
62
62
  assert(result1 === result2);
package/test/spinner.js CHANGED
@@ -3,12 +3,15 @@ import assert from 'node:assert/strict';
3
3
  import Spinner from '../lib/spinner.js';
4
4
  import Config from '../lib/config.js';
5
5
 
6
- const getConfig = options => {
6
+ const getConfig = async options => {
7
7
  const testConfig = {
8
8
  ci: false,
9
9
  config: false
10
10
  };
11
- return new Config(Object.assign({}, testConfig, options));
11
+ const config = new Config(Object.assign({}, testConfig, options));
12
+ await config.init();
13
+
14
+ return config;
12
15
  };
13
16
 
14
17
  test('should not show spinner and not execute task if disabled', async t => {
@@ -24,7 +27,7 @@ test('should show spinner and run task by default', async t => {
24
27
  const ora = t.mock.fn();
25
28
  const task = t.mock.fn(() => Promise.resolve());
26
29
  const label = 'foo';
27
- const config = getConfig({ ci: true });
30
+ const config = await getConfig({ ci: true });
28
31
  const spinner = new Spinner({ container: { ora, config } });
29
32
  await spinner.show({ task, label });
30
33
  assert.equal(task.mock.callCount(), 1);
@@ -36,7 +39,7 @@ test('should show spinner and run task by default', async t => {
36
39
  test('should run task, but not show spinner if interactive', async t => {
37
40
  const ora = t.mock.fn();
38
41
  const task = t.mock.fn(() => Promise.resolve());
39
- const config = getConfig({ ci: false });
42
+ const config = await getConfig({ ci: false });
40
43
  const spinner = new Spinner({ container: { ora, config } });
41
44
  await spinner.show({ task });
42
45
  assert.equal(task.mock.callCount(), 1);
@@ -46,7 +49,7 @@ test('should run task, but not show spinner if interactive', async t => {
46
49
  test('should run task and show spinner if interactive, but external', async t => {
47
50
  const ora = t.mock.fn();
48
51
  const task = t.mock.fn(() => Promise.resolve());
49
- const config = getConfig({ ci: false });
52
+ const config = await getConfig({ ci: false });
50
53
  const spinner = new Spinner({ container: { ora, config } });
51
54
  await spinner.show({ task, external: true });
52
55
  assert.equal(task.mock.callCount(), 1);
@@ -0,0 +1,5 @@
1
+ {
2
+ "git": {
3
+ "commitMessage": "Released version ${version}"
4
+ }
5
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "git": {
3
+ "commitMessage": "Released with version ${version}"
4
+ }
5
+ }
@@ -14,13 +14,10 @@ import { interceptPublish as interceptGitLabPublish } from './stub/gitlab.js';
14
14
  import { interceptCreate as interceptGitHubCreate } from './stub/github.js';
15
15
  import { factory, LogStub, SpinnerStub } from './util/index.js';
16
16
  import { mockFetch } from './util/mock.js';
17
+ import { createTarBlobByRawContents } from './util/fetch.js';
17
18
 
18
19
  describe('tasks.interactive', () => {
19
- const [mocker, github, gitlab, githubusercontent] = mockFetch([
20
- 'https://api.github.com',
21
- 'https://gitlab.com/api/v4',
22
- 'https://raw.githubusercontent.com'
23
- ]);
20
+ const [mocker, github, gitlab] = mockFetch(['https://api.github.com', 'https://gitlab.com/api/v4']);
24
21
 
25
22
  before(() => {
26
23
  mocker.mockGlobal();
@@ -96,18 +93,28 @@ describe('tasks.interactive', () => {
96
93
 
97
94
  const validationExtendedConfiguration = "echo 'extended_configuration'";
98
95
 
99
- githubusercontent.get('/release-it/release-it-configuration/HEAD/.release-it.json', {
96
+ github.head('/repos/release-it/release-it-configuration/tarball/main', {
100
97
  status: 200,
101
- body: {
102
- hooks: {
103
- 'before:init': validationExtendedConfiguration
104
- }
105
- }
98
+ headers: {}
99
+ });
100
+
101
+ github.get('/repos/release-it/release-it-configuration/tarball/main', {
102
+ status: 200,
103
+ body: await new Response(
104
+ createTarBlobByRawContents({
105
+ '.release-it.json': JSON.stringify({
106
+ hooks: {
107
+ 'before:init': validationExtendedConfiguration
108
+ }
109
+ })
110
+ })
111
+ ).arrayBuffer()
106
112
  });
107
113
 
108
114
  const config = {
109
- $schema: 'https://unpkg.com/release-it@18/schema/release-it.json',
110
- extends: 'github:release-it/release-it-configuration'
115
+ $schema: 'https://unpkg.com/release-it@19/schema/release-it.json',
116
+ extends: 'github:release-it/release-it-configuration',
117
+ config: true
111
118
  };
112
119
 
113
120
  const container = getContainer(config);
@@ -129,7 +136,7 @@ describe('tasks.interactive', () => {
129
136
  renameSync('.git', 'foo');
130
137
 
131
138
  const config = {
132
- $schema: 'https://unpkg.com/release-it@18/schema/release-it.json',
139
+ $schema: 'https://unpkg.com/release-it@19/schema/release-it.json',
133
140
  extends: false
134
141
  };
135
142
 
@@ -213,7 +220,7 @@ describe('tasks.interactive', () => {
213
220
  childProcess.execSync('git tag 1.0.0', execOpts);
214
221
  const sha = gitAdd('line', 'file', 'More file');
215
222
 
216
- const git = factory(Git);
223
+ const git = await factory(Git);
217
224
  const ref = (await git.getBranchName()) ?? 'HEAD';
218
225
 
219
226
  interceptGitHubCreate(github, {
package/test/tasks.js CHANGED
@@ -243,7 +243,7 @@ describe('tasks', () => {
243
243
  childProcess.execSync('git tag v1.0.0', execOpts);
244
244
  const sha = gitAdd('line', 'file', 'More file');
245
245
  childProcess.execSync('git push --follow-tags', execOpts);
246
- const git = factory(Git);
246
+ const git = await factory(Git);
247
247
  const ref = (await git.getBranchName()) ?? 'HEAD';
248
248
 
249
249
  interceptGitHubAuthentication(github);
@@ -0,0 +1,32 @@
1
+ import { Readable } from 'node:stream';
2
+ import { create as createTar } from 'tar';
3
+ import { appendFile, mkTmpDir } from './helpers.js';
4
+
5
+ export function createTarBlob(dir) {
6
+ const stream = new Readable({
7
+ read() {}
8
+ });
9
+
10
+ createTar(
11
+ {
12
+ gzip: true,
13
+ portable: true,
14
+ sync: false,
15
+ cwd: dir
16
+ },
17
+ ['.']
18
+ )
19
+ .on('data', chunk => stream.push(chunk))
20
+ .on('end', () => stream.push(null));
21
+
22
+ return stream;
23
+ }
24
+
25
+ export function createTarBlobByRawContents(contents) {
26
+ const dir = mkTmpDir();
27
+ for (const [key, value] of Object.entries(contents)) {
28
+ appendFile(value, key, dir);
29
+ }
30
+
31
+ return createTarBlob(dir);
32
+ }
@@ -12,13 +12,7 @@ const mkTmpDir = () => {
12
12
  const readFile = file => promises.readFile(path.resolve(file), 'utf8');
13
13
 
14
14
  const gitAdd = (content, filePath, message) => {
15
- const pathSegments = filePath.split('/').filter(Boolean);
16
- pathSegments.pop();
17
- if (pathSegments.length) {
18
- mkdirSync(path.resolve(pathSegments.join('/')), { mode: parseInt('0777', 8), recursive: true });
19
- }
20
-
21
- appendFileSync(filePath, content);
15
+ appendFile(content, filePath);
22
16
  childProcess.execSync(`git add ${filePath}`, execOpts);
23
17
  const stdout = childProcess.execSync(`git commit -m "${message}"`, { encoding: 'utf-8' });
24
18
  const match = stdout.match(/\[.+([a-z0-9]{7})\]/);
@@ -32,4 +26,15 @@ const getArgs = (fn, prefix) =>
32
26
  .filter(cmd => cmd.startsWith(prefix))
33
27
  .map(cmd => cmd.trim());
34
28
 
35
- export { mkTmpDir, readFile, gitAdd, getArgs };
29
+ const appendFile = (content, filePath, cwd) => {
30
+ filePath = path.resolve(cwd ?? '', filePath);
31
+ const dirPath = path.dirname(filePath);
32
+
33
+ if (dirPath) {
34
+ mkdirSync(dirPath, { mode: parseInt('0777', 8), recursive: true });
35
+ }
36
+
37
+ appendFileSync(filePath, content);
38
+ };
39
+
40
+ export { mkTmpDir, readFile, gitAdd, getArgs, appendFile };
@@ -36,11 +36,12 @@ export class SpinnerStub {
36
36
  }
37
37
  }
38
38
 
39
- export let factory = (Definition, { namespace, options = {}, container = {} } = {}) => {
39
+ export let factory = async (Definition, { namespace, options = {}, container = {} } = {}) => {
40
40
  options = Object.assign({}, { ci: true, verbose: false, 'dry-run': false, debug: false }, options);
41
41
  const ns = namespace || Definition.name.toLowerCase();
42
42
  container.config = container.config || new Config(Object.assign({ config: false }, options));
43
43
  container.log = new LogStub();
44
+ await container.config.init();
44
45
 
45
46
  container.spinner = new SpinnerStub();
46
47
  container.shell = container.shell || new ShellStub({ container });