release-it 19.0.0-next.1 → 19.0.0-next.3

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/gitlab.js CHANGED
@@ -1,7 +1,6 @@
1
1
  import fs from 'node:fs';
2
- import test from 'ava';
3
- import sinon from 'sinon';
4
- import nock from 'nock';
2
+ import test, { before, after, afterEach, beforeEach, describe } from 'node:test';
3
+ import assert from 'node:assert/strict';
5
4
  import { Agent } from 'undici';
6
5
  import Git from '../lib/plugin/git/Git.js';
7
6
  import GitLab from '../lib/plugin/gitlab/GitLab.js';
@@ -13,405 +12,444 @@ import {
13
12
  interceptPublish,
14
13
  interceptAsset,
15
14
  interceptAssetGeneric,
16
- interceptMilestones
15
+ interceptMilestones,
16
+ interceptMembers
17
17
  } from './stub/gitlab.js';
18
+ import { mockFetch } from './util/mock.js';
18
19
 
19
- const tokenHeader = 'Private-Token';
20
- const tokenRef = 'GITLAB_TOKEN';
20
+ describe('GitLab', () => {
21
+ const tokenHeader = 'Private-Token';
22
+ const tokenRef = 'GITLAB_TOKEN';
23
+ const certificateAuthorityFileRef = 'CI_SERVER_TLS_CA_FILE';
21
24
 
22
- test.serial('should validate token', async t => {
23
- const tokenRef = 'MY_GITLAB_TOKEN';
24
- const pushRepo = 'https://gitlab.com/user/repo';
25
- const options = { gitlab: { release: true, tokenRef, tokenHeader, pushRepo } };
26
- const gitlab = factory(GitLab, { options });
27
- delete process.env[tokenRef];
25
+ const [mocker, api, example, local] = mockFetch([
26
+ 'https://gitlab.com/api/v4',
27
+ 'https://gitlab.example.org/api/v4',
28
+ 'https://localhost:3000/api/v4'
29
+ ]);
28
30
 
29
- await t.throwsAsync(gitlab.init(), {
30
- message: /^Environment variable "MY_GITLAB_TOKEN" is required for GitLab releases/
31
+ before(() => {
32
+ mocker.mockGlobal();
31
33
  });
32
- process.env[tokenRef] = '123';
33
34
 
34
- interceptUser(undefined, { reqheaders: { 'private-token': '123' } });
35
- interceptCollaborator(undefined, { reqheaders: { 'private-token': '123' } });
36
- await t.notThrowsAsync(gitlab.init());
37
- });
35
+ let originalEnv;
36
+ beforeEach(() => {
37
+ originalEnv = process.env;
38
+ process.env = { ...originalEnv };
38
39
 
39
- test.serial('should support CI Job token header', async t => {
40
- const tokenRef = 'CI_JOB_TOKEN';
41
- const tokenHeader = 'Job-Token';
42
- process.env[tokenRef] = 'j0b-t0k3n';
43
- const pushRepo = 'https://gitlab.com/user/repo';
44
- const options = { git: { pushRepo }, gitlab: { release: true, tokenRef, tokenHeader } };
45
- const gitlab = factory(GitLab, { options });
40
+ process.env[tokenRef] = '123';
41
+ });
46
42
 
47
- interceptPublish(undefined, { reqheaders: { 'job-token': '1' } });
43
+ afterEach(() => {
44
+ if (originalEnv !== undefined) process.env = originalEnv;
45
+ mocker.clearAll();
46
+ });
48
47
 
49
- await t.notThrowsAsync(gitlab.init());
48
+ after(() => {
49
+ mocker.unmockGlobal();
50
+ });
50
51
 
51
- delete process.env[tokenRef];
52
- });
52
+ test('should validate token', async () => {
53
+ const tokenRef = 'MY_GITLAB_TOKEN';
54
+ const pushRepo = 'https://gitlab.com/user/repo';
55
+ const options = { gitlab: { release: true, tokenRef, tokenHeader, pushRepo } };
56
+ const gitlab = factory(GitLab, { options });
57
+ delete process.env[tokenRef];
53
58
 
54
- test.serial('should upload assets and release', async t => {
55
- const pushRepo = 'https://gitlab.com/user/repo';
56
- const options = {
57
- git: { pushRepo },
58
- gitlab: {
59
- tokenRef,
60
- release: true,
61
- releaseName: 'Release ${version}',
62
- releaseNotes: 'echo Custom notes',
63
- assets: 'test/resources/file-v${version}.txt',
64
- milestones: ['${version}', '${latestVersion} UAT']
65
- }
66
- };
67
- const gitlab = factory(GitLab, { options });
68
- sinon.stub(gitlab, 'getLatestVersion').resolves('2.0.0');
69
-
70
- const git = factory(Git);
71
- const ref = (await git.getBranchName()) ?? 'HEAD';
72
-
73
- interceptUser();
74
- interceptCollaborator();
75
- interceptMilestones({
76
- query: { title: '2.0.1' },
77
- milestones: [
78
- {
79
- id: 17,
80
- iid: 3,
81
- title: '2.0.1'
82
- }
83
- ]
59
+ await assert.rejects(gitlab.init(), /Environment variable "MY_GITLAB_TOKEN" is required for GitLab releases/);
60
+
61
+ process.env[tokenRef] = '123';
62
+
63
+ interceptUser(api, { headers: { 'private-token': '123' } });
64
+ interceptCollaborator(api, { headers: { 'private-token': '123' } });
65
+ await assert.doesNotReject(gitlab.init());
84
66
  });
85
- interceptMilestones({
86
- query: { title: '2.0.0 UAT' },
87
- milestones: [
88
- {
89
- id: 42,
90
- iid: 4,
91
- title: '2.0.0 UAT'
92
- }
93
- ]
67
+
68
+ test('should support CI Job token header', async () => {
69
+ const tokenRef = 'CI_JOB_TOKEN';
70
+ const tokenHeader = 'Job-Token';
71
+ process.env[tokenRef] = 'j0b-t0k3n';
72
+ const pushRepo = 'https://gitlab.com/user/repo';
73
+ const options = { git: { pushRepo }, gitlab: { release: true, tokenRef, tokenHeader } };
74
+ const gitlab = factory(GitLab, { options });
75
+
76
+ interceptPublish(api, { headers: { 'job-token': '1' } });
77
+
78
+ await assert.doesNotReject(gitlab.init());
79
+
80
+ delete process.env[tokenRef];
94
81
  });
95
- interceptAsset();
96
- interceptPublish({
97
- body: {
98
- name: 'Release 2.0.1',
99
- ref,
100
- tag_name: '2.0.1',
101
- tag_message: 'Release 2.0.1',
102
- description: 'Custom notes',
103
- assets: {
104
- links: [
105
- {
106
- name: 'file-v2.0.1.txt',
107
- url: `${pushRepo}/uploads/7e8bec1fe27cc46a4bc6a91b9e82a07c/file-v2.0.1.txt`
108
- }
109
- ]
110
- },
111
- milestones: ['2.0.1', '2.0.0 UAT']
112
- }
82
+
83
+ test('should upload assets and release', async t => {
84
+ const pushRepo = 'https://gitlab.com/user/repo';
85
+ const options = {
86
+ git: { pushRepo },
87
+ gitlab: {
88
+ tokenRef,
89
+ release: true,
90
+ releaseName: 'Release ${version}',
91
+ releaseNotes: 'echo Custom notes',
92
+ assets: 'test/resources/file-v${version}.txt',
93
+ milestones: ['${version}', '${latestVersion} UAT']
94
+ }
95
+ };
96
+ const gitlab = factory(GitLab, { options });
97
+ t.mock.method(gitlab, 'getLatestVersion', () => Promise.resolve('2.0.0'));
98
+
99
+ const git = factory(Git);
100
+ const ref = (await git.getBranchName()) ?? 'HEAD';
101
+
102
+ interceptUser(api);
103
+ interceptCollaborator(api);
104
+ interceptMilestones(api, { query: { title: '2.0.1' }, milestones: [{ id: 17, iid: 3, title: '2.0.1' }] });
105
+ interceptMilestones(api, { query: { title: '2.0.0 UAT' }, milestones: [{ id: 42, iid: 4, title: '2.0.0 UAT' }] });
106
+ interceptAsset(api);
107
+ interceptPublish(api, {
108
+ body: {
109
+ name: 'Release 2.0.1',
110
+ ref,
111
+ tag_name: '2.0.1',
112
+ tag_message: 'Release 2.0.1',
113
+ description: 'Custom notes',
114
+ assets: {
115
+ links: [
116
+ { name: 'file-v2.0.1.txt', url: `${pushRepo}/uploads/7e8bec1fe27cc46a4bc6a91b9e82a07c/file-v2.0.1.txt` }
117
+ ]
118
+ },
119
+ milestones: ['2.0.1', '2.0.0 UAT']
120
+ }
121
+ });
122
+
123
+ await runTasks(gitlab);
124
+
125
+ assert.equal(gitlab.assets[0].url, `${pushRepo}/uploads/7e8bec1fe27cc46a4bc6a91b9e82a07c/file-v2.0.1.txt`);
126
+ const { isReleased, releaseUrl } = gitlab.getContext();
127
+ assert(isReleased);
128
+ assert.equal(releaseUrl, `${pushRepo}/-/releases/2.0.1`);
113
129
  });
114
130
 
115
- await runTasks(gitlab);
131
+ test('should upload assets with ID-based URLs', async t => {
132
+ const host = 'https://gitlab.com';
133
+ const pushRepo = `${host}/user/repo`;
134
+ const options = {
135
+ git: { pushRepo },
136
+ gitlab: {
137
+ tokenRef,
138
+ release: true,
139
+ assets: 'test/resources/file-v${version}.txt',
140
+ useIdsForUrls: true
141
+ }
142
+ };
116
143
 
117
- t.is(gitlab.assets[0].url, `${pushRepo}/uploads/7e8bec1fe27cc46a4bc6a91b9e82a07c/file-v2.0.1.txt`);
118
- const { isReleased, releaseUrl } = gitlab.getContext();
119
- t.true(isReleased);
120
- t.is(releaseUrl, `${pushRepo}/-/releases/2.0.1`);
121
- });
144
+ const gitlab = factory(GitLab, { options });
145
+ t.mock.method(gitlab, 'getLatestVersion', () => Promise.resolve('2.0.0'));
122
146
 
123
- test.serial('should upload assets with ID-based URLs too', async t => {
124
- const host = 'https://gitlab.com';
125
- const pushRepo = `${host}/user/repo`;
126
- const options = {
127
- git: { pushRepo },
128
- gitlab: {
129
- tokenRef,
130
- release: true,
131
- assets: 'test/resources/file-v${version}.txt',
132
- useIdsForUrls: true
133
- }
134
- };
135
- const gitlab = factory(GitLab, { options });
136
- sinon.stub(gitlab, 'getLatestVersion').resolves('2.0.0');
137
-
138
- interceptUser();
139
- interceptCollaborator();
140
- interceptAsset();
141
- interceptPublish();
142
-
143
- await runTasks(gitlab);
144
-
145
- t.is(gitlab.assets[0].url, `${host}/-/project/1234/uploads/7e8bec1fe27cc46a4bc6a91b9e82a07c/file-v2.0.1.txt`);
146
- });
147
+ interceptUser(api);
148
+ interceptCollaborator(api);
149
+ interceptAsset(api);
150
+ interceptPublish(api);
147
151
 
148
- test.serial('should upload assets to generic repo', async t => {
149
- const host = 'https://gitlab.com';
150
- const pushRepo = `${host}/user/repo`;
151
- const options = {
152
- git: { pushRepo },
153
- gitlab: {
154
- tokenRef,
155
- release: true,
156
- assets: 'test/resources/file-v${version}.txt',
157
- useGenericPackageRepositoryForAssets: true,
158
- genericPackageRepositoryName: 'release-it'
159
- }
160
- };
161
- const gitlab = factory(GitLab, { options });
162
- sinon.stub(gitlab, 'getLatestVersion').resolves('2.0.0');
163
-
164
- interceptUser();
165
- interceptCollaborator();
166
- interceptAssetGeneric();
167
- interceptPublish();
168
-
169
- await runTasks(gitlab);
170
-
171
- t.is(gitlab.assets[0].url, `${host}/api/v4/projects/user%2Frepo/packages/generic/release-it/2.0.1/file-v2.0.1.txt`);
172
- });
152
+ await runTasks(gitlab);
153
+
154
+ assert.equal(
155
+ gitlab.assets[0].url,
156
+ `${host}/-/project/1234/uploads/7e8bec1fe27cc46a4bc6a91b9e82a07c/file-v2.0.1.txt`
157
+ );
158
+ });
173
159
 
174
- test.serial('should throw when release milestone is missing', async t => {
175
- const pushRepo = 'https://gitlab.com/user/repo';
176
- const options = {
177
- git: { pushRepo },
178
- gitlab: {
179
- tokenRef,
180
- release: true,
181
- milestones: ['${version}', '${latestVersion} UAT']
182
- }
183
- };
184
- const gitlab = factory(GitLab, { options });
185
- sinon.stub(gitlab, 'getLatestVersion').resolves('2.0.0');
186
-
187
- interceptUser();
188
- interceptCollaborator();
189
- interceptMilestones({
190
- query: { title: '2.0.1' },
191
- milestones: [
192
- {
193
- id: 17,
194
- iid: 3,
195
- title: '2.0.1'
160
+ test('should upload assets to generic repo', async t => {
161
+ const host = 'https://gitlab.com';
162
+ const pushRepo = `${host}/user/repo`;
163
+ const options = {
164
+ git: { pushRepo },
165
+ gitlab: {
166
+ tokenRef,
167
+ release: true,
168
+ assets: 'test/resources/file-v${version}.txt',
169
+ useGenericPackageRepositoryForAssets: true,
170
+ genericPackageRepositoryName: 'release-it'
196
171
  }
197
- ]
172
+ };
173
+ const gitlab = factory(GitLab, { options });
174
+ t.mock.method(gitlab, 'getLatestVersion', () => Promise.resolve('2.0.0'));
175
+
176
+ interceptUser(api);
177
+ interceptCollaborator(api);
178
+ interceptAssetGeneric(api);
179
+ interceptPublish(api);
180
+
181
+ await runTasks(gitlab);
182
+
183
+ assert.equal(
184
+ gitlab.assets[0].url,
185
+ `${host}/api/v4/projects/user%2Frepo/packages/generic/release-it/2.0.1/file-v2.0.1.txt`
186
+ );
198
187
  });
199
- interceptMilestones({
200
- query: { title: '2.0.0 UAT' },
201
- milestones: []
188
+
189
+ test('should throw when release milestone is missing', async t => {
190
+ const pushRepo = 'https://gitlab.com/user/repo';
191
+ const options = {
192
+ git: { pushRepo },
193
+ gitlab: {
194
+ tokenRef,
195
+ release: true,
196
+ milestones: ['${version}', '${latestVersion} UAT']
197
+ }
198
+ };
199
+ const gitlab = factory(GitLab, { options });
200
+ t.mock.method(gitlab, 'getLatestVersion', () => Promise.resolve('2.0.0'));
201
+
202
+ interceptUser(api);
203
+ interceptCollaborator(api);
204
+ interceptMilestones(api, { query: { title: '2.0.1' }, milestones: [{ id: 17, iid: 3, title: '2.0.1' }] });
205
+ interceptMilestones(api, { query: { title: '2.0.0 UAT' }, milestones: [] });
206
+
207
+ await assert.rejects(
208
+ runTasks(gitlab),
209
+ /Missing one or more milestones in GitLab. Creating a GitLab release will fail./
210
+ );
202
211
  });
203
212
 
204
- await t.throwsAsync(runTasks(gitlab), {
205
- message: /^Missing one or more milestones in GitLab. Creating a GitLab release will fail./
213
+ test('should release to self-managed host', async t => {
214
+ const host = 'https://gitlab.example.org';
215
+ const options = {
216
+ git: { pushRepo: `${host}/user/repo` },
217
+ gitlab: { releaseName: 'Release ${version}', releaseNotes: 'echo readme', tokenRef }
218
+ };
219
+ const gitlab = factory(GitLab, { options });
220
+ t.mock.method(gitlab, 'getLatestVersion', () => Promise.resolve('1.0.0'));
221
+
222
+ interceptUser(example);
223
+ interceptCollaborator(example);
224
+ interceptPublish(example);
225
+
226
+ await runTasks(gitlab);
227
+
228
+ const { origin, baseUrl } = gitlab.getContext();
229
+ assert.equal(origin, host);
230
+ assert.equal(baseUrl, `${host}/api/v4`);
206
231
  });
207
- });
208
232
 
209
- test.serial('should release to self-managed host', async t => {
210
- const host = 'https://gitlab.example.org';
211
- const scope = nock(host);
212
- scope.post('/api/v4/projects/user%2Frepo/releases').reply(200, {});
213
- const options = {
214
- git: { pushRepo: `${host}/user/repo` },
215
- gitlab: { releaseName: 'Release ${version}', releaseNotes: 'echo readme', tokenRef }
216
- };
217
- const gitlab = factory(GitLab, { options });
218
- sinon.stub(gitlab, 'getLatestVersion').resolves('1.0.0');
219
-
220
- interceptUser({ host });
221
- interceptCollaborator({ host });
222
-
223
- await runTasks(gitlab);
224
-
225
- const { origin, baseUrl } = gitlab.getContext();
226
- t.is(origin, host);
227
- t.is(baseUrl, `${host}/api/v4`);
228
- });
233
+ test('should release to sub-grouped repo', async () => {
234
+ const options = { gitlab: { tokenRef }, git: { pushRepo: 'git@gitlab.com:group/sub-group/repo.git' } };
235
+ const gitlab = factory(GitLab, { options });
229
236
 
230
- test.serial('should release to sub-grouped repo', async t => {
231
- const scope = nock('https://gitlab.com');
232
- scope.post('/api/v4/projects/group%2Fsub-group%2Frepo/releases').reply(200, {});
233
- const options = { gitlab: { tokenRef }, git: { pushRepo: 'git@gitlab.com:group/sub-group/repo.git' } };
234
- const gitlab = factory(GitLab, { options });
237
+ interceptUser(api, { owner: 'sub-group' });
238
+ interceptCollaborator(api, { owner: 'sub-group', group: 'group' });
239
+ interceptPublish(api, { owner: 'group', project: 'sub-group%2Frepo' });
235
240
 
236
- interceptUser({ owner: 'sub-group' });
237
- interceptCollaborator({ owner: 'sub-group', group: 'group' });
241
+ await runTasks(gitlab);
238
242
 
239
- await runTasks(gitlab);
243
+ const { isReleased, releaseUrl } = gitlab.getContext();
244
+ assert(isReleased);
245
+ assert.match(releaseUrl, /https:\/\/gitlab.com\/group\/sub-group(\/|%2F)repo\/-\/releases\//);
246
+ });
240
247
 
241
- const { isReleased, releaseUrl } = gitlab.getContext();
242
- t.true(isReleased);
243
- t.regex(releaseUrl, /https:\/\/gitlab.com\/group\/sub-group\/repo\/-\/releases\//);
244
- });
248
+ test('should throw for unauthenticated user', async () => {
249
+ const host = 'https://gitlab.com';
250
+ const pushRepo = `${host}/user/repo`;
251
+ const options = { gitlab: { tokenRef, pushRepo, host } };
252
+ const gitlab = factory(GitLab, { options });
245
253
 
246
- test.serial('should throw for unauthenticated user', async t => {
247
- const host = 'https://gitlab.com';
248
- const pushRepo = `${host}/user/repo`;
249
- const options = { gitlab: { tokenRef, pushRepo, host } };
250
- const gitlab = factory(GitLab, { options });
251
- const scope = nock(host);
252
- scope.get(`/api/v4/user`).reply(401);
254
+ api.get('/user', { status: 401 });
253
255
 
254
- await t.throwsAsync(runTasks(gitlab), {
255
- message: /^Could not authenticate with GitLab using environment variable "GITLAB_TOKEN"/
256
+ await assert.rejects(
257
+ runTasks(gitlab),
258
+ /Could not authenticate with GitLab using environment variable "GITLAB_TOKEN"/
259
+ );
256
260
  });
257
- });
258
261
 
259
- test.serial('should throw for non-collaborator', async t => {
260
- const host = 'https://gitlab.com';
261
- const pushRepo = `${host}/john/repo`;
262
- const options = { gitlab: { tokenRef, pushRepo, host } };
263
- const gitlab = factory(GitLab, { options });
264
- const scope = nock(host);
265
- scope.get(`/api/v4/projects/john%2Frepo/members/all/1`).reply(200, { username: 'emma' });
266
- interceptUser({ owner: 'john' });
262
+ test('should throw for non-collaborator', async () => {
263
+ const host = 'https://gitlab.com';
264
+ const pushRepo = `${host}/john/repo`;
265
+ const options = { gitlab: { tokenRef, pushRepo, host } };
266
+ const gitlab = factory(GitLab, { options });
267
267
 
268
- await t.throwsAsync(runTasks(gitlab), { message: /^User john is not a collaborator for john\/repo/ });
269
- });
268
+ interceptMembers(api, { owner: 'emma' });
269
+ interceptUser(api, { owner: 'john' });
270
270
 
271
- test.serial('should throw for insufficient access level', async t => {
272
- const host = 'https://gitlab.com';
273
- const pushRepo = `${host}/john/repo`;
274
- const options = { gitlab: { tokenRef, pushRepo, host } };
275
- const gitlab = factory(GitLab, { options });
276
- const scope = nock(host);
277
- scope.get(`/api/v4/projects/john%2Frepo/members/all/1`).reply(200, { username: 'john', access_level: 10 });
278
- interceptUser({ owner: 'john' });
271
+ await assert.rejects(runTasks(gitlab), /User john is not a collaborator for john\/repo/);
272
+ });
279
273
 
280
- await t.throwsAsync(runTasks(gitlab), { message: /^User john is not a collaborator for john\/repo/ });
281
- });
274
+ test('should throw for insufficient access level', async () => {
275
+ const host = 'https://gitlab.com';
276
+ const pushRepo = `${host}/john/repo`;
277
+ const options = { gitlab: { tokenRef, pushRepo, host } };
278
+ const gitlab = factory(GitLab, { options });
282
279
 
283
- test('should not make requests in dry run', async t => {
284
- const [host, owner, repo] = ['https://gitlab.example.org', 'user', 'repo'];
285
- const pushRepo = `${host}/${owner}/${repo}`;
286
- const options = { 'dry-run': true, git: { pushRepo }, gitlab: { releaseName: 'R', tokenRef } };
287
- const gitlab = factory(GitLab, { options });
288
- sinon.stub(gitlab, 'getLatestVersion').resolves('1.0.0');
280
+ interceptMembers(api, { owner: 'john', access_level: 10 });
281
+ interceptUser(api, { owner: 'john' });
289
282
 
290
- await runTasks(gitlab);
283
+ await assert.rejects(runTasks(gitlab), /User john is not a collaborator for john\/repo/);
284
+ });
291
285
 
292
- const { isReleased, releaseUrl } = gitlab.getContext();
286
+ test('should not make requests in dry run', async t => {
287
+ const [host, owner, repo] = ['https://gitlab.example.org', 'user', 'repo'];
288
+ const pushRepo = `${host}/${owner}/${repo}`;
289
+ const options = { 'dry-run': true, git: { pushRepo }, gitlab: { releaseName: 'R', tokenRef } };
290
+ const gitlab = factory(GitLab, { options });
291
+ t.mock.method(gitlab, 'getLatestVersion', () => Promise.resolve('1.0.0'));
293
292
 
294
- t.is(gitlab.log.exec.args[2][0], 'gitlab releases#uploadAssets');
295
- t.is(gitlab.log.exec.args[3][0], 'gitlab releases#createRelease "R" (1.0.1)');
296
- t.true(isReleased);
297
- t.is(releaseUrl, `${pushRepo}/-/releases/1.0.1`);
298
- });
293
+ await runTasks(gitlab);
299
294
 
300
- test('should skip checks', async t => {
301
- const options = { gitlab: { tokenRef, skipChecks: true, release: true, milestones: ['v1.0.0'] } };
302
- const gitlab = factory(GitLab, { options });
295
+ const { isReleased, releaseUrl } = gitlab.getContext();
303
296
 
304
- await t.notThrowsAsync(gitlab.init());
305
- await t.notThrowsAsync(gitlab.beforeRelease());
297
+ assert.equal(gitlab.log.exec.mock.calls[2].arguments[0], 'gitlab releases#uploadAssets');
298
+ assert.equal(gitlab.log.exec.mock.calls[3].arguments[0], 'gitlab releases#createRelease "R" (1.0.1)');
299
+ assert(isReleased);
300
+ assert.equal(releaseUrl, `${pushRepo}/-/releases/1.0.1`);
301
+ });
306
302
 
307
- t.is(gitlab.log.exec.args.filter(entry => /checkReleaseMilestones/.test(entry[0])).length, 0);
308
- });
303
+ test('should skip checks', async () => {
304
+ const options = { gitlab: { tokenRef, skipChecks: true, release: true, milestones: ['v1.0.0'] } };
305
+ const gitlab = factory(GitLab, { options });
309
306
 
310
- test.serial('should not create fetch agent', t => {
311
- const options = { gitlab: {} };
312
- const gitlab = factory(GitLab, { options });
307
+ await assert.doesNotReject(gitlab.init());
308
+ await assert.doesNotReject(gitlab.beforeRelease());
313
309
 
314
- t.deepEqual(gitlab.certificateAuthorityOption, {});
315
- });
310
+ assert.equal(
311
+ gitlab.log.exec.mock.calls
312
+ .flatMap(call => call.arguments)
313
+ .filter(entry => /checkReleaseMilestones/.test(entry[0])).length,
314
+ 0
315
+ );
316
+ });
316
317
 
317
- test.serial('should create fetch agent if secure == false', t => {
318
- const options = { gitlab: { secure: false } };
319
- const gitlab = factory(GitLab, { options });
320
- const { dispatcher } = gitlab.certificateAuthorityOption;
318
+ test('should not create fetch agent', () => {
319
+ const options = { gitlab: {} };
320
+ const gitlab = factory(GitLab, { options });
321
321
 
322
- t.true(dispatcher instanceof Agent, "Fetch dispatcher should be an instance of undici's Agent class");
322
+ assert.deepEqual(gitlab.certificateAuthorityOption, {});
323
+ });
323
324
 
324
- const kOptions = Object.getOwnPropertySymbols(dispatcher).find(symbol => symbol.description === 'options');
325
- t.deepEqual(dispatcher[kOptions].connect, { rejectUnauthorized: false, ca: undefined });
326
- });
325
+ test('should create fetch agent if secure == false', () => {
326
+ const options = { gitlab: { secure: false } };
327
+ const gitlab = factory(GitLab, { options });
328
+ const { dispatcher } = gitlab.certificateAuthorityOption;
327
329
 
328
- test.serial('should create fetch agent if certificateAuthorityFile', t => {
329
- const sandbox = sinon.createSandbox();
330
- sandbox.stub(fs, 'readFileSync').returns('test certificate');
330
+ assert(dispatcher instanceof Agent, "Fetch dispatcher should be an instance of undici's Agent class");
331
331
 
332
- const options = { gitlab: { certificateAuthorityFile: 'cert.crt' } };
333
- const gitlab = factory(GitLab, { options });
334
- const { dispatcher } = gitlab.certificateAuthorityOption;
332
+ const kOptions = Object.getOwnPropertySymbols(dispatcher).find(symbol => symbol.description === 'options');
333
+ assert.deepEqual(dispatcher[kOptions].connect, { rejectUnauthorized: false, ca: undefined });
334
+ });
335
335
 
336
- t.true(dispatcher instanceof Agent, "Fetch dispatcher should be an instance of undici's Agent class");
336
+ test('should create fetch agent if certificateAuthorityFile', t => {
337
+ const readFileSync = t.mock.method(fs, 'readFileSync', () => 'test certificate');
337
338
 
338
- const kOptions = Object.getOwnPropertySymbols(dispatcher).find(symbol => symbol.description === 'options');
339
- t.deepEqual(dispatcher[kOptions].connect, { rejectUnauthorized: undefined, ca: 'test certificate' });
339
+ const options = { gitlab: { certificateAuthorityFile: 'cert.crt' } };
340
+ const gitlab = factory(GitLab, { options });
341
+ const { dispatcher } = gitlab.certificateAuthorityOption;
340
342
 
341
- sandbox.restore();
342
- });
343
+ assert(dispatcher instanceof Agent, "Fetch dispatcher should be an instance of undici's Agent class");
343
344
 
344
- test.serial('should throw for insecure connections to self-hosted instances', async t => {
345
- const host = 'https://localhost:3000';
345
+ const kOptions = Object.getOwnPropertySymbols(dispatcher).find(symbol => symbol.description === 'options');
346
+ assert.deepEqual(dispatcher[kOptions].connect, { rejectUnauthorized: undefined, ca: 'test certificate' });
347
+
348
+ readFileSync.mock.restore();
349
+ });
346
350
 
347
- const options = {
348
- git: { pushRepo: `${host}/user/repo` },
349
- gitlab: { host, tokenRef, origin: host }
350
- };
351
- const gitlab = factory(GitLab, { options });
352
- const server = new GitlabTestServer();
351
+ test('should create fetch agent if CI_SERVER_TLS_CA_FILE env is set', t => {
352
+ const readFileSync = t.mock.method(fs, 'readFileSync', () => 'test certificate');
353
+ process.env[certificateAuthorityFileRef] = 'ca.crt';
353
354
 
354
- t.teardown(async () => {
355
- nock.disableNetConnect();
356
- await server.stop();
355
+ const options = { gitlab: {} };
356
+ const gitlab = factory(GitLab, { options });
357
+ const { dispatcher } = gitlab.certificateAuthorityOption;
358
+
359
+ assert(dispatcher instanceof Agent, "Fetch dispatcher should be an instance of undici's Agent class");
360
+
361
+ const kOptions = Object.getOwnPropertySymbols(dispatcher).find(symbol => symbol.description === 'options');
362
+ assert.deepEqual(dispatcher[kOptions].connect, { rejectUnauthorized: undefined, ca: 'test certificate' });
363
+
364
+ readFileSync.mock.restore();
357
365
  });
358
366
 
359
- await server.run();
360
- nock.enableNetConnect();
367
+ test('should create fetch agent if certificateAuthorityFileRef env is set', t => {
368
+ const readFileSync = t.mock.method(fs, 'readFileSync', () => 'test certificate');
369
+ process.env['GITLAB_CA_FILE'] = 'custom-ca.crt';
370
+
371
+ const options = { gitlab: { certificateAuthorityFileRef: 'GITLAB_CA_FILE' } };
372
+ const gitlab = factory(GitLab, { options });
373
+ const { dispatcher } = gitlab.certificateAuthorityOption;
361
374
 
362
- await t.throwsAsync(gitlab.init(), {
363
- message: /^Could not authenticate with GitLab using environment variable "GITLAB_TOKEN"/
375
+ assert(dispatcher instanceof Agent, "Fetch dispatcher should be an instance of undici's Agent class");
376
+
377
+ const kOptions = Object.getOwnPropertySymbols(dispatcher).find(symbol => symbol.description === 'options');
378
+ assert.deepEqual(dispatcher[kOptions].connect, { rejectUnauthorized: undefined, ca: 'test certificate' });
379
+
380
+ readFileSync.mock.restore();
364
381
  });
365
- });
366
382
 
367
- test.serial('should succesfully connect to self-hosted instance if insecure connection allowed', async t => {
368
- const host = 'https://localhost:3000';
369
-
370
- const options = {
371
- git: { pushRepo: `${host}/user/repo` },
372
- gitlab: {
373
- host,
374
- tokenRef,
375
- origin: host,
376
- secure: false
377
- }
378
- };
379
- const gitlab = factory(GitLab, { options });
380
- const server = new GitlabTestServer();
381
-
382
- t.teardown(async () => {
383
- nock.disableNetConnect();
384
- await server.stop();
383
+ test('should throw for insecure connections to self-hosted instances', async t => {
384
+ const host = 'https://localhost:3000';
385
+
386
+ const options = {
387
+ git: { pushRepo: `${host}/user/repo` },
388
+ gitlab: { host, tokenRef, origin: host }
389
+ };
390
+ const gitlab = factory(GitLab, { options });
391
+ const server = new GitlabTestServer();
392
+
393
+ t.after(async () => {
394
+ await server.stop();
395
+ });
396
+
397
+ await server.run();
398
+
399
+ await assert.rejects(gitlab.init(), /Could not authenticate with GitLab using environment variable "GITLAB_TOKEN"/);
385
400
  });
386
401
 
387
- await server.run();
388
- nock.enableNetConnect();
402
+ test('should succesfully connect to self-hosted instance if insecure connection allowed', async t => {
403
+ const host = 'https://localhost:3000';
389
404
 
390
- await t.notThrowsAsync(gitlab.init());
391
- });
405
+ const options = {
406
+ git: { pushRepo: `${host}/user/repo` },
407
+ gitlab: {
408
+ host,
409
+ tokenRef,
410
+ origin: host,
411
+ secure: false
412
+ }
413
+ };
414
+ const gitlab = factory(GitLab, { options });
415
+ const server = new GitlabTestServer();
392
416
 
393
- test.serial('should succesfully connect to self-hosted instance with valid CA file', async t => {
394
- const host = 'https://localhost:3000';
395
-
396
- const options = {
397
- git: { pushRepo: `${host}/user/repo` },
398
- gitlab: {
399
- host,
400
- tokenRef,
401
- origin: host,
402
- certificateAuthorityFile: 'test/util/https-server/client/my-private-root-ca.cert.pem'
403
- }
404
- };
405
- const gitlab = factory(GitLab, { options });
406
- const server = new GitlabTestServer();
407
-
408
- t.teardown(async () => {
409
- nock.disableNetConnect();
410
- await server.stop();
417
+ t.after(async () => {
418
+ await server.stop();
419
+ });
420
+
421
+ await server.run();
422
+
423
+ interceptUser(local);
424
+ interceptCollaborator(local);
425
+
426
+ await assert.doesNotReject(gitlab.init());
411
427
  });
412
428
 
413
- await server.run();
414
- nock.enableNetConnect();
429
+ test('should succesfully connect to self-hosted instance with valid CA file', async t => {
430
+ const host = 'https://localhost:3000';
431
+
432
+ const options = {
433
+ git: { pushRepo: `${host}/user/repo` },
434
+ gitlab: {
435
+ host,
436
+ tokenRef,
437
+ origin: host,
438
+ certificateAuthorityFile: 'test/util/https-server/client/my-private-root-ca.cert.pem'
439
+ }
440
+ };
441
+ const gitlab = factory(GitLab, { options });
442
+ const server = new GitlabTestServer();
415
443
 
416
- await t.notThrowsAsync(gitlab.init());
444
+ t.after(async () => {
445
+ await server.stop();
446
+ });
447
+
448
+ await server.run();
449
+
450
+ interceptUser(local);
451
+ interceptCollaborator(local);
452
+
453
+ await assert.doesNotReject(gitlab.init());
454
+ });
417
455
  });