Merge commit '06d0ff377173de8eaa6942ba2880930d980a0d9c'
This commit is contained in:
34
.github/workflows/emoji-bot.yml
vendored
34
.github/workflows/emoji-bot.yml
vendored
@@ -35,3 +35,37 @@ jobs:
|
|||||||
working-directory: ./bot
|
working-directory: ./bot
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
name: Emoji Bot
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
reaction:
|
||||||
|
types:
|
||||||
|
- created
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
issues: write
|
||||||
|
pull-requests: write
|
||||||
|
discussions: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
run:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: 20
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: npm ci
|
||||||
|
|
||||||
|
- name: Run emoji bot
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
EMOJI_BOT_DRY_RUN: "false"
|
||||||
|
run: node bot/index.js
|
||||||
|
|||||||
7
bot/comments/acknowledge.md
Normal file
7
bot/comments/acknowledge.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
Hey @{{actor}}, we caught your ✅ reaction and queued this item for ops.
|
||||||
|
|
||||||
|
- Added labels: {{labels}}
|
||||||
|
- Assigned: {{assignees}}
|
||||||
|
- Context: {{context}}
|
||||||
|
|
||||||
|
Thanks for keeping the signal strong! {{footer}}
|
||||||
7
bot/comments/close.md
Normal file
7
bot/comments/close.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
❌ Reaction received. Closing this out per the automation rules.
|
||||||
|
|
||||||
|
- Added labels: {{labels}}
|
||||||
|
- Assigned: {{assignees}}
|
||||||
|
- Context: {{context}}
|
||||||
|
|
||||||
|
If this was a mistake, re-open with a ✅ reaction and a quick note. {{footer}}
|
||||||
7
bot/comments/escalate.md
Normal file
7
bot/comments/escalate.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
⚡ Escalation triggered by @{{actor}}. We’ve pulled in the right crew to swarm on this.
|
||||||
|
|
||||||
|
- Added labels: {{labels}}
|
||||||
|
- Assigned: {{assignees}}
|
||||||
|
- Context: {{context}}
|
||||||
|
|
||||||
|
We’ll drop updates here as we make progress. {{footer}}
|
||||||
7
bot/comments/help.md
Normal file
7
bot/comments/help.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
🛟 @{{actor}} asked for help via emoji. A support agent will take a look shortly.
|
||||||
|
|
||||||
|
- Added labels: {{labels}}
|
||||||
|
- Assigned: {{assignees}}
|
||||||
|
- Context: {{context}}
|
||||||
|
|
||||||
|
If this is urgent, drop more details and we’ll escalate. {{footer}}
|
||||||
207
bot/index.js
207
bot/index.js
@@ -42,3 +42,210 @@ if (reaction) {
|
|||||||
} else {
|
} else {
|
||||||
console.log("💬 Comment ignored — no emoji trigger detected.");
|
console.log("💬 Comment ignored — no emoji trigger detected.");
|
||||||
}
|
}
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
const yaml = require('js-yaml');
|
||||||
|
const core = require('@actions/core');
|
||||||
|
const github = require('@actions/github');
|
||||||
|
|
||||||
|
function loadYaml(filePath) {
|
||||||
|
const absolutePath = path.resolve(filePath);
|
||||||
|
const fileContents = fs.readFileSync(absolutePath, 'utf8');
|
||||||
|
return yaml.load(fileContents);
|
||||||
|
}
|
||||||
|
|
||||||
|
function resolveTemplate(config, templateKey) {
|
||||||
|
const templateMap = config?.defaults?.templates || {};
|
||||||
|
const resolvedPath = templateMap[templateKey] || templateKey;
|
||||||
|
return path.resolve(resolvedPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderTemplate(content, context) {
|
||||||
|
return content.replace(/{{(.*?)}}/g, (_, key) => {
|
||||||
|
const trimmed = key.trim();
|
||||||
|
return Object.prototype.hasOwnProperty.call(context, trimmed)
|
||||||
|
? context[trimmed]
|
||||||
|
: '';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function mapLabels(labelKeys, defaults) {
|
||||||
|
const labelMap = defaults?.labels || {};
|
||||||
|
return (labelKeys || []).map((key) => labelMap[key] || key);
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseArgs(argv) {
|
||||||
|
const args = { eventPath: null, dryRunOverride: null };
|
||||||
|
for (let i = 0; i < argv.length; i += 1) {
|
||||||
|
const arg = argv[i];
|
||||||
|
if (arg === '--event') {
|
||||||
|
args.eventPath = argv[i + 1];
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
if (arg === '--dry-run') {
|
||||||
|
args.dryRunOverride = true;
|
||||||
|
}
|
||||||
|
if (arg === '--execute') {
|
||||||
|
args.dryRunOverride = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadEventPayload(eventPathFromArgs) {
|
||||||
|
const explicitPath = eventPathFromArgs || process.env.GITHUB_EVENT_PATH;
|
||||||
|
if (!explicitPath) {
|
||||||
|
return github.context.payload;
|
||||||
|
}
|
||||||
|
const absolutePath = path.resolve(explicitPath);
|
||||||
|
const payload = fs.readFileSync(absolutePath, 'utf8');
|
||||||
|
return JSON.parse(payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
function resolveTargetNumber(payload) {
|
||||||
|
if (payload.issue?.number) return payload.issue.number;
|
||||||
|
if (payload.pull_request?.number) return payload.pull_request.number;
|
||||||
|
if (payload.comment?.issue_url) {
|
||||||
|
const parts = payload.comment.issue_url.split('/');
|
||||||
|
return Number(parts[parts.length - 1]);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildContext(payload, config, reactionDefinition) {
|
||||||
|
const labels = mapLabels(reactionDefinition.addLabels, config.defaults);
|
||||||
|
const assignees = reactionDefinition.assign || [];
|
||||||
|
const footer = config.defaults?.commentFooter || '';
|
||||||
|
return {
|
||||||
|
labels: labels.length ? labels.join(', ') : 'none',
|
||||||
|
assignees: assignees.length ? assignees.join(', ') : 'none',
|
||||||
|
footer,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async function applyActions({
|
||||||
|
octokit,
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
issueNumber,
|
||||||
|
reactionDefinition,
|
||||||
|
labels,
|
||||||
|
assignees,
|
||||||
|
dryRun,
|
||||||
|
}) {
|
||||||
|
if (labels.length) {
|
||||||
|
if (dryRun) {
|
||||||
|
core.info(`[dry-run] Would add labels ${labels.join(', ')} to ${owner}/${repo}#${issueNumber}`);
|
||||||
|
} else {
|
||||||
|
await octokit.rest.issues.addLabels({ owner, repo, issue_number: issueNumber, labels });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (assignees.length) {
|
||||||
|
if (dryRun) {
|
||||||
|
core.info(`[dry-run] Would assign ${assignees.join(', ')} to ${owner}/${repo}#${issueNumber}`);
|
||||||
|
} else {
|
||||||
|
await octokit.rest.issues.addAssignees({ owner, repo, issue_number: issueNumber, assignees });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reactionDefinition.close) {
|
||||||
|
if (dryRun) {
|
||||||
|
core.info(`[dry-run] Would close ${owner}/${repo}#${issueNumber}`);
|
||||||
|
} else {
|
||||||
|
await octokit.rest.issues.update({ owner, repo, issue_number: issueNumber, state: 'closed' });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildCommentBody(templatePath, context) {
|
||||||
|
const templateContent = fs.readFileSync(templatePath, 'utf8');
|
||||||
|
return renderTemplate(templateContent, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function postComment({ octokit, owner, repo, issueNumber, body, dryRun }) {
|
||||||
|
if (dryRun) {
|
||||||
|
core.info(`[dry-run] Would post comment to ${owner}/${repo}#${issueNumber}:\n${body}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await octokit.rest.issues.createComment({ owner, repo, issue_number: issueNumber, body });
|
||||||
|
}
|
||||||
|
|
||||||
|
async function run() {
|
||||||
|
const config = loadYaml('emoji-bot-config.yml');
|
||||||
|
const args = parseArgs(process.argv.slice(2));
|
||||||
|
const payload = loadEventPayload(args.eventPath);
|
||||||
|
const reaction = payload.reaction?.content;
|
||||||
|
|
||||||
|
if (!reaction) {
|
||||||
|
core.info('No reaction found in payload. Exiting.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const eventName = process.env.GITHUB_EVENT_NAME || 'local';
|
||||||
|
const targetNumber = resolveTargetNumber(payload);
|
||||||
|
if (!targetNumber) {
|
||||||
|
core.info('Could not resolve target issue or pull request number. Exiting.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const reactionDefinition = config.reactions?.[reaction];
|
||||||
|
if (!reactionDefinition) {
|
||||||
|
core.info(`Reaction ${reaction} is not configured. Exiting.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const owner = payload.repository?.owner?.login || github.context.repo.owner;
|
||||||
|
const repo = payload.repository?.name || github.context.repo.repo;
|
||||||
|
const token = process.env.GITHUB_TOKEN || process.env.GH_TOKEN;
|
||||||
|
const octokit = token ? github.getOctokit(token) : null;
|
||||||
|
|
||||||
|
const dryRunEnv = process.env.EMOJI_BOT_DRY_RUN;
|
||||||
|
const configDefault = Boolean(config.defaults?.dryRun);
|
||||||
|
const dryRun = typeof args.dryRunOverride === 'boolean'
|
||||||
|
? args.dryRunOverride
|
||||||
|
: typeof dryRunEnv === 'string'
|
||||||
|
? dryRunEnv.toLowerCase() !== 'false'
|
||||||
|
: configDefault;
|
||||||
|
|
||||||
|
const templatePath = resolveTemplate(config, reactionDefinition.template);
|
||||||
|
const labels = mapLabels(reactionDefinition.addLabels, config.defaults);
|
||||||
|
const assignees = reactionDefinition.assign || [];
|
||||||
|
const context = buildContext(payload, config, reactionDefinition);
|
||||||
|
const renderedContext = {
|
||||||
|
...context,
|
||||||
|
actor: payload.sender?.login || 'unknown',
|
||||||
|
context: `${owner}/${repo}#${targetNumber} (${eventName})`,
|
||||||
|
};
|
||||||
|
const body = buildCommentBody(templatePath, renderedContext);
|
||||||
|
|
||||||
|
if (!octokit) {
|
||||||
|
core.warning('GITHUB_TOKEN was not provided; running in dry-run mode.');
|
||||||
|
}
|
||||||
|
|
||||||
|
const client = octokit || github.getOctokit('');
|
||||||
|
await applyActions({
|
||||||
|
octokit: client,
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
issueNumber: targetNumber,
|
||||||
|
reactionDefinition,
|
||||||
|
labels,
|
||||||
|
assignees,
|
||||||
|
dryRun: dryRun || !token,
|
||||||
|
});
|
||||||
|
|
||||||
|
await postComment({
|
||||||
|
octokit: client,
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
issueNumber: targetNumber,
|
||||||
|
body,
|
||||||
|
dryRun: dryRun || !token,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
run().catch((error) => {
|
||||||
|
core.setFailed(error.message);
|
||||||
|
});
|
||||||
|
|
||||||
|
|||||||
38
docs/emoji-bot-spec.txt
Normal file
38
docs/emoji-bot-spec.txt
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
Emoji Bot Spec (v0.1)
|
||||||
|
====================
|
||||||
|
|
||||||
|
Summary
|
||||||
|
-------
|
||||||
|
A GitHub Action that listens for reaction events and routes work using emojis.
|
||||||
|
Each emoji maps to a declarative rule set defined in `emoji-bot-config.yml` and
|
||||||
|
uses markdown templates in `bot/comments/` for replies.
|
||||||
|
|
||||||
|
Events
|
||||||
|
------
|
||||||
|
- `reaction.created` on issues, PRs, and comments
|
||||||
|
- Manual `workflow_dispatch` trigger for smoke testing
|
||||||
|
|
||||||
|
Config
|
||||||
|
------
|
||||||
|
- `defaults.dryRun` toggles between logging and performing mutations
|
||||||
|
- `defaults.templates` maps logical names to comment markdown files
|
||||||
|
- `reactions` keys are emoji strings with actions: `addLabels`, `assign`, `close`, `template`, `note`
|
||||||
|
- `defaults.labels` stores reusable label names to avoid duplication
|
||||||
|
|
||||||
|
Actions
|
||||||
|
-------
|
||||||
|
For each matched reaction:
|
||||||
|
- Apply `addLabels` using the canonical labels map
|
||||||
|
- Assign `assign` usernames
|
||||||
|
- Render the configured template with `actor`, `labels`, `assignees`, `context`, and `footer`
|
||||||
|
- If `close` is true, close the issue or pull request
|
||||||
|
|
||||||
|
Local Testing
|
||||||
|
-------------
|
||||||
|
- Run `node bot/index.js --event <path-to-sample-event.json> --dry-run`
|
||||||
|
- Use `npm test` for the rest of the repo if needed; the bot is dependency-light
|
||||||
|
|
||||||
|
Notes
|
||||||
|
-----
|
||||||
|
- The bot relies on `@actions/github` and the built-in `GITHUB_TOKEN`
|
||||||
|
- Templates include a footer marker so duplicate comments are easy to find
|
||||||
@@ -28,3 +28,59 @@ guardian_agent: "@guardian-agent"
|
|||||||
|
|
||||||
# Optional: Default GitHub Project ID to update
|
# Optional: Default GitHub Project ID to update
|
||||||
default_project_id: 12345678 # Example: 12345678
|
default_project_id: 12345678 # Example: 12345678
|
||||||
|
# High-level configuration for the emoji-driven automation bot.
|
||||||
|
# Each reaction entry maps an emoji to the actions the bot should perform.
|
||||||
|
|
||||||
|
meta:
|
||||||
|
name: emoji-bot
|
||||||
|
description: GitHub-native visual automation powered by reactions.
|
||||||
|
maintainers:
|
||||||
|
- ops-team
|
||||||
|
- automation-guild
|
||||||
|
|
||||||
|
defaults:
|
||||||
|
dryRun: true
|
||||||
|
commentFooter: "<!-- emoji-bot -->"
|
||||||
|
templates:
|
||||||
|
acknowledge: bot/comments/acknowledge.md
|
||||||
|
help: bot/comments/help.md
|
||||||
|
close: bot/comments/close.md
|
||||||
|
escalate: bot/comments/escalate.md
|
||||||
|
labels:
|
||||||
|
acknowledged: "status: acknowledged"
|
||||||
|
needsHelp: "needs: support"
|
||||||
|
closed: "status: closed"
|
||||||
|
|
||||||
|
reactions:
|
||||||
|
"✅":
|
||||||
|
template: acknowledge
|
||||||
|
addLabels:
|
||||||
|
- acknowledged
|
||||||
|
assign:
|
||||||
|
- ops-team
|
||||||
|
note: Mark work as acknowledged by operations.
|
||||||
|
|
||||||
|
"🛟":
|
||||||
|
template: help
|
||||||
|
addLabels:
|
||||||
|
- needsHelp
|
||||||
|
assign:
|
||||||
|
- automation-guild
|
||||||
|
note: Route the conversation to a support agent.
|
||||||
|
|
||||||
|
"❌":
|
||||||
|
template: close
|
||||||
|
addLabels:
|
||||||
|
- closed
|
||||||
|
close: true
|
||||||
|
note: Close items that are explicitly rejected.
|
||||||
|
|
||||||
|
"⚡":
|
||||||
|
template: escalate
|
||||||
|
addLabels:
|
||||||
|
- acknowledged
|
||||||
|
- "priority: high"
|
||||||
|
assign:
|
||||||
|
- ops-team
|
||||||
|
- automation-guild
|
||||||
|
note: Escalate urgent work to both groups.
|
||||||
|
|||||||
275
package-lock.json
generated
275
package-lock.json
generated
@@ -9,10 +9,13 @@
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@actions/core": "^1.11.1",
|
||||||
|
"@actions/github": "^6.0.1",
|
||||||
"bullmq": "^5.64.1",
|
"bullmq": "^5.64.1",
|
||||||
"express": "^5.1.0",
|
"express": "^5.1.0",
|
||||||
"fastify": "^5.6.2",
|
"fastify": "^5.6.2",
|
||||||
"ioredis": "^5.8.2",
|
"ioredis": "^5.8.2",
|
||||||
|
"js-yaml": "^4.1.0",
|
||||||
"node-cron": "^4.2.1",
|
"node-cron": "^4.2.1",
|
||||||
"react": "^19.2.0",
|
"react": "^19.2.0",
|
||||||
"react-dom": "^19.2.0",
|
"react-dom": "^19.2.0",
|
||||||
@@ -42,6 +45,56 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/@actions/core": {
|
||||||
|
"version": "1.11.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.11.1.tgz",
|
||||||
|
"integrity": "sha512-hXJCSrkwfA46Vd9Z3q4cpEpHB1rL5NG04+/rbqW9d3+CSvtB1tYe8UTpAlixa1vj0m/ULglfEK2UKxMGxCxv5A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@actions/exec": "^1.1.1",
|
||||||
|
"@actions/http-client": "^2.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@actions/exec": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@actions/exec/-/exec-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-+sCcHHbVdk93a0XT19ECtO/gIXoxvdsgQLzb2fE2/5sIZmWQuluYyjPQtrtTHdU1YzTZ7bAPN4sITq2xi1679w==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@actions/io": "^1.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@actions/github": {
|
||||||
|
"version": "6.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@actions/github/-/github-6.0.1.tgz",
|
||||||
|
"integrity": "sha512-xbZVcaqD4XnQAe35qSQqskb3SqIAfRyLBrHMd/8TuL7hJSz2QtbDwnNM8zWx4zO5l2fnGtseNE3MbEvD7BxVMw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@actions/http-client": "^2.2.0",
|
||||||
|
"@octokit/core": "^5.0.1",
|
||||||
|
"@octokit/plugin-paginate-rest": "^9.2.2",
|
||||||
|
"@octokit/plugin-rest-endpoint-methods": "^10.4.0",
|
||||||
|
"@octokit/request": "^8.4.1",
|
||||||
|
"@octokit/request-error": "^5.1.1",
|
||||||
|
"undici": "^5.28.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@actions/http-client": {
|
||||||
|
"version": "2.2.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.2.3.tgz",
|
||||||
|
"integrity": "sha512-mx8hyJi/hjFvbPokCg4uRd4ZX78t+YyRPtnKWwIl+RzNaVuFpQHfmlGVfsKEJN8LwTCvL+DfVgAM04XaHkm6bA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"tunnel": "^0.0.6",
|
||||||
|
"undici": "^5.25.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@actions/io": {
|
||||||
|
"version": "1.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@actions/io/-/io-1.1.3.tgz",
|
||||||
|
"integrity": "sha512-wi9JjgKLYS7U/z8PPbco+PvTb/nRWjeoFlJ1Qer83k/3C5PHQi28hiVdeE2kHXmIL99mQFawx8qt/JPjZilJ8Q==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/@adobe/css-tools": {
|
"node_modules/@adobe/css-tools": {
|
||||||
"version": "4.4.4",
|
"version": "4.4.4",
|
||||||
"resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.4.tgz",
|
"resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.4.tgz",
|
||||||
@@ -1028,6 +1081,15 @@
|
|||||||
"fast-uri": "^3.0.0"
|
"fast-uri": "^3.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@fastify/busboy": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz",
|
||||||
|
"integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@fastify/error": {
|
"node_modules/@fastify/error": {
|
||||||
"version": "4.2.0",
|
"version": "4.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/@fastify/error/-/error-4.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/@fastify/error/-/error-4.2.0.tgz",
|
||||||
@@ -1287,6 +1349,164 @@
|
|||||||
"url": "https://paulmillr.com/funding/"
|
"url": "https://paulmillr.com/funding/"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@octokit/auth-token": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/core": {
|
||||||
|
"version": "5.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.2.2.tgz",
|
||||||
|
"integrity": "sha512-/g2d4sW9nUDJOMz3mabVQvOGhVa4e/BN/Um7yca9Bb2XTzPPnfTWHWQg+IsEYO7M3Vx+EXvaM/I2pJWIMun1bg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/auth-token": "^4.0.0",
|
||||||
|
"@octokit/graphql": "^7.1.0",
|
||||||
|
"@octokit/request": "^8.4.1",
|
||||||
|
"@octokit/request-error": "^5.1.1",
|
||||||
|
"@octokit/types": "^13.0.0",
|
||||||
|
"before-after-hook": "^2.2.0",
|
||||||
|
"universal-user-agent": "^6.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/endpoint": {
|
||||||
|
"version": "9.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.6.tgz",
|
||||||
|
"integrity": "sha512-H1fNTMA57HbkFESSt3Y9+FBICv+0jFceJFPWDePYlR/iMGrwM5ph+Dd4XRQs+8X+PUFURLQgX9ChPfhJ/1uNQw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/types": "^13.1.0",
|
||||||
|
"universal-user-agent": "^6.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/graphql": {
|
||||||
|
"version": "7.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-7.1.1.tgz",
|
||||||
|
"integrity": "sha512-3mkDltSfcDUoa176nlGoA32RGjeWjl3K7F/BwHwRMJUW/IteSa4bnSV8p2ThNkcIcZU2umkZWxwETSSCJf2Q7g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/request": "^8.4.1",
|
||||||
|
"@octokit/types": "^13.0.0",
|
||||||
|
"universal-user-agent": "^6.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/openapi-types": {
|
||||||
|
"version": "24.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-24.2.0.tgz",
|
||||||
|
"integrity": "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/plugin-paginate-rest": {
|
||||||
|
"version": "9.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-9.2.2.tgz",
|
||||||
|
"integrity": "sha512-u3KYkGF7GcZnSD/3UP0S7K5XUFT2FkOQdcfXZGZQPGv3lm4F2Xbf71lvjldr8c1H3nNbF+33cLEkWYbokGWqiQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/types": "^12.6.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@octokit/core": "5"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/plugin-paginate-rest/node_modules/@octokit/openapi-types": {
|
||||||
|
"version": "20.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-20.0.0.tgz",
|
||||||
|
"integrity": "sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/plugin-paginate-rest/node_modules/@octokit/types": {
|
||||||
|
"version": "12.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.6.0.tgz",
|
||||||
|
"integrity": "sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/openapi-types": "^20.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/plugin-rest-endpoint-methods": {
|
||||||
|
"version": "10.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-10.4.1.tgz",
|
||||||
|
"integrity": "sha512-xV1b+ceKV9KytQe3zCVqjg+8GTGfDYwaT1ATU5isiUyVtlVAO3HNdzpS4sr4GBx4hxQ46s7ITtZrAsxG22+rVg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/types": "^12.6.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@octokit/core": "5"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/plugin-rest-endpoint-methods/node_modules/@octokit/openapi-types": {
|
||||||
|
"version": "20.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-20.0.0.tgz",
|
||||||
|
"integrity": "sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/plugin-rest-endpoint-methods/node_modules/@octokit/types": {
|
||||||
|
"version": "12.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.6.0.tgz",
|
||||||
|
"integrity": "sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/openapi-types": "^20.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/request": {
|
||||||
|
"version": "8.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.4.1.tgz",
|
||||||
|
"integrity": "sha512-qnB2+SY3hkCmBxZsR/MPCybNmbJe4KAlfWErXq+rBKkQJlbjdJeS85VI9r8UqeLYLvnAenU8Q1okM/0MBsAGXw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/endpoint": "^9.0.6",
|
||||||
|
"@octokit/request-error": "^5.1.1",
|
||||||
|
"@octokit/types": "^13.1.0",
|
||||||
|
"universal-user-agent": "^6.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/request-error": {
|
||||||
|
"version": "5.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.1.1.tgz",
|
||||||
|
"integrity": "sha512-v9iyEQJH6ZntoENr9/yXxjuezh4My67CBSu9r6Ve/05Iu5gNgnisNWOsoJHTP6k0Rr0+HQIpnH+kyammu90q/g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/types": "^13.1.0",
|
||||||
|
"deprecation": "^2.0.0",
|
||||||
|
"once": "^1.4.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/types": {
|
||||||
|
"version": "13.10.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.10.0.tgz",
|
||||||
|
"integrity": "sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/openapi-types": "^24.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@paralleldrive/cuid2": {
|
"node_modules/@paralleldrive/cuid2": {
|
||||||
"version": "2.3.1",
|
"version": "2.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/@paralleldrive/cuid2/-/cuid2-2.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/@paralleldrive/cuid2/-/cuid2-2.3.1.tgz",
|
||||||
@@ -2234,6 +2454,12 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/argparse": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
|
||||||
|
"license": "Python-2.0"
|
||||||
|
},
|
||||||
"node_modules/aria-query": {
|
"node_modules/aria-query": {
|
||||||
"version": "5.3.0",
|
"version": "5.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz",
|
||||||
@@ -2297,6 +2523,12 @@
|
|||||||
"baseline-browser-mapping": "dist/cli.js"
|
"baseline-browser-mapping": "dist/cli.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/before-after-hook": {
|
||||||
|
"version": "2.2.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz",
|
||||||
|
"integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==",
|
||||||
|
"license": "Apache-2.0"
|
||||||
|
},
|
||||||
"node_modules/bidi-js": {
|
"node_modules/bidi-js": {
|
||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/bidi-js/-/bidi-js-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/bidi-js/-/bidi-js-1.0.3.tgz",
|
||||||
@@ -2659,6 +2891,12 @@
|
|||||||
"node": ">= 0.8"
|
"node": ">= 0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/deprecation": {
|
||||||
|
"version": "2.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz",
|
||||||
|
"integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==",
|
||||||
|
"license": "ISC"
|
||||||
|
},
|
||||||
"node_modules/dequal": {
|
"node_modules/dequal": {
|
||||||
"version": "2.0.3",
|
"version": "2.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
|
||||||
@@ -3451,6 +3689,18 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/js-yaml": {
|
||||||
|
"version": "4.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz",
|
||||||
|
"integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"argparse": "^2.0.1"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"js-yaml": "bin/js-yaml.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/jsdom": {
|
"node_modules/jsdom": {
|
||||||
"version": "27.2.0",
|
"version": "27.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/jsdom/-/jsdom-27.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/jsdom/-/jsdom-27.2.0.tgz",
|
||||||
@@ -4824,6 +5074,13 @@
|
|||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"fsevents": "~2.3.3"
|
"fsevents": "~2.3.3"
|
||||||
|
"node_modules/tunnel": {
|
||||||
|
"version": "0.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
|
||||||
|
"integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.6.11 <=0.7.0 || >=0.7.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/type-is": {
|
"node_modules/type-is": {
|
||||||
@@ -4854,6 +5111,18 @@
|
|||||||
"node": ">=14.17"
|
"node": ">=14.17"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/undici": {
|
||||||
|
"version": "5.29.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/undici/-/undici-5.29.0.tgz",
|
||||||
|
"integrity": "sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@fastify/busboy": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/undici-types": {
|
"node_modules/undici-types": {
|
||||||
"version": "7.16.0",
|
"version": "7.16.0",
|
||||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz",
|
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz",
|
||||||
@@ -4861,6 +5130,12 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/universal-user-agent": {
|
||||||
|
"version": "6.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.1.tgz",
|
||||||
|
"integrity": "sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==",
|
||||||
|
"license": "ISC"
|
||||||
|
},
|
||||||
"node_modules/unpipe": {
|
"node_modules/unpipe": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
|
||||||
|
|||||||
@@ -14,10 +14,13 @@
|
|||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"type": "commonjs",
|
"type": "commonjs",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@actions/core": "^1.11.1",
|
||||||
|
"@actions/github": "^6.0.1",
|
||||||
"bullmq": "^5.64.1",
|
"bullmq": "^5.64.1",
|
||||||
"express": "^5.1.0",
|
"express": "^5.1.0",
|
||||||
"fastify": "^5.6.2",
|
"fastify": "^5.6.2",
|
||||||
"ioredis": "^5.8.2",
|
"ioredis": "^5.8.2",
|
||||||
|
"js-yaml": "^4.1.0",
|
||||||
"node-cron": "^4.2.1",
|
"node-cron": "^4.2.1",
|
||||||
"react": "^19.2.0",
|
"react": "^19.2.0",
|
||||||
"react-dom": "^19.2.0",
|
"react-dom": "^19.2.0",
|
||||||
|
|||||||
Reference in New Issue
Block a user