Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tail Up #86

Merged
merged 54 commits into from
Apr 10, 2021
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
54 commits
Select commit Hold shift click to select a range
7fb1b1b
Deployment Logs in CLI
JakeCooper Apr 7, 2021
c5b9fce
Deploy Logs in CLI
JakeCooper Apr 7, 2021
65c97a8
Live log tail
JakeCooper Apr 7, 2021
eb0d866
Remove loggin code
JakeCooper Apr 7, 2021
6d40cda
Update main.go
JakeCooper Apr 7, 2021
d9d2c94
Add detached flag
JakeCooper Apr 7, 2021
195c813
Merge branch 'cooper/deployment-logs' of github.com:railwayapp/cli in…
JakeCooper Apr 7, 2021
a156456
Don't fetch all deployments everytime
JakeCooper Apr 7, 2021
37d8166
Remove up command
JakeCooper Apr 7, 2021
4219921
Add line number
JakeCooper Apr 7, 2021
5160c21
Comment
JakeCooper Apr 7, 2021
790cf2f
Tail up on deploy
JakeCooper Apr 7, 2021
4318461
Cant spell FML
JakeCooper Apr 7, 2021
f89e601
Fix flag err
JakeCooper Apr 7, 2021
68bdaae
Merge branch 'cooper/deployment-logs' into cooper/tail-up
JakeCooper Apr 7, 2021
d69764e
Re add tail detach for up
JakeCooper Apr 7, 2021
14111a3
use latest deploy
JakeCooper Apr 7, 2021
43667d6
Remove println
JakeCooper Apr 7, 2021
c5e2e7d
Remove status indicator
JakeCooper Apr 7, 2021
8211097
Merge branch 'cooper/deployment-logs' into cooper/tail-up
JakeCooper Apr 7, 2021
0b4742e
Custom errors
JakeCooper Apr 8, 2021
7561a47
Factor out incorrect errors
JakeCooper Apr 8, 2021
605131c
Filter out removed
JakeCooper Apr 8, 2021
be59758
Tail up
JakeCooper Apr 8, 2021
56874e1
Fix pointer walk
JakeCooper Apr 8, 2021
26872fb
Update main.go
JakeCooper Apr 8, 2021
eaee90c
Flatten root cmd
JakeCooper Apr 8, 2021
ebe870e
Remove helper wrapper
JakeCooper Apr 8, 2021
b903df0
Remove helper flag
JakeCooper Apr 8, 2021
eadea0d
Merge branch 'cooper/deployment-logs' into cooper/tail-up
JakeCooper Apr 8, 2021
99e2392
Merge branch 'master' into cooper/tail-up
JakeCooper Apr 8, 2021
1612327
Fix print offset
JakeCooper Apr 8, 2021
3d0a471
WTF
JakeCooper Apr 8, 2021
e758abe
As if this section wasn't confusing enough
JakeCooper Apr 8, 2021
435862f
Use print
JakeCooper Apr 8, 2021
e0d29e8
Merge branch 'cooper/fix-offset-print' into cooper/tail-up
JakeCooper Apr 8, 2021
87a4ae6
Merge branch 'master' into cooper/tail-up
JakeCooper Apr 8, 2021
33b3dd1
Merge branch 'master' into cooper/tail-up
JakeCooper Apr 8, 2021
8ee0741
Support build log timeouts newlines
JakeCooper Apr 9, 2021
dc4499f
Attach to cloud build line
JakeCooper Apr 9, 2021
ae3b695
No idxMp
JakeCooper Apr 9, 2021
cb6016e
Remove unused function
JakeCooper Apr 9, 2021
3a8c17d
Move prevwalk up
JakeCooper Apr 9, 2021
3b7edab
Remove todo since it's done
JakeCooper Apr 9, 2021
0a0f732
Big refactory
JakeCooper Apr 9, 2021
bc7e15d
Remove unused
JakeCooper Apr 9, 2021
dcd5ac5
Fix NPE
JakeCooper Apr 9, 2021
00cbe76
GQL soft error
JakeCooper Apr 9, 2021
c85ae11
Handle build failure
JakeCooper Apr 9, 2021
9596b7c
Do not export active state
JakeCooper Apr 9, 2021
4267093
Remove surperfluous build function
JakeCooper Apr 9, 2021
1fa5ca9
Only check logs once
JakeCooper Apr 9, 2021
8441dd9
Added lil railway logs fin
JakeCooper Apr 9, 2021
ddcc28f
Deploy logs
JakeCooper Apr 9, 2021
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
3 changes: 2 additions & 1 deletion cmd/design.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 3,15 @@ package cmd
import (
"context"
"fmt"

"github.com/railwayapp/cli/entity"
"github.com/railwayapp/cli/ui"
)

