decap-cms-backend-github 3.8.3 → 3.9.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -2
- package/dist/decap-cms-backend-github.js +4 -4
- package/dist/decap-cms-backend-github.js.map +1 -1
- package/dist/esm/API.js +21 -7
- package/dist/esm/implementation.js +1 -1
- package/package.json +4 -4
- package/src/API.ts +29 -11
- package/src/__tests__/API.spec.js +36 -0
- package/src/implementation.tsx +1 -1
package/dist/esm/API.js
CHANGED
|
@@ -642,22 +642,36 @@ export default class API {
|
|
|
642
642
|
const branchesWithFilter = await Promise.all(branches.map(b => this.filterOpenAuthoringBranches(b)));
|
|
643
643
|
branches = branchesWithFilter.filter(b => b.filter).map(b => b.branch);
|
|
644
644
|
} else {
|
|
645
|
-
//
|
|
646
|
-
|
|
645
|
+
// One fetch, two filters. `getPullRequests` re-requests the list for
|
|
646
|
+
// each predicate, and both calls here pass the same `head`/`state`, so
|
|
647
|
+
// the two below issued a byte-identical
|
|
648
|
+
// `GET /pulls?base=…&state=open&per_page=100` on every collection load —
|
|
649
|
+
// 2.0s + 1.8s of it when the request goes through a proxy. The predicate
|
|
650
|
+
// is applied client-side anyway, so the page only needs fetching once.
|
|
651
|
+
const openPullRequests = await this.getPullRequests(undefined, PullRequestState.Open, () => true);
|
|
652
|
+
|
|
653
|
+
// Backwards compatibility: entries created before the CMS labelled its
|
|
654
|
+
// pull requests. Effectively always empty on a repo that has only ever
|
|
655
|
+
// been edited by a current CMS.
|
|
656
|
+
const unlabeled = openPullRequests.filter(pr => !pr.head.repo.fork && withoutCmsLabel(pr, this.cmsLabelPrefix));
|
|
647
657
|
let prCount = 0;
|
|
648
|
-
for (const pr of
|
|
658
|
+
for (const pr of unlabeled) {
|
|
649
659
|
if (!migrationNotified) {
|
|
650
660
|
migrationNotified = true;
|
|
651
661
|
alert(oneLine`
|
|
652
|
-
Decap CMS is adding labels to ${
|
|
662
|
+
Decap CMS is adding labels to ${unlabeled.length} of your Editorial Workflow
|
|
653
663
|
entries. The "Workflow" tab will be unavailable during this migration. You may use other
|
|
654
664
|
areas of the CMS during this time. Note that closing the CMS will pause the migration.
|
|
655
665
|
`);
|
|
656
666
|
}
|
|
657
667
|
prCount = prCount + 1;
|
|
658
|
-
await this.migratePullRequest(pr, `${prCount} of ${
|
|
668
|
+
await this.migratePullRequest(pr, `${prCount} of ${unlabeled.length}`);
|
|
659
669
|
}
|
|
660
|
-
|
|
670
|
+
|
|
671
|
+
// Migration is what puts the label on, so when it ran the list has to be
|
|
672
|
+
// read again — the page fetched above predates those labels. Conditional
|
|
673
|
+
// rather than unconditional precisely because that path is the rare one.
|
|
674
|
+
const cmsPullRequests = unlabeled.length ? await this.getPullRequests(undefined, PullRequestState.Open, pr => withCmsLabel(pr, this.cmsLabelPrefix)) : openPullRequests.filter(pr => withCmsLabel(pr, this.cmsLabelPrefix));
|
|
661
675
|
branches = cmsPullRequests.map(pr => pr.head.ref);
|
|
662
676
|
}
|
|
663
677
|
return branches;
|
|
@@ -1218,7 +1232,7 @@ export default class API {
|
|
|
1218
1232
|
}
|
|
1219
1233
|
|
|
1220
1234
|
/**
|
|
1221
|
-
*
|
|
1235
|
+
* How a notes issue is recognised on the host.
|
|
1222
1236
|
*/
|
|
1223
1237
|
static NOTES_LABEL = 'decap-cms-notes';
|
|
1224
1238
|
static NOTE_ISSUE_PREFIX = 'Notes: ';
|
|
@@ -262,7 +262,7 @@ export default class GitHub {
|
|
|
262
262
|
useOpenAuthoring: this.useOpenAuthoring,
|
|
263
263
|
initialWorkflowStatus: this.options.initialWorkflowStatus,
|
|
264
264
|
baseUrl: this.baseUrl,
|
|
265
|
-
getUser:
|
|
265
|
+
getUser: this.currentUser.bind(this)
|
|
266
266
|
});
|
|
267
267
|
const user = await this.api.user();
|
|
268
268
|
const isCollab = await this.api.hasWriteAccess().catch(error => {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "decap-cms-backend-github",
|
|
3
3
|
"description": "GitHub backend for Decap CMS",
|
|
4
|
-
"version": "3.
|
|
4
|
+
"version": "3.9.0-beta.1",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -34,9 +34,9 @@
|
|
|
34
34
|
"lodash": "^4.17.11",
|
|
35
35
|
"prop-types": "^15.7.2",
|
|
36
36
|
"react": "^19.1.0",
|
|
37
|
-
"decap-cms-lib-auth": "3.3.
|
|
38
|
-
"decap-cms-lib-util": "3.
|
|
39
|
-
"decap-cms-ui-default": "3.9.
|
|
37
|
+
"decap-cms-lib-auth": "3.3.3-beta.0",
|
|
38
|
+
"decap-cms-lib-util": "3.9.0-beta.1",
|
|
39
|
+
"decap-cms-ui-default": "3.9.3-beta.0"
|
|
40
40
|
},
|
|
41
41
|
"browser": {
|
|
42
42
|
"path": "path-browserify"
|
package/src/API.ts
CHANGED
|
@@ -899,28 +899,46 @@ export default class API {
|
|
|
899
899
|
);
|
|
900
900
|
branches = branchesWithFilter.filter(b => b.filter).map(b => b.branch);
|
|
901
901
|
} else {
|
|
902
|
-
//
|
|
903
|
-
|
|
902
|
+
// One fetch, two filters. `getPullRequests` re-requests the list for
|
|
903
|
+
// each predicate, and both calls here pass the same `head`/`state`, so
|
|
904
|
+
// the two below issued a byte-identical
|
|
905
|
+
// `GET /pulls?base=…&state=open&per_page=100` on every collection load —
|
|
906
|
+
// 2.0s + 1.8s of it when the request goes through a proxy. The predicate
|
|
907
|
+
// is applied client-side anyway, so the page only needs fetching once.
|
|
908
|
+
const openPullRequests = await this.getPullRequests(
|
|
904
909
|
undefined,
|
|
905
910
|
PullRequestState.Open,
|
|
911
|
+
() => true,
|
|
912
|
+
);
|
|
913
|
+
|
|
914
|
+
// Backwards compatibility: entries created before the CMS labelled its
|
|
915
|
+
// pull requests. Effectively always empty on a repo that has only ever
|
|
916
|
+
// been edited by a current CMS.
|
|
917
|
+
const unlabeled = openPullRequests.filter(
|
|
906
918
|
pr => !pr.head.repo.fork && withoutCmsLabel(pr, this.cmsLabelPrefix),
|
|
907
919
|
);
|
|
908
920
|
let prCount = 0;
|
|
909
|
-
for (const pr of
|
|
921
|
+
for (const pr of unlabeled) {
|
|
910
922
|
if (!migrationNotified) {
|
|
911
923
|
migrationNotified = true;
|
|
912
924
|
alert(oneLine`
|
|
913
|
-
Decap CMS is adding labels to ${
|
|
925
|
+
Decap CMS is adding labels to ${unlabeled.length} of your Editorial Workflow
|
|
914
926
|
entries. The "Workflow" tab will be unavailable during this migration. You may use other
|
|
915
927
|
areas of the CMS during this time. Note that closing the CMS will pause the migration.
|
|
916
928
|
`);
|
|
917
929
|
}
|
|
918
930
|
prCount = prCount + 1;
|
|
919
|
-
await this.migratePullRequest(pr, `${prCount} of ${
|
|
931
|
+
await this.migratePullRequest(pr, `${prCount} of ${unlabeled.length}`);
|
|
920
932
|
}
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
933
|
+
|
|
934
|
+
// Migration is what puts the label on, so when it ran the list has to be
|
|
935
|
+
// read again — the page fetched above predates those labels. Conditional
|
|
936
|
+
// rather than unconditional precisely because that path is the rare one.
|
|
937
|
+
const cmsPullRequests = unlabeled.length
|
|
938
|
+
? await this.getPullRequests(undefined, PullRequestState.Open, pr =>
|
|
939
|
+
withCmsLabel(pr, this.cmsLabelPrefix),
|
|
940
|
+
)
|
|
941
|
+
: openPullRequests.filter(pr => withCmsLabel(pr, this.cmsLabelPrefix));
|
|
924
942
|
branches = cmsPullRequests.map(pr => pr.head.ref);
|
|
925
943
|
}
|
|
926
944
|
|
|
@@ -1556,10 +1574,10 @@ export default class API {
|
|
|
1556
1574
|
}
|
|
1557
1575
|
|
|
1558
1576
|
/**
|
|
1559
|
-
*
|
|
1577
|
+
* How a notes issue is recognised on the host.
|
|
1560
1578
|
*/
|
|
1561
|
-
|
|
1562
|
-
|
|
1579
|
+
static readonly NOTES_LABEL = 'decap-cms-notes';
|
|
1580
|
+
static readonly NOTE_ISSUE_PREFIX = 'Notes: ';
|
|
1563
1581
|
|
|
1564
1582
|
/**
|
|
1565
1583
|
* Parse a GitHub comment into a Note object
|
|
@@ -724,6 +724,42 @@ describe('github API', () => {
|
|
|
724
724
|
});
|
|
725
725
|
});
|
|
726
726
|
|
|
727
|
+
describe('listUnpublishedBranches', () => {
|
|
728
|
+
function pullRequest(ref, labels) {
|
|
729
|
+
return { head: { ref, repo: { fork: false } }, labels: labels.map(name => ({ name })) };
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
it('reads the open pull request list once when nothing needs migrating', async () => {
|
|
733
|
+
const api = new API({ branch: 'main', repo: 'owner/repo' });
|
|
734
|
+
api.requestAllPages = jest
|
|
735
|
+
.fn()
|
|
736
|
+
.mockResolvedValue([pullRequest('cms/posts/a-post', ['decap-cms/pending_review'])]);
|
|
737
|
+
|
|
738
|
+
await expect(api.listUnpublishedBranches()).resolves.toEqual(['cms/posts/a-post']);
|
|
739
|
+
|
|
740
|
+
// The labelled and unlabelled sets are two filters over the same
|
|
741
|
+
// `GET /pulls?base=…&state=open` page, so asking for both must not cost
|
|
742
|
+
// two identical round trips.
|
|
743
|
+
expect(api.requestAllPages).toHaveBeenCalledTimes(1);
|
|
744
|
+
});
|
|
745
|
+
|
|
746
|
+
it('re-reads the list after a migration, because migrating is what adds the label', async () => {
|
|
747
|
+
const api = new API({ branch: 'main', repo: 'owner/repo' });
|
|
748
|
+
const unlabeled = pullRequest('cms/posts/legacy', []);
|
|
749
|
+
api.requestAllPages = jest
|
|
750
|
+
.fn()
|
|
751
|
+
.mockResolvedValueOnce([unlabeled])
|
|
752
|
+
.mockResolvedValueOnce([pullRequest('cms/posts/legacy', ['decap-cms/draft'])]);
|
|
753
|
+
api.migratePullRequest = jest.fn().mockResolvedValue(undefined);
|
|
754
|
+
global.alert = jest.fn();
|
|
755
|
+
|
|
756
|
+
await expect(api.listUnpublishedBranches()).resolves.toEqual(['cms/posts/legacy']);
|
|
757
|
+
|
|
758
|
+
expect(api.migratePullRequest).toHaveBeenCalledTimes(1);
|
|
759
|
+
expect(api.requestAllPages).toHaveBeenCalledTimes(2);
|
|
760
|
+
});
|
|
761
|
+
});
|
|
762
|
+
|
|
727
763
|
describe('listFiles', () => {
|
|
728
764
|
it('should get files by depth', async () => {
|
|
729
765
|
const api = new API({ branch: 'master', repo: 'owner/repo' });
|
package/src/implementation.tsx
CHANGED
|
@@ -358,7 +358,7 @@ export default class GitHub implements Implementation {
|
|
|
358
358
|
useOpenAuthoring: this.useOpenAuthoring,
|
|
359
359
|
initialWorkflowStatus: this.options.initialWorkflowStatus,
|
|
360
360
|
baseUrl: this.baseUrl,
|
|
361
|
-
getUser:
|
|
361
|
+
getUser: this.currentUser.bind(this),
|
|
362
362
|
});
|
|
363
363
|
const user = await this.api!.user();
|
|
364
364
|
const isCollab = await this.api!.hasWriteAccess().catch(error => {
|