Skip to content

Commit

Permalink
feat: migrate
Browse files Browse the repository at this point in the history
  • Loading branch information
ernado committed Dec 2, 2024
1 parent 70d8229 commit ed7403a
Show file tree
Hide file tree
Showing 13 changed files with 301 additions and 22 deletions.
42 changes: 21 additions & 21 deletions .k8s/deployment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,27 +23,27 @@ spec:
- name: atlas
secret:
secretName: atlas
# initContainers:
# - name: migrate
# image: ghcr.io/gotd/bot/migrate:main
# volumeMounts:
# - mountPath: "/root/.config/"
# name: atlas
# readOnly: true
# args:
# - --config
# - file://root/.config/atlas.hcl
# - --env
# - prod
# - migrate
# - apply
# resources:
# requests:
# cpu: 100m
# memory: 64M
# limits:
# cpu: 500m
# memory: 128M
initContainers:
- name: migrate
image: ghcr.io/gotd/bot/migrate:main
volumeMounts:
- mountPath: "/root/.config/"
name: atlas
readOnly: true
args:
- --config
- file://root/.config/atlas.hcl
- --env
- prod
- migrate
- apply
resources:
requests:
cpu: 100m
memory: 64M
limits:
cpu: 500m
memory: 128M
containers:
- name: bot
image: ghcr.io/gotd/bot:main
Expand Down
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,25 @@ and ensuring stability.
* `/json` - inspects replied message
* `/dice` - sends dice
* `/stat` - prints metrics

## Skip deploy

Add `!skip` to commit message.

## Migrations

### Add migration

To add migration named `some-migration-name`:

```console
atlas migrate --env dev diff some-migration-name
```

## Golden files

In package directory:

```console
go test -update
```
9 changes: 9 additions & 0 deletions atlas.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Define an environment named "local"
env "dev" {
// Define the URL of the Dev Database for this environment
// See: https://atlasgo.io/concepts/dev-database
dev = "docker://postgres/15/test?search_path=public"

# use at least atlas version v0.10.2-7425aae-canary
src = "ent://internal/ent/schema"
}
55 changes: 55 additions & 0 deletions go.sum

Large diffs are not rendered by default.

33 changes: 33 additions & 0 deletions internal/ent/entc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//go:build ignore
// +build ignore

package main

import (
"log"

"entgo.io/ent/entc"
"entgo.io/ent/entc/gen"
"github.com/go-faster/errors"
)

func main() {
if err := run(); err != nil {
log.Fatalf("error: %v", err)
}
}

func run() error {
if err := entc.Generate("./schema", &gen.Config{
Features: []gen.Feature{
gen.FeatureUpsert,
gen.FeatureVersionedMigration,
gen.FeatureIntercept,
gen.FeatureNamedEdges,
},
}); err != nil {
return errors.Wrap(err, "ent codegen")
}

return nil
}
3 changes: 3 additions & 0 deletions internal/ent/generate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package ent

//go:generate go run ./entc.go
22 changes: 22 additions & 0 deletions internal/ent/schema/session.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package schema

import (
"entgo.io/ent"
"entgo.io/ent/schema/field"
"github.com/google/uuid"
)

type TelegramSession struct {
ent.Schema
}

func (TelegramSession) Fields() []ent.Field {
return []ent.Field{
field.UUID("id", uuid.New()),
field.Bytes("data"),
}
}

func (TelegramSession) Edges() []ent.Edge {
return []ent.Edge{}
}
56 changes: 56 additions & 0 deletions internal/ent/schema/state.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package schema

import (
"entgo.io/ent"
"entgo.io/ent/schema/field"
"entgo.io/ent/schema/index"
)

// LastChannelMessage holds the last message ID of Telegram channel.
//
// We use it to compute how many messages were sent between PR event notification
// and last messsage, since Telegram does not allow to bots to query messages in a channel.
//
// The number of messages is used to find out if old event notification is out of context
// and we should send a new message for a new event instead of editing.
type LastChannelMessage struct {
ent.Schema
}

func (LastChannelMessage) Fields() []ent.Field {
return []ent.Field{
field.Int64("id").Unique().Immutable().Comment("Telegram channel ID."),
field.Int("message_id").Comment("Telegram message ID of last observed message in channel."),
}
}

func (LastChannelMessage) Edges() []ent.Edge {
return []ent.Edge{}
}

type PRNotification struct {
ent.Schema
}

func (PRNotification) Fields() []ent.Field {
return []ent.Field{
field.Int64("repo_id").Comment("Github repository ID."),
field.Int("pull_request_id").Comment("Pull request number."),
field.String("pull_request_title").Default("").Comment("Pull request title."),
field.String("pull_request_body").Default("").Comment("Pull request body."),
field.String("pull_request_author_login").Default("").Comment("Pull request author's login."),
// TODO(tdakkota): store notify peer_id.
field.Int("message_id").Comment("Telegram message ID. Belongs to notify channel."),
}
}

