-
Notifications
You must be signed in to change notification settings - Fork 228
/
Copy pathdeploy.go
134 lines (129 loc) · 4.86 KB
/
deploy.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
package deploy
import (
"context"
"fmt"
"os"
"path/filepath"
"strings"
"github.com/go-errors/errors"
"github.com/spf13/afero"
"github.com/supabase/cli/internal/utils"
"github.com/supabase/cli/internal/utils/flags"
"github.com/supabase/cli/pkg/cast"
"github.com/supabase/cli/pkg/config"
"github.com/supabase/cli/pkg/function"
)
func Run(ctx context.Context, slugs []string, projectRef string, noVerifyJWT *bool, importMapPath string, fsys afero.Fs) error {
// Load function config and project id
if err := flags.LoadConfig(fsys); err != nil {
return err
} else if len(slugs) > 0 {
for _, s := range slugs {
if err := utils.ValidateFunctionSlug(s); err != nil {
return err
}
}
} else if slugs, err = GetFunctionSlugs(fsys); err != nil {
return err
}
// TODO: require all functions to be deployed from config for v2
if len(slugs) == 0 {
return errors.Errorf("No Functions specified or found in %s", utils.Bold(utils.FunctionsDir))
}
functionConfig, err := GetFunctionConfig(slugs, importMapPath, noVerifyJWT, fsys)
if err != nil {
return err
}
api := function.NewEdgeRuntimeAPI(projectRef, *utils.GetSupabase(), NewDockerBundler(fsys))
if err := api.UpsertFunctions(ctx, functionConfig); err != nil {
return err
}
fmt.Printf("Deployed Functions on project %s: %s\n", utils.Aqua(projectRef), strings.Join(slugs, ", "))
url := fmt.Sprintf("%s/project/%v/functions", utils.GetSupabaseDashboardURL(), projectRef)
fmt.Println("You can inspect your deployment in the Dashboard: " + url)
return nil
}
func GetFunctionSlugs(fsys afero.Fs) (slugs []string, err error) {
pattern := filepath.Join(utils.FunctionsDir, "*", "index.ts")
paths, err := afero.Glob(fsys, pattern)
if err != nil {
return nil, errors.Errorf("failed to glob function slugs: %w", err)
}
for _, path := range paths {
slug := filepath.Base(filepath.Dir(path))
if utils.FuncSlugPattern.MatchString(slug) {
slugs = append(slugs, slug)
}
}
// Add all function slugs declared in config file
for slug := range utils.Config.Functions {
slugs = append(slugs, slug)
}
return slugs, nil
}
func GetFunctionConfig(slugs []string, importMapPath string, noVerifyJWT *bool, fsys afero.Fs) (config.FunctionConfig, error) {
// Although some functions do not require import map, it's more convenient to setup
// vscode deno extension with a single import map for all functions.
fallbackExists := true
functionsUsingDeprecatedGlobalFallback := []string{}
functionsUsingDeprecatedImportMap := []string{}
if _, err := fsys.Stat(utils.FallbackImportMapPath); errors.Is(err, os.ErrNotExist) {
fallbackExists = false
} else if err != nil {
return nil, errors.Errorf("failed to fallback import map: %w", err)
}
// Flag import map is specified relative to current directory instead of workdir
if len(importMapPath) > 0 && !filepath.IsAbs(importMapPath) {
importMapPath = filepath.Join(utils.CurrentDirAbs, importMapPath)
}
functionConfig := make(config.FunctionConfig, len(slugs))
for _, name := range slugs {
function := utils.Config.Functions[name]
// Precedence order: flag > config > fallback
functionDir := filepath.Join(utils.FunctionsDir, name)
if len(function.Entrypoint) == 0 {
function.Entrypoint = filepath.Join(functionDir, "index.ts")
}
if len(importMapPath) > 0 {
function.ImportMap = importMapPath
} else if len(function.ImportMap) == 0 {
denoJsonPath := filepath.Join(functionDir, "deno.json")
denoJsoncPath := filepath.Join(functionDir, "deno.jsonc")
importMapPath := filepath.Join(functionDir, "import_map.json")
if _, err := fsys.Stat(denoJsonPath); err == nil {
function.ImportMap = denoJsonPath
} else if _, err := fsys.Stat(denoJsoncPath); err == nil {
function.ImportMap = denoJsoncPath
} else if _, err := fsys.Stat(importMapPath); err == nil {
function.ImportMap = importMapPath
functionsUsingDeprecatedImportMap = append(functionsUsingDeprecatedImportMap, name)
} else if fallbackExists {
function.ImportMap = utils.FallbackImportMapPath
functionsUsingDeprecatedGlobalFallback = append(functionsUsingDeprecatedGlobalFallback, name)
}
}
if noVerifyJWT != nil {
function.VerifyJWT = cast.Ptr(!*noVerifyJWT)
}
functionConfig[name] = function
}
if len(functionsUsingDeprecatedImportMap) > 0 {
fmt.Fprintln(os.Stderr,
utils.Yellow("WARNING:"),
"Functions using deprecated import_map.json (please migrate to deno.json):",
utils.Aqua(strings.Join(functionsUsingDeprecatedImportMap, ", ")),
)
}
if len(functionsUsingDeprecatedGlobalFallback) > 0 {
fmt.Fprintln(os.Stderr,
utils.Yellow("WARNING:"),
"Functions using fallback import map:",
utils.Aqua(strings.Join(functionsUsingDeprecatedGlobalFallback, ", ")),
)
fmt.Fprintln(os.Stderr,
"Please use recommended per function dependency declaration ",
utils.Aqua("https://supabase.com/docs/guides/functions/import-maps"),
)
}
return functionConfig, nil
}