Skip to content

Commit

Permalink
Merge pull request #4 from zillemarco/zillemarco-add-gitlab-support
Browse files Browse the repository at this point in the history
Add support for GitLab as provider
  • Loading branch information
kaxada authored Dec 11, 2023
2 parents 4ca12e3 + 3790ae9 commit 68a5f82
Show file tree
Hide file tree
Showing 11 changed files with 550 additions and 65 deletions.
2 changes: 1 addition & 1 deletion .env.development
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ DB_PASSWORD=rootpwd
DB_HOST=127.0.0.1
DB_DIALECT=mysql
PORT=8000
RETURN_JSON_ON_LOGIN=false
RETURN_JSON_ON_LOGIN=
12 changes: 9 additions & 3 deletions database/controllers/repo.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,29 @@ const User = require("../models/user.model");

const saveRepo = async (
githubRepoId,
gitlabRepoId,
DEICommitSHA,
repoLink,
badgeType,
attachment,
name
userId
) => {
if ((githubRepoId && gitlabRepoId) || (!githubRepoId && !gitlabRepoId)) {
return "Error creating repo: provide either githubRepoId or gitlabRepoId";
}

try {
// Find a user by their name
const user = await User.findOne({ where: { name } });
const user = await User.findOne({ where: { id: userId } });

if (!user) {
throw new Error(`User with name '${name}' not found.`);
throw new Error(`User with id '${userId}' not found.`);
}

// Create a new repo associated with the user
const repo = await Repo.create({
githubRepoId,
gitlabRepoId,
DEICommitSHA,
repoLink,
badgeType,
Expand Down
37 changes: 28 additions & 9 deletions database/controllers/user.controller.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,23 @@
const User = require("../models/user.model");

const saveUser = async (login, name, email, githubId) => {
const findUser = async (userId) => {
return await User.findOne({ where: { id: userId } });
};

const saveUser = async (login, name, email, githubId, gitlabId) => {
if ((githubId && gitlabId) || (!githubId && !gitlabId)) {
console.error("Error creating user: provide either githubId or gitlabId");
return null;
}

try {
// Find a user by their GitHub ID
let user = await User.findOne({ where: { githubId } });
// Find a user by their GitHub ID or GitLab ID
let user = null;
if (githubId) {
user = await User.findOne({ where: { githubId } });
} else if (gitlabId) {
user = await User.findOne({ where: { gitlabId } });
}

if (!user) {
// If the user doesn't exist, create a new one
Expand All @@ -12,9 +26,10 @@ const saveUser = async (login, name, email, githubId) => {
name,
email,
githubId,
gitlabId,
});
console.log("New user created");
return `New user created: ${user.login}`;
console.log(`New user created: ${user.login}`);
return user;
} else {
// User already exists; update if necessary
const updates = [];
Expand All @@ -34,15 +49,19 @@ const saveUser = async (login, name, email, githubId) => {

if (updates.length > 0) {
await user.save();
return `User ${user.login} updated: ${updates.join(", ")}`;
console.log(`User ${user.login} updated: ${updates.join(", ")}`);
}

console.log("User Already Exists");
return "User Already Exists";
return user;
}
} catch (error) {
return `Error saving user: ${error.message}`;
console.error(`Error saving user: ${error.message}`);
return null;
}
};

module.exports = saveUser;
module.exports = {
saveUser,
findUser,
};
7 changes: 6 additions & 1 deletion database/models/repo.model.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ const User = require("./user.model");
const Repo = sequelize.define("repos", {
githubRepoId: {
type: DataTypes.INTEGER,
allowNull: false,
allowNull: true,
},
gitlabRepoId: {
type: DataTypes.INTEGER,
allowNull: true,
},
DEICommitSHA: {
type: DataTypes.STRING,
Expand All @@ -26,6 +30,7 @@ const Repo = sequelize.define("repos", {
},
userId: {
type: DataTypes.INTEGER,
allowNull: false,
references: {
model: "users",
key: "id",
Expand Down
6 changes: 5 additions & 1 deletion database/models/user.model.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ const User = sequelize.define("users", {
},
githubId: {
type: DataTypes.INTEGER,
allowNull: false,
allowNull: true,
},
gitlabId: {
type: DataTypes.INTEGER,
allowNull: true,
},
});

Expand Down
20 changes: 15 additions & 5 deletions src/badges/bronzeBadge.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,16 @@ const augurAPI = require("../helpers/augurAPI");
const mailer = require("../helpers/mailer");
const saveRepo = require("../../database/controllers/repo.controller");

const bronzeBadge = async (name, email, id, url, content, DEICommitSHA) => {
const bronzeBadge = async (
userId,
userName,
email,
githubRepoId,
gitlabRepoId,
url,
content,
DEICommitSHA
) => {
// Check for specific titles
const titlesToCheck = [
"Project Access",
Expand All @@ -22,7 +31,7 @@ const bronzeBadge = async (name, email, id, url, content, DEICommitSHA) => {
}

if (!hasAllTitles) {
mailer(email, name, "Bronze", null, null, results.join("\n"));
mailer(email, userName, "Bronze", null, null, results.join("\n"));
} else if (hasAllTitles) {
// email content
const markdownLink =
Expand All @@ -31,16 +40,17 @@ const bronzeBadge = async (name, email, id, url, content, DEICommitSHA) => {
"<img src="https://raw.githubusercontent.com/AllInOpenSource/BadgingAPI/main/src/assets/badges/bronze-badge.svg" alt="DEI Badging Bronze Badge" />";

// send email
mailer(email, name, "Bronze", markdownLink, htmlLink);
mailer(email, userName, "Bronze", markdownLink, htmlLink);

// save repo to database and return repo id
const repo_id = await saveRepo(
id,
githubRepoId,
gitlabRepoId,
DEICommitSHA,
url,
"Bronze",
markdownLink,
name
userId
);

// use repo id in augur api call
Expand Down
64 changes: 36 additions & 28 deletions src/helpers/github.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,12 @@ const getUserRepositories = async (octokit) => {
}

return {
repositories: repos.map((repo) => repo.full_name),
repositories: repos.map((repo) => {
return {
id: repo.id,
fullName: repo.full_name,
};
}),
errors: [],
};
} catch (error) {
Expand All @@ -128,20 +133,22 @@ const getUserRepositories = async (octokit) => {
/**
* Get the id and url of the provided repository path
* @param {*} octokit An Octokit instance
* @param {*} owner The (username) owner of the repository
* @param {*} repositoryPath The path to the repository, without the owner prefix
* @param {*} repositoryId The id of the repository
* @returns A json object with `info` (the repository infos) and `errors`
*/
const getRepositoryInfo = async (octokit, owner, repositoryPath) => {
const getRepositoryInfo = async (octokit, repositoryId) => {
try {
const {
data: { id, html_url },
} = await octokit.repos.get({ owner, repo: repositoryPath });
data: { id, html_url, full_name },
} = await octokit.request("GET /repositories/{repositoryId}", {
repositoryId,
});

return {
info: {
id,
url: html_url,
fullName: full_name,
},
errors: [],
};
Expand All @@ -156,23 +163,17 @@ const getRepositoryInfo = async (octokit, owner, repositoryPath) => {
/**
* Get the content and commit SHA of a file inside a repository
* @param {*} octokit An Octokit instance
* @param {*} owner The (username) owner of the repository
* @param {*} repositoryPath The path to the repository, without the owner prefix
* @param {*} repositoryFullName The full path to the repository
* @param {*} filePath The path to the file inside the repository
* @returns A json object with `file` (SHA and content) and `errors`
*/
const getFileContentAndSHA = async (
octokit,
owner,
repositoryPath,
filePath
) => {
const getFileContentAndSHA = async (octokit, repositoryFullName, filePath) => {
try {
const {
data: { sha, content },
} = await octokit.repos.getContent({
owner,
repo: repositoryPath,
owner: repositoryFullName.split("/")[0],
repo: repositoryFullName.split("/")[1],
path: filePath,
});

Expand All @@ -193,23 +194,20 @@ const getFileContentAndSHA = async (

/**
* Scans a list of repositories to try and apply for a badge
* @param {*} userId Id of the user
* @param {*} name Full name of the user
* @param {*} email User email used to send them emails with the results
* @param {*} repositories List of repositories to scan
* @param {*} repositoryIds List of repositories id to scan
*/
const scanRepositories = async (name, email, repositories) => {
const scanRepositories = async (userId, name, email, repositoryIds) => {
const octokit = new Octokit();
let results = [];

try {
for (const repository of repositories) {
const owner = repository.split("/")[0];
const repositoryPath = repository.split("/")[1];

for (const repositoryId of repositoryIds) {
const { info, errors: info_errors } = await getRepositoryInfo(
octokit,
owner,
repositoryPath
repositoryId
);
if (info_errors.length > 0) {
console.error(info_errors);
Expand All @@ -218,8 +216,7 @@ const scanRepositories = async (name, email, repositories) => {

const { file, errors: file_errors } = await getFileContentAndSHA(
octokit,
owner,
repositoryPath,
info.fullName,
"DEI.md"
);
if (file_errors.length > 0) {
Expand All @@ -230,17 +227,19 @@ const scanRepositories = async (name, email, repositories) => {
try {
// Check if the repo was badged before
const existingRepo = await Repo.findOne({
where: { githubRepoId: info.id },
where: { githubRepoId: info.id, DEICommitSHA: file.sha },
});

if (file.content) {
if (existingRepo) {
// Compare the DEICommitSHA with the existing repo's DEICommitSHA
if (existingRepo.DEICommitSHA !== file.sha) {
bronzeBadge(
userId,
name,
email,
info.id,
null,
info.url,
file.content,
file.sha
Expand All @@ -251,7 +250,16 @@ const scanRepositories = async (name, email, repositories) => {
}
} else {
// Repo not badged before, badge it
bronzeBadge(name, email, info.id, info.url, file.content, file.sha);
bronzeBadge(
userId,
name,
email,
info.id,
null,
info.url,
file.content,
file.sha
);
}
}
} catch (error) {
Expand Down
Loading

0 comments on commit 68a5f82

Please sign in to comment.