func (PRNotification) Indexes() []ent.Index {
return []ent.Index{
index.Fields("repo_id", "pull_request_id").
Unique(),
}
}

func (PRNotification) Edges() []ent.Edge {
return []ent.Edge{}
}
56 changes: 56 additions & 0 deletions internal/ent/schema/telegram_state.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package schema

import (
"entgo.io/ent"
"entgo.io/ent/schema/edge"
"entgo.io/ent/schema/field"
"entgo.io/ent/schema/index"
)

type TelegramUserState struct {
ent.Schema
}

func (TelegramUserState) Fields() []ent.Field {
return []ent.Field{
field.Int64("id").Unique().Comment("User ID"),
field.Int("qts").Default(0),
field.Int("pts").Default(0),
field.Int("date").Default(0),
field.Int("seq").Default(0),
}
}

func (TelegramUserState) Edges() []ent.Edge {
return []ent.Edge{
edge.To("channels", TelegramChannelState.Type),
}
}

type TelegramChannelState struct {
ent.Schema
}

func (TelegramChannelState) Fields() []ent.Field {
return []ent.Field{
field.Int64("channel_id").Comment("Channel id"),
field.Int64("user_id").Comment("User id"),
field.Int("pts").Default(0),
}
}

func (TelegramChannelState) Indexes() []ent.Index {
return []ent.Index{
index.Fields("user_id", "channel_id").Unique(),
}
}

func (TelegramChannelState) Edges() []ent.Edge {
return []ent.Edge{
edge.From("user", TelegramUserState.Type).
Ref("channels").
Field("user_id").
Unique().
Required(),
}
}
14 changes: 14 additions & 0 deletions migrations/20241202075819_init.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
-- Create "last_channel_messages" table
CREATE TABLE "last_channel_messages" ("id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, "message_id" bigint NOT NULL, PRIMARY KEY ("id"));
-- Create "pr_notifications" table
CREATE TABLE "pr_notifications" ("id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, "repo_id" bigint NOT NULL, "pull_request_id" bigint NOT NULL, "pull_request_title" character varying NOT NULL DEFAULT '', "pull_request_body" character varying NOT NULL DEFAULT '', "pull_request_author_login" character varying NOT NULL DEFAULT '', "message_id" bigint NOT NULL, PRIMARY KEY ("id"));
-- Create index "prnotification_repo_id_pull_request_id" to table: "pr_notifications"
CREATE UNIQUE INDEX "prnotification_repo_id_pull_request_id" ON "pr_notifications" ("repo_id", "pull_request_id");
-- Create "telegram_sessions" table
CREATE TABLE "telegram_sessions" ("id" uuid NOT NULL, "data" bytea NOT NULL, PRIMARY KEY ("id"));
-- Create "telegram_user_states" table
CREATE TABLE "telegram_user_states" ("id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, "qts" bigint NOT NULL DEFAULT 0, "pts" bigint NOT NULL DEFAULT 0, "date" bigint NOT NULL DEFAULT 0, "seq" bigint NOT NULL DEFAULT 0, PRIMARY KEY ("id"));
-- Create "telegram_channel_states" table
CREATE TABLE "telegram_channel_states" ("id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, "channel_id" bigint NOT NULL, "pts" bigint NOT NULL DEFAULT 0, "user_id" bigint NOT NULL, PRIMARY KEY ("id"), CONSTRAINT "telegram_channel_states_telegram_user_states_channels" FOREIGN KEY ("user_id") REFERENCES "telegram_user_states" ("id") ON UPDATE NO ACTION ON DELETE NO ACTION);
-- Create index "telegramchannelstate_user_id_channel_id" to table: "telegram_channel_states"
CREATE UNIQUE INDEX "telegramchannelstate_user_id_channel_id" ON "telegram_channel_states" ("user_id", "channel_id");
1 change: 0 additions & 1 deletion migrations/KEEP

This file was deleted.

2 changes: 2 additions & 0 deletions migrations/atlas.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
h1:eedbVlNX32AqqHPWysC6pTUXwuRcNB6S72+ZaB9zp64=
20241202075819_init.sql h1:r0lJLQNwt57c2NIRwSmfUM+3yL/2NOZ4seeGxvzgVj0=
8 changes: 8 additions & 0 deletions tools.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
//go:build tools

package bot

import (
_ "entgo.io/ent/cmd/ent"
_ "github.com/dmarkham/enumer"
)

0 comments on commit ed7403a

Please sign in to comment.