Skip to content

Merge pull request #1 from th30d4y/copilot/create-github-actions-work… #4

Merge pull request #1 from th30d4y/copilot/create-github-actions-work…

Merge pull request #1 from th30d4y/copilot/create-github-actions-work… #4

Workflow file for this run

name: Organization Issue/PR Bot

Check failure on line 1 in .github/workflows/org-bot.yml

View workflow run for this annotation

GitHub Actions / .github/workflows/org-bot.yml

Invalid workflow file

(Line: 13, Col: 3): Unexpected value 'members'
on:
issues:
types: [opened]
pull_request:
types: [opened]
permissions:
contents: read
issues: write
pull-requests: write
members: read
jobs:
welcome-and-notify:
runs-on: ubuntu-latest
steps:
- name: Build event metadata
id: metadata
uses: actions/github-script@v7
with:
script: |
try {
const payload = context.payload;
if (context.eventName === "issues" && payload.issue) {
core.setOutput("type", "Issue");
core.setOutput("number", String(payload.issue.number));
core.setOutput("title", payload.issue.title || "(no title)");
core.setOutput("url", payload.issue.html_url);
return;
}
if (context.eventName === "pull_request" && payload.pull_request) {
core.setOutput("type", "Pull Request");
core.setOutput("number", String(payload.pull_request.number));
core.setOutput("title", payload.pull_request.title || "(no title)");
core.setOutput("url", payload.pull_request.html_url);
return;
}
core.setFailed(`Unsupported event payload for "${context.eventName}".`);
} catch (error) {
core.setFailed(`Failed to build event metadata: ${error.message}`);
}
- name: Post welcome comment
uses: actions/github-script@v7
env:
BOT_MESSAGE: |
👋 Hello! Thanks for your contribution. We will review this and get back to you as soon as possible. — th30d4y
with:
script: |
const message = process.env.BOT_MESSAGE.trim();
const issueNumber = context.issue.number;
const owner = context.repo.owner;
const repo = context.repo.repo;
try {
const comments = await github.paginate(github.rest.issues.listComments, {
owner,
repo,
issue_number: issueNumber,
per_page: 100
});
const normalize = (text) => (text || "").replace(/\r\n/g, "\n").trim();
const expected = normalize(message);
const alreadyCommented = comments.some((comment) => {
if (!comment?.body) return false;
if (!comment.user?.type?.toLowerCase().includes('bot')) return false;
return normalize(comment.body) === expected;
});
if (alreadyCommented) {
core.info(`Skipping comment: matching bot comment already exists on #${issueNumber}`);
return;
}
await github.rest.issues.createComment({
owner,
repo,
issue_number: issueNumber,
body: message
});
} catch (error) {
core.setFailed(`Failed to post welcome comment: ${error.message}`);
}
- name: Resolve organization owner recipients
id: recipients
uses: actions/github-script@v7
with:
result-encoding: string
script: |
const org = context.repo.owner;
try {
const admins = await github.paginate(github.rest.orgs.listMembers, {
org,
role: "admin",
per_page: 100
});
if (!admins.length) {
core.warning(`No organization owners/admins found for org "${org}".`);
return "";
}
const recipientSet = new Set(
admins.map((admin) => `${admin.id}+${admin.login}@users.noreply.github.com`)
);
const recipients = [...recipientSet].join(",");
core.info(`Resolved ${recipientSet.size} organization owner recipient(s).`);
return recipients;
} catch (error) {
core.setFailed(`Failed to resolve organization owners: ${error.message}`);
return "";
}
- name: Send owner notification email
if: ${{ steps.recipients.outputs.result != '' }}
uses: dawidd6/action-send-mail@v3
with:
server_address: smtp.gmail.com
server_port: 465
secure: true
username: ${{ secrets.EMAIL_USER }}
password: ${{ secrets.EMAIL_PASS }}
subject: "[${{ github.repository }}] New ${{ steps.metadata.outputs.type }} Opened: ${{ steps.metadata.outputs.title }}"
to: ${{ steps.recipients.outputs.result }}
from: th30d4y Bot <${{ secrets.EMAIL_USER }}>
html_body: |
<h3>📣 New ${{ steps.metadata.outputs.type }} Created</h3>
<p><strong>Repository:</strong> <code>${{ github.repository }}</code></p>
<p><strong>Type:</strong> ${{ steps.metadata.outputs.type }}</p>
<p><strong>Title:</strong> ${{ steps.metadata.outputs.title }}</p>
<p><strong>URL:</strong> <a href="${{ steps.metadata.outputs.url }}">${{ steps.metadata.outputs.url }}</a></p>
<hr />
<p>Automated notification by <strong>th30d4y</strong>.</p>
- name: Fail when email was not sent
if: ${{ steps.recipients.outputs.result == '' }}
shell: bash
run: |
echo "No recipients resolved, email notification was not sent." >&2
exit 1