Skip to content
Draft
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
9 changes: 9 additions & 0 deletions pkg/helpers/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,21 @@ import (
buildx "github.com/docker/buildx/build"
)

// ErrMissingProjectID is returned by BeginBuild when no project ID can be
// resolved from the command line, environment, or depot.json. The message is
// surfaced to users (including via depot/build-push-action) and is intended to
// be actionable so they don't have to debug a misleading authentication error.
var ErrMissingProjectID = errors.New(`no project ID specified. Please provide a project ID via the --project flag, the DEPOT_PROJECT_ID environment variable (the build-push-action sets this from its "project" input), or by adding a depot.json file to your project root (run "depot init")`)

func BeginBuild(ctx context.Context, req *cliv1.CreateBuildRequest, token string) (depotbuild.Build, error) {
var build depotbuild.Build
var err error
if id := os.Getenv("DEPOT_BUILD_ID"); id != "" {
build, err = depotbuild.FromExistingBuild(ctx, id, token, nil)
} else {
if req.GetProjectId() == "" {
return depotbuild.Build{}, ErrMissingProjectID
}
build, err = depotbuild.NewBuild(ctx, req, token)
}
if err != nil {
Expand Down
56 changes: 56 additions & 0 deletions pkg/helpers/build_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package helpers

import (
"context"
"errors"
"strings"
"testing"

cliv1 "github.com/depot/cli/pkg/proto/depot/cli/v1"
)

func TestBeginBuildReturnsClearErrorWhenProjectIDMissing(t *testing.T) {
// Make sure we don't accidentally take the DEPOT_BUILD_ID branch.
t.Setenv("DEPOT_BUILD_ID", "")

cases := []struct {
name string
req *cliv1.CreateBuildRequest
}{
{
name: "nil ProjectId",
req: &cliv1.CreateBuildRequest{},
},
{
name: "empty string ProjectId",
req: &cliv1.CreateBuildRequest{ProjectId: stringPtr("")},
},
}

for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
_, err := BeginBuild(context.Background(), tc.req, "fake-token")
if err == nil {
t.Fatal("expected an error, got nil")
}
if !errors.Is(err, ErrMissingProjectID) {
t.Fatalf("expected ErrMissingProjectID, got %v", err)
}
// Sanity check that the message stays actionable for users.
msg := err.Error()
for _, want := range []string{
"no project ID specified",
"--project",
"DEPOT_PROJECT_ID",
"depot.json",
"depot init",
} {
if !strings.Contains(msg, want) {
t.Errorf("error message missing %q: %s", want, msg)
}
}
})
}
}

func stringPtr(s string) *string { return &s }
Loading