Compare commits
25 Commits
Author | SHA1 | Date | |
---|---|---|---|
a71ffb2415 | |||
dc2be85236 | |||
964e1ce9ac | |||
fba6e3d4c5 | |||
7df51bad07 | |||
5c7af1e59f | |||
e72f7fe5c6 | |||
da48b987ba | |||
9eabac7022 | |||
00683fbab1 | |||
3434bbf815 | |||
85ac242627 | |||
9b71872d12 | |||
281595f8c8 | |||
83f03994a9 | |||
01837f8420 | |||
b5735e3721 | |||
0dc45f1414 | |||
9d1c3f7457 | |||
017279730a | |||
0b50b14146 | |||
dfa27c0604 | |||
19e839a282 | |||
647e2ec886 | |||
4e267850bf |
@ -1,32 +1,50 @@
|
|||||||
image: hosttoday/ht-docker-node
|
image: hosttoday/ht-docker-node:latest
|
||||||
|
|
||||||
stages:
|
stages:
|
||||||
- test
|
- test
|
||||||
- release
|
- release
|
||||||
|
- page
|
||||||
|
|
||||||
|
testLEGACY:
|
||||||
|
stage: test
|
||||||
|
script:
|
||||||
|
- npmci test legacy
|
||||||
|
tags:
|
||||||
|
- docker
|
||||||
|
|
||||||
testLTS:
|
testLTS:
|
||||||
stage: test
|
stage: test
|
||||||
script:
|
script:
|
||||||
- npmci install 4
|
- npmci test lts
|
||||||
- npm install
|
|
||||||
- npm test
|
|
||||||
tags:
|
tags:
|
||||||
- docker
|
- docker
|
||||||
|
|
||||||
testSTABLE:
|
testSTABLE:
|
||||||
stage: test
|
stage: test
|
||||||
script:
|
script:
|
||||||
- npmci install stable
|
- npmci test stable
|
||||||
- npm install
|
|
||||||
- npm test
|
|
||||||
tags:
|
tags:
|
||||||
- docker
|
- docker
|
||||||
|
|
||||||
release:
|
release:
|
||||||
stage: release
|
stage: release
|
||||||
script:
|
script:
|
||||||
- npm -v
|
- npmci publish
|
||||||
only:
|
only:
|
||||||
- master
|
- tags
|
||||||
tags:
|
tags:
|
||||||
- docker
|
- docker
|
||||||
|
|
||||||
|
pages:
|
||||||
|
stage: page
|
||||||
|
script:
|
||||||
|
- npmci test lts
|
||||||
|
- mkdir .public
|
||||||
|
- cp -r test/assets/docs/ .public
|
||||||
|
- cp -r test/assets/coverage/ .public
|
||||||
|
- mv .public public
|
||||||
|
artifacts:
|
||||||
|
paths:
|
||||||
|
- public
|
||||||
|
only:
|
||||||
|
- master
|
@ -1,6 +1,6 @@
|
|||||||
.idea/
|
.idea/
|
||||||
support
|
compile/
|
||||||
compile
|
coverage/
|
||||||
test/
|
test/
|
||||||
docs/
|
docs/
|
||||||
examples
|
examples
|
||||||
|
7
CHANGELOG
Normal file
7
CHANGELOG
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
Please view this file on the master branch, on stable branches it's out of date.
|
||||||
|
|
||||||
|
v 6.0.0 (unreleased)
|
||||||
|
- handle bithound
|
||||||
|
- check package.json
|
||||||
|
- check .gitlab-ci-yml
|
||||||
|
- check appveyor.yml
|
4
CONTRIBUTING.md
Normal file
4
CONTRIBUTING.md
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
# Contribution Guide
|
||||||
|
|
||||||
|
This module is developed on the fabulous GitLab.com:
|
||||||
|
https://gitlab.com/pushrocks/npmts
|
@ -2,8 +2,8 @@
|
|||||||
Write npm modules with TypeScript without hassle.
|
Write npm modules with TypeScript without hassle.
|
||||||
|
|
||||||
## Status
|
## Status
|
||||||
[](https://travis-ci.org/pushrocks/npmts)
|
[](https://gitlab.com/pushrocks/npmts/commits/master)
|
||||||
[](https://ci.appveyor.com/project/philkunz/npmts)
|
[](https://ci.appveyor.com/project/philkunz/npmts/branch/master)
|
||||||
[](https://david-dm.org/pushrocks/npmts)
|
[](https://david-dm.org/pushrocks/npmts)
|
||||||
[](https://www.bithound.io/github/pushrocks/npmts/master/dependencies/npm)
|
[](https://www.bithound.io/github/pushrocks/npmts/master/dependencies/npm)
|
||||||
[](https://www.bithound.io/github/pushrocks/npmts)
|
[](https://www.bithound.io/github/pushrocks/npmts)
|
||||||
@ -51,7 +51,10 @@ the npmts.json is the main config file. You can use it to customize the behaviou
|
|||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"mode":"default",
|
"mode":"default",
|
||||||
"codecov":true,
|
"codecov":{
|
||||||
|
"publish":true,
|
||||||
|
"token":"sometoken"
|
||||||
|
},
|
||||||
"ts":{
|
"ts":{
|
||||||
"./customdir/*.ts":"./"
|
"./customdir/*.ts":"./"
|
||||||
},
|
},
|
||||||
|
3
dist/npmts.options.js
vendored
3
dist/npmts.options.js
vendored
@ -41,9 +41,6 @@ exports.run = function (configArg) {
|
|||||||
: plugins.beautylog.info("NOT A RELEASE build!");
|
: plugins.beautylog.info("NOT A RELEASE build!");
|
||||||
exports.isRelease() && exports.doPublish() ? plugins.beautylog.info("All right: This is the first subBuild, so this one publishes COVERAGE + DOCS when tests succeed!")
|
exports.isRelease() && exports.doPublish() ? plugins.beautylog.info("All right: This is the first subBuild, so this one publishes COVERAGE + DOCS when tests succeed!")
|
||||||
: plugins.beautylog.info("We are not publishing anything!");
|
: plugins.beautylog.info("We are not publishing anything!");
|
||||||
// handle coveralls
|
|
||||||
config.codecov ? void (0) : config.codecov = true;
|
|
||||||
exports.isCi() ? void (0) : config.codecov = false;
|
|
||||||
config.coverageTreshold ? void (0) : config.coverageTreshold = 70;
|
config.coverageTreshold ? void (0) : config.coverageTreshold = 70;
|
||||||
// handle docs
|
// handle docs
|
||||||
config.docs ? void (0) : config.docs = {};
|
config.docs ? void (0) : config.docs = {};
|
||||||
|
1
dist/npmts.plugins.js
vendored
1
dist/npmts.plugins.js
vendored
@ -4,7 +4,6 @@ exports.beautylog = require("beautylog");
|
|||||||
exports.fs = require("fs-extra");
|
exports.fs = require("fs-extra");
|
||||||
exports.gulp = require("gulp");
|
exports.gulp = require("gulp");
|
||||||
exports.g = {
|
exports.g = {
|
||||||
codecov: require("gulp-codecov"),
|
|
||||||
gFunction: require("gulp-function"),
|
gFunction: require("gulp-function"),
|
||||||
istanbul: require("gulp-istanbul"),
|
istanbul: require("gulp-istanbul"),
|
||||||
jsdoc3: require("gulp-jsdoc3"),
|
jsdoc3: require("gulp-jsdoc3"),
|
||||||
|
2
dist/npmts.publish.js
vendored
2
dist/npmts.publish.js
vendored
@ -1,13 +1,11 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
require("typings-global");
|
require("typings-global");
|
||||||
var plugins = require("./npmts.plugins");
|
var plugins = require("./npmts.plugins");
|
||||||
var NpmtsTests = require("./npmts.tests");
|
|
||||||
var NpmtsJsdoc = require("./npmts.jsdoc");
|
var NpmtsJsdoc = require("./npmts.jsdoc");
|
||||||
exports.run = function (configArg) {
|
exports.run = function (configArg) {
|
||||||
var done = plugins.Q.defer();
|
var done = plugins.Q.defer();
|
||||||
var config = configArg;
|
var config = configArg;
|
||||||
var promiseArray = [];
|
var promiseArray = [];
|
||||||
config.codecov ? promiseArray.push(NpmtsTests.publishCoverage(configArg)) : void (0);
|
|
||||||
config.docs.publish ? promiseArray.push(NpmtsJsdoc.publishDocs(configArg)) : void (0);
|
config.docs.publish ? promiseArray.push(NpmtsJsdoc.publishDocs(configArg)) : void (0);
|
||||||
promiseArray.length === 0 ? plugins.beautylog.info("Did not publish anything!") : void (0);
|
promiseArray.length === 0 ? plugins.beautylog.info("Did not publish anything!") : void (0);
|
||||||
plugins.Q.all(promiseArray).then(done.resolve);
|
plugins.Q.all(promiseArray).then(done.resolve);
|
||||||
|
11
dist/npmts.tests.js
vendored
11
dist/npmts.tests.js
vendored
@ -3,17 +3,6 @@ require("typings-global");
|
|||||||
var plugins = require("./npmts.plugins");
|
var plugins = require("./npmts.plugins");
|
||||||
var paths = require("./npmts.paths");
|
var paths = require("./npmts.paths");
|
||||||
var npmts_promisechain_1 = require("./npmts.promisechain");
|
var npmts_promisechain_1 = require("./npmts.promisechain");
|
||||||
exports.publishCoverage = function (configArg) {
|
|
||||||
var done = plugins.Q.defer();
|
|
||||||
plugins.beautylog.log("now uploading coverage data to codecov.io");
|
|
||||||
var stream = plugins.gulp.src([plugins.path.join(paths.cwd, "./coverage/lcov.info")])
|
|
||||||
.pipe(plugins.g.codecov())
|
|
||||||
.pipe(plugins.g.gFunction(function () {
|
|
||||||
plugins.beautylog.ok("Coverage data has been uploaded to codecov.io!");
|
|
||||||
done.resolve(configArg);
|
|
||||||
}, "atEnd"));
|
|
||||||
return done.promise;
|
|
||||||
};
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @returns {*}
|
* @returns {*}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "npmts",
|
"name": "npmts",
|
||||||
"version": "5.1.16",
|
"version": "5.2.1",
|
||||||
"description": "write npm modules with TypeScript",
|
"description": "write npm modules with TypeScript",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"bin": {
|
"bin": {
|
||||||
@ -13,7 +13,7 @@
|
|||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git+https://github.com/pushrocks/npmts.git"
|
"url": "git+https://gitlab.com/pushrocks/npmts.git"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"TypeScript",
|
"TypeScript",
|
||||||
@ -22,15 +22,14 @@
|
|||||||
"author": "Lossless Digital UG (haftungsbeschraenkt)",
|
"author": "Lossless Digital UG (haftungsbeschraenkt)",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/pushrocks/npmts/issues"
|
"url": "https://gitlab.com/pushrocks/npmts/issues"
|
||||||
},
|
},
|
||||||
"homepage": "https://github.com/pushrocks/npmts#readme",
|
"homepage": "https://gitlab.com/pushrocks/npmts#readme",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"beautylog": "5.0.6",
|
"beautylog": "5.0.6",
|
||||||
"early": "^2.0.1",
|
"early": "^2.0.1",
|
||||||
"fs-extra": "^0.30.0",
|
"fs-extra": "^0.30.0",
|
||||||
"gulp": "3.9.1",
|
"gulp": "3.9.1",
|
||||||
"gulp-codecov": "^2.0.1",
|
|
||||||
"gulp-concat": "^2.6.0",
|
"gulp-concat": "^2.6.0",
|
||||||
"gulp-function": "^1.3.1",
|
"gulp-function": "^1.3.1",
|
||||||
"gulp-if": "^2.0.1",
|
"gulp-if": "^2.0.1",
|
||||||
|
2
test/assets/dist/index.js
vendored
2
test/assets/dist/index.js
vendored
@ -6,4 +6,4 @@ var testplugin = {
|
|||||||
};
|
};
|
||||||
module.exports = testplugin;
|
module.exports = testplugin;
|
||||||
|
|
||||||
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImluZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDZDQUE2QztBQUM3QyxJQUFJLFVBQVUsR0FBRztJQUNiLFlBQVksRUFBRTtRQUNWLE9BQU8sQ0FBQyxHQUFHLENBQUMsd0JBQXdCLENBQUMsQ0FBQztJQUMxQyxDQUFDO0NBQ0osQ0FBQztBQUNGLE1BQU0sQ0FBQyxPQUFPLEdBQUcsVUFBVSxDQUFDIiwiZmlsZSI6ImluZGV4LmpzIiwic291cmNlc0NvbnRlbnQiOlsiLy8vIDxyZWZlcmVuY2UgcGF0aD1cIi4vdHlwaW5ncy9pbmRleC5kLnRzXCIgLz5cbmxldCB0ZXN0cGx1Z2luID0ge1xuICAgIGxvZ1NvbWV0aGluZzogZnVuY3Rpb24oKXtcbiAgICAgICAgY29uc29sZS5sb2coXCJvbmx5IGZ1bmN0aW9uIGV4ZWN1dGVkXCIpO1xuICAgIH1cbn07XG5tb2R1bGUuZXhwb3J0cyA9IHRlc3RwbHVnaW47Il19
|
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImluZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDZDQUE2QztBQUM3QyxJQUFJLFVBQVUsR0FBRztJQUNiLFlBQVksRUFBRTtRQUNWLE9BQU8sQ0FBQyxHQUFHLENBQUMsd0JBQXdCLENBQUMsQ0FBQztJQUMxQyxDQUFDO0NBQ0osQ0FBQztBQUNGLE1BQU0sQ0FBQyxPQUFPLEdBQUcsVUFBVSxDQUFDIiwiZmlsZSI6ImluZGV4LmpzIiwic291cmNlc0NvbnRlbnQiOlsiLy8vIDxyZWZlcmVuY2UgcGF0aD1cIi4vdHlwaW5ncy9pbmRleC5kLnRzXCIgLz5cclxubGV0IHRlc3RwbHVnaW4gPSB7XHJcbiAgICBsb2dTb21ldGhpbmc6IGZ1bmN0aW9uKCl7XHJcbiAgICAgICAgY29uc29sZS5sb2coXCJvbmx5IGZ1bmN0aW9uIGV4ZWN1dGVkXCIpO1xyXG4gICAgfVxyXG59O1xyXG5tb2R1bGUuZXhwb3J0cyA9IHRlc3RwbHVnaW47Il19
|
||||||
|
@ -12,7 +12,6 @@
|
|||||||
"./subts2/typings.json",
|
"./subts2/typings.json",
|
||||||
"./customdir/typings.json"
|
"./customdir/typings.json"
|
||||||
],
|
],
|
||||||
"codecov":true,
|
|
||||||
"docs": {
|
"docs": {
|
||||||
"publish":true
|
"publish":true
|
||||||
},
|
},
|
||||||
|
@ -8,4 +8,4 @@ describe("testplugins", function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsaURBQWlEO0FBQ2pELElBQUksVUFBVSxHQUFHLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO0FBQzdDLFFBQVEsQ0FBQyxhQUFhLEVBQUM7SUFDbkIsUUFBUSxDQUFDLGVBQWUsRUFBQztRQUNyQixFQUFFLENBQUMsc0JBQXNCLEVBQUM7WUFDdEIsVUFBVSxDQUFDLFlBQVksRUFBRSxDQUFBO1FBQzdCLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQyxDQUFDLENBQUM7QUFDUCxDQUFDLENBQUMsQ0FBQyIsImZpbGUiOiJ0ZXN0LmpzIiwic291cmNlc0NvbnRlbnQiOlsiLy8vIDxyZWZlcmVuY2UgcGF0aD1cIi4uL3RzL3R5cGluZ3MvaW5kZXguZC50c1wiIC8+XG52YXIgdGVzdHBsdWdpbiA9IHJlcXVpcmUoXCIuLi9kaXN0L2luZGV4LmpzXCIpO1xuZGVzY3JpYmUoXCJ0ZXN0cGx1Z2luc1wiLGZ1bmN0aW9uKCl7XG4gICAgZGVzY3JpYmUoXCIubG9nU29tZXRoaW5nXCIsZnVuY3Rpb24oKXtcbiAgICAgICAgaXQoXCJzaG91bGQgbG9nIHNvbWV0aGluZ1wiLGZ1bmN0aW9uKCl7XG4gICAgICAgICAgICB0ZXN0cGx1Z2luLmxvZ1NvbWV0aGluZygpXG4gICAgICAgIH0pO1xuICAgIH0pO1xufSk7Il19
|
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsaURBQWlEO0FBQ2pELElBQUksVUFBVSxHQUFHLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO0FBQzdDLFFBQVEsQ0FBQyxhQUFhLEVBQUM7SUFDbkIsUUFBUSxDQUFDLGVBQWUsRUFBQztRQUNyQixFQUFFLENBQUMsc0JBQXNCLEVBQUM7WUFDdEIsVUFBVSxDQUFDLFlBQVksRUFBRSxDQUFBO1FBQzdCLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQyxDQUFDLENBQUM7QUFDUCxDQUFDLENBQUMsQ0FBQyIsImZpbGUiOiJ0ZXN0LmpzIiwic291cmNlc0NvbnRlbnQiOlsiLy8vIDxyZWZlcmVuY2UgcGF0aD1cIi4uL3RzL3R5cGluZ3MvaW5kZXguZC50c1wiIC8+XHJcbnZhciB0ZXN0cGx1Z2luID0gcmVxdWlyZShcIi4uL2Rpc3QvaW5kZXguanNcIik7XHJcbmRlc2NyaWJlKFwidGVzdHBsdWdpbnNcIixmdW5jdGlvbigpe1xyXG4gICAgZGVzY3JpYmUoXCIubG9nU29tZXRoaW5nXCIsZnVuY3Rpb24oKXtcclxuICAgICAgICBpdChcInNob3VsZCBsb2cgc29tZXRoaW5nXCIsZnVuY3Rpb24oKXtcclxuICAgICAgICAgICAgdGVzdHBsdWdpbi5sb2dTb21ldGhpbmcoKVxyXG4gICAgICAgIH0pO1xyXG4gICAgfSk7XHJcbn0pOyJdfQ==
|
||||||
|
@ -49,9 +49,7 @@ export var run = function(configArg){
|
|||||||
isRelease() && doPublish() ? plugins.beautylog.info("All right: This is the first subBuild, so this one publishes COVERAGE + DOCS when tests succeed!")
|
isRelease() && doPublish() ? plugins.beautylog.info("All right: This is the first subBuild, so this one publishes COVERAGE + DOCS when tests succeed!")
|
||||||
: plugins.beautylog.info("We are not publishing anything!");
|
: plugins.beautylog.info("We are not publishing anything!");
|
||||||
|
|
||||||
// handle coveralls
|
|
||||||
config.codecov ? void(0) : config.codecov = true;
|
|
||||||
isCi() ? void(0) : config.codecov = false;
|
|
||||||
|
|
||||||
config.coverageTreshold ? void(0) : config.coverageTreshold = 70;
|
config.coverageTreshold ? void(0) : config.coverageTreshold = 70;
|
||||||
|
|
||||||
|
@ -3,7 +3,6 @@ export import beautylog = require("beautylog");
|
|||||||
export let fs = require("fs-extra");
|
export let fs = require("fs-extra");
|
||||||
export let gulp = require("gulp");
|
export let gulp = require("gulp");
|
||||||
export let g = {
|
export let g = {
|
||||||
codecov: require("gulp-codecov"),
|
|
||||||
gFunction: require("gulp-function"),
|
gFunction: require("gulp-function"),
|
||||||
istanbul: require("gulp-istanbul"),
|
istanbul: require("gulp-istanbul"),
|
||||||
jsdoc3: require("gulp-jsdoc3"),
|
jsdoc3: require("gulp-jsdoc3"),
|
||||||
|
@ -1,15 +1,12 @@
|
|||||||
import "typings-global";
|
import "typings-global";
|
||||||
import plugins = require("./npmts.plugins");
|
import plugins = require("./npmts.plugins");
|
||||||
import paths = require("./npmts.paths");
|
import paths = require("./npmts.paths");
|
||||||
import NpmtsTests = require("./npmts.tests");
|
|
||||||
import NpmtsJsdoc = require("./npmts.jsdoc");
|
import NpmtsJsdoc = require("./npmts.jsdoc");
|
||||||
|
|
||||||
|
|
||||||
export let run = function(configArg){
|
export let run = function(configArg){
|
||||||
let done = plugins.Q.defer();
|
let done = plugins.Q.defer();
|
||||||
let config = configArg;
|
let config = configArg;
|
||||||
let promiseArray = [];
|
let promiseArray = [];
|
||||||
config.codecov ? promiseArray.push(NpmtsTests.publishCoverage(configArg)) : void(0);
|
|
||||||
config.docs.publish ? promiseArray.push(NpmtsJsdoc.publishDocs(configArg)) : void(0);
|
config.docs.publish ? promiseArray.push(NpmtsJsdoc.publishDocs(configArg)) : void(0);
|
||||||
promiseArray.length === 0 ? plugins.beautylog.info("Did not publish anything!") : void(0);
|
promiseArray.length === 0 ? plugins.beautylog.info("Did not publish anything!") : void(0);
|
||||||
|
|
||||||
|
@ -3,18 +3,6 @@ import plugins = require("./npmts.plugins");
|
|||||||
import paths = require("./npmts.paths");
|
import paths = require("./npmts.paths");
|
||||||
import {npmtsOra} from "./npmts.promisechain";
|
import {npmtsOra} from "./npmts.promisechain";
|
||||||
|
|
||||||
export let publishCoverage = function(configArg){
|
|
||||||
let done = plugins.Q.defer();
|
|
||||||
plugins.beautylog.log("now uploading coverage data to codecov.io");
|
|
||||||
var stream = plugins.gulp.src([plugins.path.join(paths.cwd,"./coverage/lcov.info")])
|
|
||||||
.pipe(plugins.g.codecov())
|
|
||||||
.pipe(plugins.g.gFunction(function(){
|
|
||||||
plugins.beautylog.ok("Coverage data has been uploaded to codecov.io!");
|
|
||||||
done.resolve(configArg);
|
|
||||||
},"atEnd"));
|
|
||||||
return done.promise;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @returns {*}
|
* @returns {*}
|
||||||
|
Reference in New Issue
Block a user