diff --git a/src/main/java/org/kohsuke/github/GHRepository.java b/src/main/java/org/kohsuke/github/GHRepository.java index ee572ad69c..062de20195 100644 --- a/src/main/java/org/kohsuke/github/GHRepository.java +++ b/src/main/java/org/kohsuke/github/GHRepository.java @@ -2904,9 +2904,7 @@ public GHIssueEvent getIssueEvent(long id) throws IOException { * @return the paged iterable */ public PagedIterable listWorkflows() { - return root.createRequest() - .withUrlPath(getApiTailUrl("actions/workflows")) - .toIterable(GHWorkflow[].class, item -> item.wrapUp(root)); + return new GHWorkflowsIterable(this); } /** diff --git a/src/main/java/org/kohsuke/github/GHWorkflowsIterable.java b/src/main/java/org/kohsuke/github/GHWorkflowsIterable.java new file mode 100644 index 0000000000..19c77f3cae --- /dev/null +++ b/src/main/java/org/kohsuke/github/GHWorkflowsIterable.java @@ -0,0 +1,53 @@ +package org.kohsuke.github; + +import java.net.MalformedURLException; +import java.util.Iterator; + +import javax.annotation.Nonnull; + +/** + * Iterable for workflows listing. + */ +class GHWorkflowsIterable extends PagedIterable { + private final transient GHRepository owner; + + private GHWorkflowsPage result; + + public GHWorkflowsIterable(GHRepository owner) { + this.owner = owner; + } + + @Nonnull + @Override + public PagedIterator _iterator(int pageSize) { + try { + GitHubRequest request = owner.getRoot() + .createRequest() + .withUrlPath(owner.getApiTailUrl("actions/workflows")) + .build(); + + return new PagedIterator<>( + adapt(GitHubPageIterator + .create(owner.getRoot().getClient(), GHWorkflowsPage.class, request, pageSize)), + null); + } catch (MalformedURLException e) { + throw new GHException("Malformed URL", e); + } + } + + protected Iterator adapt(final Iterator base) { + return new Iterator() { + public boolean hasNext() { + return base.hasNext(); + } + + public GHWorkflow[] next() { + GHWorkflowsPage v = base.next(); + if (result == null) { + result = v; + } + return v.getWorkflows(owner); + } + }; + } +} diff --git a/src/main/java/org/kohsuke/github/GHWorkflowsPage.java b/src/main/java/org/kohsuke/github/GHWorkflowsPage.java new file mode 100644 index 0000000000..01460ed827 --- /dev/null +++ b/src/main/java/org/kohsuke/github/GHWorkflowsPage.java @@ -0,0 +1,20 @@ +package org.kohsuke.github; + +/** + * Represents the one page of workflow result when listing workflows. + */ +class GHWorkflowsPage { + private int total_count; + private GHWorkflow[] workflows; + + public int getTotalCount() { + return total_count; + } + + GHWorkflow[] getWorkflows(GHRepository owner) { + for (GHWorkflow workflow : workflows) { + workflow.wrapUp(owner); + } + return workflows; + } +} diff --git a/src/test/java/org/kohsuke/github/GHWorkflowTest.java b/src/test/java/org/kohsuke/github/GHWorkflowTest.java index 75a391b0e8..7e71315da2 100644 --- a/src/test/java/org/kohsuke/github/GHWorkflowTest.java +++ b/src/test/java/org/kohsuke/github/GHWorkflowTest.java @@ -6,6 +6,7 @@ import java.io.IOException; import java.util.Collections; +import java.util.List; import static com.github.tomakehurst.wiremock.client.WireMock.containing; import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor; @@ -86,4 +87,21 @@ public void testDispatch() throws IOException { .withRequestBody(containing("parameter")) .withRequestBody(containing("value"))); } + + @Test + public void testListWorkflows() throws IOException { + List workflows = repo.listWorkflows().toList(); + + GHWorkflow workflow = workflows.get(0); + assertEquals(6817859L, workflow.getId()); + assertEquals("MDg6V29ya2Zsb3c2ODE3ODU5", workflow.getNodeId()); + assertEquals("test-workflow", workflow.getName()); + assertEquals(".github/workflows/test-workflow.yml", workflow.getPath()); + assertEquals("active", workflow.getState()); + assertEquals("/repos/hub4j-test-org/GHWorkflowTest/actions/workflows/6817859", workflow.getUrl().getPath()); + assertEquals("/hub4j-test-org/GHWorkflowTest/blob/main/.github/workflows/test-workflow.yml", + workflow.getHtmlUrl().getPath()); + assertEquals("/hub4j-test-org/GHWorkflowTest/workflows/test-workflow/badge.svg", + workflow.getBadgeUrl().getPath()); + } } diff --git a/src/test/resources/org/kohsuke/github/GHWorkflowTest/wiremock/testListWorkflows/__files/repos_hub4j-test-org_ghworkflowtest-2.json b/src/test/resources/org/kohsuke/github/GHWorkflowTest/wiremock/testListWorkflows/__files/repos_hub4j-test-org_ghworkflowtest-2.json new file mode 100644 index 0000000000..c984c8be47 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/GHWorkflowTest/wiremock/testListWorkflows/__files/repos_hub4j-test-org_ghworkflowtest-2.json @@ -0,0 +1,126 @@ +{ + "id": 348651606, + "node_id": "MDEwOlJlcG9zaXRvcnkzNDg2NTE2MDY=", + "name": "GHWorkflowTest", + "full_name": "hub4j-test-org/GHWorkflowTest", + "private": false, + "owner": { + "login": "hub4j-test-org", + "id": 7544739, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjc1NDQ3Mzk=", + "avatar_url": "https://avatars.githubusercontent.com/u/7544739?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/hub4j-test-org", + "html_url": "https://github.com/hub4j-test-org", + "followers_url": "https://api.github.com/users/hub4j-test-org/followers", + "following_url": "https://api.github.com/users/hub4j-test-org/following{/other_user}", + "gists_url": "https://api.github.com/users/hub4j-test-org/gists{/gist_id}", + "starred_url": "https://api.github.com/users/hub4j-test-org/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/hub4j-test-org/subscriptions", + "organizations_url": "https://api.github.com/users/hub4j-test-org/orgs", + "repos_url": "https://api.github.com/users/hub4j-test-org/repos", + "events_url": "https://api.github.com/users/hub4j-test-org/events{/privacy}", + "received_events_url": "https://api.github.com/users/hub4j-test-org/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/hub4j-test-org/GHWorkflowTest", + "description": "Repository used for GHWorkflowTest", + "fork": false, + "url": "https://api.github.com/repos/hub4j-test-org/GHWorkflowTest", + "forks_url": "https://api.github.com/repos/hub4j-test-org/GHWorkflowTest/forks", + "keys_url": "https://api.github.com/repos/hub4j-test-org/GHWorkflowTest/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/hub4j-test-org/GHWorkflowTest/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/hub4j-test-org/GHWorkflowTest/teams", + "hooks_url": "https://api.github.com/repos/hub4j-test-org/GHWorkflowTest/hooks", + "issue_events_url": "https://api.github.com/repos/hub4j-test-org/GHWorkflowTest/issues/events{/number}", + "events_url": "https://api.github.com/repos/hub4j-test-org/GHWorkflowTest/events", + "assignees_url": "https://api.github.com/repos/hub4j-test-org/GHWorkflowTest/assignees{/user}", + "branches_url": "https://api.github.com/repos/hub4j-test-org/GHWorkflowTest/branches{/branch}", + "tags_url": "https://api.github.com/repos/hub4j-test-org/GHWorkflowTest/tags", + "blobs_url": "https://api.github.com/repos/hub4j-test-org/GHWorkflowTest/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/hub4j-test-org/GHWorkflowTest/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/hub4j-test-org/GHWorkflowTest/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/hub4j-test-org/GHWorkflowTest/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/hub4j-test-org/GHWorkflowTest/statuses/{sha}", + "languages_url": "https://api.github.com/repos/hub4j-test-org/GHWorkflowTest/languages", + "stargazers_url": "https://api.github.com/repos/hub4j-test-org/GHWorkflowTest/stargazers", + "contributors_url": "https://api.github.com/repos/hub4j-test-org/GHWorkflowTest/contributors", + "subscribers_url": "https://api.github.com/repos/hub4j-test-org/GHWorkflowTest/subscribers", + "subscription_url": "https://api.github.com/repos/hub4j-test-org/GHWorkflowTest/subscription", + "commits_url": "https://api.github.com/repos/hub4j-test-org/GHWorkflowTest/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/hub4j-test-org/GHWorkflowTest/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/hub4j-test-org/GHWorkflowTest/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/hub4j-test-org/GHWorkflowTest/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/hub4j-test-org/GHWorkflowTest/contents/{+path}", + "compare_url": "https://api.github.com/repos/hub4j-test-org/GHWorkflowTest/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/hub4j-test-org/GHWorkflowTest/merges", + "archive_url": "https://api.github.com/repos/hub4j-test-org/GHWorkflowTest/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/hub4j-test-org/GHWorkflowTest/downloads", + "issues_url": "https://api.github.com/repos/hub4j-test-org/GHWorkflowTest/issues{/number}", + "pulls_url": "https://api.github.com/repos/hub4j-test-org/GHWorkflowTest/pulls{/number}", + "milestones_url": "https://api.github.com/repos/hub4j-test-org/GHWorkflowTest/milestones{/number}", + "notifications_url": "https://api.github.com/repos/hub4j-test-org/GHWorkflowTest/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/hub4j-test-org/GHWorkflowTest/labels{/name}", + "releases_url": "https://api.github.com/repos/hub4j-test-org/GHWorkflowTest/releases{/id}", + "deployments_url": "https://api.github.com/repos/hub4j-test-org/GHWorkflowTest/deployments", + "created_at": "2021-03-17T09:32:03Z", + "updated_at": "2021-03-17T09:33:34Z", + "pushed_at": "2021-03-17T09:33:32Z", + "git_url": "git://github.com/hub4j-test-org/GHWorkflowTest.git", + "ssh_url": "git@github.com:hub4j-test-org/GHWorkflowTest.git", + "clone_url": "https://github.com/hub4j-test-org/GHWorkflowTest.git", + "svn_url": "https://github.com/hub4j-test-org/GHWorkflowTest", + "homepage": null, + "size": 1, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "forks_count": 0, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 0, + "license": null, + "forks": 0, + "open_issues": 0, + "watchers": 0, + "default_branch": "main", + "permissions": { + "admin": true, + "push": true, + "pull": true + }, + "temp_clone_token": "", + "allow_squash_merge": true, + "allow_merge_commit": true, + "allow_rebase_merge": true, + "delete_branch_on_merge": false, + "organization": { + "login": "hub4j-test-org", + "id": 7544739, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjc1NDQ3Mzk=", + "avatar_url": "https://avatars.githubusercontent.com/u/7544739?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/hub4j-test-org", + "html_url": "https://github.com/hub4j-test-org", + "followers_url": "https://api.github.com/users/hub4j-test-org/followers", + "following_url": "https://api.github.com/users/hub4j-test-org/following{/other_user}", + "gists_url": "https://api.github.com/users/hub4j-test-org/gists{/gist_id}", + "starred_url": "https://api.github.com/users/hub4j-test-org/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/hub4j-test-org/subscriptions", + "organizations_url": "https://api.github.com/users/hub4j-test-org/orgs", + "repos_url": "https://api.github.com/users/hub4j-test-org/repos", + "events_url": "https://api.github.com/users/hub4j-test-org/events{/privacy}", + "received_events_url": "https://api.github.com/users/hub4j-test-org/received_events", + "type": "Organization", + "site_admin": false + }, + "network_count": 0, + "subscribers_count": 10 +} \ No newline at end of file diff --git a/src/test/resources/org/kohsuke/github/GHWorkflowTest/wiremock/testListWorkflows/__files/repos_hub4j-test-org_ghworkflowtest_actions_workflows-3.json b/src/test/resources/org/kohsuke/github/GHWorkflowTest/wiremock/testListWorkflows/__files/repos_hub4j-test-org_ghworkflowtest_actions_workflows-3.json new file mode 100644 index 0000000000..6111529a6b --- /dev/null +++ b/src/test/resources/org/kohsuke/github/GHWorkflowTest/wiremock/testListWorkflows/__files/repos_hub4j-test-org_ghworkflowtest_actions_workflows-3.json @@ -0,0 +1,17 @@ +{ + "total_count": 1, + "workflows": [ + { + "id": 6817859, + "node_id": "MDg6V29ya2Zsb3c2ODE3ODU5", + "name": "test-workflow", + "path": ".github/workflows/test-workflow.yml", + "state": "active", + "created_at": "2021-03-17T10:33:32.000+01:00", + "updated_at": "2021-03-25T11:36:24.000+01:00", + "url": "https://api.github.com/repos/hub4j-test-org/GHWorkflowTest/actions/workflows/6817859", + "html_url": "https://github.com/hub4j-test-org/GHWorkflowTest/blob/main/.github/workflows/test-workflow.yml", + "badge_url": "https://github.com/hub4j-test-org/GHWorkflowTest/workflows/test-workflow/badge.svg" + } + ] +} \ No newline at end of file diff --git a/src/test/resources/org/kohsuke/github/GHWorkflowTest/wiremock/testListWorkflows/__files/user-1.json b/src/test/resources/org/kohsuke/github/GHWorkflowTest/wiremock/testListWorkflows/__files/user-1.json new file mode 100644 index 0000000000..6009ca36b4 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/GHWorkflowTest/wiremock/testListWorkflows/__files/user-1.json @@ -0,0 +1,46 @@ +{ + "login": "gsmet", + "id": 1279749, + "node_id": "MDQ6VXNlcjEyNzk3NDk=", + "avatar_url": "https://avatars.githubusercontent.com/u/1279749?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/gsmet", + "html_url": "https://github.com/gsmet", + "followers_url": "https://api.github.com/users/gsmet/followers", + "following_url": "https://api.github.com/users/gsmet/following{/other_user}", + "gists_url": "https://api.github.com/users/gsmet/gists{/gist_id}", + "starred_url": "https://api.github.com/users/gsmet/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/gsmet/subscriptions", + "organizations_url": "https://api.github.com/users/gsmet/orgs", + "repos_url": "https://api.github.com/users/gsmet/repos", + "events_url": "https://api.github.com/users/gsmet/events{/privacy}", + "received_events_url": "https://api.github.com/users/gsmet/received_events", + "type": "User", + "site_admin": false, + "name": "Guillaume Smet", + "company": "Red Hat", + "blog": "https://www.redhat.com/", + "location": "Lyon, France", + "email": "guillaume.smet@gmail.com", + "hireable": null, + "bio": "Happy camper at Red Hat, working on Quarkus and the Hibernate portfolio.", + "twitter_username": "gsmet_", + "public_repos": 102, + "public_gists": 14, + "followers": 126, + "following": 3, + "created_at": "2011-12-22T11:03:22Z", + "updated_at": "2021-03-25T13:53:32Z", + "private_gists": 14, + "total_private_repos": 4, + "owned_private_repos": 1, + "disk_usage": 68258, + "collaborators": 1, + "two_factor_authentication": true, + "plan": { + "name": "free", + "space": 976562499, + "collaborators": 0, + "private_repos": 10000 + } +} \ No newline at end of file diff --git a/src/test/resources/org/kohsuke/github/GHWorkflowTest/wiremock/testListWorkflows/mappings/repos_hub4j-test-org_ghworkflowtest-2.json b/src/test/resources/org/kohsuke/github/GHWorkflowTest/wiremock/testListWorkflows/mappings/repos_hub4j-test-org_ghworkflowtest-2.json new file mode 100644 index 0000000000..8cd5b19c2a --- /dev/null +++ b/src/test/resources/org/kohsuke/github/GHWorkflowTest/wiremock/testListWorkflows/mappings/repos_hub4j-test-org_ghworkflowtest-2.json @@ -0,0 +1,46 @@ +{ + "id": "df58f346-eeca-4472-aa08-1d09980919b3", + "name": "repos_hub4j-test-org_ghworkflowtest", + "request": { + "url": "/repos/hub4j-test-org/GHWorkflowTest", + "method": "GET", + "headers": { + "Accept": { + "equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2" + } + } + }, + "response": { + "status": 200, + "bodyFileName": "repos_hub4j-test-org_ghworkflowtest-2.json", + "headers": { + "Server": "GitHub.com", + "Date": "Mon, 29 Mar 2021 17:51:53 GMT", + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "private, max-age=60, s-maxage=60", + "Vary": [ + "Accept, Authorization, Cookie, X-GitHub-OTP", + "Accept-Encoding, Accept, X-Requested-With" + ], + "ETag": "W/\"082e0c2ae9f1d8387e22ebe7279d627738b78d114a3badc2d9e60dfb0b2a6abf\"", + "Last-Modified": "Wed, 17 Mar 2021 09:33:34 GMT", + "X-OAuth-Scopes": "repo, user, workflow", + "X-Accepted-OAuth-Scopes": "repo", + "X-GitHub-Media-Type": "unknown, github.v3", + "X-RateLimit-Limit": "5000", + "X-RateLimit-Remaining": "4995", + "X-RateLimit-Reset": "1617043912", + "X-RateLimit-Used": "5", + "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", + "X-Frame-Options": "deny", + "X-Content-Type-Options": "nosniff", + "X-XSS-Protection": "0", + "Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin", + "Content-Security-Policy": "default-src 'none'", + "X-GitHub-Request-Id": "C8C8:5652:A3CF5A:A72804:606213B9" + } + }, + "uuid": "df58f346-eeca-4472-aa08-1d09980919b3", + "persistent": true, + "insertionIndex": 2 +} \ No newline at end of file diff --git a/src/test/resources/org/kohsuke/github/GHWorkflowTest/wiremock/testListWorkflows/mappings/repos_hub4j-test-org_ghworkflowtest_actions_workflows-3.json b/src/test/resources/org/kohsuke/github/GHWorkflowTest/wiremock/testListWorkflows/mappings/repos_hub4j-test-org_ghworkflowtest_actions_workflows-3.json new file mode 100644 index 0000000000..48c9b6ff63 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/GHWorkflowTest/wiremock/testListWorkflows/mappings/repos_hub4j-test-org_ghworkflowtest_actions_workflows-3.json @@ -0,0 +1,45 @@ +{ + "id": "dd811eda-cc06-40cd-9260-383e392b9313", + "name": "repos_hub4j-test-org_ghworkflowtest_actions_workflows", + "request": { + "url": "/repos/hub4j-test-org/GHWorkflowTest/actions/workflows", + "method": "GET", + "headers": { + "Accept": { + "equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2" + } + } + }, + "response": { + "status": 200, + "bodyFileName": "repos_hub4j-test-org_ghworkflowtest_actions_workflows-3.json", + "headers": { + "Server": "GitHub.com", + "Date": "Mon, 29 Mar 2021 17:51:53 GMT", + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "private, max-age=60, s-maxage=60", + "Vary": [ + "Accept, Authorization, Cookie, X-GitHub-OTP", + "Accept-Encoding, Accept, X-Requested-With" + ], + "ETag": "W/\"76b4179d3e0eeaba9ea886a4fe4f776be351a51e1667ac4744affde359313a96\"", + "X-OAuth-Scopes": "repo, user, workflow", + "X-Accepted-OAuth-Scopes": "", + "X-GitHub-Media-Type": "unknown, github.v3", + "X-RateLimit-Limit": "5000", + "X-RateLimit-Remaining": "4994", + "X-RateLimit-Reset": "1617043912", + "X-RateLimit-Used": "6", + "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", + "X-Frame-Options": "deny", + "X-Content-Type-Options": "nosniff", + "X-XSS-Protection": "0", + "Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin", + "Content-Security-Policy": "default-src 'none'", + "X-GitHub-Request-Id": "C8C8:5652:A3CF91:A72838:606213B9" + } + }, + "uuid": "dd811eda-cc06-40cd-9260-383e392b9313", + "persistent": true, + "insertionIndex": 3 +} \ No newline at end of file diff --git a/src/test/resources/org/kohsuke/github/GHWorkflowTest/wiremock/testListWorkflows/mappings/user-1.json b/src/test/resources/org/kohsuke/github/GHWorkflowTest/wiremock/testListWorkflows/mappings/user-1.json new file mode 100644 index 0000000000..69def68b04 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/GHWorkflowTest/wiremock/testListWorkflows/mappings/user-1.json @@ -0,0 +1,46 @@ +{ + "id": "19315fcd-1c12-48ea-a908-1a01560c6be4", + "name": "user", + "request": { + "url": "/user", + "method": "GET", + "headers": { + "Accept": { + "equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2" + } + } + }, + "response": { + "status": 200, + "bodyFileName": "user-1.json", + "headers": { + "Server": "GitHub.com", + "Date": "Mon, 29 Mar 2021 17:51:52 GMT", + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "private, max-age=60, s-maxage=60", + "Vary": [ + "Accept, Authorization, Cookie, X-GitHub-OTP", + "Accept-Encoding, Accept, X-Requested-With" + ], + "ETag": "W/\"a86162d7dda1332f6aff41cf72b1bbcdc96c13eea262334a896dcd7a09be5d27\"", + "Last-Modified": "Thu, 25 Mar 2021 13:53:32 GMT", + "X-OAuth-Scopes": "repo, user, workflow", + "X-Accepted-OAuth-Scopes": "", + "X-GitHub-Media-Type": "unknown, github.v3", + "X-RateLimit-Limit": "5000", + "X-RateLimit-Remaining": "4999", + "X-RateLimit-Reset": "1617043912", + "X-RateLimit-Used": "1", + "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", + "X-Frame-Options": "deny", + "X-Content-Type-Options": "nosniff", + "X-XSS-Protection": "0", + "Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin", + "Content-Security-Policy": "default-src 'none'", + "X-GitHub-Request-Id": "C8C8:5652:A3CE7E:A72720:606213B7" + } + }, + "uuid": "19315fcd-1c12-48ea-a908-1a01560c6be4", + "persistent": true, + "insertionIndex": 1 +} \ No newline at end of file