google-app-enginegoogle-app-engine-go

Build error on deploy only: cannot use appengine.AccessToken


A simple Go GAE (Flexible) app I'm writing fails to deploy as soon as I bring in cloud.google.com packages to use Google services. Snippet from deploy log:

...
golang.org/x/oauth2/google
# golang.org/x/oauth2/google
_gopath/src/golang.org/x/oauth2/google/appengine_hook.go:12: cannot use appengine.AccessToken (type func(appengine.Context, ...string) (string, time.Time, error)) as type func("golang.org/x/net/context".Context, ...string) (string, time.Time, error) in assignment
_gopath/src/golang.org/x/oauth2/google/appengine_hook.go:13: cannot use appengine.AppID (type func(appengine.Context) string) as type func("golang.org/x/net/context".Context) string in assignment
...

This can be reproduced locally via go install -v -tags appenginevm within the app to deploy. The app builds and runs fine without the appenginevm tag.

I've just followed the helloworld example and modified it, and can't find anyone else with this problem (a few Google searches yielded nothing useful).

Anyone know how to fix this / what I'm missing?

Thanks in advance. The full program is below.

package main

import (
    "context"
    "fmt"
    "log"
    "net/http"
    "time"

    "cloud.google.com/go/storage"
)

var (
    client *storage.Client
)

func main() {
    ctx := context.Background()

    var err error
    client, err = storage.NewClient(ctx)
    if err != nil {
        log.Fatal(err)
        return
    }
    defer client.Close()

    http.HandleFunc("/_ah/health", healthCheckHandler)
    http.HandleFunc("/", indexHandler)
    log.Print("Listening on http://localhost:8080")
    log.Fatal(http.ListenAndServe(":8080", nil))
}

func httpError(w http.ResponseWriter, err error) {
    log.Println(err)
    http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
}

func healthCheckHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprint(w, "OK")
}

func indexHandler(w http.ResponseWriter, r *http.Request) {
    start := time.Now()

    finish := time.Since(start)
    fmt.Fprintf(w, "Done %v %v", finish)
}

Here is the app.yaml

env: flex
runtime: go

Solution

  • It turned out that I had an old version of the "google.golang.org/appengine" package locally, and what I wasn't aware of is that the "gcloud app deploy" command seems to upload all these dependencies instead of resolving dependencies remotely.

    So my old local copy of this library was breaking the remote compilation process.

    I figured this out purely through curiosity by running "go get -u google.golang.org/appengine" and having it fail:

    package google.golang.org/appengine: google.golang.org/appengine is a custom import path
    for https://github.com/golang/appengine, but
    $GOPATH/src/google.golang.org/appengine is checked out from
    https://github.com/golang/appengine.git
    

    So I nuked that and got a fresh copy, now it all works.

    TL;DR make sure your local packages are all up to date if you get remote compile errors.