You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Extend command-action to support the discussion_comment event in addition to issue_comment, so IssueOps commands can be triggered from comments on GitHub Discussions.
To stay aligned with the I/F finalized in #100, this change extends the same output vocabulary (number, context) and the allowed_contexts input vocabulary to cover discussions.
Note
This issue depends on #100. Implement it after the number / context output redesign in #100 has landed, and base the new behavior on that redesigned surface.
Motivation
command-action currently only handles issue_comment and emits a warning for any other eventName (src/main.ts:11-14). Workflows triggered by on: discussion_comment are dropped without doing any parsing.
GitHub Discussions are a first-class collaboration surface in many repositories, and IssueOps-style commands (.deploy, .preview, .label, etc.) are equally useful in discussion threads (Q&A triage, RFC voting, release-note drafting, etc.).
src/main.ts:11-14 currently rejects any event other than issue_comment. Replace the equality check with an allow-list of {"issue_comment", "discussion_comment"}.
Keep the warning message for unsupported events but list both accepted events.
2. Extend allowed_contexts vocabulary
Add discussion to the allowed values of allowed_contexts (currently issue / pull_request).
Update the validContexts set in src/main.ts:8 to {"issue", "pull_request", "discussion"}.
Update the default of allowed_contexts in action.yaml:14 from issue,pull_request to issue,pull_request,discussion. This is a strict addition: workflows that do not listen to discussion_comment are unaffected, and workflows that do gain support without manual opt-in.
3. Determine the triggering context
Introduce a single helper that, given the current @actions/githubcontext, returns the discriminated triple { kind: "issue" | "pull_request" | "discussion", number, commentId, actor, body }. Use it from both isValidContext (for the allowed_contexts filter) and the output emission site, so the kind is computed in exactly one place.
Determination rules:
Event
Condition
kind
issue_comment
payload.issue.pull_request != null
"pull_request"
issue_comment
otherwise
"issue"
discussion_comment
always
"discussion"
This replaces the existing isPr boolean in src/main.ts:26 (which #100 already plans to lift out — coordinate so both changes converge on the same helper rather than introducing two competing abstractions).
4. Outputs on the discussion context
After isValidContext passes, emit the following for a discussion kind:
The legacy name does not apply to discussions; downstream consumers should migrate to number (per #100's deprecation). For issue_comment events, issue_number continues to be emitted unchanged.
5. Parser reuse
parse(body) in src/parse.ts already operates on a plain comment body string. No parser changes required.
Confirm via a unit test on main.ts that a discussion comment body flows through the same parsing path.
6. README updates
Update §Inputs / §Outputs tables (regenerated by pnpm generate):
allowed_contexts default changes to issue,pull_request,discussion.
Description adds discussion as an allowed value.
context output description lists the three possible values.
Add a §Getting Started example for discussions:
on: discussion_comment: types: [created]
permissions: discussions: write (required for adding reactions to discussion comments via github.graphql — addReaction mutation; same level of detail as the existing Tips section for issue/PR reactions).
Brief callout linking to allowed_contexts if the workflow wants to restrict to discussions only.
7. Tests
src/main.ts currently has no unit tests. Add src/main.test.ts (vitest) covering the matrix below. Use vi.mock("@actions/github", ...) to inject eventName and payload per case, and spy on core.setOutput / core.warning to assert emission.
warning emitted, continue="false", no other outputs
allowed_contexts filter mismatch
discussion_comment with allowed_contexts="issue"
discussion payload
info emitted, continue="false"
Spec details
action.yaml
inputs:
allowed_contexts:
description: 'The comment contexts that trigger the IssueOps command, specified as a comma-separated list. Allowed values: "issue", "pull_request", "discussion".'default: 'issue,pull_request,discussion'outputs:
context:
description: 'The context that triggered this action. One of "issue", "pull_request", or "discussion".'# (other outputs unchanged from #100)
When allowed_contexts does not include discussion, a discussion_comment event sets continue="false" and emits an info message, without setting number / context / etc.
src/main.test.ts covers the five cases in the test matrix above.
README §Inputs / §Outputs tables are regenerated via pnpm generate and reflect the new default and discussion value.
README has a discussion_comment example workflow including permissions: discussions: write.
pnpm build produces an updated dist/, committed in the same PR.
pnpm typecheck, pnpm lint, pnpm test, pnpm generate (no drift) all pass in CI.
Out of scope
Filtering by Discussion category (Q&A, General, Announcements, etc.). If demand surfaces, design a separate input (e.g. allowed_discussion_categories) in a follow-up issue.
Answering / marking discussion comments as the chosen answer. Belongs to user-side workflow logic via the GraphQL API, not this action.
Reaction support. Already handled by the README Tips section pattern and out of scope for this action.
The discussion_comment payload exposes discussion.number, comment.id, comment.body, and comment.user.login in the same shape as documented in GitHub Webhooks docs. Verify against @actions/github's WebhookPayload typings during implementation; if the field shape differs, adjust the helper accordingly.
Expanding the allowed_contexts default to include discussion is treated as a non-breaking addition because the action still requires the workflow's on: trigger to fire discussion_comment for the new path to activate.
Summary
Extend
command-actionto support thediscussion_commentevent in addition toissue_comment, so IssueOps commands can be triggered from comments on GitHub Discussions.To stay aligned with the I/F finalized in #100, this change extends the same output vocabulary (
number,context) and theallowed_contextsinput vocabulary to cover discussions.Note
This issue depends on #100. Implement it after the
number/contextoutput redesign in #100 has landed, and base the new behavior on that redesigned surface.Motivation
command-actioncurrently only handlesissue_commentand emits a warning for any othereventName(src/main.ts:11-14). Workflows triggered byon: discussion_commentare dropped without doing any parsing..deploy,.preview,.label, etc.) are equally useful in discussion threads (Q&A triage, RFC voting, release-note drafting, etc.).numberandcontextoutputs, soft-deprecateissue_number#100 already moves the output vocabulary toward an event-agnostic shape (number/context). Extending it once more to cover discussions is cheap if it ships right after feat(output): addnumberandcontextoutputs, soft-deprecateissue_number#100, and avoids a third migration later.Proposed changes
1. Accept
discussion_commentinisValidContextsrc/main.ts:11-14currently rejects any event other thanissue_comment. Replace the equality check with an allow-list of{"issue_comment", "discussion_comment"}.2. Extend
allowed_contextsvocabularydiscussionto the allowed values ofallowed_contexts(currentlyissue/pull_request).validContextsset insrc/main.ts:8to{"issue", "pull_request", "discussion"}.allowed_contextsinaction.yaml:14fromissue,pull_requesttoissue,pull_request,discussion. This is a strict addition: workflows that do not listen todiscussion_commentare unaffected, and workflows that do gain support without manual opt-in.3. Determine the triggering context
Introduce a single helper that, given the current
@actions/githubcontext, returns the discriminated triple{ kind: "issue" | "pull_request" | "discussion", number, commentId, actor, body }. Use it from bothisValidContext(for theallowed_contextsfilter) and the output emission site, so the kind is computed in exactly one place.Determination rules:
kindissue_commentpayload.issue.pull_request != null"pull_request"issue_comment"issue"discussion_comment"discussion"This replaces the existing
isPrboolean insrc/main.ts:26(which #100 already plans to lift out — coordinate so both changes converge on the same helper rather than introducing two competing abstractions).4. Outputs on the
discussioncontextAfter
isValidContextpasses, emit the following for adiscussionkind:numberpayload.discussion.numbernumberfor issue/PR.context"discussion"comment_idpayload.comment.idissue_comment.actorpayload.comment.user.loginissue_comment.command/params/continueissue_numbernumber(per #100's deprecation). Forissue_commentevents,issue_numbercontinues to be emitted unchanged.5. Parser reuse
parse(body)insrc/parse.tsalready operates on a plain comment body string. No parser changes required.main.tsthat a discussion comment body flows through the same parsing path.6. README updates
pnpm generate):allowed_contextsdefault changes toissue,pull_request,discussion.discussionas an allowed value.contextoutput description lists the three possible values.on: discussion_comment: types: [created]permissions: discussions: write(required for adding reactions to discussion comments viagithub.graphql—addReactionmutation; same level of detail as the existing Tips section for issue/PR reactions).allowed_contextsif the workflow wants to restrict to discussions only.7. Tests
src/main.tscurrently has no unit tests. Addsrc/main.test.ts(vitest) covering the matrix below. Usevi.mock("@actions/github", ...)to injecteventNameandpayloadper case, and spy oncore.setOutput/core.warningto assert emission.issue_commentpayload.issue.pull_request == nullcontext="issue",number=payload.issue.number,issue_numberemittedissue_commentpayload.issue.pull_request != nullcontext="pull_request",number=payload.issue.number,issue_numberemitteddiscussion_commentpayload.discussion.numbersetcontext="discussion",number=payload.discussion.number,issue_numbernot emittedpushcontinue="false", no other outputsallowed_contextsfilter mismatchdiscussion_commentwithallowed_contexts="issue"continue="false"Spec details
action.yamlsrc/main.ts(sketch)Output emission inside
runthen becomes:Acceptance criteria
action.yamldeclaresallowed_contextsdefaultissue,pull_request,discussionand listsdiscussionin the description.action.yaml'scontextoutput description lists"issue","pull_request","discussion".src/main.tsacceptseventNameof eitherissue_commentordiscussion_commentand rejects others with a warning.{ kind, number, commentId, actor, body }and is used by both theallowed_contextsfilter and the output emission.discussion_comment:number === payload.discussion.number,context === "discussion",issue_numberis not emitted.issue_comment(issue or PR): behavior matches feat(output): addnumberandcontextoutputs, soft-deprecateissue_number#100 (number === payload.issue.number,issue_numberstill emitted).allowed_contextsdoes not includediscussion, adiscussion_commentevent setscontinue="false"and emits an info message, without settingnumber/context/ etc.src/main.test.tscovers the five cases in the test matrix above.pnpm generateand reflect the new default anddiscussionvalue.permissions: discussions: write.pnpm buildproduces an updateddist/, committed in the same PR.pnpm typecheck,pnpm lint,pnpm test,pnpm generate(no drift) all pass in CI.Out of scope
Q&A,General,Announcements, etc.). If demand surfaces, design a separate input (e.g.allowed_discussion_categories) in a follow-up issue.issue_number. Tracked separately under feat(output): addnumberandcontextoutputs, soft-deprecateissue_number#100's "next major release" plan.Migration
For existing v1 consumers, no migration is required:
issue_commentare unaffected.on: discussion_comment: types: [created]andpermissions: discussions: write, and switch fromoutputs.issue_numbertooutputs.number(already recommended by feat(output): addnumberandcontextoutputs, soft-deprecateissue_number#100).Assumptions
discussion.number,comment.id,comment.body, andcomment.user.loginin the same shape as documented in GitHub Webhooks docs. Verify against@actions/github'sWebhookPayloadtypings during implementation; if the field shape differs, adjust the helper accordingly.allowed_contextsdefault to includediscussionis treated as a non-breaking addition because the action still requires the workflow'son:trigger to firediscussion_commentfor the new path to activate."discussion"(singular, matchingallowed_contexts) is consistent with the existing"issue"/"pull_request"vocabulary in feat(output): addnumberandcontextoutputs, soft-deprecateissue_number#100.References
numberandcontextoutputs, soft-deprecateissue_number#100 — output redesign that introducesnumberandcontext. This issue extends that vocabulary.src/main.ts:8—validContextsset.src/main.ts:11-14— current eventName rejection.src/main.ts:26— currentisPrcomputation.src/main.ts:58-60— current output emission site.action.yaml:14— currentallowed_contextsdefault.action.yaml:25-28— current outputs declaration.discussion_comment.