Skip to content

Commit

Permalink
feat: Support _creator as a maintainer as well
Browse files Browse the repository at this point in the history
  • Loading branch information
dploeger committed Nov 21, 2023
1 parent 50fb1c3 commit 1ca8fd3
Show file tree
Hide file tree
Showing 6 changed files with 256 additions and 6 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ A table of maintainers for pages.

- PagePattern: A regular expression that is matched against the full document path. Parent pages are separated through a "/".
- Maintainer: The users that should receive all notifications for pages matching this pattern (separated by ,). You can
use `_lastauthor` to reference the last author of the page)
use `_lastauthor` to reference the last author of the page and `_creator` to reference the first author of the page.

### Panel "Exceptions"

Expand Down
4 changes: 3 additions & 1 deletion lib/api/Confluence.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,15 @@ export class Confluence {
*/
public async getDocumentInfo(documentId: number): Promise<DocumentInfo> {
this._log.debug(`Getting document information of document ${documentId}`)
const documentUrl = `${this.confluenceUrl}/rest/api/content/${documentId}?expand=ancestors,version,metadata.labels`
const documentUrl = `${this.confluenceUrl}/rest/api/content/${documentId}?expand=ancestors,version,metadata.labels,history`
const document = await got(documentUrl, {
username: this.confluenceUser,
password: this.confluencePassword,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
}).json<any>()

const author = document.version.by.username ?? null
const creator = document.history['createdBy'].username ?? null

if (!author) {
this._log.error(`Can't get author from this document:
Expand Down Expand Up @@ -125,6 +126,7 @@ export class Confluence {
const documentInfo = new DocumentInfo(
documentId,
author,
creator,
(lastVersionDate as Moment).toISOString(),
lastVersionMessage,
title,
Expand Down
13 changes: 12 additions & 1 deletion lib/api/DocumentInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export interface DocumentInfo {
export class DocumentInfo implements DocumentInfo {
public id: number
public author: string
public creator: string
public lastVersionDate: string
public lastVersionMessage: string
public title: string
Expand All @@ -61,6 +62,7 @@ export class DocumentInfo implements DocumentInfo {
constructor(
id: number,
author: string,
creator: string,
lastVersionDate: string,
lastVersionMessage: string,
title: string,
Expand All @@ -71,6 +73,7 @@ export class DocumentInfo implements DocumentInfo {
) {
this.id = id
this.author = author
this.creator = creator
this.lastVersionDate = lastVersionDate
this.lastVersionMessage = lastVersionMessage
this.title = title
Expand All @@ -88,6 +91,7 @@ export class DocumentInfo implements DocumentInfo {
return new DocumentInfo(
documentInfo.id,
documentInfo.author,
documentInfo.creator,
documentInfo.lastVersionDate,
documentInfo.lastVersionMessage,
documentInfo.title,
Expand All @@ -101,18 +105,25 @@ export class DocumentInfo implements DocumentInfo {
public getRecipients(maintainers: Maintainer[], domain?: string): string[] {
const retval = []
let addLastAuthor = maintainers.length > 0 ? false : true
let addCreator = false
for (const maintainer of maintainers) {
if (this.matchesPath(maintainer.pagePattern)) {
const maintainers = maintainer.maintainer.split(/,/)
if (maintainers.indexOf('_lastauthor') > 0) {
addLastAuthor = true
}
retval.push(...maintainers.filter((entry) => entry != '_lastauthor'))
if (maintainers.indexOf('_creator') > 0) {
addCreator = true
}
retval.push(...maintainers.filter((entry) => ['_lastauthor', '_creator'].indexOf(entry) == -1))
}
}
if (addLastAuthor) {
retval.push(this.author)
}
if (addCreator) {
retval.push(this.creator)
}
if (domain) {
return retval.map((target) => `${target}@${domain}`)
}
Expand Down
3 changes: 2 additions & 1 deletion resources/configurationDocument.html
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@
<ac:structured-macro ac:name="panel" ac:schema-version="1" ac:macro-id="1d192d60-7e69-4af8-8dd6-4006a7bfc952">
<ac:parameter ac:name="title">Maintainer</ac:parameter>
<ac:rich-text-body>
<i>This table holds a list of RegExp patterns for page paths and titles and the associated maintainers (separated by ,) for this pages, which will be notified instead of the last version's author. The last author can be added as well, if desired by using _lastauthor as the username.</i>
<i>This table holds a list of RegExp patterns for page paths and titles and the associated maintainers (separated by ,) for this pages, which will be notified instead of the last version's author. Use
<b>_lastauthor</b> to reference the last author of the page and <b>_creator</b> to reference the first author of the page.</i>
<table class="wrapped">
<colgroup>
<col/>
Expand Down
174 changes: 172 additions & 2 deletions test/MockServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,166 @@ export class MockServer {
</table>
</ac:rich-text-body>
</ac:structured-macro>
<ac:structured-macro ac:name='panel' ac:schema-version='1' ac:macro-id='93f1d981-c841-4cb4-b6e2-5940dfe69132'>
<ac:parameter ac:name='title'>Notification Template</ac:parameter>
<ac:rich-text-body>
<ac:structured-macro ac:name='panel' ac:schema-version='1' ac:macro-id='f8503e48-c671-4ed6-897c-def2b2c3fa29'>
<ac:parameter ac:name='title'>Subject</ac:parameter>
<ac:rich-text-body><p>${MockServer.NOTIFICATION_SUBJECT}</p></ac:rich-text-body>
</ac:structured-macro>
<ac:structured-macro ac:name='panel' ac:schema-version='1' ac:macro-id='63c16112-dea3-434e-b1cb-467ff4e36d5f'>
<ac:parameter ac:name='title'>Body</ac:parameter>
<ac:rich-text-body>${MockServer.NOTIFICATION_BODY}</ac:rich-text-body>
</ac:structured-macro>
</ac:rich-text-body>
</ac:structured-macro>
`,
},
},
})
this._scope
.get('/rest/api/content/12348?expand=body.storage')
.basicAuth({
user: 'nobody',
pass: 'nothing',
})
.reply(200, {
body: {
storage: {
value: `
<ac:structured-macro ac:name='panel' ac:schema-version='1' ac:macro-id='4671afbe-d914-470a-bb9e-8b7321f60f79'>
<ac:parameter ac:name='title'>Configuration</ac:parameter>
<ac:rich-text-body>
<table class='wrapped'>
<colgroup>
<col/>
<col/>
</colgroup>
<tbody>
<tr>
<th>Space</th>
<td>SAMPLE</td>
</tr>
<tr>
<th>Domain</th>
<td>example.com</td>
</tr>
<tr>
<th>NotificationFrom</th>
<td>Notification &lt;noreply@example.com&gt;</td>
</tr>
</tbody>
</table>
</ac:rich-text-body>
</ac:structured-macro>
<ac:structured-macro ac:name='panel' ac:schema-version='1' ac:macro-id='ecfe796e-b701-4f30-a74a-b94dbb33daff'>
<ac:parameter ac:name='title'>SMTP</ac:parameter>
<ac:rich-text-body>
<table>
<colgroup>
<col/>
<col/>
</colgroup>
<tbody>
<tr>
<th>Host</th>
<td colspan='1'>localhost</td>
</tr>
<tr>
<th>Port</th>
<td colspan='1'>25</td>
</tr>
</tbody>
</table>
</ac:rich-text-body>
</ac:structured-macro>
<ac:structured-macro ac:name='panel' ac:schema-version='1' ac:macro-id='f19cd8b2-57e0-4c68-a823-8a2daee08c12'>
<ac:parameter ac:name='title'>Checks</ac:parameter>
<ac:rich-text-body>
<table class='wrapped'>
<colgroup>
<col/>
<col/>
</colgroup>
<tbody>
<tr>
<th>Labels</th>
<th>MaxAge</th>
</tr>
<tr>
<td>test1</td>
<td>356</td>
</tr>
<tr>
<td colspan='1'>test2</td>
<td colspan='1'>1234</td>
</tr>
</tbody>
</table>
</ac:rich-text-body>
</ac:structured-macro>
<ac:structured-macro ac:name='panel' ac:schema-version='1' ac:macro-id='1d192d60-7e69-4af8-8dd6-4006a7bfc952'>
<ac:parameter ac:name='title'>Maintainer</ac:parameter>
<ac:rich-text-body>
<table class='wrapped'>
<colgroup>
<col/>
<col/>
</colgroup>
<tbody>
<tr>
<th>Pagepattern</th>
<th>Maintainer</th>
</tr>
<tr>
<td>main/Test/.*</td>
<td>maintainer,_creator</td>
</tr>
</tbody>
</table>
</ac:rich-text-body>
</ac:structured-macro>
<ac:structured-macro ac:name='panel' ac:schema-version='1' ac:macro-id='1d192d60-7e69-4af8-8dd6-4006a7bfc952'>
<ac:parameter ac:name='title'>Exceptions</ac:parameter>
<ac:rich-text-body>
<table class='wrapped'>
<colgroup>
<col/>
</colgroup>
<tbody>
<tr>
<th>RegularExpression</th>
</tr>
<tr>
<td>main/Test/NOT</td>
</tr>
</tbody>
</table>
</ac:rich-text-body>
</ac:structured-macro>
<ac:structured-macro ac:name="panel" ac:schema-version="1" ac:macro-id="1d192d60-7e69-4af8-8dd6-4006a7bfc952">
<ac:parameter ac:name="title">Excluded labels</ac:parameter>
<ac:rich-text-body>
<i>This table holds a list of labels. A document which has one of these will be excluded from notifications.</i>
<table class="wrapped">
<colgroup>
<col/>
<col/>
</colgroup>
<tbody>
<tr>
<th>Label</th>
</tr>
<tr>
<td>NOT</td>
</tr>
<tr>
<td>NOT2</td>
</tr>
</tbody>
</table>
</ac:rich-text-body>
</ac:structured-macro>
<ac:structured-macro ac:name='panel' ac:schema-version='1' ac:macro-id='93f1d981-c841-4cb4-b6e2-5940dfe69132'>
<ac:parameter ac:name='title'>Notification Template</ac:parameter>
<ac:rich-text-body>
Expand Down Expand Up @@ -507,7 +667,7 @@ export class MockServer {

public addDocumentEndpoint(): void {
this._scope
.get('/rest/api/content/123?expand=ancestors,version,metadata.labels')
.get('/rest/api/content/123?expand=ancestors,version,metadata.labels,history')
.basicAuth({
user: 'nobody',
pass: 'nothing',
Expand All @@ -529,6 +689,11 @@ export class MockServer {
when: '2020-01-01T00:00:00.000+02:00',
message: 'Some change',
},
history: {
createdBy: {
username: 'creator',
},
},
title: 'Test',
metadata: {
labels: {
Expand All @@ -542,7 +707,7 @@ export class MockServer {
},
},
})
.get('/rest/api/content/234?expand=ancestors,version,metadata.labels')
.get('/rest/api/content/234?expand=ancestors,version,metadata.labels,history')
.basicAuth({
user: 'nobody',
pass: 'nothing',
Expand All @@ -560,6 +725,11 @@ export class MockServer {
title: 'Test',
},
],
history: {
createdBy: {
username: 'creator',
},
},
version: {
by: {
username: 'author2',
Expand Down
Loading

0 comments on commit 1ca8fd3

Please sign in to comment.