Skip to content

safe-outputs: Apply labels when creating discussions#15597

Merged
pelikhan merged 7 commits intomainfrom
copilot/fix-create-discussion-labels
Feb 14, 2026
Merged

safe-outputs: Apply labels when creating discussions#15597
pelikhan merged 7 commits intomainfrom
copilot/fix-create-discussion-labels

Conversation

Copy link
Contributor

Copilot AI commented Feb 14, 2026

safe-outputs.create-discussion.labels were parsed from config but never applied to created discussions. The createDiscussion GraphQL mutation doesn't accept labels, and no follow-up step existed to add them.

Changes

Label Application Flow

  • fetchLabelIds(): Query repository labels, match requested labels case-insensitively, return node IDs
  • applyLabelsToDiscussion(): Apply labels via addLabelsToLabelable GraphQL mutation after discussion creation
  • Merge config labels with per-message labels, sanitize and deduplicate (consistent with create_issue behavior)
  • Graceful failure: Log warnings if labels can't be applied, but discussion creation succeeds

Smoke Test Updates

  • Updated smoke-copilot workflow to test discussion creation with labels
  • Added test requirement Weekly Research Report: AI Workflow Automation Landscape and Strategic Opportunities - August 2025 #9 to create a discussion in the announcements category titled "copilot was here" with the label "ai-generated"
  • Configured discussion to expire in 1 day (24 hours) with automatic cleanup via close-older-discussions: true
  • Provides end-to-end validation of the discussion label application, expiration, and cleanup features

Technical Note
Discussions require GraphQL addLabelsToLabelable (label node IDs) rather than REST issues.addLabels (label names) used by issues/PRs.

Example

safe-outputs:
  create-discussion:
    category: announcements
    labels: [automation, report]
    expires: 1d
    close-older-discussions: true

Discussions will now receive both labels (if they exist in the repository), expire after 1 day, and automatically close older discussions with the same workflow-id marker.

Warning

<issue_title>safe-outputs create-discussion does not apply configured labels</issue_title>
<issue_description>## Summary
safe-outputs.create-discussion.labels appears to be accepted in config but not applied to newly created discussions.

What I observed

The create_discussion handler parses config.labels, but those labels are never used when creating the discussion.

Expected behavior

When safe-outputs.create-discussion.labels is configured, created discussions should receive those labels.

Actual behavior

Discussion is created successfully, but no labels are applied.

Reproduction

  1. Configure workflow safe-outputs with create-discussion and labels:
safe-outputs:
  create-discussion:
    category: announcements
    labels: [automation, report]
  1. Emit a valid create_discussion output item.
  2. Observe created discussion has no labels.

Code evidence

  • create_discussion parses labels from config, but does not use them later:
    • actions/setup/js/create_discussion.cjs:196
  • Discussion creation GraphQL mutation only sends repositoryId, categoryId, title, and body:
    • actions/setup/js/create_discussion.cjs:405
  • By contrast, create_issue builds and passes labels to API create call:
    • actions/setup/js/create_issue.cjs:376
    • actions/setup/js/create_issue.cjs:469
  • Schema/docs indicate labels should be attached to created discussions:
    • pkg/parser/schemas/main_workflow_schema.json:4364
    • pkg/workflow/create_discussion.go:18

Likely root cause

The discussion creation path lacks a label-attachment step (either during createDiscussion input if supported, or a follow-up mutation to apply labels after creation).

Suggested fix

After discussion creation, resolve label IDs for configured labels and apply them to the created discussion node (or include label IDs directly if supported by the create mutation input).

Impact

Workflows depending on discussion labels for triage, filtering, and close-older-discussions matching do not behave as configured.
</issue_description>

Comments on the Issue (you are @copilot in this section)

<issue_title>safe-outputs create-discussion does not apply configured labels</issue_title>

<issue_description>## Summary
safe-outputs.create-discussion.labels appears to be accepted in config but not applied to newly created discussions.

What I observed

The create_discussion handler parses config.labels, but those labels are never used when creating the discussion.

Expected behavior

When safe-outputs.create-discussion.labels is configured, created discussions should receive those labels.

Actual behavior

Discussion is created successfully, but no labels are applied.

Reproduction

  1. Configure workflow safe-outputs with create-discussion and labels:
safe-outputs:
  create-discussion:
    category: announcements
    labels: [automation, report]
  1. Emit a valid create_discussion output item.
  2. Observe created discussion has no labels.

