Skip to content

Commit

Permalink
Add cli tooling to run migrations directly (#145)
Browse files Browse the repository at this point in the history
* update readme

* fixes

* add migrate cmd

* add migrate cmd

* fix path

* update readme
  • Loading branch information
adelowo authored Feb 1, 2025
1 parent 101a434 commit 4fd334e
Show file tree
Hide file tree
Showing 8 changed files with 183 additions and 5 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ tidy_dependencies:
go mod tidy

migrate:
migrate -path ./internal/datastore/postgres/migrations/ -database "postgres://malak:malak@localhost:9432/malak?sslmode=disable" up
go run cmd/*.go migrate

migrate-down:
migrate -path ./internal/datastore/postgres/migrations/ -database "postgres://malak:malak@localhost:9432/malak?sslmode=disable" down
Expand Down
115 changes: 113 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,17 @@ That's where Malak comes in. Self-hosted on your own infra or hosted by us.
White-label by design. Ready to be deployed on your own domain.
Own full control of your data and company state if you decide to selfhost.

- [Features](#features)
- [FAQs](#faqs)
- [Self hosting](#self-hosting)
- [Frontend](#frontend)
- [Migrations](#migrations)
- [Backend](#backend)

## Features

> [!WARNING]
> Actively being built and not ready yet :)
> [!NOTE]
> Hosted version available by mid March :)
- 100% Opensource. Own your own data, metrics, and story
- Send investors' updates to anyone via email
Expand All @@ -34,6 +41,110 @@ Own full control of your data and company state if you decide to selfhost.
- Tailwind CSS
- Stripe ( optional )

## Self-hosting

### Migrations

```sh
malak migrate
```

> [!IMPORTANT]
> Everytime you upgrade the backend or re-download the binary/docker image,
> it makes sense to run the migrations again as migrations are usually added to
> support newer
> features or enhance existing ones
### Backend

You can either download the raw binary or use our docker image. You can view
a list of all available releases on [Github](https://github.com/ayinke-llc/malak/releases).

The docker image is also available as `docker pull ghcr.io/ayinke-llc/malak:version`
where `version` can be the version you want. The version can be in two formats:

- semver version number e.g: `docker pull ghcr.io/ayinke-llc/malak:0.4.2`
- commit hash e.g: `docker pull ghcr.io/ayinke-llc/malak:101a434d`

Plans are extremely important in Malak. Even though you are self hosting
and not taking payments, you can still limit certain features for users
on your instance. Every company/workspace must be have a plan.

At the very minimum, your configuration needs to look like this:

> [!IMPORTANT]
> You can also use environment values to configure this in cloud environments
> using the syntax `MALAK_`. So for `auth.google.client_id`, you can use `MALAK_AUTH_GOOGLE_CLIENT_ID`
Your `config.yml` below:

```yml
auth:
google:
client_id: "GOOGLE_CLIENT_ID"
client_secret: "GOOGLE_CLIENT_SECRET"
redirect_uri: "GOOGLE_REDIRECT_URI"
is_enabled: true

jwt:
key: YOUR_SECRET_KEY

uploader:
s3:
access_key: YOUR_ACCESS_KEY
access_secret: YOUR_SECRET_KEY
region: lagos-1
endpoint: http://localhost:9000
use_tls: false

email:
provider: smtp # OR resend
sender: email@yourdomain
sender_name: Malak
resend:
api_key: RESEND_API_KEY
smtp:
host: localhost
password: random
username: random
use_tls: false
port: 9125
```
You can view a complete list of all available configuration here.
#### Listing plans
```sh
malak plans list
```

#### Create a new plan

```sh
malak plans create
```

#### Set a default plan for newly created workspaces

```sh
malak plans set-default plan_id
```

### Frontend

```env
NEXT_PUBLIC_GOOGLE_CLIENT_ID=
NEXT_PUBLIC_MALAK_POSTHOG_KEY=
NEXT_PUBLIC_MALAK_ENABLE_POSTHOG=
NEXT_PUBLIC_MALAK_POSTHOG_HOST=
NEXT_PUBLIC_MALAK_TERMS_CONDITION_LINK=
NEXT_PUBLIC_MALAK_PRIVACY_POLICY_LINK=
NEXT_PUBLIC_SENTRY_DSN=
NEXT_PUBLIC_DECKS_DOMAIN=https://deck.yourdowmain
NEXT_PUBLIC_SUPPORT_EMAIL=support@yourdomain
```

## FAQs

### Managing Minio
Expand Down
2 changes: 1 addition & 1 deletion cmd/integration.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import (
func addIntegrationCommand(c *cobra.Command, cfg *config.Config) {

cmd := &cobra.Command{
Use: "integration",
Use: "integrations",
Short: "Manage your system wide integrations",
}

Expand Down
1 change: 1 addition & 0 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ func Execute() error {
addCronCommand(rootCmd, cfg)
addPlanCommand(rootCmd, cfg)
addIntegrationCommand(rootCmd, cfg)
addMigrateCommand(rootCmd, cfg)

return rootCmd.Execute()
}
Expand Down
58 changes: 58 additions & 0 deletions cmd/migrate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package main

import (
"errors"

"github.com/ayinke-llc/hermes"
"github.com/ayinke-llc/malak"
"github.com/ayinke-llc/malak/config"
"github.com/golang-migrate/migrate/v4"
_ "github.com/golang-migrate/migrate/v4/database/postgres"
"github.com/golang-migrate/migrate/v4/source/iofs"
"github.com/spf13/cobra"
"go.uber.org/zap"
)

func addMigrateCommand(c *cobra.Command, cfg *config.Config) {

cmd := &cobra.Command{
Use: "migrate",
Short: "Migrate your database to the latest version",
RunE: func(cmd *cobra.Command, args []string) error {

logger, err := getLogger(hermes.DeRef(cfg))
if err != nil {
return err
}

logger.Debug("Migrating the database to the latest version")

d, err := iofs.New(malak.Migrations, "internal/datastore/postgres/migrations")
if err != nil {
logger.Error("could not set up embedded migrations", zap.Error(err))
return err
}

m, err := migrate.NewWithSourceInstance("iofs", d, cfg.Database.Postgres.DSN)
if err != nil {
logger.Error("could not set up migrations", zap.Error(err))
return err
}

err = m.Up()
if errors.Is(err, migrate.ErrNoChange) {
logger.Info("no new migration to run")
return nil
}

if err != nil {
logger.Error("could not run migrations", zap.Error(err))
return err
}

return nil
},
}

c.AddCommand(cmd)
}
3 changes: 2 additions & 1 deletion cmd/plan.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ import (
func addPlanCommand(c *cobra.Command, cfg *config.Config) {

cmd := &cobra.Command{
Use: "plan",
Use: "plans",
Short: "Manage your plans",
}

cmd.AddCommand(listPlans(c, cfg))
Expand Down
6 changes: 6 additions & 0 deletions migrate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package malak

import "embed"

//go:embed internal/datastore/postgres/migrations
var Migrations embed.FS
1 change: 1 addition & 0 deletions web/ui/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ NEXT_PUBLIC_MALAK_TERMS_CONDITION_LINK=
NEXT_PUBLIC_MALAK_PRIVACY_POLICY_LINK=
NEXT_PUBLIC_SENTRY_DSN=
NEXT_PUBLIC_DECKS_DOMAIN=https://deck.malak.vc
NEXT_PUBLIC_SUPPORT_EMAIL=support@ayinke.ventures

0 comments on commit 4fd334e

Please sign in to comment.