Skip to content

[add] GitHub actions of GitHub-reward & Lark-GitHub-bot#25

Merged
TechQuery merged 1 commit into
mainfrom
GitHub-reward
Apr 2, 2026
Merged

[add] GitHub actions of GitHub-reward & Lark-GitHub-bot#25
TechQuery merged 1 commit into
mainfrom
GitHub-reward

Conversation

@TechQuery

@TechQuery TechQuery commented Apr 2, 2026

Copy link
Copy Markdown
Member

PR-25 PR-25 PR-25 Powered by Pull Request Badge

Copilot AI review requested due to automatic review settings April 2, 2026 18:56
@TechQuery TechQuery added the feature New feature or request label Apr 2, 2026
@github-project-automation github-project-automation Bot moved this to In progress in 开源项目 Apr 2, 2026

Copilot AI left a comment

Copy link
Copy Markdown

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 introduces new GitHub Actions workflows and Deno-based automation scripts to (1) distribute “reward” amounts when reward-labeled issues are closed, (2) generate monthly reward statistics, and (3) send GitHub event notifications to Lark/Feishu.

Changes:

  • Add reward-claim and monthly reward-statistics workflows backed by new Deno scripts that tag releases / push tags.
  • Add a Lark notification workflow and an event-to-card serialization script.
  • Add a reward issue template and update recommended VS Code extensions.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
.vscode/extensions.json Updates editor extension recommendations (adds Copilot Chat).
.github/workflows/statistic-member-reward.yml Monthly scheduled workflow to compute reward summaries and publish a release/tag.
.github/workflows/Lark-notification.yml Multi-event workflow to serialize GitHub event payloads and send to Lark.
.github/workflows/claim-issue-reward.yml Workflow to calculate/split rewards on issue close and persist results via tags/comments.
.github/scripts/type.ts Defines the Reward data shape used by reward scripts.
.github/scripts/transform-message.ts Converts GitHub event payloads into a Lark interactive card JSON.
.github/scripts/share-reward.ts Computes reward distribution from linked merged PR participants and persists it.
.github/scripts/deno.json Adds Deno config (currently not auto-applied from repo root).
.github/scripts/count-reward.ts Aggregates reward tags into a monthly summary and publishes tag/release.
.github/ISSUE_TEMPLATE/reward-task.yml Adds an issue template for creating reward-labeled tasks.

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


let rawYAML = '';

for (const tag of rewardTags) rawYAML += (await $`git tag -l --format="%(contents)" ${tag}`) + '\n';

Copilot AI Apr 2, 2026

Copy link

Choose a reason for hiding this comment

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

In the loop building rawYAML, you’re concatenating the $ command result object directly into a string. In zx this will not reliably produce the command stdout (often becomes "[object Object]"), which will break YAML.parse. Use the command output explicitly (e.g., .stdout or .text()) when appending tag contents.

Suggested change
for (const tag of rewardTags) rawYAML += (await $`git tag -l --format="%(contents)" ${tag}`) + '\n';
for (const tag of rewardTags) {
const tagContents = await $`git tag -l --format="%(contents)" ${tag}`;
rawYAML += tagContents.stdout + '\n';
}

Copilot uses AI. Check for mistakes.
Comment on lines +39 to +50
const PR_DATA = await $`gh api graphql \
-f query=${graphqlQuery} \
-f owner=${repositoryOwner} \
-f name=${repositoryName} \
-F number=${issueNumber} \
--jq '.data.repository.issue.closedByPullRequestsReferences.nodes[] | select(.merged == true) | {url: .url, mergeCommitSha: .mergeCommit.oid}' | head -n 1`;

const prData = PR_DATA.text().trim();

if (!prData) throw new ReferenceError('No merged PR is found for the given issue number.');

const { url: PR_URL, mergeCommitSha } = JSON.parse(prData);

Copilot AI Apr 2, 2026

Copy link

Choose a reason for hiding this comment

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