Code evidence

  • create_discussion parses labels from config, but does not use them later:
    • actions/setup/js/create_discussion.cjs:196
  • Discussion creation GraphQL mutation only sends repositoryId, categoryId, title, and body:
    • actions/setup/js/create_discussion.cjs:405
  • By contrast, create_issue builds and passes labels to API create call:
    • actions/setup/js/create_issue.cjs:376
    • actions/setup/js/create_issue.cjs:469
  • Schema/docs indicate labels should be attached to created discussions:
    • pkg/parser/schemas/main_workflow_schema.json:4364
    • pkg/workflow/create_discussion.go:18

Likely root cause

The discussion creation path lacks a label-attachment step (either during createDiscussion input if supported, or a follow-up mutation to apply labels after creation).

Suggested fix

After discussion creation, resolve label IDs for configured labels and apply them to the created discussion node (or include label IDs directly if supported by the create mutation input).

Impact

Workflows depending on discussion labels for triage, filtering, and close-older-discussions matching do not behave as configured.
</issue_description>

Comments on the Issue (you are @copilot in this section)

<issue_title>safe-outputs create-discussion does not apply configured labels</issue_title>

<issue_description>## Summary
safe-outputs.create-discussion.labels appears to be accepted in config but not applied to newly created discussions.

What I observed

The create_discussion handler parses config.labels, but those labels are never used when creating the discussion.

Expected behavior

When safe-outputs.create-discussion.labels is configured, created discussions should receive those labels.

Actual behavior

Discussion is created successfully, but no labels are applied.

Reproduction

  1. Configure workflow safe-outputs with create-discussion and labels:
safe-outputs:
  create-discussion:
    category: announcements
    labels: [automation, report]
  1. Emit a valid create_discussion output item.
  2. Observe created discussion has no labels.

Code evidence

  • create_discussion parses labels from config, but does not use them later:
    • actions/setup/js/create_discussion.cjs:196
  • Discussion creation GraphQL mutation only sends repositoryId, categoryId, title, and body:
    • actions/setup/js/create_discussion.cjs:405
  • By contrast, create_issue builds and passes labels to API create call:
    • actions/setup/js/create_issue.cjs:376
    • actions/setup/js/create_issue.cjs:469
  • Schema/docs indicate labels should be attached to created discussions:
    • pkg/parser/schemas/main_workflow_schema.json:4364
    • pkg/workflow/create_discussion.go:18

Likely root cause

The discussion creation path lacks a label-attachment step (either during createDiscussion input if supported, or a follow-up mutation to apply labels after creation).

Suggested fix

After discussion creation, resolve label IDs for configured labels and apply them to the created discussion node (or include label IDs directly if supported by the create mutation input).

Impact

Workflows depending on discussion labels for triage, filtering, and close-older-discussions matching do not behave as configured.
</issue_description>

Comments on the Issue (you are @copilot in this section)

<issue_title>safe-outputs create-discussion does not apply configured labels</issue_title>

<issue_description>## Summary
safe-outputs.create-discussion.labels appears to be accepted in config but not applied to newly created discussions.

What I observed

The create_discussion handler parses config.labels, but those labels are never used when creating the discussion.

Expected behavior

When safe-outputs.create-discussion.labels is configured, created discussions should receive those labels.

Actual behavior

Discussion is created successfully, but no labels are applied.

Reproduction

  1. Configure workflow safe-outputs with create-discussion and labels:
safe-outputs:
  create-discussion:
    category: announcements
    labels: [automation, report]
  1. Emit a valid create_discussion output item.
  2. Observe created discussion has no labels.

Code evidence

  • create_discussion parses labels from config, but does not use them later:
    • actions/setup/js/create_discussion.cjs:196
  • Discussion creation GraphQL mutation only sends repositoryId, categoryId, title, and body:
    • actions/setup/js/create_discussion.cjs:405
  • By contrast, create_issue builds and passes labels to API create call:
    • actions/setup/js/create_issue.cjs:376
    • actions/setup/js/create_issue.cjs:469
  • Schema/docs indicate labels should be attached to created discussions:
    • pkg/parser/schemas/main_workflow_schema.json:4364
    • pkg/workflow/create_discussion.go:18

Likely root cause

The discussion creation path lacks a label-attachment step (either during createDiscussion input if supported, or a follow-up mutation to apply labels after creation).

Suggested fix

After discussion creation, resolve label IDs for configured labels and apply them to the created discussion node (or include label IDs directly if supported by the create mutation input).

Impact

Workflows depending on discussion labels for triage, filtering, and close-older-discussions matching do not behave as configured.
</issue_description>

Comments on the Issue (you are @copilot in this section)

Original prompt

This section details on the original issue you should resolve

