Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
MuriloDalRi committed Apr 10, 2024
1 parent 7c22110 commit 5a1ce8f
Show file tree
Hide file tree
Showing 12 changed files with 163 additions and 2 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/afternoon_seal_quotes.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,4 @@ jobs:
- name: Afternoon Seal Quotes
id: afternoon_seal_quotes
run: |
./bin/seal_runner.rb afternoon_seal_quotes
./bin/seal_runner.rb gems
28 changes: 28 additions & 0 deletions .github/workflows/gem_version_checker.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: "Gem Version Checker"

on:
workflow_dispatch: {}
schedule:
- cron: '00 13 * * 3' # Runs at 13:00 UTC, Every Wednesday.

env:
SEAL_ORGANISATION: alphagov
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}

jobs:
gem-version-checker:
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: Gem Version Checker
id: gem_version_checker
run: |
./bin/seal_runner.rb gems
File renamed without changes.
1 change: 1 addition & 0 deletions bin/seal_runner.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#!/usr/bin/env ruby

require_relative '../lib/gem_version_checker'
require_relative '../lib/seal'
require_relative '../lib/team_builder'

Expand Down
43 changes: 43 additions & 0 deletions lib/gem_version_checker.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
require "uri"
require "net/http"
require "json"
require_relative "slack_poster"

class GemVersionChecker
def print_version_discrepancies(gems)
gems.filter_map { |gem|
repo_name = gem["app_name"]
repo_url = gem["links"]["repo_url"]
rubygems_version = fetch_rubygems_version(repo_name)
if rubygems_version && change_is_significant?(repo_name, rubygems_version)
"<#{repo_url}|#{repo_name}> has unreleased changes since v#{rubygems_version}"
end
}.join("\n")
end

def fetch_rubygems_version(gem_name)
uri = URI("https://rubygems.org/api/v1/gems/#{gem_name}.json")
res = Net::HTTP.get_response(uri)

JSON.parse(res.body)["version"] if res.is_a?(Net::HTTPSuccess)
end

def files_changed_since_tag(repo, tag)
Dir.mktmpdir do |path|
Dir.chdir(path) do
if system("git clone --recursive --depth 1 --shallow-submodules --no-single-branch https://github.com/alphagov/#{repo}.git > /dev/null 2>&1")
Dir.chdir(repo) { `git diff --name-only #{tag}`.split("\n") }
else
puts "Warning: Failed to clone #{repo}"
[]
end
end
end
end

def change_is_significant?(repo_name, previous_version)
files_changed_since_tag(repo_name, "v#{previous_version}").any? do |path|
path.start_with?("app/", "lib/") || path == "CHANGELOG.md"
end
end
end
26 changes: 26 additions & 0 deletions lib/message_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ def build
build_dependapanda_message
when :ci
build_ci_message
when :gems
build_gems_message
else
build_regular_message
end
Expand Down Expand Up @@ -57,6 +59,30 @@ def build_ci_message
Message.new(ci_message, mood: "robot_face")
end

def build_gems_message
Message.new(gems_message, mood: "gem")
end

def gems_message
@message = all_govuk_gems.group_by { |gem| gem["team"] == team }.each do |team, gems|
GemVersionChecker.new.print_version_discrepancies(gems)
end

template_file = Pathname.new("#{TEMPLATE_DIR}/gem_alerts.text.erb")
ERB.new(template_file.read, trim_mode: "-").result(binding).strip
end

def all_govuk_gems
@all_govuk_gems ||= fetch_gems
end

def fetch_gems
res = Net::HTTP.get_response("https://docs.publishing.service.gov.uk/gems.json")
raise "HTTP request failed: #{res.code}" unless res.is_a?(Net::HTTPSuccess)

JSON.parse(res.body)
end

def ci_message
@repos = check_team_repos_ci.reject { |_, v| v }.keys
return nil if @repos.empty?
Expand Down
2 changes: 2 additions & 0 deletions lib/seal.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ def bark_at(team, mode: nil)
MessageBuilder.new(team, :ci).build if team.ci_checks
when "seal_prs"
MessageBuilder.new(team, :seal).build if team.seal_prs
when "gems"
MessageBuilder.new(team, :gems).build if team.gems
end

return if message.nil? || message.text.nil?
Expand Down
4 changes: 3 additions & 1 deletion lib/slack_poster.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ def assign_poster_settings
[":#{@season_symbol}angrier_seal:", "#{@season_name}Angry Seal"]
when "robot_face"
[":robot_face:", "Angry CI Robot"]
when "gem"
[":gem:", "Gem Release Robot"]
when "tea"
[":manatea:", "Tea Seal"]
when "charter"
Expand Down Expand Up @@ -103,6 +105,6 @@ def set_mood_from_team
end