gh api ... --jq '...{...}' | head -n 1 is brittle because --jq output for objects is typically multi-line JSON; head -n 1 can truncate it (e.g., just "{") and make JSON.parse(prData) fail. Prefer making the jq output single-line (compact) or extracting a single JSON-encoded line before piping to head, so the parsed string is always valid JSON.

Copilot uses AI. Check for mistakes.
Comment on lines +70 to +72
// Filter out Bot users from the list
const allUsers = [author.login, ...assignees.map(({ login }) => login)];
const users = allUsers.filter(login => !isBotUser(login));

Copilot AI Apr 2, 2026

Copy link

Choose a reason for hiding this comment

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

allUsers can contain duplicates (e.g., author is also an assignee), and the current filter doesn’t dedupe. That will incorrectly increase users.length, reduce per-person reward, and may create multiple entries for the same payee. Consider normalizing to unique logins (e.g., via a Set) before calculating the split.

Suggested change
// Filter out Bot users from the list
const allUsers = [author.login, ...assignees.map(({ login }) => login)];
const users = allUsers.filter(login => !isBotUser(login));
// Filter out Bot users from the list and deduplicate logins
const allUsers = [author.login, ...assignees.map(({ login }) => login)];
const users = [...new Set(allUsers.filter(login => !isBotUser(login)))];

Copilot uses AI. Check for mistakes.
Comment on lines +17 to +30
- name: Check for new commits since last statistic
run: |
last_tag=$(git describe --tags --abbrev=0 --match "statistic-*" || echo "")

if [ -z "$last_tag" ]; then
echo "No previous statistic tags found."
echo "NEW_COMMITS=true" >> $GITHUB_ENV
else
new_commits=$(git log $last_tag..HEAD --oneline)
if [ -z "$new_commits" ]; then
echo "No new commits since last statistic tag."
echo "NEW_COMMITS=false" >> $GITHUB_ENV
else
echo "New commits found."

Copilot AI Apr 2, 2026

Copy link

Choose a reason for hiding this comment

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

The workflow decides whether to run stats based on “new commits since last statistic tag”, but reward tags can be created without any new commits (the claim workflow only pushes tags). In that case this workflow will skip even though there is new reward data. Consider checking for new reward-* tags (or tag dates) instead of commit history, or always run the stats script and let it exit gracefully when there’s no data.

Suggested change
- name: Check for new commits since last statistic
run: |
last_tag=$(git describe --tags --abbrev=0 --match "statistic-*" || echo "")
if [ -z "$last_tag" ]; then
echo "No previous statistic tags found."
echo "NEW_COMMITS=true" >> $GITHUB_ENV
else
new_commits=$(git log $last_tag..HEAD --oneline)
if [ -z "$new_commits" ]; then
echo "No new commits since last statistic tag."
echo "NEW_COMMITS=false" >> $GITHUB_ENV
else
echo "New commits found."
- name: Check for new reward tags since last statistic
run: |
last_tag=$(git for-each-ref --sort=-creatordate --format='%(refname:short)' "refs/tags/statistic-*" | head -n 1)
if [ -z "$last_tag" ]; then
echo "No previous statistic tags found."
echo "NEW_COMMITS=true" >> $GITHUB_ENV
else
last_tag_ts=$(git for-each-ref --format='%(creatordate:unix)' "refs/tags/$last_tag")
latest_reward_tag_ts=$(git for-each-ref --sort=-creatordate --format='%(creatordate:unix)' "refs/tags/reward-*" | head -n 1)
if [ -z "$latest_reward_tag_ts" ]; then
echo "No reward tags found."
echo "NEW_COMMITS=false" >> $GITHUB_ENV
elif [ "$latest_reward_tag_ts" -le "$last_tag_ts" ]; then
echo "No new reward tags since last statistic tag."
echo "NEW_COMMITS=false" >> $GITHUB_ENV
else
echo "New reward tags found."

