Skip to content

Commit

Permalink
Merge pull request #1264 from Cyb3r-Jak3/pages-deployment-autoPaginate
Browse files Browse the repository at this point in the history
Add support for pages deployment auto pagination
  • Loading branch information
jacobbednarz authored Jul 7, 2023
2 parents 6fdc6f8 + bbd657e commit 845abcd
Show file tree
Hide file tree
Showing 5 changed files with 249 additions and 100 deletions.
19 changes: 19 additions & 0 deletions .changelog/1264.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
```release-note:breaking-change
pages_deployment: add support for auto pagination
```

```release-note:enchancement
pages_deployment: add Force to DeletePagesDeploymentParams
```

```release-note:breaking-change
pages_deployment: change DeletePagesDeploymentParams to contain all parameters
```

```release-note:breaking-change
pages_project: rename PagesProject to GetPagesProject
```

```release-note:breaking-change
pages_project: change to use ResourceContainer for account ID
```
74 changes: 45 additions & 29 deletions pages_deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,22 +62,16 @@ type pagesDeploymentResponse struct {
Result PagesProjectDeployment `json:"result"`
}

type pagesDeploymentStageLogsResponse struct {
Response
Result PagesDeploymentStageLogs `json:"result"`
ResultInfo `json:"result_info"`
}

type pagesDeploymentLogsResponse struct {
Response
Result PagesDeploymentLogs `json:"result"`
ResultInfo `json:"result_info"`
}

type ListPagesDeploymentsParams struct {
ProjectName string
ProjectName string `url:"-"`

PaginationOptions
ResultInfo
}

