Skip to content

Commit 8bc54bf

Browse files
authored
Merge branch 'main' into patch-1
2 parents 40cb491 + 3840b0b commit 8bc54bf

File tree

8 files changed

+467
-83
lines changed

8 files changed

+467
-83
lines changed

.github/ISSUE_TEMPLATE/open_community_working_meeting.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ about: Regular Open Community Working Meetings Issue - This template is for thos
55

66
# Open Community Working Meeting 2022-MM-DD - 14:00 PT
77

8-
Zoom Meeting link: https://postman.zoom.us/j/89562933116?pwd=OWlsQ0RrcDY4S1JQU2d2Q2M0aFFlZz09
8+
Google Meet joining info - Video call link: https://meet.google.com/rag-mhbi-cgt
99

1010
You can find these events scheduled on our **[JSON Schema Community Calendar](https://calendar.google.com/calendar/u/0/embed?src=info@json-schema.org)**.
1111

.github/workflows/failed-actions-notify.yml

Lines changed: 22 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -8,36 +8,30 @@ on:
88
branches:
99
- main
1010

11+
permissions:
12+
actions: read
13+
1114
jobs:
12-
notify-slack:
15+
on-failure:
1316
runs-on: ubuntu-latest
14-
if: ${{ github.event.workflow_run.conclusion == 'failure' }}
17+
if: |
18+
(github.event.workflow_run.conclusion == 'failure' ||
19+
github.event.workflow_run.conclusion == 'timed_out') &&
20+
github.event.workflow_run.name != 'Slack Notifications for Failed GitHub Actions'
21+
timeout-minutes: 10
1522
steps:
16-
- name: Check out repository
17-
uses: actions/checkout@v4
18-
19-
- name: Send Slack notification
23+
- name: Send Slack Notification
24+
uses: ravsamhq/notify-slack-action@v2
25+
with:
26+
status: ${{ github.event.workflow_run.conclusion }}
27+
notification_title: " ${{github.event.workflow_run.name}} - ${{github.event.workflow_run.conclusion}} on ${{github.event.workflow_run.head_branch}} - <${{github.server_url}}/${{github.repository}}/actions/runs/${{github.event.workflow_run.id}}|View Failure>"
28+
message_format: ":fire: *${{github.event.workflow_run.name}}* ${{github.event.workflow_run.conclusion}} in <${{github.server_url}}/${{github.repository}}/${{github.event.workflow_run.head_branch}}|${{github.repository}}>"
29+
footer: "Linked Repo <${{github.server_url}}/${{github.repository}}|${{github.repository}}> | <${{github.server_url}}/${{github.repository}}/actions/runs/${{github.event.workflow_run.id}}|View Failure>"
30+
env:
31+
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_WORKFLOW_NOTIF }}
32+
33+
- name: Check Slack Notification Status
2034
if: failure()
2135
run: |
22-
const fetch = require('node-fetch');
23-
24-
const SLACK_WEBHOOK_URL = process.env.SLACK_WEBHOOK_URL;
25-
const context = JSON.parse(process.env.GITHUB_CONTEXT);
26-
27-
const slackMessage = {
28-
channel: '#github',
29-
issue: `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`,
30-
status: context.jobStatus,
31-
text: `GitHub Actions workflow failed: ${context.workflow}`
32-
};
33-
34-
await fetch(SLACK_WEBHOOK_URL, {
35-
method: 'POST',
36-
headers: {
37-
'Content-Type': 'application/json',
38-
},
39-
body: JSON.stringify(slackMessage),
40-
});
41-
env:
42-
SLACK_WEBHOOK_URL: ${{ vars.SLACK_WEBHOOK_FAIL_ACTIONS }}
43-
GITHUB_CONTEXT: ${{ toJson(github) }}
36+
echo "Failed to send Slack notification"
37+
echo "Workflow Run ID: ${{ github.event.workflow_run.id }}"
Lines changed: 128 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,29 @@
1-
name: Send reminders to join the OCWM
1+
name: Send Office Hours Reminders
22

33
on:
44
schedule:
5-
- cron: '0 15 1-7 * 5' #Runs at 15:00, between day 1 and 7 of the month on Friday
6-
- cron: '0 15 1-7 * 2' #Runs at 15:00, between day 1 and 7 of the month on Tuesday
5+
# Europe/Americas: Last Friday of previous month, first Friday (if before Tuesday), and day of (first Tuesday), even months
6+
- cron: '0 9 25-31 5,7,9,11,1,3 5' # Last Friday of odd months at 9 UTC
7+
- cron: '0 9 1-7 6,8,10,12,2,4 5' # First Friday at 9 UTC in even months
8+
- cron: '0 9 1-7 6,8,10,12,2,4 2' # First Tuesday at 9 UTC in even months
9+
# APAC/Americas: Last Friday of previous month, first Friday (if before Tuesday), and day of (first Tuesday), odd months
10+
- cron: '0 17 25-31 4,6,8,10,12,2 5' # Last Friday of even months at 17 UTC
11+
- cron: '0 17 1-7 7,9,11,1,3,5 5' # First Friday at 17 UTC in odd months
12+
- cron: '0 17 1-7 7,9,11,1,3,5 2' # First Tuesday at 17 UTC in odd months
713

