Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions internal/functions/deploy/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,20 @@ func Run(ctx context.Context, slugs []string, useDocker bool, noVerifyJWT *bool,
if utils.IsDockerRunning(ctx) {
opt = function.WithBundler(NewDockerBundler(fsys))
} else {
// Bundling static_files requires the eszip bundler, which only runs
// inside the edge-runtime Docker image. Without Docker, the API
// upload path silently drops static_files and the deployed function
// ships without them. Fail fast so the user can start Docker or
// switch to --use-api with static_files removed.
var withStatic []string
for slug, fc := range functionConfig {
if fc.Enabled && len(fc.StaticFiles) > 0 {
withStatic = append(withStatic, slug)
}
}
if len(withStatic) > 0 {
return errors.Errorf("Docker is not running, but static_files is configured for: %s.\nStart Docker and re-run, or remove static_files from config.toml.", strings.Join(withStatic, ", "))
}
fmt.Fprintln(os.Stderr, utils.Yellow("WARNING:"), "Docker is not running")
}
}
Expand Down
38 changes: 38 additions & 0 deletions internal/functions/deploy/deploy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ package deploy
import (
"context"
"fmt"
"net"
"net/http"
"net/url"
"os"
"path/filepath"
"testing"

"github.com/docker/docker/client"
"github.com/h2non/gock"
"github.com/spf13/afero"
"github.com/spf13/viper"
Expand Down Expand Up @@ -199,6 +201,42 @@ import_map = "./import_map.json"
assert.ErrorContains(t, err, "Invalid Function name.")
})

t.Run("throws error when static_files configured but Docker not running", func(t *testing.T) {
t.Cleanup(func() { clear(utils.Config.Functions) })
// Point docker client at an unreachable host to simulate daemon down.
// WithHost needs an *http.Transport on the client, so install one first.
require.NoError(t, client.WithHTTPClient(&http.Client{Transport: &http.Transport{}})(utils.Docker))
listener, err := net.Listen("tcp", "127.0.0.1:0")
require.NoError(t, err)
unreachable := "tcp://" + listener.Addr().String()
require.NoError(t, listener.Close())
require.NoError(t, client.WithHost(unreachable)(utils.Docker))
// Setup in-memory fs with static_files configured
fsys := afero.NewMemMapFs()
require.NoError(t, utils.WriteConfig(fsys, false))
f, err := fsys.OpenFile(utils.ConfigPath, os.O_APPEND|os.O_WRONLY, 0600)
require.NoError(t, err)
_, err = f.WriteString(`
[functions.` + slug + `]
static_files = ["./functions/` + slug + `/templates/*.html"]
`)
require.NoError(t, err)
require.NoError(t, f.Close())
entrypointPath := filepath.Join(utils.FunctionsDir, slug, "index.ts")
require.NoError(t, afero.WriteFile(fsys, entrypointPath, []byte{}, 0644))
templatePath := filepath.Join(utils.FunctionsDir, slug, "templates", "welcome.html")
require.NoError(t, afero.WriteFile(fsys, templatePath, []byte("<html></html>"), 0644))
// Setup valid access token
token := apitest.RandomAccessToken(t)
t.Setenv("SUPABASE_ACCESS_TOKEN", string(token))
// Run test
err = Run(context.Background(), []string{slug}, true, nil, "", 1, false, fsys)
// Check error: deploy must fail loudly rather than silently dropping static files
assert.ErrorContains(t, err, "Docker is not running")
assert.ErrorContains(t, err, "static_files")
assert.ErrorContains(t, err, slug)
})

t.Run("throws error on empty functions", func(t *testing.T) {
// Setup in-memory fs
fsys := afero.NewMemMapFs()
Expand Down