- Goal:
We started building a tool that queries our github organization for all commits in the last 9 days by repo, and then displays them in a table.
If we only grab one commit, we can display things on the table without issue, but we want to have a selection of commits in a drop down incase we want to change it. When trying to map the value to the tag component, I'm not seeing the data available for selection. The output of the data itself looks good to me, but after a few days of struggling, I need help with the mapping.
- Steps:
Mapping the data from a transformer instead of from the direct output I'm using, changing the data structure, lots of different mapping trial and erroring.
-
Details:
-
Screenshots:
- App json export: (here's how to get a json export)
App Code:
const org = "org";
const token = token;
const perPage = 100;
const daysToFetch = 9;
let page = 1;
let repositories = ;
const excludedAuthors = [
"Endpoint Admin",
"endpointadmin",
"dependabot[bot]"
];
async function fetchAllRepositories(page) {
const url = https://api.github.com/orgs/${org}/repos?per_page=${perPage}&page=${page};
try {
const response = await fetch(url, {
headers: {
'Authorization': token ${token}
}
});
if (!response.ok) {
throw new Error(`Error fetching repositories: ${response.statusText}`);
}
return response.json();
} catch (error) {
console.error('Error during fetchRepositories:', error);
throw error;
}
}
async function hasDeployTopic(repoName) {
const url = https://api.github.com/repos/${org}/${repoName};
try {
const response = await fetch(url, {
headers: {
'Authorization': token ${token}
}
});
if (!response.ok) {
throw new Error(`Error fetching repository details for ${repoName}: ${response.statusText}`);
}
const repoData = await response.json();
return repoData.topics && repoData.topics.includes('deploy');
} catch (error) {
console.error(Error during hasDeployTopic for ${repoName}:, error);
throw error;
}
}
async function fetchValidCommits(repoName) {
let commitPage = 1;
let validCommits = ;
const currentDate = new Date();
const nineDaysAgo = new Date();
nineDaysAgo.setDate(currentDate.getDate() - daysToFetch);
while (true) {
const url = https://api.github.com/repos/${org}/${repoName}/commits?sha=main&per_page=${perPage}&page=${commitPage};
try {
const response = await fetch(url, {
headers: {
'Authorization': `token ${token}`
}
});
if (!response.ok) {
throw new Error(`Error fetching commits for ${repoName}: ${response.statusText}`);
}
const commits = await response.json();
if (commits.length === 0) {
break;
}
for (let commit of commits) {
if (!excludedAuthors.includes(commit.commit.author.name)) {
const commitDate = new Date(commit.commit.author.date);
if (commitDate >= nineDaysAgo && commitDate <= currentDate) {
validCommits.push({
sha: commit.sha,
label: `${commit.sha} - ${commit.commit.author.date} - ${commit.commit.author.name}`
});
} else if (commitDate < nineDaysAgo) {
if (validCommits.length === 0) {
validCommits.push({
sha: 'WILL NOT DEPLOY',
label: 'No valid commits within the last 9 days'
});
}
return validCommits;
}
}
}
commitPage++;
} catch (error) {
console.error(`Error during fetchValidCommits for ${repoName}:`, error);
return validCommits.length > 0 ? validCommits : [{
sha: 'Error fetching SHA',
label: 'Error fetching commit details'
}];
}
}
if (validCommits.length === 0) {
validCommits.push({
sha: 'WILL NOT DEPLOY',
label: 'No valid commits within the last 9 days'
});
}
return validCommits;
}
async function getAllRepositories() {
try {
while (true) {
const repos = await fetchAllRepositories(page);
if (repos.length === 0) {
break;
}
const activeRepos = repos.filter(repo => !repo.archived);
const repoDetailsPromises = activeRepos.map(async repo => {
const hasTopic = await hasDeployTopic(repo.name);
if (hasTopic) {
const commits = await fetchValidCommits(repo.name);
return {
repo: repo.name,
commits: commits
};
} else {
return null; // Exclude this repository
}
});
const repoDetails = await Promise.all(repoDetailsPromises);
repositories = repositories.concat(repoDetails.filter(detail => detail !== null));
page++;
}
return repositories;
} catch (error) {
console.error('Error during getAllRepositories:', error);
throw error;
}
}
return getAllRepositories()
.then(repoDetails => {
console.log(Fetched details for ${repoDetails.length} active repositories:, repoDetails);
if (repoDetails.length > 0) {
return repoDetails;
} else {
console.log('No active repositories found.');
return [];
}
})
.catch(error => {
console.error('Error fetching repository details:', error);
return ;
});
Transformer Code:
const repos = {{fetchAllRepositories.data}};
// Initialize an empty object to store the results
const result = {};
// Iterate over each repository
repos.forEach(repo => {
// Check if the repo and its commits are defined
if (repo && repo.repo && Array.isArray(repo.commits)) {
const repoName = repo.repo;
// Initialize an empty array for this repo's commits
result[repoName] = ;
// Iterate over each commit in the repo
repo.commits.forEach(commit => {
// Check if the commit and its sha are defined
if (commit && commit.sha) {
// Push the sha to the corresponding repo's array
result[repoName].push(commit.sha);
}
});
}
});
// Return the final result
console.log('result', result)
return result;
Output Example:
* {
* "endpoint-2.0-client": [
* “Commit”1234”,
* “Commit”1234”,
* “Commit”1234”,
* “Commit”1234”
* ],
* "platform-api": [
* “Commit”1234”
* ],