<issue_title>safe-outputs create-discussion does not apply configured labels</issue_title>
<issue_description>## Summary
safe-outputs.create-discussion.labels appears to be accepted in config but not applied to newly created discussions.

What I observed

The create_discussion handler parses config.labels, but those labels are never used when creating the discussion.

Expected behavior

When safe-outputs.create-discussion.labels is configured, created discussions should receive those labels.

Actual behavior

Discussion is created successfully, but no labels are applied.

Reproduction

  1. Configure workflow safe-outputs with create-discussion and labels:
safe-outputs:
  create-discussion:
    category: announcements
    labels: [automation, report]
  1. Emit a valid create_discussion output item.
  2. Observe created discussion has no labels.

Code evidence

  • create_discussion parses labels from config, but does not use them later:
    • actions/setup/js/create_discussion.cjs:196
  • Discussion creation GraphQL mutation only sends repositoryId, categoryId, title, and body:
    • actions/setup/js/create_discussion.cjs:405
  • By contrast, create_issue builds and passes labels to API create call:
    • actions/setup/js/create_issue.cjs:376
    • actions/setup/js/create_issue.cjs:469
  • Schema/docs indicate labels should be attached to created discussions:
    • pkg/parser/schemas/main_workflow_schema.json:4364
    • pkg/workflow/create_discussion.go:18

Likely root cause

The discussion creation path lacks a label-attachment step (either during createDiscussion input if supported, or a follow-up mutation to apply labels after creation).

Suggested fix

After discussion creation, resolve label IDs for configured labels and apply them to the created discussion node (or include label IDs directly if supported by the create mutation input).

Impact

Workflows depending on discussion labels for triage, filtering, and close-older-discussions matching do not behave as configured.
</issue_description>

Comments on the Issue (you are @copilot in this section)


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI and others added 2 commits February 14, 2026 04:37
- Add fetchLabelIds() to fetch label node IDs from repository
- Add applyLabelsToDiscussion() to apply labels via GraphQL
- Build discussionLabels array with sanitization and deduplication
- Apply labels after discussion creation
- Handle errors gracefully (log warnings, continue if label application fails)
- Add comprehensive tests for label functionality

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix labels not applied to created discussions safe-outputs: Apply labels when creating discussions Feb 14, 2026
Copilot AI requested a review from pelikhan February 14, 2026 04:44
Copilot stopped work on behalf of pelikhan due to an error February 14, 2026 04:47
@pelikhan
Copy link
Contributor

@copilot update smoke codex to create a discussion in announcements category titled "codex was here" and with label "codex-was-here". Update prompt to make it one of the agent goals

- Add create-discussion to safe-outputs with announcements category
- Configure codex-was-here label for discussions
- Add test requirement #7 for discussion creation testing
- Update output section to include discussion creation test result

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Feb 14, 2026

@copilot update smoke codex to create a discussion in announcements category titled "codex was here" and with label "codex-was-here". Update prompt to make it one of the agent goals

Updated smoke-codex workflow in commit 4b150b4:

The workflow will now test the label application functionality for discussions.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • https://api.github.com/user
    • Triggering command: /usr/bin/gh gh api user --jq .login (http block)

If you need me to access, download, or install something from one of these locations, you can either:

@pelikhan
Copy link
Contributor

@copilot create-didcussion in smoke-codex should expire in 1d and close-older-discussions

…ussions

- Set expires: 1d for create-discussion (24 hours)
- Enable close-older-discussions: true to clean up old discussions

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Feb 14, 2026

@copilot create-didcussion in smoke-codex should expire in 1d and close-older-discussions

Updated in commit 6e4234c:

  • Set expires: 1d (24 hours) for create-discussion
  • Enabled close-older-discussions: true

The smoke-codex workflow will now create discussions that expire in 1 day and automatically close older discussions with the same workflow-id marker.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • https://api.github.com/user
    • Triggering command: /usr/bin/gh gh api user --jq .login (http block)

If you need me to access, download, or install something from one of these locations, you can either:

@github-actions
Copy link
Contributor

📰 BREAKING: Smoke Copilot is now investigating this pull request. Sources say the story is developing...

@github-actions
Copy link
Contributor

github-actions bot commented Feb 14, 2026

Changeset Generator failed. Please review the logs for details.

@github-actions
Copy link
Contributor

🧪 Smoke Temporary ID is now testing temporary ID functionality...

@github-actions
Copy link
Contributor

github-actions bot commented Feb 14, 2026

🎬 THE ENDSmoke Claude MISSION: ACCOMPLISHED! The hero saves the day! ✨

@github-actions
Copy link
Contributor

github-actions bot commented Feb 14, 2026

