Skip to content

Commit fe4d0e0

Browse files
committed
Update push-to-discussions.yml
1 parent 7919d2f commit fe4d0e0

File tree

1 file changed

+125
-104
lines changed

1 file changed

+125
-104
lines changed
Lines changed: 125 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Push → Discussion (GraphQL)
1+
name: Push → Discussion (gh cli)
22

33
on:
44
push:
@@ -10,114 +10,135 @@ permissions:
1010
discussions: write
1111

1212
env:
13-
DISCUSSIONS_CATEGORY: Push Updates # must match the category name in your repo
13+
DISCUSSIONS_CATEGORY: Push Updates
1414

1515
jobs:
1616
post:
1717
runs-on: ubuntu-latest
18+
env:
19+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} # gh uses this
1820
steps:
19-
- name: Create a discussion for this push
20-
uses: actions/github-script@v7
21-
with:
22-
github-token: ${{ secrets.GITHUB_TOKEN }}
23-
script: |
24-
const { owner, repo } = context.repo;
25-
const desiredName = (process.env.DISCUSSIONS_CATEGORY || "").trim();
26-
27-
// 1) GraphQL: get repo id + discussion categories
28-
const query = `
29-
query($owner: String!, $name: String!) {
30-
repository(owner: $owner, name: $name) {
31-
id
32-
hasDiscussionsEnabled
33-
discussionCategories(first: 50) {
34-
nodes { id name }
35-
}
21+
- name: Build title and body from push payload
22+
id: build
23+
run: |
24+
set -euo pipefail
25+
26+
EV="$GITHUB_EVENT_PATH"
27+
28+
OWNER="${GITHUB_REPOSITORY%/*}"
29+
REPO="${GITHUB_REPOSITORY#*/}"
30+
31+
BRANCH="$(jq -r '.ref' "$EV" | sed 's#^refs/heads/##')"
32+
[ -z "$BRANCH" ] && BRANCH="(unknown)"
33+
34+
PUSHER="$(jq -r '.pusher.name // .sender.login // "unknown"' "$EV")"
35+
36+
BEFORE="$(jq -r '.before' "$EV")"
37+
AFTER="$(jq -r '.after' "$EV")"
38+
COMPARE="$(jq -r '.compare // empty' "$EV")"
39+
if [ -z "$COMPARE" ]; then
40+
COMPARE="https://github.com/${OWNER}/${REPO}/compare/${BEFORE}...${AFTER}"
41+
fi
42+
43+
COMMIT_COUNT="$(jq -r '.commits | length' "$EV")"
44+
45+
# Commit list (first line of message, author, link)
46+
COMMITS_MD="$(jq -r '
47+
if (.commits | length) == 0 then
48+
""
49+
else
50+
[.commits[]
51+
| "- [`\(.id[0:7])`](\(.url)) \((.message // "" ) | split("\n")[0]) — _\(.author.name // "unknown")_"
52+
] | join("\n")
53+
end
54+
' "$EV")"
55+
56+
TITLE="Push to ${BRANCH} by ${PUSHER} — ${COMMIT_COUNT} commit"
57+
[ "$COMMIT_COUNT" -ne 1 ] && TITLE="${TITLE}s"
58+
59+
{
60+
echo "> _This discussion was created automatically by GitHub Actions from a \`push\` event._"
61+
echo
62+
echo "**Branch:** \`${BRANCH}\`"
63+
echo "**Pusher:** ${PUSHER}"
64+
echo "**Compare:** ${COMPARE}"
65+
echo
66+
echo "### Commits"
67+
if [ -n "$COMMITS_MD" ]; then
68+
echo "$COMMITS_MD"
69+
else
70+
echo "_No commit details available._"
71+
fi
72+
echo
73+
echo "<sub>— end of automated log —</sub>"
74+
} > body.md
75+
76+
echo "title<<EOF" >> $GITHUB_OUTPUT
77+
echo "$TITLE" >> $GITHUB_OUTPUT
78+
echo "EOF" >> $GITHUB_OUTPUT
79+
80+
- name: Resolve repo & category IDs via GraphQL
81+
id: ids
82+
run: |
83+
set -euo pipefail
84+
OWNER="${GITHUB_REPOSITORY%/*}"
85+
REPO="${GITHUB_REPOSITORY#*/}"
86+
87+
# Query repo info + categories
88+
RESP="$(gh api graphql -f query='
89+
query($owner:String!, $name:String!){
90+
repository(owner:$owner, name:$name){
91+
id
92+
hasDiscussionsEnabled
93+
discussionCategories(first:50){
94+
nodes{ id name }
3695
}
3796
}
38-
`;
39-
let repoInfo;
40-
try {
41-
repoInfo = await github.graphql(query, { owner, name: repo });
42-
} catch (e) {
43-
core.setFailed(\`GraphQL repo/category lookup failed: \${e.message}\`);
44-
return;
45-
}
46-
47-
const repository = repoInfo?.repository;
48-
if (!repository) {
49-
core.setFailed("Repository not found by GraphQL; check owner/repo context.");
50-
return;
51-
}
52-
if (!repository.hasDiscussionsEnabled) {
53-
core.setFailed("Discussions are not enabled for this repository (Settings → General → Features → Discussions).");
54-
return;
55-
}
56-
57-
const categories = repository.discussionCategories?.nodes || [];
58-
const category = categories.find(c => c.name.toLowerCase() === desiredName.toLowerCase());
59-
if (!category) {
60-
const names = categories.map(c => `- ${c.name}`).join("\n") || "(none found)";
61-
core.setFailed(`Category "${desiredName}" not found.\nAvailable categories:\n${names}`);
62-
return;
63-
}
64-
65-
// 2) Build title/body from push payload
66-
const push = context.payload;
67-
const branch = (push.ref || "").replace("refs/heads/", "") || "(unknown)";
68-
const pusher = push.pusher?.name || push.sender?.login || "unknown";
69-
const commits = push.commits || [];
70-
const commitCount = commits.length;
71-
72-
const title = `Push to ${branch} by ${pusher} — ${commitCount} commit${commitCount === 1 ? "" : "s"}`;
73-
74-
const lines = commits.map(c => {
75-
const sha7 = (c.id || "").slice(0,7);
76-
const first = (c.message || "").split("\n")[0];
77-
const author = c.author?.name || "unknown";
78-
const url = c.url || \`https://github.com/${owner}/${repo}/commit/\${c.id}\`;
79-
return `- [\`${sha7}\`](${url}) ${first} — _${author}_`;
80-
});
81-
82-
const compareUrl =
83-
push.compare ||
84-
\`https://github.com/${owner}/${repo}/compare/\${push.before}...\${push.after}\`;
85-
86-
const body = [
87-
`> _This discussion was created automatically by GitHub Actions from a \`push\` event._`,
88-
"",
89-
`**Branch:** \`${branch}\``,
90-
`**Pusher:** ${pusher}`,
91-
`**Compare:** ${compareUrl}`,
92-
"",
93-
"### Commits",
94-
lines.length ? lines.join("\n") : "_No commit details available._",
95-
"",
96-
"<sub>— end of automated log —</sub>"
97-
].join("\n");
98-
99-
// 3) GraphQL: create discussion
100-
const mutation = `
101-
mutation($repoId: ID!, $catId: ID!, $title: String!, $body: String!) {
102-
createDiscussion(input: {
103-
repositoryId: $repoId,
104-
categoryId: $catId,
105-
title: $title,
106-
body: $body
107-
}) {
108-
discussion { url }
97+
}' -f owner="$OWNER" -f name="$REPO")"
98+
99+
REPO_ID="$(echo "$RESP" | jq -r '.data.repository.id')"
100+
DISC_ENABLED="$(echo "$RESP" | jq -r '.data.repository.hasDiscussionsEnabled')"
101+
[ "$DISC_ENABLED" != "true" ] && { echo "Discussions not enabled"; exit 1; }
102+
103+
CAT_NAME="${DISCUSSIONS_CATEGORY}"
104+
CAT_ID="$(echo "$RESP" | jq -r --arg n "$CAT_NAME" '
105+
.data.repository.discussionCategories.nodes[]
106+
| select((.name|ascii_downcase)==($n|ascii_downcase))
107+
| .id
108+
')"
109+
110+
if [ -z "$CAT_ID" ]; then
111+
echo "Available categories:"
112+
echo "$RESP" | jq -r '.data.repository.discussionCategories.nodes[].name'
113+
echo "Category \"$CAT_NAME\" not found."
114+
exit 1
115+
fi
116+
117+
echo "repo_id=$REPO_ID" >> $GITHUB_OUTPUT
118+
echo "cat_id=$CAT_ID" >> $GITHUB_OUTPUT
119+
120+
- name: Create discussion
121+
run: |
122+
set -euo pipefail
123+
TITLE="${{ steps.build.outputs.title }}"
124+
REPO_ID="${{ steps.ids.outputs.repo_id }}"
125+
CAT_ID="${{ steps.ids.outputs.cat_id }}"
126+
BODY_CONTENT="$(cat body.md)"
127+
128+
gh api graphql \
129+
-f query='
130+
mutation($repoId:ID!, $catId:ID!, $title:String!, $body:String!){
131+
createDiscussion(input:{
132+
repositoryId:$repoId,
133+
categoryId:$catId,
134+
title:$title,
135+
body:$body
136+
}){
137+
discussion{ url }
109138
}
110-
}
111-
`;
112-
try {
113-
const res = await github.graphql(mutation, {
114-
repoId: repository.id,
115-
catId: category.id,
116-
title,
117-
body
118-
});
119-
const url = res?.createDiscussion?.discussion?.url;
120-
core.info(\`Created discussion: \${url}\`);
121-
} catch (e) {
122-
core.setFailed(\`Failed to create discussion via GraphQL: \${e.message}\`);
123-
}
139+
}' \
140+
-f repoId="$REPO_ID" \
141+
-f catId="$CAT_ID" \
142+
-f title="$TITLE" \
143+
-f body="$BODY_CONTENT" \
144+
--jq '.data.createDiscussion.discussion.url'

0 commit comments

Comments
 (0)