Skip to content

Commit 3da524d

Browse files
authored
Merge branch 'main' into publishpipeline
2 parents 5ce9917 + 4cb5e00 commit 3da524d

File tree

9 files changed

+275
-50
lines changed

9 files changed

+275
-50
lines changed
Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
name: Release Comment Handler
2+
3+
on:
4+
issues:
5+
types:
6+
- labeled
7+
8+
jobs:
9+
comment_on_label:
10+
if: github.event.label.name == 'prerelease' || github.event.label.name == 'fixed'
11+
runs-on: ubuntu-latest
12+
permissions:
13+
issues: write
14+
contents: read
15+
steps:
16+
- name: Gather participants
17+
id: participants
18+
uses: actions/github-script@v7
19+
with:
20+
script: |
21+
console.log("=== WORKFLOW START ===");
22+
const issue_number = context.payload.issue.number;
23+
const repo = context.repo;
24+
25+
console.log(`Processing issue #${issue_number} in ${repo.owner}/${repo.repo}`);
26+
27+
// Get issue details (for author)
28+
const issue = context.payload.issue;
29+
const author = issue.user.login;
30+
console.log(`Issue author: ${author}`);
31+
32+
// Use a Set to track all unique participants (normalized to lowercase for deduplication)
33+
const all_participants = new Set();
34+
35+
// Add the issue author
36+
all_participants.add(author.toLowerCase());
37+
console.log(`Added author to participants: ${author.toLowerCase()}`);
38+
39+
// Get all comments and add commenters
40+
console.log("=== FETCHING COMMENTS ===");
41+
const comments = await github.paginate(
42+
github.rest.issues.listComments,
43+
{ ...repo, issue_number }
44+
);
45+
console.log(`Found ${comments.length} comments`);
46+
47+
if (comments.length === 0) {
48+
console.log("❌ NO COMMENTS FOUND - This might be why no users are tagged");
49+
}
50+
51+
comments.forEach((c, index) => {
52+
const commenter = c.user.login.toLowerCase();
53+
all_participants.add(commenter);
54+
console.log(`Comment #${index + 1}: Added commenter: ${commenter} (original: ${c.user.login})`);
55+
});
56+
57+
// Get all reactions from comments
58+
let totalCommentReactions = 0;
59+
for (const comment of comments) {
60+
const reactions = await github.paginate(
61+
github.rest.reactions.listForIssueComment,
62+
{ ...repo, comment_id: comment.id }
63+
);
64+
totalCommentReactions += reactions.length;
65+
reactions.forEach(r => {
66+
const reactor = r.user.login.toLowerCase();
67+
all_participants.add(reactor);
68+
console.log(`Added comment reactor: ${reactor}`);
69+
});
70+
}
71+
console.log(`Processed ${totalCommentReactions} reactions from comments`);
72+
73+
// Get reactions on main issue body
74+
const issue_reactions = await github.paginate(
75+
github.rest.reactions.listForIssue,
76+
{ ...repo, issue_number }
77+
);
78+
console.log(`Found ${issue_reactions.length} reactions on issue body`);
79+
80+
issue_reactions.forEach(r => {
81+
const reactor = r.user.login.toLowerCase();
82+
all_participants.add(reactor);
83+
console.log(`Added issue reactor: ${reactor}`);
84+
});
85+
86+
console.log(`Total unique participants before bot filtering: ${all_participants.size}`);
87+
console.log(`Participants: ${Array.from(all_participants).join(', ')}`);
88+
89+
// Filter out bot users
90+
const isBotUser = (username) => {
91+
const lowerUsername = username.toLowerCase();
92+
return lowerUsername.endsWith('[bot]') ||
93+
lowerUsername === 'dependabot' ||
94+
lowerUsername === 'renovate' ||
95+
lowerUsername === 'greenkeeper' ||
96+
lowerUsername === 'codecov' ||
97+
lowerUsername === 'coveralls' ||
98+
lowerUsername.startsWith('dependabot[') ||
99+
lowerUsername.includes('-bot') ||
100+
lowerUsername.includes('_bot');
101+
};
102+
103+
// Convert Set to array and filter out bots
104+
const all_users = Array.from(all_participants).filter(user => !isBotUser(user));
105+
106+
const filteredBots = Array.from(all_participants).filter(user => isBotUser(user));
107+
console.log(`Filtered out ${filteredBots.length} bot users: ${filteredBots.join(', ')}`);
108+
console.log(`Final participants count: ${all_users.length}`);
109+
console.log(`Final participants: ${all_users.join(', ')}`);
110+
111+
if (all_users.length === 0) {
112+
console.log("No participants to mention after filtering");
113+
const fs = require('fs');
114+
fs.appendFileSync(process.env.GITHUB_ENV, 'MENTIONS=\n');
115+
return;
116+
}
117+
118+
const mentions = all_users.map(u => `@${u}`).join(' ');
119+
console.log(`Generated mentions: ${mentions}`);
120+
console.log(`Setting environment variable 'MENTIONS' to: "${mentions}"`);
121+
122+
const fs = require('fs');
123+
fs.appendFileSync(process.env.GITHUB_ENV, `MENTIONS=${mentions}\n`);
124+
return { mentions: mentions };
125+
result-encoding: string
126+
127+
- name: Add label comment
128+
uses: actions/github-script@v7
129+
with:
130+
script: |
131+
console.log("=== STEP 2: ADD COMMENT ===");
132+
console.log("Environment variable access:");
133+
console.log("process.env.MENTIONS:", process.env.MENTIONS);
134+
135+
const mentions = process.env.MENTIONS || '';
136+
const labelName = context.payload.label.name;
137+
138+
console.log(`Processing label: ${labelName}`);
139+
console.log(`Mentions received: "${mentions}"`);
140+
console.log(`Mentions length: ${mentions.length}`);
141+
console.log(`Mentions trimmed length: ${mentions.trim().length}`);
142+
143+
let message;
144+
145+
if (labelName === 'prerelease') {
146+
console.log("Processing prerelease label");
147+
if (mentions.trim() === "") {
148+
console.log("No participants to mention for prerelease. Skipping comment creation.");
149+
return;
150+
}
151+
message = `${mentions}\n\nA fix for this issue is now available in the next pre-releases of C#DK/C#. If you'd like to try out the fix, please see [these instructions](https://github.com/microsoft/vscode-dotnettools/wiki/Installing-and-updating-pre%E2%80%90release-versions-of-C%23-Dev-Kit-and-C%23-Extension) to update or try pre-release versions.`;
152+
console.log("Generated prerelease message");
153+
} else if (labelName === 'fixed') {
154+
console.log("Processing fixed label");
155+
message = mentions.trim() !== ""
156+
? `${mentions}\n\nThis issue has been fixed! Please update to the latest versions of VS Code, C# Dev Kit, and the C# extension.`
157+
: `This issue has been fixed! Please update to the latest versions of VS Code, C# Dev Kit, and the C# extension.`;
158+
console.log(`Generated fixed message ${mentions.trim() !== "" ? "with" : "without"} mentions`);
159+
}
160+
161+
console.log(`Final message length: ${message.length}`);
162+
console.log(`Creating comment on issue #${context.payload.issue.number}`);
163+
164+
await github.rest.issues.createComment({
165+
...context.repo,
166+
issue_number: context.payload.issue.number,
167+
body: message
168+
});
169+
170+
console.log("Comment created successfully");