814
jobs:
9-
ocwm-reminders:
15+
send-reminders:
1016
runs-on: ubuntu-latest
1117
steps:
1218
- name: Checkout Repository
1319
uses: actions/checkout@v4
14-
- name: Set up Node 20
20+
21+
- name: Set up Node.js
1522
uses: actions/setup-node@v4
1623
with:
1724
node-version: '20'
1825

19-
- name: Get Token
26+
- name: Get GitHub App Token
2027
uses: actions/create-github-app-token@v1
2128
id: get_workflow_token
2229
with:
@@ -29,57 +36,126 @@ jobs:
2936
- name: Send reminders
3037
uses: actions/github-script@v7
3138
env:
32-
MY_TOKEN: ${{ steps.get_workflow_token.outputs.token }}
39+
GITHUB_TOKEN: ${{ steps.get_workflow_token.outputs.token }}
3340
OWNER: ${{ vars.ORGANISATION }}
3441
REPO: 'community'
3542
OCWM_LABEL: ${{ vars.OCWM_LABEL }}
36-
SLACK_WEBHOOK: ${{ vars.SLACK_WEBHOOK_REMINDER }}
43+
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_OFFICEHOURS }}
3744
with:
3845
script: |
39-
40-
const octokit = require('@octokit/core').Octokit;
41-
const mygithub = new octokit({
42-
request: { fetch: fetch,},
43-
auth: process.env.MY_TOKEN
44-
});
45-
46-
let targetLabel = encodeURIComponent(process.env.OCWM_LABEL);
47-
48-
const { data: workMeetings } = await mygithub.request(`GET /repos/${process.env.OWNER}/${process.env.REPO}/issues?labels=${targetLabel}&per_page=1`, {
49-
})
50-
51-
const issueNumber = workMeetings[0].number
52-
const newTitle = workMeetings[0].title;
53-
const issueDate = newTitle.replace(/Open Community Working Meeting /g, "");
54-
55-
//Date of the next meeting
56-
const nextMeetingDate = new Date();
57-
nextMeetingDate.setDate(nextMeetingDate.getDate() + (2 + 7 - nextMeetingDate.getDay()) % 7);
58-
59-
const formattedDate = nextMeetingDate.toISOString().split('T')[0];
60-
61-
const reminderText = (new Date().getDay() === 2) ? "today" : formattedDate;
62-
63-
// Checking if the reminder should be sent
64-
const today = new Date();
65-
const firstTuesday = new Date(today.getFullYear(), today.getMonth(), 1);
66-
firstTuesday.setDate(firstTuesday.getDate() + (2 + 7 - firstTuesday.getDay()) % 7);
67-
const firstFriday = new Date(today.getFullYear(), today.getMonth(), 1);
68-
firstFriday.setDate(firstFriday.getDate() + (5 + 7 - firstFriday.getDay()) % 7);
69-
70-
if ((today.getDay() === 2 && today.getDate() === firstTuesday.getDate()) || (today.getDay() === 5 && today.getDate() === firstFriday.getDate() && firstFriday < firstTuesday)) {
71-
// Notify Slack
72-
const SLACK_WEBHOOK_URL = process.env.SLACK_WEBHOOK;
73-
const SLACK_MESSAGE = `{
74-
"issue": "https://github.com/${process.env.OWNER}/${process.env.REPO}/issues/${issueNumber}",
75-
"date": "${reminderText}"
76-
}`;
77-
78-
await fetch(SLACK_WEBHOOK_URL, {
46+
const { Octokit } = require("@octokit/core");
47+
const github = new Octokit({ auth: process.env.GITHUB_TOKEN });
48+
49+
function getFirstTuesdayOfMonth(year, month) {
50+
let date = new Date(Date.UTC(year, month, 1));
51+
while (date.getUTCDay() !== 2) {
52+
date.setUTCDate(date.getUTCDate() + 1);
53+
}
54+
return date;
55+
}
56+
57+
function getLastTuesdayOfMonth(year, month) {
58+
let date = new Date(Date.UTC(year, month + 1, 0)); // Last day of the month
59+
while (date.getUTCDay() !== 2) {
60+
date.setUTCDate(date.getUTCDate() - 1);
61+
}
62+
return date;
63+
}
64+
65+
function isLastFridayOfMonth(date) {
66+
const lastDayOfMonth = new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth() + 1, 0));
67+
const lastFriday = new Date(lastDayOfMonth);
68+
lastFriday.setUTCDate(lastFriday.getUTCDate() - (lastFriday.getUTCDay() + 2) % 7);
69+
return date.getUTCDate() === lastFriday.getUTCDate();
70+
}
71+
72+
function isFirstFridayOfMonth(date) {
73+
return date.getUTCDay() === 5 && date.getUTCDate() <= 7;
74+
}
75+
76+
try {
77+
const today = new Date();
78+
const currentMonth = today.getUTCMonth();
79+
const isEuropeAmericas = [5, 7, 9, 11, 1, 3].includes(currentMonth+1);
80+
const isFriday = today.getUTCDay() === 5;
81+
const isTuesday = today.getUTCDay() === 2;
82+
const isLastFriday = isLastFridayOfMonth(today);
83+
const isFirstFriday = isFirstFridayOfMonth(today);
84+
85+
console.log(`Current date: ${today.toISOString()}, Month: ${currentMonth + 1}, Is Europe/Americas: ${isEuropeAmericas}, Is Friday: ${isFriday}, Is Tuesday: ${isTuesday}, Is Last Friday: ${isLastFriday}, Is First Friday: ${isFirstFriday}`);
86+
87+
let timezone, time, date;
88+
if (isEuropeAmericas) {
89+
timezone = "Europe/Americas friendly";
90+
time = "10:00 BST";
91+
} else {
92+
timezone = "APAC/Americas friendly";
93+
time = "10:00 PT";
94+
}
95+
96+
const firstTuesdayThisMonth = getFirstTuesdayOfMonth(today.getUTCFullYear(), currentMonth);
97+
const lastTuesdayLastMonth = getLastTuesdayOfMonth(today.getUTCFullYear(), currentMonth);
98+
99+
let shouldSendReminder = false;
100+
101+
if (isFriday) {
102+
if(isLastFriday && today > lastTuesdayLastMonth){
103+
shouldSendReminder = true;
104+
const firstTuesdayNextMonth = getFirstTuesdayOfMonth(today.getUTCFullYear(), currentMonth + 1);
105+
date = firstTuesdayNextMonth.toISOString().split('T')[0];
106+
} else if (isFirstFriday && today < firstTuesdayThisMonth) {
107+
shouldSendReminder = true;
108+
date = firstTuesdayThisMonth.toISOString().split('T')[0];
109+
}
110+
} else if (isTuesday) {
111+
shouldSendReminder = true;
112+
date = "today";
113+
}
114+
115+
if (!shouldSendReminder) {
116+
console.log("Not the correct day for sending a reminder");
117+
return;
118+
}
119+
120+
console.log(`Calculated date for reminder: ${date}`);
121+
122+
// Fetch the latest open Office Hours issue
123+
const targetLabel = encodeURIComponent(process.env.OCWM_LABEL);
124+
const { data: workMeetings } = await github.request(`GET /repos/${process.env.OWNER}/${process.env.REPO}/issues?labels=${targetLabel}&per_page=1&state=open`);
125+
126+
if (workMeetings.length === 0) {
127+
console.log("No open Office Hours issue found");
128+
return;
129+
}
130+
131+
const issueNumber = workMeetings[0].number;
132+
const issueLink = `https://github.com/${process.env.OWNER}/${process.env.REPO}/issues/${issueNumber}`;
133+
134+
console.log(`Found issue: ${issueLink}`);
135+
136+
// Prepare the message for Slack
137+
const message = {
138+
issue: issueLink,
139+
date: date,
140+
timezone: timezone,
141+
time: time
142+
};
143+
144+
console.log(`Sending message to Slack: ${JSON.stringify(message)}`);
145+
146+
// Send the message to Slack
147+
const response = await fetch(process.env.SLACK_WEBHOOK, {
79148
method: 'POST',
80-
headers: {
81-
'Content-Type': 'application/json',
82-
},
83-
body: SLACK_MESSAGE,
149+
headers: { 'Content-Type': 'application/json' },
150+
body: JSON.stringify(message)
84151
});
152+
153+
if (!response.ok) {
154+
throw new Error(`Failed to send Slack message: ${response.statusText}`);
155+
}
156+
157+
console.log(`Reminder sent for ${timezone} session on ${date}`);
158+
} catch (error) {
159+
console.error(`An error occurred: ${error.message}`);
160+
core.setFailed(error.message);
85161
}

.github/workflows/stale.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ jobs:
5555
stale-pr-label: 'Status: Stale'
5656

5757
# Number of days of inactivity before an issue/PR is marked as stale.
58-
days-before-stale: 30
58+
days-before-stale: 180
5959

6060
# Number of days of inactivity before an issue/PR is closed.
6161
days-before-close: 180

0 commit comments

Comments
 (0)