Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add new worklow to track the voting process #1278

Merged
merged 60 commits into from
Jul 23, 2024
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
422213e
Add new worklow to track the voting process
AayushSaini101 Jun 17, 2024
ab5f4f0
Merge branch 'master' into Issue-1268
AayushSaini101 Jun 17, 2024
dc9e22d
Merge branch 'master' into Issue-1268
AayushSaini101 Jun 19, 2024
63a26df
Updated structure of the worklow
AayushSaini101 Jun 19, 2024
f6853b8
Add extra field to track not participated count
AayushSaini101 Jun 20, 2024
0788db0
Update the names of variables
AayushSaini101 Jun 20, 2024
430f472
Update variables
AayushSaini101 Jun 20, 2024
5cb67c6
Update the vote tracking workflow
AayushSaini101 Jun 20, 2024
9f4c86e
Remove extra variables
AayushSaini101 Jun 20, 2024
82e2d61
Update the tracker concept
AayushSaini101 Jun 20, 2024
cea8957
Update
AayushSaini101 Jun 20, 2024
27917da
update names
AayushSaini101 Jun 20, 2024
171f667
update issue name
AayushSaini101 Jun 20, 2024
1051429
Introduce Markdown to track voting details
AayushSaini101 Jun 21, 2024
597f206
Merge branch 'master' into Issue-1268
AayushSaini101 Jun 21, 2024
07bebfa
Merge branch 'master' into Issue-1268
AayushSaini101 Jun 24, 2024
711d9f6
Add doc about the new workflow and optimise tracker
AayushSaini101 Jun 24, 2024
bfd0988
Use proper variable naming
AayushSaini101 Jun 24, 2024
711b464
Merge branch 'master' into Issue-1268
AayushSaini101 Jun 24, 2024
08c37ab
Update voting.md
AayushSaini101 Jun 24, 2024
7a41ad2
Update .github/scripts/vote_tracker.js
AayushSaini101 Jun 24, 2024
8c12491
Update voting.md
AayushSaini101 Jun 24, 2024
34fcb9b
Update required changes
AayushSaini101 Jun 25, 2024
7f4e172
Merge branch 'master' into Issue-1268
AayushSaini101 Jun 25, 2024
8cb254b
Update to check tsc member
AayushSaini101 Jun 25, 2024
bf6e6e4
Update voting file yml
AayushSaini101 Jun 25, 2024
796386b
remove logging
AayushSaini101 Jun 25, 2024
be7732a
Fix undefined issue
AayushSaini101 Jun 25, 2024
17443f5
Fix the format
AayushSaini101 Jun 25, 2024
901932e
Merge branch 'master' into Issue-1268
AayushSaini101 Jul 1, 2024
7e461c5
Update voting.md
AayushSaini101 Jul 3, 2024
dd19fca
Update voting.md
AayushSaini101 Jul 3, 2024
936f6b0
Update .github/workflows/vote-tracker.yml
AayushSaini101 Jul 3, 2024
541b512
Update the workflow
AayushSaini101 Jul 3, 2024
998863c
Remove extra space
AayushSaini101 Jul 3, 2024
8b7fb66
Update requirments
AayushSaini101 Jul 8, 2024
cde79e9
Merge branch 'master' into Issue-1268
AayushSaini101 Jul 9, 2024
2ce1a67
Update vote_tracker.js
AayushSaini101 Jul 11, 2024
3173ed1
Update vote_tracker.js
AayushSaini101 Jul 17, 2024
daf62e4
Update voteTrackingFile.json
AayushSaini101 Jul 17, 2024
1a0b934
Update .github/scripts/vote_tracker.js
AayushSaini101 Jul 17, 2024
7dcec19
Update vote_tracker.js
AayushSaini101 Jul 17, 2024
f9ddf5a
Merge branch 'master' into Issue-1268
AayushSaini101 Jul 17, 2024
9b822e3
Update voteTrackingFile.json
AayushSaini101 Jul 22, 2024
928ad7e
Update voting.md
AayushSaini101 Jul 22, 2024
944c20e
Merge branch 'master' into Issue-1268
AayushSaini101 Jul 22, 2024
f09efa9
Add markdown file and update the md file generator flow
AayushSaini101 Jul 22, 2024
a2e9222
Update voting.md
AayushSaini101 Jul 22, 2024
348c3a8
Merge branch 'master' into Issue-1268
AayushSaini101 Jul 22, 2024
b03a2be
Fix invalid data
AayushSaini101 Jul 22, 2024
320b543
Fix md file
AayushSaini101 Jul 22, 2024
ddb9272
Update TSC_VOTING_OVERVIEW.md
AayushSaini101 Jul 23, 2024
6c20357
Update voteTrackingFile.json
AayushSaini101 Jul 23, 2024
e96e819
Update TSC_VOTING_OVERVIEW.md
AayushSaini101 Jul 23, 2024
e520dda
Update voteTrackingFile.json
AayushSaini101 Jul 23, 2024
173327a
Update TSC_VOTING_OVERVIEW.md
AayushSaini101 Jul 23, 2024
21f7e76
Update voteTrackingFile.json
AayushSaini101 Jul 23, 2024
8d9dcf1
Merge branch 'master' into Issue-1268
AayushSaini101 Jul 23, 2024
0fc7c38
Add lowerCase matching
AayushSaini101 Jul 23, 2024
cc4e3f8
add lowercase
AayushSaini101 Jul 23, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 120 additions & 0 deletions .github/scripts/vote_tracker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
const yaml = require('js-yaml');
const fs = require('fs');
Copy link
Member

