Skip to content

WIP: confluence: replace gopencils with resty/v3#723

Open
mrueg wants to merge 1 commit intokovetskiy:masterfrom
mrueg:resty
Open

WIP: confluence: replace gopencils with resty/v3#723
mrueg wants to merge 1 commit intokovetskiy:masterfrom
mrueg:resty

Conversation

@mrueg
Copy link
Collaborator

@mrueg mrueg commented Feb 8, 2026

This migration replaces the unmaintained gopencils library with resty v3.

Key changes include:
- Updated API struct and NewAPI to use resty.Client.
- Replaced custom multipart form handling with resty's native support (SetFileReader, SetFormData).
- Updated all API methods to use resty's fluent request API.
- Implemented resty.Logger for trace logging.
- Updated error handling to utilize resty.Response and provided more detailed error output.

@mrueg mrueg changed the title confluence: replace gopencils with resty/v2 confluence: replace gopencils with resty/v3 Feb 8, 2026
@mrueg mrueg changed the title confluence: replace gopencils with resty/v3 WIP: confluence: replace gopencils with resty/v3 Feb 8, 2026
This migration replaces the unmaintained gopencils library with resty v3.

Key changes include:
- Updated API struct and NewAPI to use resty.Client.
- Replaced custom multipart form handling with resty's native support (SetFileReader, SetFormData).
- Updated all API methods to use resty's fluent request API.
- Implemented resty.Logger for trace logging.
- Updated error handling to utilize resty.Response and provided more detailed error output.
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Migrates the Confluence client implementation from the unmaintained gopencils library to resty.dev/v3, updating request construction, multipart uploads, and error handling to use Resty’s client and fluent request API.

Changes:

  • Replace gopencils.Resource usage with resty.Client and R()-based requests across Confluence API methods.
  • Switch attachment uploads to Resty’s native multipart helpers (SetFileReader, SetFormData).
  • Update tracing/debug logging and error formatting to use resty.Response.

Reviewed changes

Copilot reviewed 2 out of 3 changed files in this pull request and generated 4 comments.

File Description
go.mod Drops gopencils and adds resty.dev/v3 dependency.
go.sum Removes gopencils checksums and adds resty.dev/v3 checksums.
confluence/api.go Refactors all Confluence HTTP calls to Resty and updates logging/error handling accordingly.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +724 to +725
u, _ := url.Parse(api.rest.BaseURL())
if strings.HasSuffix(u.Host, "jira.com") || strings.HasSuffix(u.Host, "atlassian.net") {
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

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

url.Parse(api.rest.BaseURL()) ignores the returned error. If parsing fails, u will be nil and u.Host will panic; even for partially-parsable URLs this can silently select the wrong (cloud vs server) codepath. Handle the parse error (and/or fall back to api.BaseURL) before reading u.Host.

Suggested change
u, _ := url.Parse(api.rest.BaseURL())
if strings.HasSuffix(u.Host, "jira.com") || strings.HasSuffix(u.Host, "atlassian.net") {
baseURL := api.rest.BaseURL()
u, parseErr := url.Parse(baseURL)
host := baseURL
if parseErr == nil && u != nil && u.Host != "" {
host = u.Host
}
if strings.HasSuffix(host, "jira.com") || strings.HasSuffix(host, "atlassian.net") {

Copilot uses AI. Check for mistakes.
Comment on lines +597 to 603
_, err := api.rest.R().
SetQueryParam("cql", fmt.Sprintf("user.fullname~%q", name)).
SetResult(&response).
Get("search/user")
if err != nil {
return nil, err
}
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

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

This request ignores the HTTP status code. With resty, non-2xx responses typically don’t surface as err, so a 401/403/etc can be misreported later as “user not found”. Capture the response (resp := ...Get(...)) and call newErrorResponseNotOK(resp) when resp.StatusCode() != http.StatusOK.

Copilot uses AI. Check for mistakes.
Comment on lines +631 to 636
_, err := api.rest.R().
SetResult(&user).
Get("user/current")
if err != nil {
return nil, err
}
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

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

This request ignores the HTTP status code. With resty, err usually only covers transport/unmarshal errors, so authentication/permission failures (e.g., 401/403) could be returned as a nil error and an empty/partial user. Capture the response and check resp.StatusCode() == http.StatusOK (otherwise return newErrorResponseNotOK(resp)).

Copilot uses AI. Check for mistakes.
Comment on lines +641 to +667
func (api *API) RestrictPageUpdatesCloud(
page *PageInfo,
allowedUser string,
) error {
user, err := api.GetCurrentUser()
if err != nil {
return err
}

var result interface{}

request, err := api.rest.
Res("content").
Id(page.ID).
Res("restriction", &result).
Post([]map[string]interface{}{
resp, err := api.rest.R().
SetBody([]map[string]interface{}{
{
"operation": "update",
"restrictions": map[string]interface{}{
"user": []map[string]interface{}{
{
"type": "known",
"accountId": user.AccountID,
},
},
},
},
})
}).
SetResult(&result).
Post("content/" + page.ID + "/restriction")
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

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

RestrictPageUpdatesCloud ignores the allowedUser argument (it always restricts to the current user’s accountId). This is surprising given the API and differs from the server implementation. Either use allowedUser (likely by resolving it to an accountId) or rename/remove the parameter to avoid misleading callers.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants