1// Copyright 2020 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5package main 6 7import ( 8 "context" 9 "flag" 10 "os" 11 "path/filepath" 12 "strings" 13 14 "cloud.google.com/go/storage" 15 "go.skia.org/infra/go/auth" 16 "go.skia.org/infra/go/skerr" 17 "go.skia.org/infra/task_driver/go/lib/auth_steps" 18 "go.skia.org/infra/task_driver/go/lib/docker" 19 "go.skia.org/infra/task_driver/go/lib/os_steps" 20 "go.skia.org/infra/task_driver/go/td" 21) 22 23const dockerImage = "gcr.io/skia-public/canvaskit-emsdk:3.1.26_v2" 24const innerBuildScript = "/SRC/infra/canvaskit/build_gmtests.sh" 25 26func main() { 27 var ( 28 // Required properties for this task. 29 outPath = flag.String("out_path", "", "The directory to put the built wasm/js code.") 30 projectID = flag.String("project_id", "", "ID of the Google Cloud project.") 31 skiaPath = flag.String("skia_path", "", "Path to skia repo root.") 32 taskID = flag.String("task_id", "", "task id this data was generated on") 33 taskName = flag.String("task_name", "", "Name of the task.") 34 workPath = flag.String("work_path", "", "The directory to use to store temporary files (e.g. docker build)") 35 36 // Debugging flags. 37 local = flag.Bool("local", false, "True if running locally (as opposed to on the bots)") 38 outputSteps = flag.String("o", "", "If provided, dump a JSON blob of step data to the given file. Prints to stdout if '-' is given.") 39 ) 40 41 // Setup. 42 ctx := td.StartRun(projectID, taskID, taskName, outputSteps, local) 43 defer td.EndRun(ctx) 44 45 outAbsPath := td.MustGetAbsolutePathOfFlag(ctx, *outPath, "out_path") 46 skiaAbsPath := td.MustGetAbsolutePathOfFlag(ctx, *skiaPath, "skia_path") 47 workAbsPath := td.MustGetAbsolutePathOfFlag(ctx, *workPath, "work_path") 48 49 if err := os_steps.MkdirAll(ctx, workAbsPath); err != nil { 50 td.Fatal(ctx, err) 51 } 52 if err := os_steps.MkdirAll(ctx, outAbsPath); err != nil { 53 td.Fatal(ctx, err) 54 } 55 56 doc, err := setupDocker(ctx, *local) 57 if err != nil { 58 td.Fatal(ctx, err) 59 } 60 defer func() { _ = doc.Cleanup(ctx) }() 61 62 command := []string{innerBuildScript} 63 volumes := []string{skiaAbsPath + ":/SRC", workAbsPath + ":/OUT"} 64 65 if err := doc.Run(ctx, dockerImage, command, volumes, nil); err != nil { 66 td.Fatal(ctx, err) 67 } 68 69 if err := extractOutput(ctx, workAbsPath, outAbsPath); err != nil { 70 td.Fatal(ctx, err) 71 } 72} 73 74func setupDocker(ctx context.Context, isLocal bool) (*docker.Docker, error) { 75 ctx = td.StartStep(ctx, td.Props("setup docker").Infra()) 76 defer td.EndStep(ctx) 77 // Create token source with scope for cloud registry (storage). 78 ts, err := auth_steps.Init(ctx, isLocal, auth.ScopeUserinfoEmail, storage.ScopeReadOnly) 79 if err != nil { 80 return nil, td.FailStep(ctx, err) 81 } 82 83 return docker.New(ctx, ts) 84} 85 86func extractOutput(ctx context.Context, workDir, outAbsPath string) error { 87 ctx = td.StartStep(ctx, td.Props("copy compiled JS and wasm into output")) 88 defer td.EndStep(ctx) 89 90 files, err := os_steps.ReadDir(ctx, workDir) 91 if err != nil { 92 return td.FailStep(ctx, skerr.Wrapf(err, "getting output from %s", workDir)) 93 } 94 95 for _, f := range files { 96 name := f.Name() 97 if strings.Contains(name, "wasm_gm_tests") { 98 oldFile := filepath.Join(workDir, name) 99 newFile := filepath.Join(outAbsPath, name) 100 if err := os.Rename(oldFile, newFile); err != nil { 101 return td.FailStep(ctx, skerr.Wrapf(err, "copying %s to %s", oldFile, newFile)) 102 } 103 } 104 } 105 return nil 106} 107