diff --git a/badges/coverage.svg b/badges/coverage.svg index fd27744..dd7ea94 100644 --- a/badges/coverage.svg +++ b/badges/coverage.svg @@ -1 +1 @@ -Coverage: 16.23%Coverage16.23% \ No newline at end of file +Coverage: 15.42%Coverage15.42% \ No newline at end of file diff --git a/dist/index.js b/dist/index.js index 9d75164..decfae7 100644 --- a/dist/index.js +++ b/dist/index.js @@ -122960,6 +122960,7 @@ const { } = __nccwpck_require__(70006) const { generateTestResults, + getGithubCalls, getUniqueBy, getRawCollapsible } = __nccwpck_require__(70062) @@ -122969,6 +122970,8 @@ const allowHTTP = getAllowHTTP() const defaultPolicy = getDefaultPolicy() const egressRules = getEgressRules() const trustedGithubAccounts = getTrustedGithubAccounts() +const repoName = process.env.GITHUB_REPOSITORY // e.g. koalalab-inc/bolt +const repoOwner = repoName.split('/')[0] // e.g. koalalab-inc function actionString(action) { switch (action) { @@ -123010,6 +123013,8 @@ async function generateSummary() { const randomString = Math.random().toString(36).substring(7) const jobName = `${jobID}-${runId}-${runAttempt}-${runNumber}-${randomString}` + const githubCallsFilename = `${homeDir}/github_calls.json` + if (isDebugMode === 'true') { // Upload auditd log file to artifacts const artifactName = `${jobName}-bolt-auditd-log` @@ -123045,19 +123050,41 @@ async function generateSummary() { await exec(`cp ${homeDir}/${outputFile} ${outputFile}`) const results = await generateTestResults(outputFile) + const githubCalls = getGithubCalls(githubCallsFilename) const uniqueResults = getUniqueBy(results, ['destination', 'scheme']) // const uniqueResultRows = uniqueResults.map(resultToRow) - const githubAccountCalls = results.filter(result => { - return result.trusted_github_account_flag !== undefined - }) + // const githubAccountCalls = results.filter(result => { + // return result.trusted_github_account_flag !== undefined + // }) - const githubAccounts = githubAccountCalls.reduce((accounts, call) => { - const path = call.request_path - const method = call.request_method - const name = call.github_account_name - const trusted_flag = call.trusted_github_account_flag + // const githubAccounts = githubAccountCalls.reduce((accounts, call) => { + // const path = call.request_path + // const method = call.request_method + // const name = call.github_account_name + // const trusted_flag = call.trusted_github_account_flag + // accounts[name] = accounts[name] || {} + // accounts[name]['name'] = name + // accounts[name]['trusted'] = trusted_flag + // const paths = accounts[name]['paths'] || [] + // if (!paths.some(p => p.path === path)) { + // accounts[name]['paths'] = [...paths, { path, method }] + // } + // return accounts + // }, []) + + const githubAccounts = githubCalls.reduce((accounts, call) => { + const path = call.path + const method = call.method + let name = '' + if (path.startsWith('/orgs/') || path.startsWith('/repos/')) { + const parts = path.split('/') + name = parts[2] + } + + const trusted_flag = + trustedGithubAccounts.includes(name) || name === repoOwner accounts[name] = accounts[name] || {} accounts[name]['name'] = name accounts[name]['trusted'] = trusted_flag @@ -123137,15 +123164,15 @@ async function generateSummary() { const configTableString = core.summary.addTable(configTable).stringify() core.summary.emptyBuffer() - // const trustedGithubAccountsHeaderString = core.summary - // .addHeading('🔒 Trusted Github Accounts', 4) - // .stringify() - // core.summary.emptyBuffer() + const trustedGithubAccountsHeaderString = core.summary + .addHeading('🔒 Trusted Github Accounts', 4) + .stringify() + core.summary.emptyBuffer() - // const trustedGithubAccountsTableString = core.summary - // .addTable(trustedGithubAccountsData) - // .stringify() - // core.summary.emptyBuffer() + const trustedGithubAccountsTableString = core.summary + .addTable(trustedGithubAccountsData) + .stringify() + core.summary.emptyBuffer() const knownDestinationsHeaderString = core.summary .addHeading('✅ Known Destinations', 4) @@ -123188,20 +123215,20 @@ ${configTableString} ` ) - // if (trustedGithubAccounts.length > 0) { - // summary = summary - // .addRaw( - // ` - //
- // - // ${trustedGithubAccountsHeaderString} - // - // ${trustedGithubAccountsTableString} - //
- // ` - // ) - // .addQuote('NOTE: The account in which workflow runs is always trusted.') - // } + if (trustedGithubAccounts.length > 0) { + summary = summary + .addRaw( + ` +
+ + ${trustedGithubAccountsHeaderString} + + ${trustedGithubAccountsTableString} +
+ ` + ) + .addQuote('NOTE: The account in which workflow runs is always trusted.') + } if (egressRules.length > 0) { summary = summary @@ -123218,28 +123245,28 @@ ${configTableString} .addEOL() } - // if (untrustedGithubAccounts.length > 0) { - // summary = summary.addHeading( - // '🚨 Requests to untrusted GitHub accounts found', - // 3 - // ).addRaw(` - // > [!CAUTION] - // > If you do not recognize these GitHub Accounts, you may want to investigate further. Add them to your trusted GitHub accounts if this is expected. See [Docs](https://github.com/koalalab-inc/bolt?tab=readme-ov-file#configure) for more information. - // `) - - // for (const account of untrustedGithubAccounts) { - // summary = summary.addRaw(` - //
- // - // ${account.name} - // - // - //
- // `) - // } - // } + if (untrustedGithubAccounts.length > 0) { + summary = summary.addHeading( + '🚨 Requests to untrusted GitHub accounts found', + 3 + ).addRaw(` + > [!CAUTION] + > If you do not recognize these GitHub Accounts, you may want to investigate further. Add them to your trusted GitHub accounts if this is expected. See [Docs](https://github.com/koalalab-inc/bolt?tab=readme-ov-file#configure) for more information. + `) + + for (const account of untrustedGithubAccounts) { + summary = summary.addRaw(` +
+ + ${account.name} + + +
+ `) + } + } summary = summary.addRaw(auditSummaryRaw) @@ -123321,6 +123348,30 @@ async function generateTestResults(filePath) { } } +function getGithubCalls(githubCallsFilename) { + try { + const githubCallsFileContent = fs.readFileSync(githubCallsFilename, 'utf-8') + const lines = githubCallsFileContent.split('\n') + + const githubCalls = [] + + for (const line of lines) { + if (line.length === 0) continue + try { + const githubCall = JSON.parse(line) + githubCalls.push(githubCall) + } catch (error) { + console.error(`Error parsing JSON on line: ${line}`) + } + } + + return githubCalls + } catch (error) { + console.error(`Error reading file: ${error.message}`) + return [] + } +} + function getUniqueBy(arr, keys) { const uniqueObj = arr.reduce((unique, o) => { const key = keys.map(k => o[k]).join('|') @@ -123343,6 +123394,7 @@ function getRawCollapsible({ body, header }) { module.exports = { generateTestResults, + getGithubCalls, getUniqueBy, getRawCollapsible } @@ -123353,7 +123405,7 @@ module.exports = { /***/ 49554: /***/ ((module) => { -const releaseVersion = 'v1.6.2' +const releaseVersion = 'v1.7.0-rc' module.exports = { releaseVersion diff --git a/package.json b/package.json index 1f3cf50..b3b8180 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "bolt", "description": "A GitHub Action to install and run Bolt", - "version": "1.4.2-rc", + "version": "v1.7.0-rc", "author": "Abhishek Anand", "private": true, "homepage": "https://github.com/koalalab-inc/bolt#readme", diff --git a/src/summary.js b/src/summary.js index 684f56e..7189cba 100644 --- a/src/summary.js +++ b/src/summary.js @@ -13,6 +13,7 @@ const { } = require('./input') const { generateTestResults, + getGithubCalls, getUniqueBy, getRawCollapsible } = require('./summary_utils') @@ -22,6 +23,8 @@ const allowHTTP = getAllowHTTP() const defaultPolicy = getDefaultPolicy() const egressRules = getEgressRules() const trustedGithubAccounts = getTrustedGithubAccounts() +const repoName = process.env.GITHUB_REPOSITORY // e.g. koalalab-inc/bolt +const repoOwner = repoName.split('/')[0] // e.g. koalalab-inc function actionString(action) { switch (action) { @@ -63,6 +66,8 @@ async function generateSummary() { const randomString = Math.random().toString(36).substring(7) const jobName = `${jobID}-${runId}-${runAttempt}-${runNumber}-${randomString}` + const githubCallsFilename = `${homeDir}/github_calls.json` + if (isDebugMode === 'true') { // Upload auditd log file to artifacts const artifactName = `${jobName}-bolt-auditd-log` @@ -98,19 +103,41 @@ async function generateSummary() { await exec(`cp ${homeDir}/${outputFile} ${outputFile}`) const results = await generateTestResults(outputFile) + const githubCalls = getGithubCalls(githubCallsFilename) const uniqueResults = getUniqueBy(results, ['destination', 'scheme']) // const uniqueResultRows = uniqueResults.map(resultToRow) - const githubAccountCalls = results.filter(result => { - return result.trusted_github_account_flag !== undefined - }) + // const githubAccountCalls = results.filter(result => { + // return result.trusted_github_account_flag !== undefined + // }) + + // const githubAccounts = githubAccountCalls.reduce((accounts, call) => { + // const path = call.request_path + // const method = call.request_method + // const name = call.github_account_name + // const trusted_flag = call.trusted_github_account_flag + // accounts[name] = accounts[name] || {} + // accounts[name]['name'] = name + // accounts[name]['trusted'] = trusted_flag + // const paths = accounts[name]['paths'] || [] + // if (!paths.some(p => p.path === path)) { + // accounts[name]['paths'] = [...paths, { path, method }] + // } + // return accounts + // }, []) + + const githubAccounts = githubCalls.reduce((accounts, call) => { + const path = call.path + const method = call.method + let name = '' + if (path.startsWith('/orgs/') || path.startsWith('/repos/')) { + const parts = path.split('/') + name = parts[2] + } - const githubAccounts = githubAccountCalls.reduce((accounts, call) => { - const path = call.request_path - const method = call.request_method - const name = call.github_account_name - const trusted_flag = call.trusted_github_account_flag + const trusted_flag = + trustedGithubAccounts.includes(name) || name === repoOwner accounts[name] = accounts[name] || {} accounts[name]['name'] = name accounts[name]['trusted'] = trusted_flag @@ -190,15 +217,15 @@ async function generateSummary() { const configTableString = core.summary.addTable(configTable).stringify() core.summary.emptyBuffer() - // const trustedGithubAccountsHeaderString = core.summary - // .addHeading('🔒 Trusted Github Accounts', 4) - // .stringify() - // core.summary.emptyBuffer() + const trustedGithubAccountsHeaderString = core.summary + .addHeading('🔒 Trusted Github Accounts', 4) + .stringify() + core.summary.emptyBuffer() - // const trustedGithubAccountsTableString = core.summary - // .addTable(trustedGithubAccountsData) - // .stringify() - // core.summary.emptyBuffer() + const trustedGithubAccountsTableString = core.summary + .addTable(trustedGithubAccountsData) + .stringify() + core.summary.emptyBuffer() const knownDestinationsHeaderString = core.summary .addHeading('✅ Known Destinations', 4) @@ -241,20 +268,20 @@ ${configTableString} ` ) - // if (trustedGithubAccounts.length > 0) { - // summary = summary - // .addRaw( - // ` - //
- // - // ${trustedGithubAccountsHeaderString} - // - // ${trustedGithubAccountsTableString} - //
- // ` - // ) - // .addQuote('NOTE: The account in which workflow runs is always trusted.') - // } + if (trustedGithubAccounts.length > 0) { + summary = summary + .addRaw( + ` +
+ + ${trustedGithubAccountsHeaderString} + + ${trustedGithubAccountsTableString} +
+ ` + ) + .addQuote('NOTE: The account in which workflow runs is always trusted.') + } if (egressRules.length > 0) { summary = summary @@ -271,28 +298,28 @@ ${configTableString} .addEOL() } - // if (untrustedGithubAccounts.length > 0) { - // summary = summary.addHeading( - // '🚨 Requests to untrusted GitHub accounts found', - // 3 - // ).addRaw(` - // > [!CAUTION] - // > If you do not recognize these GitHub Accounts, you may want to investigate further. Add them to your trusted GitHub accounts if this is expected. See [Docs](https://github.com/koalalab-inc/bolt?tab=readme-ov-file#configure) for more information. - // `) - - // for (const account of untrustedGithubAccounts) { - // summary = summary.addRaw(` - //
- // - // ${account.name} - // - // - //
- // `) - // } - // } + if (untrustedGithubAccounts.length > 0) { + summary = summary.addHeading( + '🚨 Requests to untrusted GitHub accounts found', + 3 + ).addRaw(` + > [!CAUTION] + > If you do not recognize these GitHub Accounts, you may want to investigate further. Add them to your trusted GitHub accounts if this is expected. See [Docs](https://github.com/koalalab-inc/bolt?tab=readme-ov-file#configure) for more information. + `) + + for (const account of untrustedGithubAccounts) { + summary = summary.addRaw(` +
+ + ${account.name} + + +
+ `) + } + } summary = summary.addRaw(auditSummaryRaw) diff --git a/src/summary_utils.js b/src/summary_utils.js index 4e5cd72..e8a67e6 100644 --- a/src/summary_utils.js +++ b/src/summary_utils.js @@ -27,6 +27,30 @@ async function generateTestResults(filePath) { } } +function getGithubCalls(githubCallsFilename) { + try { + const githubCallsFileContent = fs.readFileSync(githubCallsFilename, 'utf-8') + const lines = githubCallsFileContent.split('\n') + + const githubCalls = [] + + for (const line of lines) { + if (line.length === 0) continue + try { + const githubCall = JSON.parse(line) + githubCalls.push(githubCall) + } catch (error) { + console.error(`Error parsing JSON on line: ${line}`) + } + } + + return githubCalls + } catch (error) { + console.error(`Error reading file: ${error.message}`) + return [] + } +} + function getUniqueBy(arr, keys) { const uniqueObj = arr.reduce((unique, o) => { const key = keys.map(k => o[k]).join('|') @@ -49,6 +73,7 @@ function getRawCollapsible({ body, header }) { module.exports = { generateTestResults, + getGithubCalls, getUniqueBy, getRawCollapsible } diff --git a/src/version.js b/src/version.js index 30b8ea9..8800e62 100644 --- a/src/version.js +++ b/src/version.js @@ -1,4 +1,4 @@ -const releaseVersion = 'v1.6.2' +const releaseVersion = 'v1.7.0-rc' module.exports = { releaseVersion