diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 3b2584063..10f17a2fc 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -23,7 +23,7 @@ Please avoid: ## Building the project Prerequisites: -- Go 1.16+ +- Go 1.21+ Build with: * Unix-like systems: `make` diff --git a/.github/workflows/deployment.yml b/.github/workflows/deployment.yml index e866eea11..95f0f145c 100644 --- a/.github/workflows/deployment.yml +++ b/.github/workflows/deployment.yml @@ -1,6 +1,6 @@ name: Deployment -concurrency: +concurrency: group: ${{ github.workflow }}-${{ github.ref_name }} cancel-in-progress: true @@ -17,7 +17,7 @@ on: default: production type: environment go_version: - default: "1.19" + default: "1.21" type: string platforms: default: "linux,macos,windows" @@ -61,7 +61,7 @@ jobs: dist/*.tar.gz dist/*.rpm dist/*.deb - + macos: runs-on: macos-latest environment: ${{ inputs.environment }} @@ -132,7 +132,7 @@ jobs: dist/*.tar.gz dist/*.zip dist/*.pkg - + windows: runs-on: windows-latest environment: ${{ inputs.environment }} @@ -354,6 +354,7 @@ jobs: if: inputs.environment == 'production' && !contains(inputs.tag_name, '-') with: formula-name: gh + formula-path: Formula/g/gh.rb tag-name: ${{ inputs.tag_name }} push-to: cli/homebrew-core env: diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 1a3a33318..a375e2d8f 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -13,10 +13,10 @@ jobs: runs-on: ${{ matrix.os }} steps: - - name: Set up Go 1.19 + - name: Set up Go 1.21 uses: actions/setup-go@v4 with: - go-version: 1.19 + go-version: 1.21 - name: Check out code uses: actions/checkout@v3 diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index dd1fede0d..c8defbf3a 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -19,10 +19,10 @@ jobs: runs-on: ubuntu-latest steps: - - name: Set up Go 1.19 + - name: Set up Go 1.21 uses: actions/setup-go@v4 with: - go-version: 1.19 + go-version: 1.21 - name: Check out code uses: actions/checkout@v3 @@ -40,7 +40,7 @@ jobs: go mod verify go mod download - LINT_VERSION=1.50.1 + LINT_VERSION=1.54.1 curl -fsSL https://github.com/golangci/golangci-lint/releases/download/v${LINT_VERSION}/golangci-lint-${LINT_VERSION}-linux-amd64.tar.gz | \ tar xz --strip-components 1 --wildcards \*/golangci-lint mkdir -p bin && mv golangci-lint bin/ diff --git a/api/http_client.go b/api/http_client.go index 691f99481..9f2d59ce3 100644 --- a/api/http_client.go +++ b/api/http_client.go @@ -23,6 +23,7 @@ type HTTPClientOptions struct { EnableCache bool Log io.Writer LogColorize bool + LogVerboseHTTP bool SkipAcceptHeaders bool } @@ -35,10 +36,15 @@ func NewHTTPClient(opts HTTPClientOptions) (*http.Client, error) { LogIgnoreEnv: true, } - if debugEnabled, debugValue := utils.IsDebugEnabled(); debugEnabled { + debugEnabled, debugValue := utils.IsDebugEnabled() + if strings.Contains(debugValue, "api") { + opts.LogVerboseHTTP = true + } + + if opts.LogVerboseHTTP || debugEnabled { clientOpts.Log = opts.Log clientOpts.LogColorize = opts.LogColorize - clientOpts.LogVerboseHTTP = strings.Contains(debugValue, "api") + clientOpts.LogVerboseHTTP = opts.LogVerboseHTTP } headers := map[string]string{ @@ -63,8 +69,6 @@ func NewHTTPClient(opts HTTPClientOptions) (*http.Client, error) { client.Transport = AddAuthTokenHeader(client.Transport, opts.Config) } - client.Transport = AddASCIISanitizer(client.Transport) - return client, nil } @@ -91,9 +95,17 @@ func AddAuthTokenHeader(rt http.RoundTripper, cfg tokenGetter) http.RoundTripper return &funcTripper{roundTrip: func(req *http.Request) (*http.Response, error) { // If the header is already set in the request, don't overwrite it. if req.Header.Get(authorization) == "" { - hostname := ghinstance.NormalizeHostname(getHost(req)) - if token, _ := cfg.Token(hostname); token != "" { - req.Header.Set(authorization, fmt.Sprintf("token %s", token)) + var redirectHostnameChange bool + if req.Response != nil && req.Response.Request != nil { + redirectHostnameChange = getHost(req) != getHost(req.Response.Request) + } + // Only set header if an initial request or redirect request to the same host as the initial request. + // If the host has changed during a redirect do not add the authentication token header. + if !redirectHostnameChange { + hostname := ghinstance.NormalizeHostname(getHost(req)) + if token, _ := cfg.Token(hostname); token != "" { + req.Header.Set(authorization, fmt.Sprintf("token %s", token)) + } } } return rt.RoundTrip(req) @@ -128,5 +140,5 @@ func getHost(r *http.Request) string { if r.Host != "" { return r.Host } - return r.URL.Hostname() + return r.URL.Host } diff --git a/api/http_client_test.go b/api/http_client_test.go index ee59dbfc1..b1e84e582 100644 --- a/api/http_client_test.go +++ b/api/http_client_test.go @@ -1,11 +1,13 @@ package api import ( + "encoding/json" "fmt" + "io" "net/http" "net/http/httptest" - "os" "regexp" + "strings" "testing" "github.com/MakeNowJust/heredoc" @@ -16,16 +18,14 @@ import ( func TestNewHTTPClient(t *testing.T) { type args struct { - config tokenGetter - appVersion string - setAccept bool + config tokenGetter + appVersion string + setAccept bool + logVerboseHTTP bool } tests := []struct { name string args args - envDebug string - setGhDebug bool - envGhDebug string host string wantHeader map[string]string wantStderr string @@ -33,9 +33,10 @@ func TestNewHTTPClient(t *testing.T) { { name: "github.com with Accept header", args: args{ - config: tinyConfig{"github.com:oauth_token": "MYTOKEN"}, - appVersion: "v1.2.3", - setAccept: true, + config: tinyConfig{"github.com:oauth_token": "MYTOKEN"}, + appVersion: "v1.2.3", + setAccept: true, + logVerboseHTTP: false, }, host: "github.com", wantHeader: map[string]string{ @@ -48,9 +49,10 @@ func TestNewHTTPClient(t *testing.T) { { name: "github.com no Accept header", args: args{ - config: tinyConfig{"github.com:oauth_token": "MYTOKEN"}, - appVersion: "v1.2.3", - setAccept: false, + config: tinyConfig{"github.com:oauth_token": "MYTOKEN"}, + appVersion: "v1.2.3", + setAccept: false, + logVerboseHTTP: false, }, host: "github.com", wantHeader: map[string]string{ @@ -63,9 +65,10 @@ func TestNewHTTPClient(t *testing.T) { { name: "github.com no authentication token", args: args{ - config: tinyConfig{"example.com:oauth_token": "MYTOKEN"}, - appVersion: "v1.2.3", - setAccept: true, + config: tinyConfig{"example.com:oauth_token": "MYTOKEN"}, + appVersion: "v1.2.3", + setAccept: true, + logVerboseHTTP: false, }, host: "github.com", wantHeader: map[string]string{ @@ -78,45 +81,12 @@ func TestNewHTTPClient(t *testing.T) { { name: "github.com in verbose mode", args: args{ - config: tinyConfig{"github.com:oauth_token": "MYTOKEN"}, - appVersion: "v1.2.3", - setAccept: true, + config: tinyConfig{"github.com:oauth_token": "MYTOKEN"}, + appVersion: "v1.2.3", + setAccept: true, + logVerboseHTTP: true, }, - host: "github.com", - envDebug: "api", - setGhDebug: false, - wantHeader: map[string]string{ - "authorization": "token MYTOKEN", - "user-agent": "GitHub CLI v1.2.3", - "accept": "application/vnd.github.merge-info-preview+json, application/vnd.github.nebula-preview", - }, - wantStderr: heredoc.Doc(` - * Request at