type GetPagesDeploymentInfoParams struct {
Expand All @@ -101,12 +95,14 @@ type GetPagesDeploymentLogsParams struct {
}

type DeletePagesDeploymentParams struct {
ProjectName string
DeploymentID string
ProjectName string `url:"-"`
DeploymentID string `url:"-"`
Force bool `url:"force,omitempty"`
}

type CreatePagesDeploymentParams struct {
ProjectName string
ProjectName string `json:"-"`
Branch string `json:"branch,omitempty"`
}

type RetryPagesDeploymentParams struct {
Expand All @@ -122,33 +118,53 @@ type RollbackPagesDeploymentParams struct {
var (
ErrMissingProjectName = errors.New("required missing project name")
ErrMissingDeploymentID = errors.New("required missing deployment ID")
ErrMissingStageName = errors.New("required missing stage name")
)

// ListPagesDeployments returns all deployments for a Pages project.
//
// API reference: https://api.cloudflare.com/#pages-deployment-get-deployments
func (api *API) ListPagesDeployments(ctx context.Context, rc *ResourceContainer, params ListPagesDeploymentsParams) ([]PagesProjectDeployment, ResultInfo, error) {
func (api *API) ListPagesDeployments(ctx context.Context, rc *ResourceContainer, params ListPagesDeploymentsParams) ([]PagesProjectDeployment, *ResultInfo, error) {
if rc.Identifier == "" {
return []PagesProjectDeployment{}, ResultInfo{}, ErrMissingAccountID
return []PagesProjectDeployment{}, &ResultInfo{}, ErrMissingAccountID
}

if params.ProjectName == "" {
return []PagesProjectDeployment{}, ResultInfo{}, ErrMissingProjectName
return []PagesProjectDeployment{}, &ResultInfo{}, ErrMissingProjectName
}

uri := buildURI(fmt.Sprintf("/accounts/%s/pages/projects/%s/deployments", rc.Identifier, params.ProjectName), params.PaginationOptions)
autoPaginate := true
if params.PerPage >= 1 || params.Page >= 1 {
autoPaginate = false
}

res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
if err != nil {
return []PagesProjectDeployment{}, ResultInfo{}, err
if params.PerPage < 1 {
params.PerPage = 25
}
var r pagesDeploymentListResponse
err = json.Unmarshal(res, &r)
if err != nil {
return []PagesProjectDeployment{}, ResultInfo{}, fmt.Errorf("%s: %w", errUnmarshalError, err)

if params.Page < 1 {
params.Page = 1
}
return r.Result, r.ResultInfo, nil

var deployments []PagesProjectDeployment
var r pagesDeploymentListResponse

for {
uri := buildURI(fmt.Sprintf("/accounts/%s/pages/projects/%s/deployments", rc.Identifier, params.ProjectName), params)
res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
if err != nil {
return []PagesProjectDeployment{}, &ResultInfo{}, err
}
err = json.Unmarshal(res, &r)
if err != nil {
return []PagesProjectDeployment{}, &ResultInfo{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
}
deployments = append(deployments, r.Result...)
params.ResultInfo = r.ResultInfo.Next()
if params.Done() || !autoPaginate {
break
}
}
return deployments, &r.ResultInfo, nil
}

// GetPagesDeploymentInfo returns a deployment for a Pages project.
Expand Down Expand Up @@ -217,20 +233,20 @@ func (api *API) GetPagesDeploymentLogs(ctx context.Context, rc *ResourceContaine
// DeletePagesDeployment deletes a Pages deployment.
//
// API reference: https://api.cloudflare.com/#pages-deployment-delete-deployment
func (api *API) DeletePagesDeployment(ctx context.Context, rc *ResourceContainer, projectName, deploymentID string) error {
func (api *API) DeletePagesDeployment(ctx context.Context, rc *ResourceContainer, params DeletePagesDeploymentParams) error {
if rc.Identifier == "" {
return ErrMissingAccountID
}

if projectName == "" {
if params.ProjectName == "" {
return ErrMissingProjectName
}

if deploymentID == "" {
if params.DeploymentID == "" {
return ErrMissingDeploymentID
}

uri := fmt.Sprintf("/accounts/%s/pages/projects/%s/deployments/%s", rc.Identifier, projectName, deploymentID)
uri := buildURI(fmt.Sprintf("/accounts/%s/pages/projects/%s/deployments/%s", rc.Identifier, params.ProjectName, params.DeploymentID), params)

_, err := api.makeRequestContext(ctx, http.MethodDelete, uri, nil)
if err != nil {
Expand All @@ -253,7 +269,7 @@ func (api *API) CreatePagesDeployment(ctx context.Context, rc *ResourceContainer

uri := fmt.Sprintf("/accounts/%s/pages/projects/%s/deployments", rc.Identifier, params.ProjectName)

res, err := api.makeRequestContext(ctx, http.MethodPost, uri, nil)
res, err := api.makeRequestContext(ctx, http.MethodPost, uri, params)
if err != nil {
return PagesProjectDeployment{}, err
}
Expand Down
120 changes: 71 additions & 49 deletions pages_deployment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
)

const (
testPagesDeplyomentResponse = `
testPagesDeploymentResponse = `
{
"id": "0012e50b-fa5d-44db-8cb5-1f372785dcbe",
"short_id": "0012e50b",
Expand Down Expand Up @@ -207,44 +207,6 @@ var (
Status: "success",
}

expectedPagesDeploymentStageLogEntries = []PagesDeploymentStageLogEntry{
{
ID: 0,
Timestamp: &pagesDeploymentDummyTime,
Message: "Installing dependencies",
},
{
ID: 1,
Timestamp: &pagesDeploymentDummyTime,
Message: "Verify run directory",
},
{
ID: 2,
Timestamp: &pagesDeploymentDummyTime,
Message: "Executing user command: bash test.sh",
},
{
ID: 3,
Timestamp: &pagesDeploymentDummyTime,
Message: "Finished",
},
{
ID: 4,
Timestamp: &pagesDeploymentDummyTime,
Message: "Building functions...",
},
{
ID: 5,
Timestamp: &pagesDeploymentDummyTime,
Message: "Validating asset output directory",
},
{
ID: 6,
Timestamp: &pagesDeploymentDummyTime,
Message: "Parsed 2 valid header rules.",
},
}

expectedPagesDeploymentLogs = &PagesDeploymentLogs{
Total: 6,
IncludesContainerLogs: true,
Expand Down Expand Up @@ -289,6 +251,8 @@ func TestListPagesDeployments(t *testing.T) {

handler := func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, http.MethodGet, r.Method, "Expected method 'GET', got %s", r.Method)
assert.Equal(t, "25", r.URL.Query().Get("per_page"))
assert.Equal(t, "1", r.URL.Query().Get("page"))

w.Header().Set("content-type", "application/json")
fmt.Fprintf(w, `{
Expand All @@ -304,7 +268,7 @@ func TestListPagesDeployments(t *testing.T) {
"count": 1,
"total_count": 1
}
}`, testPagesDeplyomentResponse)
}`, testPagesDeploymentResponse)
}

mux.HandleFunc("/accounts/"+testAccountID+"/pages/projects/test/deployments", handler)
Expand All @@ -319,12 +283,70 @@ func TestListPagesDeployments(t *testing.T) {
Total: 1,
}
actual, resultInfo, err := client.ListPagesDeployments(context.Background(), AccountIdentifier(testAccountID), ListPagesDeploymentsParams{
ProjectName: "test",
PaginationOptions: PaginationOptions{},
ProjectName: "test",
ResultInfo: ResultInfo{},
})
if assert.NoError(t, err) {
assert.Equal(t, expectedPagesDeployments, actual)
assert.Equal(t, expectedResultInfo, resultInfo)
assert.Equal(t, &expectedResultInfo, resultInfo)
}
}

func TestListPagesDeploymentsPagination(t *testing.T) {
setup()
defer teardown()
var page1Called, page2Called bool
handler := func(w http.ResponseWriter, r *http.Request) {
page := r.URL.Query().Get("page")
w.Header().Set("content-type", "application/json")
switch page {
case "1":
page1Called = true
fmt.Fprintf(w, `{
"success": true,
"errors": [],
"messages": [],
"result": [
%s
],
"result_info": {
"page": 1,
"per_page": 25,
"total_count": 26,
"total_pages": 2
}
}`, testPagesDeploymentResponse)
case "2":
page2Called = true
fmt.Fprintf(w, `{
"success": true,
"errors": [],
"messages": [],
"result": [
%s
],
"result_info": {
"page": 2,
"per_page": 25,
"total_count": 26,
"total_pages": 2
}
}`, testPagesDeploymentResponse)
default:
assert.Failf(t, "Unexpected page number", "Expected page 1 or 2, got %s", page)
return
}
}
mux.HandleFunc("/accounts/"+testAccountID+"/pages/projects/test/deployments", handler)
actual, resultInfo, err := client.ListPagesDeployments(context.Background(), AccountIdentifier(testAccountID), ListPagesDeploymentsParams{
ProjectName: "test",
ResultInfo: ResultInfo{},
})
if assert.NoError(t, err) {
assert.True(t, page1Called)
assert.True(t, page2Called)
assert.Equal(t, 2, len(actual))
assert.Equal(t, 26, resultInfo.Total)
}
}

Expand All @@ -341,7 +363,7 @@ func TestGetPagesDeploymentInfo(t *testing.T) {
"errors": [],
"messages": [],
"result": %s
}`, testPagesDeplyomentResponse)
}`, testPagesDeploymentResponse)
}

mux.HandleFunc("/accounts/"+testAccountID+"/pages/projects/test/deployments/0012e50b-fa5d-44db-8cb5-1f372785dcbe", handler)
Expand Down Expand Up @@ -386,7 +408,7 @@ func TestDeletePagesDeployment(t *testing.T) {

handler := func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, http.MethodDelete, r.Method, "Expected method 'DELETE', got %s", r.Method)

assert.Equal(t, "true", r.URL.Query().Get("force"))
w.Header().Set("content-type", "application/json")
fmt.Fprintf(w, `{
"success": true,
Expand All @@ -398,7 +420,7 @@ func TestDeletePagesDeployment(t *testing.T) {

mux.HandleFunc("/accounts/"+testAccountID+"/pages/projects/test/deployments/0012e50b-fa5d-44db-8cb5-1f372785dcbe", handler)

err := client.DeletePagesDeployment(context.Background(), AccountIdentifier(testAccountID), "test", "0012e50b-fa5d-44db-8cb5-1f372785dcbe")
err := client.DeletePagesDeployment(context.Background(), AccountIdentifier(testAccountID), DeletePagesDeploymentParams{ProjectName: "test", DeploymentID: "0012e50b-fa5d-44db-8cb5-1f372785dcbe", Force: true})
assert.NoError(t, err)
}

Expand All @@ -415,7 +437,7 @@ func TestCreatePagesDeployment(t *testing.T) {
"errors": [],
"messages": [],
"result": %s
}`, testPagesDeplyomentResponse)
}`, testPagesDeploymentResponse)
}

mux.HandleFunc("/accounts/"+testAccountID+"/pages/projects/test/deployments", handler)
Expand All @@ -442,7 +464,7 @@ func TestRetryPagesDeployment(t *testing.T) {
"errors": [],
"messages": [],
"result": %s
}`, testPagesDeplyomentResponse)
}`, testPagesDeploymentResponse)
}

mux.HandleFunc("/accounts/"+testAccountID+"/pages/projects/test/deployments/0012e50b-fa5d-44db-8cb5-1f372785dcbe/retry", handler)
Expand All @@ -466,7 +488,7 @@ func TestRollbackPagesDeployment(t *testing.T) {
"errors": [],
"messages": [],
"result": %s
}`, testPagesDeplyomentResponse)
}`, testPagesDeploymentResponse)
}

mux.HandleFunc("/accounts/"+testAccountID+"/pages/projects/test/deployments/0012e50b-fa5d-44db-8cb5-1f372785dcbe/rollback", handler)
Expand Down
Loading

0 comments on commit 845abcd

Please sign in to comment.