Skip to content

Commit

Permalink
Add govuk repo tags check
Browse files Browse the repository at this point in the history
Checks wether repos have been tagged correctly.

This code was in the govuk-saas-config which is in the process of being retired.
  • Loading branch information
MuriloDalRi committed Aug 15, 2024
1 parent 3a009c3 commit e0fb1b6
Show file tree
Hide file tree
Showing 4 changed files with 198 additions and 0 deletions.
61 changes: 61 additions & 0 deletions .github/workflows/verify_repo_tags.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
name: "Verify Repo Tags"

on:
workflow_dispatch: {}
schedule:
- cron: '00 10 * * 1-5' # Runs at 10:00 UTC, Monday through Friday.

jobs:
verify-repo-tags:
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: Verify Repo Tags
id: verify_repo_tags
env:
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
run: |
EXIT_CODE=0
output=$(bundle exec rake verify_repo_tags) || EXIT_CODE=$?
echo "$output"
exit $EXIT_CODE
- name: Notify failure
uses: slackapi/slack-github-action@v1
if: ${{ failure() }}
with:
payload: |
{
"channel": "#govuk-platform-support",
"username": "Platform Alerts",
"text": "The <https://github.com/alphagov/govuk-developer-docs/blob/main/data/repos.yml|Developer Docs repo list> is out of sync with the repos tagged as 'govuk' in GitHub.",
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "The <https://github.com/alphagov/govuk-developer-docs/blob/main/data/repos.yml|Developer Docs repo list> is out of sync with the repos tagged as 'govuk' in GitHub."
},
"accessory": {
"type": "button",
"text": {
"type": "plain_text",
"text": "Check the build logs for details"
},
"url": "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}",
"action_id": "button-view-workflow"
}
}
]
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }}
20 changes: 20 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
require_relative "lib/validate_repos"

begin
require "rspec/core/rake_task"

Expand Down Expand Up @@ -25,6 +27,24 @@ rescue LoadError
# no rubocop available
end

desc "Verify that GOVUK repos are tagged #govuk"
task :verify_repo_tags do
validator = ValidateRepos.new

untagged_message = <<~UNTAGGED
The following repos in the repos.yml file in govuk-developer-docs do not have the govuk tag on GitHub:
UNTAGGED

falsely_tagged_message = <<~FALSETAG
The following repos have the govuk tag on GitHub but are not in the repos.yml file in govuk-developer-docs:
FALSETAG

puts "#{untagged_message}\n#{validator.untagged_repos}" unless validator.untagged_repos.empty?
puts "#{falsely_tagged_message}\n#{validator.falsely_tagged_repos}" unless validator.falsely_tagged_repos.empty?

exit 1 unless validator.untagged_repos.empty? && validator.falsely_tagged_repos.empty?
end

task default: %i[
jsonlint
rubocop
Expand Down
46 changes: 46 additions & 0 deletions lib/validate_repos.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
require "json"
require "octokit"
require "open-uri"
require "yaml"

class ValidateRepos
def initialize
Octokit.auto_paginate = true
@client = Octokit::Client.new(access_token: ENV.fetch("GITHUB_TOKEN"))
end

def github_repos_tagged_govuk
@github_repos_tagged_govuk ||= repos.map { |repo| repo["name"] }
end

def govuk_repo_names
@govuk_repo_names ||= JSON.parse(Net::HTTP.get_response(URI.parse("https://docs.publishing.service.gov.uk/repos.json")).body)
.map { |repo| repo["app_name"] }
.reject { |app| ignored_apps.include?(app) }
end

def untagged_repos
(govuk_repo_names - github_repos_tagged_govuk).join("\n")
end

def falsely_tagged_repos
(github_repos_tagged_govuk - govuk_repo_names).join("\n")
end

def repos
@client
.org_repos("alphagov", accept: "application/vnd.github.mercy-preview+json")
.select { |repo| repo.topics.to_a.include?("govuk") }
.reject(&:archived)
.reject { |repo| ignored_repos.include?(repo.full_name) }
.sort_by { |repo| repo[:full_name] }
end

def ignored_repos
["alphagov/licensify"] # Licensify consists of 3 apps in 1 repo
end

def ignored_apps
%w[licensify-backend]
end
end
71 changes: 71 additions & 0 deletions spec/validate_repos_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
require "spec_helper"
require_relative "../lib/validate_repos"

RSpec.describe ValidateRepos do
before do
@repo_mock = double("Repo", topics: %w[govuk], archived: false, full_name: "this-is-a-govuk-repo")
allow(@repo_mock).to receive(:[]).with("name").and_return("this-is-a-govuk-repo")
allow(@repo_mock).to receive(:[]).with(:full_name).and_return("this-is-a-govuk-repo")
allow(ENV).to receive(:fetch).with("GITHUB_TOKEN").and_return("dummy_token")
allow_any_instance_of(Octokit::Client).to receive(:org_repos).and_return([@repo_mock])
end

it "should ignore any repos that exist in repos.json AND are tagged govuk in GitHub" do
repos = [{
"app_name" => "this-is-a-govuk-repo",
}]

stub_repos_json(repos)

validator = ValidateRepos.new

expect(validator.untagged_repos).to eq("")
expect(validator.falsely_tagged_repos).to eq("")
end

it "doesn't say that a repo is missing the govuk tag if it has been added to the ignore list" do
app_name = "this-is-a-govuk-repo"
allow_any_instance_of(ValidateRepos).to receive(:ignored_repos).and_return(["alphagov/#{app_name}"])

repos = [{
"app_name" => app_name,
}]

stub_repos_json(repos)

validator = ValidateRepos.new

expect(validator.untagged_repos).to eq("")
expect(validator.falsely_tagged_repos).to eq("")
end

it "should alert if it finds an untagged repo in repos.json" do
repos = [
{ "app_name" => "this-is-a-govuk-repo" },
{ "app_name" => "this-govuk-repo-is-not-tagged!" },
]

stub_repos_json(repos)

validator = ValidateRepos.new

expect(validator.untagged_repos).to eq("this-govuk-repo-is-not-tagged!")
expect(validator.falsely_tagged_repos).to eq("")
end

it "should alert if it finds a repo that has falsely been tagged as govuk." do
repos = []

stub_repos_json(repos)

validator = ValidateRepos.new

expect(validator.falsely_tagged_repos).to eq("this-is-a-govuk-repo")
expect(validator.untagged_repos).to eq("")
end

def stub_repos_json(repos)
stub_request(:get, "https://docs.publishing.service.gov.uk/repos.json")
.to_return(status: 200, body: repos.to_json, headers: {})
end
end

0 comments on commit e0fb1b6

Please sign in to comment.