From aaebcb41fb04f6fed68645ed614edc8820206533 Mon Sep 17 00:00:00 2001 From: Andrea Brancaleoni Date: Fri, 7 Jun 2024 10:57:01 +0200 Subject: [PATCH 1/7] workflow add-maintainer-custom-property: extrude --- .../add-maintainer-custom-property.yml | 37 +++-------------- .../add-mantainer-custom-property/action.cjs | 21 ++++++++++ .../add-mantainer-custom-property/action.yml | 40 +++++++++++++++++++ 3 files changed, 66 insertions(+), 32 deletions(-) create mode 100644 actions/add-mantainer-custom-property/action.cjs create mode 100644 actions/add-mantainer-custom-property/action.yml diff --git a/.github/workflows/add-maintainer-custom-property.yml b/.github/workflows/add-maintainer-custom-property.yml index 668ac412..c3624dbd 100644 --- a/.github/workflows/add-maintainer-custom-property.yml +++ b/.github/workflows/add-maintainer-custom-property.yml @@ -9,36 +9,9 @@ jobs: run: runs-on: ubuntu-latest steps: - - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 - - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + - uses: brave/security-action/actions/add-maintainer-custom-property@main with: - node-version: '20.x' - - id: npm - run: cd ${{ github.workspace }}; npm ci - shell: bash - - name: run - id: run - uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 - env: - IGNORE_MAINTAINERS: brave-builds,brave-browser-releases,brave-support-admin - DEBUG: false - with: - github-token: ${{ secrets.CUSTOM_PROPERTY_MANAGER_GITHUB_TOKEN }} - script: | - console.log('${{ github.workspace }}/src/addMaintainerCustomProperty.js'); - const { default: addMaintainerCustomProperty } = await import('${{ github.workspace }}/src/addMaintainerCustomProperty.js'); - return await addMaintainerCustomProperty({ - org: process.env.GITHUB_REPOSITORY_OWNER, - github: github, - ignoreMaintainers: process.env.IGNORE_MAINTAINERS, - debug: process.env.DEBUG - }); - - uses: actions-ecosystem/action-slack-notifier@fc778468d09c43a6f4d1b8cccaca59766656996a # v1.1.0 - if: ${{ fromJson(steps.run.outputs.result) != '' }} - with: - slack_token: ${{ secrets.HOTSPOTS_SLACK_TOKEN }} - message: | - [add-maintainer-custom-property] ${{ fromJson(steps.run.outputs.result) }} - channel: secops-hotspots - color: yellow - verbose: false + ignore_maintainers: brave-builds,brave-browser-releases,brave-support-admin + debug: false + github_token: ${{ secrets.CUSTOM_PROPERTY_MANAGER_GITHUB_TOKEN }} + slack_token: ${{ secrets.HOTSPOTS_SLACK_TOKEN }} \ No newline at end of file diff --git a/actions/add-mantainer-custom-property/action.cjs b/actions/add-mantainer-custom-property/action.cjs new file mode 100644 index 00000000..fb807800 --- /dev/null +++ b/actions/add-mantainer-custom-property/action.cjs @@ -0,0 +1,21 @@ +module.exports = async ({ github, context, inputs, actionPath, core, debug = false }) => { + const { default: addMaintainerCustomProperty } = await import(`${actionPath}/src/addMaintainerCustomProperty.js`) + const { default: sendSlackMessage } = await import(`${actionPath}/src/sendSlackMessage.js`) + + const reposWithoutMaintainer = await addMaintainerCustomProperty({ + org: context.repo.owner, + github, + ignoreMaintainers: inputs.ignore_maintainers, + debug + }) + + if (reposWithoutMaintainer.trim().length > 0) { + await sendSlackMessage({ + token: inputs.slack_token, + message: `[add-maintainer-custom-property] ${reposWithoutMaintainer}`, + channel: '#secops-hotspots', + color: 'yellow', + username: 'add-maintainer-custom-property' + }) + } +} diff --git a/actions/add-mantainer-custom-property/action.yml b/actions/add-mantainer-custom-property/action.yml new file mode 100644 index 00000000..8ed40043 --- /dev/null +++ b/actions/add-mantainer-custom-property/action.yml @@ -0,0 +1,40 @@ +# action that add maintainer as a custom property +# to all repositories in this organization +name: add-maintainer-custom-property +description: Add Maintainer as Custom Property to Repositories +inputs: + github_token: + description: 'GitHub Token' + required: true + slack_token: + description: 'Slack Token' + required: true + ignore_maintainers: + description: 'Comma separated list of maintainers to ignore' + default: brave-builds,brave-browser-releases,brave-support-admin + debug: + description: 'Debug mode' + required: false +runs: + using: 'composite' + steps: + - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + with: + node-version: '20.x' + - id: npm + run: cd ${{ github.action_path }}/../..; npm ci + shell: bash + - name: run + id: run + uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 + env: + DEBUG: ${{ (inputs.debug == 'true' || runner.debug) && 'true' || 'false'}} + with: + github-token: ${{ inputs.github_token }} + script: | + const actionPath = '${{ github.action_path }}/../../' + const inputs = ${{ toJson(inputs) }} + + const script = require('${{ github.action_path }}/action.cjs') + await script({github, context, inputs, actionPath, core, + debug: process.env.DEBUG === 'true'}) From bb91ec0e4c92385daf7f93afdc5022d8b2f56a94 Mon Sep 17 00:00:00 2001 From: Andrea Brancaleoni Date: Fri, 7 Jun 2024 11:08:44 +0200 Subject: [PATCH 2/7] workflow check-new-repos: extrude --- .github/workflows/check-new-repos.yml | 53 ++------------------------- actions/check-new-repos/action.cjs | 48 ++++++++++++++++++++++++ actions/check-new-repos/action.yml | 35 ++++++++++++++++++ 3 files changed, 87 insertions(+), 49 deletions(-) create mode 100644 actions/check-new-repos/action.cjs create mode 100644 actions/check-new-repos/action.yml diff --git a/.github/workflows/check-new-repos.yml b/.github/workflows/check-new-repos.yml index 0b3f8937..5ab0876d 100644 --- a/.github/workflows/check-new-repos.yml +++ b/.github/workflows/check-new-repos.yml @@ -8,54 +8,9 @@ jobs: build: runs-on: ubuntu-latest steps: - - name: Check New Repos - id: check-new-repos - uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 - with: - github-token: ${{ secrets.GH_PAT }} - script: | - var query = `query ($owner: String!) { - repositoryOwner(login: $owner) { - repositories(last: 100) { - totalCount - nodes { - name - createdAt - } - } - } - }`; - const variables = { - owner: context.repo.owner - } - const result = await github.graphql(query, variables); - const totalCount = result.repositoryOwner.repositories.totalCount; - - // DEBUG: console.log("totalCount: %s", totalCount); - const repositories = result.repositoryOwner.repositories; - const yesterday = ((d) => d.setDate(d.getDate() - 1))(new Date()); - var newerThanADay = repositories.nodes.filter( - repo => new Date(repo.createdAt) > yesterday - ); - // DEBUG: console.log("NewerThanADay: %o", newerThanADay); - var message = ""; - if (newerThanADay.length > 0) { - message += `${newerThanADay.length} new repos in ${variables.owner}:\n\n`; - for (let i = 0; i < newerThanADay.length; i++) { - message += `- ${newerThanADay[i].name}\n`; - } - message += `\nTotal repositories in ${variables.owner}: ${totalCount}`; - - core.setSecret(message); - } - - return message; - - uses: actions-ecosystem/action-slack-notifier@fc778468d09c43a6f4d1b8cccaca59766656996a # v1.1.0 - if: ${{ fromJson(steps.check-new-repos.outputs.result) != '' }} + - name: check new repos + uses: brave/security-action/actions/check-new-repos@main with: + github_token: ${{ secrets.GH_PAT }} slack_token: ${{ secrets.HOTSPOTS_SLACK_TOKEN }} - message: | - [check-new-repos] ${{ fromJson(steps.check-new-repos.outputs.result) }} - channel: secops-hotspots - color: yellow - verbose: false + debug: false \ No newline at end of file diff --git a/actions/check-new-repos/action.cjs b/actions/check-new-repos/action.cjs new file mode 100644 index 00000000..c6c47538 --- /dev/null +++ b/actions/check-new-repos/action.cjs @@ -0,0 +1,48 @@ +module.exports = async ({ github, context, inputs, actionPath, core, debug = false }) => { + const { default: sendSlackMessage } = await import(`${actionPath}/src/sendSlackMessage.js`) + + const query = `query ($owner: String!) { + repositoryOwner(login: $owner) { + repositories(last: 100) { + totalCount + nodes { + name + createdAt + } + } + } + }` + const variables = { + owner: context.repo.owner + } + const result = await github.graphql(query, variables) + const totalCount = result.repositoryOwner.repositories.totalCount + + // DEBUG: console.log("totalCount: %s", totalCount) + const repositories = result.repositoryOwner.repositories + const yesterday = ((d) => d.setDate(d.getDate() - 1))(new Date()) + const newerThanADay = repositories.nodes.filter( + repo => new Date(repo.createdAt) > yesterday + ) + // DEBUG: console.log("NewerThanADay: %o", newerThanADay); + let message = '' + if (newerThanADay.length > 0) { + message += `${newerThanADay.length} new repos in ${variables.owner}:\n\n` + for (let i = 0; i < newerThanADay.length; i++) { + message += `- ${newerThanADay[i].name}\n` + } + message += `\nTotal repositories in ${variables.owner}: ${totalCount}` + + core.setSecret(message) + } + + if (message.trim().length > 0) { + await sendSlackMessage({ + token: inputs.slack_token, + message: `[check-new-repos] ${message}`, + channel: '#secops-hotspots', + color: 'yellow', + username: 'check-new-repos' + }) + } +} diff --git a/actions/check-new-repos/action.yml b/actions/check-new-repos/action.yml new file mode 100644 index 00000000..fb983709 --- /dev/null +++ b/actions/check-new-repos/action.yml @@ -0,0 +1,35 @@ +name: check-new-repositories +description: Check New Repositories +inputs: + github_token: + description: 'GitHub Token' + required: true + slack_token: + description: 'Slack Token' + required: true + debug: + description: 'Debug mode' + required: false +runs: + using: 'composite' + steps: + - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + with: + node-version: '20.x' + - id: npm + run: cd ${{ github.action_path }}/../..; npm ci + shell: bash + - name: Check New Repos + id: check-new-repos + uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 + env: + DEBUG: ${{ (inputs.debug == 'true' || runner.debug) && 'true' || 'false'}} + with: + github-token: ${{ inputs.github_token }} + script: | + const actionPath = '${{ github.action_path }}/../../' + const inputs = ${{ toJson(inputs) }} + + const script = require('${{ github.action_path }}/action.cjs') + await script({github, context, inputs, actionPath, core, + debug: process.env.DEBUG === 'true'}) From d70d41c7ee79d63f4588d682e996c441ee5efd95 Mon Sep 17 00:00:00 2001 From: Andrea Brancaleoni Date: Fri, 7 Jun 2024 11:24:54 +0200 Subject: [PATCH 3/7] workflow dependabot-auto-dismiss: extrude --- .github/workflows/dependabot-auto-dismiss.yml | 25 +++----------- actions/dependabot-auto-dismiss/action.cjs | 6 ++++ actions/dependabot-auto-dismiss/action.yml | 34 +++++++++++++++++++ .../dependabot-auto-dismiss/dismiss.txt | 0 4 files changed, 45 insertions(+), 20 deletions(-) create mode 100644 actions/dependabot-auto-dismiss/action.cjs create mode 100644 actions/dependabot-auto-dismiss/action.yml rename .github/dependabot-dismiss.txt => actions/dependabot-auto-dismiss/dismiss.txt (100%) diff --git a/.github/workflows/dependabot-auto-dismiss.yml b/.github/workflows/dependabot-auto-dismiss.yml index 60580adf..e001d4e9 100644 --- a/.github/workflows/dependabot-auto-dismiss.yml +++ b/.github/workflows/dependabot-auto-dismiss.yml @@ -8,24 +8,9 @@ jobs: run: runs-on: ubuntu-latest steps: - - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 - - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + - name: dependabot auto dismiss + uses: brave/security-action/actions/dependabot-auto-dismiss@main with: - node-version: '20.x' - - id: npm - run: cd ${{ github.workspace }}; npm ci - shell: bash - - uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 - env: - SLACK_TOKEN: ${{ secrets.HOTSPOTS_SLACK_TOKEN }} - SLACK_CHANNEL: '#secops-hotspots' - DEBUG: false - with: - github-token: ${{ secrets.DEPENDABOT_AUTO_DISMISS_GITHUB_TOKEN }} - script: | - const debug = process.env.DEBUG === 'true'; - const { default: sendSlackMessage } = await import('${{ github.workspace }}/src/sendSlackMessage.js'); - const { default: dependabotDismiss } = await import('${{ github.workspace }}/src/dependabotDismiss.js'); - const message = await dependabotDismiss({debug, org: process.env.GITHUB_REPOSITORY_OWNER, github: github, dependabotDismissConfig: '${{ github.workspace }}/.github/dependabot-dismiss.txt'}); - if (message.length > 0) - await sendSlackMessage({debug, username: 'dependabot-auto-dismiss', message: message, channel: process.env.SLACK_CHANNEL, token: process.env.SLACK_TOKEN}); + github_token: ${{ secrets.DEPENDABOT_AUTO_DISMISS_GITHUB_TOKEN }} + slack_token: ${{ secrets.HOTSPOTS_SLACK_TOKEN }} + debug: false \ No newline at end of file diff --git a/actions/dependabot-auto-dismiss/action.cjs b/actions/dependabot-auto-dismiss/action.cjs new file mode 100644 index 00000000..8852f986 --- /dev/null +++ b/actions/dependabot-auto-dismiss/action.cjs @@ -0,0 +1,6 @@ +module.exports = async ({ github, context, inputs, actionPath, core, debug = false }) => { + const { default: sendSlackMessage } = await import(`${actionPath}/src/sendSlackMessage.js`) + const { default: dependabotDismiss } = await import(`${actionPath}/src/dependabotDismiss.js`) + const message = await dependabotDismiss({ debug, org: context.repo.owner, github, dependabotDismissConfig: `${actionPath}/actions/dependabot-auto-dismiss/dismiss.txt` }) + if (message.length > 0) { await sendSlackMessage({ debug, username: 'dependabot-auto-dismiss', message, channel: '#secops-hotspots', token: inputs.slack_token }) } +} diff --git a/actions/dependabot-auto-dismiss/action.yml b/actions/dependabot-auto-dismiss/action.yml new file mode 100644 index 00000000..57b76b3f --- /dev/null +++ b/actions/dependabot-auto-dismiss/action.yml @@ -0,0 +1,34 @@ +name: weekly-dependabot-auto-dismiss +description: Weekly Dependabot Auto Dismiss +inputs: + github_token: + description: 'GitHub Token' + required: true + slack_token: + description: 'Slack Token' + required: true + debug: + description: 'Debug mode' + required: false +runs: + using: 'composite' + steps: + - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 + - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + with: + node-version: '20.x' + - id: npm + run: cd ${{ github.action_path }}/../..; npm ci + shell: bash + - uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 + env: + DEBUG: ${{ (inputs.debug == 'true' || runner.debug) && 'true' || 'false'}} + with: + github-token: ${{ inputs.github_token }} + script: | + const actionPath = '${{ github.action_path }}/../../' + const inputs = ${{ toJson(inputs) }} + + const script = require('${{ github.action_path }}/action.cjs') + await script({github, context, inputs, actionPath, core, + debug: process.env.DEBUG === 'true'}) \ No newline at end of file diff --git a/.github/dependabot-dismiss.txt b/actions/dependabot-auto-dismiss/dismiss.txt similarity index 100% rename from .github/dependabot-dismiss.txt rename to actions/dependabot-auto-dismiss/dismiss.txt From 2575a928e353d98409be38e5b98d91672ebca3cf Mon Sep 17 00:00:00 2001 From: Andrea Brancaleoni Date: Fri, 7 Jun 2024 14:18:28 +0200 Subject: [PATCH 4/7] workflow dependabot-nudge: extrude --- .github/workflows/dependabot-nudge.yml | 51 +++----------------------- actions/dependabot-nudge/action.cjs | 29 +++++++++++++++ actions/dependabot-nudge/action.yml | 36 ++++++++++++++++++ 3 files changed, 71 insertions(+), 45 deletions(-) create mode 100644 actions/dependabot-nudge/action.cjs create mode 100644 actions/dependabot-nudge/action.yml diff --git a/.github/workflows/dependabot-nudge.yml b/.github/workflows/dependabot-nudge.yml index dc05200b..23469a68 100644 --- a/.github/workflows/dependabot-nudge.yml +++ b/.github/workflows/dependabot-nudge.yml @@ -8,49 +8,10 @@ jobs: run: runs-on: ubuntu-latest steps: - - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 - - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + - name: dependabot nudge + uses: brave/security-action/actions/dependabot-nudge@main with: - node-version: '20.x' - - id: npm - run: cd ${{ github.workspace }}; npm ci - shell: bash - - uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 - env: - SLACK_TOKEN: ${{ secrets.HOTSPOTS_SLACK_TOKEN }} - SLACK_CHANNEL: '#secops-hotspots' - GH_TO_SLACK_USER_MAP: ${{ secrets.GH_TO_SLACK_USER_MAP }} - DEBUG: false - with: - github-token: ${{ secrets.DEPENDABOT_NUDGE_GITHUB_TOKEN }} - script: | - const debug = process.env.DEBUG === 'true'; - const { default: sendSlackMessage } = await import('${{ github.workspace }}/src/sendSlackMessage.js'); - const { default: dependabotNudge } = await import('${{ github.workspace }}/src/dependabotNudge.js'); - - let githubToSlack = {}; - try { - githubToSlack = JSON.parse(process.env.GH_TO_SLACK_USER_MAP); - } catch (e) { - if (debug) console.log('GH_TO_SLACK_USER_MAP is not valid JSON'); - } - - // set minlevel to 'medium' if it's the first Monday of the month, otherwise stick to high or critical issues - let minlevel = 'medium'; - const today = new Date(); - if (today.getDate() > 7) { - if (debug) - console.log('Not the first Monday of the month!'); - minlevel = 'high'; - } - - const messages = await dependabotNudge({debug, org: process.env.GITHUB_REPOSITORY_OWNER, github: github, minlevel: minlevel, githubToSlack: githubToSlack}); - - for (const message of messages) { - try { - await sendSlackMessage({debug, username: 'dependabot', message: message, channel: process.env.SLACK_CHANNEL, token: process.env.SLACK_TOKEN}); - } catch (error) { - if (debug) - console.log(error); - } - } + github_token: ${{ secrets.DEPENDABOT_NUDGE_GITHUB_TOKEN }} + slack_token: ${{ secrets.HOTSPOTS_SLACK_TOKEN }} + gh_to_slack_user_map: ${{ secrets.GH_TO_SLACK_USER_MAP }} + debug: false \ No newline at end of file diff --git a/actions/dependabot-nudge/action.cjs b/actions/dependabot-nudge/action.cjs new file mode 100644 index 00000000..979180c9 --- /dev/null +++ b/actions/dependabot-nudge/action.cjs @@ -0,0 +1,29 @@ +module.exports = async ({ github, context, inputs, actionPath, core, debug = false }) => { + const { default: sendSlackMessage } = await import(`${actionPath}/src/sendSlackMessage.js`) + const { default: dependabotNudge } = await import(`${actionPath}/src/dependabotNudge.js`) + + let githubToSlack = {} + try { + githubToSlack = JSON.parse(inputs.gh_to_slack_user_map) + } catch (e) { + if (debug) console.log('GH_TO_SLACK_USER_MAP is not valid JSON') + } + + // set minlevel to 'medium' if it's the first Monday of the month, otherwise stick to high or critical issues + let minlevel = 'medium' + const today = new Date() + if (today.getDate() > 7) { + if (debug) { console.log('Not the first Monday of the month!') } + minlevel = 'high' + } + + const messages = await dependabotNudge({ debug, org: context.repo.owner, github, minlevel, githubToSlack }) + + for (const message of messages) { + try { + await sendSlackMessage({ debug, username: 'dependabot', message, channel: '#secops-hotspots', token: inputs.slack_token }) + } catch (error) { + if (debug) { console.log(error) } + } + } +} diff --git a/actions/dependabot-nudge/action.yml b/actions/dependabot-nudge/action.yml new file mode 100644 index 00000000..d1e1b7d2 --- /dev/null +++ b/actions/dependabot-nudge/action.yml @@ -0,0 +1,36 @@ +name: weekly-dependabot-nudge +description: Weekly Dependabot Nudge +inputs: + github_token: + description: 'GitHub Token' + required: true + slack_token: + description: 'Slack Token' + required: true + gh_to_slack_user_map: + description: 'JSON map of github usernames to slack usernames' + required: false + debug: + description: 'Debug mode' + required: false +runs: + using: 'composite' + steps: + - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + with: + node-version: '20.x' + - id: npm + run: cd ${{ github.action_path }}/../..; npm ci + shell: bash + - uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 + env: + DEBUG: ${{ (inputs.debug == 'true' || runner.debug) && 'true' || 'false'}} + with: + github-token: ${{ inputs.github_token }} + script: |- + const actionPath = '${{ github.action_path }}/../../' + const inputs = ${{ toJson(inputs) }} + + const script = require('${{ github.action_path }}/action.cjs') + await script({github, context, inputs, actionPath, core, + debug: process.env.DEBUG === 'true'}) From bbf1429f7c550c4d3f599aafb61225656b001d36 Mon Sep 17 00:00:00 2001 From: Andrea Brancaleoni Date: Fri, 7 Jun 2024 14:33:08 +0200 Subject: [PATCH 5/7] workflow older-than-2y: extrude --- .github/workflows/older-than-2y.yml | 55 +++-------------------------- actions/older-than-2y/action.cjs | 42 ++++++++++++++++++++++ actions/older-than-2y/action.yml | 35 ++++++++++++++++++ 3 files changed, 81 insertions(+), 51 deletions(-) create mode 100644 actions/older-than-2y/action.cjs create mode 100644 actions/older-than-2y/action.yml diff --git a/.github/workflows/older-than-2y.yml b/.github/workflows/older-than-2y.yml index 6a8885d5..106042de 100644 --- a/.github/workflows/older-than-2y.yml +++ b/.github/workflows/older-than-2y.yml @@ -8,56 +8,9 @@ jobs: build: runs-on: ubuntu-latest steps: - - name: Older Than 2 Years Informer - id: older-than-2y - uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 - with: - github-token: ${{ secrets.GH_PAT }} - script: | - const org = process.env.GITHUB_REPOSITORY_OWNER; - - function formatInMessage(r) { - var pushedAt = new Date(r.pushed_at); - return `- ${r.private ? 'šŸ˜Ž ' : ''} ${r.full_name} ${r.html_url}\tšŸŒŸ ${r.stargazers_count}šŸ“${r.forks} - Last pushed ${pushedAt.getFullYear()}/${pushedAt.getMonth()}/${pushedAt.getDay()+1}\n` - } - - const v = await github.paginate('GET /orgs/{org}/repos', { - org: org, - headers: { - 'X-GitHub-Api-Version': '2022-11-28' - } - }) - const maxOlderDate = ((d) => d.setDate(d.getDate() - 2*365))(new Date()); // 2 years - const reposOlderThanDate = v.filter(r => r.archived === false).filter(r => r.disabled === false).filter(r => new Date(r.pushed_at) < maxOlderDate) - const forks = reposOlderThanDate.filter(r => r.fork === true) - const nonForks = reposOlderThanDate.filter(r => r.fork === false) - // console.log(reposOlderThanDate[0]) // DEBUG - - if (reposOlderThanDate.length == 0) return ""; - - var message = `${org} has ${reposOlderThanDate.length} outdated repositories.\nConsider archiving them.` - - if (nonForks.length !== 0) message += "\n\nRepositories:\n" - for (var i = 0; i < nonForks.length; i++) { - var r = nonForks[i] - message += formatInMessage(r) - } - - if (forks.length !== 0) message += "\n\nForks:\n" - for (var i = 0; i < forks.length; i++) { - var r = forks[i] - message += formatInMessage(r) - } - - core.setSecret(message); - - return message; - - uses: actions-ecosystem/action-slack-notifier@fc778468d09c43a6f4d1b8cccaca59766656996a # v1.1.0 - if: ${{ fromJson(steps.older-than-2y.outputs.result) != '' }} + - name: older than 2 years informer + uses: brave/security-action/actions/older-than-2y@main with: + github_token: ${{ secrets.GH_PAT }} slack_token: ${{ secrets.HOTSPOTS_SLACK_TOKEN }} - message: | - [older-than-2y] ${{ fromJson(steps.older-than-2y.outputs.result) }} - channel: secops-hotspots - color: blue - verbose: false + debug: false \ No newline at end of file diff --git a/actions/older-than-2y/action.cjs b/actions/older-than-2y/action.cjs new file mode 100644 index 00000000..6cbc7dc7 --- /dev/null +++ b/actions/older-than-2y/action.cjs @@ -0,0 +1,42 @@ +function formatInMessage (r) { + const pushedAt = new Date(r.pushed_at) + return `- ${r.private ? 'šŸ˜Ž ' : ''} ${r.full_name} ${r.html_url}\tšŸŒŸ ${r.stargazers_count}šŸ“${r.forks} - Last pushed ${pushedAt.getFullYear()}/${pushedAt.getMonth()}/${pushedAt.getDay() + 1}\n` +} + +module.exports = async ({ github, context, inputs, actionPath, core, debug = false }) => { + const { default: sendSlackMessage } = await import(`${actionPath}/src/sendSlackMessage.js`) + + const org = context.repo.owner + + const v = await github.paginate('GET /orgs/{org}/repos', { + org, + headers: { + 'X-GitHub-Api-Version': '2022-11-28' + } + }) + const maxOlderDate = ((d) => d.setDate(d.getDate() - 2 * 365))(new Date()) // 2 years + const reposOlderThanDate = v.filter(r => r.archived === false).filter(r => r.disabled === false).filter(r => new Date(r.pushed_at) < maxOlderDate) + const forks = reposOlderThanDate.filter(r => r.fork === true) + const nonForks = reposOlderThanDate.filter(r => r.fork === false) + // console.log(reposOlderThanDate[0]) // DEBUG + + if (reposOlderThanDate.length === 0) return '' + + let message = `${org} has ${reposOlderThanDate.length} outdated repositories.\nConsider archiving them.` + + if (nonForks.length !== 0) message += '\n\nRepositories:\n' + for (let i = 0; i < nonForks.length; i++) { + const r = nonForks[i] + message += formatInMessage(r) + } + + if (forks.length !== 0) message += '\n\nForks:\n' + for (let i = 0; i < forks.length; i++) { + const r = forks[i] + message += formatInMessage(r) + } + + core.setSecret(message) + + if (message.length > 0) { await sendSlackMessage({ debug, username: 'older-than-2y', message: `[older-than-2y] ${message}`, color: 'blue', channel: '#security-hotspots', token: inputs.slack_token }) } +} diff --git a/actions/older-than-2y/action.yml b/actions/older-than-2y/action.yml new file mode 100644 index 00000000..16215b37 --- /dev/null +++ b/actions/older-than-2y/action.yml @@ -0,0 +1,35 @@ +name: older-than-2y +description: Older Than 2 Years Informer +inputs: + github_token: + description: 'GitHub Token' + required: true + slack_token: + description: 'Slack Token' + required: true + debug: + description: 'Debug mode' + required: false +runs: + using: 'composite' + steps: + - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + with: + node-version: '20.x' + - id: npm + run: cd ${{ github.action_path }}/../..; npm ci + shell: bash + - name: Older Than 2 Years Informer + id: older-than-2y + uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 + env: + DEBUG: ${{ (inputs.debug == 'true' || runner.debug) && 'true' || 'false'}} + with: + github-token: ${{ inputs.github_token }} + script: | + const actionPath = '${{ github.action_path }}/../../' + const inputs = ${{ toJson(inputs) }} + + const script = require('${{ github.action_path }}/action.cjs') + await script({github, context, inputs, actionPath, core, + debug: process.env.DEBUG === 'true'}) From 7bd4f3807b878b6128f7adf19495c9b14fe0b52c Mon Sep 17 00:00:00 2001 From: Andrea Brancaleoni Date: Fri, 7 Jun 2024 14:51:40 +0200 Subject: [PATCH 6/7] workflow renovate-sanity-check: extrude --- .github/workflows/renovate-sanity-check.yml | 33 +++--------------- actions/renovate-sanity-check/action.cjs | 13 ++++++++ actions/renovate-sanity-check/action.yml | 37 +++++++++++++++++++++ 3 files changed, 54 insertions(+), 29 deletions(-) create mode 100644 actions/renovate-sanity-check/action.cjs create mode 100644 actions/renovate-sanity-check/action.yml diff --git a/.github/workflows/renovate-sanity-check.yml b/.github/workflows/renovate-sanity-check.yml index e46f5df1..1bb30762 100644 --- a/.github/workflows/renovate-sanity-check.yml +++ b/.github/workflows/renovate-sanity-check.yml @@ -9,34 +9,9 @@ jobs: run: runs-on: ubuntu-latest steps: - - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 - - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 - with: - node-version: '20.x' - - id: npm - run: cd ${{ github.workspace }}; npm ci - shell: bash - - name: run - id: run - uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 - env: - DEBUG: false - with: - github-token: ${{ secrets.CUSTOM_PROPERTY_MANAGER_GITHUB_TOKEN }} - script: | - console.log('${{ github.workspace }}/src/renovateSanityCheck.js'); - const { default: renovateSanityCheck } = await import('${{ github.workspace }}/src/renovateSanityCheck.js'); - return await renovateSanityCheck({ - org: process.env.GITHUB_REPOSITORY_OWNER, - github: github, - debug: process.env.DEBUG - }); - - uses: actions-ecosystem/action-slack-notifier@fc778468d09c43a6f4d1b8cccaca59766656996a # v1.1.0 - if: ${{ fromJson(steps.run.outputs.result) != '' }} + - name: Renovate Sanity Check + uses: brave/security-action/actions/renovate-sanity-check@main with: + github_token: ${{ secrets.CUSTOM_PROPERTY_MANAGER_GITHUB_TOKEN }} slack_token: ${{ secrets.HOTSPOTS_SLACK_TOKEN }} - message: | - [renovate-sanity-check] ${{ fromJson(steps.run.outputs.result) }} - channel: secops-hotspots - color: yellow - verbose: false + debug: false \ No newline at end of file diff --git a/actions/renovate-sanity-check/action.cjs b/actions/renovate-sanity-check/action.cjs new file mode 100644 index 00000000..438f81b3 --- /dev/null +++ b/actions/renovate-sanity-check/action.cjs @@ -0,0 +1,13 @@ +module.exports = async ({ github, context, inputs, actionPath, core, debug = false }) => { + console.log(`${actionPath}/src/renovateSanityCheck.js`) + const { default: renovateSanityCheck } = await import(`${actionPath}/src/renovateSanityCheck.js`) + const { default: sendSlackMessage } = await import(`${actionPath}/src/sendSlackMessage.js`) + + const message = await renovateSanityCheck({ + org: context.repo.owner, + github, + debug + }) + + if (message.length > 0) { await sendSlackMessage({ debug, username: 'renovate-sanity-check', message: `[renovate-sanity-check] ${message}`, color: 'yellow', channel: '#security-action', token: inputs.slack_token }) } +} diff --git a/actions/renovate-sanity-check/action.yml b/actions/renovate-sanity-check/action.yml new file mode 100644 index 00000000..4b0d8c06 --- /dev/null +++ b/actions/renovate-sanity-check/action.yml @@ -0,0 +1,37 @@ +# action that runs monthly and check if all repositories in the organization are following the renovate central configuration +# to all repositories in this organization +name: renovate-sanity-check +description: Renovate Sanity Check +inputs: + github_token: + description: 'GitHub token' + required: true + slack_token: + description: 'Slack token' + required: true + debug: + description: 'Debug mode' + default: "false" +runs: + using: 'composite' + steps: + - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + with: + node-version: '20.x' + - id: npm + run: cd ${{ github.action_path }}/../..; npm ci + shell: bash + - name: run + id: run + uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 + env: + DEBUG: ${{ (inputs.debug == 'true' || runner.debug) && 'true' || 'false'}} + with: + github-token: ${{ inputs.github_token }} + script: | + const actionPath = '${{ github.action_path }}/../../' + const inputs = ${{ toJson(inputs) }} + + const script = require('${{ github.action_path }}/action.cjs') + await script({github, context, inputs, actionPath, core, + debug: process.env.DEBUG === 'true'}) From d3850ebcdc4c976e9210f5d6acdcdd713f7c10be Mon Sep 17 00:00:00 2001 From: Andrea Brancaleoni Date: Fri, 7 Jun 2024 19:24:18 +0200 Subject: [PATCH 7/7] *: use ORG_READ_GITHUB_TOKEN instead of GH_PAT --- .github/workflows/check-new-repos.yml | 2 +- .github/workflows/older-than-2y.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/check-new-repos.yml b/.github/workflows/check-new-repos.yml index 5ab0876d..a526e0a8 100644 --- a/.github/workflows/check-new-repos.yml +++ b/.github/workflows/check-new-repos.yml @@ -11,6 +11,6 @@ jobs: - name: check new repos uses: brave/security-action/actions/check-new-repos@main with: - github_token: ${{ secrets.GH_PAT }} + github_token: ${{ secrets.ORG_READ_GITHUB_TOKEN }} slack_token: ${{ secrets.HOTSPOTS_SLACK_TOKEN }} debug: false \ No newline at end of file diff --git a/.github/workflows/older-than-2y.yml b/.github/workflows/older-than-2y.yml index 106042de..c712787a 100644 --- a/.github/workflows/older-than-2y.yml +++ b/.github/workflows/older-than-2y.yml @@ -11,6 +11,6 @@ jobs: - name: older than 2 years informer uses: brave/security-action/actions/older-than-2y@main with: - github_token: ${{ secrets.GH_PAT }} + github_token: ${{ secrets.ORG_READ_GITHUB_TOKEN }} slack_token: ${{ secrets.HOTSPOTS_SLACK_TOKEN }} debug: false \ No newline at end of file