Skip to content
Merged
Show file tree
Hide file tree
Changes from 13 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
5 changes: 5 additions & 0 deletions .changeset/lovely-shrimps-show.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@gram/cli": minor
---

Enable asset upload to gram via `gram upload`
2 changes: 1 addition & 1 deletion cli/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ replace github.com/speakeasy-api/gram/server => ../server
require (
github.com/BurntSushi/toml v1.5.0
github.com/charmbracelet/log v0.4.2
github.com/google/uuid v1.6.0
github.com/hashicorp/go-retryablehttp v0.7.8
github.com/speakeasy-api/gram/server v0.0.0-00010101000000-000000000000
github.com/stretchr/testify v1.11.1
Expand All @@ -27,7 +28,6 @@ require (
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/go-chi/chi/v5 v5.2.3 // indirect
github.com/go-logfmt/logfmt v0.6.0 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
Expand Down
2 changes: 0 additions & 2 deletions cli/internal/api/assets.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"context"
"fmt"
"io"
"log/slog"

"github.com/speakeasy-api/gram/server/gen/assets"
assets_client "github.com/speakeasy-api/gram/server/gen/http/assets/client"
Expand Down Expand Up @@ -51,7 +50,6 @@ type UploadOpenAPIv3Request struct {

func (c *AssetsClient) UploadOpenAPIv3(
ctx context.Context,
logger *slog.Logger,
req *UploadOpenAPIv3Request,
) (*assets.UploadOpenAPIv3Result, error) {
payload := &assets.UploadOpenAPIv3Form{
Expand Down
103 changes: 93 additions & 10 deletions cli/internal/api/deployments.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ import (
"context"
"fmt"

"github.com/google/uuid"
"github.com/speakeasy-api/gram/cli/internal/secret"
"github.com/speakeasy-api/gram/server/gen/deployments"
depl_client "github.com/speakeasy-api/gram/server/gen/http/deployments/client"
"github.com/speakeasy-api/gram/server/gen/types"
goahttp "goa.design/goa/v3/http"
)

Expand Down Expand Up @@ -55,7 +57,10 @@ func (c *DeploymentsClient) CreateDeployment(
req CreateDeploymentRequest,
) (*deployments.CreateDeploymentResult, error) {
key := req.APIKey.Reveal()
result, err := c.client.CreateDeployment(ctx, &deployments.CreateDeploymentPayload{
if req.IdempotencyKey == "" {
req.IdempotencyKey = uuid.New().String()
}
payload := &deployments.CreateDeploymentPayload{
ApikeyToken: &key,
ProjectSlugInput: &req.ProjectSlug,
IdempotencyKey: req.IdempotencyKey,
Expand All @@ -68,7 +73,8 @@ func (c *DeploymentsClient) CreateDeployment(
ExternalID: nil,
ExternalURL: nil,
Packages: nil,
})
}
result, err := c.client.CreateDeployment(ctx, payload)
if err != nil {
return nil, fmt.Errorf("failed to create deployment: %w", err)
}
Expand All @@ -82,7 +88,7 @@ func (c *DeploymentsClient) GetDeployment(
apiKey secret.Secret,
projectSlug string,
deploymentID string,
) (*deployments.GetDeploymentResult, error) {
) (*types.Deployment, error) {
key := apiKey.Reveal()
result, err := c.client.GetDeployment(ctx, &deployments.GetDeploymentPayload{
ApikeyToken: &key,
Expand All @@ -94,24 +100,101 @@ func (c *DeploymentsClient) GetDeployment(
return nil, fmt.Errorf("failed to get deployment: %w", err)
}

return result, nil
return &types.Deployment{
ID: result.ID,
OrganizationID: result.OrganizationID,
ProjectID: result.ProjectID,
UserID: result.UserID,
CreatedAt: result.CreatedAt,
Status: result.Status,
IdempotencyKey: result.IdempotencyKey,
GithubRepo: result.GithubRepo,
GithubPr: result.GithubPr,
GithubSha: result.GithubSha,
ExternalID: result.ExternalID,
ExternalURL: result.ExternalURL,
ClonedFrom: result.ClonedFrom,
Openapiv3ToolCount: result.Openapiv3ToolCount,
Openapiv3Assets: result.Openapiv3Assets,
FunctionsToolCount: result.FunctionsToolCount,
FunctionsAssets: result.FunctionsAssets,
Packages: result.Packages,
}, nil
}

// GetLatestDeployment retrieves the latest deployment for a project.
func (c *DeploymentsClient) GetLatestDeployment(
ctx context.Context,
apiKey secret.Secret,
projectSlug string,
) (*deployments.GetLatestDeploymentResult, error) {
) (*types.Deployment, error) {
key := apiKey.Reveal()
result, err := c.client.GetLatestDeployment(ctx, &deployments.GetLatestDeploymentPayload{
ApikeyToken: &key,
ProjectSlugInput: &projectSlug,
SessionToken: nil,
})
result, err := c.client.GetLatestDeployment(
ctx,
&deployments.GetLatestDeploymentPayload{
ApikeyToken: &key,
ProjectSlugInput: &projectSlug,
SessionToken: nil,
},
)
if err != nil {
return nil, fmt.Errorf("failed to get latest deployment: %w", err)
}

return result.Deployment, nil
}

// GetActiveDeployment retrieves the active deployment for a project.
func (c *DeploymentsClient) GetActiveDeployment(
ctx context.Context,
apiKey secret.Secret,
projectSlug string,
) (*types.Deployment, error) {
key := apiKey.Reveal()
result, err := c.client.GetActiveDeployment(
ctx,
&deployments.GetActiveDeploymentPayload{
ApikeyToken: &key,
ProjectSlugInput: &projectSlug,
SessionToken: nil,
},
)
if err != nil {
return nil, fmt.Errorf("failed to get active deployment: %w", err)
}

return result.Deployment, nil
}

// EvolveRequest lists the assets to add to a deployment.
type EvolveRequest struct {
Assets []*deployments.AddOpenAPIv3DeploymentAssetForm
APIKey secret.Secret
DeploymentID string
ProjectSlug string
}

// Evolve adds assets to an existing deployment.
func (c *DeploymentsClient) Evolve(
ctx context.Context,
req EvolveRequest,
) (*deployments.EvolveResult, error) {
key := req.APIKey.Reveal()
result, err := c.client.Evolve(ctx, &deployments.EvolvePayload{
ApikeyToken: &key,
ProjectSlugInput: &req.ProjectSlug,
DeploymentID: &req.DeploymentID,
UpsertOpenapiv3Assets: req.Assets,
UpsertFunctions: []*deployments.AddFunctionsForm{},
ExcludeOpenapiv3Assets: []string{},
ExcludeFunctions: []string{},
ExcludePackages: []string{},
UpsertPackages: []*deployments.AddPackageForm{},
SessionToken: nil,
})
if err != nil {
return nil, fmt.Errorf("failed to evolve deployment: %w", err)
}

return result, nil
}
6 changes: 4 additions & 2 deletions cli/internal/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

"github.com/urfave/cli/v2"

"github.com/speakeasy-api/gram/cli/internal/app/logging"
"github.com/speakeasy-api/gram/cli/internal/o11y"
)

Expand All @@ -23,6 +24,7 @@ func newApp() *cli.App {
Version: fmt.Sprintf("%s (%s)", Version, shortSha),
Commands: []*cli.Command{
newPushCommand(),
newUploadCommand(),
newStatusCommand(),
},
Flags: []cli.Flag{
Expand All @@ -48,11 +50,11 @@ func newApp() *cli.App {
Before: func(c *cli.Context) error {
logger := slog.New(o11y.NewLogHandler(&o11y.LogHandlerOptions{
RawLevel: c.String("log-level"),
Pretty: c.Bool("pretty"),
Pretty: c.Bool("log-pretty"),
DataDogAttr: true,
}))

ctx := PushLogger(c.Context, logger)
ctx := logging.PushLogger(c.Context, logger)
c.Context = ctx
return nil
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package app
package logging

import (
"context"
Expand Down
Loading