SUPPORT.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,11 @@ The template has a section to include the `C#` output window logs. These logs ar
4040

4141
##### C# LSP Trace Logs
4242
- To capture detailed requests sent to the Roslyn language server:
43-
1. Set the `C#` output window log level to `Trace` (as described above).
44-
2. Open the `C# LSP Trace Logs` output window.
43+
1. Open the `C# LSP Trace Logs` output window.
44+
2. Set the output window log level to `Trace`.
4545
3. Reproduce the issue.
4646
4. Copy the contents of the `C# LSP Trace Logs` output window.
47+
5. After collecting the logs, reset the log level to `Info`.
4748

4849

4950
##### Other Ways to Set the Log Level

package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5627,6 +5627,11 @@
56275627
"when": "editorLangId == csharp && (dotnet.server.activationContext == 'Roslyn' || dotnet.server.activationContext == 'OmniSharp')",
56285628
"group": "2_dotnet@2"
56295629
}
5630+
],
5631+
"issue/reporter": [
5632+
{
5633+
"command": "csharp.reportIssue"
5634+
}
56305635
]
56315636
},
56325637
"viewsWelcome": [

src/lsptoolshost/activate.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ export async function activateRoslynLanguageServer(
8383
registerCopilotContextProviders(context, languageServer, _channel);
8484

8585
// Register any commands that need to be handled by the extension.
86-
registerCommands(context, languageServer, hostExecutableResolver, _channel);
86+
registerCommands(context, languageServer, hostExecutableResolver, _channel, _traceChannel);
8787
registerNestedCodeActionCommands(context, languageServer, _channel);
8888
registerCodeActionFixAllCommands(context, languageServer, _channel);
8989

src/lsptoolshost/commands.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,10 @@ export function registerCommands(
1515
context: vscode.ExtensionContext,
1616
languageServer: RoslynLanguageServer,
1717
hostExecutableResolver: IHostExecutableResolver,
18-
outputChannel: vscode.LogOutputChannel
18+
outputChannel: vscode.LogOutputChannel,
19+
csharpTraceChannel: vscode.LogOutputChannel
1920
) {
20-
registerExtensionCommands(context, languageServer, hostExecutableResolver, outputChannel);
21+
registerExtensionCommands(context, hostExecutableResolver, outputChannel, csharpTraceChannel);
2122
registerWorkspaceCommands(context, languageServer);
2223
registerServerCommands(context, languageServer, outputChannel);
2324
}
@@ -27,16 +28,17 @@ export function registerCommands(
2728
*/
2829
function registerExtensionCommands(
2930
context: vscode.ExtensionContext,
30-
languageServer: RoslynLanguageServer,
3131
hostExecutableResolver: IHostExecutableResolver,
32-
outputChannel: vscode.LogOutputChannel
32+
outputChannel: vscode.LogOutputChannel,
33+
csharpTraceChannel: vscode.LogOutputChannel
3334
) {
3435
context.subscriptions.push(
3536
vscode.commands.registerCommand('csharp.reportIssue', async () =>
3637
reportIssue(
37-
context.extension.packageJSON.version,
38+
context,
3839
getDotnetInfo,
3940
/*shouldIncludeMonoInfo:*/ false,
41+
[outputChannel, csharpTraceChannel],
4042
hostExecutableResolver
4143
)
4244
)

src/omnisharp/features/commands.ts

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ export default function registerCommands(
3535
eventStream: EventStream,
3636
monoResolver: IHostExecutableResolver,
3737
dotnetResolver: IHostExecutableResolver,
38-
workspaceInformationProvider: IWorkspaceDebugInformationProvider
38+
workspaceInformationProvider: IWorkspaceDebugInformationProvider,
39+
outputChannel: vscode.OutputChannel
3940
): CompositeDisposable {
4041
const disposable = new CompositeDisposable();
4142
disposable.add(vscode.commands.registerCommand('o.restart', async () => restartOmniSharp(context, server)));
@@ -66,20 +67,31 @@ export default function registerCommands(
6667
);
6768

6869
disposable.add(
69-
vscode.commands.registerCommand('csharp.reportIssue', async () =>
70-
reportIssue(
71-
context.extension.packageJSON.version,
70+
vscode.commands.registerCommand('csharp.reportIssue', async () => {
71+
const logOutputChannel = isLogOutputChannel(outputChannel);
72+
return reportIssue(
73+
context,
7274
getDotnetInfo,
7375
platformInfo.isValidPlatformForMono(),
76+
logOutputChannel ? [logOutputChannel] : [],
7477
dotnetResolver,
7578
monoResolver
76-
)
77-
)
79+
);
80+
})
7881
);
7982

8083
return new CompositeDisposable(disposable);
8184
}
8285

86+
function isLogOutputChannel(channel: vscode.OutputChannel): vscode.LogOutputChannel | undefined {
87+
const anyChannel = channel as any;
88+
if (anyChannel.logLevel) {
89+
return channel as vscode.LogOutputChannel;
90+
} else {
91+
return undefined;
92+
}
93+
}
94+
8395
async function restartOmniSharp(context: vscode.ExtensionContext, server: OmniSharpServer) {
8496
if (server.isRunning()) {
8597
await server.restart();

src/omnisharp/omnisharpLanguageServer.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,8 @@ async function activate(
240240
eventStream,
241241
omnisharpMonoResolver,
242242
omnisharpDotnetResolver,
243-
workspaceInformationProvider
243+
workspaceInformationProvider,
244+
outputChannel
244245
)
245246
);
246247

0 commit comments

Comments
 (0)