Skip to content

Commit

Permalink
chore: reminder emails & slack notifications
Browse files Browse the repository at this point in the history
  • Loading branch information
kayprogrammer committed Dec 23, 2024
1 parent 1320d0f commit 92f25d3
Show file tree
Hide file tree
Showing 15 changed files with 1,024 additions and 167 deletions.
6 changes: 5 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,8 @@ PGADMIN_PASSWORD=
LITPAD_WALLET_SECRET=secret
CLOUDINARY_CLOUD_NAME=
CLOUDINARY_API_KEY=
CLOUDINARY_API_SECRET=
CLOUDINARY_API_SECRET=
REDIS_URL=
REMINDER_CRON_HOURS=

# https://github.com/hibiken/asynqmon
83 changes: 69 additions & 14 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,17 @@ jobs:
runs-on: ubuntu-latest

steps:
# Checkout code
- name: Checkout code
uses: actions/checkout@v2

# Install dependencies
- name: Install Dependencies
run: |
sudo apt-get update
sudo apt-get install -y sshpass expect rsync
sudo apt-get install -y sshpass rsync
# Setup SSH with passphrase
- name: Setup SSH passphrase
env:
SSH_PASSPHRASE: ${{ secrets.SSH_PASSPHRASE }}
Expand All @@ -31,35 +34,87 @@ jobs:
echo "$SSH_PRIVATE_KEY" | tr -d '\r' | DISPLAY=None SSH_ASKPASS=~/.ssh_askpass ssh-add - >/dev/null
echo "SSH key added"
# Verify SSH connection
- name: Verify SSH Connection
env:
VPS_IP: ${{ secrets.VPS_IP }}
run: |
sshpass -p "${{ secrets.SSH_PASSPHRASE }}" ssh -o StrictHostKeyChecking=no docker@${VPS_IP} "echo Connection successful"
- name: Install rsync on VPS
env:
VPS_IP: ${{ secrets.VPS_IP }}
run: |
sshpass -p "${{ secrets.SSH_PASSPHRASE }}" ssh -o StrictHostKeyChecking=no docker@${VPS_IP} << 'EOF'
sudo apt-get update
sudo apt-get install -y rsync
EOF
# Copy files to VPS
- name: Copy files to VPS
env:
VPS_IP: ${{ secrets.VPS_IP }}
run: |
sshpass -p "${{ secrets.SSH_PASSPHRASE }}" rsync -avz -e "ssh -o StrictHostKeyChecking=no" ./ docker@${VPS_IP}:/backend
echo "Files copied to VPS"
- name: SSH and run Docker Compose
# SSH and deploy with Docker
- name: SSH and Deploy Docker
env:
VPS_IP: ${{ secrets.VPS_IP }}
run: |
sshpass -p "${{ secrets.SSH_PASSPHRASE }}" ssh -o StrictHostKeyChecking=no docker@${VPS_IP} << 'EOF'
cd /backend
docker-compose down
docker-compose up -d --build --remove-orphans
echo "Docker Compose executed"
# Backup the current running container
if docker ps -q -f name=backend; then
docker tag backend:latest backend:backup || echo "Failed to tag existing image"
fi
# Try to build and deploy the new Docker container
if ! docker-compose down || ! docker-compose up -d --build --remove-orphans; then
echo "Deployment failed. Rolling back..."
docker-compose down
if docker images | grep -q 'backend:backup'; then
docker tag backend:backup backend:latest
docker-compose up -d
echo "Rollback to the previous version was successful."
else
echo "No backup available for rollback. Exiting..."
exit 1
fi
fi
echo "Deployment successful"
EOF
# Notify Slack - Success
- name: Notify Slack - Success
if: success()
uses: slackapi/[email protected]
with:
method: chat.postMessage
token: ${{ secrets.SLACK_BOT_TOKEN }}
payload: |
channel: ${{ secrets.SLACK_CHANNEL_ID }}
text: "✅ Backend Deployment to VPS succeeded! 🚀"
attachments:
- color: "36a64f"
fields:
- title: "Status"
short: true
value: "Success"
- title: "Deployment Details"
short: true
value: "The latest code was successfully deployed to the VPS."
# Notify Slack - Failure
- name: Notify Slack - Failure
if: failure()
uses: slackapi/[email protected]
with:
method: chat.postMessage
token: ${{ secrets.SLACK_BOT_TOKEN }}
payload: |
channel: ${{ secrets.SLACK_CHANNEL_ID }}
text: "❌ Backend Deployment to VPS failed! 😞"
attachments:
- color: "ff0000"
fields:
- title: "Status"
short: true
value: "Failed"
- title: "Error"
short: true
value: "The deployment process encountered an issue. Check the logs for details."
108 changes: 55 additions & 53 deletions config/conf.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,59 +5,61 @@ import (
)

