Skip to content

Commit

Permalink
feat: Add hub-settings tool to sync settings from yaml to github.
Browse files Browse the repository at this point in the history
  • Loading branch information
iphydf committed Jan 2, 2024
1 parent 15b1544 commit db9dc2c
Show file tree
Hide file tree
Showing 11 changed files with 333 additions and 2 deletions.
4 changes: 4 additions & 0 deletions BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ haskell_library(
"//third_party/haskell:QuickCheck",
"//third_party/haskell:aeson",
"//third_party/haskell:base",
"//third_party/haskell:casing",
"//third_party/haskell:generic-arbitrary",
"//third_party/haskell:quickcheck-text",
"//third_party/haskell:text",
],
Expand Down Expand Up @@ -64,6 +66,7 @@ haskell_library(
"//third_party/haskell:aeson",
"//third_party/haskell:base",
"//third_party/haskell:bytestring",
"//third_party/haskell:casing",
"//third_party/haskell:containers",
"//third_party/haskell:cryptohash",
"//third_party/haskell:directory",
Expand All @@ -83,6 +86,7 @@ haskell_library(
"//third_party/haskell:unordered-containers",
"//third_party/haskell:uuid",
"//third_party/haskell:vector",
"//third_party/haskell:yaml",
],
)

Expand Down
159 changes: 159 additions & 0 deletions admin/settings.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
_common:
editRepo: &editRepo
private: false
has_issues: true
has_projects: false
has_wiki: false
default_branch: "master"
delete_branch_on_merge: true
is_template: false
allow_squash_merge: true
allow_merge_commit: false
allow_rebase_merge: false
archived: false
security_and_analysis:
secret_scanning:
status: "enabled"
secret_scanning_push_protection:
status: "enabled"

branchProtection: &branchProtection
enforce_admins: true
required_pull_request_reviews:
require_code_owner_reviews: true
required_signatures: true
restrictions:
users: []
teams: ["reviewers"]
required_linear_history: true
allow_force_pushes: false
allow_deletions: false
block_creations: true
required_conversation_resolution: true
lock_branch: false

c-toxcore:
editRepo:
<<: *editRepo
name: "c-toxcore"
description: "The future of online communications."
homepage: "https://tox.chat"

branches:
"master":
<<: *branchProtection
required_status_checks:
strict: true
contexts:
- "CodeFactor"
- "Hound"
- "Mergeable"
- "Milestone Check"
- "WIP"
- "bazel-dbg"
- "bazel-opt"
- "build-android"
- "build-macos"
- "ci/circleci: asan"
- "ci/circleci: bazel-asan"
- "ci/circleci: bazel-msan"
- "ci/circleci: bazel-tsan"
- "ci/circleci: clang-analyze"
- "ci/circleci: cpplint"
- "ci/circleci: infer"
- "ci/circleci: static-analysis"
- "ci/circleci: tsan"
- "ci/circleci: ubsan"
- "cimple"
- "cimplefmt"
- "code-review/reviewable"
- "common / buildifier"
- "coverage-linux"
- "docker-bootstrap-node"
- "docker-bootstrap-node-websocket"
- "docker-clusterfuzz"
- "docker-esp32"
- "docker-fuzzer"
- "docker-toxcore-js"
- "docker-win32"
- "docker-win64"
- "freebsd"
- "mypy"
- "program-analysis"
- "restyled"
- "sonar-scan"

experimental:
editRepo:
<<: *editRepo
name: "experimental"
description: "Experimental - Anyone can submit anything in here"
homepage: "https://toktok.ltd"

branches:
"master":
<<: *branchProtection
required_status_checks:
strict: true
contexts:
- "Mergeable"
- "Milestone Check"
- "WIP"
- "code-review/reviewable"
- "Hound"

js-toxcore-c:
editRepo:
<<: *editRepo
name: "js-toxcore-c"
description: "Node bindings for toxcore"
homepage: "https://toktok.ltd"

branches:
"master":
<<: *branchProtection
required_status_checks:
strict: true
contexts:
- "Mergeable"
- "Milestone Check"
- "WIP"
- "code-review/reviewable"
- "Hound"
- "DeepScan"
- "build (12.x)"
- "build (13.x)"
- "docker"
- "CodeQL"
- "codecov/patch"
- "codecov/project"
- "restyled"
- "security/snyk (TokTok)"