Choose a reason for hiding this comment

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

if the funcion is async, and you call it with await then lets properly use some async/await code, and not old school sync fs functions.

example:

Suggested change
const fs = require('fs');
const { readFile } = require('fs').promises;
await readFile()

every single use of await, should be wrapped in proper try/catch and when you catch an error, enrich it with proper additional comment, where error happened.

for example once you refactor fs.readFileSync('MAINTAINERS.yaml', 'utf8') then please properly describe the error as something like Unable to read MAINTAINERS.yaml file.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done , also added try catch blow during reading and writing into files

const path = require('path');
const message = process.env.COMMENT_BODY;
const eventNumber = process.env.EVENT_NUMBER;
const eventTitle = process.env.EVENT_TITLE
const orgName = process.env.ORG_NAME
const repoName = process.env.REPO_NAME
const filePath = path.join('VoteTracking.json');

const bindingVotesSectionMatch = message.match(/Binding votes \(\d+\)[\s\S]*?(?=(<details>|$))/);
const bindingVotesSection = bindingVotesSectionMatch ? bindingVotesSectionMatch[0] : '';
const rows = bindingVotesSection.match(/\| @\w+.*?\|.*?\|.*?\|/g) || [];
const latestVotes = rows.map(row => {
const [ , user, vote, timestamp] = row.split('|').map(col => col.trim());
return { user: user.replace('@', ''), vote, timestamp, isVotedInLast3Months: true };
});

// Initialize vote tracking file if it doesn't exist
if (!fs.existsSync(filePath)) {
const yamlData = fs.readFileSync('MAINTAINERS.yaml', 'utf8');
const parsedData = yaml.load(yamlData);
const tscMembers = parsedData.filter(entry => entry.isTscMember).map(entry => ({
name: entry.github,
lastParticipatedVoteTime: '',
hasVotedInLast3Months: 'false',
lastVoteClosedTime: new Date().toISOString().split('T')[0],
agreeCount: 0,
disagreeCount: 0,
abstainCount: 0,
notParticipatingCount: 0
}));
fs.writeFileSync(filePath, JSON.stringify(tscMembers, null, 2));
}

const voteDetails = JSON.parse(fs.readFileSync(filePath, 'utf8'));
const latestVotesInfo = []
voteDetails.map(voteInfo => {
const currentTime = new Date().toISOString().split('T')[0];
const userInfo = latestVotes.find(vote => vote.user === voteInfo.name);
const choice = userInfo ? userInfo.vote : "Not participated";

if (userInfo) {
voteInfo.hasVotedInLast3Months = true;
voteInfo.lastParticipatedVoteTime = currentTime;
voteInfo[choice === "In favor" ? 'agreeCount' : choice === "Against" ? 'disagreeCount' : 'abstainCount']++;
} else {
voteInfo.notParticipatingCount++;
voteInfo.lastVoteClosedTime = currentTime;
if (!checkVotingDurationMoreThanThreeMonths(voteInfo)) {
voteInfo.hasVotedInLast3Months = false;
}
}

let updatedVoteInfo = {};
Object.keys(voteInfo).forEach(key => {
if (key == 'name') {
updatedVoteInfo['name'] = voteInfo.name
updatedVoteInfo[eventTitle+"$$"+eventNumber] = choice
}
else {
updatedVoteInfo[key] = voteInfo[key];
}
})
latestVotesInfo.push(updatedVoteInfo)
});

fs.writeFileSync(filePath, JSON.stringify(latestVotesInfo, null, 2));

// Check voting duration
function checkVotingDurationMoreThanThreeMonths(voteInfo) {
const currentDate = new Date();
const threeMonthsAgoDate = new Date(currentDate);
threeMonthsAgoDate.setMonth(currentDate.getMonth() - 3);
return new Date(voteInfo.lastVoteClosedTime) >= threeMonthsAgoDate &&
new Date(voteInfo.lastParticipatedVoteTime) <= threeMonthsAgoDate;
}

