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

test PR #59

Merged
merged 24 commits into from
Dec 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
20 changes: 18 additions & 2 deletions .github/workflows/code-path-changes.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,33 @@ name: Notify Code Path Changes

on:
pull_request:
types: [opened, synchronize]
paths:
- '**'

env:
OAUTH2_CLIENT_ID: ${{ secrets.OAUTH2_CLIENT_ID }}
OAUTH2_CLIENT_SECRET: ${{ secrets.OAUTH2_CLIENT_SECRET }}
OAUTH2_REFRESH_TOKEN: ${{ secrets.OAUTH2_REFRESH_TOKEN }}
GITHUB_REPOSITORY: ${{ github.repository }}
GITHUB_PR_NUMBER: ${{ github.event.pull_request.number }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

jobs:
notify:
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v3

- name: Set up Node.js (if using JavaScript/Node.js script)
uses: actions/setup-node@v3
with:
node-version: '16'

- name: Install dependencies
run: npm install axios nodemailer

- name: Run Notification Script
run: |
chmod +x test/send_notification_on_change.sh
./test//send_notification_on_change.sh
node test/send-notification-on-change.js
2 changes: 2 additions & 0 deletions test/codepath-notification
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
^test/.*$: [email protected]
^.github/.*$: [email protected]
1 change: 0 additions & 1 deletion test/codepath-notification.yml

This file was deleted.

125 changes: 125 additions & 0 deletions test/send-notification-on-change.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
const fs = require('fs');
const path = require('path');
const axios = require('axios');
const nodemailer = require('nodemailer');

async function getAccessToken(clientId, clientSecret, refreshToken) {
try {
const response = await axios.post('https://oauth2.googleapis.com/token', {
client_id: clientId,
client_secret: clientSecret,
refresh_token: refreshToken,
grant_type: 'refresh_token',
});
return response.data.access_token;
} catch (error) {
console.error('Failed to fetch access token:', error.response?.data || error.message);
process.exit(1);
}
}

(async () => {
const configFilePath = path.join(__dirname, 'codepath-notification');
const repo = process.env.GITHUB_REPOSITORY;
const prNumber = process.env.GITHUB_PR_NUMBER;
const token = process.env.GITHUB_TOKEN;

// Generate OAuth2 access token
const CLIENT_ID = process.env.OAUTH2_CLIENT_ID;
const CLIENT_SECRET = process.env.OAUTH2_CLIENT_SECRET;
const REFRESH_TOKEN = process.env.OAUTH2_REFRESH_TOKEN;

if (!repo || !prNumber || !token || !CLIENT_ID || !CLIENT_SECRET | !REFRESH_TOKEN) {
console.error('Missing required environment variables.');
process.exit(1);
}

try {
// Read and process the configuration file
const configFileContent = fs.readFileSync(configFilePath, 'utf-8');
const configRules = configFileContent
.split('\n')
.filter(line => line.trim() !== '') // Filter out empty lines
.map(line => {
const [regex, email] = line.split(':').map(part => part.trim());
return { regex: new RegExp(regex), email };
});

// Fetch changed files
const [owner, repoName] = repo.split('/');
const apiUrl = `https://api.github.com/repos/${owner}/${repoName}/pulls/${prNumber}/files`;

const response = await axios.get(apiUrl, {
headers: {
Authorization: `Bearer ${token}`,
Accept: 'application/vnd.github.v3+json',
},
});

const changedFiles = response.data.map(file => file.filename);
console.log('Changed files:', changedFiles);

// Group matched files by email address
const matchesByEmail = {};
changedFiles.forEach(file => {
configRules.forEach(rule => {
if (rule.regex.test(file)) {
if (!matchesByEmail[rule.email]) {
matchesByEmail[rule.email] = [];
}
matchesByEmail[rule.email].push(file);
}
});
});

console.log('Grouped matches by email:', matchesByEmail);

const accessToken = await getAccessToken(CLIENT_ID, CLIENT_SECRET, REFRESH_TOKEN);

// Configure Nodemailer with OAuth2
// service: 'Gmail',
const transporter = nodemailer.createTransport({
host: "smtp.gmail.com",
port: 465,
secure: true,
auth: {
type: 'OAuth2',
user: '[email protected]',
clientId: CLIENT_ID,
clientSecret: CLIENT_SECRET,
refreshToken: REFRESH_TOKEN,
accessToken: accessToken
},
});

// Send one email per recipient
for (const [email, files] of Object.entries(matchesByEmail)) {
const emailBody = `
${email},
<p>
Files owned by you have been changed in open source ${repo}. The <a href="https://github.com/${repo}/pull/${prNumber}">pull request is #${prNumber}</a>. These are the files you own that have been modified:
<ul>
${files.map(file => `<li>${file}</li>`).join('')}
</ul>
`;

try {
await transporter.sendMail({
from: `"Prebid Info" <[email protected]>`,
to: email,
subject: `Files have been changed in open source ${repo}`,
html: emailBody,
});

console.log(`Email sent successfully to ${email}`);
console.log(`${emailBody}`);
} catch (error) {
console.error(`Failed to send email to ${email}:`, error.message);
}
}
} catch (error) {
console.error('Error:', error.message);
process.exit(1);
}
})();

42 changes: 27 additions & 15 deletions test/send_notification_on_change.sh
Original file line number Diff line number Diff line change
@@ -1,46 +1,58 @@
#!/usr/bin/env bash

# Path to the codepath-notification file
NOTIFICATION_FILE="codepath-notification"
NOTIFICATION_FILE="test/codepath-notification"

# SMTP Configuration
SMTP_SERVER="smtp.google.com"
SMTP_PORT="587"
USERNAME="${{ secrets.EMAIL_USERNAME }}"
PASSWORD="${{ secrets.EMAIL_PASSWORD }}"
USERNAME="$EMAIL_USERNAME"
PASSWORD="$EMAIL_PASSWORD"
FROM_EMAIL="[email protected]"

# Git command to get the list of changed files in the merge request
CHANGED_FILES=$(git diff --name-only origin/main...HEAD)
echo "git branch"
echo $(git branch -a)
echo "---"
CHANGED_FILES=$(git diff --name-only)
# Associative array to store file changes by email
declare -A EMAIL_BUCKETS

# Email sending function using sendemail
send_email() {
local recipient=$1
local file=$2
echo "Sending notification to $recipient for changes in $file"

SUBJECT="Code Path Change Notification"
BODY="The following file was modified: $file"

# Send email using sendemail
sendemail -f "$FROM_EMAIL" \
-t "$recipient" \
-u "$SUBJECT" \
-m "$BODY" \
-s "$SMTP_SERVER:$SMTP_PORT" \
-xu "$USERNAME" \
-xp "$PASSWORD" \
-o tls=yes
echo "Sending email to $recipient with body=$BODY"
# sendemail -f "$FROM_EMAIL" \
# -t "$recipient" \
# -u "$SUBJECT" \
# -m "$BODY" \
# -s "$SMTP_SERVER:$SMTP_PORT" \
# -xu "$USERNAME" \
# -xp "$PASSWORD" \
# -o tls=yes
}


# Process the codepath-notification file
while IFS= read -r line; do
path_pattern=$(echo "$line" | awk '{print $1}')
email=$(echo "$line" | awk '{print $2}')

for file in $CHANGED_FILES; do
if [[ $file == $path_pattern ]]; then
send_email "$email" "$file"
# Append the file to the email bucket
EMAIL_BUCKETS["$email"]+="$file\n"
fi
done
done < "$NOTIFICATION_FILE"

# Send emails for each recipient
for email in "${!EMAIL_BUCKETS[@]}"; do
send_email "$email" "${EMAIL_BUCKETS[$email]}"
done
Loading