🌑 The shadows whisper... Smoke Codex failed. The oracle requires further meditation...

@github-actions
Copy link
Contributor

🧪 Smoke Project is now testing project operations...

@github-actions
Copy link
Contributor

Smoke Project completed successfully. All project operations validated.

- Change create-discussion label from copilot-was-here to ai-generated
- Update test requirement #9 to reflect the new label
- Recompile workflow

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Feb 14, 2026

@copilot use ai-generated label for create-discussion sample in smoke copilot

Updated in commit 977949a:

smoke-copilot now tests discussion creation with the ai-generated label.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • https://api.github.com/user
    • Triggering command: /usr/bin/gh gh api user --jq .login (http block)

If you need me to access, download, or install something from one of these locations, you can either:

@github-actions
Copy link
Contributor

📰 VERDICT: Smoke Copilot has concluded. All systems operational. This is a developing story. 🎤

@github-actions
Copy link
Contributor

🧪 Smoke Temporary ID is now testing temporary ID functionality...

@github-actions
Copy link
Contributor

🧪 Smoke Project is now testing project operations...

@github-actions
Copy link
Contributor

github-actions bot commented Feb 14, 2026

🌑 The shadows whisper... Smoke Codex failed. The oracle requires further meditation...

@github-actions
Copy link
Contributor

github-actions bot commented Feb 14, 2026

Changeset Generator failed. Please review the logs for details.

@github-actions
Copy link
Contributor

📰 BREAKING: Smoke Copilot is now investigating this pull request. Sources say the story is developing...

@github-actions
Copy link
Contributor

github-actions bot commented Feb 14, 2026

🎬 THE ENDSmoke Claude MISSION: ACCOMPLISHED! The hero saves the day! ✨

@github-actions
Copy link
Contributor

Smoke Temporary ID completed successfully. Temporary ID validation passed.

@github-actions
Copy link
Contributor

Smoke Project completed successfully. All project operations validated.

@github-actions
Copy link
Contributor

Agent Container Tool Check ✅

Tool Status Version
bash 5.2.21
sh available
git 2.52.0
jq 1.7
yq 4.52.2
curl 8.5.0
gh 2.86.0
node 20.20.0
python3 3.12.3
go 1.24.13
java 21.0.10
dotnet 10.0.102

Result: 12/12 tools available ✅

All required development tools are present and functional in the agent container environment.

AI generated by Agent Container Smoke Test

@github-actions
Copy link
Contributor

🚀 Smoke Test Results

PR Titles:

Test Results:

  • ✅ GitHub MCP
  • ✅ Safe Inputs GH CLI
  • ❌ Serena MCP (not available)
  • ❌ Playwright (not available)
  • ✅ File Writing
  • ✅ Bash Tool
  • ✅ Discussion Interaction
  • ✅ Build gh-aw
  • ✅ Discussion Creation
  • ✅ Workflow Dispatch
  • ✅ PR Review

Overall: PARTIAL PASS (9/11 tests, 81.8%)

cc: @pelikhan

AI generated by Smoke Copilot

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Smoke Test Review

Added create_discussion safe-output to smoke-copilot workflow with 24-hour expiration. Changes look good - proper integration of discussion creation testing.

📰 BREAKING: Report filed by Smoke Copilot for issue #15597

mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
cat > /opt/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_EOF'
{"add_comment":{"allowed_repos":["github/gh-aw"],"max":2},"add_labels":{"allowed":["smoke-copilot"],"allowed_repos":["github/gh-aw"],"max":3},"create_issue":{"expires":2,"group":true,"max":1},"create_pull_request_review_comment":{"max":5},"dispatch_workflow":{"max":1,"workflow_files":{"haiku-printer":".yml"},"workflows":["haiku-printer"]},"missing_data":{},"missing_tool":{},"noop":{"max":1},"remove_labels":{"allowed":["smoke"],"max":3},"send-slack-message":{"description":"Send a message to Slack (stub for testing)","inputs":{"message":{"default":null,"description":"The message to send","required":true,"type":"string"}},"output":"Slack message stub executed!"},"submit_pull_request_review":{"max":1}}
{"add_comment":{"allowed_repos":["github/gh-aw"],"max":2},"add_labels":{"allowed":["smoke-copilot"],"allowed_repos":["github/gh-aw"],"max":3},"create_discussion":{"expires":24,"max":1},"create_issue":{"expires":2,"group":true,"max":1},"create_pull_request_review_comment":{"max":5},"dispatch_workflow":{"max":1,"workflow_files":{"haiku-printer":".yml"},"workflows":["haiku-printer"]},"missing_data":{},"missing_tool":{},"noop":{"max":1},"remove_labels":{"allowed":["smoke"],"max":3},"send-slack-message":{"description":"Send a message to Slack (stub for testing)","inputs":{"message":{"default":null,"description":"The message to send","required":true,"type":"string"}},"output":"Slack message stub executed!"},"submit_pull_request_review":{"max":1}}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Good addition: create_discussion config now includes expires: 24 (hours) to automatically clean up test discussions after 1 day.

