From 3941c3ef1cbdbe72807532f81e96275bf8bb5e3f Mon Sep 17 00:00:00 2001 From: Murilo Dal Ri Date: Tue, 28 Nov 2023 13:38:01 +0000 Subject: [PATCH] wip --- .github/workflows/afternoon_seal.yml | 19 +++++++++-- .github/workflows/ci_checks.yml | 49 ++++++++++++++++++++++++++++ ignored_ci_repos.yml | 13 ++++++++ lib/github_fetcher.rb | 21 ++++++++++++ lib/message_builder.rb | 18 ++++++++++ lib/seal.rb | 2 ++ lib/slack_poster.rb | 4 ++- templates/list_ci_issues.text.erb | 4 +++ 8 files changed, 127 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/ci_checks.yml create mode 100644 ignored_ci_repos.yml create mode 100644 templates/list_ci_issues.text.erb diff --git a/.github/workflows/afternoon_seal.yml b/.github/workflows/afternoon_seal.yml index 71c8e4ba..e25e13f3 100644 --- a/.github/workflows/afternoon_seal.yml +++ b/.github/workflows/afternoon_seal.yml @@ -7,6 +7,7 @@ on: env: SEAL_ORGANISATION: alphagov + GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} jobs: @@ -25,10 +26,24 @@ jobs: id: afternoon_seal run: | teams=( + ai-govuk + data-products + govuk-datagovuk govuk-developers - govuk-platform-security-reliability + govuk-frontenders + govuk-licensing + govuk-navigation-tech + govuk-platform-engineering + govuk-platform-security-reliability-team + govuk-publishing-access-and-permissions-team + govuk-publishing-experience-tech + govuk-publishing-mainstream-experience-tech + govuk-publishing-platform + govuk-search-improvement + tech-content-interactions-on-platform-govuk + user-experience-measurement-govuk-robot-invasion ) for team in ${teams[*]} ; do - ./bin/seal_runner.rb $team quotes + ./bin/seal_runner.rb $team ci done diff --git a/.github/workflows/ci_checks.yml b/.github/workflows/ci_checks.yml new file mode 100644 index 00000000..b24fed43 --- /dev/null +++ b/.github/workflows/ci_checks.yml @@ -0,0 +1,49 @@ +name: "CI Checks" + +on: + workflow_dispatch: {} + schedule: + - cron: '00 9 * * 1-5' # Runs at 9:00, Monday through Friday. + +env: + SEAL_ORGANISATION: alphagov + GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} + SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} + +jobs: + ci-checks: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup ruby + uses: ruby/setup-ruby@v1 + with: + bundler-cache: true + + - name: CI Checks + id: ci_checks + run: | + teams=( + ai-govuk + data-products + govuk-datagovuk + govuk-developers + govuk-frontenders + govuk-licensing + govuk-navigation-tech + govuk-platform-engineering + govuk-platform-security-reliability-team + govuk-publishing-access-and-permissions-team + govuk-publishing-experience-tech + govuk-publishing-mainstream-experience-tech + govuk-publishing-platform + govuk-search-improvement + tech-content-interactions-on-platform-govuk + user-experience-measurement-govuk-robot-invasion + ) + + for team in ${teams[*]} ; do + ./bin/seal_runner.rb $team ci + done diff --git a/ignored_ci_repos.yml b/ignored_ci_repos.yml new file mode 100644 index 00000000..323f93d0 --- /dev/null +++ b/ignored_ci_repos.yml @@ -0,0 +1,13 @@ +- govuk-rfcs +- bulk-merger +- govuk-paas-office-ip-router +- gem-release-alert +- govuk-aws +- govuk-aws-data +- govuk-load-testing +- seal +- govuk-pact-broker +- govuk-rota-announcer +- govuk-secrets +- govuk-user-reviewer +- govuk-docker diff --git a/lib/github_fetcher.rb b/lib/github_fetcher.rb index c14f113a..0320ad16 100644 --- a/lib/github_fetcher.rb +++ b/lib/github_fetcher.rb @@ -1,4 +1,5 @@ require "octokit" +require "yaml" require_relative "security_alert_handler" class GithubFetcher @@ -37,6 +38,10 @@ def pull_requests_from_github end end + def check_team_repos_ci + repos.each_with_object({}) { |repo, sca_sast_enabled| sca_sast_enabled[repo] = has_sas_sast_scans?(repo) } + end + def security_alerts_count @security_alert_handler&.security_alerts_count end @@ -141,4 +146,20 @@ def marked_ready_for_review_at(pull_request, repo) puts "Error fetching marked ready for review time for PR #{pull_request.html_url}: #{e.message}" nil end + + def ignored_ci_repos + YAML.load_file(File.join(File.dirname(__FILE__), "../ignored_ci_repos.yml")) + end + + def has_sas_sast_scans?(repo) + return true if ignored_ci_repos.include?(repo) + ci_file = Base64.decode64(github.contents("alphagov/#{repo}", path: ".github/workflows/ci.yml").content) + sca_string = "uses: alphagov/govuk-infrastructure/.github/workflows/dependency-review.yml@main" + sast_string = "uses: alphagov/govuk-infrastructure/.github/workflows/codeql-analysis.yml@main" + + ci_file.include?(sca_string) && ci_file.include?(sast_string) + rescue StandardError => e + puts "Error fetching CI file for repo #{repo}: #{e.message}" + true # if a CI file is not present assume no scans are needed + end end diff --git a/lib/message_builder.rb b/lib/message_builder.rb index 866c40e4..58a838d1 100644 --- a/lib/message_builder.rb +++ b/lib/message_builder.rb @@ -16,6 +16,8 @@ def build case @mode when :panda build_dependapanda_message + when :ci + build_ci_message else build_regular_message end @@ -57,6 +59,18 @@ def build_regular_message end end + def build_ci_message + Message.new(ci_message, mood: "robot_face") + end + + def ci_message + @repos = check_team_repos_ci.reject { |_,v| v }.keys + return nil if @repos.empty? + + template_file = TEMPLATE_DIR + "list_ci_issues.text.erb" + ERB.new(template_file.read, trim_mode: '-').result(binding).strip + end + def pr_date(pr) pr[:marked_ready_for_review_at] || pr[:created] end @@ -69,6 +83,10 @@ def pull_requests @pull_requests ||= github_fetcher.list_pull_requests end + def check_team_repos_ci + @check_team_repos_ci ||= github_fetcher.check_team_repos_ci + end + def old_pull_requests @old_pull_requests ||= pull_requests.select { |pr| rotten?(pr) } end diff --git a/lib/seal.rb b/lib/seal.rb index 88c36159..853965b9 100755 --- a/lib/seal.rb +++ b/lib/seal.rb @@ -28,6 +28,8 @@ def bark_at(team, mode: nil) Message.new(team.quotes.sample) if team.quotes_days.map(&:downcase).include?(Date.today.strftime("%A").downcase) when "dependapanda" MessageBuilder.new(team, :panda).build + when "ci" + MessageBuilder.new(team, :ci).build else MessageBuilder.new(team, :seal).build end diff --git a/lib/slack_poster.rb b/lib/slack_poster.rb index 66dd2567..7d0ab64f 100644 --- a/lib/slack_poster.rb +++ b/lib/slack_poster.rb @@ -57,6 +57,8 @@ def assign_poster_settings [":#{@season_symbol}seal_of_approval:", "#{@season_name}Seal of Approval"] when "angry" [":#{@season_symbol}angrier_seal:", "#{@season_name}Angry Seal"] + when "robot_face" + [":#{@season_symbol}robot_face:", "#{@season_name}Angry CI Robot"] when "tea" [":manatea:", "Tea Seal"] when "charter" @@ -100,6 +102,6 @@ def set_mood_from_team end def channel - @team_channel = "#bot-testing" if ENV["DEVELOPMENT"] + @team_channel = "#murilo-testing" end end diff --git a/templates/list_ci_issues.text.erb b/templates/list_ci_issues.text.erb new file mode 100644 index 00000000..772a06ed --- /dev/null +++ b/templates/list_ci_issues.text.erb @@ -0,0 +1,4 @@ +The following repos are missing <<%= "https://docs.publishing.service.gov.uk/manual/dependency-review.html" %>|<%= html_encode("SCA") %>> and <<%= "https://docs.publishing.service.gov.uk/manual/codeql.html" %>|<%= html_encode("SAST") %>> scans in their CI pipelines (.github/workflows/ci.yml): +<% @repos.each do |repo| -%> +<<%= "https://github.com/alphagov/#{repo}" %>|<%= html_encode(repo) %>> +<% end -%>