func (h *Handler) Design(ctx context.Context, req *entity.CommandRequest) error {
fmt.Print(ui.Heading("Alerts"))
fmt.Print(ui.AlertDanger("Something bad is going to happen!"))
fmt.Print(ui.AlertWarning("That might not hve been what you wanted"))
fmt.Print(ui.AlertWarning("That might not have been what you wanted"))
fmt.Print(ui.AlertInfo("Just so you know you know, Railway is awesome"))

fmt.Println("")
Expand Down
15 changes: 15 additions & 0 deletions cmd/logs.go
Original file line number Diff line number Diff line change
@@ -0,0 1,15 @@
package cmd

import (
"context"

"github.com/railwayapp/cli/entity"
)

func (h *Handler) Logs(ctx context.Context, req *entity.CommandRequest) error {
numLines, err := req.Cmd.Flags().GetInt32("num_lines")
if err != nil {
return err
}
return h.ctrl.GetActiveDeploymentLogs(ctx, numLines)
}
9 changes: 8 additions & 1 deletion cmd/up.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 18,12 @@ func (h *Handler) Up(ctx context.Context, req *entity.CommandRequest) error {
} else {
ui.StopSpinner(fmt.Sprintf("☁️ Deploy available at %s\n", ui.GrayText(url)))
}
return nil
detach, err := req.Cmd.Flags().GetBool("detach")
if err != nil {
return err
}
if detach {
return nil
}
return h.ctrl.GetActiveDeploymentLogs(ctx, 0)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this mean that railway up, by default, streams both build and runtime logs indefinitely after?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes it does

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I'd vote to only see build logs after up.

My flow is usually to make sure the deploy worked, then go back to writing code. Right now it's difficult to see when it switches from build to deploy then you have to ctrl-C out (which may also not be obvious to less-experienced devs).

One idea might be to detect when the build succeeded and prompt the user to continue streaming the deploy logs or exit.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I figured the "Build Completed" line is solid for this

My issue is that we fire build completed regardless of outcome, and only fetch the actual deployment logs (Which contains the "Failed to Deploy!" stuff. If we do a prompt, users might not see that

Could see it either way tho. Don't really have a strong opinion so can add a prompt pretty easily

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might need to defer a stop to the spinner?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😆
image

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LOL

}
76 changes: 76 additions & 0 deletions controller/logs.go
Original file line number Diff line number Diff line change
@@ -0,0 1,76 @@
package controller

import (
"context"
"fmt"
"math"
"strings"
"time"

"github.com/railwayapp/cli/entity"
)

func (c *Controller) GetActiveDeploymentLogs(ctx context.Context, numLines int32) error {
projectID, err := c.cfg.GetProject()
if err != nil {
return err
}
environmentID, err := c.cfg.GetEnvironment()
if err != nil {
return err
}
deployments, err := c.gtwy.GetDeploymentsForEnvironment(ctx, projectID, environmentID)
if err != nil {
return err
}

latestDeploy := deployments[0]
// Streaming
prevIdx := 0
status := latestDeploy.Status
for {
err := func() error {
if prevIdx != 0 {
time.Sleep(time.Second * 2)
}
deploy, err := c.gtwy.GetDeploymentByID(ctx, projectID, latestDeploy.ID)
if err != nil {
return err
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should also check status == "FAILED" and break out of this

if deploy.Status != status {
// Reset when moving states
prevIdx = 0
status = deploy.Status
}
logs := fetchCurrentLogs(*deploy)
partials := strings.Split(logs, "\n")
nextIdx := len(partials)
delimiter := prevIdx
if numLines != 0 {
// If num is provided do a walkback by n lines to get latest n logs
delimiter = int(math.Max(float64(len(partials)-int(numLines)), float64(prevIdx)))
}
delta := partials[delimiter:nextIdx]
if len(delta) == 0 {
return nil
}
fmt.Println(strings.Join(delta, "\n"))
prevIdx = nextIdx
return nil
}()
if err != nil {
return err
}
if numLines != 0 {
// Break if numlines provided
return nil
}
}
}

func fetchCurrentLogs(deployment entity.Deployment) string {
if deployment.Status == "BUILDING" {
return deployment.BuildLogs
}
return deployment.DeployLogs
}
8 changes: 8 additions & 0 deletions entity/deployment.go
Original file line number Diff line number Diff line change
@@ -0,0 1,8 @@
package entity

type Deployment struct {
ID string `json:"id"`
BuildLogs string `json:"buildLogs"`
DeployLogs string `json:"deployLogs"`
Status string `json:"status"`
}
64 changes: 64 additions & 0 deletions gateway/deployment.go
Original file line number Diff line number Diff line change
@@ -0,0 1,64 @@
package gateway

import (
"context"

gql "github.com/machinebox/graphql"
"github.com/railwayapp/cli/entity"
"github.com/railwayapp/cli/errors"
)

func (g *Gateway) GetDeploymentsForEnvironment(ctx context.Context, projectId string, environmentId string) ([]entity.Deployment, error) {
gqlReq := gql.NewRequest(`
query ($projectId: ID!, $environmentId: ID!) {
allDeploymentsForEnvironment(projectId: $projectId, environmentId: $environmentId) {
id
status
}
}
`)

gqlReq.Var("projectId", projectId)
gqlReq.Var("environmentId", environmentId)

err := g.authorize(ctx, gqlReq.Header)
if err != nil {
return nil, err
}

var resp struct {
Deployments []entity.Deployment `json:"allDeploymentsForEnvironment"`
}
if err := g.gqlClient.Run(ctx, gqlReq, &resp); err != nil {
return nil, errors.PluginGetFailed
}
return resp.Deployments, nil
}

func (g *Gateway) GetDeploymentByID(ctx context.Context, projectId string, deploymentId string) (*entity.Deployment, error) {
gqlReq := gql.NewRequest(`
query ($projectId: ID!, $deploymentId: ID!) {
deploymentById(projectId: $projectId, deploymentId: $deploymentId) {
id
buildLogs
deployLogs
status
}
}
`)
gqlReq.Var("projectId", projectId)
gqlReq.Var("deploymentId", deploymentId)

err := g.authorize(ctx, gqlReq.Header)
if err != nil {
return nil, err
}

var resp struct {
Deployment *entity.Deployment `json:"deploymentById"`
}
if err := g.gqlClient.Run(ctx, gqlReq, &resp); err != nil {
return nil, errors.PluginGetFailed
}
return resp.Deployment, nil
}
15 changes: 13 additions & 2 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,11 176,22 @@ func init() {
RunE: contextualize(handler.Version, handler.Panic),
})

addRootCmd(&cobra.Command{
upCmd := &cobra.Command{
Use: "up",
Short: "Upload and deploy project from the current directory",
RunE: contextualize(handler.Up, handler.Panic),
})
}
upCmd.Flags().BoolP("detach", "d", false, "--detatch")
JakeCooper marked this conversation as resolved.
Show resolved Hide resolved

addRootCmd(upCmd)
gschier marked this conversation as resolved.
Show resolved Hide resolved

logsCmd := &cobra.Command{
Use: "logs",
Short: "View the most-recent deploy's logs",
RunE: contextualize(handler.Logs, handler.Panic),
}
logsCmd.Flags().Int32P("num_lines", "n", 0, "--lines")
addRootCmd(logsCmd)

addRootCmd(&cobra.Command{
Use: "docs",
Expand Down