@sentry/junior-github 0.53.0 → 0.55.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/README.md +19 -0
- package/SETUP.md +1 -0
- package/index.d.ts +9 -0
- package/index.js +150 -0
- package/package.json +18 -2
- package/plugin.yaml +0 -10
- package/skills/github-code/SKILL.md +5 -15
package/README.md
CHANGED
|
@@ -8,4 +8,23 @@ Install it alongside `@sentry/junior`:
|
|
|
8
8
|
pnpm add @sentry/junior @sentry/junior-github
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
+
Register the trusted plugin from app code:
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import { createApp } from "@sentry/junior";
|
|
15
|
+
import { githubPlugin } from "@sentry/junior-github";
|
|
16
|
+
|
|
17
|
+
const app = await createApp({
|
|
18
|
+
plugins: [
|
|
19
|
+
githubPlugin({
|
|
20
|
+
botNameEnv: "GITHUB_APP_BOT_NAME",
|
|
21
|
+
botEmailEnv: "GITHUB_APP_BOT_EMAIL",
|
|
22
|
+
}),
|
|
23
|
+
],
|
|
24
|
+
});
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Also list `@sentry/junior-github` in `juniorNitro({ plugins: { packages: [...] } })`
|
|
28
|
+
so Nitro bundles the manifest and bundled GitHub skill.
|
|
29
|
+
|
|
11
30
|
Full setup guide: https://junior.sentry.dev/extend/github-plugin/
|
package/SETUP.md
CHANGED
package/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { JuniorPlugin } from "@sentry/junior-plugin-api";
|
|
2
|
+
|
|
3
|
+
export interface GitHubPluginOptions {
|
|
4
|
+
botEmailEnv?: string;
|
|
5
|
+
botNameEnv?: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
/** Register trusted GitHub runtime hooks for commit attribution and package loading. */
|
|
9
|
+
export function githubPlugin(options?: GitHubPluginOptions): JuniorPlugin;
|
package/index.js
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { defineJuniorPlugin } from "@sentry/junior-plugin-api";
|
|
2
|
+
|
|
3
|
+
function readEnv(name) {
|
|
4
|
+
const value = process.env[name];
|
|
5
|
+
return typeof value === "string" && value ? value : undefined;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
function cleanIdentityPart(value) {
|
|
9
|
+
return String(value ?? "")
|
|
10
|
+
.replaceAll("\n", " ")
|
|
11
|
+
.replaceAll("\r", " ")
|
|
12
|
+
.replace(/[<>]/g, "")
|
|
13
|
+
.trim();
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function requesterName(requester) {
|
|
17
|
+
return (
|
|
18
|
+
cleanIdentityPart(requester?.fullName) ||
|
|
19
|
+
cleanIdentityPart(requester?.userName) ||
|
|
20
|
+
cleanIdentityPart(requester?.userId) ||
|
|
21
|
+
undefined
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function requesterEmail(requester) {
|
|
26
|
+
const email = cleanIdentityPart(requester?.email);
|
|
27
|
+
return email && !/\s/.test(email) ? email : "noreply";
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function isGitCommitCommand(command) {
|
|
31
|
+
return /(?:^|[\s;|&])git(?:\s+(?:-C\s+\S+|-c\s+\S+|--git-dir(?:=\S+|\s+\S+)|--work-tree(?:=\S+|\s+\S+)|--namespace(?:=\S+|\s+\S+)))*\s+commit(?:\s|$)/.test(
|
|
32
|
+
command,
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function prepareCommitMsgHook() {
|
|
37
|
+
return `#!/usr/bin/env bash
|
|
38
|
+
set -eu
|
|
39
|
+
|
|
40
|
+
message_file="\${1:-}"
|
|
41
|
+
if [ -z "$message_file" ]; then
|
|
42
|
+
exit 1
|
|
43
|
+
fi
|
|
44
|
+
|
|
45
|
+
if [ -z "\${JUNIOR_GIT_AUTHOR_NAME:-}" ] || [ -z "\${JUNIOR_GIT_AUTHOR_EMAIL:-}" ]; then
|
|
46
|
+
echo "Junior GitHub plugin internal error: bot commit attribution was not injected by the host runtime. Do not set Git author env vars manually; report this configuration error." >&2
|
|
47
|
+
exit 1
|
|
48
|
+
fi
|
|
49
|
+
|
|
50
|
+
if [ "\${GIT_AUTHOR_NAME:-}" != "$JUNIOR_GIT_AUTHOR_NAME" ] || [ "\${GIT_AUTHOR_EMAIL:-}" != "$JUNIOR_GIT_AUTHOR_EMAIL" ]; then
|
|
51
|
+
echo "Junior GitHub plugin internal error: Git author was not set to the configured bot identity. Do not override Git author manually; report this configuration error." >&2
|
|
52
|
+
exit 1
|
|
53
|
+
fi
|
|
54
|
+
|
|
55
|
+
if [ -z "\${JUNIOR_GIT_COAUTHOR_NAME:-}" ] || [ -z "\${JUNIOR_GIT_COAUTHOR_EMAIL:-}" ]; then
|
|
56
|
+
echo "Junior GitHub plugin internal error: requester coauthor identity was not injected by the host runtime. Do not set coauthor env vars manually; report this configuration error." >&2
|
|
57
|
+
exit 1
|
|
58
|
+
fi
|
|
59
|
+
|
|
60
|
+
trailer="Co-authored-by: $JUNIOR_GIT_COAUTHOR_NAME <$JUNIOR_GIT_COAUTHOR_EMAIL>"
|
|
61
|
+
if grep -Fqx "$trailer" "$message_file"; then
|
|
62
|
+
exit 0
|
|
63
|
+
fi
|
|
64
|
+
|
|
65
|
+
printf '\\n%s\\n' "$trailer" >> "$message_file"
|
|
66
|
+
`;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
async function configureGit(ctx, key, value) {
|
|
70
|
+
const result = await ctx.sandbox.run({
|
|
71
|
+
cmd: "git",
|
|
72
|
+
args: ["config", "--global", key, value],
|
|
73
|
+
});
|
|
74
|
+
if (result.exitCode !== 0) {
|
|
75
|
+
throw new Error(
|
|
76
|
+
`Failed to configure git ${key}: ${result.stderr || result.stdout}`,
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/** Register trusted GitHub runtime hooks for commit attribution and package loading. */
|
|
82
|
+
export function githubPlugin(options = {}) {
|
|
83
|
+
const botNameEnv = options.botNameEnv ?? "GITHUB_APP_BOT_NAME";
|
|
84
|
+
const botEmailEnv = options.botEmailEnv ?? "GITHUB_APP_BOT_EMAIL";
|
|
85
|
+
|
|
86
|
+
return defineJuniorPlugin({
|
|
87
|
+
name: "github",
|
|
88
|
+
pluginConfig: {
|
|
89
|
+
packages: ["@sentry/junior-github"],
|
|
90
|
+
},
|
|
91
|
+
hooks: {
|
|
92
|
+
async sandboxPrepare(ctx) {
|
|
93
|
+
const hooksPath = `${ctx.sandbox.juniorRoot}/git-hooks`;
|
|
94
|
+
await ctx.sandbox.writeFile({
|
|
95
|
+
path: `${hooksPath}/prepare-commit-msg`,
|
|
96
|
+
mode: 0o755,
|
|
97
|
+
content: prepareCommitMsgHook(),
|
|
98
|
+
});
|
|
99
|
+
await Promise.all([
|
|
100
|
+
configureGit(ctx, "core.hooksPath", hooksPath),
|
|
101
|
+
configureGit(ctx, "commit.gpgsign", "false"),
|
|
102
|
+
configureGit(ctx, "credential.helper", ""),
|
|
103
|
+
configureGit(ctx, "http.emptyAuth", "true"),
|
|
104
|
+
]);
|
|
105
|
+
},
|
|
106
|
+
beforeToolExecute(ctx) {
|
|
107
|
+
if (ctx.tool.name !== "bash") {
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
const command =
|
|
111
|
+
typeof ctx.tool.input === "object" &&
|
|
112
|
+
ctx.tool.input &&
|
|
113
|
+
"command" in ctx.tool.input
|
|
114
|
+
? String(ctx.tool.input.command ?? "")
|
|
115
|
+
: "";
|
|
116
|
+
const botName = readEnv(botNameEnv);
|
|
117
|
+
const botEmail = readEnv(botEmailEnv);
|
|
118
|
+
if ((!botName || !botEmail) && isGitCommitCommand(command)) {
|
|
119
|
+
ctx.decision.deny(
|
|
120
|
+
`Junior GitHub plugin is misconfigured: host env vars ${botNameEnv} and ${botEmailEnv} are missing. This is an internal deployment configuration error; do not set them in the sandbox.`,
|
|
121
|
+
);
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
if (!botName || !botEmail) {
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
const coauthorName = requesterName(ctx.requester);
|
|
128
|
+
if (!coauthorName && isGitCommitCommand(command)) {
|
|
129
|
+
ctx.decision.deny(
|
|
130
|
+
"Junior GitHub plugin could not determine requester identity for commit attribution. This is an internal request-context error; do not set coauthor env vars manually.",
|
|
131
|
+
);
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
ctx.env.set("GIT_AUTHOR_NAME", botName);
|
|
135
|
+
ctx.env.set("GIT_AUTHOR_EMAIL", botEmail);
|
|
136
|
+
ctx.env.set("GIT_COMMITTER_NAME", botName);
|
|
137
|
+
ctx.env.set("GIT_COMMITTER_EMAIL", botEmail);
|
|
138
|
+
ctx.env.set("JUNIOR_GIT_AUTHOR_NAME", botName);
|
|
139
|
+
ctx.env.set("JUNIOR_GIT_AUTHOR_EMAIL", botEmail);
|
|
140
|
+
if (coauthorName) {
|
|
141
|
+
ctx.env.set("JUNIOR_GIT_COAUTHOR_NAME", coauthorName);
|
|
142
|
+
ctx.env.set(
|
|
143
|
+
"JUNIOR_GIT_COAUTHOR_EMAIL",
|
|
144
|
+
requesterEmail(ctx.requester),
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
},
|
|
148
|
+
},
|
|
149
|
+
});
|
|
150
|
+
}
|
package/package.json
CHANGED
|
@@ -1,14 +1,30 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sentry/junior-github",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.55.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
8
8
|
"type": "module",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/getsentry/junior.git",
|
|
12
|
+
"directory": "packages/junior-github"
|
|
13
|
+
},
|
|
14
|
+
"exports": {
|
|
15
|
+
".": {
|
|
16
|
+
"types": "./index.d.ts",
|
|
17
|
+
"default": "./index.js"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
9
20
|
"files": [
|
|
21
|
+
"index.d.ts",
|
|
22
|
+
"index.js",
|
|
10
23
|
"plugin.yaml",
|
|
11
24
|
"skills",
|
|
12
25
|
"SETUP.md"
|
|
13
|
-
]
|
|
26
|
+
],
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"@sentry/junior-plugin-api": "0.55.0"
|
|
29
|
+
}
|
|
14
30
|
}
|
package/plugin.yaml
CHANGED
|
@@ -1,16 +1,6 @@
|
|
|
1
1
|
name: github
|
|
2
2
|
description: GitHub issue, pull request, and repository workflows via GitHub App
|
|
3
3
|
|
|
4
|
-
capabilities:
|
|
5
|
-
- actions.read
|
|
6
|
-
- actions.write
|
|
7
|
-
- issues.read
|
|
8
|
-
- issues.write
|
|
9
|
-
- contents.read
|
|
10
|
-
- contents.write
|
|
11
|
-
- pull-requests.read
|
|
12
|
-
- pull-requests.write
|
|
13
|
-
|
|
14
4
|
config-keys:
|
|
15
5
|
- org
|
|
16
6
|
- repo
|
|
@@ -10,10 +10,10 @@ Use `gh` and `git` for repository checkout, source investigation, code changes,
|
|
|
10
10
|
|
|
11
11
|
## References
|
|
12
12
|
|
|
13
|
-
| Need
|
|
14
|
-
|
|
|
15
|
-
| Command syntax, permissions, config | [references/api-surface.md](references/api-surface.md)
|
|
16
|
-
| Failed commands, auth errors
|
|
13
|
+
| Need | Load |
|
|
14
|
+
| ----------------------------------- | -------------------------------------------------------------------------------------- |
|
|
15
|
+
| Command syntax, permissions, config | [references/api-surface.md](references/api-surface.md) |
|
|
16
|
+
| Failed commands, auth errors | [references/troubleshooting-workarounds.md](references/troubleshooting-workarounds.md) |
|
|
17
17
|
|
|
18
18
|
## Core rules
|
|
19
19
|
|
|
@@ -102,17 +102,7 @@ Types: `feat`, `fix`, `ref`, `docs`, `test`, `build`, `ci`, `chore`. Imperative
|
|
|
102
102
|
|
|
103
103
|
Body only when it helps reviewers understand _why_.
|
|
104
104
|
|
|
105
|
-
Footer order: `Fixes`/`Refs` lines
|
|
106
|
-
|
|
107
|
-
#### On-behalf-of commits
|
|
108
|
-
|
|
109
|
-
If the commit is authored by a bot and a human requested the work, add a trailer:
|
|
110
|
-
|
|
111
|
-
```
|
|
112
|
-
Co-authored-by: Full Name <email>
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
Resolve name and email from evidence — requester context, Slack profile (`slackUserLookup`), GitHub profile, or repo commit history. If email cannot be confirmed, use `Full Name <noreply>` and note the gap in the PR body.
|
|
105
|
+
Footer order: `Fixes`/`Refs` lines.
|
|
116
106
|
|
|
117
107
|
### 6. Create or update PR
|
|
118
108
|
|