@ubiquity-os/plugin-sdk 2.0.6 → 3.1.0
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/dist/index.d.mts +91 -19
- package/dist/index.d.ts +91 -19
- package/dist/index.js +171 -98
- package/dist/index.mjs +168 -95
- package/dist/signature.d.mts +32 -1
- package/dist/signature.d.ts +32 -1
- package/dist/signature.js +38 -0
- package/dist/signature.mjs +37 -0
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -1,17 +1,104 @@
|
|
|
1
1
|
import * as hono_types from 'hono/types';
|
|
2
2
|
import { EmitterWebhookEventName, EmitterWebhookEvent } from '@octokit/webhooks';
|
|
3
3
|
import { Hono } from 'hono';
|
|
4
|
-
import
|
|
4
|
+
import * as _ubiquity_os_ubiquity_os_logger from '@ubiquity-os/ubiquity-os-logger';
|
|
5
|
+
import { LogReturn, Metadata, Logs, LogLevel } from '@ubiquity-os/ubiquity-os-logger';
|
|
6
|
+
import { RestEndpointMethodTypes } from '@octokit/plugin-rest-endpoint-methods';
|
|
5
7
|
import { customOctokit } from './octokit.mjs';
|
|
6
8
|
import { Manifest } from './manifest.mjs';
|
|
7
9
|
import { TAnySchema } from '@sinclair/typebox';
|
|
8
|
-
import { RestEndpointMethodTypes } from '@octokit/plugin-rest-endpoint-methods';
|
|
9
10
|
import '@octokit/core/dist-types/types';
|
|
10
11
|
import '@octokit/plugin-paginate-graphql';
|
|
11
12
|
import '@octokit/plugin-paginate-rest';
|
|
12
13
|
import '@octokit/request-error';
|
|
13
14
|
import '@octokit/core';
|
|
14
15
|
|
|
16
|
+
interface CommentOptions {
|
|
17
|
+
raw?: boolean;
|
|
18
|
+
updateComment?: boolean;
|
|
19
|
+
}
|
|
20
|
+
type PostedGithubComment = RestEndpointMethodTypes["issues"]["updateComment"]["response"]["data"] | RestEndpointMethodTypes["issues"]["createComment"]["response"]["data"] | RestEndpointMethodTypes["pulls"]["createReplyForReviewComment"]["response"]["data"];
|
|
21
|
+
type WithIssueNumber<T> = T & {
|
|
22
|
+
issueNumber: number;
|
|
23
|
+
};
|
|
24
|
+
interface IssueContext {
|
|
25
|
+
issueNumber: number;
|
|
26
|
+
commentId?: number;
|
|
27
|
+
owner: string;
|
|
28
|
+
repo: string;
|
|
29
|
+
}
|
|
30
|
+
declare class CommentHandler {
|
|
31
|
+
static readonly HEADER_NAME = "UbiquityOS";
|
|
32
|
+
private _lastCommentId;
|
|
33
|
+
_updateIssueComment(context: Context, params: {
|
|
34
|
+
owner: string;
|
|
35
|
+
repo: string;
|
|
36
|
+
body: string;
|
|
37
|
+
issueNumber: number;
|
|
38
|
+
}): Promise<WithIssueNumber<PostedGithubComment>>;
|
|
39
|
+
_updateReviewComment(context: Context, params: {
|
|
40
|
+
owner: string;
|
|
41
|
+
repo: string;
|
|
42
|
+
body: string;
|
|
43
|
+
issueNumber: number;
|
|
44
|
+
}): Promise<WithIssueNumber<PostedGithubComment>>;
|
|
45
|
+
_createNewComment(context: Context, params: {
|
|
46
|
+
owner: string;
|
|
47
|
+
repo: string;
|
|
48
|
+
body: string;
|
|
49
|
+
issueNumber: number;
|
|
50
|
+
commentId?: number;
|
|
51
|
+
}): Promise<WithIssueNumber<PostedGithubComment>>;
|
|
52
|
+
_getIssueNumber(context: Context): number | undefined;
|
|
53
|
+
_getCommentId(context: Context): number | undefined;
|
|
54
|
+
_extractIssueContext(context: Context): IssueContext | null;
|
|
55
|
+
_processMessage(context: Context, message: LogReturn | Error): Promise<{
|
|
56
|
+
metadata: {
|
|
57
|
+
message: string;
|
|
58
|
+
name: string;
|
|
59
|
+
stack: string | undefined;
|
|
60
|
+
};
|
|
61
|
+
logMessage: {
|
|
62
|
+
raw: string;
|
|
63
|
+
diff: string;
|
|
64
|
+
level: _ubiquity_os_ubiquity_os_logger.LogLevel;
|
|
65
|
+
type: _ubiquity_os_ubiquity_os_logger.LogLevelWithOk;
|
|
66
|
+
};
|
|
67
|
+
} | {
|
|
68
|
+
metadata: {
|
|
69
|
+
message: string | undefined;
|
|
70
|
+
stack: string | string[] | undefined;
|
|
71
|
+
caller: {} | undefined;
|
|
72
|
+
error?: Error | {
|
|
73
|
+
stack: string;
|
|
74
|
+
} | undefined;
|
|
75
|
+
name?: string | undefined;
|
|
76
|
+
} | {
|
|
77
|
+
logMessage: {
|
|
78
|
+
raw: string;
|
|
79
|
+
diff: string;
|
|
80
|
+
level: _ubiquity_os_ubiquity_os_logger.LogLevel;
|
|
81
|
+
type: _ubiquity_os_ubiquity_os_logger.LogLevelWithOk;
|
|
82
|
+
};
|
|
83
|
+
metadata?: Metadata;
|
|
84
|
+
};
|
|
85
|
+
logMessage: {
|
|
86
|
+
raw: string;
|
|
87
|
+
diff: string;
|
|
88
|
+
level: _ubiquity_os_ubiquity_os_logger.LogLevel;
|
|
89
|
+
type: _ubiquity_os_ubiquity_os_logger.LogLevelWithOk;
|
|
90
|
+
};
|
|
91
|
+
}>;
|
|
92
|
+
_getInstigatorName(context: Context): string;
|
|
93
|
+
_createMetadataContent(context: Context, metadata: Metadata): Promise<{
|
|
94
|
+
header: string;
|
|
95
|
+
jsonPretty: string;
|
|
96
|
+
}>;
|
|
97
|
+
_formatMetadataContent(logMessage: LogReturn["logMessage"], header: string, jsonPretty: string): string;
|
|
98
|
+
_createCommentBody(context: Context, message: LogReturn | Error, options: CommentOptions): Promise<string>;
|
|
99
|
+
postComment(context: Context, message: LogReturn | Error, options?: CommentOptions): Promise<WithIssueNumber<PostedGithubComment> | null>;
|
|
100
|
+
}
|
|
101
|
+
|
|
15
102
|
interface Context<TConfig = unknown, TEnv = unknown, TCommand = unknown, TSupportedEvents extends EmitterWebhookEventName = EmitterWebhookEventName> {
|
|
16
103
|
eventName: TSupportedEvents;
|
|
17
104
|
payload: {
|
|
@@ -22,6 +109,7 @@ interface Context<TConfig = unknown, TEnv = unknown, TCommand = unknown, TSuppor
|
|
|
22
109
|
config: TConfig;
|
|
23
110
|
env: TEnv;
|
|
24
111
|
logger: Logs;
|
|
112
|
+
commentHandler: CommentHandler;
|
|
25
113
|
}
|
|
26
114
|
|
|
27
115
|
type Return = Record<string, unknown> | undefined | void;
|
|
@@ -44,20 +132,4 @@ declare function createPlugin<TConfig = unknown, TEnv = unknown, TCommand = unkn
|
|
|
44
132
|
|
|
45
133
|
declare function createActionsPlugin<TConfig = unknown, TEnv = unknown, TCommand = unknown, TSupportedEvents extends EmitterWebhookEventName = EmitterWebhookEventName>(handler: (context: Context<TConfig, TEnv, TCommand, TSupportedEvents>) => HandlerReturn, options?: Options): Promise<void>;
|
|
46
134
|
|
|
47
|
-
|
|
48
|
-
raw?: boolean;
|
|
49
|
-
updateComment?: boolean;
|
|
50
|
-
}
|
|
51
|
-
type WithIssueNumber<T> = T & {
|
|
52
|
-
issueNumber: number;
|
|
53
|
-
};
|
|
54
|
-
type PostComment = {
|
|
55
|
-
(context: Context, message: LogReturn | Error, options?: CommentOptions): Promise<WithIssueNumber<RestEndpointMethodTypes["issues"]["updateComment"]["response"]["data"] | RestEndpointMethodTypes["issues"]["createComment"]["response"]["data"]> | null>;
|
|
56
|
-
lastCommentId?: number;
|
|
57
|
-
};
|
|
58
|
-
/**
|
|
59
|
-
* Posts a comment on a GitHub issue if the issue exists in the context payload, embedding structured metadata to it.
|
|
60
|
-
*/
|
|
61
|
-
declare const postComment: PostComment;
|
|
62
|
-
|
|
63
|
-
export { type Context, createActionsPlugin, createPlugin, postComment };
|
|
135
|
+
export { CommentHandler, type Context, createActionsPlugin, createPlugin };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,17 +1,104 @@
|
|
|
1
1
|
import * as hono_types from 'hono/types';
|
|
2
2
|
import { EmitterWebhookEventName, EmitterWebhookEvent } from '@octokit/webhooks';
|
|
3
3
|
import { Hono } from 'hono';
|
|
4
|
-
import
|
|
4
|
+
import * as _ubiquity_os_ubiquity_os_logger from '@ubiquity-os/ubiquity-os-logger';
|
|
5
|
+
import { LogReturn, Metadata, Logs, LogLevel } from '@ubiquity-os/ubiquity-os-logger';
|
|
6
|
+
import { RestEndpointMethodTypes } from '@octokit/plugin-rest-endpoint-methods';
|
|
5
7
|
import { customOctokit } from './octokit.js';
|
|
6
8
|
import { Manifest } from './manifest.js';
|
|
7
9
|
import { TAnySchema } from '@sinclair/typebox';
|
|
8
|
-
import { RestEndpointMethodTypes } from '@octokit/plugin-rest-endpoint-methods';
|
|
9
10
|
import '@octokit/core/dist-types/types';
|
|
10
11
|
import '@octokit/plugin-paginate-graphql';
|
|
11
12
|
import '@octokit/plugin-paginate-rest';
|
|
12
13
|
import '@octokit/request-error';
|
|
13
14
|
import '@octokit/core';
|
|
14
15
|
|
|
16
|
+
interface CommentOptions {
|
|
17
|
+
raw?: boolean;
|
|
18
|
+
updateComment?: boolean;
|
|
19
|
+
}
|
|
20
|
+
type PostedGithubComment = RestEndpointMethodTypes["issues"]["updateComment"]["response"]["data"] | RestEndpointMethodTypes["issues"]["createComment"]["response"]["data"] | RestEndpointMethodTypes["pulls"]["createReplyForReviewComment"]["response"]["data"];
|
|
21
|
+
type WithIssueNumber<T> = T & {
|
|
22
|
+
issueNumber: number;
|
|
23
|
+
};
|
|
24
|
+
interface IssueContext {
|
|
25
|
+
issueNumber: number;
|
|
26
|
+
commentId?: number;
|
|
27
|
+
owner: string;
|
|
28
|
+
repo: string;
|
|
29
|
+
}
|
|
30
|
+
declare class CommentHandler {
|
|
31
|
+
static readonly HEADER_NAME = "UbiquityOS";
|
|
32
|
+
private _lastCommentId;
|
|
33
|
+
_updateIssueComment(context: Context, params: {
|
|
34
|
+
owner: string;
|
|
35
|
+
repo: string;
|
|
36
|
+
body: string;
|
|
37
|
+
issueNumber: number;
|
|
38
|
+
}): Promise<WithIssueNumber<PostedGithubComment>>;
|
|
39
|
+
_updateReviewComment(context: Context, params: {
|
|
40
|
+
owner: string;
|
|
41
|
+
repo: string;
|
|
42
|
+
body: string;
|
|
43
|
+
issueNumber: number;
|
|
44
|
+
}): Promise<WithIssueNumber<PostedGithubComment>>;
|
|
45
|
+
_createNewComment(context: Context, params: {
|
|
46
|
+
owner: string;
|
|
47
|
+
repo: string;
|
|
48
|
+
body: string;
|
|
49
|
+
issueNumber: number;
|
|
50
|
+
commentId?: number;
|
|
51
|
+
}): Promise<WithIssueNumber<PostedGithubComment>>;
|
|
52
|
+
_getIssueNumber(context: Context): number | undefined;
|
|
53
|
+
_getCommentId(context: Context): number | undefined;
|
|
54
|
+
_extractIssueContext(context: Context): IssueContext | null;
|
|
55
|
+
_processMessage(context: Context, message: LogReturn | Error): Promise<{
|
|
56
|
+
metadata: {
|
|
57
|
+
message: string;
|
|
58
|
+
name: string;
|
|
59
|
+
stack: string | undefined;
|
|
60
|
+
};
|
|
61
|
+
logMessage: {
|
|
62
|
+
raw: string;
|
|
63
|
+
diff: string;
|
|
64
|
+
level: _ubiquity_os_ubiquity_os_logger.LogLevel;
|
|
65
|
+
type: _ubiquity_os_ubiquity_os_logger.LogLevelWithOk;
|
|
66
|
+
};
|
|
67
|
+
} | {
|
|
68
|
+
metadata: {
|
|
69
|
+
message: string | undefined;
|
|
70
|
+
stack: string | string[] | undefined;
|
|
71
|
+
caller: {} | undefined;
|
|
72
|
+
error?: Error | {
|
|
73
|
+
stack: string;
|
|
74
|
+
} | undefined;
|
|
75
|
+
name?: string | undefined;
|
|
76
|
+
} | {
|
|
77
|
+
logMessage: {
|
|
78
|
+
raw: string;
|
|
79
|
+
diff: string;
|
|
80
|
+
level: _ubiquity_os_ubiquity_os_logger.LogLevel;
|
|
81
|
+
type: _ubiquity_os_ubiquity_os_logger.LogLevelWithOk;
|
|
82
|
+
};
|
|
83
|
+
metadata?: Metadata;
|
|
84
|
+
};
|
|
85
|
+
logMessage: {
|
|
86
|
+
raw: string;
|
|
87
|
+
diff: string;
|
|
88
|
+
level: _ubiquity_os_ubiquity_os_logger.LogLevel;
|
|
89
|
+
type: _ubiquity_os_ubiquity_os_logger.LogLevelWithOk;
|
|
90
|
+
};
|
|
91
|
+
}>;
|
|
92
|
+
_getInstigatorName(context: Context): string;
|
|
93
|
+
_createMetadataContent(context: Context, metadata: Metadata): Promise<{
|
|
94
|
+
header: string;
|
|
95
|
+
jsonPretty: string;
|
|
96
|
+
}>;
|
|
97
|
+
_formatMetadataContent(logMessage: LogReturn["logMessage"], header: string, jsonPretty: string): string;
|
|
98
|
+
_createCommentBody(context: Context, message: LogReturn | Error, options: CommentOptions): Promise<string>;
|
|
99
|
+
postComment(context: Context, message: LogReturn | Error, options?: CommentOptions): Promise<WithIssueNumber<PostedGithubComment> | null>;
|
|
100
|
+
}
|
|
101
|
+
|
|
15
102
|
interface Context<TConfig = unknown, TEnv = unknown, TCommand = unknown, TSupportedEvents extends EmitterWebhookEventName = EmitterWebhookEventName> {
|
|
16
103
|
eventName: TSupportedEvents;
|
|
17
104
|
payload: {
|
|
@@ -22,6 +109,7 @@ interface Context<TConfig = unknown, TEnv = unknown, TCommand = unknown, TSuppor
|
|
|
22
109
|
config: TConfig;
|
|
23
110
|
env: TEnv;
|
|
24
111
|
logger: Logs;
|
|
112
|
+
commentHandler: CommentHandler;
|
|
25
113
|
}
|
|
26
114
|
|
|
27
115
|
type Return = Record<string, unknown> | undefined | void;
|
|
@@ -44,20 +132,4 @@ declare function createPlugin<TConfig = unknown, TEnv = unknown, TCommand = unkn
|
|
|
44
132
|
|
|
45
133
|
declare function createActionsPlugin<TConfig = unknown, TEnv = unknown, TCommand = unknown, TSupportedEvents extends EmitterWebhookEventName = EmitterWebhookEventName>(handler: (context: Context<TConfig, TEnv, TCommand, TSupportedEvents>) => HandlerReturn, options?: Options): Promise<void>;
|
|
46
134
|
|
|
47
|
-
|
|
48
|
-
raw?: boolean;
|
|
49
|
-
updateComment?: boolean;
|
|
50
|
-
}
|
|
51
|
-
type WithIssueNumber<T> = T & {
|
|
52
|
-
issueNumber: number;
|
|
53
|
-
};
|
|
54
|
-
type PostComment = {
|
|
55
|
-
(context: Context, message: LogReturn | Error, options?: CommentOptions): Promise<WithIssueNumber<RestEndpointMethodTypes["issues"]["updateComment"]["response"]["data"] | RestEndpointMethodTypes["issues"]["createComment"]["response"]["data"]> | null>;
|
|
56
|
-
lastCommentId?: number;
|
|
57
|
-
};
|
|
58
|
-
/**
|
|
59
|
-
* Posts a comment on a GitHub issue if the issue exists in the context payload, embedding structured metadata to it.
|
|
60
|
-
*/
|
|
61
|
-
declare const postComment: PostComment;
|
|
62
|
-
|
|
63
|
-
export { type Context, createActionsPlugin, createPlugin, postComment };
|
|
135
|
+
export { CommentHandler, type Context, createActionsPlugin, createPlugin };
|
package/dist/index.js
CHANGED
|
@@ -30,15 +30,15 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/index.ts
|
|
31
31
|
var src_exports = {};
|
|
32
32
|
__export(src_exports, {
|
|
33
|
+
CommentHandler: () => CommentHandler,
|
|
33
34
|
createActionsPlugin: () => createActionsPlugin,
|
|
34
|
-
createPlugin: () => createPlugin
|
|
35
|
-
postComment: () => postComment
|
|
35
|
+
createPlugin: () => createPlugin
|
|
36
36
|
});
|
|
37
37
|
module.exports = __toCommonJS(src_exports);
|
|
38
38
|
|
|
39
39
|
// src/server.ts
|
|
40
40
|
var import_value2 = require("@sinclair/typebox/value");
|
|
41
|
-
var
|
|
41
|
+
var import_ubiquity_os_logger3 = require("@ubiquity-os/ubiquity-os-logger");
|
|
42
42
|
var import_hono = require("hono");
|
|
43
43
|
var import_adapter2 = require("hono/adapter");
|
|
44
44
|
var import_http_exception = require("hono/http-exception");
|
|
@@ -116,89 +116,168 @@ function getPluginOptions(options) {
|
|
|
116
116
|
}
|
|
117
117
|
|
|
118
118
|
// src/comment.ts
|
|
119
|
-
var
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
119
|
+
var CommentHandler = class _CommentHandler {
|
|
120
|
+
static HEADER_NAME = "UbiquityOS";
|
|
121
|
+
_lastCommentId = { reviewCommentId: null, issueCommentId: null };
|
|
122
|
+
async _updateIssueComment(context2, params) {
|
|
123
|
+
if (!this._lastCommentId.issueCommentId) {
|
|
124
|
+
throw context2.logger.error("issueCommentId is missing");
|
|
125
|
+
}
|
|
126
|
+
const commentData = await context2.octokit.rest.issues.updateComment({
|
|
127
|
+
owner: params.owner,
|
|
128
|
+
repo: params.repo,
|
|
129
|
+
comment_id: this._lastCommentId.issueCommentId,
|
|
130
|
+
body: params.body
|
|
131
|
+
});
|
|
132
|
+
return { ...commentData.data, issueNumber: params.issueNumber };
|
|
131
133
|
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
134
|
+
async _updateReviewComment(context2, params) {
|
|
135
|
+
if (!this._lastCommentId.reviewCommentId) {
|
|
136
|
+
throw context2.logger.error("reviewCommentId is missing");
|
|
137
|
+
}
|
|
138
|
+
const commentData = await context2.octokit.rest.pulls.updateReviewComment({
|
|
139
|
+
owner: params.owner,
|
|
140
|
+
repo: params.repo,
|
|
141
|
+
comment_id: this._lastCommentId.reviewCommentId,
|
|
142
|
+
body: params.body
|
|
143
|
+
});
|
|
144
|
+
return { ...commentData.data, issueNumber: params.issueNumber };
|
|
145
|
+
}
|
|
146
|
+
async _createNewComment(context2, params) {
|
|
147
|
+
if (params.commentId) {
|
|
148
|
+
const commentData2 = await context2.octokit.rest.pulls.createReplyForReviewComment({
|
|
149
|
+
owner: params.owner,
|
|
150
|
+
repo: params.repo,
|
|
151
|
+
pull_number: params.issueNumber,
|
|
152
|
+
comment_id: params.commentId,
|
|
153
|
+
body: params.body
|
|
148
154
|
});
|
|
149
|
-
|
|
150
|
-
return { ...
|
|
155
|
+
this._lastCommentId.reviewCommentId = commentData2.data.id;
|
|
156
|
+
return { ...commentData2.data, issueNumber: params.issueNumber };
|
|
151
157
|
}
|
|
152
|
-
|
|
153
|
-
|
|
158
|
+
const commentData = await context2.octokit.rest.issues.createComment({
|
|
159
|
+
owner: params.owner,
|
|
160
|
+
repo: params.repo,
|
|
161
|
+
issue_number: params.issueNumber,
|
|
162
|
+
body: params.body
|
|
163
|
+
});
|
|
164
|
+
this._lastCommentId.issueCommentId = commentData.data.id;
|
|
165
|
+
return { ...commentData.data, issueNumber: params.issueNumber };
|
|
154
166
|
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
+
_getIssueNumber(context2) {
|
|
168
|
+
if ("issue" in context2.payload) return context2.payload.issue.number;
|
|
169
|
+
if ("pull_request" in context2.payload) return context2.payload.pull_request.number;
|
|
170
|
+
if ("discussion" in context2.payload) return context2.payload.discussion.number;
|
|
171
|
+
return void 0;
|
|
172
|
+
}
|
|
173
|
+
_getCommentId(context2) {
|
|
174
|
+
return "pull_request" in context2.payload && "comment" in context2.payload ? context2.payload.comment.id : void 0;
|
|
175
|
+
}
|
|
176
|
+
_extractIssueContext(context2) {
|
|
177
|
+
if (!("repository" in context2.payload) || !context2.payload.repository?.owner?.login) {
|
|
178
|
+
return null;
|
|
179
|
+
}
|
|
180
|
+
const issueNumber = this._getIssueNumber(context2);
|
|
181
|
+
if (!issueNumber) return null;
|
|
182
|
+
return {
|
|
183
|
+
issueNumber,
|
|
184
|
+
commentId: this._getCommentId(context2),
|
|
185
|
+
owner: context2.payload.repository.owner.login,
|
|
186
|
+
repo: context2.payload.repository.name
|
|
167
187
|
};
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
188
|
+
}
|
|
189
|
+
async _processMessage(context2, message) {
|
|
190
|
+
if (message instanceof Error) {
|
|
191
|
+
const metadata2 = {
|
|
192
|
+
message: message.message,
|
|
193
|
+
name: message.name,
|
|
194
|
+
stack: message.stack
|
|
195
|
+
};
|
|
196
|
+
return { metadata: metadata2, logMessage: context2.logger.error(message.message).logMessage };
|
|
197
|
+
}
|
|
198
|
+
const metadata = message.metadata ? {
|
|
199
|
+
...message.metadata,
|
|
172
200
|
message: message.metadata.message,
|
|
173
201
|
stack: message.metadata.stack || message.metadata.error?.stack,
|
|
174
202
|
caller: message.metadata.caller || message.metadata.error?.stack?.split("\n")[2]?.match(/at (\S+)/)?.[1]
|
|
175
|
-
};
|
|
176
|
-
logMessage
|
|
177
|
-
callingFnName = metadata.caller;
|
|
178
|
-
} else {
|
|
179
|
-
metadata = { ...message };
|
|
203
|
+
} : { ...message };
|
|
204
|
+
return { metadata, logMessage: message.logMessage };
|
|
180
205
|
}
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
206
|
+
_getInstigatorName(context2) {
|
|
207
|
+
if ("installation" in context2.payload && context2.payload.installation && "account" in context2.payload.installation && context2.payload.installation?.account?.name) {
|
|
208
|
+
return context2.payload.installation?.account?.name;
|
|
209
|
+
}
|
|
210
|
+
return context2.payload.sender?.login || _CommentHandler.HEADER_NAME;
|
|
186
211
|
}
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
212
|
+
async _createMetadataContent(context2, metadata) {
|
|
213
|
+
const jsonPretty = sanitizeMetadata(metadata);
|
|
214
|
+
const instigatorName = this._getInstigatorName(context2);
|
|
215
|
+
const runUrl = PluginRuntimeInfo.getInstance().runUrl;
|
|
216
|
+
const version = await PluginRuntimeInfo.getInstance().version;
|
|
217
|
+
const callingFnName = metadata.caller || "anonymous";
|
|
218
|
+
return {
|
|
219
|
+
header: `<!-- ${_CommentHandler.HEADER_NAME} - ${callingFnName} - ${version} - @${instigatorName} - ${runUrl}`,
|
|
220
|
+
jsonPretty
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
_formatMetadataContent(logMessage, header, jsonPretty) {
|
|
224
|
+
const metadataVisible = ["```json", jsonPretty, "```"].join("\n");
|
|
225
|
+
const metadataHidden = [header, jsonPretty, "-->"].join("\n");
|
|
226
|
+
return logMessage?.type === "fatal" ? [metadataVisible, metadataHidden].join("\n") : metadataHidden;
|
|
197
227
|
}
|
|
198
|
-
|
|
228
|
+
async _createCommentBody(context2, message, options) {
|
|
229
|
+
const { metadata, logMessage } = await this._processMessage(context2, message);
|
|
230
|
+
const { header, jsonPretty } = await this._createMetadataContent(context2, metadata);
|
|
231
|
+
const metadataContent = this._formatMetadataContent(logMessage, header, jsonPretty);
|
|
232
|
+
return `${options.raw ? logMessage?.raw : logMessage?.diff}
|
|
199
233
|
|
|
200
|
-
${
|
|
234
|
+
${metadataContent}
|
|
201
235
|
`;
|
|
236
|
+
}
|
|
237
|
+
async postComment(context2, message, options = { updateComment: true, raw: false }) {
|
|
238
|
+
const issueContext = this._extractIssueContext(context2);
|
|
239
|
+
if (!issueContext) {
|
|
240
|
+
context2.logger.info("Cannot post comment: missing issue context in payload");
|
|
241
|
+
return null;
|
|
242
|
+
}
|
|
243
|
+
const body = await this._createCommentBody(context2, message, options);
|
|
244
|
+
const { issueNumber, commentId, owner, repo } = issueContext;
|
|
245
|
+
const params = { owner, repo, body, issueNumber };
|
|
246
|
+
if (options.updateComment) {
|
|
247
|
+
if (this._lastCommentId.issueCommentId && !("pull_request" in context2.payload && "comment" in context2.payload)) {
|
|
248
|
+
return this._updateIssueComment(context2, params);
|
|
249
|
+
}
|
|
250
|
+
if (this._lastCommentId.reviewCommentId && "pull_request" in context2.payload && "comment" in context2.payload) {
|
|
251
|
+
return this._updateReviewComment(context2, params);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
return this._createNewComment(context2, { ...params, commentId });
|
|
255
|
+
}
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
// src/error.ts
|
|
259
|
+
var import_ubiquity_os_logger2 = require("@ubiquity-os/ubiquity-os-logger");
|
|
260
|
+
function transformError(context2, error) {
|
|
261
|
+
let loggerError;
|
|
262
|
+
if (error instanceof AggregateError) {
|
|
263
|
+
loggerError = context2.logger.error(
|
|
264
|
+
error.errors.map((err) => {
|
|
265
|
+
if (err instanceof import_ubiquity_os_logger2.LogReturn) {
|
|
266
|
+
return err.logMessage.raw;
|
|
267
|
+
} else if (err instanceof Error) {
|
|
268
|
+
return err.message;
|
|
269
|
+
} else {
|
|
270
|
+
return err;
|
|
271
|
+
}
|
|
272
|
+
}).join("\n\n"),
|
|
273
|
+
{ error }
|
|
274
|
+
);
|
|
275
|
+
} else if (error instanceof Error || error instanceof import_ubiquity_os_logger2.LogReturn) {
|
|
276
|
+
loggerError = error;
|
|
277
|
+
} else {
|
|
278
|
+
loggerError = context2.logger.error(String(error));
|
|
279
|
+
}
|
|
280
|
+
return loggerError;
|
|
202
281
|
}
|
|
203
282
|
|
|
204
283
|
// src/octokit.ts
|
|
@@ -297,7 +376,7 @@ function createPlugin(handler, manifest, options) {
|
|
|
297
376
|
app.get("/manifest.json", (ctx) => {
|
|
298
377
|
return ctx.json(manifest);
|
|
299
378
|
});
|
|
300
|
-
app.post("/", async (ctx)
|
|
379
|
+
app.post("/", async function appPost(ctx) {
|
|
301
380
|
if (ctx.req.header("content-type") !== "application/json") {
|
|
302
381
|
throw new import_http_exception.HTTPException(400, { message: "Content-Type must be application/json" });
|
|
303
382
|
}
|
|
@@ -355,21 +434,17 @@ function createPlugin(handler, manifest, options) {
|
|
|
355
434
|
octokit: new customOctokit({ auth: inputs.authToken }),
|
|
356
435
|
config: config2,
|
|
357
436
|
env,
|
|
358
|
-
logger: new
|
|
437
|
+
logger: new import_ubiquity_os_logger3.Logs(pluginOptions.logLevel),
|
|
438
|
+
commentHandler: new CommentHandler()
|
|
359
439
|
};
|
|
360
440
|
try {
|
|
361
441
|
const result = await handler(context2);
|
|
362
442
|
return ctx.json({ stateId: inputs.stateId, output: result ?? {} });
|
|
363
443
|
} catch (error) {
|
|
364
444
|
console.error(error);
|
|
365
|
-
|
|
366
|
-
if (error instanceof Error || error instanceof import_ubiquity_os_logger2.LogReturn) {
|
|
367
|
-
loggerError = error;
|
|
368
|
-
} else {
|
|
369
|
-
loggerError = context2.logger.error(`Error: ${error}`);
|
|
370
|
-
}
|
|
445
|
+
const loggerError = transformError(context2, error);
|
|
371
446
|
if (pluginOptions.postCommentOnError && loggerError) {
|
|
372
|
-
await postComment(context2, loggerError);
|
|
447
|
+
await context2.commentHandler.postComment(context2, loggerError);
|
|
373
448
|
}
|
|
374
449
|
throw new import_http_exception.HTTPException(500, { message: "Unexpected error" });
|
|
375
450
|
}
|
|
@@ -381,7 +456,7 @@ function createPlugin(handler, manifest, options) {
|
|
|
381
456
|
var core = __toESM(require("@actions/core"));
|
|
382
457
|
var github2 = __toESM(require("@actions/github"));
|
|
383
458
|
var import_value3 = require("@sinclair/typebox/value");
|
|
384
|
-
var
|
|
459
|
+
var import_ubiquity_os_logger4 = require("@ubiquity-os/ubiquity-os-logger");
|
|
385
460
|
var import_dotenv = require("dotenv");
|
|
386
461
|
(0, import_dotenv.config)();
|
|
387
462
|
async function createActionsPlugin(handler, options) {
|
|
@@ -395,7 +470,7 @@ async function createActionsPlugin(handler, options) {
|
|
|
395
470
|
const inputSchemaErrors = [...import_value3.Value.Errors(inputSchema, body)];
|
|
396
471
|
if (inputSchemaErrors.length) {
|
|
397
472
|
console.dir(inputSchemaErrors, { depth: null });
|
|
398
|
-
core.setFailed(`Error: Invalid inputs payload: ${inputSchemaErrors.join(",")}`);
|
|
473
|
+
core.setFailed(`Error: Invalid inputs payload: ${inputSchemaErrors.map((o) => o.message).join(", ")}`);
|
|
399
474
|
return;
|
|
400
475
|
}
|
|
401
476
|
const signature = body.signature;
|
|
@@ -410,6 +485,7 @@ async function createActionsPlugin(handler, options) {
|
|
|
410
485
|
config2 = import_value3.Value.Decode(pluginOptions.settingsSchema, import_value3.Value.Default(pluginOptions.settingsSchema, inputs.settings));
|
|
411
486
|
} catch (e) {
|
|
412
487
|
console.dir(...import_value3.Value.Errors(pluginOptions.settingsSchema, inputs.settings), { depth: null });
|
|
488
|
+
core.setFailed(`Error: Invalid settings provided.`);
|
|
413
489
|
throw e;
|
|
414
490
|
}
|
|
415
491
|
} else {
|
|
@@ -421,6 +497,7 @@ async function createActionsPlugin(handler, options) {
|
|
|
421
497
|
env = import_value3.Value.Decode(pluginOptions.envSchema, import_value3.Value.Default(pluginOptions.envSchema, process.env));
|
|
422
498
|
} catch (e) {
|
|
423
499
|
console.dir(...import_value3.Value.Errors(pluginOptions.envSchema, process.env), { depth: null });
|
|
500
|
+
core.setFailed(`Error: Invalid environment provided.`);
|
|
424
501
|
throw e;
|
|
425
502
|
}
|
|
426
503
|
} else {
|
|
@@ -444,7 +521,8 @@ async function createActionsPlugin(handler, options) {
|
|
|
444
521
|
octokit: new customOctokit({ auth: inputs.authToken }),
|
|
445
522
|
config: config2,
|
|
446
523
|
env,
|
|
447
|
-
logger: new
|
|
524
|
+
logger: new import_ubiquity_os_logger4.Logs(pluginOptions.logLevel),
|
|
525
|
+
commentHandler: new CommentHandler()
|
|
448
526
|
};
|
|
449
527
|
try {
|
|
450
528
|
const result = await handler(context2);
|
|
@@ -452,19 +530,14 @@ async function createActionsPlugin(handler, options) {
|
|
|
452
530
|
await returnDataToKernel(pluginGithubToken, inputs.stateId, result);
|
|
453
531
|
} catch (error) {
|
|
454
532
|
console.error(error);
|
|
455
|
-
|
|
456
|
-
if (
|
|
457
|
-
core.setFailed(
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
core.setFailed(error.logMessage.raw);
|
|
461
|
-
loggerError = error;
|
|
462
|
-
} else {
|
|
463
|
-
core.setFailed(`Error: ${error}`);
|
|
464
|
-
loggerError = context2.logger.error(`Error: ${error}`);
|
|
533
|
+
const loggerError = transformError(context2, error);
|
|
534
|
+
if (loggerError instanceof import_ubiquity_os_logger4.LogReturn) {
|
|
535
|
+
core.setFailed(loggerError.logMessage.diff);
|
|
536
|
+
} else if (loggerError instanceof Error) {
|
|
537
|
+
core.setFailed(loggerError);
|
|
465
538
|
}
|
|
466
539
|
if (pluginOptions.postCommentOnError && loggerError) {
|
|
467
|
-
await postComment(context2, loggerError);
|
|
540
|
+
await context2.commentHandler.postComment(context2, loggerError);
|
|
468
541
|
}
|
|
469
542
|
}
|
|
470
543
|
}
|
|
@@ -482,7 +555,7 @@ async function returnDataToKernel(repoToken, stateId, output) {
|
|
|
482
555
|
}
|
|
483
556
|
// Annotate the CommonJS export names for ESM import in node:
|
|
484
557
|
0 && (module.exports = {
|
|
558
|
+
CommentHandler,
|
|
485
559
|
createActionsPlugin,
|
|
486
|
-
createPlugin
|
|
487
|
-
postComment
|
|
560
|
+
createPlugin
|
|
488
561
|
});
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// src/server.ts
|
|
2
2
|
import { Value as Value2 } from "@sinclair/typebox/value";
|
|
3
|
-
import {
|
|
3
|
+
import { Logs } from "@ubiquity-os/ubiquity-os-logger";
|
|
4
4
|
import { Hono } from "hono";
|
|
5
5
|
import { env as honoEnv } from "hono/adapter";
|
|
6
6
|
import { HTTPException } from "hono/http-exception";
|
|
@@ -78,89 +78,168 @@ function getPluginOptions(options) {
|
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
// src/comment.ts
|
|
81
|
-
var
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
81
|
+
var CommentHandler = class _CommentHandler {
|
|
82
|
+
static HEADER_NAME = "UbiquityOS";
|
|
83
|
+
_lastCommentId = { reviewCommentId: null, issueCommentId: null };
|
|
84
|
+
async _updateIssueComment(context2, params) {
|
|
85
|
+
if (!this._lastCommentId.issueCommentId) {
|
|
86
|
+
throw context2.logger.error("issueCommentId is missing");
|
|
87
|
+
}
|
|
88
|
+
const commentData = await context2.octokit.rest.issues.updateComment({
|
|
89
|
+
owner: params.owner,
|
|
90
|
+
repo: params.repo,
|
|
91
|
+
comment_id: this._lastCommentId.issueCommentId,
|
|
92
|
+
body: params.body
|
|
93
|
+
});
|
|
94
|
+
return { ...commentData.data, issueNumber: params.issueNumber };
|
|
93
95
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
96
|
+
async _updateReviewComment(context2, params) {
|
|
97
|
+
if (!this._lastCommentId.reviewCommentId) {
|
|
98
|
+
throw context2.logger.error("reviewCommentId is missing");
|
|
99
|
+
}
|
|
100
|
+
const commentData = await context2.octokit.rest.pulls.updateReviewComment({
|
|
101
|
+
owner: params.owner,
|
|
102
|
+
repo: params.repo,
|
|
103
|
+
comment_id: this._lastCommentId.reviewCommentId,
|
|
104
|
+
body: params.body
|
|
105
|
+
});
|
|
106
|
+
return { ...commentData.data, issueNumber: params.issueNumber };
|
|
107
|
+
}
|
|
108
|
+
async _createNewComment(context2, params) {
|
|
109
|
+
if (params.commentId) {
|
|
110
|
+
const commentData2 = await context2.octokit.rest.pulls.createReplyForReviewComment({
|
|
111
|
+
owner: params.owner,
|
|
112
|
+
repo: params.repo,
|
|
113
|
+
pull_number: params.issueNumber,
|
|
114
|
+
comment_id: params.commentId,
|
|
115
|
+
body: params.body
|
|
110
116
|
});
|
|
111
|
-
|
|
112
|
-
return { ...
|
|
117
|
+
this._lastCommentId.reviewCommentId = commentData2.data.id;
|
|
118
|
+
return { ...commentData2.data, issueNumber: params.issueNumber };
|
|
113
119
|
}
|
|
114
|
-
|
|
115
|
-
|
|
120
|
+
const commentData = await context2.octokit.rest.issues.createComment({
|
|
121
|
+
owner: params.owner,
|
|
122
|
+
repo: params.repo,
|
|
123
|
+
issue_number: params.issueNumber,
|
|
124
|
+
body: params.body
|
|
125
|
+
});
|
|
126
|
+
this._lastCommentId.issueCommentId = commentData.data.id;
|
|
127
|
+
return { ...commentData.data, issueNumber: params.issueNumber };
|
|
116
128
|
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
+
_getIssueNumber(context2) {
|
|
130
|
+
if ("issue" in context2.payload) return context2.payload.issue.number;
|
|
131
|
+
if ("pull_request" in context2.payload) return context2.payload.pull_request.number;
|
|
132
|
+
if ("discussion" in context2.payload) return context2.payload.discussion.number;
|
|
133
|
+
return void 0;
|
|
134
|
+
}
|
|
135
|
+
_getCommentId(context2) {
|
|
136
|
+
return "pull_request" in context2.payload && "comment" in context2.payload ? context2.payload.comment.id : void 0;
|
|
137
|
+
}
|
|
138
|
+
_extractIssueContext(context2) {
|
|
139
|
+
if (!("repository" in context2.payload) || !context2.payload.repository?.owner?.login) {
|
|
140
|
+
return null;
|
|
141
|
+
}
|
|
142
|
+
const issueNumber = this._getIssueNumber(context2);
|
|
143
|
+
if (!issueNumber) return null;
|
|
144
|
+
return {
|
|
145
|
+
issueNumber,
|
|
146
|
+
commentId: this._getCommentId(context2),
|
|
147
|
+
owner: context2.payload.repository.owner.login,
|
|
148
|
+
repo: context2.payload.repository.name
|
|
129
149
|
};
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
150
|
+
}
|
|
151
|
+
async _processMessage(context2, message) {
|
|
152
|
+
if (message instanceof Error) {
|
|
153
|
+
const metadata2 = {
|
|
154
|
+
message: message.message,
|
|
155
|
+
name: message.name,
|
|
156
|
+
stack: message.stack
|
|
157
|
+
};
|
|
158
|
+
return { metadata: metadata2, logMessage: context2.logger.error(message.message).logMessage };
|
|
159
|
+
}
|
|
160
|
+
const metadata = message.metadata ? {
|
|
161
|
+
...message.metadata,
|
|
134
162
|
message: message.metadata.message,
|
|
135
163
|
stack: message.metadata.stack || message.metadata.error?.stack,
|
|
136
164
|
caller: message.metadata.caller || message.metadata.error?.stack?.split("\n")[2]?.match(/at (\S+)/)?.[1]
|
|
137
|
-
};
|
|
138
|
-
logMessage
|
|
139
|
-
callingFnName = metadata.caller;
|
|
140
|
-
} else {
|
|
141
|
-
metadata = { ...message };
|
|
165
|
+
} : { ...message };
|
|
166
|
+
return { metadata, logMessage: message.logMessage };
|
|
142
167
|
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
168
|
+
_getInstigatorName(context2) {
|
|
169
|
+
if ("installation" in context2.payload && context2.payload.installation && "account" in context2.payload.installation && context2.payload.installation?.account?.name) {
|
|
170
|
+
return context2.payload.installation?.account?.name;
|
|
171
|
+
}
|
|
172
|
+
return context2.payload.sender?.login || _CommentHandler.HEADER_NAME;
|
|
148
173
|
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
174
|
+
async _createMetadataContent(context2, metadata) {
|
|
175
|
+
const jsonPretty = sanitizeMetadata(metadata);
|
|
176
|
+
const instigatorName = this._getInstigatorName(context2);
|
|
177
|
+
const runUrl = PluginRuntimeInfo.getInstance().runUrl;
|
|
178
|
+
const version = await PluginRuntimeInfo.getInstance().version;
|
|
179
|
+
const callingFnName = metadata.caller || "anonymous";
|
|
180
|
+
return {
|
|
181
|
+
header: `<!-- ${_CommentHandler.HEADER_NAME} - ${callingFnName} - ${version} - @${instigatorName} - ${runUrl}`,
|
|
182
|
+
jsonPretty
|
|
183
|
+
};
|
|
159
184
|
}
|
|
160
|
-
|
|
185
|
+
_formatMetadataContent(logMessage, header, jsonPretty) {
|
|
186
|
+
const metadataVisible = ["```json", jsonPretty, "```"].join("\n");
|
|
187
|
+
const metadataHidden = [header, jsonPretty, "-->"].join("\n");
|
|
188
|
+
return logMessage?.type === "fatal" ? [metadataVisible, metadataHidden].join("\n") : metadataHidden;
|
|
189
|
+
}
|
|
190
|
+
async _createCommentBody(context2, message, options) {
|
|
191
|
+
const { metadata, logMessage } = await this._processMessage(context2, message);
|
|
192
|
+
const { header, jsonPretty } = await this._createMetadataContent(context2, metadata);
|
|
193
|
+
const metadataContent = this._formatMetadataContent(logMessage, header, jsonPretty);
|
|
194
|
+
return `${options.raw ? logMessage?.raw : logMessage?.diff}
|
|
161
195
|
|
|
162
|
-
${
|
|
196
|
+
${metadataContent}
|
|
163
197
|
`;
|
|
198
|
+
}
|
|
199
|
+
async postComment(context2, message, options = { updateComment: true, raw: false }) {
|
|
200
|
+
const issueContext = this._extractIssueContext(context2);
|
|
201
|
+
if (!issueContext) {
|
|
202
|
+
context2.logger.info("Cannot post comment: missing issue context in payload");
|
|
203
|
+
return null;
|
|
204
|
+
}
|
|
205
|
+
const body = await this._createCommentBody(context2, message, options);
|
|
206
|
+
const { issueNumber, commentId, owner, repo } = issueContext;
|
|
207
|
+
const params = { owner, repo, body, issueNumber };
|
|
208
|
+
if (options.updateComment) {
|
|
209
|
+
if (this._lastCommentId.issueCommentId && !("pull_request" in context2.payload && "comment" in context2.payload)) {
|
|
210
|
+
return this._updateIssueComment(context2, params);
|
|
211
|
+
}
|
|
212
|
+
if (this._lastCommentId.reviewCommentId && "pull_request" in context2.payload && "comment" in context2.payload) {
|
|
213
|
+
return this._updateReviewComment(context2, params);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
return this._createNewComment(context2, { ...params, commentId });
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
|
|
220
|
+
// src/error.ts
|
|
221
|
+
import { LogReturn as LogReturn2 } from "@ubiquity-os/ubiquity-os-logger";
|
|
222
|
+
function transformError(context2, error) {
|
|
223
|
+
let loggerError;
|
|
224
|
+
if (error instanceof AggregateError) {
|
|
225
|
+
loggerError = context2.logger.error(
|
|
226
|
+
error.errors.map((err) => {
|
|
227
|
+
if (err instanceof LogReturn2) {
|
|
228
|
+
return err.logMessage.raw;
|
|
229
|
+
} else if (err instanceof Error) {
|
|
230
|
+
return err.message;
|
|
231
|
+
} else {
|
|
232
|
+
return err;
|
|
233
|
+
}
|
|
234
|
+
}).join("\n\n"),
|
|
235
|
+
{ error }
|
|
236
|
+
);
|
|
237
|
+
} else if (error instanceof Error || error instanceof LogReturn2) {
|
|
238
|
+
loggerError = error;
|
|
239
|
+
} else {
|
|
240
|
+
loggerError = context2.logger.error(String(error));
|
|
241
|
+
}
|
|
242
|
+
return loggerError;
|
|
164
243
|
}
|
|
165
244
|
|
|
166
245
|
// src/octokit.ts
|
|
@@ -259,7 +338,7 @@ function createPlugin(handler, manifest, options) {
|
|
|
259
338
|
app.get("/manifest.json", (ctx) => {
|
|
260
339
|
return ctx.json(manifest);
|
|
261
340
|
});
|
|
262
|
-
app.post("/", async (ctx)
|
|
341
|
+
app.post("/", async function appPost(ctx) {
|
|
263
342
|
if (ctx.req.header("content-type") !== "application/json") {
|
|
264
343
|
throw new HTTPException(400, { message: "Content-Type must be application/json" });
|
|
265
344
|
}
|
|
@@ -317,21 +396,17 @@ function createPlugin(handler, manifest, options) {
|
|
|
317
396
|
octokit: new customOctokit({ auth: inputs.authToken }),
|
|
318
397
|
config: config2,
|
|
319
398
|
env,
|
|
320
|
-
logger: new Logs(pluginOptions.logLevel)
|
|
399
|
+
logger: new Logs(pluginOptions.logLevel),
|
|
400
|
+
commentHandler: new CommentHandler()
|
|
321
401
|
};
|
|
322
402
|
try {
|
|
323
403
|
const result = await handler(context2);
|
|
324
404
|
return ctx.json({ stateId: inputs.stateId, output: result ?? {} });
|
|
325
405
|
} catch (error) {
|
|
326
406
|
console.error(error);
|
|
327
|
-
|
|
328
|
-
if (error instanceof Error || error instanceof LogReturn2) {
|
|
329
|
-
loggerError = error;
|
|
330
|
-
} else {
|
|
331
|
-
loggerError = context2.logger.error(`Error: ${error}`);
|
|
332
|
-
}
|
|
407
|
+
const loggerError = transformError(context2, error);
|
|
333
408
|
if (pluginOptions.postCommentOnError && loggerError) {
|
|
334
|
-
await postComment(context2, loggerError);
|
|
409
|
+
await context2.commentHandler.postComment(context2, loggerError);
|
|
335
410
|
}
|
|
336
411
|
throw new HTTPException(500, { message: "Unexpected error" });
|
|
337
412
|
}
|
|
@@ -357,7 +432,7 @@ async function createActionsPlugin(handler, options) {
|
|
|
357
432
|
const inputSchemaErrors = [...Value3.Errors(inputSchema, body)];
|
|
358
433
|
if (inputSchemaErrors.length) {
|
|
359
434
|
console.dir(inputSchemaErrors, { depth: null });
|
|
360
|
-
core.setFailed(`Error: Invalid inputs payload: ${inputSchemaErrors.join(",")}`);
|
|
435
|
+
core.setFailed(`Error: Invalid inputs payload: ${inputSchemaErrors.map((o) => o.message).join(", ")}`);
|
|
361
436
|
return;
|
|
362
437
|
}
|
|
363
438
|
const signature = body.signature;
|
|
@@ -372,6 +447,7 @@ async function createActionsPlugin(handler, options) {
|
|
|
372
447
|
config2 = Value3.Decode(pluginOptions.settingsSchema, Value3.Default(pluginOptions.settingsSchema, inputs.settings));
|
|
373
448
|
} catch (e) {
|
|
374
449
|
console.dir(...Value3.Errors(pluginOptions.settingsSchema, inputs.settings), { depth: null });
|
|
450
|
+
core.setFailed(`Error: Invalid settings provided.`);
|
|
375
451
|
throw e;
|
|
376
452
|
}
|
|
377
453
|
} else {
|
|
@@ -383,6 +459,7 @@ async function createActionsPlugin(handler, options) {
|
|
|
383
459
|
env = Value3.Decode(pluginOptions.envSchema, Value3.Default(pluginOptions.envSchema, process.env));
|
|
384
460
|
} catch (e) {
|
|
385
461
|
console.dir(...Value3.Errors(pluginOptions.envSchema, process.env), { depth: null });
|
|
462
|
+
core.setFailed(`Error: Invalid environment provided.`);
|
|
386
463
|
throw e;
|
|
387
464
|
}
|
|
388
465
|
} else {
|
|
@@ -406,7 +483,8 @@ async function createActionsPlugin(handler, options) {
|
|
|
406
483
|
octokit: new customOctokit({ auth: inputs.authToken }),
|
|
407
484
|
config: config2,
|
|
408
485
|
env,
|
|
409
|
-
logger: new Logs2(pluginOptions.logLevel)
|
|
486
|
+
logger: new Logs2(pluginOptions.logLevel),
|
|
487
|
+
commentHandler: new CommentHandler()
|
|
410
488
|
};
|
|
411
489
|
try {
|
|
412
490
|
const result = await handler(context2);
|
|
@@ -414,19 +492,14 @@ async function createActionsPlugin(handler, options) {
|
|
|
414
492
|
await returnDataToKernel(pluginGithubToken, inputs.stateId, result);
|
|
415
493
|
} catch (error) {
|
|
416
494
|
console.error(error);
|
|
417
|
-
|
|
418
|
-
if (
|
|
419
|
-
core.setFailed(
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
core.setFailed(error.logMessage.raw);
|
|
423
|
-
loggerError = error;
|
|
424
|
-
} else {
|
|
425
|
-
core.setFailed(`Error: ${error}`);
|
|
426
|
-
loggerError = context2.logger.error(`Error: ${error}`);
|
|
495
|
+
const loggerError = transformError(context2, error);
|
|
496
|
+
if (loggerError instanceof LogReturn3) {
|
|
497
|
+
core.setFailed(loggerError.logMessage.diff);
|
|
498
|
+
} else if (loggerError instanceof Error) {
|
|
499
|
+
core.setFailed(loggerError);
|
|
427
500
|
}
|
|
428
501
|
if (pluginOptions.postCommentOnError && loggerError) {
|
|
429
|
-
await postComment(context2, loggerError);
|
|
502
|
+
await context2.commentHandler.postComment(context2, loggerError);
|
|
430
503
|
}
|
|
431
504
|
}
|
|
432
505
|
}
|
|
@@ -443,7 +516,7 @@ async function returnDataToKernel(repoToken, stateId, output) {
|
|
|
443
516
|
});
|
|
444
517
|
}
|
|
445
518
|
export {
|
|
519
|
+
CommentHandler,
|
|
446
520
|
createActionsPlugin,
|
|
447
|
-
createPlugin
|
|
448
|
-
postComment
|
|
521
|
+
createPlugin
|
|
449
522
|
};
|
package/dist/signature.d.mts
CHANGED
|
@@ -1,3 +1,34 @@
|
|
|
1
|
+
import { EmitterWebhookEventName, EmitterWebhookEvent } from '@octokit/webhooks';
|
|
2
|
+
import * as _sinclair_typebox from '@sinclair/typebox';
|
|
3
|
+
import { StaticDecode } from '@sinclair/typebox';
|
|
4
|
+
|
|
5
|
+
declare const commandCallSchema: _sinclair_typebox.TUnion<[_sinclair_typebox.TNull, _sinclair_typebox.TObject<{
|
|
6
|
+
name: _sinclair_typebox.TString;
|
|
7
|
+
parameters: _sinclair_typebox.TUnknown;
|
|
8
|
+
}>]>;
|
|
9
|
+
type CommandCall = StaticDecode<typeof commandCallSchema>;
|
|
10
|
+
|
|
11
|
+
declare class PluginInput<T extends EmitterWebhookEventName = EmitterWebhookEventName> {
|
|
12
|
+
private _privateKey;
|
|
13
|
+
stateId: string;
|
|
14
|
+
eventName: T;
|
|
15
|
+
eventPayload: EmitterWebhookEvent<T>["payload"];
|
|
16
|
+
settings: unknown;
|
|
17
|
+
authToken: string;
|
|
18
|
+
ref: string;
|
|
19
|
+
command: CommandCall;
|
|
20
|
+
constructor(privateKey: string, stateId: string, eventName: T, eventPayload: EmitterWebhookEvent<T>["payload"], settings: unknown, authToken: string, ref: string, command: CommandCall);
|
|
21
|
+
getInputs(): Promise<{
|
|
22
|
+
signature: string;
|
|
23
|
+
stateId: string;
|
|
24
|
+
eventName: T;
|
|
25
|
+
eventPayload: string;
|
|
26
|
+
settings: string;
|
|
27
|
+
authToken: string;
|
|
28
|
+
ref: string;
|
|
29
|
+
command: string;
|
|
30
|
+
}>;
|
|
31
|
+
}
|
|
1
32
|
interface Inputs {
|
|
2
33
|
stateId: unknown;
|
|
3
34
|
eventName: unknown;
|
|
@@ -10,4 +41,4 @@ interface Inputs {
|
|
|
10
41
|
declare function verifySignature(publicKeyPem: string, inputs: Inputs, signature: string): Promise<boolean>;
|
|
11
42
|
declare function signPayload(payload: string, privateKey: string): Promise<string>;
|
|
12
43
|
|
|
13
|
-
export { signPayload, verifySignature };
|
|
44
|
+
export { PluginInput, signPayload, verifySignature };
|
package/dist/signature.d.ts
CHANGED
|
@@ -1,3 +1,34 @@
|
|
|
1
|
+
import { EmitterWebhookEventName, EmitterWebhookEvent } from '@octokit/webhooks';
|
|
2
|
+
import * as _sinclair_typebox from '@sinclair/typebox';
|
|
3
|
+
import { StaticDecode } from '@sinclair/typebox';
|
|
4
|
+
|
|
5
|
+
declare const commandCallSchema: _sinclair_typebox.TUnion<[_sinclair_typebox.TNull, _sinclair_typebox.TObject<{
|
|
6
|
+
name: _sinclair_typebox.TString;
|
|
7
|
+
parameters: _sinclair_typebox.TUnknown;
|
|
8
|
+
}>]>;
|
|
9
|
+
type CommandCall = StaticDecode<typeof commandCallSchema>;
|
|
10
|
+
|
|
11
|
+
declare class PluginInput<T extends EmitterWebhookEventName = EmitterWebhookEventName> {
|
|
12
|
+
private _privateKey;
|
|
13
|
+
stateId: string;
|
|
14
|
+
eventName: T;
|
|
15
|
+
eventPayload: EmitterWebhookEvent<T>["payload"];
|
|
16
|
+
settings: unknown;
|
|
17
|
+
authToken: string;
|
|
18
|
+
ref: string;
|
|
19
|
+
command: CommandCall;
|
|
20
|
+
constructor(privateKey: string, stateId: string, eventName: T, eventPayload: EmitterWebhookEvent<T>["payload"], settings: unknown, authToken: string, ref: string, command: CommandCall);
|
|
21
|
+
getInputs(): Promise<{
|
|
22
|
+
signature: string;
|
|
23
|
+
stateId: string;
|
|
24
|
+
eventName: T;
|
|
25
|
+
eventPayload: string;
|
|
26
|
+
settings: string;
|
|
27
|
+
authToken: string;
|
|
28
|
+
ref: string;
|
|
29
|
+
command: string;
|
|
30
|
+
}>;
|
|
31
|
+
}
|
|
1
32
|
interface Inputs {
|
|
2
33
|
stateId: unknown;
|
|
3
34
|
eventName: unknown;
|
|
@@ -10,4 +41,4 @@ interface Inputs {
|
|
|
10
41
|
declare function verifySignature(publicKeyPem: string, inputs: Inputs, signature: string): Promise<boolean>;
|
|
11
42
|
declare function signPayload(payload: string, privateKey: string): Promise<string>;
|
|
12
43
|
|
|
13
|
-
export { signPayload, verifySignature };
|
|
44
|
+
export { PluginInput, signPayload, verifySignature };
|
package/dist/signature.js
CHANGED
|
@@ -20,10 +20,47 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/signature.ts
|
|
21
21
|
var signature_exports = {};
|
|
22
22
|
__export(signature_exports, {
|
|
23
|
+
PluginInput: () => PluginInput,
|
|
23
24
|
signPayload: () => signPayload,
|
|
24
25
|
verifySignature: () => verifySignature
|
|
25
26
|
});
|
|
26
27
|
module.exports = __toCommonJS(signature_exports);
|
|
28
|
+
var PluginInput = class {
|
|
29
|
+
_privateKey;
|
|
30
|
+
stateId;
|
|
31
|
+
eventName;
|
|
32
|
+
eventPayload;
|
|
33
|
+
settings;
|
|
34
|
+
authToken;
|
|
35
|
+
ref;
|
|
36
|
+
command;
|
|
37
|
+
constructor(privateKey, stateId, eventName, eventPayload, settings, authToken, ref, command) {
|
|
38
|
+
this._privateKey = privateKey;
|
|
39
|
+
this.stateId = stateId;
|
|
40
|
+
this.eventName = eventName;
|
|
41
|
+
this.eventPayload = eventPayload;
|
|
42
|
+
this.settings = settings;
|
|
43
|
+
this.authToken = authToken;
|
|
44
|
+
this.ref = ref;
|
|
45
|
+
this.command = command;
|
|
46
|
+
}
|
|
47
|
+
async getInputs() {
|
|
48
|
+
const inputs = {
|
|
49
|
+
stateId: this.stateId,
|
|
50
|
+
eventName: this.eventName,
|
|
51
|
+
eventPayload: JSON.stringify(this.eventPayload),
|
|
52
|
+
settings: JSON.stringify(this.settings),
|
|
53
|
+
authToken: this.authToken,
|
|
54
|
+
ref: this.ref,
|
|
55
|
+
command: JSON.stringify(this.command)
|
|
56
|
+
};
|
|
57
|
+
const signature = await signPayload(JSON.stringify(inputs), this._privateKey);
|
|
58
|
+
return {
|
|
59
|
+
...inputs,
|
|
60
|
+
signature
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
};
|
|
27
64
|
async function verifySignature(publicKeyPem, inputs, signature) {
|
|
28
65
|
try {
|
|
29
66
|
const inputsOrdered = {
|
|
@@ -77,6 +114,7 @@ async function signPayload(payload, privateKey) {
|
|
|
77
114
|
}
|
|
78
115
|
// Annotate the CommonJS export names for ESM import in node:
|
|
79
116
|
0 && (module.exports = {
|
|
117
|
+
PluginInput,
|
|
80
118
|
signPayload,
|
|
81
119
|
verifySignature
|
|
82
120
|
});
|
package/dist/signature.mjs
CHANGED
|
@@ -1,4 +1,40 @@
|
|
|
1
1
|
// src/signature.ts
|
|
2
|
+
var PluginInput = class {
|
|
3
|
+
_privateKey;
|
|
4
|
+
stateId;
|
|
5
|
+
eventName;
|
|
6
|
+
eventPayload;
|
|
7
|
+
settings;
|
|
8
|
+
authToken;
|
|
9
|
+
ref;
|
|
10
|
+
command;
|
|
11
|
+
constructor(privateKey, stateId, eventName, eventPayload, settings, authToken, ref, command) {
|
|
12
|
+
this._privateKey = privateKey;
|
|
13
|
+
this.stateId = stateId;
|
|
14
|
+
this.eventName = eventName;
|
|
15
|
+
this.eventPayload = eventPayload;
|
|
16
|
+
this.settings = settings;
|
|
17
|
+
this.authToken = authToken;
|
|
18
|
+
this.ref = ref;
|
|
19
|
+
this.command = command;
|
|
20
|
+
}
|
|
21
|
+
async getInputs() {
|
|
22
|
+
const inputs = {
|
|
23
|
+
stateId: this.stateId,
|
|
24
|
+
eventName: this.eventName,
|
|
25
|
+
eventPayload: JSON.stringify(this.eventPayload),
|
|
26
|
+
settings: JSON.stringify(this.settings),
|
|
27
|
+
authToken: this.authToken,
|
|
28
|
+
ref: this.ref,
|
|
29
|
+
command: JSON.stringify(this.command)
|
|
30
|
+
};
|
|
31
|
+
const signature = await signPayload(JSON.stringify(inputs), this._privateKey);
|
|
32
|
+
return {
|
|
33
|
+
...inputs,
|
|
34
|
+
signature
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
};
|
|
2
38
|
async function verifySignature(publicKeyPem, inputs, signature) {
|
|
3
39
|
try {
|
|
4
40
|
const inputsOrdered = {
|
|
@@ -51,6 +87,7 @@ async function signPayload(payload, privateKey) {
|
|
|
51
87
|
return btoa(String.fromCharCode(...new Uint8Array(signature)));
|
|
52
88
|
}
|
|
53
89
|
export {
|
|
90
|
+
PluginInput,
|
|
54
91
|
signPayload,
|
|
55
92
|
verifySignature
|
|
56
93
|
};
|