Revert "feat(core): Align GitHub metadata handling with other backends (#3292)"
This reverts commit 8193b5ace89d6f14a6c756235a50b186a763b6b1.
This commit is contained in:
parent
60edf10530
commit
5bdd3df9cc
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,4 +1,4 @@
|
|||||||
const { Octokit } = require('@octokit/rest');
|
const Octokit = require('@octokit/rest');
|
||||||
const fs = require('fs-extra');
|
const fs = require('fs-extra');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const {
|
const {
|
||||||
|
@ -200,7 +200,7 @@ function flushClockAndSave() {
|
|||||||
|
|
||||||
function populateEntry(entry, onDone = flushClockAndSave) {
|
function populateEntry(entry, onDone = flushClockAndSave) {
|
||||||
const keys = Object.keys(entry);
|
const keys = Object.keys(entry);
|
||||||
for (const key of keys) {
|
for (let key of keys) {
|
||||||
const value = entry[key];
|
const value = entry[key];
|
||||||
if (key === 'body') {
|
if (key === 'body') {
|
||||||
cy.getMarkdownEditor()
|
cy.getMarkdownEditor()
|
||||||
|
@ -23,7 +23,6 @@ import {
|
|||||||
PreviewState,
|
PreviewState,
|
||||||
FetchError,
|
FetchError,
|
||||||
parseContentKey,
|
parseContentKey,
|
||||||
branchFromContentKey,
|
|
||||||
} from 'netlify-cms-lib-util';
|
} from 'netlify-cms-lib-util';
|
||||||
import { oneLine } from 'common-tags';
|
import { oneLine } from 'common-tags';
|
||||||
import { parse } from 'what-the-diff';
|
import { parse } from 'what-the-diff';
|
||||||
@ -450,8 +449,8 @@ export default class API {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async editorialWorkflowGit(files: (Entry | AssetProxy)[], entry: Entry, options: PersistOptions) {
|
async editorialWorkflowGit(files: (Entry | AssetProxy)[], entry: Entry, options: PersistOptions) {
|
||||||
const contentKey = generateContentKey(options.collectionName as string, entry.slug);
|
const contentKey = this.generateContentKey(options.collectionName as string, entry.slug);
|
||||||
const branch = branchFromContentKey(contentKey);
|
const branch = this.branchFromContentKey(contentKey);
|
||||||
const unpublished = options.unpublished || false;
|
const unpublished = options.unpublished || false;
|
||||||
if (!unpublished) {
|
if (!unpublished) {
|
||||||
const defaultBranchSha = await this.branchCommitSha(this.branch);
|
const defaultBranchSha = await this.branchCommitSha(this.branch);
|
||||||
@ -498,6 +497,18 @@ export default class API {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
generateContentKey(collectionName: string, slug: string) {
|
||||||
|
return generateContentKey(collectionName, slug);
|
||||||
|
}
|
||||||
|
|
||||||
|
contentKeyFromBranch(branch: string) {
|
||||||
|
return branch.substring(`${CMS_BRANCH_PREFIX}/`.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
branchFromContentKey(contentKey: string) {
|
||||||
|
return `${CMS_BRANCH_PREFIX}/${contentKey}`;
|
||||||
|
}
|
||||||
|
|
||||||
async isFileExists(path: string, branch: string) {
|
async isFileExists(path: string, branch: string) {
|
||||||
const fileExists = await this.readFile(path, null, { branch })
|
const fileExists = await this.readFile(path, null, { branch })
|
||||||
.then(() => true)
|
.then(() => true)
|
||||||
@ -548,7 +559,7 @@ export default class API {
|
|||||||
|
|
||||||
async retrieveMetadata(contentKey: string) {
|
async retrieveMetadata(contentKey: string) {
|
||||||
const { collection, slug } = parseContentKey(contentKey);
|
const { collection, slug } = parseContentKey(contentKey);
|
||||||
const branch = branchFromContentKey(contentKey);
|
const branch = this.branchFromContentKey(contentKey);
|
||||||
const pullRequest = await this.getBranchPullRequest(branch);
|
const pullRequest = await this.getBranchPullRequest(branch);
|
||||||
const diff = await this.getDifferences(branch);
|
const diff = await this.getDifferences(branch);
|
||||||
const { newPath: path, newFile } = diff.find(d => !d.binary) as {
|
const { newPath: path, newFile } = diff.find(d => !d.binary) as {
|
||||||
@ -598,8 +609,8 @@ export default class API {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async updateUnpublishedEntryStatus(collection: string, slug: string, newStatus: string) {
|
async updateUnpublishedEntryStatus(collection: string, slug: string, newStatus: string) {
|
||||||
const contentKey = generateContentKey(collection, slug);
|
const contentKey = this.generateContentKey(collection, slug);
|
||||||
const branch = branchFromContentKey(contentKey);
|
const branch = this.branchFromContentKey(contentKey);
|
||||||
const pullRequest = await this.getBranchPullRequest(branch);
|
const pullRequest = await this.getBranchPullRequest(branch);
|
||||||
|
|
||||||
await this.addPullRequestComment(pullRequest, statusToLabel(newStatus));
|
await this.addPullRequestComment(pullRequest, statusToLabel(newStatus));
|
||||||
@ -621,8 +632,8 @@ export default class API {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async publishUnpublishedEntry(collectionName: string, slug: string) {
|
async publishUnpublishedEntry(collectionName: string, slug: string) {
|
||||||
const contentKey = generateContentKey(collectionName, slug);
|
const contentKey = this.generateContentKey(collectionName, slug);
|
||||||
const branch = branchFromContentKey(contentKey);
|
const branch = this.branchFromContentKey(contentKey);
|
||||||
const pullRequest = await this.getBranchPullRequest(branch);
|
const pullRequest = await this.getBranchPullRequest(branch);
|
||||||
|
|
||||||
await this.mergePullRequest(pullRequest);
|
await this.mergePullRequest(pullRequest);
|
||||||
@ -643,8 +654,8 @@ export default class API {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async deleteUnpublishedEntry(collectionName: string, slug: string) {
|
async deleteUnpublishedEntry(collectionName: string, slug: string) {
|
||||||
const contentKey = generateContentKey(collectionName, slug);
|
const contentKey = this.generateContentKey(collectionName, slug);
|
||||||
const branch = branchFromContentKey(contentKey);
|
const branch = this.branchFromContentKey(contentKey);
|
||||||
const pullRequest = await this.getBranchPullRequest(branch);
|
const pullRequest = await this.getBranchPullRequest(branch);
|
||||||
|
|
||||||
await this.declinePullRequest(pullRequest);
|
await this.declinePullRequest(pullRequest);
|
||||||
@ -663,8 +674,8 @@ export default class API {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async getStatuses(collectionName: string, slug: string) {
|
async getStatuses(collectionName: string, slug: string) {
|
||||||
const contentKey = generateContentKey(collectionName, slug);
|
const contentKey = this.generateContentKey(collectionName, slug);
|
||||||
const branch = branchFromContentKey(contentKey);
|
const branch = this.branchFromContentKey(contentKey);
|
||||||
const pullRequest = await this.getBranchPullRequest(branch);
|
const pullRequest = await this.getBranchPullRequest(branch);
|
||||||
const statuses = await this.getPullRequestStatuses(pullRequest);
|
const statuses = await this.getPullRequestStatuses(pullRequest);
|
||||||
|
|
||||||
|
@ -34,8 +34,6 @@ import {
|
|||||||
getLargeMediaFilteredMediaFiles,
|
getLargeMediaFilteredMediaFiles,
|
||||||
FetchError,
|
FetchError,
|
||||||
blobToFileObj,
|
blobToFileObj,
|
||||||
contentKeyFromBranch,
|
|
||||||
generateContentKey,
|
|
||||||
} from 'netlify-cms-lib-util';
|
} from 'netlify-cms-lib-util';
|
||||||
import NetlifyAuthenticator from 'netlify-cms-lib-auth';
|
import NetlifyAuthenticator from 'netlify-cms-lib-auth';
|
||||||
import AuthenticationPage from './AuthenticationPage';
|
import AuthenticationPage from './AuthenticationPage';
|
||||||
@ -447,7 +445,7 @@ export default class BitbucketBackend implements Implementation {
|
|||||||
async unpublishedEntries() {
|
async unpublishedEntries() {
|
||||||
const listEntriesKeys = () =>
|
const listEntriesKeys = () =>
|
||||||
this.api!.listUnpublishedBranches().then(branches =>
|
this.api!.listUnpublishedBranches().then(branches =>
|
||||||
branches.map(branch => contentKeyFromBranch(branch)),
|
branches.map(branch => this.api!.contentKeyFromBranch(branch)),
|
||||||
);
|
);
|
||||||
|
|
||||||
const readUnpublishedBranchFile = (contentKey: string) =>
|
const readUnpublishedBranchFile = (contentKey: string) =>
|
||||||
@ -464,7 +462,7 @@ export default class BitbucketBackend implements Implementation {
|
|||||||
this.loadEntryMediaFiles(branch, files),
|
this.loadEntryMediaFiles(branch, files),
|
||||||
} = {},
|
} = {},
|
||||||
) {
|
) {
|
||||||
const contentKey = generateContentKey(collection, slug);
|
const contentKey = this.api!.generateContentKey(collection, slug);
|
||||||
const data = await this.api!.readUnpublishedBranchFile(contentKey);
|
const data = await this.api!.readUnpublishedBranchFile(contentKey);
|
||||||
const mediaFiles = await loadEntryMediaFiles(
|
const mediaFiles = await loadEntryMediaFiles(
|
||||||
data.metaData.branch,
|
data.metaData.branch,
|
||||||
|
@ -71,20 +71,6 @@ export default class API extends GithubAPI {
|
|||||||
return Promise.resolve({ login: '', ...this.commitAuthor });
|
return Promise.resolve({ login: '', ...this.commitAuthor });
|
||||||
}
|
}
|
||||||
|
|
||||||
async getHeadReference(head: string) {
|
|
||||||
if (!this.repoOwner) {
|
|
||||||
// get the repo owner from the branch url
|
|
||||||
// this is required for returning the full head reference, e.g. owner:head
|
|
||||||
// when filtering pull requests based on the head
|
|
||||||
const branch = await this.getDefaultBranch();
|
|
||||||
const self = branch._links.self;
|
|
||||||
const regex = new RegExp('https?://.+?/repos/(.+?)/');
|
|
||||||
const owner = self.match(regex);
|
|
||||||
this.repoOwner = owner ? owner[1] : '';
|
|
||||||
}
|
|
||||||
return super.getHeadReference(head);
|
|
||||||
}
|
|
||||||
|
|
||||||
commit(message: string, changeTree: { parentSha?: string; sha: string }) {
|
commit(message: string, changeTree: { parentSha?: string; sha: string }) {
|
||||||
const commitParams: {
|
const commitParams: {
|
||||||
message: string;
|
message: string;
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -9,18 +9,17 @@ import { createHttpLink } from 'apollo-link-http';
|
|||||||
import { setContext } from 'apollo-link-context';
|
import { setContext } from 'apollo-link-context';
|
||||||
import {
|
import {
|
||||||
APIError,
|
APIError,
|
||||||
|
EditorialWorkflowError,
|
||||||
readFile,
|
readFile,
|
||||||
localForage,
|
localForage,
|
||||||
DEFAULT_PR_BODY,
|
DEFAULT_PR_BODY,
|
||||||
branchFromContentKey,
|
|
||||||
} from 'netlify-cms-lib-util';
|
} from 'netlify-cms-lib-util';
|
||||||
import { trim } from 'lodash';
|
import { trim } from 'lodash';
|
||||||
import introspectionQueryResultData from './fragmentTypes';
|
import introspectionQueryResultData from './fragmentTypes';
|
||||||
import API, { Config, BlobArgs, API_NAME, PullRequestState, MOCK_PULL_REQUEST } from './API';
|
import API, { Config, BlobArgs, PR, API_NAME } from './API';
|
||||||
import * as queries from './queries';
|
import * as queries from './queries';
|
||||||
import * as mutations from './mutations';
|
import * as mutations from './mutations';
|
||||||
import { GraphQLError } from 'graphql';
|
import { GraphQLError } from 'graphql';
|
||||||
import { Octokit } from '@octokit/rest';
|
|
||||||
|
|
||||||
const NO_CACHE = 'no-cache';
|
const NO_CACHE = 'no-cache';
|
||||||
const CACHE_FIRST = 'cache-first';
|
const CACHE_FIRST = 'cache-first';
|
||||||
@ -49,37 +48,25 @@ interface TreeFile {
|
|||||||
name: string;
|
name: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
type GraphQLPullRequest = {
|
|
||||||
id: string;
|
|
||||||
baseRefName: string;
|
|
||||||
baseRefOid: string;
|
|
||||||
body: string;
|
|
||||||
headRefName: string;
|
|
||||||
headRefOid: string;
|
|
||||||
number: number;
|
|
||||||
state: string;
|
|
||||||
title: string;
|
|
||||||
mergedAt: string | null;
|
|
||||||
labels: { nodes: { name: string }[] };
|
|
||||||
};
|
|
||||||
|
|
||||||
const transformPullRequest = (pr: GraphQLPullRequest) => {
|
|
||||||
return {
|
|
||||||
...pr,
|
|
||||||
labels: pr.labels.nodes,
|
|
||||||
head: { ref: pr.headRefName, sha: pr.headRefOid },
|
|
||||||
base: { ref: pr.baseRefName, sha: pr.baseRefOid },
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
type Error = GraphQLError & { type: string };
|
type Error = GraphQLError & { type: string };
|
||||||
|
|
||||||
export default class GraphQLAPI extends API {
|
export default class GraphQLAPI extends API {
|
||||||
|
repoOwner: string;
|
||||||
|
repoName: string;
|
||||||
|
originRepoOwner: string;
|
||||||
|
originRepoName: string;
|
||||||
client: ApolloClient<NormalizedCacheObject>;
|
client: ApolloClient<NormalizedCacheObject>;
|
||||||
|
|
||||||
constructor(config: Config) {
|
constructor(config: Config) {
|
||||||
super(config);
|
super(config);
|
||||||
|
|
||||||
|
const [repoParts, originRepoParts] = [this.repo.split('/'), this.originRepo.split('/')];
|
||||||
|
this.repoOwner = repoParts[0];
|
||||||
|
this.repoName = repoParts[1];
|
||||||
|
|
||||||
|
this.originRepoOwner = originRepoParts[0];
|
||||||
|
this.originRepoName = originRepoParts[1];
|
||||||
|
|
||||||
this.client = this.getApolloClient();
|
this.client = this.getApolloClient();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -227,62 +214,7 @@ export default class GraphQLAPI extends API {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async getPullRequests(
|
async getStatuses(sha: string) {
|
||||||
head: string | undefined,
|
|
||||||
state: PullRequestState,
|
|
||||||
predicate: (pr: Octokit.PullsListResponseItem) => boolean,
|
|
||||||
) {
|
|
||||||
const { originRepoOwner: owner, originRepoName: name } = this;
|
|
||||||
let states;
|
|
||||||
if (state === PullRequestState.Open) {
|
|
||||||
states = ['OPEN'];
|
|
||||||
} else if (state === PullRequestState.Closed) {
|
|
||||||
states = ['CLOSED', 'MERGED'];
|
|
||||||
} else {
|
|
||||||
states = ['OPEN', 'CLOSED', 'MERGED'];
|
|
||||||
}
|
|
||||||
const { data } = await this.query({
|
|
||||||
query: queries.pullRequests,
|
|
||||||
variables: {
|
|
||||||
owner,
|
|
||||||
name,
|
|
||||||
...(head ? { head } : {}),
|
|
||||||
states,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
const {
|
|
||||||
pullRequests,
|
|
||||||
}: {
|
|
||||||
pullRequests: {
|
|
||||||
nodes: GraphQLPullRequest[];
|
|
||||||
};
|
|
||||||
} = data.repository;
|
|
||||||
|
|
||||||
const mapped = pullRequests.nodes.map(transformPullRequest);
|
|
||||||
|
|
||||||
return ((mapped as unknown) as Octokit.PullsListResponseItem[]).filter(predicate);
|
|
||||||
}
|
|
||||||
|
|
||||||
async getCmsBranches() {
|
|
||||||
const { repoOwner: owner, repoName: name } = this;
|
|
||||||
const { data } = await this.query({
|
|
||||||
query: queries.cmsBranches,
|
|
||||||
variables: {
|
|
||||||
owner,
|
|
||||||
name,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
return data.repository.refs.nodes.map(({ name, prefix }: { name: string; prefix: string }) => ({
|
|
||||||
ref: `${prefix}${name}`,
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
async getStatuses(collectionName: string, slug: string) {
|
|
||||||
const contentKey = this.generateContentKey(collectionName, slug);
|
|
||||||
const branch = branchFromContentKey(contentKey);
|
|
||||||
const pullRequest = await this.getBranchPullRequest(branch);
|
|
||||||
const sha = pullRequest.head.sha;
|
|
||||||
const { originRepoOwner: owner, originRepoName: name } = this;
|
const { originRepoOwner: owner, originRepoName: name } = this;
|
||||||
const { data } = await this.query({ query: queries.statues, variables: { owner, name, sha } });
|
const { data } = await this.query({ query: queries.statues, variables: { owner, name, sha } });
|
||||||
if (data.repository.object) {
|
if (data.repository.object) {
|
||||||
@ -333,6 +265,76 @@ export default class GraphQLAPI extends API {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async listUnpublishedBranches() {
|
||||||
|
if (this.useOpenAuthoring) {
|
||||||
|
return super.listUnpublishedBranches();
|
||||||
|
}
|
||||||
|
console.log(
|
||||||
|
'%c Checking for Unpublished entries',
|
||||||
|
'line-height: 30px;text-align: center;font-weight: bold',
|
||||||
|
);
|
||||||
|
const { repoOwner: owner, repoName: name } = this;
|
||||||
|
const { data } = await this.query({
|
||||||
|
query: queries.unpublishedPrBranches,
|
||||||
|
variables: { owner, name },
|
||||||
|
});
|
||||||
|
const { nodes } = data.repository.refs as {
|
||||||
|
nodes: {
|
||||||
|
associatedPullRequests: { nodes: { headRef: { prefix: string; name: string } }[] };
|
||||||
|
}[];
|
||||||
|
};
|
||||||
|
if (nodes.length > 0) {
|
||||||
|
const branches = [] as { ref: string }[];
|
||||||
|
nodes.forEach(({ associatedPullRequests }) => {
|
||||||
|
associatedPullRequests.nodes.forEach(({ headRef }) => {
|
||||||
|
branches.push({ ref: `${headRef.prefix}${headRef.name}` });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return await Promise.all(branches.map(branch => this.migrateBranch(branch)));
|
||||||
|
} else {
|
||||||
|
console.log(
|
||||||
|
'%c No Unpublished entries',
|
||||||
|
'line-height: 30px;text-align: center;font-weight: bold',
|
||||||
|
);
|
||||||
|
throw new APIError('Not Found', 404, 'GitHub');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async readUnpublishedBranchFile(contentKey: string) {
|
||||||
|
// retrieveMetadata(contentKey) rejects in case of no metadata
|
||||||
|
const metaData = await this.retrieveMetadata(contentKey).catch(() => null);
|
||||||
|
if (metaData && metaData.objects && metaData.objects.entry && metaData.objects.entry.path) {
|
||||||
|
const { path } = metaData.objects.entry;
|
||||||
|
const { repoOwner: headOwner, repoName: headRepoName } = this;
|
||||||
|
const { originRepoOwner: baseOwner, originRepoName: baseRepoName } = this;
|
||||||
|
|
||||||
|
const { data } = await this.query({
|
||||||
|
query: queries.unpublishedBranchFile,
|
||||||
|
variables: {
|
||||||
|
headOwner,
|
||||||
|
headRepoName,
|
||||||
|
headExpression: `${metaData.branch}:${path}`,
|
||||||
|
baseOwner,
|
||||||
|
baseRepoName,
|
||||||
|
baseExpression: `${this.branch}:${path}`,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (!data.head.object) {
|
||||||
|
throw new EditorialWorkflowError('content is not under editorial workflow', true);
|
||||||
|
}
|
||||||
|
const result = {
|
||||||
|
metaData,
|
||||||
|
fileData: data.head.object.text,
|
||||||
|
isModification: !!data.base.object,
|
||||||
|
slug: this.slugFromContentKey(contentKey, metaData.collection),
|
||||||
|
};
|
||||||
|
return result;
|
||||||
|
} else {
|
||||||
|
throw new EditorialWorkflowError('content is not under editorial workflow', true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
getBranchQualifiedName(branch: string) {
|
getBranchQualifiedName(branch: string) {
|
||||||
return `refs/heads/${branch}`;
|
return `refs/heads/${branch}`;
|
||||||
}
|
}
|
||||||
@ -412,10 +414,7 @@ export default class GraphQLAPI extends API {
|
|||||||
// https://developer.github.com/v4/enum/pullrequeststate/
|
// https://developer.github.com/v4/enum/pullrequeststate/
|
||||||
// GraphQL state: [CLOSED, MERGED, OPEN]
|
// GraphQL state: [CLOSED, MERGED, OPEN]
|
||||||
// REST API state: [closed, open]
|
// REST API state: [closed, open]
|
||||||
const state =
|
const state = data.repository.pullRequest.state === 'OPEN' ? 'open' : 'closed';
|
||||||
data.repository.pullRequest.state === 'OPEN'
|
|
||||||
? PullRequestState.Open
|
|
||||||
: PullRequestState.Closed;
|
|
||||||
return {
|
return {
|
||||||
...data.repository.pullRequest,
|
...data.repository.pullRequest,
|
||||||
state,
|
state,
|
||||||
@ -425,6 +424,7 @@ export default class GraphQLAPI extends API {
|
|||||||
getPullRequestAndBranchQuery(branch: string, number: number) {
|
getPullRequestAndBranchQuery(branch: string, number: number) {
|
||||||
const { repoOwner: owner, repoName: name } = this;
|
const { repoOwner: owner, repoName: name } = this;
|
||||||
const { originRepoOwner, originRepoName } = this;
|
const { originRepoOwner, originRepoName } = this;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
query: queries.pullRequestAndBranch,
|
query: queries.pullRequestAndBranch,
|
||||||
variables: {
|
variables: {
|
||||||
@ -448,7 +448,7 @@ export default class GraphQLAPI extends API {
|
|||||||
return { branch: repository.branch, pullRequest: origin.pullRequest };
|
return { branch: repository.branch, pullRequest: origin.pullRequest };
|
||||||
}
|
}
|
||||||
|
|
||||||
async openPR(number: number) {
|
async openPR({ number }: PR) {
|
||||||
const pullRequest = await this.getPullRequest(number);
|
const pullRequest = await this.getPullRequest(number);
|
||||||
|
|
||||||
const { data } = await this.mutate({
|
const { data } = await this.mutate({
|
||||||
@ -467,10 +467,10 @@ export default class GraphQLAPI extends API {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
return data!.reopenPullRequest;
|
return data!.closePullRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
async closePR(number: number) {
|
async closePR({ number }: PR) {
|
||||||
const pullRequest = await this.getPullRequest(number);
|
const pullRequest = await this.getPullRequest(number);
|
||||||
|
|
||||||
const { data } = await this.mutate({
|
const { data } = await this.mutate({
|
||||||
@ -495,12 +495,13 @@ export default class GraphQLAPI extends API {
|
|||||||
async deleteUnpublishedEntry(collectionName: string, slug: string) {
|
async deleteUnpublishedEntry(collectionName: string, slug: string) {
|
||||||
try {
|
try {
|
||||||
const contentKey = this.generateContentKey(collectionName, slug);
|
const contentKey = this.generateContentKey(collectionName, slug);
|
||||||
const branchName = branchFromContentKey(contentKey);
|
const branchName = this.generateBranchName(contentKey);
|
||||||
|
|
||||||
const metadata = await this.retrieveMetadata(contentKey);
|
const metadata = await this.retrieveMetadata(contentKey);
|
||||||
if (metadata.pullRequest.number !== MOCK_PULL_REQUEST) {
|
if (metadata && metadata.pr) {
|
||||||
const { branch, pullRequest } = await this.getPullRequestAndBranch(
|
const { branch, pullRequest } = await this.getPullRequestAndBranch(
|
||||||
branchName,
|
branchName,
|
||||||
metadata.pullRequest.number,
|
metadata.pr.number,
|
||||||
);
|
);
|
||||||
|
|
||||||
const { data } = await this.mutate({
|
const { data } = await this.mutate({
|
||||||
@ -630,7 +631,7 @@ export default class GraphQLAPI extends API {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
const { pullRequest } = data!.createPullRequest;
|
const { pullRequest } = data!.createPullRequest;
|
||||||
return (transformPullRequest(pullRequest) as unknown) as Octokit.PullsCreateResponse;
|
return { ...pullRequest, head: { sha: pullRequest.headRefOid } };
|
||||||
}
|
}
|
||||||
|
|
||||||
async getFileSha(path: string, { repoURL = this.repoURL, branch = this.branch } = {}) {
|
async getFileSha(path: string, { repoURL = this.repoURL, branch = this.branch } = {}) {
|
||||||
|
@ -21,35 +21,28 @@ describe('github API', () => {
|
|||||||
describe('editorialWorkflowGit', () => {
|
describe('editorialWorkflowGit', () => {
|
||||||
it('should create PR with correct base branch name when publishing with editorial workflow', () => {
|
it('should create PR with correct base branch name when publishing with editorial workflow', () => {
|
||||||
let prBaseBranch = null;
|
let prBaseBranch = null;
|
||||||
let labels = null;
|
const api = new API({ branch: 'gh-pages', repo: 'my-repo' });
|
||||||
const api = new API({
|
|
||||||
branch: 'gh-pages',
|
|
||||||
repo: 'owner/my-repo',
|
|
||||||
initialWorkflowStatus: 'draft',
|
|
||||||
});
|
|
||||||
const responses = {
|
const responses = {
|
||||||
'/repos/owner/my-repo/branches/gh-pages': () => ({ commit: { sha: 'def' } }),
|
'/repos/my-repo/branches/gh-pages': () => ({ commit: { sha: 'def' } }),
|
||||||
'/repos/owner/my-repo/git/trees/def': () => ({ tree: [] }),
|
'/repos/my-repo/git/trees/def': () => ({ tree: [] }),
|
||||||
'/repos/owner/my-repo/git/trees': () => ({}),
|
'/repos/my-repo/git/trees': () => ({}),
|
||||||
'/repos/owner/my-repo/git/commits': () => ({}),
|
'/repos/my-repo/git/commits': () => ({}),
|
||||||
'/repos/owner/my-repo/git/refs': () => ({}),
|
'/repos/my-repo/git/refs': () => ({}),
|
||||||
'/repos/owner/my-repo/pulls': req => {
|
'/repos/my-repo/pulls': pullRequest => {
|
||||||
prBaseBranch = JSON.parse(req.body).base;
|
prBaseBranch = JSON.parse(pullRequest.body).base;
|
||||||
return { head: { sha: 'cbd' }, labels: [], number: 1 };
|
return { head: { sha: 'cbd' } };
|
||||||
},
|
|
||||||
'/repos/owner/my-repo/issues/1/labels': req => {
|
|
||||||
labels = JSON.parse(req.body).labels;
|
|
||||||
return {};
|
|
||||||
},
|
},
|
||||||
|
'/user': () => ({}),
|
||||||
|
'/repos/my-repo/git/blobs': () => ({}),
|
||||||
|
'/repos/my-repo/git/refs/meta/_netlify_cms': () => ({ object: {} }),
|
||||||
};
|
};
|
||||||
mockAPI(api, responses);
|
mockAPI(api, responses);
|
||||||
|
|
||||||
return expect(
|
return expect(
|
||||||
api.editorialWorkflowGit([], { slug: 'entry', sha: 'abc' }, null, {}).then(() => ({
|
api
|
||||||
prBaseBranch,
|
.editorialWorkflowGit([], { slug: 'entry', sha: 'abc' }, null, {})
|
||||||
labels,
|
.then(() => prBaseBranch),
|
||||||
})),
|
).resolves.toEqual('gh-pages');
|
||||||
).resolves.toEqual({ prBaseBranch: 'gh-pages', labels: ['netlify-cms/draft'] });
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -298,64 +291,39 @@ describe('github API', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('migratePullRequest', () => {
|
describe('migrateBranch', () => {
|
||||||
it('should migrate to pull request labels when no version', async () => {
|
it('should migrate to version 1 when no version', async () => {
|
||||||
const api = new API({ branch: 'master', repo: 'owner/repo' });
|
const api = new API({ branch: 'master', repo: 'owner/repo' });
|
||||||
|
|
||||||
const pr = {
|
const newBranch = { ref: 'refs/heads/cms/posts/2019-11-11-post-title' };
|
||||||
head: { ref: 'cms/2019-11-11-post-title' },
|
api.migrateToVersion1 = jest.fn().mockResolvedValue(newBranch);
|
||||||
title: 'pr title',
|
|
||||||
number: 1,
|
|
||||||
labels: [],
|
|
||||||
};
|
|
||||||
const metadata = { type: 'PR' };
|
const metadata = { type: 'PR' };
|
||||||
api.retrieveMetadataOld = jest.fn().mockResolvedValue(metadata);
|
api.retrieveMetadata = jest.fn().mockResolvedValue(metadata);
|
||||||
const newBranch = 'cms/posts/2019-11-11-post-title';
|
|
||||||
const migrateToVersion1Result = {
|
|
||||||
metadata: { ...metadata, branch: newBranch, version: '1' },
|
|
||||||
pullRequest: { ...pr, number: 2 },
|
|
||||||
};
|
|
||||||
api.migrateToVersion1 = jest.fn().mockResolvedValue(migrateToVersion1Result);
|
|
||||||
api.migrateToPullRequestLabels = jest.fn();
|
|
||||||
|
|
||||||
await api.migratePullRequest(pr);
|
const branch = { ref: 'refs/heads/cms/2019-11-11-post-title' };
|
||||||
|
await expect(api.migrateBranch(branch)).resolves.toBe(newBranch);
|
||||||
|
|
||||||
expect(api.migrateToVersion1).toHaveBeenCalledTimes(1);
|
expect(api.migrateToVersion1).toHaveBeenCalledTimes(1);
|
||||||
expect(api.migrateToVersion1).toHaveBeenCalledWith(pr, metadata);
|
expect(api.migrateToVersion1).toHaveBeenCalledWith(branch, metadata);
|
||||||
|
|
||||||
expect(api.migrateToPullRequestLabels).toHaveBeenCalledTimes(1);
|
expect(api.retrieveMetadata).toHaveBeenCalledTimes(1);
|
||||||
expect(api.migrateToPullRequestLabels).toHaveBeenCalledWith(
|
expect(api.retrieveMetadata).toHaveBeenCalledWith('2019-11-11-post-title');
|
||||||
migrateToVersion1Result.pullRequest,
|
|
||||||
migrateToVersion1Result.metadata,
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(api.retrieveMetadataOld).toHaveBeenCalledTimes(1);
|
|
||||||
expect(api.retrieveMetadataOld).toHaveBeenCalledWith('2019-11-11-post-title');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should migrate to pull request labels when version is 1', async () => {
|
it('should not migrate to version 1 when version is 1', async () => {
|
||||||
const api = new API({ branch: 'master', repo: 'owner/repo' });
|
const api = new API({ branch: 'master', repo: 'owner/repo' });
|
||||||
|
|
||||||
api.migrateToVersion1 = jest.fn();
|
api.migrateToVersion1 = jest.fn();
|
||||||
const pr = {
|
|
||||||
head: { ref: 'cms/posts/2019-11-11-post-title' },
|
|
||||||
title: 'pr title',
|
|
||||||
number: 1,
|
|
||||||
labels: [],
|
|
||||||
};
|
|
||||||
const metadata = { type: 'PR', version: '1' };
|
const metadata = { type: 'PR', version: '1' };
|
||||||
api.retrieveMetadataOld = jest.fn().mockResolvedValue(metadata);
|
api.retrieveMetadata = jest.fn().mockResolvedValue(metadata);
|
||||||
api.migrateToPullRequestLabels = jest.fn().mockResolvedValue(pr, metadata);
|
|
||||||
|
|
||||||
await api.migratePullRequest(pr);
|
const branch = { ref: 'refs/heads/cms/posts/2019-11-11-post-title' };
|
||||||
|
await expect(api.migrateBranch(branch)).resolves.toBe(branch);
|
||||||
|
|
||||||
expect(api.migrateToVersion1).toHaveBeenCalledTimes(0);
|
expect(api.migrateToVersion1).toHaveBeenCalledTimes(0);
|
||||||
|
|
||||||
expect(api.migrateToPullRequestLabels).toHaveBeenCalledTimes(1);
|
expect(api.retrieveMetadata).toHaveBeenCalledTimes(1);
|
||||||
expect(api.migrateToPullRequestLabels).toHaveBeenCalledWith(pr, metadata);
|
expect(api.retrieveMetadata).toHaveBeenCalledWith('posts/2019-11-11-post-title');
|
||||||
|
|
||||||
expect(api.retrieveMetadataOld).toHaveBeenCalledTimes(1);
|
|
||||||
expect(api.retrieveMetadataOld).toHaveBeenCalledWith('posts/2019-11-11-post-title');
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -363,17 +331,10 @@ describe('github API', () => {
|
|||||||
it('should migrate to version 1', async () => {
|
it('should migrate to version 1', async () => {
|
||||||
const api = new API({ branch: 'master', repo: 'owner/repo' });
|
const api = new API({ branch: 'master', repo: 'owner/repo' });
|
||||||
|
|
||||||
const pr = {
|
|
||||||
head: { ref: 'cms/2019-11-11-post-title', sha: 'pr_head' },
|
|
||||||
title: 'pr title',
|
|
||||||
number: 1,
|
|
||||||
labels: [],
|
|
||||||
};
|
|
||||||
|
|
||||||
const newBranch = { ref: 'refs/heads/cms/posts/2019-11-11-post-title' };
|
const newBranch = { ref: 'refs/heads/cms/posts/2019-11-11-post-title' };
|
||||||
api.createBranch = jest.fn().mockResolvedValue(newBranch);
|
api.createBranch = jest.fn().mockResolvedValue(newBranch);
|
||||||
|
|
||||||
const newPr = { ...pr, number: 2 };
|
const newPr = { number: 2, head: { sha: 'new_head' } };
|
||||||
api.createPR = jest.fn().mockResolvedValue(newPr);
|
api.createPR = jest.fn().mockResolvedValue(newPr);
|
||||||
|
|
||||||
api.storeMetadata = jest.fn();
|
api.storeMetadata = jest.fn();
|
||||||
@ -381,42 +342,35 @@ describe('github API', () => {
|
|||||||
api.deleteBranch = jest.fn();
|
api.deleteBranch = jest.fn();
|
||||||
api.deleteMetadata = jest.fn();
|
api.deleteMetadata = jest.fn();
|
||||||
|
|
||||||
const branch = 'cms/2019-11-11-post-title';
|
const branch = { ref: 'refs/heads/cms/2019-11-11-post-title' };
|
||||||
const metadata = {
|
const metadata = {
|
||||||
branch,
|
branch: 'cms/2019-11-11-post-title',
|
||||||
type: 'PR',
|
type: 'PR',
|
||||||
pr: { head: pr.head.sha },
|
pr: { head: 'old_head' },
|
||||||
commitMessage: 'commitMessage',
|
commitMessage: 'commitMessage',
|
||||||
collection: 'posts',
|
collection: 'posts',
|
||||||
};
|
};
|
||||||
|
|
||||||
const expectedMetadata = {
|
await expect(api.migrateToVersion1(branch, metadata)).resolves.toBe(newBranch);
|
||||||
|
|
||||||
|
expect(api.createBranch).toHaveBeenCalledTimes(1);
|
||||||
|
expect(api.createBranch).toHaveBeenCalledWith('cms/posts/2019-11-11-post-title', 'old_head');
|
||||||
|
|
||||||
|
expect(api.createPR).toHaveBeenCalledTimes(1);
|
||||||
|
expect(api.createPR).toHaveBeenCalledWith('commitMessage', 'cms/posts/2019-11-11-post-title');
|
||||||
|
|
||||||
|
expect(api.storeMetadata).toHaveBeenCalledTimes(1);
|
||||||
|
expect(api.storeMetadata).toHaveBeenCalledWith('posts/2019-11-11-post-title', {
|
||||||
type: 'PR',
|
type: 'PR',
|
||||||
pr: { head: newPr.head.sha, number: 2 },
|
pr: { head: 'new_head', number: 2 },
|
||||||
commitMessage: 'commitMessage',
|
commitMessage: 'commitMessage',
|
||||||
collection: 'posts',
|
collection: 'posts',
|
||||||
branch: 'cms/posts/2019-11-11-post-title',
|
branch: 'cms/posts/2019-11-11-post-title',
|
||||||
version: '1',
|
version: '1',
|
||||||
};
|
|
||||||
await expect(api.migrateToVersion1(pr, metadata)).resolves.toEqual({
|
|
||||||
metadata: expectedMetadata,
|
|
||||||
pullRequest: newPr,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(api.createBranch).toHaveBeenCalledTimes(1);
|
|
||||||
expect(api.createBranch).toHaveBeenCalledWith('cms/posts/2019-11-11-post-title', 'pr_head');
|
|
||||||
|
|
||||||
expect(api.createPR).toHaveBeenCalledTimes(1);
|
|
||||||
expect(api.createPR).toHaveBeenCalledWith('pr title', 'cms/posts/2019-11-11-post-title');
|
|
||||||
|
|
||||||
expect(api.storeMetadata).toHaveBeenCalledTimes(1);
|
|
||||||
expect(api.storeMetadata).toHaveBeenCalledWith(
|
|
||||||
'posts/2019-11-11-post-title',
|
|
||||||
expectedMetadata,
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(api.closePR).toHaveBeenCalledTimes(1);
|
expect(api.closePR).toHaveBeenCalledTimes(1);
|
||||||
expect(api.closePR).toHaveBeenCalledWith(metadata.pr.number);
|
expect(api.closePR).toHaveBeenCalledWith(metadata.pr);
|
||||||
|
|
||||||
expect(api.deleteBranch).toHaveBeenCalledTimes(1);
|
expect(api.deleteBranch).toHaveBeenCalledTimes(1);
|
||||||
expect(api.deleteBranch).toHaveBeenCalledWith('cms/2019-11-11-post-title');
|
expect(api.deleteBranch).toHaveBeenCalledWith('cms/2019-11-11-post-title');
|
||||||
@ -426,55 +380,20 @@ describe('github API', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('migrateToPullRequestLabels', () => {
|
|
||||||
it('should migrate to pull request labels', async () => {
|
|
||||||
const api = new API({ branch: 'master', repo: 'owner/repo' });
|
|
||||||
|
|
||||||
const pr = {
|
|
||||||
head: { ref: 'cms/posts/2019-11-11-post-title', sha: 'pr_head' },
|
|
||||||
title: 'pr title',
|
|
||||||
number: 1,
|
|
||||||
labels: [],
|
|
||||||
};
|
|
||||||
|
|
||||||
api.setPullRequestStatus = jest.fn();
|
|
||||||
api.deleteMetadata = jest.fn();
|
|
||||||
|
|
||||||
const metadata = {
|
|
||||||
branch: pr.head.ref,
|
|
||||||
type: 'PR',
|
|
||||||
pr: { head: pr.head.sha },
|
|
||||||
commitMessage: 'commitMessage',
|
|
||||||
collection: 'posts',
|
|
||||||
status: 'pending_review',
|
|
||||||
};
|
|
||||||
|
|
||||||
await api.migrateToPullRequestLabels(pr, metadata);
|
|
||||||
|
|
||||||
expect(api.setPullRequestStatus).toHaveBeenCalledTimes(1);
|
|
||||||
expect(api.setPullRequestStatus).toHaveBeenCalledWith(pr, 'pending_review');
|
|
||||||
|
|
||||||
expect(api.deleteMetadata).toHaveBeenCalledTimes(1);
|
|
||||||
expect(api.deleteMetadata).toHaveBeenCalledWith('posts/2019-11-11-post-title');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('rebaseSingleCommit', () => {
|
describe('rebaseSingleCommit', () => {
|
||||||
it('should create updated tree and commit', async () => {
|
it('should create updated tree and commit', async () => {
|
||||||
const api = new API({ branch: 'master', repo: 'owner/repo' });
|
const api = new API({ branch: 'master', repo: 'owner/repo' });
|
||||||
|
|
||||||
api.getDifferences = jest.fn().mockResolvedValueOnce({
|
api.getCommitsDiff = jest.fn().mockResolvedValueOnce([
|
||||||
files: [
|
{ filename: 'removed.md', status: 'removed', sha: 'removed_sha' },
|
||||||
{ filename: 'removed.md', status: 'removed', sha: 'removed_sha' },
|
{
|
||||||
{
|
filename: 'renamed.md',
|
||||||
filename: 'renamed.md',
|
status: 'renamed',
|
||||||
status: 'renamed',
|
previous_filename: 'previous_filename.md',
|
||||||
previous_filename: 'previous_filename.md',
|
sha: 'renamed_sha',
|
||||||
sha: 'renamed_sha',
|
},
|
||||||
},
|
{ filename: 'added.md', status: 'added', sha: 'added_sha' },
|
||||||
{ filename: 'added.md', status: 'added', sha: 'added_sha' },
|
]);
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
const newTree = { sha: 'new_tree_sha' };
|
const newTree = { sha: 'new_tree_sha' };
|
||||||
api.updateTree = jest.fn().mockResolvedValueOnce(newTree);
|
api.updateTree = jest.fn().mockResolvedValueOnce(newTree);
|
||||||
@ -495,8 +414,8 @@ describe('github API', () => {
|
|||||||
|
|
||||||
await expect(api.rebaseSingleCommit(baseCommit, commit)).resolves.toBe(newCommit);
|
await expect(api.rebaseSingleCommit(baseCommit, commit)).resolves.toBe(newCommit);
|
||||||
|
|
||||||
expect(api.getDifferences).toHaveBeenCalledTimes(1);
|
expect(api.getCommitsDiff).toHaveBeenCalledTimes(1);
|
||||||
expect(api.getDifferences).toHaveBeenCalledWith('parent_sha', 'sha', '/repos/owner/repo');
|
expect(api.getCommitsDiff).toHaveBeenCalledWith('parent_sha', 'sha');
|
||||||
|
|
||||||
expect(api.updateTree).toHaveBeenCalledTimes(1);
|
expect(api.updateTree).toHaveBeenCalledTimes(1);
|
||||||
expect(api.updateTree).toHaveBeenCalledWith('base_commit_sha', [
|
expect(api.updateTree).toHaveBeenCalledWith('base_commit_sha', [
|
||||||
@ -609,18 +528,13 @@ describe('github API', () => {
|
|||||||
];
|
];
|
||||||
|
|
||||||
api.request = jest.fn(() => Promise.resolve({ statuses }));
|
api.request = jest.fn(() => Promise.resolve({ statuses }));
|
||||||
const sha = 'sha';
|
|
||||||
api.getBranchPullRequest = jest.fn(() => Promise.resolve({ head: { sha } }));
|
|
||||||
|
|
||||||
const collection = 'collection';
|
const sha = 'sha';
|
||||||
const slug = 'slug';
|
await expect(api.getStatuses(sha)).resolves.toEqual([
|
||||||
await expect(api.getStatuses(collection, slug)).resolves.toEqual([
|
|
||||||
{ context: 'deploy', state: 'success', target_url: 'deploy-url' },
|
{ context: 'deploy', state: 'success', target_url: 'deploy-url' },
|
||||||
{ context: 'build', state: 'other' },
|
{ context: 'build', state: 'other' },
|
||||||
]);
|
]);
|
||||||
|
|
||||||
expect(api.getBranchPullRequest).toHaveBeenCalledTimes(1);
|
|
||||||
expect(api.getBranchPullRequest).toHaveBeenCalledWith('cms/collection/slug');
|
|
||||||
expect(api.request).toHaveBeenCalledTimes(1);
|
expect(api.request).toHaveBeenCalledTimes(1);
|
||||||
expect(api.request).toHaveBeenCalledWith(`/repos/repo/commits/${sha}/status`);
|
expect(api.request).toHaveBeenCalledWith(`/repos/repo/commits/${sha}/status`);
|
||||||
});
|
});
|
||||||
|
@ -9,7 +9,7 @@ describe('github GraphQL API', () => {
|
|||||||
|
|
||||||
describe('editorialWorkflowGit', () => {
|
describe('editorialWorkflowGit', () => {
|
||||||
it('should should flatten nested tree into a list of files', () => {
|
it('should should flatten nested tree into a list of files', () => {
|
||||||
const api = new GraphQLAPI({ branch: 'gh-pages', repo: 'owner/my-repo' });
|
const api = new GraphQLAPI({ branch: 'gh-pages', repo: 'my-repo' });
|
||||||
const entries = [
|
const entries = [
|
||||||
{
|
{
|
||||||
name: 'post-1.md',
|
name: 'post-1.md',
|
||||||
|
@ -185,9 +185,7 @@ describe('github backend implementation', () => {
|
|||||||
isModification: true,
|
isModification: true,
|
||||||
metaData: {
|
metaData: {
|
||||||
branch: 'branch',
|
branch: 'branch',
|
||||||
objects: {
|
objects: { entry: { path: 'entry-path' }, files: [{ path: 'image.png', sha: 'sha' }] },
|
||||||
entry: { path: 'entry-path', mediaFiles: [{ path: 'image.png', id: 'sha' }] },
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
readUnpublishedBranchFile.mockResolvedValue(data);
|
readUnpublishedBranchFile.mockResolvedValue(data);
|
||||||
|
@ -41,7 +41,6 @@ export const pullRequest = gql`
|
|||||||
fragment PullRequestParts on PullRequest {
|
fragment PullRequestParts on PullRequest {
|
||||||
id
|
id
|
||||||
baseRefName
|
baseRefName
|
||||||
baseRefOid
|
|
||||||
body
|
body
|
||||||
headRefName
|
headRefName
|
||||||
headRefOid
|
headRefOid
|
||||||
@ -52,11 +51,6 @@ export const pullRequest = gql`
|
|||||||
repository {
|
repository {
|
||||||
...RepositoryParts
|
...RepositoryParts
|
||||||
}
|
}
|
||||||
labels(last: 100) {
|
|
||||||
nodes {
|
|
||||||
name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
${repository}
|
${repository}
|
||||||
`;
|
`;
|
||||||
|
@ -25,7 +25,6 @@ import {
|
|||||||
UnpublishedEntryMediaFile,
|
UnpublishedEntryMediaFile,
|
||||||
runWithLock,
|
runWithLock,
|
||||||
blobToFileObj,
|
blobToFileObj,
|
||||||
contentKeyFromBranch,
|
|
||||||
} from 'netlify-cms-lib-util';
|
} from 'netlify-cms-lib-util';
|
||||||
import AuthenticationPage from './AuthenticationPage';
|
import AuthenticationPage from './AuthenticationPage';
|
||||||
import { Octokit } from '@octokit/rest';
|
import { Octokit } from '@octokit/rest';
|
||||||
@ -300,7 +299,7 @@ export default class GitHub implements Implementation {
|
|||||||
const repoURL = this.useOpenAuthoring ? this.api!.originRepoURL : this.api!.repoURL;
|
const repoURL = this.useOpenAuthoring ? this.api!.originRepoURL : this.api!.repoURL;
|
||||||
|
|
||||||
const readFile = (path: string, id: string | null | undefined) =>
|
const readFile = (path: string, id: string | null | undefined) =>
|
||||||
this.api!.readFile(path, id, { repoURL }).catch(() => '') as Promise<string>;
|
this.api!.readFile(path, id, { repoURL }) as Promise<string>;
|
||||||
|
|
||||||
return entriesByFiles(files, readFile, 'GitHub');
|
return entriesByFiles(files, readFile, 'GitHub');
|
||||||
}
|
}
|
||||||
@ -308,12 +307,10 @@ export default class GitHub implements Implementation {
|
|||||||
// Fetches a single entry.
|
// Fetches a single entry.
|
||||||
getEntry(path: string) {
|
getEntry(path: string) {
|
||||||
const repoURL = this.api!.originRepoURL;
|
const repoURL = this.api!.originRepoURL;
|
||||||
return this.api!.readFile(path, null, { repoURL })
|
return this.api!.readFile(path, null, { repoURL }).then(data => ({
|
||||||
.then(data => ({
|
file: { path, id: null },
|
||||||
file: { path, id: null },
|
data: data as string,
|
||||||
data: data as string,
|
}));
|
||||||
}))
|
|
||||||
.catch(() => ({ file: { path, id: null }, data: '' }));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getMedia(mediaFolder = this.mediaFolder) {
|
getMedia(mediaFolder = this.mediaFolder) {
|
||||||
@ -415,7 +412,7 @@ export default class GitHub implements Implementation {
|
|||||||
unpublishedEntries() {
|
unpublishedEntries() {
|
||||||
const listEntriesKeys = () =>
|
const listEntriesKeys = () =>
|
||||||
this.api!.listUnpublishedBranches().then(branches =>
|
this.api!.listUnpublishedBranches().then(branches =>
|
||||||
branches.map(branch => contentKeyFromBranch(branch)),
|
branches.map(({ ref }) => this.api!.contentKeyFromRef(ref)),
|
||||||
);
|
);
|
||||||
|
|
||||||
const readUnpublishedBranchFile = (contentKey: string) =>
|
const readUnpublishedBranchFile = (contentKey: string) =>
|
||||||
@ -434,10 +431,10 @@ export default class GitHub implements Implementation {
|
|||||||
) {
|
) {
|
||||||
const contentKey = this.api!.generateContentKey(collection, slug);
|
const contentKey = this.api!.generateContentKey(collection, slug);
|
||||||
const data = await this.api!.readUnpublishedBranchFile(contentKey);
|
const data = await this.api!.readUnpublishedBranchFile(contentKey);
|
||||||
const files = data.metaData.objects.entry.mediaFiles || [];
|
const files = data.metaData.objects.files || [];
|
||||||
const mediaFiles = await loadEntryMediaFiles(
|
const mediaFiles = await loadEntryMediaFiles(
|
||||||
data.metaData.branch,
|
data.metaData.branch,
|
||||||
files.map(({ id, path }) => ({ id, path })),
|
files.map(({ sha: id, path }) => ({ id, path })),
|
||||||
);
|
);
|
||||||
return {
|
return {
|
||||||
slug,
|
slug,
|
||||||
@ -449,18 +446,28 @@ export default class GitHub implements Implementation {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async getDeployPreview(collection: string, slug: string) {
|
/**
|
||||||
try {
|
* Uses GitHub's Statuses API to retrieve statuses, infers which is for a
|
||||||
const statuses = await this.api!.getStatuses(collection, slug);
|
* deploy preview via `getPreviewStatus`. Returns the url provided by the
|
||||||
const deployStatus = getPreviewStatus(statuses, this.previewContext);
|
* status, as well as the status state, which should be one of 'success',
|
||||||
|
* 'pending', and 'failure'.
|
||||||
|
*/
|
||||||
|
async getDeployPreview(collectionName: string, slug: string) {
|
||||||
|
const contentKey = this.api!.generateContentKey(collectionName, slug);
|
||||||
|
const data = await this.api!.retrieveMetadata(contentKey);
|
||||||
|
|
||||||
if (deployStatus) {
|
if (!data || !data.pr) {
|
||||||
const { target_url: url, state } = deployStatus;
|
return null;
|
||||||
return { url, status: state };
|
}
|
||||||
} else {
|
|
||||||
return null;
|
const headSHA = typeof data.pr.head === 'string' ? data.pr.head : data.pr.head.sha;
|
||||||
}
|
const statuses = await this.api!.getStatuses(headSHA);
|
||||||
} catch (e) {
|
const deployStatus = getPreviewStatus(statuses, this.previewContext);
|
||||||
|
|
||||||
|
if (deployStatus) {
|
||||||
|
const { target_url: url, state } = deployStatus;
|
||||||
|
return { url, status: state };
|
||||||
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,37 @@ export const blob = gql`
|
|||||||
${fragments.blobWithText}
|
${fragments.blobWithText}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
export const unpublishedBranchFile = gql`
|
||||||
|
query unpublishedBranchFile(
|
||||||
|
$headOwner: String!
|
||||||
|
$headRepoName: String!
|
||||||
|
$headExpression: String!
|
||||||
|
$baseOwner: String!
|
||||||
|
$baseRepoName: String!
|
||||||
|
$baseExpression: String!
|
||||||
|
) {
|
||||||
|
head: repository(owner: $headOwner, name: $headRepoName) {
|
||||||
|
...RepositoryParts
|
||||||
|
object(expression: $headExpression) {
|
||||||
|
... on Blob {
|
||||||
|
...BlobWithTextParts
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
base: repository(owner: $baseOwner, name: $baseRepoName) {
|
||||||
|
...RepositoryParts
|
||||||
|
object(expression: $baseExpression) {
|
||||||
|
... on Blob {
|
||||||
|
id
|
||||||
|
oid
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
${fragments.repository}
|
||||||
|
${fragments.blobWithText}
|
||||||
|
`;
|
||||||
|
|
||||||
export const statues = gql`
|
export const statues = gql`
|
||||||
query statues($owner: String!, $name: String!, $sha: GitObjectID!) {
|
query statues($owner: String!, $name: String!, $sha: GitObjectID!) {
|
||||||
repository(owner: $owner, name: $name) {
|
repository(owner: $owner, name: $name) {
|
||||||
@ -109,6 +140,30 @@ export const files = (depth: number) => gql`
|
|||||||
${fragments.fileEntry}
|
${fragments.fileEntry}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
export const unpublishedPrBranches = gql`
|
||||||
|
query unpublishedPrBranches($owner: String!, $name: String!) {
|
||||||
|
repository(owner: $owner, name: $name) {
|
||||||
|
...RepositoryParts
|
||||||
|
refs(refPrefix: "refs/heads/cms/", last: 50) {
|
||||||
|
nodes {
|
||||||
|
id
|
||||||
|
associatedPullRequests(last: 50, states: OPEN) {
|
||||||
|
nodes {
|
||||||
|
id
|
||||||
|
headRef {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
prefix
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
${fragments.repository}
|
||||||
|
`;
|
||||||
|
|
||||||
const branchQueryPart = `
|
const branchQueryPart = `
|
||||||
branch: ref(qualifiedName: $qualifiedName) {
|
branch: ref(qualifiedName: $qualifiedName) {
|
||||||
...BranchParts
|
...BranchParts
|
||||||
@ -126,21 +181,6 @@ export const branch = gql`
|
|||||||
${fragments.branch}
|
${fragments.branch}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const cmsBranches = gql`
|
|
||||||
query cmsBranches($owner: String!, $name: String!) {
|
|
||||||
repository(owner: $owner, name: $name) {
|
|
||||||
...RepositoryParts
|
|
||||||
refs(refPrefix: "refs/heads/cms/", last: 100) {
|
|
||||||
nodes {
|
|
||||||
...BranchParts
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
${fragments.repository}
|
|
||||||
${fragments.branch}
|
|
||||||
`;
|
|
||||||
|
|
||||||
export const repository = gql`
|
export const repository = gql`
|
||||||
query repository($owner: String!, $name: String!) {
|
query repository($owner: String!, $name: String!) {
|
||||||
repository(owner: $owner, name: $name) {
|
repository(owner: $owner, name: $name) {
|
||||||
@ -166,27 +206,13 @@ export const pullRequest = gql`
|
|||||||
${fragments.pullRequest}
|
${fragments.pullRequest}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const pullRequests = gql`
|
|
||||||
query pullRequests($owner: String!, $name: String!, $head: String, $states: [PullRequestState!]) {
|
|
||||||
repository(owner: $owner, name: $name) {
|
|
||||||
id
|
|
||||||
pullRequests(last: 100, headRefName: $head, states: $states) {
|
|
||||||
nodes {
|
|
||||||
...PullRequestParts
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
${fragments.pullRequest}
|
|
||||||
`;
|
|
||||||
|
|
||||||
export const pullRequestAndBranch = gql`
|
export const pullRequestAndBranch = gql`
|
||||||
query pullRequestAndBranch($owner: String!, $name: String!, $originRepoOwner: String!, $originRepoName: String!, $qualifiedName: String!, $number: Int!) {
|
query pullRequestAndBranch($owner: String!, $name: String!, $origin_owner: String!, $origin_name: String!, $qualifiedName: String!, $number: Int!) {
|
||||||
repository(owner: $owner, name: $name) {
|
repository(owner: $owner, name: $name) {
|
||||||
...RepositoryParts
|
...RepositoryParts
|
||||||
${branchQueryPart}
|
${branchQueryPart}
|
||||||
}
|
}
|
||||||
origin: repository(owner: $originRepoOwner, name: $originRepoName) {
|
origin: repository(owner: $origin_owner, name: $origin_name) {
|
||||||
...RepositoryParts
|
...RepositoryParts
|
||||||
${pullRequestQueryPart}
|
${pullRequestQueryPart}
|
||||||
}
|
}
|
||||||
@ -196,6 +222,47 @@ export const pullRequestAndBranch = gql`
|
|||||||
${fragments.pullRequest}
|
${fragments.pullRequest}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
export const commitTree = gql`
|
||||||
|
query commitTree($owner: String!, $name: String!, $sha: GitObjectID!) {
|
||||||
|
repository(owner: $owner, name: $name) {
|
||||||
|
...RepositoryParts
|
||||||
|
commit: object(oid: $sha) {
|
||||||
|
...ObjectParts
|
||||||
|
... on Commit {
|
||||||
|
tree {
|
||||||
|
...ObjectParts
|
||||||
|
entries {
|
||||||
|
...TreeEntryParts
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
${fragments.repository}
|
||||||
|
${fragments.object}
|
||||||
|
${fragments.treeEntry}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const tree = gql`
|
||||||
|
query tree($owner: String!, $name: String!, $sha: GitObjectID!) {
|
||||||
|
repository(owner: $owner, name: $name) {
|
||||||
|
...RepositoryParts
|
||||||
|
tree: object(oid: $sha) {
|
||||||
|
...ObjectParts
|
||||||
|
... on Tree {
|
||||||
|
entries {
|
||||||
|
...TreeEntryParts
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
${fragments.repository}
|
||||||
|
${fragments.object}
|
||||||
|
${fragments.treeEntry}
|
||||||
|
`;
|
||||||
|
|
||||||
export const fileSha = gql`
|
export const fileSha = gql`
|
||||||
query fileSha($owner: String!, $name: String!, $expression: String!) {
|
query fileSha($owner: String!, $name: String!, $expression: String!) {
|
||||||
repository(owner: $owner, name: $name) {
|
repository(owner: $owner, name: $name) {
|
||||||
|
@ -21,7 +21,6 @@ import {
|
|||||||
responseParser,
|
responseParser,
|
||||||
PreviewState,
|
PreviewState,
|
||||||
parseContentKey,
|
parseContentKey,
|
||||||
branchFromContentKey,
|
|
||||||
} from 'netlify-cms-lib-util';
|
} from 'netlify-cms-lib-util';
|
||||||
import { Base64 } from 'js-base64';
|
import { Base64 } from 'js-base64';
|
||||||
import { Map, Set } from 'immutable';
|
import { Map, Set } from 'immutable';
|
||||||
@ -458,6 +457,18 @@ export default class API {
|
|||||||
])(`${this.repoURL}/repository/files/${encodeURIComponent(path)}`);
|
])(`${this.repoURL}/repository/files/${encodeURIComponent(path)}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
generateContentKey(collectionName: string, slug: string) {
|
||||||
|
return generateContentKey(collectionName, slug);
|
||||||
|
}
|
||||||
|
|
||||||
|
contentKeyFromBranch(branch: string) {
|
||||||
|
return branch.substring(`${CMS_BRANCH_PREFIX}/`.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
branchFromContentKey(contentKey: string) {
|
||||||
|
return `${CMS_BRANCH_PREFIX}/${contentKey}`;
|
||||||
|
}
|
||||||
|
|
||||||
async getMergeRequests(sourceBranch?: string) {
|
async getMergeRequests(sourceBranch?: string) {
|
||||||
const mergeRequests: GitLabMergeRequest[] = await this.requestJSON({
|
const mergeRequests: GitLabMergeRequest[] = await this.requestJSON({
|
||||||
url: `${this.repoURL}/merge_requests`,
|
url: `${this.repoURL}/merge_requests`,
|
||||||
@ -544,7 +555,7 @@ export default class API {
|
|||||||
|
|
||||||
async retrieveMetadata(contentKey: string) {
|
async retrieveMetadata(contentKey: string) {
|
||||||
const { collection, slug } = parseContentKey(contentKey);
|
const { collection, slug } = parseContentKey(contentKey);
|
||||||
const branch = branchFromContentKey(contentKey);
|
const branch = this.branchFromContentKey(contentKey);
|
||||||
const mergeRequest = await this.getBranchMergeRequest(branch);
|
const mergeRequest = await this.getBranchMergeRequest(branch);
|
||||||
const diff = await this.getDifferences(mergeRequest.sha);
|
const diff = await this.getDifferences(mergeRequest.sha);
|
||||||
const { old_path: path, new_file: newFile } = diff.find(d => !d.binary) as {
|
const { old_path: path, new_file: newFile } = diff.find(d => !d.binary) as {
|
||||||
@ -635,8 +646,8 @@ export default class API {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async editorialWorkflowGit(files: (Entry | AssetProxy)[], entry: Entry, options: PersistOptions) {
|
async editorialWorkflowGit(files: (Entry | AssetProxy)[], entry: Entry, options: PersistOptions) {
|
||||||
const contentKey = generateContentKey(options.collectionName as string, entry.slug);
|
const contentKey = this.generateContentKey(options.collectionName as string, entry.slug);
|
||||||
const branch = branchFromContentKey(contentKey);
|
const branch = this.branchFromContentKey(contentKey);
|
||||||
const unpublished = options.unpublished || false;
|
const unpublished = options.unpublished || false;
|
||||||
if (!unpublished) {
|
if (!unpublished) {
|
||||||
const items = await this.getCommitItems(files, this.branch);
|
const items = await this.getCommitItems(files, this.branch);
|
||||||
@ -683,8 +694,8 @@ export default class API {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async updateUnpublishedEntryStatus(collection: string, slug: string, newStatus: string) {
|
async updateUnpublishedEntryStatus(collection: string, slug: string, newStatus: string) {
|
||||||
const contentKey = generateContentKey(collection, slug);
|
const contentKey = this.generateContentKey(collection, slug);
|
||||||
const branch = branchFromContentKey(contentKey);
|
const branch = this.branchFromContentKey(contentKey);
|
||||||
const mergeRequest = await this.getBranchMergeRequest(branch);
|
const mergeRequest = await this.getBranchMergeRequest(branch);
|
||||||
|
|
||||||
const labels = [
|
const labels = [
|
||||||
@ -711,8 +722,8 @@ export default class API {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async publishUnpublishedEntry(collectionName: string, slug: string) {
|
async publishUnpublishedEntry(collectionName: string, slug: string) {
|
||||||
const contentKey = generateContentKey(collectionName, slug);
|
const contentKey = this.generateContentKey(collectionName, slug);
|
||||||
const branch = branchFromContentKey(contentKey);
|
const branch = this.branchFromContentKey(contentKey);
|
||||||
const mergeRequest = await this.getBranchMergeRequest(branch);
|
const mergeRequest = await this.getBranchMergeRequest(branch);
|
||||||
await this.mergeMergeRequest(mergeRequest);
|
await this.mergeMergeRequest(mergeRequest);
|
||||||
}
|
}
|
||||||
@ -736,8 +747,8 @@ export default class API {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async deleteUnpublishedEntry(collectionName: string, slug: string) {
|
async deleteUnpublishedEntry(collectionName: string, slug: string) {
|
||||||
const contentKey = generateContentKey(collectionName, slug);
|
const contentKey = this.generateContentKey(collectionName, slug);
|
||||||
const branch = branchFromContentKey(contentKey);
|
const branch = this.branchFromContentKey(contentKey);
|
||||||
const mergeRequest = await this.getBranchMergeRequest(branch);
|
const mergeRequest = await this.getBranchMergeRequest(branch);
|
||||||
await this.closeMergeRequest(mergeRequest);
|
await this.closeMergeRequest(mergeRequest);
|
||||||
await this.deleteBranch(branch);
|
await this.deleteBranch(branch);
|
||||||
@ -754,8 +765,8 @@ export default class API {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async getStatuses(collectionName: string, slug: string) {
|
async getStatuses(collectionName: string, slug: string) {
|
||||||
const contentKey = generateContentKey(collectionName, slug);
|
const contentKey = this.generateContentKey(collectionName, slug);
|
||||||
const branch = branchFromContentKey(contentKey);
|
const branch = this.branchFromContentKey(contentKey);
|
||||||
const mergeRequest = await this.getBranchMergeRequest(branch);
|
const mergeRequest = await this.getBranchMergeRequest(branch);
|
||||||
const statuses: GitLabCommitStatus[] = await this.getMergeRequestStatues(mergeRequest, branch);
|
const statuses: GitLabCommitStatus[] = await this.getMergeRequestStatues(mergeRequest, branch);
|
||||||
// eslint-disable-next-line @typescript-eslint/camelcase
|
// eslint-disable-next-line @typescript-eslint/camelcase
|
||||||
|
@ -27,8 +27,6 @@ import {
|
|||||||
runWithLock,
|
runWithLock,
|
||||||
getBlobSHA,
|
getBlobSHA,
|
||||||
blobToFileObj,
|
blobToFileObj,
|
||||||
contentKeyFromBranch,
|
|
||||||
generateContentKey,
|
|
||||||
} from 'netlify-cms-lib-util';
|
} from 'netlify-cms-lib-util';
|
||||||
import AuthenticationPage from './AuthenticationPage';
|
import AuthenticationPage from './AuthenticationPage';
|
||||||
import API, { API_NAME } from './API';
|
import API, { API_NAME } from './API';
|
||||||
@ -299,7 +297,7 @@ export default class GitLab implements Implementation {
|
|||||||
async unpublishedEntries() {
|
async unpublishedEntries() {
|
||||||
const listEntriesKeys = () =>
|
const listEntriesKeys = () =>
|
||||||
this.api!.listUnpublishedBranches().then(branches =>
|
this.api!.listUnpublishedBranches().then(branches =>
|
||||||
branches.map(branch => contentKeyFromBranch(branch)),
|
branches.map(branch => this.api!.contentKeyFromBranch(branch)),
|
||||||
);
|
);
|
||||||
|
|
||||||
const readUnpublishedBranchFile = (contentKey: string) =>
|
const readUnpublishedBranchFile = (contentKey: string) =>
|
||||||
@ -316,7 +314,7 @@ export default class GitLab implements Implementation {
|
|||||||
this.loadEntryMediaFiles(branch, files),
|
this.loadEntryMediaFiles(branch, files),
|
||||||
} = {},
|
} = {},
|
||||||
) {
|
) {
|
||||||
const contentKey = generateContentKey(collection, slug);
|
const contentKey = this.api!.generateContentKey(collection, slug);
|
||||||
const data = await this.api!.readUnpublishedBranchFile(contentKey);
|
const data = await this.api!.readUnpublishedBranchFile(contentKey);
|
||||||
const mediaFiles = await loadEntryMediaFiles(
|
const mediaFiles = await loadEntryMediaFiles(
|
||||||
data.metaData.branch,
|
data.metaData.branch,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user