type Config struct {
ProjectName string `mapstructure:"PROJECT_NAME"`
Debug bool `mapstructure:"DEBUG"`
EmailOtpExpireSeconds int64 `mapstructure:"EMAIL_OTP_EXPIRE_SECONDS"`
AccessTokenExpireMinutes int `mapstructure:"ACCESS_TOKEN_EXPIRE_MINUTES"`
RefreshTokenExpireMinutes int `mapstructure:"REFRESH_TOKEN_EXPIRE_MINUTES"`
Port string `mapstructure:"PORT"`
SecretKey string `mapstructure:"SECRET_KEY"`
FirstSuperuserEmail string `mapstructure:"FIRST_SUPERUSER_EMAIL"`
FirstSuperUserPassword string `mapstructure:"FIRST_SUPERUSER_PASSWORD"`
FirstWriterEmail string `mapstructure:"FIRST_WRITER_EMAIL"`
FirstWriterPassword string `mapstructure:"FIRST_WRITER_PASSWORD"`
FirstReaderEmail string `mapstructure:"FIRST_READER_EMAIL"`
FirstReaderPassword string `mapstructure:"FIRST_READER_PASSWORD"`
PostgresUser string `mapstructure:"POSTGRES_USER"`
PostgresPassword string `mapstructure:"POSTGRES_PASSWORD"`
PostgresServer string `mapstructure:"POSTGRES_SERVER"`
PostgresPort string `mapstructure:"POSTGRES_PORT"`
PostgresDB string `mapstructure:"POSTGRES_DB"`
TestPostgresDB string `mapstructure:"TEST_POSTGRES_DB"`
MailSenderEmail string `mapstructure:"MAIL_SENDER_EMAIL"`
MailFrom string `mapstructure:"MAIL_FROM"`
MailSenderPassword string `mapstructure:"MAIL_SENDER_PASSWORD"`
MailSenderHost string `mapstructure:"MAIL_SENDER_HOST"`
MailSenderPort int `mapstructure:"MAIL_SENDER_PORT"`
MailApiKey string `mapstructure:"MAIL_API_KEY"`
BrevoListID int `mapstructure:"BREVO_LIST_ID"`
BrevoContactsUrl string `mapstructure:"BREVO_CONTACTS_URL"`
CORSAllowedOrigins string `mapstructure:"CORS_ALLOWED_ORIGINS"`
CORSAllowCredentials bool `mapstructure:"CORS_ALLOW_CREDENTIALS"`
GoogleClientID string `mapstructure:"GOOGLE_CLIENT_ID"`
GoogleClientSecret string `mapstructure:"GOOGLE_CLIENT_SECRET"`
FacebookAppID string `mapstructure:"FACEBOOK_APP_ID"`
SocialsPassword string `mapstructure:"SOCIALS_PASSWORD"`
EmailVerificationPath string `mapstructure:"EMAIL_VERIFICATION_PATH"`
PasswordResetPath string `mapstructure:"PASSWORD_RESET_PATH"`
StripePublicKey string `mapstructure:"STRIPE_PUBLIC_KEY"`
StripeSecretKey string `mapstructure:"STRIPE_SECRET_KEY"`
StripeWebhookSecret string `mapstructure:"STRIPE_WEBHOOK_SECRET"`
SocketSecret string `mapstructure:"SOCKET_SECRET"`
S3AccessKey string `mapstructure:"S3_ACCESS_KEY"`
S3SecretKey string `mapstructure:"S3_SECRET_KEY"`
S3EndpointUrl string `mapstructure:"S3_ENDPOINT_URL"`
BookCoverImagesBucket string `mapstructure:"BOOK_COVER_IMAGES_BUCKET"`
UserImagesBucket string `mapstructure:"USER_IMAGES_BUCKET"`
IDFrontImagesBucket string `mapstructure:"ID_FRONT_IMAGES_BUCKET"`
IDBackImagesBucket string `mapstructure:"ID_BACK_IMAGES_BUCKET"`
WalletSecret string `mapstructure:"LITPAD_WALLET_SECRET"`
PGAdminPassword string `mapstructure:"PGADMIN_PASSWORD"`
ICPPrivateKey string `mapstructure:"ICP_PRIVATE_KEY"`
ICPPublicKey string `mapstructure:"ICP_PUBLIC_KEY"`
CloudinaryCloudName string `mapstructure:"CLOUDINARY_CLOUD_NAME"`
CloudinaryApiKey string `mapstructure:"CLOUDINARY_API_KEY"`
CloudinaryApiSecret string `mapstructure:"CLOUDINARY_API_SECRET"`
ProjectName string `mapstructure:"PROJECT_NAME"`
Debug bool `mapstructure:"DEBUG"`
EmailOtpExpireSeconds int64 `mapstructure:"EMAIL_OTP_EXPIRE_SECONDS"`
AccessTokenExpireMinutes int `mapstructure:"ACCESS_TOKEN_EXPIRE_MINUTES"`
RefreshTokenExpireMinutes int `mapstructure:"REFRESH_TOKEN_EXPIRE_MINUTES"`
Port string `mapstructure:"PORT"`
SecretKey string `mapstructure:"SECRET_KEY"`
FirstSuperuserEmail string `mapstructure:"FIRST_SUPERUSER_EMAIL"`
FirstSuperUserPassword string `mapstructure:"FIRST_SUPERUSER_PASSWORD"`
FirstWriterEmail string `mapstructure:"FIRST_WRITER_EMAIL"`
FirstWriterPassword string `mapstructure:"FIRST_WRITER_PASSWORD"`
FirstReaderEmail string `mapstructure:"FIRST_READER_EMAIL"`
FirstReaderPassword string `mapstructure:"FIRST_READER_PASSWORD"`
PostgresUser string `mapstructure:"POSTGRES_USER"`
PostgresPassword string `mapstructure:"POSTGRES_PASSWORD"`
PostgresServer string `mapstructure:"POSTGRES_SERVER"`
PostgresPort string `mapstructure:"POSTGRES_PORT"`
PostgresDB string `mapstructure:"POSTGRES_DB"`
TestPostgresDB string `mapstructure:"TEST_POSTGRES_DB"`
MailSenderEmail string `mapstructure:"MAIL_SENDER_EMAIL"`
MailFrom string `mapstructure:"MAIL_FROM"`
MailSenderPassword string `mapstructure:"MAIL_SENDER_PASSWORD"`
MailSenderHost string `mapstructure:"MAIL_SENDER_HOST"`
MailSenderPort int `mapstructure:"MAIL_SENDER_PORT"`
MailApiKey string `mapstructure:"MAIL_API_KEY"`
BrevoListID int `mapstructure:"BREVO_LIST_ID"`
BrevoContactsUrl string `mapstructure:"BREVO_CONTACTS_URL"`
CORSAllowedOrigins string `mapstructure:"CORS_ALLOWED_ORIGINS"`
CORSAllowCredentials bool `mapstructure:"CORS_ALLOW_CREDENTIALS"`
GoogleClientID string `mapstructure:"GOOGLE_CLIENT_ID"`
GoogleClientSecret string `mapstructure:"GOOGLE_CLIENT_SECRET"`
FacebookAppID string `mapstructure:"FACEBOOK_APP_ID"`
SocialsPassword string `mapstructure:"SOCIALS_PASSWORD"`
EmailVerificationPath string `mapstructure:"EMAIL_VERIFICATION_PATH"`
PasswordResetPath string `mapstructure:"PASSWORD_RESET_PATH"`
StripePublicKey string `mapstructure:"STRIPE_PUBLIC_KEY"`
StripeSecretKey string `mapstructure:"STRIPE_SECRET_KEY"`
StripeWebhookSecret string `mapstructure:"STRIPE_WEBHOOK_SECRET"`
SocketSecret string `mapstructure:"SOCKET_SECRET"`
S3AccessKey string `mapstructure:"S3_ACCESS_KEY"`
S3SecretKey string `mapstructure:"S3_SECRET_KEY"`
S3EndpointUrl string `mapstructure:"S3_ENDPOINT_URL"`
BookCoverImagesBucket string `mapstructure:"BOOK_COVER_IMAGES_BUCKET"`
UserImagesBucket string `mapstructure:"USER_IMAGES_BUCKET"`
IDFrontImagesBucket string `mapstructure:"ID_FRONT_IMAGES_BUCKET"`
IDBackImagesBucket string `mapstructure:"ID_BACK_IMAGES_BUCKET"`
WalletSecret string `mapstructure:"LITPAD_WALLET_SECRET"`
PGAdminPassword string `mapstructure:"PGADMIN_PASSWORD"`
ICPPrivateKey string `mapstructure:"ICP_PRIVATE_KEY"`
ICPPublicKey string `mapstructure:"ICP_PUBLIC_KEY"`
CloudinaryCloudName string `mapstructure:"CLOUDINARY_CLOUD_NAME"`
CloudinaryApiKey string `mapstructure:"CLOUDINARY_API_KEY"`
CloudinaryApiSecret string `mapstructure:"CLOUDINARY_API_SECRET"`
RedisUrl string `mapstructure:"REDIS_URL"`
ReminderCronHours uint `mapstructure:"REMINDER_CRON_HOURS"`
}

