-
Notifications
You must be signed in to change notification settings - Fork 406
#RI-3478 - automatic update dependencies versions #2493
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
Merged
vlad-dargel
merged 30 commits into
main
from
feature/RI-3478_automatic_update_dependencies_versions
Sep 22, 2023
Merged
Changes from all commits
Commits
Show all changes
30 commits
Select commit
Hold shift + click to select a range
e8b19b0
#RI-3478 - Automate updates of the dependencies file
egor-zalenski 4c3f4a9
#RI-4842 - Add application version to all telemetry events
egor-zalenski 8f4a01a
#RI-4842 - Add application version to all telemetry events
egor-zalenski 580b5cd
#RI-3478 - Automate updates of the dependencies file
egor-zalenski 3e9ee40
#RI-3478 - Automate updates of the dependencies file
egor-zalenski d2f864f
Updated config.yml
egor-zalenski 6dbcf9b
#RI-3478 - Automate updates of the dependencies file
egor-zalenski ad65eba
#RI-3478 - Automate updates of the dependencies file
egor-zalenski 56a2f07
#RI-3478 - Automate updates of the dependencies file
egor-zalenski 93ae782
#RI-3478 - Automate updates of the dependencies file
egor-zalenski 2749f1c
#RI-3478 - Automate updates of the dependencies file
egor-zalenski 06119b6
#RI-3478 - Automate updates of the dependencies file
egor-zalenski 08d1c79
#RI-3478 - Automate updates of the dependencies file
egor-zalenski fc59158
#RI-3478 - Automate updates of the dependencies file
egor-zalenski ee68797
#RI-3478 - Automate updates of the dependencies file
egor-zalenski 589e936
#RI-3478 - Automate updates of the dependencies file
egor-zalenski 87e620c
#RI-3478 - Added summary
egor-zalenski 7774009
#RI-3478 - Added weekly jobs
egor-zalenski 76d6523
#RI-3478 - not build plugins for licenses check
egor-zalenski bdf16ec
#RI-3478 - not build plugins for licenses check
egor-zalenski 7b235ef
#RI-3478 - not build plugins for licenses check
egor-zalenski f111227
#RI-3478 - not build plugins for licenses check
egor-zalenski 035b579
#RI-3478 - not build plugins for licenses check
egor-zalenski 2dfb38c
#RI-3478 - not build plugins for licenses check
egor-zalenski b378ba4
#RI-3478 - not build plugins for licenses check
egor-zalenski a8b7fd8
#RI-3478 - not build plugins for licenses check
egor-zalenski 3674895
#RI-3478 - not build plugins for licenses check
egor-zalenski dc81e46
#RI-3478 - not build plugins for licenses check
egor-zalenski 51fe4cf
#RI-3478 - not build plugins for licenses check
egor-zalenski 416625b
Remove license checks for regular job
egor-zalenski File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,252 @@ | ||
const fs = require('fs'); | ||
const { join } = require('path'); | ||
const { last, set } = require('lodash'); | ||
const { google } = require('googleapis'); | ||
const { exec } = require('child_process'); | ||
const csvParser = require('csv-parser'); | ||
const { stringify } = require('csv-stringify'); | ||
|
||
const licenseFolderName = 'licenses'; | ||
const spreadsheetId = process.env.SPREADSHEET_ID; | ||
const outputFilePath = `./${licenseFolderName}/licenses.csv`; | ||
const summaryFilePath = `./${licenseFolderName}/summary.csv`; | ||
const allData = []; | ||
let csvFiles = []; | ||
|
||
|
||
// Main function | ||
async function main() { | ||
const folderPath = './'; | ||
const packageJsons = findPackageJsonFiles(folderPath); // Find all package.json files in the given folder | ||
|
||
console.log('All package.jsons was found:', packageJsons); | ||
|
||
// Create the folder if it doesn't exist | ||
if (!fs.existsSync(licenseFolderName)) { | ||
fs.mkdirSync(licenseFolderName); | ||
} | ||
|
||
try { | ||
await Promise.all(packageJsons.map(runLicenseCheck)); | ||
console.log('All csv files was generated'); | ||
await generateSummary() | ||
await sendLicensesToGoogleSheet() | ||
} catch (error) { | ||
console.error('An error occurred:', error); | ||
process.exit(1); | ||
} | ||
} | ||
|
||
main(); | ||
|
||
// Function to find all package.json files in a given folder | ||
function findPackageJsonFiles(folderPath) { | ||
const packageJsonPaths = []; | ||
const packageJsonName = 'package.json'; | ||
const excludeFolders = ['dist', 'node_modules', 'static', 'electron', 'redisgraph']; | ||
|
||
// Recursive function to search for package.json files | ||
function searchForPackageJson(currentPath) { | ||
const files = fs.readdirSync(currentPath); | ||
|
||
for (const file of files) { | ||
const filePath = join(currentPath, file); | ||
const stats = fs.statSync(filePath); | ||
|
||
if (stats.isDirectory() && !excludeFolders.includes(file)) { | ||
searchForPackageJson(filePath); | ||
} else if (file === packageJsonName) { | ||
packageJsonPaths.push(`./${filePath.slice(0, -packageJsonName.length - 1)}`); | ||
} | ||
} | ||
} | ||
|
||
searchForPackageJson(folderPath); | ||
return packageJsonPaths; | ||
} | ||
|
||
// Function to run license check for a given package.json file | ||
async function runLicenseCheck(path) { | ||
const name = last(path.split('/')) || 'electron'; | ||
|
||
const COMMANDS = [ | ||
`license-checker --start ${path} --csv --out ./${licenseFolderName}/${name}_prod.csv --production`, | ||
`license-checker --start ${path} --csv --out ./${licenseFolderName}/${name}_dev.csv --development`, | ||
] | ||
|
||
return await Promise.all(COMMANDS.map((command) => | ||
new Promise((resolve, reject) => { | ||
exec(command, (error, stdout, stderr) => { | ||
if (error) { | ||
console.error(`Failed command: ${commandProd}, error:`, stderr); | ||
reject(error); | ||
} | ||
resolve(); | ||
}); | ||
}) | ||
)); | ||
} | ||
|
||
async function sendLicensesToGoogleSheet() { | ||
try { | ||
const serviceAccountKey = JSON.parse(fs.readFileSync('./gasKey.json', 'utf-8')); | ||
|
||
// Set up JWT client | ||
const jwtClient = new google.auth.JWT( | ||
serviceAccountKey.client_email, | ||
null, | ||
serviceAccountKey.private_key, | ||
['https://www.googleapis.com/auth/spreadsheets'] | ||
); | ||
|
||
const sheets = google.sheets('v4'); | ||
|
||
// Read all .csv files in the 'licenses' folder | ||
csvFiles.forEach((csvFile) => { | ||
// Extract sheet name from file name | ||
const sheetName = csvFile.replace('.csv', '').replaceAll('_', ' '); | ||
|
||
const data = []; | ||
fs.createReadStream(`./${licenseFolderName}/${csvFile}`) | ||
.pipe(csvParser({ headers: false })) | ||
.on('data', (row) => { | ||
data.push(Object.values(row)); | ||
}) | ||
.on('end', async () => { | ||
const resource = { values: data }; | ||
|
||
try { | ||
const response = await sheets.spreadsheets.get({ | ||
auth: jwtClient, | ||
spreadsheetId, | ||
}); | ||
|
||
const sheet = response.data.sheets.find((sheet) => sheet.properties.title === sheetName); | ||
if (sheet) { | ||
// Clear contents of the sheet starting from cell A2 | ||
await sheets.spreadsheets.values.clear({ | ||
auth: jwtClient, | ||
spreadsheetId, | ||
range: `${sheetName}!A1:Z`, // Assuming Z is the last column | ||
}); | ||
} else { | ||
// Create the sheet if it doesn't exist | ||
await sheets.spreadsheets.batchUpdate({ | ||
auth: jwtClient, | ||
spreadsheetId, | ||
resource: set({}, 'requests[0].addSheet.properties.title', sheetName), | ||
}); | ||
} | ||
} catch (error) { | ||
console.error(`Error checking/creating sheet for ${sheetName}:`, error); | ||
} | ||
|
||
try { | ||
await sheets.spreadsheets.values.batchUpdate({ | ||
auth: jwtClient, | ||
spreadsheetId, | ||
resource: { | ||
valueInputOption: 'RAW', | ||
data: [ | ||
{ | ||
range: `${sheetName}!A1`, // Use the sheet name as the range and start from A2 | ||
majorDimension: 'ROWS', | ||
values: data, | ||
}, | ||
], | ||
}, | ||
}); | ||
|
||
console.log(`CSV data has been inserted into ${sheetName} sheet.`); | ||
} catch (err) { | ||
console.error(`Error inserting data for ${sheetName}:`, err); | ||
} | ||
}); | ||
}); | ||
} catch (error) { | ||
console.error('Error loading service account key:', error); | ||
} | ||
} | ||
|
||
// Function to read and process each CSV file | ||
const processCSVFile = (file) => { | ||
return new Promise((resolve, reject) => { | ||
const parser = csvParser({ columns: true, trim: true }); | ||
const input = fs.createReadStream(`./${licenseFolderName}/${file}`); | ||
|
||
parser.on('data', (record) => { | ||
allData.push(record); | ||
}); | ||
|
||
parser.on('end', () => { | ||
resolve(); | ||
}); | ||
|
||
parser.on('error', (err) => { | ||
reject(err); | ||
}); | ||
|
||
input.pipe(parser); | ||
}); | ||
}; | ||
|
||
// Process and aggregate license data | ||
const processLicenseData = () => { | ||
const licenseCountMap = {}; | ||
for (const record of allData) { | ||
const license = record.license; | ||
licenseCountMap[license] = (licenseCountMap[license] || 0) + 1; | ||
} | ||
return licenseCountMap; | ||
}; | ||
|
||
// Create summary CSV data | ||
const createSummaryData = (licenseCountMap) => { | ||
const summaryData = [['License', 'Count']]; | ||
for (const license in licenseCountMap) { | ||
summaryData.push([license, licenseCountMap[license]]); | ||
} | ||
return summaryData; | ||
}; | ||
|
||
// Write summary CSV file | ||
const writeSummaryCSV = async (summaryData) => { | ||
try { | ||
const summaryCsvString = await stringifyPromise(summaryData); | ||
fs.writeFileSync(summaryFilePath, summaryCsvString); | ||
csvFiles.push(last(summaryFilePath.split('/'))); | ||
console.log(`Summary CSV saved as ${summaryFilePath}`); | ||
} catch (err) { | ||
console.error(`Error: ${err}`); | ||
} | ||
}; | ||
|
||
// Stringify as a promise | ||
const stringifyPromise = (data) => { | ||
return new Promise((resolve, reject) => { | ||
stringify(data, (err, csvString) => { | ||
if (err) { | ||
reject(err); | ||
} else { | ||
resolve(csvString); | ||
} | ||
}); | ||
}); | ||
}; | ||
|
||
async function generateSummary() { | ||
csvFiles = fs.readdirSync(licenseFolderName).filter(file => file.endsWith('.csv')).sort(); | ||
|
||
for (const file of csvFiles) { | ||
try { | ||
await processCSVFile(file); | ||
} catch (err) { | ||
console.error(`Error processing ${file}: ${err}`); | ||
} | ||
} | ||
|
||
const licenseCountMap = processLicenseData(); | ||
const summaryData = createSummaryData(licenseCountMap); | ||
|
||
await writeSummaryCSV(summaryData); | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also if we have such checks on weekly basis, why do we need it for feature/main branches?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was for test, removed