forked from heavy-duty/stoke
Add labels to issue creation
This commit is contained in:
parent
ee0cb85c7b
commit
7b372eb2dc
2 changed files with 73 additions and 0 deletions
|
|
@ -686,6 +686,7 @@ issue
|
||||||
.option('-b, --body <body>', 'issue body (markdown)')
|
.option('-b, --body <body>', 'issue body (markdown)')
|
||||||
.option('--body-file <path>', 'read the issue body from a file')
|
.option('--body-file <path>', 'read the issue body from a file')
|
||||||
.option('--assignee <username...>', 'assign the issue to one or more users')
|
.option('--assignee <username...>', 'assign the issue to one or more users')
|
||||||
|
.option('--label <name...>', 'apply one or more labels by name')
|
||||||
.action(async (options) => {
|
.action(async (options) => {
|
||||||
try {
|
try {
|
||||||
const config = loadConfig();
|
const config = loadConfig();
|
||||||
|
|
@ -697,6 +698,9 @@ issue
|
||||||
if (options.assignee && options.assignee.length) {
|
if (options.assignee && options.assignee.length) {
|
||||||
payload.assignees = options.assignee;
|
payload.assignees = options.assignee;
|
||||||
}
|
}
|
||||||
|
if (options.label && options.label.length) {
|
||||||
|
payload.labels = await resolveLabelIds(client, options.owner, options.repo, options.label);
|
||||||
|
}
|
||||||
const result = await client.createIssue(options.owner, options.repo, payload);
|
const result = await client.createIssue(options.owner, options.repo, payload);
|
||||||
console.log(`Issue created: #${result.number} ${result.title}`);
|
console.log(`Issue created: #${result.number} ${result.title}`);
|
||||||
console.log(`URL: ${result.html_url}`);
|
console.log(`URL: ${result.html_url}`);
|
||||||
|
|
|
||||||
|
|
@ -77,6 +77,75 @@ test('issue create --body-file reports unreadable files cleanly', () => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('issue create resolves repeated label names into the initial create payload', async () => {
|
||||||
|
const cfg = path.join(os.tmpdir(), `stoke-cfg-${process.pid}-issue-labels.json`);
|
||||||
|
const requests = [];
|
||||||
|
const server = http.createServer((req, res) => {
|
||||||
|
let data = '';
|
||||||
|
req.on('data', (chunk) => { data += chunk; });
|
||||||
|
req.on('end', () => {
|
||||||
|
requests.push({ method: req.method, url: req.url, body: data });
|
||||||
|
res.writeHead(req.method === 'POST' ? 201 : 200, { 'Content-Type': 'application/json' });
|
||||||
|
if (req.method === 'GET') {
|
||||||
|
res.end(JSON.stringify([
|
||||||
|
{ id: 107, name: 'ready', color: '0e8a16' },
|
||||||
|
{ id: 100, name: 'enhancement', color: '84b6eb' },
|
||||||
|
]));
|
||||||
|
} else {
|
||||||
|
res.end(JSON.stringify({ number: 27, title: 'Probe', html_url: 'https://forge.test/o/r/issues/27' }));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
await new Promise((resolve) => server.listen(0, '127.0.0.1', resolve));
|
||||||
|
const { port } = server.address();
|
||||||
|
fs.writeFileSync(cfg, JSON.stringify({ url: `http://127.0.0.1:${port}`, token: 'tok' }));
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await spawnAsync(
|
||||||
|
['issue', 'create', '-o', 'o', '-r', 'r', '-t', 'Probe', '--label', 'ready', '--label', 'enhancement'],
|
||||||
|
{ STOKE_CONFIG_FILE: cfg },
|
||||||
|
);
|
||||||
|
assert.equal(res.status, 0, res.stderr);
|
||||||
|
assert.deepEqual(requests.map(({ method }) => method), ['GET', 'POST']);
|
||||||
|
assert.match(requests[0].url, /^\/api\/v1\/repos\/o\/r\/labels\?/);
|
||||||
|
assert.equal(requests[1].url, '/api/v1/repos/o/r/issues');
|
||||||
|
assert.deepEqual(JSON.parse(requests[1].body), {
|
||||||
|
title: 'Probe',
|
||||||
|
body: '',
|
||||||
|
labels: [107, 100],
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
await new Promise((resolve) => server.close(resolve));
|
||||||
|
fs.unlinkSync(cfg);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test('issue create rejects an unknown label before creating the issue', async () => {
|
||||||
|
const cfg = path.join(os.tmpdir(), `stoke-cfg-${process.pid}-unknown-issue-label.json`);
|
||||||
|
let createRequests = 0;
|
||||||
|
const server = http.createServer((req, res) => {
|
||||||
|
if (req.method === 'POST') createRequests += 1;
|
||||||
|
res.writeHead(200, { 'Content-Type': 'application/json' });
|
||||||
|
res.end(JSON.stringify([{ id: 107, name: 'ready', color: '0e8a16' }]));
|
||||||
|
});
|
||||||
|
await new Promise((resolve) => server.listen(0, '127.0.0.1', resolve));
|
||||||
|
const { port } = server.address();
|
||||||
|
fs.writeFileSync(cfg, JSON.stringify({ url: `http://127.0.0.1:${port}`, token: 'tok' }));
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await spawnAsync(
|
||||||
|
['issue', 'create', '-o', 'o', '-r', 'r', '-t', 'Probe', '--label', 'nonexistent'],
|
||||||
|
{ STOKE_CONFIG_FILE: cfg },
|
||||||
|
);
|
||||||
|
assert.equal(res.status, 1);
|
||||||
|
assert.match(res.stderr, /Label not found in o\/r: nonexistent/);
|
||||||
|
assert.equal(createRequests, 0);
|
||||||
|
} finally {
|
||||||
|
await new Promise((resolve) => server.close(resolve));
|
||||||
|
fs.unlinkSync(cfg);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
test('pr show validates --number before any network call', () => {
|
test('pr show validates --number before any network call', () => {
|
||||||
const cfg = path.join(os.tmpdir(), `stoke-cfg-${process.pid}.json`);
|
const cfg = path.join(os.tmpdir(), `stoke-cfg-${process.pid}.json`);
|
||||||
fs.writeFileSync(cfg, JSON.stringify({ url: 'https://forge.test', token: 'tok' }));
|
fs.writeFileSync(cfg, JSON.stringify({ url: 'https://forge.test', token: 'tok' }));
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue