Skip to content

Commit 81b7b96

Browse files
feat: add support for Edge Functions (#378)
1 parent 1697e53 commit 81b7b96

File tree

2 files changed

+127
-13
lines changed

2 files changed

+127
-13
lines changed

go/porcelain/deploy.go

Lines changed: 67 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ const (
4141
functionUpload
4242

4343
lfsVersionString = "version https://git-lfs.github.com/spec/v1"
44+
45+
edgeFunctionsInternalPath = ".netlify/internal/edge-functions/"
4446
)
4547

4648
var installDirs = []string{"node_modules/", "bower_components/"}
@@ -75,6 +77,7 @@ type DeployOptions struct {
7577
SiteID string
7678
Dir string
7779
FunctionsDir string
80+
EdgeFunctionsDir string
7881
BuildDir string
7982
LargeMediaEnabled bool
8083

@@ -210,6 +213,16 @@ func (n *Netlify) DoDeploy(ctx context.Context, options *DeployOptions, deploy *
210213
}
211214
}
212215

216+
if options.EdgeFunctionsDir != "" {
217+
err = addEdgeFunctionsToDeployFiles(options.EdgeFunctionsDir, files, options.Observer)
218+
if err != nil {
219+
if options.Observer != nil {
220+
options.Observer.OnFailedWalk()
221+
}
222+
return nil, err
223+
}
224+
}
225+
213226
options.files = files
214227

215228
functions, schedules, err := bundle(ctx, options.FunctionsDir, options.Observer)
@@ -513,6 +526,28 @@ func (n *Netlify) uploadFile(ctx context.Context, d *models.Deploy, f *FileBundl
513526
}
514527
}
515528

529+
func createFileBundle(rel, path string) (*FileBundle, error) {
530+
o, err := os.Open(path)
531+
if err != nil {
532+
return nil, err
533+
}
534+
defer o.Close()
535+
536+
file := &FileBundle{
537+
Name: rel,
538+
Path: path,
539+
}
540+
541+
s := sha1.New()
542+
if _, err := io.Copy(s, o); err != nil {
543+
return nil, err
544+
}
545+
546+
file.Sum = hex.EncodeToString(s.Sum(nil))
547+
548+
return file, nil
549+
}
550+
516551
func walk(dir string, observer DeployObserver, useLargeMedia, ignoreInstallDirs bool) (*deployFiles, error) {
517552
files := newDeployFiles()
518553

@@ -532,22 +567,10 @@ func walk(dir string, observer DeployObserver, useLargeMedia, ignoreInstallDirs
532567
return nil
533568
}
534569

535-
o, err := os.Open(path)
570+
file, err := createFileBundle(rel, path)
536571
if err != nil {
537572
return err
538573
}
539-
defer o.Close()
540-
541-
file := &FileBundle{
542-
Name: rel,
543-
Path: path,
544-
}
545-
546-
s := sha1.New()
547-
if _, err := io.Copy(s, o); err != nil {
548-
return err
549-
}
550-
file.Sum = hex.EncodeToString(s.Sum(nil))
551574

552575
if useLargeMedia {
553576
o, err := os.Open(path)
@@ -585,6 +608,37 @@ func walk(dir string, observer DeployObserver, useLargeMedia, ignoreInstallDirs
585608
return files, err
586609
}
587610

611+
func addEdgeFunctionsToDeployFiles(dir string, files *deployFiles, observer DeployObserver) error {
612+
return filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
613+
if err != nil {
614+
return err
615+
}
616+
617+
if !info.IsDir() && info.Mode().IsRegular() {
618+
osRel, err := filepath.Rel(dir, path)
619+
if err != nil {
620+
return err
621+
}
622+
rel := edgeFunctionsInternalPath + forceSlashSeparators(osRel)
623+
624+
file, err := createFileBundle(rel, path)
625+
if err != nil {
626+
return err
627+
}
628+
629+
files.Add(rel, file)
630+
631+
if observer != nil {
632+
if err := observer.OnSuccessfulStep(file); err != nil {
633+
return err
634+
}
635+
}
636+
}
637+
638+
return nil
639+
})
640+
}
641+
588642
func bundle(ctx context.Context, functionDir string, observer DeployObserver) (*deployFiles, []*models.FunctionSchedule, error) {
589643
if functionDir == "" {
590644
return nil, nil, nil

go/porcelain/deploy_test.go

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,66 @@ func TestWalk_IgnoreNodeModulesInRoot(t *testing.T) {
170170
assert.NotNil(t, files.Files["more/node_modules/inner-package"])
171171
}
172172

173+
func TestWalk_EdgeFunctions(t *testing.T) {
174+
files := newDeployFiles()
175+
176+
netlifyDir, err := ioutil.TempDir("", ".netlify")
177+
require.Nil(t, err)
178+
defer os.RemoveAll(netlifyDir)
179+
180+
edgeFunctionsDir, err := ioutil.TempDir(netlifyDir, "edge-functions-dist")
181+
require.Nil(t, err)
182+
defer os.RemoveAll(edgeFunctionsDir)
183+
184+
err = ioutil.WriteFile(filepath.Join(edgeFunctionsDir, "manifest.json"), []byte{}, 0644)
185+
require.Nil(t, err)
186+
err = ioutil.WriteFile(filepath.Join(edgeFunctionsDir, "123456789.js"), []byte{}, 0644)
187+
require.Nil(t, err)
188+
189+
err = addEdgeFunctionsToDeployFiles(edgeFunctionsDir, files, mockObserver{})
190+
require.Nil(t, err)
191+
192+
assert.NotNil(t, files.Files[".netlify/internal/edge-functions/manifest.json"])
193+
assert.NotNil(t, files.Files[".netlify/internal/edge-functions/123456789.js"])
194+
}
195+
196+
func TestWalk_PublishedFilesAndEdgeFunctions(t *testing.T) {
197+
publishDir, err := ioutil.TempDir("", "publish")
198+
require.Nil(t, err)
199+
defer os.RemoveAll(publishDir)
200+
201+
netlifyDir, err := ioutil.TempDir("", ".netlify")
202+
require.Nil(t, err)
203+
defer os.RemoveAll(netlifyDir)
204+
205+
edgeFunctionsDir, err := ioutil.TempDir(netlifyDir, "edge-functions-dist")
206+
require.Nil(t, err)
207+
defer os.RemoveAll(edgeFunctionsDir)
208+
209+
err = os.Mkdir(filepath.Join(publishDir, "assets"), os.ModePerm)
210+
require.Nil(t, err)
211+
err = ioutil.WriteFile(filepath.Join(publishDir, "assets", "styles.css"), []byte{}, 0644)
212+
require.Nil(t, err)
213+
err = ioutil.WriteFile(filepath.Join(publishDir, "index.html"), []byte{}, 0644)
214+
require.Nil(t, err)
215+
216+
err = ioutil.WriteFile(filepath.Join(edgeFunctionsDir, "manifest.json"), []byte{}, 0644)
217+
require.Nil(t, err)
218+
err = ioutil.WriteFile(filepath.Join(edgeFunctionsDir, "123456789.js"), []byte{}, 0644)
219+
require.Nil(t, err)
220+
221+
files, err := walk(publishDir, mockObserver{}, false, false)
222+
require.Nil(t, err)
223+
224+
err = addEdgeFunctionsToDeployFiles(edgeFunctionsDir, files, mockObserver{})
225+
require.Nil(t, err)
226+
227+
assert.NotNil(t, files.Files["assets/styles.css"])
228+
assert.NotNil(t, files.Files["index.html"])
229+
assert.NotNil(t, files.Files[".netlify/internal/edge-functions/manifest.json"])
230+
assert.NotNil(t, files.Files[".netlify/internal/edge-functions/123456789.js"])
231+
}
232+
173233
func TestUploadFiles_Cancelation(t *testing.T) {
174234
ctx, cancel := gocontext.WithCancel(gocontext.Background())
175235
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {

0 commit comments

Comments
 (0)