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

release: 0.5.0 #54

Open
wants to merge 17 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
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
4 changes: 0 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ jobs:
lint:
name: lint
runs-on: ubuntu-latest


steps:
- uses: actions/checkout@v4

Expand All @@ -27,7 +25,6 @@ jobs:
test:
name: test
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

Expand All @@ -41,4 +38,3 @@ jobs:

- name: Run tests
run: ./scripts/test

2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "0.4.0"
".": "0.5.0"
}
2 changes: 2 additions & 0 deletions .stats.yml
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
configured_endpoints: 111
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-3655d5ad0ac3e228c1519af70dbf3d0bfa3c47a2d06d4cac92a650da051b49a6.yml
openapi_spec_hash: 5dbb5577e6a7cae7db615b1b06c9d23e
config_hash: 719ad411c0ec7402a7a4c1f95515280c
34 changes: 34 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,39 @@
# Changelog

## 0.5.0 (2025-04-10)

Full Changelog: [v0.4.0...v0.5.0](https://github.com/gitpod-io/gitpod-sdk-go/compare/v0.4.0...v0.5.0)

### Features

* **client:** allow custom baseurls without trailing slash ([#55](https://github.com/gitpod-io/gitpod-sdk-go/issues/55)) ([20b4808](https://github.com/gitpod-io/gitpod-sdk-go/commit/20b480853025ee9b5402ae5a361010c7de9eabdc))
* **client:** improve default client options support ([#57](https://github.com/gitpod-io/gitpod-sdk-go/issues/57)) ([0cb0d29](https://github.com/gitpod-io/gitpod-sdk-go/commit/0cb0d293a64defd394978cd2b4da6cb006753a69))
* **client:** support custom http clients ([#65](https://github.com/gitpod-io/gitpod-sdk-go/issues/65)) ([ba2780f](https://github.com/gitpod-io/gitpod-sdk-go/commit/ba2780f5173f3e569527a24e9151e258e90df509))


### Bug Fixes

* **client:** return error on bad custom url instead of panic ([#64](https://github.com/gitpod-io/gitpod-sdk-go/issues/64)) ([656a0d1](https://github.com/gitpod-io/gitpod-sdk-go/commit/656a0d137cfa42afa6d540d80d306d254f4841aa))
* **client:** unmarshal stream events into fresh memory ([#63](https://github.com/gitpod-io/gitpod-sdk-go/issues/63)) ([9cf0811](https://github.com/gitpod-io/gitpod-sdk-go/commit/9cf08112fe7b5e702311882b79f167956b09753f))
* **test:** return early after test failure ([#61](https://github.com/gitpod-io/gitpod-sdk-go/issues/61)) ([0295d21](https://github.com/gitpod-io/gitpod-sdk-go/commit/0295d214d2934e8d4789883255885d3e5ea474c9))


### Chores

* add request options to client tests ([#60](https://github.com/gitpod-io/gitpod-sdk-go/issues/60)) ([b575336](https://github.com/gitpod-io/gitpod-sdk-go/commit/b5753364f5bc6c5617205b2145ade577bc43ac72))
* **docs:** improve security documentation ([#59](https://github.com/gitpod-io/gitpod-sdk-go/issues/59)) ([2d3d9e7](https://github.com/gitpod-io/gitpod-sdk-go/commit/2d3d9e7bdb95db8579085db1a23fa7f558b3ab2b))
* fix typos ([#62](https://github.com/gitpod-io/gitpod-sdk-go/issues/62)) ([2ab745f](https://github.com/gitpod-io/gitpod-sdk-go/commit/2ab745f9136f7c6f4528f05e26c1c22a4b15b959))
* **internal:** codegen related update ([#56](https://github.com/gitpod-io/gitpod-sdk-go/issues/56)) ([dc521f6](https://github.com/gitpod-io/gitpod-sdk-go/commit/dc521f608d7475d2d98f64fe118433450ab5b2af))
* **internal:** expand CI branch coverage ([7d00669](https://github.com/gitpod-io/gitpod-sdk-go/commit/7d00669f67ba5d7007feceb6f25863de34a237df))
* **internal:** reduce CI branch coverage ([3b674ac](https://github.com/gitpod-io/gitpod-sdk-go/commit/3b674ac888efc38b3713547841770b6c77af2ac8))
* **internal:** remove extra empty newlines ([#58](https://github.com/gitpod-io/gitpod-sdk-go/issues/58)) ([80ff63b](https://github.com/gitpod-io/gitpod-sdk-go/commit/80ff63b57f6df81750f4acaee91003902d2ddae6))
* **tests:** improve enum examples ([#66](https://github.com/gitpod-io/gitpod-sdk-go/issues/66)) ([359070f](https://github.com/gitpod-io/gitpod-sdk-go/commit/359070f05052c648ae75a806ddd037c8eb28dbe7))


### Documentation

* update URLs from stainlessapi.com to stainless.com ([#53](https://github.com/gitpod-io/gitpod-sdk-go/issues/53)) ([a5f0af7](https://github.com/gitpod-io/gitpod-sdk-go/commit/a5f0af754b7fb4ef5d967aa53ce3ad22648826be))

## 0.4.0 (2025-02-21)

Full Changelog: [v0.3.2...v0.4.0](https://github.com/gitpod-io/gitpod-sdk-go/compare/v0.3.2...v0.4.0)
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
The Gitpod Go library provides convenient access to [the Gitpod REST
API](https://docs.gitpod.io) from applications written in Go. The full API of this library can be found in [api.md](api.md).

It is generated with [Stainless](https://www.stainlessapi.com/).
It is generated with [Stainless](https://www.stainless.com/).

## Installation

Expand All @@ -24,7 +24,7 @@ Or to pin the version:
<!-- x-release-please-start-version -->

```sh
go get -u 'github.com/gitpod-io/gitpod-sdk-go@v0.4.0'
go get -u 'github.com/gitpod-io/gitpod-sdk-go@v0.5.0'
```

<!-- x-release-please-end -->
Expand Down
4 changes: 2 additions & 2 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

## Reporting Security Issues

This SDK is generated by [Stainless Software Inc](http://stainlessapi.com). Stainless takes security seriously, and encourages you to report any security vulnerability promptly so that appropriate action can be taken.
This SDK is generated by [Stainless Software Inc](http://stainless.com). Stainless takes security seriously, and encourages you to report any security vulnerability promptly so that appropriate action can be taken.

To report a security issue, please contact the Stainless team at security@stainlessapi.com.
To report a security issue, please contact the Stainless team at security@stainless.com.

## Responsible Disclosure

Expand Down
16 changes: 11 additions & 5 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,22 @@ type Client struct {
Users *UserService
}

// DefaultClientOptions read from the environment (GITPOD_API_KEY). This should be
// used to initialize new clients.
func DefaultClientOptions() []option.RequestOption {
defaults := []option.RequestOption{option.WithEnvironmentProduction()}
if o, ok := os.LookupEnv("GITPOD_API_KEY"); ok {
defaults = append(defaults, option.WithBearerToken(o))
}
return defaults
}

// NewClient generates a new client with the default option read from the
// environment (GITPOD_API_KEY). The option passed in as arguments are applied
// after these default arguments, and all option will be passed down to the
// services and requests that this client makes.
func NewClient(opts ...option.RequestOption) (r *Client) {
defaults := []option.RequestOption{option.WithEnvironmentProduction()}
if o, ok := os.LookupEnv("GITPOD_API_KEY"); ok {
defaults = append(defaults, option.WithBearerToken(o))
}
opts = append(defaults, opts...)
opts = append(DefaultClientOptions(), opts...)

r = &Client{Options: opts}

Expand Down
8 changes: 8 additions & 0 deletions client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ func (t *closureTransport) RoundTrip(req *http.Request) (*http.Response, error)
func TestUserAgentHeader(t *testing.T) {
var userAgent string
client := gitpod.NewClient(
option.WithBearerToken("My Bearer Token"),
option.WithHTTPClient(&http.Client{
Transport: &closureTransport{
fn: func(req *http.Request) (*http.Response, error) {
Expand All @@ -46,6 +47,7 @@ func TestUserAgentHeader(t *testing.T) {
func TestRetryAfter(t *testing.T) {
retryCountHeaders := make([]string, 0)
client := gitpod.NewClient(
option.WithBearerToken("My Bearer Token"),
option.WithHTTPClient(&http.Client{
Transport: &closureTransport{
fn: func(req *http.Request) (*http.Response, error) {
Expand Down Expand Up @@ -79,6 +81,7 @@ func TestRetryAfter(t *testing.T) {
func TestDeleteRetryCountHeader(t *testing.T) {
retryCountHeaders := make([]string, 0)
client := gitpod.NewClient(
option.WithBearerToken("My Bearer Token"),
option.WithHTTPClient(&http.Client{
Transport: &closureTransport{
fn: func(req *http.Request) (*http.Response, error) {
Expand Down Expand Up @@ -108,6 +111,7 @@ func TestDeleteRetryCountHeader(t *testing.T) {
func TestOverwriteRetryCountHeader(t *testing.T) {
retryCountHeaders := make([]string, 0)
client := gitpod.NewClient(
option.WithBearerToken("My Bearer Token"),
option.WithHTTPClient(&http.Client{
Transport: &closureTransport{
fn: func(req *http.Request) (*http.Response, error) {
Expand Down Expand Up @@ -137,6 +141,7 @@ func TestOverwriteRetryCountHeader(t *testing.T) {
func TestRetryAfterMs(t *testing.T) {
attempts := 0
client := gitpod.NewClient(
option.WithBearerToken("My Bearer Token"),
option.WithHTTPClient(&http.Client{
Transport: &closureTransport{
fn: func(req *http.Request) (*http.Response, error) {
Expand All @@ -162,6 +167,7 @@ func TestRetryAfterMs(t *testing.T) {

func TestContextCancel(t *testing.T) {
client := gitpod.NewClient(
option.WithBearerToken("My Bearer Token"),
option.WithHTTPClient(&http.Client{
Transport: &closureTransport{
fn: func(req *http.Request) (*http.Response, error) {
Expand All @@ -181,6 +187,7 @@ func TestContextCancel(t *testing.T) {

func TestContextCancelDelay(t *testing.T) {
client := gitpod.NewClient(
option.WithBearerToken("My Bearer Token"),
option.WithHTTPClient(&http.Client{
Transport: &closureTransport{
fn: func(req *http.Request) (*http.Response, error) {
Expand Down Expand Up @@ -208,6 +215,7 @@ func TestContextDeadline(t *testing.T) {

go func() {
client := gitpod.NewClient(
option.WithBearerToken("My Bearer Token"),
option.WithHTTPClient(&http.Client{
Transport: &closureTransport{
fn: func(req *http.Request) (*http.Response, error) {
Expand Down
4 changes: 2 additions & 2 deletions environmentautomation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func TestEnvironmentAutomationUpsertWithOptionalParams(t *testing.T) {
Image: gitpod.F("x"),
}),
}),
TriggeredBy: gitpod.F([]gitpod.AutomationsFileServicesTriggeredBy{gitpod.AutomationsFileServicesTriggeredByManual}),
TriggeredBy: gitpod.F([]gitpod.AutomationsFileServicesTriggeredBy{gitpod.AutomationsFileServicesTriggeredByPostDevcontainerStart}),
},
}),
Tasks: gitpod.F(map[string]gitpod.AutomationsFileTaskParam{
Expand All @@ -59,7 +59,7 @@ func TestEnvironmentAutomationUpsertWithOptionalParams(t *testing.T) {
Image: gitpod.F("x"),
}),
}),
TriggeredBy: gitpod.F([]gitpod.AutomationsFileTasksTriggeredBy{gitpod.AutomationsFileTasksTriggeredByManual}),
TriggeredBy: gitpod.F([]gitpod.AutomationsFileTasksTriggeredBy{gitpod.AutomationsFileTasksTriggeredByPostEnvironmentStart}),
},
}),
}),
Expand Down
2 changes: 1 addition & 1 deletion environmentautomationtaskexecution_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ func TestEnvironmentAutomationTaskExecutionListWithOptionalParams(t *testing.T)
PageSize: gitpod.F(int64(0)),
Filter: gitpod.F(gitpod.EnvironmentAutomationTaskExecutionListParamsFilter{
EnvironmentIDs: gitpod.F([]string{"182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}),
Phases: gitpod.F([]shared.TaskExecutionPhase{shared.TaskExecutionPhaseUnspecified, shared.TaskExecutionPhasePending}),
Phases: gitpod.F([]shared.TaskExecutionPhase{shared.TaskExecutionPhaseRunning, shared.TaskExecutionPhaseFailed}),
TaskIDs: gitpod.F([]string{"182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}),
TaskReferences: gitpod.F([]string{"string"}),
}),
Expand Down
2 changes: 1 addition & 1 deletion event_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func TestEventListWithOptionalParams(t *testing.T) {
PageSize: gitpod.F(int64(0)),
Filter: gitpod.F(gitpod.EventListParamsFilter{
ActorIDs: gitpod.F([]string{"d2c94c27-3b76-4a42-b88c-95a85e392c68"}),
ActorPrincipals: gitpod.F([]shared.Principal{shared.PrincipalUnspecified}),
ActorPrincipals: gitpod.F([]shared.Principal{shared.PrincipalUser}),
SubjectIDs: gitpod.F([]string{"182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}),
SubjectTypes: gitpod.F([]gitpod.ResourceType{gitpod.ResourceTypeUnspecified}),
}),
Expand Down
61 changes: 53 additions & 8 deletions internal/requestconfig/requestconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"io"
"math"
"math/rand"
"mime"
"net/http"
"net/url"
"runtime"
Expand All @@ -21,6 +22,7 @@ import (
"github.com/gitpod-io/gitpod-sdk-go/internal/apierror"
"github.com/gitpod-io/gitpod-sdk-go/internal/apiform"
"github.com/gitpod-io/gitpod-sdk-go/internal/apiquery"
"github.com/gitpod-io/gitpod-sdk-go/internal/param"
)

func getDefaultHeaders() map[string]string {
Expand Down Expand Up @@ -76,7 +78,17 @@ func getPlatformProperties() map[string]string {
}
}

func NewRequestConfig(ctx context.Context, method string, u string, body interface{}, dst interface{}, opts ...func(*RequestConfig) error) (*RequestConfig, error) {
type RequestOption interface {
Apply(*RequestConfig) error
}

type RequestOptionFunc func(*RequestConfig) error
type PreRequestOptionFunc func(*RequestConfig) error

func (s RequestOptionFunc) Apply(r *RequestConfig) error { return s(r) }
func (s PreRequestOptionFunc) Apply(r *RequestConfig) error { return s(r) }

func NewRequestConfig(ctx context.Context, method string, u string, body interface{}, dst interface{}, opts ...RequestOption) (*RequestConfig, error) {
var reader io.Reader

contentType := "application/json"
Expand Down Expand Up @@ -173,16 +185,30 @@ func NewRequestConfig(ctx context.Context, method string, u string, body interfa
return &cfg, nil
}

func UseDefaultParam[T any](dst *param.Field[T], src *T) {
if !dst.Present && src != nil {
dst.Value = *src
dst.Present = true
}
}

// This interface is primarily used to describe an [*http.Client], but also
// supports custom HTTP implementations.
type HTTPDoer interface {
Do(req *http.Request) (*http.Response, error)
}

// RequestConfig represents all the state related to one request.
//
// Editing the variables inside RequestConfig directly is unstable api. Prefer
// composing func(\*RequestConfig) error instead if possible.
// composing the RequestOption instead if possible.
type RequestConfig struct {
MaxRetries int
RequestTimeout time.Duration
Context context.Context
Request *http.Request
BaseURL *url.URL
CustomHTTPDoer HTTPDoer
HTTPClient *http.Client
Middlewares []middleware
BearerToken string
Expand Down Expand Up @@ -222,7 +248,7 @@ func shouldRetry(req *http.Request, res *http.Response) bool {
return true
}

// If the header explictly wants a retry behavior, respect that over the
// If the header explicitly wants a retry behavior, respect that over the
// http status code.
if res.Header.Get("x-should-retry") == "true" {
return true
Expand Down Expand Up @@ -380,6 +406,9 @@ func (cfg *RequestConfig) Execute() (err error) {
}

handler := cfg.HTTPClient.Do
if cfg.CustomHTTPDoer != nil {
handler = cfg.CustomHTTPDoer.Do
}
for i := len(cfg.Middlewares) - 1; i >= 0; i -= 1 {
handler = applyMiddleware(cfg.Middlewares[i], handler)
}
Expand Down Expand Up @@ -485,7 +514,8 @@ func (cfg *RequestConfig) Execute() (err error) {

// If we are not json, return plaintext
contentType := res.Header.Get("content-type")
isJSON := strings.Contains(contentType, "application/json") || strings.Contains(contentType, "application/vnd.api+json")
mediaType, _, _ := mime.ParseMediaType(contentType)
isJSON := strings.Contains(mediaType, "application/json") || strings.HasSuffix(mediaType, "+json")
if !isJSON {
switch dst := cfg.ResponseBodyInto.(type) {
case *string:
Expand All @@ -496,7 +526,7 @@ func (cfg *RequestConfig) Execute() (err error) {
case *[]byte:
*dst = contents
default:
return fmt.Errorf("expected destination type of 'string' or '[]byte' for responses with content-type that is not 'application/json'")
return fmt.Errorf("expected destination type of 'string' or '[]byte' for responses with content-type '%s' that is not 'application/json'", contentType)
}
return nil
}
Expand All @@ -515,7 +545,7 @@ func (cfg *RequestConfig) Execute() (err error) {
return nil
}

func ExecuteNewRequest(ctx context.Context, method string, u string, body interface{}, dst interface{}, opts ...func(*RequestConfig) error) error {
func ExecuteNewRequest(ctx context.Context, method string, u string, body interface{}, dst interface{}, opts ...RequestOption) error {
cfg, err := NewRequestConfig(ctx, method, u, body, dst, opts...)
if err != nil {
return err
Expand Down Expand Up @@ -549,12 +579,27 @@ func (cfg *RequestConfig) Clone(ctx context.Context) *RequestConfig {
return new
}

func (cfg *RequestConfig) Apply(opts ...func(*RequestConfig) error) error {
func (cfg *RequestConfig) Apply(opts ...RequestOption) error {
for _, opt := range opts {
err := opt(cfg)
err := opt.Apply(cfg)
if err != nil {
return err
}
}
return nil
}

func PreRequestOptions(opts ...RequestOption) (RequestConfig, error) {
cfg := RequestConfig{}
for _, opt := range opts {
if _, ok := opt.(PreRequestOptionFunc); !ok {
continue
}

err := opt.Apply(&cfg)
if err != nil {
return cfg, err
}
}
return cfg, nil
}
2 changes: 1 addition & 1 deletion internal/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@

package internal

const PackageVersion = "0.4.0" // x-release-please-version
const PackageVersion = "0.5.0" // x-release-please-version
Loading