def channel
@team_channel = "#bot-testing" if ENV["DEVELOPMENT"]
@team_channel = "#murilo-testing"
end
end
3 changes: 3 additions & 0 deletions lib/team.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ def initialize(
afternoon_seal_quotes: nil,
dependapanda: nil,
ci_checks: nil,
gems: nil,
compact: nil,
exclude_labels: nil,
exclude_titles: nil,
Expand All @@ -22,6 +23,7 @@ def initialize(
@afternoon_seal_quotes = (afternoon_seal_quotes.nil? ? false : afternoon_seal_quotes)
@dependapanda = (dependapanda.nil? ? false : dependapanda)
@ci_checks = (ci_checks.nil? ? false : ci_checks)
@gems = (gems.nil? ? false : gems)
@compact = (compact.nil? ? false : compact)
@quotes_days = quotes_days || []
@exclude_labels = exclude_labels || []
Expand All @@ -40,6 +42,7 @@ def initialize(
afternoon_seal_quotes
dependapanda
ci_checks
gems
compact
exclude_labels
exclude_titles
Expand Down
2 changes: 2 additions & 0 deletions lib/team_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ def build_all_teams
raise "#{team_name} is a GOV.UK team and shouldn't list repos in ./config/alphagov.yml"
end
team_config["ci_checks"] = is_govuk_team?(team_name)
team_config["gems"] = is_govuk_team?(team_name)
Team.new(**apply_env(team_config))
end
end
Expand All @@ -60,6 +61,7 @@ def apply_env(config)
afternoon_seal_quotes: env["AFTERNOON_SEAL_QUOTES"] == "true" || config["afternoon_seal_quotes"],
dependapanda: env["DEPENDAPANDA"] == "true" || config["dependapanda"],
ci_checks: env["CI_CHECKS"] == "true" || config["ci_checks"],
gems: env["GEMS"] == "true" || config["gems"],
compact: env["COMPACT"] == "true" || config["compact"],
exclude_labels: env["GITHUB_EXCLUDE_LABELS"]&.split(",") || config["exclude_labels"],
exclude_titles: env["GITHUB_EXCLUDE_TITLES"]&.split(",") || config["exclude_titles"],
Expand Down
53 changes: 53 additions & 0 deletions spec/gem_version_checker_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
require "./lib/gem_version_checker"

RSpec.describe GemVersionChecker do
subject(:gem_version_checker) { described_class.new }

let(:slack_poster) { instance_double(SlackPoster, send_request: nil) }

before do
allow(SlackPoster).to receive(:new).and_return(slack_poster)
end

it "fetches version number of a gem from rubygems" do
stub_rubygems_call("6.0.1")

expect(gem_version_checker.fetch_rubygems_version("example")).to eq("6.0.1")
end

it "detects when there are no files changed since the last release that are built into the gem" do
stub_devdocs_call
stub_rubygems_call("1.2.3")
stub_files_changed_since_tag(["README.md"])

expect { gem_version_checker.print_version_discrepancies }.to output("team: #platform-security-reliability-team\n").to_stdout
end

it "detects when there are files changed since the last release that are built into the gem" do
stub_devdocs_call
stub_rubygems_call("1.2.2")
stub_files_changed_since_tag(["lib/foo.rb"])

expect { gem_version_checker.print_version_discrepancies }.to output(
"team: #platform-security-reliability-team\n<https://example.com|example> has unreleased changes since v1.2.2\n",
).to_stdout
end

def stub_files_changed_since_tag(files)
allow(gem_version_checker).to receive(:files_changed_since_tag) do
files
end
end

def stub_rubygems_call(version)
repo = { "version": version }
stub_request(:get, "https://rubygems.org/api/v1/gems/example.json")
.to_return(status: 200, body: repo.to_json, headers: {})
end

def stub_devdocs_call
repo = [{ "app_name": "example", "team": "#platform-security-reliability-team", "links": { "repo_url": "https://example.com" } }]
stub_request(:get, "https://docs.publishing.service.gov.uk/gems.json")
.to_return(status: 200, body: repo.to_json, headers: {})
end
end
1 change: 1 addition & 0 deletions templates/gem_alerts.text.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<%= @message %>

0 comments on commit 5a1ce8f

Please sign in to comment.