Copilot uses AI. Check for mistakes.
Comment on lines +4 to +45
on:
push:
issues:
pull_request:
discussion:
issue_comment:
discussion_comment:
pull_request_review_comment:
release:
types:
- published

jobs:
send-Lark-message:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6

- uses: denoland/setup-deno@v2
with:
deno-version: v2.x

- name: Event Message serialization
id: message
run: |
YAML=$(
cat <<JSON | deno run -A .github/scripts/transform-message.ts
${{ toJSON(github) }}
JSON
)
{
echo 'content<<EOF'
echo "$YAML"
echo 'EOF'
} >> "$GITHUB_OUTPUT"

- name: Send message to Lark
if: ${{ contains(steps.message.outputs.content, ':') }}
uses: Open-Source-Bazaar/feishu-action@v3
with:
url: ${{ secrets.LARK_CHATBOT_HOOK_URL }}
msg_type: interactive

Copilot AI Apr 2, 2026

Copy link

Choose a reason for hiding this comment

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

This workflow runs on pull_request events but the “Send message to Lark” step depends on secrets.LARK_CHATBOT_HOOK_URL, which is not available for PRs from forks; the action may fail or behave unexpectedly. Add a guard to skip the job/step when secrets aren’t available (e.g., only run for non-fork PRs) or adjust the trigger strategy (with appropriate security precautions).

Copilot uses AI. Check for mistakes.
Comment on lines +90 to +106
push: ({ event: { head_commit }, ref, ref_name, server_url, repository, actor }) => {
const commitUrl = head_commit?.url || `${server_url}/${repository}/tree/${ref_name}`;
const commitMessage =
head_commit?.message || 'Create/Delete/Update Branch (No head commit)';

return {
title: 'GitHub 代码提交',
elements: [
{
tag: 'markdown',
content: [
createContentItem('提交链接:', createLink(commitUrl)),
createContentItem(
'代码分支:',
createLink(`${server_url}/${repository}/tree/${ref_name}`, ref_name)
),
createContentItem(

Copilot AI Apr 2, 2026

Copy link

Choose a reason for hiding this comment

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

For push events, head_commit.url in the webhook payload is an API URL (not a browser-friendly HTML URL), so the generated “提交链接” may point to the REST endpoint. Consider building the commit page link from server_url, repository, and the commit SHA instead (or otherwise ensure the URL is a web URL).

Copilot uses AI. Check for mistakes.
Comment thread .github/scripts/deno.json
Comment on lines +1 to +3
{
"nodeModulesDir": "none"
}

Copilot AI Apr 2, 2026

Copy link

Choose a reason for hiding this comment

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

This deno.json lives under .github/scripts/, but the workflows run deno ... .github/scripts/*.ts from the repo root. Deno only auto-loads config from the current directory (and ancestors), so this config likely won’t be applied unless you pass --config .github/scripts/deno.json or move the config to the repository root.

Copilot uses AI. Check for mistakes.
id: message
run: |
YAML=$(
cat <<JSON | deno run -A .github/scripts/transform-message.ts

Copilot AI Apr 2, 2026

Copy link

Choose a reason for hiding this comment

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

The serialization step runs deno run -A, which grants full permissions (run, env, net, read/write) even though this script appears to only transform stdin to stdout. Tightening permissions here (remove -A and only grant what’s required) reduces blast radius if the script or its dependencies ever become compromised.

Suggested change
cat <<JSON | deno run -A .github/scripts/transform-message.ts
cat <<JSON | deno run .github/scripts/transform-message.ts

Copilot uses AI. Check for mistakes.
@TechQuery TechQuery merged commit dac7b89 into main Apr 2, 2026
6 checks passed
@TechQuery TechQuery deleted the GitHub-reward branch April 2, 2026 19:09
@github-project-automation github-project-automation Bot moved this from In progress to Done in 开源项目 Apr 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature New feature or request

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants