mirror of
https://github.com/verdaccio/verdaccio.git
synced 2025-02-21 07:29:37 +01:00
Merge branch 'master' into master
This commit is contained in:
commit
dffe497a09
@ -5,12 +5,14 @@ title: "Notifications"
|
||||
|
||||
Notify was built primarily to use with Slack's Incoming
|
||||
webhooks, but will also deliver a simple payload to
|
||||
any endpoint. Currently only active for `publish` / `create`
|
||||
commands.
|
||||
any endpoint. Currently only active for `npm publish`
|
||||
command.
|
||||
|
||||
## Usage
|
||||
|
||||
An example with a **HipChat** and **Google Hangouts Chat** hook:
|
||||
An example with a **HipChat**, **Stride** and **Google Hangouts Chat** hook:
|
||||
|
||||
> Verdaccio supports any API, feel free to ad more examples.
|
||||
|
||||
#### Single notification
|
||||
|
||||
@ -43,7 +45,84 @@ notify:
|
||||
content: '{"body": {"version": 1,"type": "doc","content": [{"type": "paragraph","content": [{"type": "text","text": "New package published: * {{ name }}* Publisher name: * {{ publisher.name }}"}]}]}}'
|
||||
```
|
||||
|
||||
### Publisher information
|
||||
## Template
|
||||
|
||||
We use [Handlebars](https://handlebarsjs.com/) as main template engine.
|
||||
|
||||
### Format Examples
|
||||
|
||||
```
|
||||
# iterate all versions
|
||||
{{ name }}{{#each versions}} v{{version}}{{/each}}`"}
|
||||
|
||||
# publisher and `dist-tag` package published
|
||||
{{ publisher.name }} has published {{publishedPackage}}"}
|
||||
```
|
||||
|
||||
### Properties
|
||||
|
||||
List of properties accesible via template
|
||||
|
||||
* Metadata
|
||||
* Publisher (who is publishing)
|
||||
* Package Published (package@1.0.0)
|
||||
|
||||
### Metadata
|
||||
|
||||
Package metadata that the template has access
|
||||
|
||||
```
|
||||
{
|
||||
"_id": "@test/pkg1",
|
||||
"name": "@test/pkg1",
|
||||
"description": "",
|
||||
"dist-tags": {
|
||||
"beta": "1.0.54"
|
||||
},
|
||||
"versions": {
|
||||
"1.0.54": {
|
||||
"name": "@test/pkg1",
|
||||
"version": "1.0.54",
|
||||
"description": "some description",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": {
|
||||
"name": "Author Name",
|
||||
"email": "author@domain.com"
|
||||
},
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"webpack": "4.12.0"
|
||||
},
|
||||
"readmeFilename": "README.md",
|
||||
"_id": "@ test/pkg1@1.0.54",
|
||||
"_npmVersion": "6.1.0",
|
||||
"_nodeVersion": "9.9.0",
|
||||
"_npmUser": {},
|
||||
"dist": {
|
||||
"integrity": "sha512-JlXWpLtMUBAqvVZBvH7UVLhXkGE1ctmXbDjbH/l0zMuG7wVzQ7GshTYvD/b5C+G2vOL2oiIS1RtayA/kKkTwKw==",
|
||||
"shasum": "29c55c52c1e76e966e706165e5b9f22e32aa9f22",
|
||||
"tarball": "http://localhost:4873/@test/pkg1/-/@test/pkg1-1.0.54.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"readme": "# test",
|
||||
"_attachments": {
|
||||
"@test/pkg1-1.0.54.tgz": {
|
||||
"content_type": "application/octet-stream",
|
||||
"data": "H4sIAAAAAAAAE+y9Z5PjyJIgOJ ...",
|
||||
"length": 33112
|
||||
}
|
||||
},
|
||||
"time": {}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### Publisher
|
||||
|
||||
You can access to the package publisher information in the `content` of a webhook using the `publisher` object.
|
||||
|
||||
@ -69,6 +148,14 @@ notify:
|
||||
|
||||
**Note:** it's not possible to get the publisher information if the `package.json` file already has the `publisher` property.
|
||||
|
||||
### Package Published
|
||||
|
||||
You can acces to the package is being published with the keyword `{{publishedPackage}}` as follows.
|
||||
|
||||
```
|
||||
{{ publisher.name }} has published {{publishedPackage}}"}
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
Property | Type | Required | Support | Default | Description
|
||||
@ -78,4 +165,4 @@ packagePattern| string | No | all | | Only run this notification if the package
|
||||
packagePatternFlags| string | No | all | | Any flags to be used with the regular expression
|
||||
headers| array/object | Yes | all | | If this endpoint requires specific headers, set them here as an array of key: value objects.
|
||||
endpoint| string | Yes | all | | set the URL endpoint for this call
|
||||
content| string | Yes | all | | any [handlebar](https://handlebarsjs.com/) expressions
|
||||
content| string | Yes | all | | any [Handlebar](https://handlebarsjs.com/) expressions
|
||||
|
@ -12,6 +12,7 @@ import {notify} from '../../../lib/notify';
|
||||
import type {Router} from 'express';
|
||||
import type {Config, Callback} from '@verdaccio/types';
|
||||
import type {IAuth, $ResponseExtend, $RequestExtend, $NextFunctionVer, IStorageHandler} from '../../../../types';
|
||||
import logger from '../../../lib/logger';
|
||||
|
||||
export default function(router: Router, auth: IAuth, storage: IStorageHandler, config: Config) {
|
||||
const can = allow(auth);
|
||||
@ -80,18 +81,24 @@ export default function(router: Router, auth: IAuth, storage: IStorageHandler, c
|
||||
return next(err);
|
||||
}
|
||||
|
||||
const t2 = Object.keys(metadata.versions)[0];
|
||||
metadata.versions[t2].readme = _.isNil(metadata.readme) === false ? String(metadata.readme) : '';
|
||||
create_version(t2, metadata.versions[t2], function(err) {
|
||||
const versionToPublish = Object.keys(metadata.versions)[0];
|
||||
metadata.versions[versionToPublish].readme = _.isNil(metadata.readme) === false ? String(metadata.readme) : '';
|
||||
create_version(versionToPublish, metadata.versions[versionToPublish], function(err) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
add_tags(metadata[DIST_TAGS], function(err) {
|
||||
add_tags(metadata[DIST_TAGS], async function(err) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
notify(metadata, config, req.remote_user);
|
||||
|
||||
try {
|
||||
await notify(metadata, config, req.remote_user, `${metadata.name}@${versionToPublish}`);
|
||||
} catch (err) {
|
||||
logger.logger.error({err}, 'notify batch service has failed: @{err}');
|
||||
}
|
||||
|
||||
res.status(201);
|
||||
return next({ok: ok_message, success: true});
|
||||
});
|
||||
|
@ -1,9 +1,9 @@
|
||||
const Handlebars = require('handlebars');
|
||||
const request = require('request');
|
||||
const _ = require('lodash');
|
||||
const logger = require('./logger');
|
||||
import Handlebars from 'handlebars';
|
||||
import request from 'request';
|
||||
import _ from 'lodash';
|
||||
import logger from './logger';
|
||||
|
||||
const handleNotify = function(metadata, notifyEntry, publisherInfo) {
|
||||
const handleNotify = function(metadata, notifyEntry, publisherInfo, publishedPackage) {
|
||||
let regex;
|
||||
if (metadata.name && notifyEntry.packagePattern) {
|
||||
// FUTURE: comment out due https://github.com/verdaccio/verdaccio/pull/108#issuecomment-312421052
|
||||
@ -18,7 +18,7 @@ const handleNotify = function(metadata, notifyEntry, publisherInfo) {
|
||||
|
||||
// don't override 'publisher' if package.json already has that
|
||||
if (!metadata.publisher) {
|
||||
metadata = {...metadata, publisher: publisherInfo};
|
||||
metadata = {...metadata, publishedPackage, publisher: publisherInfo};
|
||||
}
|
||||
const content = template(metadata);
|
||||
|
||||
@ -52,29 +52,40 @@ const handleNotify = function(metadata, notifyEntry, publisherInfo) {
|
||||
return new Promise((resolve, reject) => {
|
||||
request(options, function(err, response, body) {
|
||||
if (err || response.statusCode >= 400) {
|
||||
const errorMessage = _.isNil(err) ? response.statusMessage : err;
|
||||
logger.logger.error({err: errorMessage}, ' notify error: @{err.message}');
|
||||
const errorMessage = _.isNil(err) ? response.body : err.message;
|
||||
logger.logger.error({errorMessage}, 'notify service has thrown an error: @{errorMessage}');
|
||||
|
||||
reject(errorMessage);
|
||||
} else {
|
||||
logger.logger.info({content: content}, 'A notification has been shipped: @{content}');
|
||||
if (body) {
|
||||
logger.logger.debug({body: body}, ' body: @{body}');
|
||||
logger.logger.info({content}, 'A notification has been shipped: @{content}');
|
||||
if (_.isNil(body) === false) {
|
||||
const bodyResolved = _.isNil(body) === false ? body : null;
|
||||
|
||||
logger.logger.debug({body}, ' body: @{body}');
|
||||
return resolve(bodyResolved);
|
||||
}
|
||||
resolve(_.isNil(body) === false ? body : null);
|
||||
|
||||
reject(Error('body is missing'));
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const notify = function(metadata, config, publisherInfo) {
|
||||
function sendNotification(metadata, key, ...moreMedatata) {
|
||||
return handleNotify(metadata, key, ...moreMedatata);
|
||||
}
|
||||
|
||||
const notify = function(metadata, config, ...moreMedatata) {
|
||||
if (config.notify) {
|
||||
if (config.notify.content) {
|
||||
return handleNotify(metadata, config.notify, publisherInfo);
|
||||
return sendNotification(metadata, config.notify, ...moreMedatata);
|
||||
} else {
|
||||
// multiple notifications endpoints PR #108
|
||||
return Promise.all(_.map(config.notify, (key) => handleNotify(metadata, key, publisherInfo)));
|
||||
return Promise.all(_.map(config.notify, (key) => sendNotification(metadata, key, ...moreMedatata)));
|
||||
}
|
||||
}
|
||||
|
||||
return Promise.resolve();
|
||||
};
|
||||
|
||||
module.exports.notify = notify;
|
||||
export {notify};
|
||||
|
@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
|
||||
import LastSync from './modules/LastSync';
|
||||
import Maintainers from './modules/Maintainers';
|
||||
import Dependencies from './modules/Dependencies';
|
||||
import Infos from './modules/Infos';
|
||||
|
||||
import API from '../../../utils/api';
|
||||
|
||||
@ -53,6 +54,7 @@ export default class PackageSidebar extends React.Component {
|
||||
return packageMeta ?
|
||||
(<aside className="sidebar-info">
|
||||
<LastSync packageMeta={packageMeta} />
|
||||
<Infos packageMeta={packageMeta} />
|
||||
<Maintainers packageMeta={packageMeta} />
|
||||
<Dependencies packageMeta={packageMeta} />
|
||||
{/* Package management module? Help us implement it! */}
|
||||
|
@ -0,0 +1,69 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import get from 'lodash/get';
|
||||
import Module from '../../Module';
|
||||
import isString from 'lodash/isString';
|
||||
import isNil from 'lodash/isNil';
|
||||
|
||||
import classes from './style.scss';
|
||||
|
||||
export default class Infos extends React.Component {
|
||||
static propTypes = {
|
||||
packageMeta: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
get infos() {
|
||||
const homepage = this.normalizeInfo(get(this, 'props.packageMeta.latest.homepage', null));
|
||||
const repo = this.normalizeInfo(get(this, 'props.packageMeta.latest.repository', null));
|
||||
const license = get(this, 'props.packageMeta.latest.license', 'N/A');
|
||||
|
||||
return {homepage, repo, license};
|
||||
}
|
||||
|
||||
normalizeInfo(infoObj) {
|
||||
if (isString(infoObj)) {
|
||||
return {url: infoObj};
|
||||
} else if (isNil(infoObj)) {
|
||||
return {url: ''};
|
||||
}
|
||||
|
||||
infoObj.url = this.normalizeGitUrl(infoObj);
|
||||
|
||||
return infoObj;
|
||||
}
|
||||
|
||||
normalizeGitUrl(infoObj) {
|
||||
return infoObj.url.replace(/^git\+/, '');
|
||||
}
|
||||
|
||||
render() {
|
||||
const infos = this.infos;
|
||||
|
||||
if (infos.homepage.url === '' && infos.repo.url === '' && infos.license === 'N/A') {
|
||||
return '';
|
||||
}
|
||||
|
||||
return (
|
||||
<Module
|
||||
title="Infos"
|
||||
className={classes.infosModule}
|
||||
>
|
||||
<ul>
|
||||
{infos.homepage.url && this.renderSection('Homepage', infos.homepage.url)}
|
||||
|
||||
{infos.repo.url && this.renderSection('Repository', infos.repo.url)}
|
||||
|
||||
{infos.license &&
|
||||
<li><span>License</span><span>{infos.license}</span></li>
|
||||
}
|
||||
</ul>
|
||||
</Module>
|
||||
);
|
||||
}
|
||||
|
||||
renderSection(title, url) {
|
||||
return (
|
||||
<li><span>{title}</span><a href={url} target="_blank">{url}</a></li>
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
@import '../../../../styles/variable';
|
||||
|
||||
.infosModule {
|
||||
li {
|
||||
display: flex;
|
||||
font-size: 14px;
|
||||
line-height: 2;
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
max-width: 150px;
|
||||
}
|
||||
|
||||
a:last-child,
|
||||
span:last-child {
|
||||
margin-left: auto;
|
||||
}
|
||||
}
|
||||
}
|
@ -12,7 +12,7 @@ export default class ExpressServer {
|
||||
}
|
||||
|
||||
start(port: number): Promise<any> {
|
||||
return new Promise((resolve, reject) => {
|
||||
return new Promise((resolve) => {
|
||||
this.app.use(bodyParser.json());
|
||||
this.app.use(bodyParser.urlencoded({
|
||||
extended: true
|
||||
|
@ -22,6 +22,12 @@ export default function(express) {
|
||||
|
||||
describe('notifications', () => {
|
||||
|
||||
function parseBody(notification) {
|
||||
const jsonBody = JSON.parse(notification);
|
||||
|
||||
return jsonBody;
|
||||
}
|
||||
|
||||
beforeAll(function () {
|
||||
express.post('/api/notify', function (req, res) {
|
||||
res.send(req.body);
|
||||
@ -38,7 +44,7 @@ export default function(express) {
|
||||
};
|
||||
|
||||
notify(metadata, config, publisherInfo).then(function (body) {
|
||||
const jsonBody = JSON.parse(body);
|
||||
const jsonBody = parseBody(body);
|
||||
assert.ok(
|
||||
`New package published: * ${metadata.name}*. Publisher name: * ${
|
||||
publisherInfo.name
|
||||
@ -63,7 +69,7 @@ export default function(express) {
|
||||
};
|
||||
|
||||
notify(metadata, configMultipleHeader, publisherInfo).then(function (body) {
|
||||
const jsonBody = JSON.parse(body);
|
||||
const jsonBody = parseBody(body);
|
||||
assert.ok(
|
||||
`New package published: * ${metadata.name}*. Publisher name: * ${
|
||||
publisherInfo.name
|
||||
@ -99,7 +105,7 @@ export default function(express) {
|
||||
|
||||
notify(metadata, multipleNotificationsEndpoint, publisherInfo).then(function (body) {
|
||||
body.forEach(function(notification) {
|
||||
const jsonBody = JSON.parse(notification);
|
||||
const jsonBody = parseBody(notification);
|
||||
assert.ok(
|
||||
`New package published: * ${metadata.name}*. Publisher name: * ${
|
||||
publisherInfo.name
|
||||
@ -125,7 +131,7 @@ export default function(express) {
|
||||
assert.equal(false, 'This service should fails with status code 400');
|
||||
done();
|
||||
}, function (err) {
|
||||
assert.ok('Bad Request' === err, 'The error message should be "Bad Request');
|
||||
expect(err).toEqual('bad response');
|
||||
done();
|
||||
});
|
||||
});
|
||||
@ -140,7 +146,7 @@ export default function(express) {
|
||||
|
||||
notify(metadata, config, publisherInfo).then(
|
||||
function(body) {
|
||||
const jsonBody = JSON.parse(body);
|
||||
const jsonBody = parseBody(body);
|
||||
assert.ok(
|
||||
`New package published: * ${metadata.name}*. Publisher name: * ${
|
||||
metadata.publisher.name
|
||||
|
@ -0,0 +1,3 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`<PackageSidebar /> : <Infos /> should load the Info component and match snapshot 1`] = `"<div class=\\"module infosModule\\"><h2 class=\\"moduleTitle\\">Infos</h2><div><ul><li><span>Homepage</span><a href=\\"https://github.com/verdaccio/verdaccio#readme\\" target=\\"_blank\\">https://github.com/verdaccio/verdaccio#readme</a></li><li><span>Repository</span><a href=\\"git://github.com/verdaccio/verdaccio.git\\" target=\\"_blank\\">git://github.com/verdaccio/verdaccio.git</a></li><li><span>License</span><span>WTFPL</span></li></ul></div></div>"`;
|
29
test/webui/components/PackageSidebar/infos.spec.js
Normal file
29
test/webui/components/PackageSidebar/infos.spec.js
Normal file
@ -0,0 +1,29 @@
|
||||
/**
|
||||
* Infos component
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { mount, shallow } from 'enzyme';
|
||||
import Infos from '../../../../src/webui/src/components/PackageSidebar/modules/Infos';
|
||||
import { packageMeta } from '../store/packageMeta';
|
||||
|
||||
console.error = jest.fn();
|
||||
|
||||
describe('<PackageSidebar /> : <Infos />', () => {
|
||||
it('should load the component and check getter: info with package data', () => {
|
||||
const wrapper = mount(<Infos packageMeta={packageMeta} />);
|
||||
const instance = wrapper.instance();
|
||||
const result = {
|
||||
repo: { type: 'git', url: 'git://github.com/verdaccio/verdaccio.git' },
|
||||
homepage: { url: 'https://github.com/verdaccio/verdaccio#readme' },
|
||||
license: 'WTFPL'
|
||||
};
|
||||
|
||||
expect(instance.infos).toEqual(result);
|
||||
});
|
||||
|
||||
it('should load the Info component and match snapshot', () => {
|
||||
const wrapper = shallow(<Infos packageMeta={packageMeta} />);
|
||||
expect(wrapper.html()).toMatchSnapshot();
|
||||
});
|
||||
});
|
@ -2,11 +2,13 @@
|
||||
id: notifications
|
||||
title: "Notificaciones"
|
||||
---
|
||||
Las notificaciones fueron introducidas con la idea de usar webhooks para Slack, pero también se puede enviar un *payload* a cualquier endpoint. Actualmente solo activo para los comandos `publish` / `create`.
|
||||
Notify was built primarily to use with Slack's Incoming webhooks, but will also deliver a simple payload to any endpoint. Currently only active for `npm publish` command.
|
||||
|
||||
## Uso
|
||||
|
||||
An example with a **HipChat** and **Google Hangouts Chat** hook:
|
||||
An example with a **HipChat**, **Stride** and **Google Hangouts Chat** hook:
|
||||
|
||||
> Verdaccio supports any API, feel free to ad more examples.
|
||||
|
||||
#### Notificación sencilla
|
||||
|
||||
@ -32,9 +34,119 @@ notify:
|
||||
headers: [{'Content-Type': 'application/json'}]
|
||||
endpoint: https://usagge.hipchat.com/v2/room/3729485/notification?auth_token=mySecretToken
|
||||
content: '{"color":"green","message":"New package published: * {{ name }}*","notify":true,"message_format":"text"}'
|
||||
'example-stride':
|
||||
method: POST
|
||||
headers: [{'Content-Type': 'application/json'}, {'authorization': 'Bearer secretToken'}]
|
||||
endpoint: https://api.atlassian.com/site/{cloudId}/conversation/{conversationId}/message
|
||||
content: '{"body": {"version": 1,"type": "doc","content": [{"type": "paragraph","content": [{"type": "text","text": "New package published: * {{ name }}* Publisher name: * {{ publisher.name }}"}]}]}}'
|
||||
```
|
||||
|
||||
## Configuración
|
||||
## Template
|
||||
|
||||
We use [Handlebars](https://handlebarsjs.com/) as main template engine.
|
||||
|
||||
### Format Examples
|
||||
|
||||
# iterate all versions
|
||||
{{ name }}{{#each versions}} v{{version}}{{/each}}`"}
|
||||
|
||||
# publisher and `dist-tag` package published
|
||||
{{ publisher.name }} has published {{publishedPackage}}"}
|
||||
|
||||
|
||||
### Properties
|
||||
|
||||
List of properties accesible via template
|
||||
|
||||
* Metadata
|
||||
* Publisher (who is publishing)
|
||||
* Package Published (package@1.0.0)
|
||||
|
||||
### Metadata
|
||||
|
||||
Package metadata that the template has access
|
||||
|
||||
{
|
||||
"_id": "@test/pkg1",
|
||||
"name": "@test/pkg1",
|
||||
"description": "",
|
||||
"dist-tags": {
|
||||
"beta": "1.0.54"
|
||||
},
|
||||
"versions": {
|
||||
"1.0.54": {
|
||||
"name": "@test/pkg1",
|
||||
"version": "1.0.54",
|
||||
"description": "some description",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": {
|
||||
"name": "Author Name",
|
||||
"email": "author@domain.com"
|
||||
},
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"webpack": "4.12.0"
|
||||
},
|
||||
"readmeFilename": "README.md",
|
||||
"_id": "@ test/pkg1@1.0.54",
|
||||
"_npmVersion": "6.1.0",
|
||||
"_nodeVersion": "9.9.0",
|
||||
"_npmUser": {},
|
||||
"dist": {
|
||||
"integrity": "sha512-JlXWpLtMUBAqvVZBvH7UVLhXkGE1ctmXbDjbH/l0zMuG7wVzQ7GshTYvD/b5C+G2vOL2oiIS1RtayA/kKkTwKw==",
|
||||
"shasum": "29c55c52c1e76e966e706165e5b9f22e32aa9f22",
|
||||
"tarball": "http://localhost:4873/@test/pkg1/-/@test/pkg1-1.0.54.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"readme": "# test",
|
||||
"_attachments": {
|
||||
"@test/pkg1-1.0.54.tgz": {
|
||||
"content_type": "application/octet-stream",
|
||||
"data": "H4sIAAAAAAAAE+y9Z5PjyJIgOJ ...",
|
||||
"length": 33112
|
||||
}
|
||||
},
|
||||
"time": {}
|
||||
}
|
||||
|
||||
|
||||
### Publisher
|
||||
|
||||
You can access to the package publisher information in the `content` of a webhook using the `publisher` object.
|
||||
|
||||
See below the `publisher` object type:
|
||||
|
||||
{
|
||||
name: string,
|
||||
groups: string[],
|
||||
real_groups: string[]
|
||||
}
|
||||
|
||||
|
||||
An example:
|
||||
|
||||
notify:
|
||||
method: POST
|
||||
headers: [{'Content-Type': 'application/json'}]
|
||||
endpoint: https://usagge.hipchat.com/v2/room/3729485/notification?auth_token=mySecretToken
|
||||
content: '{"color":"green","message":"New package published: * {{ name }}*. Publisher name: * {{ publisher.name }} *.","notify":true,"message_format":"text"}'
|
||||
|
||||
|
||||
**Note:** it's not possible to get the publisher information if the `package.json` file already has the `publisher` property.
|
||||
|
||||
### Package Published
|
||||
|
||||
You can acces to the package is being published with the keyword `{{publishedPackage}}` as follows.
|
||||
|
||||
{{ publisher.name }} has published {{publishedPackage}}"}
|
||||
|
||||
|
||||
## Configuration
|
||||
|
||||
| Propiedad | Tipo | Requerido | Soporte | Por Defecto | Descripción |
|
||||
| ------------------- | ------------ | --------- | ------- | ----------- | -------------------------------------------------------------------------------------------- |
|
||||
@ -43,4 +155,4 @@ notify:
|
||||
| packagePatternFlags | string | No | all | | Any flags to be used with the regular expression |
|
||||
| headers | array/object | Yes | all | | Si el endpoint requiere encabezados específicos, defínelos aquí como un arreglo (key:value). |
|
||||
| endpoint | string | Yes | all | | define el URL para el endpoint |
|
||||
| content | string | Yes | all | | any [handlebar](https://handlebarsjs.com/) expressions |
|
||||
| content | string | Yes | all | | any [Handlebar](https://handlebarsjs.com/) expressions |
|
@ -2,11 +2,13 @@
|
||||
id: notifications
|
||||
title: "Notifications"
|
||||
---
|
||||
Notify was built primarily to use with Slack's Incoming webhooks, but will also deliver a simple payload to any endpoint. Currently only active for `publish` / `create` commands.
|
||||
Notify was built primarily to use with Slack's Incoming webhooks, but will also deliver a simple payload to any endpoint. Currently only active for `npm publish` command.
|
||||
|
||||
## Usage
|
||||
|
||||
An example with a **HipChat** and **Google Hangouts Chat** hook:
|
||||
An example with a **HipChat**, **Stride** and **Google Hangouts Chat** hook:
|
||||
|
||||
> Verdaccio supports any API, feel free to ad more examples.
|
||||
|
||||
#### Single notification
|
||||
|
||||
@ -32,8 +34,118 @@ notify:
|
||||
headers: [{'Content-Type': 'application/json'}]
|
||||
endpoint: https://usagge.hipchat.com/v2/room/3729485/notification?auth_token=mySecretToken
|
||||
content: '{"color":"green","message":"New package published: * {{ name }}*","notify":true,"message_format":"text"}'
|
||||
'example-stride':
|
||||
method: POST
|
||||
headers: [{'Content-Type': 'application/json'}, {'authorization': 'Bearer secretToken'}]
|
||||
endpoint: https://api.atlassian.com/site/{cloudId}/conversation/{conversationId}/message
|
||||
content: '{"body": {"version": 1,"type": "doc","content": [{"type": "paragraph","content": [{"type": "text","text": "New package published: * {{ name }}* Publisher name: * {{ publisher.name }}"}]}]}}'
|
||||
```
|
||||
|
||||
## Template
|
||||
|
||||
We use [Handlebars](https://handlebarsjs.com/) as main template engine.
|
||||
|
||||
### Format Examples
|
||||
|
||||
# iterate all versions
|
||||
{{ name }}{{#each versions}} v{{version}}{{/each}}`"}
|
||||
|
||||
# publisher and `dist-tag` package published
|
||||
{{ publisher.name }} has published {{publishedPackage}}"}
|
||||
|
||||
|
||||
### Properties
|
||||
|
||||
List of properties accesible via template
|
||||
|
||||
* Metadata
|
||||
* Publisher (who is publishing)
|
||||
* Package Published (package@1.0.0)
|
||||
|
||||
### Metadata
|
||||
|
||||
Package metadata that the template has access
|
||||
|
||||
{
|
||||
"_id": "@test/pkg1",
|
||||
"name": "@test/pkg1",
|
||||
"description": "",
|
||||
"dist-tags": {
|
||||
"beta": "1.0.54"
|
||||
},
|
||||
"versions": {
|
||||
"1.0.54": {
|
||||
"name": "@test/pkg1",
|
||||
"version": "1.0.54",
|
||||
"description": "some description",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": {
|
||||
"name": "Author Name",
|
||||
"email": "author@domain.com"
|
||||
},
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"webpack": "4.12.0"
|
||||
},
|
||||
"readmeFilename": "README.md",
|
||||
"_id": "@ test/pkg1@1.0.54",
|
||||
"_npmVersion": "6.1.0",
|
||||
"_nodeVersion": "9.9.0",
|
||||
"_npmUser": {},
|
||||
"dist": {
|
||||
"integrity": "sha512-JlXWpLtMUBAqvVZBvH7UVLhXkGE1ctmXbDjbH/l0zMuG7wVzQ7GshTYvD/b5C+G2vOL2oiIS1RtayA/kKkTwKw==",
|
||||
"shasum": "29c55c52c1e76e966e706165e5b9f22e32aa9f22",
|
||||
"tarball": "http://localhost:4873/@test/pkg1/-/@test/pkg1-1.0.54.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"readme": "# test",
|
||||
"_attachments": {
|
||||
"@test/pkg1-1.0.54.tgz": {
|
||||
"content_type": "application/octet-stream",
|
||||
"data": "H4sIAAAAAAAAE+y9Z5PjyJIgOJ ...",
|
||||
"length": 33112
|
||||
}
|
||||
},
|
||||
"time": {}
|
||||
}
|
||||
|
||||
|
||||
### Publisher
|
||||
|
||||
You can access to the package publisher information in the `content` of a webhook using the `publisher` object.
|
||||
|
||||
See below the `publisher` object type:
|
||||
|
||||
{
|
||||
name: string,
|
||||
groups: string[],
|
||||
real_groups: string[]
|
||||
}
|
||||
|
||||
|
||||
An example:
|
||||
|
||||
notify:
|
||||
method: POST
|
||||
headers: [{'Content-Type': 'application/json'}]
|
||||
endpoint: https://usagge.hipchat.com/v2/room/3729485/notification?auth_token=mySecretToken
|
||||
content: '{"color":"green","message":"New package published: * {{ name }}*. Publisher name: * {{ publisher.name }} *.","notify":true,"message_format":"text"}'
|
||||
|
||||
|
||||
**Note:** it's not possible to get the publisher information if the `package.json` file already has the `publisher` property.
|
||||
|
||||
### Package Published
|
||||
|
||||
You can acces to the package is being published with the keyword `{{publishedPackage}}` as follows.
|
||||
|
||||
{{ publisher.name }} has published {{publishedPackage}}"}
|
||||
|
||||
|
||||
## Configuration
|
||||
|
||||
| Property | Type | Required | Support | Default | Description |
|
||||
@ -43,4 +155,4 @@ notify:
|
||||
| packagePatternFlags | string | No | all | | Any flags to be used with the regular expression |
|
||||
| headers | array/object | Yes | all | | If this endpoint requires specific headers, set them here as an array of key: value objects. |
|
||||
| endpoint | string | Yes | all | | set the URL endpoint for this call |
|
||||
| content | string | Yes | all | | any [handlebar](https://handlebarsjs.com/) expressions |
|
||||
| content | string | Yes | all | | any [Handlebar](https://handlebarsjs.com/) expressions |
|
@ -2,11 +2,13 @@
|
||||
id: notifications
|
||||
title: "Notifications"
|
||||
---
|
||||
Notify was built primarily to use with Slack's Incoming webhooks, but will also deliver a simple payload to any endpoint. Currently only active for `publish` / `create` commands.
|
||||
Notify was built primarily to use with Slack's Incoming webhooks, but will also deliver a simple payload to any endpoint. Currently only active for `npm publish` command.
|
||||
|
||||
## Usage
|
||||
|
||||
An example with a **HipChat** and **Google Hangouts Chat** hook:
|
||||
An example with a **HipChat**, **Stride** and **Google Hangouts Chat** hook:
|
||||
|
||||
> Verdaccio supports any API, feel free to ad more examples.
|
||||
|
||||
#### Single notification
|
||||
|
||||
@ -32,8 +34,118 @@ notify:
|
||||
headers: [{'Content-Type': 'application/json'}]
|
||||
endpoint: https://usagge.hipchat.com/v2/room/3729485/notification?auth_token=mySecretToken
|
||||
content: '{"color":"green","message":"New package published: * {{ name }}*","notify":true,"message_format":"text"}'
|
||||
'example-stride':
|
||||
method: POST
|
||||
headers: [{'Content-Type': 'application/json'}, {'authorization': 'Bearer secretToken'}]
|
||||
endpoint: https://api.atlassian.com/site/{cloudId}/conversation/{conversationId}/message
|
||||
content: '{"body": {"version": 1,"type": "doc","content": [{"type": "paragraph","content": [{"type": "text","text": "New package published: * {{ name }}* Publisher name: * {{ publisher.name }}"}]}]}}'
|
||||
```
|
||||
|
||||
## Template
|
||||
|
||||
We use [Handlebars](https://handlebarsjs.com/) as main template engine.
|
||||
|
||||
### Format Examples
|
||||
|
||||
# iterate all versions
|
||||
{{ name }}{{#each versions}} v{{version}}{{/each}}`"}
|
||||
|
||||
# publisher and `dist-tag` package published
|
||||
{{ publisher.name }} has published {{publishedPackage}}"}
|
||||
|
||||
|
||||
### Properties
|
||||
|
||||
List of properties accesible via template
|
||||
|
||||
* Metadata
|
||||
* Publisher (who is publishing)
|
||||
* Package Published (package@1.0.0)
|
||||
|
||||
### Metadata
|
||||
|
||||
Package metadata that the template has access
|
||||
|
||||
{
|
||||
"_id": "@test/pkg1",
|
||||
"name": "@test/pkg1",
|
||||
"description": "",
|
||||
"dist-tags": {
|
||||
"beta": "1.0.54"
|
||||
},
|
||||
"versions": {
|
||||
"1.0.54": {
|
||||
"name": "@test/pkg1",
|
||||
"version": "1.0.54",
|
||||
"description": "some description",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": {
|
||||
"name": "Author Name",
|
||||
"email": "author@domain.com"
|
||||
},
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"webpack": "4.12.0"
|
||||
},
|
||||
"readmeFilename": "README.md",
|
||||
"_id": "@ test/pkg1@1.0.54",
|
||||
"_npmVersion": "6.1.0",
|
||||
"_nodeVersion": "9.9.0",
|
||||
"_npmUser": {},
|
||||
"dist": {
|
||||
"integrity": "sha512-JlXWpLtMUBAqvVZBvH7UVLhXkGE1ctmXbDjbH/l0zMuG7wVzQ7GshTYvD/b5C+G2vOL2oiIS1RtayA/kKkTwKw==",
|
||||
"shasum": "29c55c52c1e76e966e706165e5b9f22e32aa9f22",
|
||||
"tarball": "http://localhost:4873/@test/pkg1/-/@test/pkg1-1.0.54.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"readme": "# test",
|
||||
"_attachments": {
|
||||
"@test/pkg1-1.0.54.tgz": {
|
||||
"content_type": "application/octet-stream",
|
||||
"data": "H4sIAAAAAAAAE+y9Z5PjyJIgOJ ...",
|
||||
"length": 33112
|
||||
}
|
||||
},
|
||||
"time": {}
|
||||
}
|
||||
|
||||
|
||||
### Publisher
|
||||
|
||||
You can access to the package publisher information in the `content` of a webhook using the `publisher` object.
|
||||
|
||||
See below the `publisher` object type:
|
||||
|
||||
{
|
||||
name: string,
|
||||
groups: string[],
|
||||
real_groups: string[]
|
||||
}
|
||||
|
||||
|
||||
An example:
|
||||
|
||||
notify:
|
||||
method: POST
|
||||
headers: [{'Content-Type': 'application/json'}]
|
||||
endpoint: https://usagge.hipchat.com/v2/room/3729485/notification?auth_token=mySecretToken
|
||||
content: '{"color":"green","message":"New package published: * {{ name }}*. Publisher name: * {{ publisher.name }} *.","notify":true,"message_format":"text"}'
|
||||
|
||||
|
||||
**Note:** it's not possible to get the publisher information if the `package.json` file already has the `publisher` property.
|
||||
|
||||
### Package Published
|
||||
|
||||
You can acces to the package is being published with the keyword `{{publishedPackage}}` as follows.
|
||||
|
||||
{{ publisher.name }} has published {{publishedPackage}}"}
|
||||
|
||||
|
||||
## Configuration
|
||||
|
||||
| Property | Type | Required | Support | Default | Description |
|
||||
@ -43,4 +155,4 @@ notify:
|
||||
| packagePatternFlags | string | No | all | | Any flags to be used with the regular expression |
|
||||
| headers | array/object | Yes | all | | If this endpoint requires specific headers, set them here as an array of key: value objects. |
|
||||
| endpoint | string | Yes | all | | set the URL endpoint for this call |
|
||||
| content | string | Yes | all | | any [handlebar](https://handlebarsjs.com/) expressions |
|
||||
| content | string | Yes | all | | any [Handlebar](https://handlebarsjs.com/) expressions |
|
Loading…
Reference in New Issue
Block a user