func GetConfig() (config Config) {
Expand Down
27 changes: 11 additions & 16 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,27 @@ module github.com/LitPad/backend
go 1.22.1

require (
github.com/aviate-labs/agent-go v0.5.1
github.com/aws/aws-sdk-go v1.54.16
github.com/cloudinary/cloudinary-go/v2 v2.9.0
github.com/fasthttp/websocket v1.5.8
github.com/go-playground/locales v0.14.1
github.com/go-playground/universal-translator v0.18.1
github.com/go-playground/validator/v10 v10.18.0
github.com/go-redis/redis/v8 v8.11.5
github.com/gofiber/contrib/swagger v1.1.1
github.com/gofiber/contrib/websocket v1.3.1
github.com/gofiber/fiber/v2 v2.52.4
github.com/golang-jwt/jwt/v5 v5.2.1
github.com/google/uuid v1.6.0
github.com/gosimple/slug v1.14.0
github.com/hibiken/asynq v0.25.1
github.com/huandu/facebook/v2 v2.7.1
github.com/mitchellh/mapstructure v1.5.0
github.com/shopspring/decimal v1.4.0
github.com/spf13/viper v1.18.2
github.com/stripe/stripe-go/v72 v72.122.0
github.com/stripe/stripe-go/v78 v78.5.0
github.com/swaggo/swag v1.16.3
github.com/valyala/fasthttp v1.58.0
golang.org/x/crypto v0.29.0
google.golang.org/api v0.171.0
gopkg.in/mail.v2 v2.3.1
Expand All @@ -35,16 +37,11 @@ require (
github.com/KyleBanks/depth v1.2.1 // indirect
github.com/andybalholm/brotli v1.1.1 // indirect
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
github.com/aviate-labs/leb128 v0.3.0 // indirect
github.com/aviate-labs/secp256k1 v0.0.0-5e6736a // indirect
github.com/bits-and-blooms/bitset v1.7.0 // indirect
github.com/cloudinary/cloudinary-go/v2 v2.9.0 // indirect
github.com/consensys/bavard v0.1.13 // indirect
github.com/consensys/gnark-crypto v0.12.2-0.20240215234832-d72fcb379d3e // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/creasty/defaults v1.7.0 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/fxamacker/cbor/v2 v2.6.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
github.com/go-logr/logr v1.4.1 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
Expand All @@ -70,7 +67,6 @@ require (
github.com/jackc/pgx/v5 v5.4.3 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/klauspost/compress v1.17.11 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
Expand All @@ -79,22 +75,21 @@ require (
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/mmcloughlin/addchain v0.4.0 // indirect
github.com/oklog/ulid v1.3.1 // indirect
github.com/pelletier/go-toml/v2 v2.1.0 // indirect
github.com/redis/go-redis/v9 v9.7.0 // indirect
github.com/rivo/uniseg v0.2.0 // indirect
github.com/robfig/cron/v3 v3.0.1 // indirect
github.com/sagikazarmark/locafero v0.4.0 // indirect
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
github.com/savsgio/gotils v0.0.0-20240303185622-093b76447511 // indirect
github.com/sourcegraph/conc v0.3.0 // indirect
github.com/spf13/afero v1.11.0 // indirect
github.com/spf13/cast v1.6.0 // indirect
github.com/spf13/cast v1.7.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasthttp v1.58.0 // indirect
github.com/valyala/tcplisten v1.0.0 // indirect
github.com/x448/float16 v0.8.4 // indirect
go.mongodb.org/mongo-driver v1.11.3 // indirect
go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect
Expand All @@ -108,14 +103,14 @@ require (
golang.org/x/oauth2 v0.18.0 // indirect
golang.org/x/sys v0.27.0 // indirect
golang.org/x/text v0.20.0 // indirect
golang.org/x/time v0.8.0 // indirect
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect
google.golang.org/appengine v1.6.8 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240314234333-6e1732d8331c // indirect
google.golang.org/grpc v1.62.1 // indirect
google.golang.org/protobuf v1.34.1 // indirect
google.golang.org/protobuf v1.35.2 // indirect
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
rsc.io/tmplfunc v0.0.3 // indirect
)
Loading

0 comments on commit 92f25d3

Please sign in to comment.