Skip to content

Commit

Permalink
Merge pull request #561 from alphagov/validate-repos
Browse files Browse the repository at this point in the history
Add govuk repo tags check
  • Loading branch information
MuriloDalRi authored Aug 20, 2024
2 parents 3a009c3 + e0fb1b6 commit 909ae79
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 909ae79

Please sign in to comment.