diff --git a/.github/workflows/azure-deploy.yml b/.github/workflows/azure-deploy.yml
new file mode 100644
index 0000000..05c0a99
--- /dev/null
+++ b/.github/workflows/azure-deploy.yml
@@ -0,0 +1,30 @@
+name: Deploy docker image
+
+on:
+ push:
+ branches: [ master ]
+
+jobs:
+ build:
+
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Docker Login
+ uses: Azure/docker-login@v1
+ with:
+ username: ${{ secrets.AZURE_DOCKER_REGISTRY_USER }}
+ password: ${{ secrets.AZURE_DOCKER_REGISTRY_PASSWORD }}
+ login-server: https://dotnetru.azurecr.io/v1
+
+ - uses: actions/checkout@v2
+
+ - name: Build Docker image
+ run: docker build . -t grinder
+
+ - name: Tag Docker image
+ run: docker tag grinder dotnetru.azurecr.io/vahter/grinder
+
+ - name: Push Docker image
+ run: docker push dotnetru.azurecr.io/vahter/grinder
+
diff --git a/Dockerfile b/Dockerfile
index 9bbcce5..e229f7c 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,8 +1,4 @@
-FROM resin/rpi-raspbian AS QEMU
-# We need this container to copy QEMU files and use at ARM container
-# This will fix pipeline crashes while doing smth
-
-FROM mcr.microsoft.com/dotnet/core/sdk:2.2.203-stretch AS build-dotnet
+FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build-dotnet
WORKDIR /app
# Copy csproj and restore as distinct layers
COPY *.sln ./
@@ -17,12 +13,12 @@ COPY src/Grinder/. ./src/Grinder
COPY src/Grinder.Common/. ./src/Grinder.Common
COPY src/Grinder.DataAccess/. ./src/Grinder.DataAccess
WORKDIR /app/src/Grinder
-RUN dotnet publish -r linux-arm -c Release -o out
+RUN dotnet publish -r linux-x64 -c Release -o out
# Build runtime image
-FROM mcr.microsoft.com/dotnet/core/runtime:2.2.4-stretch-slim-arm32v7
-# After COPY we can RUN anything without crashes!
-COPY --from=qemu /usr/bin/qemu-arm-static /usr/bin/qemu-arm-static
+FROM mcr.microsoft.com/dotnet/core/runtime:3.1
+
+EXPOSE 80
WORKDIR /app
COPY --from=build-dotnet /app/src/Grinder/out .
@@ -31,7 +27,5 @@ RUN mkdir -p /etc/grinder && mkdir -p /app/data
VOLUME /etc/grinder/
VOLUME /app/data/
-# In final container we don't need this, removing
-RUN rm -f /usr/bin/qemu-arm-static
ENTRYPOINT ["dotnet", "Grinder.dll"]
diff --git a/global.json b/global.json
index b1df68f..d0bfd1d 100644
--- a/global.json
+++ b/global.json
@@ -1,5 +1,5 @@
{
"sdk": {
- "version": "2.2.100"
+ "version": "3.1.300"
}
}
\ No newline at end of file
diff --git a/src/Grinder.DataAccess/Grinder.DataAccess.csproj b/src/Grinder.DataAccess/Grinder.DataAccess.csproj
index 68b9d7b..23e2b1d 100644
--- a/src/Grinder.DataAccess/Grinder.DataAccess.csproj
+++ b/src/Grinder.DataAccess/Grinder.DataAccess.csproj
@@ -1,7 +1,7 @@
- netcoreapp2.2
+ netcoreapp3.1
true
diff --git a/src/Grinder.ExportTool/Grinder.ExportTool.fsproj b/src/Grinder.ExportTool/Grinder.ExportTool.fsproj
index 5a79879..6f1332d 100644
--- a/src/Grinder.ExportTool/Grinder.ExportTool.fsproj
+++ b/src/Grinder.ExportTool/Grinder.ExportTool.fsproj
@@ -2,7 +2,7 @@
Exe
- netcoreapp2.2
+ netcoreapp3.1
true
true
diff --git a/src/Grinder/Commands.fs b/src/Grinder/Commands.fs
index 8162ea0..fca42c4 100644
--- a/src/Grinder/Commands.fs
+++ b/src/Grinder/Commands.fs
@@ -56,7 +56,9 @@ module Parser =
| Ban of BanDuration
| Unban
- type Command = Command of Usernames * CommandAction
+ type Command =
+ | UserCommand of Usernames * CommandAction
+ | Ping
let str s = pstring s
@@ -107,18 +109,22 @@ module Parser =
|> List.map attempt
|> choice
- let pban: Parser =
+ let pban: Parser =
str "ban" .>> spaces >>. (pforeverBan <|> pdistinctTimeFractions)
+ |>> Ban
let punban: Parser =
str "unban" .>> spaces >>% Unban
+ let pping: Parser =
+ str "ping" >>% Ping
+
let pcommandAction: Parser =
- (pban |>> Ban) <|> punban
+ pban <|> punban
let parseCommand botUsername =
pbotUsername botUsername >>.
- pipe2 many1Usernames pcommandAction (fun usernames command -> Command(Usernames(usernames), command))
+ (pping <|> pipe2 many1Usernames pcommandAction (fun usernames command -> UserCommand(Usernames(usernames), command)))
let runCommandParser botUsername str: ParserResult =
run (parseCommand botUsername) str
@@ -275,12 +281,13 @@ module Processing =
ChatId: TelegramChatId
Usernames: UserUsername seq
}
-
+
type Command =
| BanCommand of BanCommandContext
| BanOnReplyCommand of ActionOnReplyCommandContext
| UnbanCommand of UnbanCommandContext
| UnbanOnReplyCommand of ActionOnReplyCommandContext
+ | PingCommand
| DoNothingCommand
type CommandError =
@@ -374,7 +381,7 @@ module Processing =
let parseTextMessage (context: TextMessageContext): Command =
match Parser.parse %context.BotUsername context.MessageText with
- | BotCommand(Command((Usernames usernames), Ban(duration))) ->
+ | BotCommand(UserCommand((Usernames usernames), Ban(duration))) ->
let usernames =
usernames
|> Seq.map ^ fun username -> %username
@@ -387,7 +394,7 @@ module Processing =
Until = duration
}
BanCommand context
- | BotCommand(Command((Usernames usernames), Unban)) ->
+ | BotCommand(UserCommand((Usernames usernames), Unban)) ->
let usernames =
usernames
|> Seq.map ^ fun username -> %username
@@ -399,6 +406,8 @@ module Processing =
Usernames = usernames
}
UnbanCommand context
+ | BotCommand(Ping) ->
+ PingCommand
| InvalidCommand _ ->
DoNothingCommand
@@ -538,6 +547,9 @@ module Processing =
}
return Some <| UnbanOnReplyMessage(context.From, message, errors)
+ | PingCommand ->
+ do! botApi.SendTextToChannel "pong"
+ return None
| DoNothingCommand ->
return None
}
diff --git a/src/Grinder/Grinder.fsproj b/src/Grinder/Grinder.fsproj
index f507c82..795a112 100644
--- a/src/Grinder/Grinder.fsproj
+++ b/src/Grinder/Grinder.fsproj
@@ -2,7 +2,7 @@
Exe
- netcoreapp2.2
+ netcoreapp3.1
false
true
true
@@ -15,6 +15,7 @@
+
@@ -40,4 +41,4 @@
-
+
\ No newline at end of file
diff --git a/src/Grinder/Program.fs b/src/Grinder/Program.fs
index 0dd8b94..842a06c 100644
--- a/src/Grinder/Program.fs
+++ b/src/Grinder/Program.fs
@@ -1,5 +1,7 @@
namespace Grinder
+open System.Net
+open System.Threading
open Microsoft.Extensions.Configuration
open Funogram
open Grinder
@@ -10,6 +12,7 @@ open Funogram.Api
open Funogram.Bot
open Funogram.Types
open FunogramExt
+open System
module Program =
open System.Net.Http
@@ -40,10 +43,11 @@ module Program =
Bot: BotConfig
}
- let createHttpClient config =
+ let createHttpClient (config: Socks5Configuration) =
let messageHandler = new HttpClientHandler()
- messageHandler.Proxy <- HttpToSocks5Proxy(config.Hostname, config.Port, config.Username, config.Password)
- messageHandler.UseProxy <- true
+ if not (isNull (box config)) then
+ messageHandler.Proxy <- HttpToSocks5Proxy(config.Hostname, config.Port, config.Username, config.Password)
+ messageHandler.UseProxy <- true
new HttpClient(messageHandler)
let createBotApi config (settings: BotSettings) = {
@@ -124,11 +128,20 @@ module Program =
[]
let main _ =
- let config =
+ let mutable configBuilder =
ConfigurationBuilder()
.AddJsonFile("appsettings.json", false, true)
.AddJsonFile("/etc/grinder/appsettings.json", true, true)
.AddEnvironmentVariables("Grinder_")
+
+ match Environment.GetEnvironmentVariable("DOTNETRU_APP_CONFIG") with
+ | null -> ()
+ | connString ->
+ configBuilder <- configBuilder
+ .AddAzureAppConfiguration connString
+
+ let config =
+ configBuilder
.Build()
.Get()
.Bot;
@@ -142,23 +155,32 @@ module Program =
GrinderContext.MigrateUp()
- async {
- printfn "Starting bot"
-
- let settings = {
- Token = config.Token
- ChatsToMonitor = ChatsToMonitor.Create config.ChatsToMonitor
- AllowedUsers = AllowedUsers.Create config.AllowedUsers
- ChannelId = %config.ChannelId
- AdminUserId = %config.AdminUserId
- }
- do! startBot botConfiguration (onUpdate settings (createBotApi botConfiguration settings) dataApi) None
- |> Async.StartChild
- |> Async.Ignore
-
- printfn "Bot started"
- do! Async.Sleep(-1)
- } |> Async.RunSynchronously
+ printfn "Starting bot"
+
+ let settings = {
+ Token = config.Token
+ ChatsToMonitor = ChatsToMonitor.Create config.ChatsToMonitor
+ AllowedUsers = AllowedUsers.Create config.AllowedUsers
+ ChannelId = %config.ChannelId
+ AdminUserId = %config.AdminUserId
+ }
+ startBot botConfiguration (onUpdate settings (createBotApi botConfiguration settings) dataApi) None
+ |> Async.Start
+
+ printfn "Bot started"
+
+ // Needed for azure web app deploy check. We have to response with anything on port 80
+ use listener = new HttpListener()
+ listener.Prefixes.Add("http://*:80/")
+ listener.Start()
+
+ let buffer = System.Text.Encoding.UTF8.GetBytes "OK"
+
+ while true do
+ let ctx = listener.GetContext()
+ let output = ctx.Response.OutputStream
+ output.Write(buffer, 0, buffer.Length)
+ output.Close();
printfn "Bot exited"
0 // return an integer exit code
\ No newline at end of file
diff --git a/src/Grinder/appsettings.json b/src/Grinder/appsettings.json
index f9c3834..2b88449 100644
--- a/src/Grinder/appsettings.json
+++ b/src/Grinder/appsettings.json
@@ -3,12 +3,13 @@
"Token": "REPLACEME",
"ChannelId": 0,
"AdminUserId": 0,
- "Socks5Proxy": {
- "Hostname": "REPLACEME",
- "Port": 0,
- "Username": "REPLACEME",
- "Password": "REPLACEME"
- },
+// uncomment if you need proxy
+// "Socks5Proxy": {
+// "Hostname": "REPLACEME",
+// "Port": 0,
+// "Username": "REPLACEME",
+// "Password": "REPLACEME"
+// },
"ChatsToMonitor": [
"REPLACEME"
],
diff --git a/tests/Grinder.Tests/Grinder.Tests.fsproj b/tests/Grinder.Tests/Grinder.Tests.fsproj
index 4d659f3..7a69813 100644
--- a/tests/Grinder.Tests/Grinder.Tests.fsproj
+++ b/tests/Grinder.Tests/Grinder.Tests.fsproj
@@ -2,7 +2,7 @@
Exe
- netcoreapp2.2
+ netcoreapp3.1
false
false
true