// Convert JSON data to markdown table
function jsonToMarkdownTable(data) {
const keys = Object.keys(data[0]);
let markdownTable = '| ' + keys.map(key => {
if (key.includes('$$')) {
const [title, number] = key.split('$$');
return `[${title}](https://github.com/${orgName}/${repoName}/issues/${number})`;
}
const titles = {
name: "Github user name",
lastParticipatedVoteTime: "Last participated vote time of the user",
hasVotedInLast3Months: "Voted in last 3 months or not",
lastVoteClosedTime: "Last vote closed time",
agreeCount: "Number of agreements votes",
disagreeCount: "Number of disagreements votes",
abstainCount: "Number of abstentions votes",
notParticipatingCount: "Number of non-participations votes"
AayushSaini101 marked this conversation as resolved.
Show resolved Hide resolved
};
return `<span style="position: relative; cursor: pointer;" title="${titles[key] || key}">${key}</span>`;
}).join(' | ') + ' |\n';

markdownTable += '| ' + keys.map(() => '---').join(' | ') + ' |\n';
markdownTable += data.map(obj => '| ' + keys.map(key => {
if (key === 'name') return `[${obj[key]}](https://github.com/${obj[key]})`;
if (key.includes('$$')) {
const icons = {
derberg marked this conversation as resolved.
Show resolved Hide resolved
"In favor": "👍",
"Against": "👎",
"Abstain": "👀",
"Not participated": "🔕"
};
return `<span style="position: relative; cursor: pointer;" title="${obj[key]}">${icons[obj[key]] || obj[key]}</span>`;
}
return obj[key];
}).join(' | ') + ' |').join('\n');

return markdownTable;
}

const markdownTable = jsonToMarkdownTable(latestVotesInfo);
fs.writeFileSync('voteTrackingDetails.md', markdownTable);
console.log('Markdown table has been written to voteTrackingDetails.md');
52 changes: 52 additions & 0 deletions .github/workflows/vote-tracker.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: Vote Tracker

on:
issue_comment:
types: [created]
derberg marked this conversation as resolved.
Show resolved Hide resolved

jobs:
track-vote:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up Node.js
derberg marked this conversation as resolved.
Show resolved Hide resolved
uses: actions/setup-node@v2
with:
node-version: '14'

- name: Install the dependencies
run: npm install [email protected]
shell: bash

- name: Configure Git
run: |
git config --global user.name "github-actions[bot]"
git config --global user.email "github-actions[bot]@users.noreply.github.com"

- name: Run vote tracker script
id: vote_tracker
if: |
github.event.comment.user.login == 'git-vote[bot]' &&
Copy link
Member

Choose a reason for hiding this comment

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

shouldn't we have this login validation on a job level, to basically not run entire job if this was not met? case with comment body

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done @derberg

contains(github.event.comment.body, 'Vote closed')
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
COMMENT_BODY: ${{ github.event.comment.body }}
EVENT_NUMBER: ${{ github.event.issue.number }}
EVENT_TITLE: ${{ github.event.issue.title }}
ORG_NAME: ${{ github.repository_owner }}
REPO_NAME: ${{ github.event.repository.name }}
run: |
node .github/scripts/vote_tracker.js
echo "::set-output name=ran_successfully::true"

- name: Commit VotingTracking.json
derberg marked this conversation as resolved.
Show resolved Hide resolved
if: steps.vote_tracker.outputs.ran_successfully == 'true'
run: |
git add voteTrackingDetails.md
git add VoteTracking.json
git commit -m "Update voteTrackingDetails.md"
git push
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
11 changes: 11 additions & 0 deletions voting.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,17 @@ Voting cannot be concluded with a comment; it ends when more than half of the us

The Git Vote bot adds a comment that voting is completed.

### Tracking Voting

The [voteTrackingDetail](https://github.com/asyncapi/community/blob/master/voteTrackingDetail.md) file contains the complete voting history of all TSC Members, whether they voted or not in the community's voting processes.
AayushSaini101 marked this conversation as resolved.
Show resolved Hide resolved

* 🔕 indicates that the member did not vote in the last voting.
* 👍 indicates that the member was in favor in the last voting.
* 👎 indicates that the member was against in the last voting.
* 👀 indicates that the member abstained in the last voting.
AayushSaini101 marked this conversation as resolved.
Show resolved Hide resolved

The voteTrackingDetails file also tracks whether the member has voted in the last 3 months, helping to identify inactive TSC Members.
AayushSaini101 marked this conversation as resolved.
Show resolved Hide resolved

### Note

* As per the [Charter](./CHARTER.md), a quorum is not needed. However, Git Vote has technical limitations, and a quorum should be reached. That's why we allocate 4 weeks for voting, and it's important to actively encourage participation to ensure that the quorum (where votes cast exceed 50% of eligible voters) is met.
Expand Down
Loading