@github-actions
Copy link
Contributor

📰 VERDICT: Smoke Copilot has concluded. All systems operational. This is a developing story. 🎤

@pelikhan pelikhan marked this pull request as ready for review February 14, 2026 05:54
Copilot AI review requested due to automatic review settings February 14, 2026 05:54
@pelikhan pelikhan merged commit a984013 into main Feb 14, 2026
182 of 184 checks passed
@pelikhan pelikhan deleted the copilot/fix-create-discussion-labels branch February 14, 2026 05:56
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a bug where discussion labels configured in safe-outputs.create-discussion.labels were parsed but never applied to created discussions. The fix implements a two-step GraphQL approach: fetching label node IDs via query, then applying them using the addLabelsToLabelable mutation after discussion creation.

Changes:

  • Implemented label fetching and application functionality for discussions using GraphQL
  • Added comprehensive test coverage for label operations (merging, sanitization, deduplication, error handling)
  • Updated smoke-copilot workflow to test discussion creation with labels, expiration, and cleanup features

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
actions/setup/js/create_discussion.cjs Added fetchLabelIds() and applyLabelsToDiscussion() functions; integrated label merging, sanitization, and application into discussion creation flow
actions/setup/js/create_discussion_labels.test.cjs Added comprehensive test suite covering label application scenarios: config labels, per-message labels, merging, sanitization, missing labels, and graceful error handling
.github/workflows/smoke-copilot.md Added test requirement #9 for discussion creation with labels; configured discussion with announcements category, ai-generated label, 1d expiration, and close-older-discussions
.github/workflows/smoke-copilot.lock.yml Generated lock file reflecting workflow changes with proper configuration for create_discussion including labels, expiration, and cleanup settings

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


if (unmatchedLabels.length > 0) {
core.warning(`Could not find label IDs for: ${unmatchedLabels.join(", ")}`);
core.info(`These labels may not exist in the repository. Available labels: ${repoLabels.map(l => l.name).join(", ")}`);
Copy link

Copilot AI Feb 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line 166 logs all available repository labels when requested labels are not found. For repositories with many labels (up to the 100 label query limit), this could result in very long log messages. Consider truncating the list or limiting the number of labels shown in the informational message (e.g., showing only the first 10 labels and adding "... and N more" for the rest) to improve log readability.

Suggested change
core.info(`These labels may not exist in the repository. Available labels: ${repoLabels.map(l => l.name).join(", ")}`);
const availableLabelNames = repoLabels.map((l) => l.name);
const maxLabelsToShow = 10;
const displayedLabels = availableLabelNames.slice(0, maxLabelsToShow);
let infoMessage = `These labels may not exist in the repository. Available labels: ${displayedLabels.join(", ")}`;
if (availableLabelNames.length > maxLabelsToShow) {
const remainingCount = availableLabelNames.length - maxLabelsToShow;
infoMessage += ` ... and ${remainingCount} more`;
}
core.info(infoMessage);

Copilot uses AI. Check for mistakes.
if (labelsApplied) {
core.info(`✓ Applied labels: ${labelIdsData.map(l => l.name).join(", ")}`);
}
} else if (discussionLabels.length > 0) {
Copy link

Copilot AI Feb 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The condition discussionLabels.length > 0 is redundant in this else-if block. This code is already within the outer if (discussionLabels.length > 0) block (line 561), and the else-if only executes when labelIdsData.length === 0. The redundant check can be simplified to just else without the condition.

Suggested change
} else if (discussionLabels.length > 0) {
} else {

Copilot uses AI. Check for mistakes.
Comment on lines +33 to +36
let callCount = 0;
mockGithub.graphql.mockImplementation(async (query, variables) => {
callCount++;

Copy link

Copilot AI Feb 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The callCount variable is declared and incremented but never used in the mock implementation. This appears to be dead code that can be removed to improve code clarity.

Suggested change
let callCount = 0;
mockGithub.graphql.mockImplementation(async (query, variables) => {
callCount++;
mockGithub.graphql.mockImplementation(async (query, variables) => {

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

safe-outputs create-discussion does not apply configured labels

3 participants