Breakable Toy: Go CLI for Gitlab
Yes, this is the way to do error handling in Go. By design, you can't let exceptions propagate to the callers "silently", you have to consider what makes sense at each step. I found that on large-scale projects, it makes it significantly easier to predict and test the error handling behavior of your code. It also forces you to put the error handling first, which (imho) results in more readable, less nested code.
Truly global variables don't exist in Go — if a package foo exports a variable Bar, other packages will have to call foo.Bar to access it. That being said, it pretty much never makes sense to do that. In the example you gave, cmd.go and project.go are in the same package, and all package-level variables are shared, so identifiers conflict. If you want this variable to be shared, it's more readable to put all functions that use it in the same file.
When you want to mock some of your functions, it's the sign that there should probably be an associated interface. You can then "mock" an interface easily, by re-implementing your interface in your tests and making it do whatever you want. I find this more readable and idiomatic than using complex frameworks.


Note on the last question: if your interface has many functions:

type Fooer interface {
    Foo1(string) (string, error)
    Foo2(int) (string, int)
    ...
    // Foo42() []byte
}


and you only want to test Foo1, you can use the following syntax

type fakeFooer struct {
    Fooer
    ret string
}

func (fi fakeFooer) Foo1(_ string) (string, error) {
     return fi.ret, nil
}


and not implement any other functions. fakeFooer{"bar"} will "implement" Fooer, calling Foo1 will do what you expect, and trying to call Foo2 on it will panic (nil pointer dereference).