toktok-stack:
editRepo:
<<: *editRepo
name: "toktok-stack"
description: "A snapshot of the complete software stack (excluding some external libraries and programs)"
homepage: "https://toktok.ltd"

branches:
"master":
<<: *branchProtection
required_status_checks:
strict: true
contexts:
- "Analyze (go)"
- "Analyze (python)"
- "CodeQL"
- "Hound"
- "Mergeable"
- "Milestone Check"
- "WIP"
- "code-review/reviewable"
- "common / buildifier"
- "docker-haskell"
- "docker-test"
- "hie-bios"
- "mypy"
- "restyled"
3 changes: 3 additions & 0 deletions github-tools.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -128,10 +128,12 @@ library
aeson >=2
, base >=4 && <5
, bytestring
, casing
, containers
, cryptohash
, directory
, exceptions
, generic-arbitrary
, github >=0.25 && <0.29
, html
, http-client >=0.4.30
Expand All @@ -148,6 +150,7 @@ library
, unordered-containers
, uuid
, vector
, yaml

executable hub-automerge
main-is: hub-automerge.hs
Expand Down
2 changes: 2 additions & 0 deletions spec/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/*.json
/*.yaml
12 changes: 12 additions & 0 deletions src/GitHub/Paths/Repos.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE OverloadedStrings #-}
module GitHub.Paths.Repos where

import Data.Aeson (Value, encode)
import Data.Text (Text)
import GitHub.Data.Request (CommandMethod (Patch), RW (..), Request,
command)

editRepoR :: Text -> Text -> Value -> Request 'RW Value
editRepoR user repo =
command Patch ["repos", user, repo] . encode
12 changes: 12 additions & 0 deletions src/GitHub/Paths/Repos/Branches.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE OverloadedStrings #-}
module GitHub.Paths.Repos.Branches where

import Data.Aeson (Value, encode)
import Data.Text (Text)
import GitHub.Data.Request (CommandMethod (Put), RW (..), Request,
command)

addProtectionR :: Text -> Text -> Text -> Value -> Request 'RW Value
addProtectionR user repo branch =
command Put ["repos", user, repo, "branches", branch, "protection"] . encode
27 changes: 26 additions & 1 deletion src/GitHub/Tools/Requests.hs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,23 @@
module GitHub.Tools.Requests where

import Control.Monad.Catch (throwM)
import Data.Aeson (FromJSON)
import Data.Aeson (FromJSON, ToJSON (toJSON),
Value (Array, Null, Object))
import qualified Data.Aeson.KeyMap as KeyMap
import qualified Data.Vector as V
import qualified GitHub
import Network.HTTP.Client (Manager)

removeNulls :: ToJSON a => a -> Value
removeNulls = go . toJSON
where
go (Array x) = Array . V.map go $ x
go (Object x) = Object . KeyMap.map go . KeyMap.filter (not . isEmpty) $ x
go x = x

isEmpty Null = True
isEmpty (Array x) = null x
isEmpty _ = False

request
:: FromJSON a
Expand All @@ -24,3 +37,15 @@ request auth mgr req = do
case auth of
Nothing -> GitHub.executeRequestWithMgr' mgr req
Just tk -> GitHub.executeRequestWithMgr mgr tk req

mutate
:: FromJSON a
=> GitHub.Auth
-> Manager
-> GitHub.Request 'GitHub.RW a
-> IO a
mutate auth mgr req = do
response <- GitHub.executeRequestWithMgr mgr auth req
case response of
Left err -> throwM err
Right res -> return res
46 changes: 46 additions & 0 deletions src/GitHub/Tools/Settings.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE TemplateHaskell #-}
module GitHub.Tools.Settings
( syncSettings
) where

import Control.Monad (forM_)
import Data.Aeson.TH (Options (fieldLabelModifier),
defaultOptions, deriveJSON)
import qualified Data.ByteString.Char8 as BS
import Data.HashMap.Strict (HashMap)
import qualified Data.HashMap.Strict as HashMap
import Data.Text (Text)
import qualified Data.Text as Text
import Data.Yaml (Value, encode)
import qualified GitHub
import qualified GitHub.Paths.Repos as Repos
import qualified GitHub.Paths.Repos.Branches as Branches
import GitHub.Tools.Requests (mutate)
import Network.HTTP.Client (newManager)
import Network.HTTP.Client.TLS (tlsManagerSettings)
import Text.Casing (camel)

data Settings = Settings
{ settingsEditRepo :: Value
, settingsBranches :: Maybe (HashMap Text Value)
}
$(deriveJSON defaultOptions{fieldLabelModifier = camel . drop (Text.length "Settings")} ''Settings)

syncSettings
:: GitHub.Auth
-> HashMap Text Settings
-> IO ()
syncSettings auth repos = do
-- Initialise HTTP manager so we can benefit from keep-alive connections.
mgr <- newManager tlsManagerSettings

forM_ (each repos) $ \(repo, Settings{..}) -> do
editRes <- mutate auth mgr (Repos.editRepoR "TokTok" repo settingsEditRepo)
BS.putStrLn $ encode editRes
forM_ (maybe [] each settingsBranches) $ \(branch, update) -> do
protRes <- mutate auth mgr (Branches.addProtectionR "TokTok" repo branch update)
BS.putStrLn $ encode protRes
where
each = HashMap.toList . HashMap.filterWithKey (\k _ -> not $ "_" `Text.isPrefixOf` k)
44 changes: 44 additions & 0 deletions src/GitHub/Types/Base/EditRepo.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE Strict #-}
{-# LANGUAGE TemplateHaskell #-}
module GitHub.Types.Base.EditRepo where

import Data.Aeson.TH (Options (fieldLabelModifier),
defaultOptions, deriveJSON)
import GHC.Generics (Generic)
import Test.QuickCheck.Arbitrary (Arbitrary (..))
import Test.QuickCheck.Arbitrary.Generic (genericArbitrary)
import Text.Casing (quietSnake)

------------------------------------------------------------------------------
-- EditRepo

data EditRepo = EditRepo
{ editRepoArchived :: Maybe Bool
, editRepoHasProjects :: Maybe Bool
, editRepoDeleteBranchOnMerge :: Maybe Bool
, editRepoIsTemplate :: Maybe Bool
, editRepoAllowSquashMerge :: Maybe Bool
, editRepoHasWiki :: Maybe Bool
, editRepoAllowForking :: Maybe Bool
, editRepoSquashMergeCommitMessage :: Maybe String
, editRepoAllowMergeCommit :: Maybe Bool
, editRepoWebCommitSignoffRequired :: Maybe Bool
, editRepoUseSquashPrTitleAsDefault :: Maybe Bool
, editRepoDescription :: Maybe String
, editRepoSquashMergeCommitTitle :: Maybe String
, editRepoMergeCommitMessage :: Maybe String
, editRepoAllowUpdateBranch :: Maybe Bool
, editRepoPrivate :: Maybe Bool
, editRepoName :: Maybe String
, editRepoMergeCommitTitle :: Maybe String
, editRepoAllowRebaseMerge :: Maybe Bool
, editRepoHasIssues :: Maybe Bool
, editRepoHomepage :: Maybe String
, editRepoDefaultBranch :: Maybe String
, editRepoVisibility :: Maybe String
} deriving (Eq, Generic)
$(deriveJSON defaultOptions{fieldLabelModifier = quietSnake . drop (length "EditRepo")} ''EditRepo)

instance Arbitrary EditRepo where
arbitrary = genericArbitrary
4 changes: 3 additions & 1 deletion tools/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ load("@rules_haskell//haskell:defs.bzl", "haskell_binary")
"//third_party/haskell:base",
"//third_party/haskell:bytestring",
"//third_party/haskell:github",
"//third_party/haskell:groom",
"//third_party/haskell:text",
"//third_party/haskell:yaml",
],
) for file in glob(["*.hs"])]
) for file in glob(["hub-*.hs"])]
Loading

0 comments on commit db9dc2c

Please sign in to comment.