feat: add actions workflow enable and disable
This commit is contained in:
parent
c2ee338f1c
commit
4c6de3ad2e
4 changed files with 159 additions and 39 deletions
169
cmd/actions.go
169
cmd/actions.go
|
|
@ -2,8 +2,10 @@ package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
"text/tabwriter"
|
"text/tabwriter"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
|
@ -163,6 +165,22 @@ var workflowRunCmd = &cobra.Command{
|
||||||
RunE: runWorkflowRun,
|
RunE: runWorkflowRun,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var workflowEnableCmd = &cobra.Command{
|
||||||
|
Use: "enable <workflow>",
|
||||||
|
Short: "Enable a workflow",
|
||||||
|
Long: "Enable a workflow so it can be triggered.\n\nNote: This feature requires Forgejo 15.0+ or Gitea 1.24+.\nFor older versions, use the web UI to enable workflows.",
|
||||||
|
Args: cobra.ExactArgs(1),
|
||||||
|
RunE: runWorkflowEnable,
|
||||||
|
}
|
||||||
|
|
||||||
|
var workflowDisableCmd = &cobra.Command{
|
||||||
|
Use: "disable <workflow>",
|
||||||
|
Short: "Disable a workflow",
|
||||||
|
Long: "Disable a workflow so it cannot be triggered.\n\nNote: This feature requires Forgejo 15.0+ or Gitea 1.24+.\nFor older versions, use the web UI to disable workflows.",
|
||||||
|
Args: cobra.ExactArgs(1),
|
||||||
|
RunE: runWorkflowDisable,
|
||||||
|
}
|
||||||
|
|
||||||
// Secret commands
|
// Secret commands
|
||||||
var actionsSecretCmd = &cobra.Command{
|
var actionsSecretCmd = &cobra.Command{
|
||||||
Use: "secret",
|
Use: "secret",
|
||||||
|
|
@ -255,6 +273,8 @@ func init() {
|
||||||
workflowCmd.AddCommand(workflowListCmd)
|
workflowCmd.AddCommand(workflowListCmd)
|
||||||
workflowCmd.AddCommand(workflowViewCmd)
|
workflowCmd.AddCommand(workflowViewCmd)
|
||||||
workflowCmd.AddCommand(workflowRunCmd)
|
workflowCmd.AddCommand(workflowRunCmd)
|
||||||
|
workflowCmd.AddCommand(workflowEnableCmd)
|
||||||
|
workflowCmd.AddCommand(workflowDisableCmd)
|
||||||
|
|
||||||
// Add secret commands
|
// Add secret commands
|
||||||
actionsCmd.AddCommand(actionsSecretCmd)
|
actionsCmd.AddCommand(actionsSecretCmd)
|
||||||
|
|
@ -292,6 +312,8 @@ func init() {
|
||||||
addRepoFlags(workflowViewCmd)
|
addRepoFlags(workflowViewCmd)
|
||||||
workflowViewCmd.Flags().Bool("json", false, "Output workflow as JSON")
|
workflowViewCmd.Flags().Bool("json", false, "Output workflow as JSON")
|
||||||
addRepoFlags(workflowRunCmd)
|
addRepoFlags(workflowRunCmd)
|
||||||
|
addRepoFlags(workflowEnableCmd)
|
||||||
|
addRepoFlags(workflowDisableCmd)
|
||||||
workflowRunCmd.Flags().StringP("ref", "r", "", "Branch or tag name to run the workflow on (defaults to repository's default branch)")
|
workflowRunCmd.Flags().StringP("ref", "r", "", "Branch or tag name to run the workflow on (defaults to repository's default branch)")
|
||||||
workflowRunCmd.Flags().StringSliceP("field", "f", nil, "Add a string parameter in key=value format (can be used multiple times)")
|
workflowRunCmd.Flags().StringSliceP("field", "f", nil, "Add a string parameter in key=value format (can be used multiple times)")
|
||||||
workflowRunCmd.Flags().StringSliceP("raw-field", "F", nil, "Add a string parameter in key=value format, reading from file if value starts with @ (can be used multiple times)")
|
workflowRunCmd.Flags().StringSliceP("raw-field", "F", nil, "Add a string parameter in key=value format, reading from file if value starts with @ (can be used multiple times)")
|
||||||
|
|
@ -874,37 +896,9 @@ func runWorkflowView(cmd *cobra.Command, args []string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
workflowIdentifier := args[0]
|
workflowIdentifier := args[0]
|
||||||
|
workflow, err := findWorkflow(client, owner, name, workflowIdentifier)
|
||||||
// Find the workflow by listing from both .gitea/workflows and .forgejo/workflows
|
if err != nil {
|
||||||
var workflow *Workflow
|
return err
|
||||||
|
|
||||||
for _, dir := range []string{".gitea/workflows", ".forgejo/workflows"} {
|
|
||||||
endpoint := fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s", owner, name, dir)
|
|
||||||
|
|
||||||
var contents []ContentsResponse
|
|
||||||
if err := client.GetJSON(endpoint, &contents); err != nil {
|
|
||||||
// Directory might not exist, continue
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, content := range contents {
|
|
||||||
if content.Type == "file" && (content.Name == workflowIdentifier || content.Path == workflowIdentifier) {
|
|
||||||
workflow = &Workflow{
|
|
||||||
Name: content.Name,
|
|
||||||
Path: content.Path,
|
|
||||||
State: "active",
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if workflow != nil {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if workflow == nil {
|
|
||||||
return fmt.Errorf("workflow '%s' not found", workflowIdentifier)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
jsonOutput, _ := cmd.Flags().GetBool("json")
|
jsonOutput, _ := cmd.Flags().GetBool("json")
|
||||||
|
|
@ -1024,6 +1018,96 @@ func runWorkflowRun(cmd *cobra.Command, args []string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func runWorkflowEnable(cmd *cobra.Command, args []string) error {
|
||||||
|
cfg, err := config.Load()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to load config: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
client, err := api.NewClientFromConfig(cfg, "", getDetectedHost())
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to create client: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
repo, _ := cmd.Flags().GetString("repo")
|
||||||
|
owner, name, err := parseRepo(repo)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
workflowIdentifier := args[0]
|
||||||
|
workflow, err := findWorkflow(client, owner, name, workflowIdentifier)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
endpoint := fmt.Sprintf("/api/v1/repos/%s/%s/actions/workflows/%s/enable", owner, name, workflow.Name)
|
||||||
|
|
||||||
|
// Try PUT first (correct method per GitHub/Gitea API spec)
|
||||||
|
status, err := client.DoJSON(http.MethodPut, endpoint, nil, nil)
|
||||||
|
if err != nil && (status == http.StatusNotFound || status == http.StatusMethodNotAllowed) {
|
||||||
|
// Fall back to POST for older versions
|
||||||
|
status, err = client.DoJSON(http.MethodPost, endpoint, nil, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
if status == http.StatusNotFound && strings.Contains(err.Error(), "404") {
|
||||||
|
return fmt.Errorf("failed to enable workflow: this feature requires Forgejo 15.0+ or Gitea 1.24+\n" +
|
||||||
|
"Your instance does not support the workflow enable/disable API endpoints yet.\n" +
|
||||||
|
"You can enable workflows via the web UI instead.")
|
||||||
|
}
|
||||||
|
return fmt.Errorf("failed to enable workflow: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("✓ Workflow '%s' enabled\n", workflow.Name)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func runWorkflowDisable(cmd *cobra.Command, args []string) error {
|
||||||
|
cfg, err := config.Load()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to load config: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
client, err := api.NewClientFromConfig(cfg, "", getDetectedHost())
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to create client: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
repo, _ := cmd.Flags().GetString("repo")
|
||||||
|
owner, name, err := parseRepo(repo)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
workflowIdentifier := args[0]
|
||||||
|
workflow, err := findWorkflow(client, owner, name, workflowIdentifier)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
endpoint := fmt.Sprintf("/api/v1/repos/%s/%s/actions/workflows/%s/disable", owner, name, workflow.Name)
|
||||||
|
|
||||||
|
// Try PUT first (correct method per GitHub/Gitea API spec)
|
||||||
|
status, err := client.DoJSON(http.MethodPut, endpoint, nil, nil)
|
||||||
|
if err != nil && (status == http.StatusNotFound || status == http.StatusMethodNotAllowed) {
|
||||||
|
// Fall back to POST for older versions
|
||||||
|
status, err = client.DoJSON(http.MethodPost, endpoint, nil, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
if status == http.StatusNotFound && strings.Contains(err.Error(), "404") {
|
||||||
|
return fmt.Errorf("failed to disable workflow: this feature requires Forgejo 15.0+ or Gitea 1.24+\n" +
|
||||||
|
"Your instance does not support the workflow enable/disable API endpoints yet.\n" +
|
||||||
|
"You can disable workflows via the web UI instead.")
|
||||||
|
}
|
||||||
|
return fmt.Errorf("failed to disable workflow: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("✓ Workflow '%s' disabled\n", workflow.Name)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func splitKeyValue(s string) []string {
|
func splitKeyValue(s string) []string {
|
||||||
idx := -1
|
idx := -1
|
||||||
for i, c := range s {
|
for i, c := range s {
|
||||||
|
|
@ -1038,6 +1122,29 @@ func splitKeyValue(s string) []string {
|
||||||
return []string{s[:idx], s[idx+1:]}
|
return []string{s[:idx], s[idx+1:]}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func findWorkflow(client *api.Client, owner, name, workflowIdentifier string) (*Workflow, error) {
|
||||||
|
for _, dir := range []string{".gitea/workflows", ".forgejo/workflows"} {
|
||||||
|
endpoint := fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s", owner, name, dir)
|
||||||
|
|
||||||
|
var contents []ContentsResponse
|
||||||
|
if err := client.GetJSON(endpoint, &contents); err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, content := range contents {
|
||||||
|
if content.Type == "file" && (content.Name == workflowIdentifier || content.Path == workflowIdentifier) {
|
||||||
|
return &Workflow{
|
||||||
|
Name: content.Name,
|
||||||
|
Path: content.Path,
|
||||||
|
State: "active",
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, fmt.Errorf("workflow '%s' not found", workflowIdentifier)
|
||||||
|
}
|
||||||
|
|
||||||
// Secret command implementations
|
// Secret command implementations
|
||||||
|
|
||||||
func runActionsSecretList(cmd *cobra.Command, args []string) error {
|
func runActionsSecretList(cmd *cobra.Command, args []string) error {
|
||||||
|
|
|
||||||
2
go.mod
2
go.mod
|
|
@ -12,6 +12,7 @@ require (
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/42wim/httpsig v1.2.3 // indirect
|
github.com/42wim/httpsig v1.2.3 // indirect
|
||||||
|
github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect
|
||||||
github.com/davidmz/go-pageant v1.0.2 // indirect
|
github.com/davidmz/go-pageant v1.0.2 // indirect
|
||||||
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
||||||
github.com/go-fed/httpsig v1.1.0 // indirect
|
github.com/go-fed/httpsig v1.1.0 // indirect
|
||||||
|
|
@ -21,6 +22,7 @@ require (
|
||||||
github.com/magiconair/properties v1.8.7 // indirect
|
github.com/magiconair/properties v1.8.7 // indirect
|
||||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||||
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
|
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
|
||||||
|
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||||
github.com/sagikazarmark/locafero v0.4.0 // indirect
|
github.com/sagikazarmark/locafero v0.4.0 // indirect
|
||||||
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
|
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
|
||||||
github.com/sourcegraph/conc v0.3.0 // indirect
|
github.com/sourcegraph/conc v0.3.0 // indirect
|
||||||
|
|
|
||||||
2
go.sum
2
go.sum
|
|
@ -2,6 +2,7 @@ code.gitea.io/sdk/gitea v0.22.1 h1:7K05KjRORyTcTYULQ/AwvlVS6pawLcWyXZcTr7gHFyA=
|
||||||
code.gitea.io/sdk/gitea v0.22.1/go.mod h1:yyF5+GhljqvA30sRDreoyHILruNiy4ASufugzYg0VHM=
|
code.gitea.io/sdk/gitea v0.22.1/go.mod h1:yyF5+GhljqvA30sRDreoyHILruNiy4ASufugzYg0VHM=
|
||||||
github.com/42wim/httpsig v1.2.3 h1:xb0YyWhkYj57SPtfSttIobJUPJZB9as1nsfo7KWVcEs=
|
github.com/42wim/httpsig v1.2.3 h1:xb0YyWhkYj57SPtfSttIobJUPJZB9as1nsfo7KWVcEs=
|
||||||
github.com/42wim/httpsig v1.2.3/go.mod h1:nZq9OlYKDrUBhptd77IHx4/sZZD+IxTBADvAPI9G/EM=
|
github.com/42wim/httpsig v1.2.3/go.mod h1:nZq9OlYKDrUBhptd77IHx4/sZZD+IxTBADvAPI9G/EM=
|
||||||
|
github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
|
@ -38,6 +39,7 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI
|
||||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
||||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||||
|
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ=
|
github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ=
|
||||||
github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4=
|
github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4=
|
||||||
|
|
|
||||||
|
|
@ -88,6 +88,13 @@ func (c *Client) GetJSON(path string, result any) error {
|
||||||
|
|
||||||
// PostJSON performs a POST request to the specified path with JSON body
|
// PostJSON performs a POST request to the specified path with JSON body
|
||||||
func (c *Client) PostJSON(path string, body any, result any) error {
|
func (c *Client) PostJSON(path string, body any, result any) error {
|
||||||
|
_, err := c.DoJSON(http.MethodPost, path, body, result)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DoJSON performs an HTTP request with a JSON body and decodes the JSON response.
|
||||||
|
// Returns the HTTP status code and any error encountered.
|
||||||
|
func (c *Client) DoJSON(method string, path string, body any, result any) (int, error) {
|
||||||
baseURL := "https://" + c.hostname
|
baseURL := "https://" + c.hostname
|
||||||
url := baseURL + path
|
url := baseURL + path
|
||||||
|
|
||||||
|
|
@ -95,14 +102,14 @@ func (c *Client) PostJSON(path string, body any, result any) error {
|
||||||
if body != nil {
|
if body != nil {
|
||||||
bodyBytes, err := json.Marshal(body)
|
bodyBytes, err := json.Marshal(body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to marshal request body: %w", err)
|
return 0, fmt.Errorf("failed to marshal request body: %w", err)
|
||||||
}
|
}
|
||||||
bodyReader = bytes.NewReader(bodyBytes)
|
bodyReader = bytes.NewReader(bodyBytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
req, err := http.NewRequest(http.MethodPost, url, bodyReader)
|
req, err := http.NewRequest(method, url, bodyReader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create request: %w", err)
|
return 0, fmt.Errorf("failed to create request: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set authentication header
|
// Set authentication header
|
||||||
|
|
@ -110,12 +117,14 @@ func (c *Client) PostJSON(path string, body any, result any) error {
|
||||||
req.Header.Set("Authorization", "token "+c.token)
|
req.Header.Set("Authorization", "token "+c.token)
|
||||||
}
|
}
|
||||||
req.Header.Set("Accept", "application/json")
|
req.Header.Set("Accept", "application/json")
|
||||||
|
if body != nil {
|
||||||
req.Header.Set("Content-Type", "application/json")
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
}
|
||||||
|
|
||||||
httpClient := &http.Client{}
|
httpClient := &http.Client{}
|
||||||
resp, err := httpClient.Do(req)
|
resp, err := httpClient.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to perform request: %w", err)
|
return 0, fmt.Errorf("failed to perform request: %w", err)
|
||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
if closeErr := resp.Body.Close(); closeErr != nil && err == nil {
|
if closeErr := resp.Body.Close(); closeErr != nil && err == nil {
|
||||||
|
|
@ -125,16 +134,16 @@ func (c *Client) PostJSON(path string, body any, result any) error {
|
||||||
|
|
||||||
if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusCreated && resp.StatusCode != http.StatusNoContent {
|
if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusCreated && resp.StatusCode != http.StatusNoContent {
|
||||||
bodyBytes, _ := io.ReadAll(resp.Body)
|
bodyBytes, _ := io.ReadAll(resp.Body)
|
||||||
return fmt.Errorf("API request failed with status %d: %s", resp.StatusCode, string(bodyBytes))
|
return resp.StatusCode, fmt.Errorf("API request failed with status %d: %s", resp.StatusCode, string(bodyBytes))
|
||||||
}
|
}
|
||||||
|
|
||||||
if result != nil && resp.StatusCode != http.StatusNoContent {
|
if result != nil && resp.StatusCode != http.StatusNoContent {
|
||||||
if err := json.NewDecoder(resp.Body).Decode(result); err != nil {
|
if err := json.NewDecoder(resp.Body).Decode(result); err != nil {
|
||||||
return fmt.Errorf("failed to decode response: %w", err)
|
return resp.StatusCode, fmt.Errorf("failed to decode response: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return resp.StatusCode, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetRawLog performs a GET request and returns the raw response body as string
|
// GetRawLog performs a GET request and returns the raw response body as string
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue