mirror of
https://github.com/roleypoly/roleypoly.git
synced 2025-04-24 19:39:11 +00:00
feat: add midori skeleton, bot scaffolding, CD seeds
This commit is contained in:
parent
7c861b37ca
commit
49d44df231
30 changed files with 854 additions and 123 deletions
10
.github/workflows/build.yml
vendored
10
.github/workflows/build.yml
vendored
|
@ -41,6 +41,16 @@ jobs:
|
|||
--stamp \
|
||||
--workspace_status_command hack/workspace_status.sh
|
||||
|
||||
- name: Write Artifact Manifest
|
||||
run: |
|
||||
bash hack/generate_versions.sh > manifest.json
|
||||
|
||||
- name: Upload Artifact Manifest
|
||||
uses: actions/upload-artifact
|
||||
with:
|
||||
name: manifest.json
|
||||
path: manifest.json
|
||||
|
||||
- name: Publish Dev Container Image
|
||||
if: github.ref == 'refs/heads/main'
|
||||
run: |
|
||||
|
|
27
.github/workflows/release.yml
vendored
Normal file
27
.github/workflows/release.yml
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
name: Release Workflow
|
||||
|
||||
on: workflow_dispatch
|
||||
|
||||
jobs:
|
||||
commit_release_tag:
|
||||
name: Commit Roleypoly Release Tag
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
with:
|
||||
ssh-key: ${{secrets.DEPLOY_KEY}}
|
||||
|
||||
# - name: Setup Git
|
||||
# uses: webfactory/ssh-agent@v0.2.0
|
||||
# with:
|
||||
# ssh-private-key: ${{ secrets.DEPLOY_KEY }}
|
||||
|
||||
- name: Push changes
|
||||
id: push
|
||||
run: |
|
||||
TAG=$(date +v%Y%m%d-%H%M%S)
|
||||
git config --local user.email "gh-automation@roleypoly.com"
|
||||
git config --local user.name "Roleypoly Release Automation"
|
||||
git tag $TAG
|
||||
git push origin $TAG
|
||||
echo "::set-output release_tag=${TAG}"
|
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -3,4 +3,5 @@ bazel-out
|
|||
bazel-roleypoly
|
||||
bazel-testlogs
|
||||
node_modules
|
||||
.env
|
||||
.env
|
||||
docker-compose.yaml
|
56
deps.bzl
56
deps.bzl
|
@ -103,6 +103,12 @@ def go_repositories():
|
|||
sum = "h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=",
|
||||
version = "v1.1.1",
|
||||
)
|
||||
go_repository(
|
||||
name = "com_github_dghubble_trie",
|
||||
importpath = "github.com/dghubble/trie",
|
||||
sum = "h1:euE/xPG0HIg6XiNXYrAHxX9aVwD1gw/yM2kptLOOj6k=",
|
||||
version = "v0.0.0-20200716043226-5a94efb202d5",
|
||||
)
|
||||
go_repository(
|
||||
name = "com_github_dgrijalva_jwt_go",
|
||||
importpath = "github.com/dgrijalva/jwt-go",
|
||||
|
@ -202,8 +208,8 @@ def go_repositories():
|
|||
go_repository(
|
||||
name = "com_github_golang_protobuf",
|
||||
importpath = "github.com/golang/protobuf",
|
||||
sum = "h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=",
|
||||
version = "v1.3.1",
|
||||
sum = "h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=",
|
||||
version = "v1.3.2",
|
||||
)
|
||||
go_repository(
|
||||
name = "com_github_google_btree",
|
||||
|
@ -217,6 +223,18 @@ def go_repositories():
|
|||
sum = "h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=",
|
||||
version = "v0.3.0",
|
||||
)
|
||||
go_repository(
|
||||
name = "com_github_google_go_github_v32",
|
||||
importpath = "github.com/google/go-github/v32",
|
||||
sum = "h1:GWkQOdXqviCPx7Q7Fj+KyPoGm4SwHRh8rheoPhd27II=",
|
||||
version = "v32.1.0",
|
||||
)
|
||||
go_repository(
|
||||
name = "com_github_google_go_querystring",
|
||||
importpath = "github.com/google/go-querystring",
|
||||
sum = "h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=",
|
||||
version = "v1.0.0",
|
||||
)
|
||||
go_repository(
|
||||
name = "com_github_google_gofuzz",
|
||||
importpath = "github.com/google/gofuzz",
|
||||
|
@ -409,12 +427,6 @@ def go_repositories():
|
|||
sum = "h1:F9x/1yl3T2AeKLr2AMdilSD8+f9bvMnNN8VS5iDtovc=",
|
||||
version = "v0.0.0-20161129095857-cc309e4a2223",
|
||||
)
|
||||
go_repository(
|
||||
name = "com_github_niemeyer_pretty",
|
||||
importpath = "github.com/niemeyer/pretty",
|
||||
sum = "h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=",
|
||||
version = "v0.0.0-20200227124842-a10e7caefd8e",
|
||||
)
|
||||
go_repository(
|
||||
name = "com_github_oklog_ulid",
|
||||
importpath = "github.com/oklog/ulid",
|
||||
|
@ -622,8 +634,8 @@ def go_repositories():
|
|||
go_repository(
|
||||
name = "in_gopkg_check_v1",
|
||||
importpath = "gopkg.in/check.v1",
|
||||
sum = "h1:QRR6H1YWRnHb4Y/HeNFCTJLFVxaq6wH4YuVdsUOr75U=",
|
||||
version = "v1.0.0-20200902074654-038fdea0a05b",
|
||||
sum = "h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=",
|
||||
version = "v1.0.0-20180628173108-788fd7840127",
|
||||
)
|
||||
go_repository(
|
||||
name = "in_gopkg_errgo_v2",
|
||||
|
@ -688,8 +700,8 @@ def go_repositories():
|
|||
go_repository(
|
||||
name = "org_golang_x_crypto",
|
||||
importpath = "golang.org/x/crypto",
|
||||
sum = "h1:vclmkQCjlDX5OydZ9wv8rBCcS0QyQY66Mpf/7BZbInM=",
|
||||
version = "v0.0.0-20200820211705-5c72a883971a",
|
||||
sum = "h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=",
|
||||
version = "v0.0.0-20200622213623-75b288015ac9",
|
||||
)
|
||||
go_repository(
|
||||
name = "org_golang_x_exp",
|
||||
|
@ -700,8 +712,8 @@ def go_repositories():
|
|||
go_repository(
|
||||
name = "org_golang_x_lint",
|
||||
importpath = "golang.org/x/lint",
|
||||
sum = "h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k=",
|
||||
version = "v0.0.0-20200302205851-738671d3881b",
|
||||
sum = "h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs=",
|
||||
version = "v0.0.0-20190930215403-16217165b5de",
|
||||
)
|
||||
go_repository(
|
||||
name = "org_golang_x_mod",
|
||||
|
@ -730,8 +742,8 @@ def go_repositories():
|
|||
go_repository(
|
||||
name = "org_golang_x_sys",
|
||||
importpath = "golang.org/x/sys",
|
||||
sum = "h1:L/IKR6COd7ubZrs2oTnTi73IhgqJ71c9s80WsQnh0Es=",
|
||||
version = "v0.0.0-20200923182605-d9f96fdee20d",
|
||||
sum = "h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=",
|
||||
version = "v0.0.0-20200323222414-85ca7c5b95cd",
|
||||
)
|
||||
go_repository(
|
||||
name = "org_golang_x_text",
|
||||
|
@ -748,8 +760,8 @@ def go_repositories():
|
|||
go_repository(
|
||||
name = "org_golang_x_tools",
|
||||
importpath = "golang.org/x/tools",
|
||||
sum = "h1:VUw1+Jf6KJPf82mbTQMia6HCnNMv2BbAipkEZ4KTcqQ=",
|
||||
version = "v0.0.0-20200923182640-463111b69878",
|
||||
sum = "h1:xLt+iB5ksWcZVxqc+g9K41ZHy+6MKWfXCDsjSThnsPA=",
|
||||
version = "v0.0.0-20200904185747-39188db58858",
|
||||
)
|
||||
go_repository(
|
||||
name = "org_golang_x_xerrors",
|
||||
|
@ -760,8 +772,8 @@ def go_repositories():
|
|||
go_repository(
|
||||
name = "org_uber_go_atomic",
|
||||
importpath = "go.uber.org/atomic",
|
||||
sum = "h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=",
|
||||
version = "v1.7.0",
|
||||
sum = "h1:OI5t8sDa1Or+q8AeE+yKeB/SDYioSHAgcVljj9JIETY=",
|
||||
version = "v1.5.0",
|
||||
)
|
||||
go_repository(
|
||||
name = "org_uber_go_dig",
|
||||
|
@ -784,8 +796,8 @@ def go_repositories():
|
|||
go_repository(
|
||||
name = "org_uber_go_multierr",
|
||||
importpath = "go.uber.org/multierr",
|
||||
sum = "h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=",
|
||||
version = "v1.6.0",
|
||||
sum = "h1:f3WCSC2KzAcBXGATIxAB1E2XuCpNU255wNKZ505qi3E=",
|
||||
version = "v1.4.0",
|
||||
)
|
||||
go_repository(
|
||||
name = "org_uber_go_tools",
|
||||
|
|
10
go.mod
10
go.mod
|
@ -4,18 +4,14 @@ go 1.15
|
|||
|
||||
require (
|
||||
github.com/bwmarrin/discordgo v0.22.0
|
||||
github.com/dghubble/trie v0.0.0-20200716043226-5a94efb202d5
|
||||
github.com/facebook/ent v0.4.3
|
||||
github.com/google/go-github/v32 v32.1.0
|
||||
github.com/joho/godotenv v1.3.0
|
||||
github.com/julienschmidt/httprouter v1.3.0
|
||||
github.com/lampjaw/discordclient v0.0.0-20200923011548-6558fc9e89df
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
|
||||
github.com/segmentio/ksuid v1.0.3
|
||||
go.uber.org/fx v1.13.1
|
||||
go.uber.org/multierr v1.6.0 // indirect
|
||||
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a // indirect
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect
|
||||
golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d // indirect
|
||||
golang.org/x/tools v0.0.0-20200923182640-463111b69878 // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b // indirect
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be
|
||||
k8s.io/klog v1.0.0
|
||||
)
|
||||
|
|
44
go.sum
44
go.sum
|
@ -19,10 +19,11 @@ github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee
|
|||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dghubble/trie v0.0.0-20200716043226-5a94efb202d5 h1:euE/xPG0HIg6XiNXYrAHxX9aVwD1gw/yM2kptLOOj6k=
|
||||
github.com/dghubble/trie v0.0.0-20200716043226-5a94efb202d5/go.mod h1:xNBeoT4V92/aNvuC3IJ2g59uxuKP4/kzvkpoHrb7v4A=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||
github.com/facebook/ent v0.4.3 h1:ds9HENceKzpGBgCRlkZNq6TqBIegwKcF3e5reuV9Z0M=
|
||||
|
@ -47,14 +48,19 @@ github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4er
|
|||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY=
|
||||
github.com/google/go-github/v32 v32.1.0 h1:GWkQOdXqviCPx7Q7Fj+KyPoGm4SwHRh8rheoPhd27II=
|
||||
github.com/google/go-github/v32 v32.1.0/go.mod h1:rIEpZD9CTDQwDK9GDrtMTycQNA4JU3qBsCizh3q2WCI=
|
||||
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
|
||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
|
||||
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
|
||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
|
@ -68,7 +74,6 @@ github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc=
|
|||
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
|
||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/julienschmidt/httprouter v1.2.0 h1:TDTW5Yz1mjftljbcKqRcrYhd4XeOoI98t+9HbQbYf7g=
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U=
|
||||
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
|
||||
|
@ -77,13 +82,13 @@ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL
|
|||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/lampjaw/discordclient v0.0.0-20200923011548-6558fc9e89df h1:Y2o9fEOoAYjCw8IDyxUVaBq44AUbOLyPnYSPpM6Ef3M=
|
||||
github.com/lampjaw/discordclient v0.0.0-20200923011548-6558fc9e89df/go.mod h1:lOfqvGl1HcXws86Sczusw1DyV5d0KHPtTTtdjneekto=
|
||||
github.com/lib/pq v1.8.0 h1:9xohqzkUwzR4Ga4ivdTcawVS89YSDVxXMa3xJX3cGzg=
|
||||
github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
|
@ -99,8 +104,6 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ
|
|||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||
github.com/olekukonko/tablewriter v0.0.4 h1:vHD/YYe1Wolo78koG299f7V/VAS08c6IpCLn+Ejf/w8=
|
||||
github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA=
|
||||
|
@ -154,8 +157,6 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
|||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.5.0 h1:OI5t8sDa1Or+q8AeE+yKeB/SDYioSHAgcVljj9JIETY=
|
||||
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
|
||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/dig v1.10.0 h1:yLmDDj9/zuDjv3gz8GQGviXMs9TfysIUMUilCpgzUJY=
|
||||
go.uber.org/dig v1.10.0/go.mod h1:X34SnWGr8Fyla9zQNO2GSO2D+TIuqB14OS8JhYocIyw=
|
||||
go.uber.org/fx v1.13.1 h1:CFNTr1oin5OJ0VCZ8EycL3wzF29Jz2g0xe55RFsf2a4=
|
||||
|
@ -165,34 +166,24 @@ go.uber.org/goleak v0.10.0/go.mod h1:VCZuO8V8mFPlL0F5J5GK1rtHV3DrFcQ1R8ryq7FK0aI
|
|||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/multierr v1.4.0 h1:f3WCSC2KzAcBXGATIxAB1E2XuCpNU255wNKZ505qi3E=
|
||||
go.uber.org/multierr v1.4.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
|
||||
go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
|
||||
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
||||
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4=
|
||||
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
|
||||
go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM=
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16 h1:y6ce7gCWtnH+m3dCjzQ1PCuwl28DDIc3VNnvY29DlIA=
|
||||
golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a h1:vclmkQCjlDX5OydZ9wv8rBCcS0QyQY66Mpf/7BZbInM=
|
||||
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190409202823-959b441ac422 h1:QzoH/1pFpZguR8NrRHLcO6jKqfv2zpuSqZLgdm7ZmjI=
|
||||
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
|
@ -200,12 +191,13 @@ golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73r
|
|||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
|
@ -217,14 +209,11 @@ golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5h
|
|||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d h1:L/IKR6COd7ubZrs2oTnTi73IhgqJ71c9s80WsQnh0Es=
|
||||
golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
|
@ -240,11 +229,8 @@ golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtn
|
|||
golang.org/x/tools v0.0.0-20191030062658-86caa796c7ab/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191114200427-caa0b0f7d508/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200904185747-39188db58858 h1:xLt+iB5ksWcZVxqc+g9K41ZHy+6MKWfXCDsjSThnsPA=
|
||||
golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
|
||||
golang.org/x/tools v0.0.0-20200923182640-463111b69878 h1:VUw1+Jf6KJPf82mbTQMia6HCnNMv2BbAipkEZ4KTcqQ=
|
||||
golang.org/x/tools v0.0.0-20200923182640-463111b69878/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
|
@ -257,11 +243,9 @@ google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZi
|
|||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b h1:QRR6H1YWRnHb4Y/HeNFCTJLFVxaq6wH4YuVdsUOr75U=
|
||||
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||
|
|
25
hack/generate_versions.sh
Normal file
25
hack/generate_versions.sh
Normal file
|
@ -0,0 +1,25 @@
|
|||
#!/bin/bash
|
||||
|
||||
artifacts=$(bazel query //src/... 2>/dev/null | grep +publish)
|
||||
publishedServices=${artifacts//$'//src/'/}
|
||||
publishedServices=${publishedServices//$':+publish'/}
|
||||
|
||||
artifactList=$'{ "services": {} }'
|
||||
|
||||
getSha() {
|
||||
service=$1
|
||||
cat ./bazel-bin/src/$service/+publish.digest
|
||||
}
|
||||
|
||||
addShaToServiceList() {
|
||||
service=$1
|
||||
shaSum=$2
|
||||
artifactList=$(echo $artifactList | jq ".services+={\"${service}\":\"${shaSum}\"}")
|
||||
}
|
||||
|
||||
for service in $publishedServices; do
|
||||
shaSum=$(getSha $service)
|
||||
addShaToServiceList $service $shaSum
|
||||
done
|
||||
|
||||
echo $artifactList | jq
|
21
src/common/BUILD.bazel
Normal file
21
src/common/BUILD.bazel
Normal file
|
@ -0,0 +1,21 @@
|
|||
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
|
||||
|
||||
go_library(
|
||||
name = "common",
|
||||
srcs = [
|
||||
"await-exit.go",
|
||||
"envconfig.go",
|
||||
"finders.go",
|
||||
],
|
||||
importpath = "github.com/roleypoly/roleypoly/src/common",
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "common_test",
|
||||
srcs = [
|
||||
"envconfig_test.go",
|
||||
"finders_test.go",
|
||||
],
|
||||
embed = [":common"],
|
||||
)
|
19
src/common/await-exit.go
Normal file
19
src/common/await-exit.go
Normal file
|
@ -0,0 +1,19 @@
|
|||
package common
|
||||
|
||||
import (
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func AwaitExit() {
|
||||
syscallExit := make(chan os.Signal, 1)
|
||||
signal.Notify(
|
||||
syscallExit,
|
||||
syscall.SIGINT,
|
||||
syscall.SIGTERM,
|
||||
os.Interrupt,
|
||||
os.Kill,
|
||||
)
|
||||
<-syscallExit
|
||||
}
|
18
src/common/bot/BUILD.bazel
Normal file
18
src/common/bot/BUILD.bazel
Normal file
|
@ -0,0 +1,18 @@
|
|||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "bot",
|
||||
srcs = [
|
||||
"commandmux.go",
|
||||
"scaffolding.go",
|
||||
],
|
||||
importpath = "github.com/roleypoly/roleypoly/src/common/bot",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//src/common",
|
||||
"@com_github_bwmarrin_discordgo//:discordgo",
|
||||
"@com_github_dghubble_trie//:trie",
|
||||
"@com_github_lampjaw_discordclient//:discordclient",
|
||||
"@io_k8s_klog//:klog",
|
||||
],
|
||||
)
|
87
src/common/bot/commandmux.go
Normal file
87
src/common/bot/commandmux.go
Normal file
|
@ -0,0 +1,87 @@
|
|||
package bot
|
||||
|
||||
import (
|
||||
"context"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/dghubble/trie"
|
||||
"github.com/lampjaw/discordclient"
|
||||
"k8s.io/klog"
|
||||
)
|
||||
|
||||
type CommandMux struct {
|
||||
commandTrie *trie.PathTrie
|
||||
matcher *regexp.Regexp
|
||||
}
|
||||
|
||||
func NewCommandMux(matcher *regexp.Regexp) CommandMux {
|
||||
return CommandMux{
|
||||
commandTrie: trie.NewPathTrie(),
|
||||
matcher: matcher,
|
||||
}
|
||||
}
|
||||
|
||||
type CommandGroup []Command
|
||||
|
||||
func (cg CommandGroup) RegisterCommands(commandTrie *trie.PathTrie, prefix string) {
|
||||
for _, command := range cg {
|
||||
commandTrie.Put(prefix+"/"+command.CommandName, command.Handler)
|
||||
}
|
||||
}
|
||||
|
||||
type Command struct {
|
||||
CommandName string
|
||||
Handler HandlerFunc
|
||||
}
|
||||
|
||||
func (c CommandMux) RegisterCommandGroup(prefix string, group CommandGroup) {
|
||||
group.RegisterCommands(c.commandTrie, prefix)
|
||||
}
|
||||
|
||||
func (c CommandMux) Handler(ctx context.Context, message discordclient.Message) {
|
||||
if !c.matches(message) {
|
||||
return
|
||||
}
|
||||
|
||||
key := c.commandKeyFromMessage(message)
|
||||
|
||||
command := c.commandTrie.Get(key)
|
||||
if command == nil {
|
||||
return
|
||||
}
|
||||
|
||||
handlerFn, ok := command.(HandlerFunc)
|
||||
if !ok {
|
||||
klog.Warning("CommandMux.Handler: " + key + " handler was not HandlerFunc")
|
||||
return
|
||||
}
|
||||
|
||||
c.logCommandRun(key, message)
|
||||
handlerFn(ctx, message)
|
||||
}
|
||||
|
||||
func (c CommandMux) commandKeyFromMessage(message discordclient.Message) string {
|
||||
commandParts := strings.Split(message.RawMessage(), " ")[1:]
|
||||
return commandParts[0] + "/" + commandParts[1]
|
||||
}
|
||||
|
||||
func (c CommandMux) matches(message discordclient.Message) bool {
|
||||
return c.matcher.MatchString(message.RawMessage())
|
||||
}
|
||||
|
||||
func (c CommandMux) logCommandRun(key string, message discordclient.Message) {
|
||||
klog.Info("CommandMux: " + key + " by " + message.UserName() + " <@" + message.UserID() + ">")
|
||||
}
|
||||
|
||||
func PrefixMatcher(prefix string) *regexp.Regexp {
|
||||
return regexp.MustCompile(`^` + prefix)
|
||||
}
|
||||
|
||||
func MentionMatcher(userID string) *regexp.Regexp {
|
||||
return regexp.MustCompile(`<@!?` + userID + ">")
|
||||
}
|
||||
|
||||
func Tokenize(message discordclient.Message) []string {
|
||||
return strings.SplitAfterN(message.RawMessage(), " ", 3)
|
||||
}
|
101
src/common/bot/scaffolding.go
Normal file
101
src/common/bot/scaffolding.go
Normal file
|
@ -0,0 +1,101 @@
|
|||
package bot
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/bwmarrin/discordgo"
|
||||
"github.com/lampjaw/discordclient"
|
||||
"github.com/roleypoly/roleypoly/src/common"
|
||||
)
|
||||
|
||||
type HandlerFunc func(context.Context, discordclient.Message)
|
||||
|
||||
type BotScaffolding struct {
|
||||
BotToken string
|
||||
BotClientID string
|
||||
RootUsers []string
|
||||
AllowBots bool
|
||||
AllowEdits bool
|
||||
AllowDeletes bool
|
||||
GatewayIntents discordgo.Intent
|
||||
Handler HandlerFunc
|
||||
}
|
||||
|
||||
type Listener struct {
|
||||
DiscordClient *discordclient.DiscordClient
|
||||
config *BotScaffolding
|
||||
handler HandlerFunc
|
||||
}
|
||||
|
||||
type ctxKey string
|
||||
|
||||
var ListenerCtxKey ctxKey = "listener"
|
||||
var MessageCtxKey ctxKey = "message"
|
||||
|
||||
func ScaffoldBot(config BotScaffolding) error {
|
||||
discordClient := discordclient.NewDiscordClient(config.BotToken, config.RootUsers[0], config.BotClientID)
|
||||
discordClient.GatewayIntents = config.GatewayIntents
|
||||
discordClient.AllowBots = config.AllowBots
|
||||
|
||||
messageChannel, err := discordClient.Listen(-1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer common.AwaitExit()
|
||||
|
||||
listener := &Listener{
|
||||
config: &config,
|
||||
DiscordClient: discordClient,
|
||||
handler: config.Handler,
|
||||
}
|
||||
|
||||
go listener.processMessages(messageChannel)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l *Listener) processMessages(messageChannel <-chan discordclient.Message) {
|
||||
listenerCtx := context.WithValue(context.Background(), ListenerCtxKey, l)
|
||||
for {
|
||||
message := <-messageChannel
|
||||
|
||||
if !l.config.AllowEdits && message.Type() == discordclient.MessageTypeUpdate {
|
||||
continue
|
||||
}
|
||||
|
||||
if !l.config.AllowDeletes && message.Type() == discordclient.MessageTypeDelete {
|
||||
continue
|
||||
}
|
||||
|
||||
localCtx := context.WithValue(listenerCtx, MessageCtxKey, message)
|
||||
go l.handler(localCtx, message)
|
||||
}
|
||||
}
|
||||
|
||||
// ReplyToMessage will use the message context to reply to a message.
|
||||
// Message may be one of two types:
|
||||
// - *discordgo.MessageSend
|
||||
// - string
|
||||
func ReplyToMessage(listenerCtx context.Context, message interface{}) error {
|
||||
l := listenerCtx.Value(ListenerCtxKey).(*Listener)
|
||||
m := listenerCtx.Value(MessageCtxKey).(discordclient.Message)
|
||||
channelID := m.Channel()
|
||||
|
||||
switch message.(type) {
|
||||
case *discordgo.MessageSend:
|
||||
_, err := l.DiscordClient.Session.ChannelMessageSendComplex(channelID, message.(*discordgo.MessageSend))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case string:
|
||||
return l.DiscordClient.SendMessage(channelID, message.(string))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// NoOpHandlerFunc does no operations againdst a message. This can be an equivalent to nil.
|
||||
func NoOpHandlerFunc(context.Context, discordclient.Message) {
|
||||
|
||||
}
|
65
src/common/envconfig.go
Normal file
65
src/common/envconfig.go
Normal file
|
@ -0,0 +1,65 @@
|
|||
package common
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// GetenvValue is a holder type for Getenv to translate any Getenv strings to real types
|
||||
type GetenvValue struct {
|
||||
value string
|
||||
}
|
||||
|
||||
func Getenv(key string, defaultValue ...string) GetenvValue {
|
||||
value := ""
|
||||
if len(defaultValue) > 0 {
|
||||
value = defaultValue[0]
|
||||
}
|
||||
|
||||
envValue := os.Getenv(key)
|
||||
if envValue != "" {
|
||||
value = envValue
|
||||
}
|
||||
|
||||
return GetenvValue{
|
||||
value: strings.TrimSpace(value),
|
||||
}
|
||||
}
|
||||
|
||||
func (g GetenvValue) String() string {
|
||||
return g.value
|
||||
}
|
||||
|
||||
func (g GetenvValue) StringSlice(optionalDelimiter ...string) []string {
|
||||
delimiter := ","
|
||||
if len(optionalDelimiter) > 0 {
|
||||
delimiter = optionalDelimiter[0]
|
||||
}
|
||||
|
||||
return strings.Split(g.value, delimiter)
|
||||
}
|
||||
|
||||
func (g GetenvValue) Bool() bool {
|
||||
lowercaseValue := strings.ToLower(g.value)
|
||||
if g.value == "1" || lowercaseValue == "true" || lowercaseValue == "yes" {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func (g GetenvValue) Number() int {
|
||||
result, err := strconv.Atoi(g.value)
|
||||
|
||||
if err != nil {
|
||||
return -999999
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func (g GetenvValue) JSON(target interface{}) error {
|
||||
return json.Unmarshal([]byte(g.value), target)
|
||||
}
|
123
src/common/envconfig_test.go
Normal file
123
src/common/envconfig_test.go
Normal file
|
@ -0,0 +1,123 @@
|
|||
package common_test
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/roleypoly/roleypoly/src/common"
|
||||
)
|
||||
|
||||
var (
|
||||
testEnv = map[string]string{
|
||||
"string": "hello world",
|
||||
"slice": "hello,world",
|
||||
"slice_no_delim": "hello world",
|
||||
"slice_set_delim": "hello|world",
|
||||
"number": "10005",
|
||||
"number_bad": "abc123",
|
||||
"bool": "true",
|
||||
"bool_bad": "truth",
|
||||
"bool_no": "false",
|
||||
"bool_number": "1",
|
||||
"json": `{"hello":"world","arr":[1,2,3]}`,
|
||||
}
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
|
||||
for key, value := range testEnv {
|
||||
os.Setenv("test__"+key, value)
|
||||
}
|
||||
|
||||
m.Run()
|
||||
}
|
||||
|
||||
func TestEnvconfigString(t *testing.T) {
|
||||
testStr := common.Getenv("test__string").String()
|
||||
if testStr != testEnv["string"] {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
func TestEnvconfigStringSlice(t *testing.T) {
|
||||
testSl := common.Getenv("test__slice").StringSlice()
|
||||
if testSl[0] != "hello" || testSl[1] != "world" {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
func TestEnvconfigStringSliceNoDelimeter(t *testing.T) {
|
||||
testSl := common.Getenv("test__slice_no_delim").StringSlice()
|
||||
if testSl[0] != testEnv["slice_no_delim"] {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
func TestEnvconfigStringSliceSetDelimeter(t *testing.T) {
|
||||
testSl := common.Getenv("test__slice_set_delim").StringSlice("|")
|
||||
if testSl[0] != "hello" || testSl[1] != "world" {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
func TestEnvconfigNumber(t *testing.T) {
|
||||
testNum := common.Getenv("test__number").Number()
|
||||
if testNum != 10005 {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
func TestEnvconfigNumberBad(t *testing.T) {
|
||||
testNum := common.Getenv("test__number_bad").Number()
|
||||
if testNum != -999999 {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
func TestEnvconfigBool(t *testing.T) {
|
||||
testBool := common.Getenv("test__bool").Bool()
|
||||
if !testBool {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
func TestEnvconfigBoolBad(t *testing.T) {
|
||||
testBool := common.Getenv("test__bool_bad").Bool()
|
||||
if testBool {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
func TestEnvconfigBoolFalse(t *testing.T) {
|
||||
testBool := common.Getenv("test__bool_no").Bool()
|
||||
if testBool {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
func TestEnvconfigBoolNumber(t *testing.T) {
|
||||
testBool := common.Getenv("test__bool_number").Bool()
|
||||
if !testBool {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
func TestEnvconfigDefault(t *testing.T) {
|
||||
testBool := common.Getenv("test__thing_that_doesnt_exist", "yes").Bool()
|
||||
if !testBool {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
type testJSONData struct {
|
||||
Hello string `json:"hello,omitempty"`
|
||||
Arr []int `json:"arr,omitempty"`
|
||||
}
|
||||
|
||||
func TestEnvconfigJSON(t *testing.T) {
|
||||
data := testJSONData{}
|
||||
err := common.Getenv("test__json").JSON(&data)
|
||||
if err != nil || data.Hello != "world" || len(data.Arr) != 3 {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
12
src/common/finders.go
Normal file
12
src/common/finders.go
Normal file
|
@ -0,0 +1,12 @@
|
|||
package common
|
||||
|
||||
// FindString returns true if needle is in haystack
|
||||
func FindString(needle string, haystack []string) bool {
|
||||
for _, str := range haystack {
|
||||
if str == needle {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
17
src/common/finders_test.go
Normal file
17
src/common/finders_test.go
Normal file
|
@ -0,0 +1,17 @@
|
|||
package common_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/roleypoly/roleypoly/src/common"
|
||||
)
|
||||
|
||||
func TestFindString(t *testing.T) {
|
||||
if !common.FindString("hello", []string{"hello", "world"}) {
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
if common.FindString("foo", []string{"a", "b", "c"}) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
|
@ -11,6 +11,8 @@ go_library(
|
|||
importpath = "github.com/roleypoly/roleypoly/src/discord-bot",
|
||||
visibility = ["//visibility:private"],
|
||||
deps = [
|
||||
"//src/common",
|
||||
"//src/common/bot",
|
||||
"//src/common/version",
|
||||
"//src/discord-bot/internal/strings",
|
||||
"@com_github_bwmarrin_discordgo//:discordgo",
|
||||
|
|
|
@ -1,47 +1,37 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
"os/signal"
|
||||
"regexp"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
"github.com/bwmarrin/discordgo"
|
||||
_ "github.com/joho/godotenv/autoload"
|
||||
"github.com/lampjaw/discordclient"
|
||||
"github.com/roleypoly/roleypoly/src/common"
|
||||
"github.com/roleypoly/roleypoly/src/common/bot"
|
||||
"github.com/roleypoly/roleypoly/src/common/version"
|
||||
"k8s.io/klog"
|
||||
)
|
||||
|
||||
var (
|
||||
botToken = os.Getenv("DISCORD_BOT_TOKEN")
|
||||
botClientID = os.Getenv("DISCORD_CLIENT_ID")
|
||||
rootUsers = strings.Split(os.Getenv("ROOT_USERS"), ",")
|
||||
allowedBots = strings.Split(os.Getenv("ALLOWED_BOTS"), ",")
|
||||
appURL = os.Getenv("PUBLIC_URL")
|
||||
|
||||
selfMention = regexp.MustCompile("<@!?" + botClientID + ">")
|
||||
botToken = common.Getenv("DISCORD_BOT_TOKEN").String()
|
||||
botClientID = common.Getenv("DISCORD_CLIENT_ID").String()
|
||||
rootUsers = common.Getenv("ROOT_USERS").StringSlice()
|
||||
allowedBots = common.Getenv("ALLOWED_BOTS").StringSlice()
|
||||
appURL = common.Getenv("PUBLIC_URL").String()
|
||||
selfMention = bot.MentionMatcher(botClientID)
|
||||
)
|
||||
|
||||
func main() {
|
||||
klog.Info(version.StartupInfo("discord-bot"))
|
||||
|
||||
discordClient := discordclient.NewDiscordClient(botToken, rootUsers[0], botClientID)
|
||||
discordClient.GatewayIntents = discordgo.IntentsGuildMessages
|
||||
|
||||
messageChannel, err := discordClient.Listen(-1)
|
||||
err := bot.ScaffoldBot(bot.BotScaffolding{
|
||||
RootUsers: rootUsers,
|
||||
AllowBots: true,
|
||||
BotClientID: botClientID,
|
||||
BotToken: botToken,
|
||||
GatewayIntents: discordgo.IntentsGuildMessages,
|
||||
Handler: handle,
|
||||
})
|
||||
if err != nil {
|
||||
klog.Fatal(err)
|
||||
}
|
||||
|
||||
defer awaitExit()
|
||||
|
||||
l := listener{
|
||||
client: discordClient,
|
||||
}
|
||||
|
||||
go l.processMessages(messageChannel)
|
||||
}
|
||||
|
||||
func isBotAllowlisted(userID string) bool {
|
||||
|
@ -53,15 +43,3 @@ func isBotAllowlisted(userID string) bool {
|
|||
|
||||
return false
|
||||
}
|
||||
|
||||
func awaitExit() {
|
||||
syscallExit := make(chan os.Signal, 1)
|
||||
signal.Notify(
|
||||
syscallExit,
|
||||
syscall.SIGINT,
|
||||
syscall.SIGTERM,
|
||||
os.Interrupt,
|
||||
os.Kill,
|
||||
)
|
||||
<-syscallExit
|
||||
}
|
||||
|
|
|
@ -1,28 +1,16 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/lampjaw/discordclient"
|
||||
"k8s.io/klog"
|
||||
|
||||
"github.com/roleypoly/roleypoly/src/common/bot"
|
||||
"github.com/roleypoly/roleypoly/src/discord-bot/internal/strings"
|
||||
)
|
||||
|
||||
type listener struct {
|
||||
client *discordclient.DiscordClient
|
||||
}
|
||||
|
||||
func (l *listener) processMessages(messageChannel <-chan discordclient.Message) {
|
||||
for {
|
||||
go l.handle(<-messageChannel)
|
||||
}
|
||||
}
|
||||
|
||||
func (l *listener) handle(message discordclient.Message) {
|
||||
// Only if it's a message create
|
||||
if message.Type() != discordclient.MessageTypeCreate {
|
||||
return
|
||||
}
|
||||
|
||||
func handle(ctx context.Context, message discordclient.Message) {
|
||||
// Only if it's an allowed bot
|
||||
if message.IsBot() && !isBotAllowlisted(message.UserID()) {
|
||||
return
|
||||
|
@ -33,21 +21,17 @@ func (l *listener) handle(message discordclient.Message) {
|
|||
return
|
||||
}
|
||||
|
||||
l.defaultResponse(message)
|
||||
bot.ReplyToMessage(ctx, defaultResponse(message))
|
||||
}
|
||||
|
||||
func (l *listener) defaultResponse(message discordclient.Message) {
|
||||
channel := message.Channel()
|
||||
func defaultResponse(message discordclient.Message) string {
|
||||
guild, err := message.ResolveGuildID()
|
||||
if err != nil {
|
||||
klog.Warning("failed to fetch guild, ", err)
|
||||
}
|
||||
|
||||
l.client.SendMessage(
|
||||
channel,
|
||||
strings.Render(
|
||||
strings.MentionResponse,
|
||||
strings.MentionResponseData{GuildID: guild, AppURL: appURL},
|
||||
),
|
||||
return strings.Render(
|
||||
strings.MentionResponse,
|
||||
strings.MentionResponseData{GuildID: guild, AppURL: appURL},
|
||||
)
|
||||
}
|
||||
|
|
41
src/midori/BUILD.bazel
Normal file
41
src/midori/BUILD.bazel
Normal file
|
@ -0,0 +1,41 @@
|
|||
load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
|
||||
load("@io_bazel_rules_docker//go:image.bzl", "go_image")
|
||||
load("@io_bazel_rules_docker//container:container.bzl", "container_push")
|
||||
|
||||
go_library(
|
||||
name = "midori_lib",
|
||||
srcs = ["midori.go"],
|
||||
importpath = "github.com/roleypoly/roleypoly/src/midori",
|
||||
visibility = ["//visibility:private"],
|
||||
deps = [
|
||||
"//src/common/bot",
|
||||
"//src/common/version",
|
||||
"//src/midori/internal/commands/gh",
|
||||
"//src/midori/internal/commands/tfc",
|
||||
"//src/midori/internal/config",
|
||||
"@com_github_bwmarrin_discordgo//:discordgo",
|
||||
"@com_github_joho_godotenv//autoload",
|
||||
"@io_k8s_klog//:klog",
|
||||
],
|
||||
)
|
||||
|
||||
go_binary(
|
||||
name = "midori",
|
||||
embed = [":midori_lib"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
go_image(
|
||||
name = "image",
|
||||
embed = [":midori_lib"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
container_push(
|
||||
name = "+publish",
|
||||
format = "Docker",
|
||||
image = ":image",
|
||||
registry = "docker.pkg.github.com",
|
||||
repository = "roleypoly/roleypoly/midori",
|
||||
tag = "{STABLE_GIT_BRANCH}",
|
||||
)
|
5
src/midori/README.md
Normal file
5
src/midori/README.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
# Midori
|
||||
|
||||
Midori is a GitOps/GitHub Actions/Terraform Cloud helper bot. In it's simplest form, it is a hotline into GitHub Actions and Terraform Cloud to run and act upon the actual pipelines and such.
|
||||
|
||||
This is **not** a public bot for very obvious reasons. You may host it yourself, but it is not a required part of a Roleypoly deployment.
|
16
src/midori/internal/commands/gh/BUILD.bazel
Normal file
16
src/midori/internal/commands/gh/BUILD.bazel
Normal file
|
@ -0,0 +1,16 @@
|
|||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "gh",
|
||||
srcs = ["gh.go"],
|
||||
importpath = "github.com/roleypoly/roleypoly/src/midori/internal/commands/gh",
|
||||
visibility = ["//src/midori:__subpackages__"],
|
||||
deps = [
|
||||
"//src/common/bot",
|
||||
"//src/midori/internal/commands/helpers",
|
||||
"//src/midori/internal/config",
|
||||
"@com_github_google_go_github_v32//github:go_default_library",
|
||||
"@com_github_lampjaw_discordclient//:discordclient",
|
||||
"@org_golang_x_oauth2//:oauth2",
|
||||
],
|
||||
)
|
51
src/midori/internal/commands/gh/gh.go
Normal file
51
src/midori/internal/commands/gh/gh.go
Normal file
|
@ -0,0 +1,51 @@
|
|||
package gh
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"strings"
|
||||
|
||||
"github.com/google/go-github/v32/github"
|
||||
"github.com/lampjaw/discordclient"
|
||||
"github.com/roleypoly/roleypoly/src/common/bot"
|
||||
"github.com/roleypoly/roleypoly/src/midori/internal/commands/helpers"
|
||||
"github.com/roleypoly/roleypoly/src/midori/internal/config"
|
||||
"golang.org/x/oauth2"
|
||||
)
|
||||
|
||||
type GitHubCommands struct {
|
||||
ghClient *github.Client
|
||||
}
|
||||
|
||||
func NewGitHubCommands() GitHubCommands {
|
||||
ctx := context.Background()
|
||||
ts := oauth2.StaticTokenSource(
|
||||
&oauth2.Token{AccessToken: config.GitHubToken},
|
||||
)
|
||||
tc := oauth2.NewClient(ctx, ts)
|
||||
ghClient := github.NewClient(tc)
|
||||
|
||||
return GitHubCommands{
|
||||
ghClient: ghClient,
|
||||
}
|
||||
}
|
||||
|
||||
func (ghc GitHubCommands) CommandGroup() bot.CommandGroup {
|
||||
return bot.CommandGroup{
|
||||
{
|
||||
CommandName: "dispatch",
|
||||
Handler: helpers.MustHaveElevatedPermissions(ghc.dispatch),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (ghc GitHubCommands) dispatch(ctx context.Context, message discordclient.Message) {
|
||||
tokens := bot.Tokenize(message)
|
||||
repo, webhookName := tokens[0], tokens[1]
|
||||
payload := json.RawMessage(strings.Join(tokens[2:], " "))
|
||||
|
||||
ghc.ghClient.Repositories.Dispatch(ctx, config.GitHubOrg, repo, github.DispatchRequestOptions{
|
||||
EventType: webhookName,
|
||||
ClientPayload: &payload,
|
||||
})
|
||||
}
|
14
src/midori/internal/commands/helpers/BUILD.bazel
Normal file
14
src/midori/internal/commands/helpers/BUILD.bazel
Normal file
|
@ -0,0 +1,14 @@
|
|||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "helpers",
|
||||
srcs = ["permissions.go"],
|
||||
importpath = "github.com/roleypoly/roleypoly/src/midori/internal/commands/helpers",
|
||||
visibility = ["//src/midori:__subpackages__"],
|
||||
deps = [
|
||||
"//src/common",
|
||||
"//src/common/bot",
|
||||
"//src/midori/internal/config",
|
||||
"@com_github_lampjaw_discordclient//:discordclient",
|
||||
],
|
||||
)
|
27
src/midori/internal/commands/helpers/permissions.go
Normal file
27
src/midori/internal/commands/helpers/permissions.go
Normal file
|
@ -0,0 +1,27 @@
|
|||
package helpers
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/lampjaw/discordclient"
|
||||
"github.com/roleypoly/roleypoly/src/common"
|
||||
"github.com/roleypoly/roleypoly/src/common/bot"
|
||||
"github.com/roleypoly/roleypoly/src/midori/internal/config"
|
||||
)
|
||||
|
||||
// MustHaveElevatedPermissions ensures a command has either Developer or Root role conditions.
|
||||
func MustHaveElevatedPermissions(next bot.HandlerFunc) bot.HandlerFunc {
|
||||
return func(ctx context.Context, message discordclient.Message) {
|
||||
if common.FindString(message.UserID(), config.RootUsers) || common.FindString(message.UserID(), config.AllowlistedUsers) {
|
||||
next(ctx, message)
|
||||
return
|
||||
}
|
||||
|
||||
NoPermissionsResponse(ctx, message)
|
||||
}
|
||||
}
|
||||
|
||||
// NoPermissionsResponse responds with a simple message that shows why the command failed.
|
||||
func NoPermissionsResponse(ctx context.Context, message discordclient.Message) {
|
||||
bot.ReplyToMessage(ctx, "⛔ You do not have elevated permissions.")
|
||||
}
|
13
src/midori/internal/commands/tfc/BUILD.bazel
Normal file
13
src/midori/internal/commands/tfc/BUILD.bazel
Normal file
|
@ -0,0 +1,13 @@
|
|||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "tfc",
|
||||
srcs = ["tfc.go"],
|
||||
importpath = "github.com/roleypoly/roleypoly/src/midori/internal/commands/tfc",
|
||||
visibility = ["//src/midori:__subpackages__"],
|
||||
deps = [
|
||||
"//src/common/bot",
|
||||
"//src/midori/internal/commands/helpers",
|
||||
"@com_github_lampjaw_discordclient//:discordclient",
|
||||
],
|
||||
)
|
25
src/midori/internal/commands/tfc/tfc.go
Normal file
25
src/midori/internal/commands/tfc/tfc.go
Normal file
|
@ -0,0 +1,25 @@
|
|||
package tfc
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/lampjaw/discordclient"
|
||||
"github.com/roleypoly/roleypoly/src/common/bot"
|
||||
"github.com/roleypoly/roleypoly/src/midori/internal/commands/helpers"
|
||||
)
|
||||
|
||||
type TerraformCloudCommands struct {
|
||||
}
|
||||
|
||||
func (tfcc TerraformCloudCommands) CommandGroup() bot.CommandGroup {
|
||||
return bot.CommandGroup{
|
||||
{
|
||||
CommandName: "dispatch",
|
||||
Handler: helpers.MustHaveElevatedPermissions(tfcc.dispatch),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (tfcc TerraformCloudCommands) dispatch(ctx context.Context, message discordclient.Message) {
|
||||
bot.ReplyToMessage(ctx, "Ok!")
|
||||
}
|
9
src/midori/internal/config/BUILD.bazel
Normal file
9
src/midori/internal/config/BUILD.bazel
Normal file
|
@ -0,0 +1,9 @@
|
|||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "config",
|
||||
srcs = ["config.go"],
|
||||
importpath = "github.com/roleypoly/roleypoly/src/midori/internal/config",
|
||||
visibility = ["//src/midori:__subpackages__"],
|
||||
deps = ["//src/common"],
|
||||
)
|
15
src/midori/internal/config/config.go
Normal file
15
src/midori/internal/config/config.go
Normal file
|
@ -0,0 +1,15 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"github.com/roleypoly/roleypoly/src/common"
|
||||
)
|
||||
|
||||
var (
|
||||
BotToken = common.Getenv("MIDORI_BOT_TOKEN").String()
|
||||
ClientID = common.Getenv("MIDORI_CLIENT_ID").String()
|
||||
AllowlistedUsers = common.Getenv("MIDORI_DEVELOPERS").StringSlice()
|
||||
CommandPrefix = common.Getenv("MIDORI_PREFIX_OVERRIDE", "midori").String()
|
||||
RootUsers = common.Getenv("ROOT_USERS").StringSlice()
|
||||
GitHubOrg = common.Getenv("MIDORI_GITHUB_ORG").String()
|
||||
GitHubToken = common.Getenv("MIDORI_GITHUB_TOKEN").String()
|
||||
)
|
33
src/midori/midori.go
Normal file
33
src/midori/midori.go
Normal file
|
@ -0,0 +1,33 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"github.com/bwmarrin/discordgo"
|
||||
_ "github.com/joho/godotenv/autoload"
|
||||
"k8s.io/klog"
|
||||
|
||||
"github.com/roleypoly/roleypoly/src/common/bot"
|
||||
"github.com/roleypoly/roleypoly/src/common/version"
|
||||
"github.com/roleypoly/roleypoly/src/midori/internal/commands/gh"
|
||||
"github.com/roleypoly/roleypoly/src/midori/internal/commands/tfc"
|
||||
"github.com/roleypoly/roleypoly/src/midori/internal/config"
|
||||
)
|
||||
|
||||
func main() {
|
||||
klog.Info(version.StartupInfo("midori"))
|
||||
|
||||
mux := bot.NewCommandMux(bot.MentionMatcher(config.ClientID))
|
||||
mux.RegisterCommandGroup("gh", gh.GitHubCommands{}.CommandGroup())
|
||||
mux.RegisterCommandGroup("tfc", tfc.TerraformCloudCommands{}.CommandGroup())
|
||||
|
||||
err := bot.ScaffoldBot(bot.BotScaffolding{
|
||||
AllowBots: false,
|
||||
BotToken: config.BotToken,
|
||||
BotClientID: config.ClientID,
|
||||
RootUsers: config.RootUsers,
|
||||
GatewayIntents: discordgo.IntentsGuildMessages,
|
||||
Handler: mux.Handler,
|
||||
})
|
||||
if err != nil {
|
||||
klog.Fatal(err)
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue