Skip to content

Commit

Permalink
feat: added ci/cd
Browse files Browse the repository at this point in the history
  • Loading branch information
d.pikaliuk committed Jan 12, 2024
1 parent d530e67 commit a00e81e
Show file tree
Hide file tree
Showing 10 changed files with 120 additions and 55 deletions.
35 changes: 35 additions & 0 deletions .github/workflows/ci-cd.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: CI/CD Pipeline

on:
push:
tags:
- 'v1.*.*'

jobs:
build-and-deploy:
runs-on: ubuntu-latest

steps:
- name: Checkout Repository
uses: actions/checkout@v2

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1

- name: Login to Docker Hub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}

- name: Build and Push Docker image
uses: docker/build-push-action@v2
with:
file: ./cicd/dockerfiles/insta-bot.Dockerfile
context: .
push: true
tags: haski007/insta-bot:${{ github.ref_name }}

- name: Run Docker Compose
run: |
docker-compose -f docker-compose.yml up --build -d
30 changes: 30 additions & 0 deletions cicd/dockerfiles/insta-bot.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
FROM golang:1.21 as builder

# Set the working dixrectory in the container
WORKDIR /app

# Copy the Go modules and sum files
COPY go.mod go.sum ./

# Download Go module dependencies
RUN go mod download

# Copy the rest of the source code
COPY . .

# Build the application
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o insta-bot ./cmd/app

# Use a small image to run the application
FROM alpine:latest
RUN apk --no-cache add ca-certificates

WORKDIR /root/

# Copy the pre-built binary file from the previous stage
COPY --from=builder /app/insta-bot .
COPY --from=builder /app/token.json .


# Command to run the executable
CMD ["./insta-bot"]
40 changes: 8 additions & 32 deletions cmd/app/config.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
package main

import (
"fmt"
"os"
"time"

"github.com/haski007/insta-bot/pkg/factory"
"gopkg.in/yaml.v2"
)

