Here's how we can formulate this problem and generate the Gurobi code:

**Decision Variables:**

* `t`: Number of taro bubble teas made.
* `m`: Number of mango bubble teas made.

**Objective Function:**

Maximize profit: `4t + 6m`

**Constraints:**

* Taro constraint: `3t <= 60`
* Mango constraint: `3m <= 60`
* Milk constraint: `4t + 5m <= 140`
* Non-negativity constraints: `t >= 0`, `m >= 0`


```python
import gurobipy as gp

# Create a new model
model = gp.Model("BubbleTeaOptimization")

# Create decision variables
t = model.addVar(vtype=gp.GRB.CONTINUOUS, name="taro_teas")
m = model.addVar(vtype=gp.GRB.CONTINUOUS, name="mango_teas")

# Set objective function
model.setObjective(4 * t + 6 * m, gp.GRB.MAXIMIZE)

# Add constraints
model.addConstr(3 * t <= 60, "taro_constraint")
model.addConstr(3 * m <= 60, "mango_constraint")
model.addConstr(4 * t + 5 * m <= 140, "milk_constraint")

# Optimize model
model.optimize()

# Print results
if model.status == gp.GRB.OPTIMAL:
    print(f"Optimal Solution Found:")
    print(f"Number of Taro Bubble Teas: {t.x}")
    print(f"Number of Mango Bubble Teas: {m.x}")
    print(f"Maximum Profit: ${model.objVal}")
elif model.status == gp.GRB.INFEASIBLE:
    print("Model is infeasible.")
else:
    print(f"Optimization terminated with status: {model.status}")

```