type Config struct {
Expand All @@ -22,43 +19,22 @@ type Config struct {
}

type GoogleConfig struct {
CredentialsPath string `yaml:"credentials_path"`
Credentials string `yaml:"credentials_path" env:"GOOGLE_CREDENTIALS"`
}

type OpenAIConfig struct {
ApiKey string `yaml:"api_key"`
GPTModelForConv string `yaml:"gpt_model_for_conv"`
GPTModelForHistory string `yaml:"gpt_model_for_history"`
ApiKey string `yaml:"api_key" env:"OPENAI_API_KEY"`
GPTModelForConv string `yaml:"gpt_model_for_conv" env:"OPENAI_GPT_MODEL_FOR_CONV"`
GPTModelForHistory string `yaml:"gpt_model_for_history" env:"OPENAI_GPT_MODEL_FOR_HISTORY"`
}

type RedisClient struct {
Addr string `yaml:"addr"`
Pass string `yaml:"pass"`
ConversationTTLMin time.Duration `yaml:"conversation_ttl_min"`
HistoryMessagesTTLHours time.Duration `yaml:"history_messages_ttl_hours"`
Addr string `yaml:"addr" env:"REDIS_ADDR"`
Pass string `yaml:"pass" env:"REDIS_PASS"`
ConversationTTL time.Duration `yaml:"conversation_ttl_min" env:"REDIS_CONVERSATION_TTL"`
HistoryMessagesTTL time.Duration `yaml:"history_messages_ttl_hours" env:"REDIS_HISTORY_MESSAGES_TTL"`
}

type YouTubeConfig struct {
MaxQuality int `yaml:"max_quality"`
}

func Load(configFile string, cfg interface{}) error {
fileData, err := os.ReadFile(configFile)
if err != nil {
return fmt.Errorf("can't read config file: %w", err)
}

fileData = []byte(os.ExpandEnv(string(fileData)))

if err = yaml.Unmarshal(fileData, cfg); err != nil {
return fmt.Errorf("can't unmarshal config data: %w", err)
}

if v, ok := cfg.(interface{ Validate() error }); ok {
if err = v.Validate(); err != nil {
return fmt.Errorf("invalid config: %w", err)
}
}

return nil
}
19 changes: 8 additions & 11 deletions cmd/app/entry.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
package main

import (
"bytes"
"context"
"errors"
"fmt"
"net/http"
"os"
"os/signal"
"syscall"
"time"

"github.com/go-redis/redis"
"github.com/haski007/insta-bot/internal/bot/listener"
Expand All @@ -20,6 +19,7 @@ import (
"github.com/haski007/insta-bot/pkg/run"
"github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/sashabaranov/go-openai"
"github.com/sethvargo/go-envconfig"
"github.com/sirupsen/logrus"
"golang.org/x/oauth2/google"
"golang.org/x/sync/errgroup"
Expand All @@ -38,15 +38,12 @@ func Run(ctx context.Context, args run.Args) error {
log.SetFormatter(&logrus.JSONFormatter{})

var cfg Config
if err := Load(args.ConfigFile, &cfg); err != nil {
return fmt.Errorf("load config %s err: %w", args.ConfigFile, err)
if err := envconfig.Process(ctx, &cfg); err != nil {
return fmt.Errorf("load config from env err: %w", err)
}

// ---> Google AUTH
b, err := os.ReadFile(cfg.Clients.Google.CredentialsPath)
if err != nil {
log.Fatalf("Unable to read client secret file: %v", err)
}
b := bytes.NewBufferString(cfg.Clients.Google.Credentials).Bytes()

// If modifying these scopes, delete your previously saved token.json.
config, err := google.ConfigFromJSON(b,
Expand Down Expand Up @@ -78,7 +75,7 @@ func Run(ctx context.Context, args run.Args) error {
}

u := tgbotapi.NewUpdate(0)
u.Timeout = cfg.TelegramBot.UpdatesTimeoutSec
u.Timeout = int(cfg.TelegramBot.UpdatesTimeout.Seconds())
chUpdates := botApi.GetUpdatesChan(u)

apiCli := instapi.New()
Expand All @@ -91,8 +88,8 @@ func Run(ctx context.Context, args run.Args) error {

redisStorage, err := redisWrapper.NewClient(
redCC,
time.Minute*cfg.Clients.Redis.ConversationTTLMin,
time.Hour*cfg.Clients.Redis.HistoryMessagesTTLHours,
cfg.Clients.Redis.ConversationTTL,
cfg.Clients.Redis.HistoryMessagesTTL,
)
if err != nil {
return fmt.Errorf("connect to redis err: %w", err)
Expand Down
4 changes: 2 additions & 2 deletions cmd/app/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func main() {
}

if err := app.Run(os.Args); err != nil {
logrus.Panicln(err)
logrus.WithError(err).Fatalln("app run")
}
}

Expand All @@ -50,7 +50,7 @@ func flags() []cli.Flag {
&cli.StringFlag{
Name: "config",
Aliases: []string{"c"},
Required: true,
Required: false,
EnvVars: []string{"CONFIG_PATH"},
},
}
Expand Down
26 changes: 24 additions & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,33 @@
version: "3"
services:
insta-bot:
build:
context: .
dockerfile: cicd/dockerfiles/insta-bot.Dockerfile
environment:
REDIS_ADDR: "redis:6379"
REDIS_PASS: "${REDIS_PASS}"
REDIS_CONVERSATION_TTL: "${REDIS_CONVERSATION_TTL}"
REDIS_HISTORY_MESSAGES_TTL: "${REDIS_HISTORY_MESSAGES_TTL}"
GOOGLE_CREDENTIALS: "${GOOGLE_CREDENTIALS}"
OPENAI_API_KEY: "${OPENAI_API_KEY}"
OPENAI_GPT_MODEL_FOR_CONV: "${OPENAI_GPT_MODEL_FOR_CONV}"
OPENAI_GPT_MODEL_FOR_HISTORY: "${OPENAI_GPT_MODEL_FOR_HISTORY}"
BOT_TOKEN: "${BOT_TOKEN}"
BOT_CREATOR_USER_ID: "${BOT_CREATOR_USER_ID}"
BOT_UPDATES_TIMEOUT: "${BOT_UPDATES_TIMEOUT}"
CAPTION_CHARS_LIMIT: "${CAPTION_CHARS_LIMIT}"
ports:
- "8080:8080"
depends_on:
- redis

redis:
image: redis:alpine
command: redis-server --requirepass zakEfron1
command: redis-server --requirepass "${REDIS_PASS}"
environment:
- REDIS_REPLICATION_MODE=master
- REDIS_PASSWORD=zakEfron1
- REDIS_PASSWORD=${REDIS_PASS}
ports:
- "6381:6379"
volumes:
Expand Down
5 changes: 4 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
module github.com/haski007/insta-bot

go 1.18
go 1.21

toolchain go1.21.5

require (
github.com/PuerkitoBio/goquery v1.8.0
Expand Down Expand Up @@ -48,6 +50,7 @@ require (
github.com/prometheus/common v0.37.0 // indirect
github.com/prometheus/procfs v0.8.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/sethvargo/go-envconfig v1.0.0 // indirect
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
go.opencensus.io v0.24.0 // indirect
golang.org/x/net v0.4.0 // indirect
Expand Down
3 changes: 3 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
Expand Down Expand Up @@ -261,6 +262,8 @@ github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sashabaranov/go-openai v1.16.1 h1:R7c8jhXeQEtHkD6MoXQfkgzz/7JI6jjFKl+DXawaejQ=
github.com/sashabaranov/go-openai v1.16.1/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg=
github.com/sethvargo/go-envconfig v1.0.0 h1:1C66wzy4QrROf5ew4KdVw942CQDa55qmlYmw9FZxZdU=
github.com/sethvargo/go-envconfig v1.0.0/go.mod h1:Lzc75ghUn5ucmcRGIdGQ33DKJrcjk4kihFYgSTBmjIc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
Expand Down
8 changes: 5 additions & 3 deletions pkg/factory/telegram-bot.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package factory

import "time"

type TelegramBotCfg struct {
Token string `json:"token" yaml:"token"`
CreatorUserID int64 `json:"creator_user_id" yaml:"creator_user_id"`
UpdatesTimeoutSec int `json:"updates_timeout_sec" yaml:"updates_timeout_sec"`
Token string `json:"token" yaml:"token" env:"BOT_TOKEN"`
CreatorUserID int64 `json:"creator_user_id" yaml:"creator_user_id" env:"BOT_CREATOR_USER_ID"`
UpdatesTimeout time.Duration `json:"updates_timeout" yaml:"updates_timeout" env:"BOT_UPDATES_TIMEOUT"`
}
5 changes: 1 addition & 4 deletions pkg/run/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,7 @@ type Args struct {
}

func (a Args) Validate() error {
return validation.ValidateStruct(&a,
validation.Field(&a.ConfigFile, validation.Required),
validation.Field(&a.MetricsAddr, validation.Required),
)
return validation.ValidateStruct(&a)
}

func LogLevel(level string) logrus.Level {
Expand Down

0 comments on commit a00e81e

Please sign in to comment.