fix: gitea/refactor file saving (#492)
This commit is contained in:
parent
f89d10627a
commit
1abc18b0ce
@ -362,26 +362,29 @@ export default class API {
|
|||||||
|
|
||||||
async persistFiles(dataFiles: DataFile[], mediaFiles: AssetProxy[], options: PersistOptions) {
|
async persistFiles(dataFiles: DataFile[], mediaFiles: AssetProxy[], options: PersistOptions) {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
[mediaFiles, dataFiles].forEach(async list => {
|
const files: (DataFile | AssetProxy)[] = mediaFiles.concat(dataFiles as any);
|
||||||
list.forEach(async file => {
|
for (const file of files) {
|
||||||
const item: { raw?: string; sha?: string; toBase64?: () => Promise<string> } = file;
|
const item: { raw?: string; sha?: string; toBase64?: () => Promise<string> } = file;
|
||||||
const contentBase64 = await result(
|
const contentBase64 = await result(
|
||||||
item,
|
item,
|
||||||
'toBase64',
|
'toBase64',
|
||||||
partial(this.toBase64, item.raw as string),
|
partial(this.toBase64, item.raw as string),
|
||||||
);
|
);
|
||||||
if (options.newEntry) {
|
try {
|
||||||
await this.request(`${this.repoURL}/contents/${file.path}`, {
|
|
||||||
method: 'POST',
|
|
||||||
body: JSON.stringify({
|
|
||||||
branch: this.branch,
|
|
||||||
content: contentBase64,
|
|
||||||
message: options.commitMessage,
|
|
||||||
signoff: false,
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
const oldSha = await this.getFileSha(file.path);
|
const oldSha = await this.getFileSha(file.path);
|
||||||
|
await this.updateBlob(contentBase64, file, options, oldSha!);
|
||||||
|
} catch {
|
||||||
|
await this.createBlob(contentBase64, file, options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateBlob(
|
||||||
|
contentBase64: string,
|
||||||
|
file: AssetProxy | DataFile,
|
||||||
|
options: PersistOptions,
|
||||||
|
oldSha: string,
|
||||||
|
) {
|
||||||
await this.request(`${this.repoURL}/contents/${file.path}`, {
|
await this.request(`${this.repoURL}/contents/${file.path}`, {
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
@ -393,7 +396,16 @@ export default class API {
|
|||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
async createBlob(contentBase64: string, file: AssetProxy | DataFile, options: PersistOptions) {
|
||||||
|
await this.request(`${this.repoURL}/contents/${file.path}`, {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify({
|
||||||
|
branch: this.branch,
|
||||||
|
content: contentBase64,
|
||||||
|
message: options.commitMessage,
|
||||||
|
signoff: false,
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -415,12 +427,12 @@ export default class API {
|
|||||||
if (file) {
|
if (file) {
|
||||||
return file.sha;
|
return file.sha;
|
||||||
} else {
|
} else {
|
||||||
console.error('File not found');
|
throw new APIError('Not Found', 404, API_NAME);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async deleteFiles(paths: string[], message: string) {
|
async deleteFiles(paths: string[], message: string) {
|
||||||
paths.forEach(async file => {
|
for (const file of paths) {
|
||||||
const meta: ContentsResponse = await this.request(`${this.repoURL}/contents/${file}`, {
|
const meta: ContentsResponse = await this.request(`${this.repoURL}/contents/${file}`, {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
});
|
});
|
||||||
@ -428,7 +440,7 @@ export default class API {
|
|||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
body: JSON.stringify({ branch: this.branch, message, sha: meta.sha, signoff: false }),
|
body: JSON.stringify({ branch: this.branch, message, sha: meta.sha, signoff: false }),
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
toBase64(str: string) {
|
toBase64(str: string) {
|
||||||
|
@ -101,7 +101,7 @@ describe('gitea API', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('persistFiles', () => {
|
describe('persistFiles', () => {
|
||||||
it('should create a new file', async () => {
|
it('should check if file exists and create a new file', async () => {
|
||||||
const api = new API({ branch: 'master', repo: 'owner/repo' });
|
const api = new API({ branch: 'master', repo: 'owner/repo' });
|
||||||
|
|
||||||
const responses = {
|
const responses = {
|
||||||
@ -127,9 +127,13 @@ describe('gitea API', () => {
|
|||||||
newEntry: true,
|
newEntry: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(api.request).toHaveBeenCalledTimes(1);
|
expect(api.request).toHaveBeenCalledTimes(2);
|
||||||
|
|
||||||
expect((api.request as jest.Mock).mock.calls[0]).toEqual([
|
expect((api.request as jest.Mock).mock.calls[0]).toEqual([
|
||||||
|
'/repos/owner/repo/git/trees/master:content%2Fposts',
|
||||||
|
]);
|
||||||
|
|
||||||
|
expect((api.request as jest.Mock).mock.calls[1]).toEqual([
|
||||||
'/repos/owner/repo/contents/content/posts/new-post.md',
|
'/repos/owner/repo/contents/content/posts/new-post.md',
|
||||||
{
|
{
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
@ -174,11 +178,25 @@ describe('gitea API', () => {
|
|||||||
newEntry: false,
|
newEntry: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(api.request).toHaveBeenCalledTimes(1);
|
expect(api.request).toHaveBeenCalledTimes(2);
|
||||||
|
|
||||||
expect((api.request as jest.Mock).mock.calls[0]).toEqual([
|
expect((api.request as jest.Mock).mock.calls[0]).toEqual([
|
||||||
'/repos/owner/repo/git/trees/master:content%2Fposts',
|
'/repos/owner/repo/git/trees/master:content%2Fposts',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
expect((api.request as jest.Mock).mock.calls[1]).toEqual([
|
||||||
|
'/repos/owner/repo/contents/content/posts/update-post.md',
|
||||||
|
{
|
||||||
|
method: 'PUT',
|
||||||
|
body: JSON.stringify({
|
||||||
|
branch: 'master',
|
||||||
|
content: Base64.encode(entry.dataFiles[0].raw),
|
||||||
|
message: 'commitMessage',
|
||||||
|
sha: 'old-sha',
|
||||||
|
signoff: false,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -9,13 +9,15 @@ beta: true
|
|||||||
|
|
||||||
For repositories stored on Gitea, the `gitea` backend allows CMS users to log in directly with their Gitea account. Note that all users must have push access to your content repository for this to work.
|
For repositories stored on Gitea, the `gitea` backend allows CMS users to log in directly with their Gitea account. Note that all users must have push access to your content repository for this to work.
|
||||||
|
|
||||||
|
<Alert severity="warning">Because of the [lack](https://github.com/go-gitea/gitea/issues/14619) of a Gitea API endpoint for multifile commits, when using this backend, separate commits are created for every changed file. Please make sure this is handled correctly by your CI.</Alert>
|
||||||
|
|
||||||
## Authentication
|
## Authentication
|
||||||
|
|
||||||
Because Gitea requires a server for authentication and Netlify doesn't support Gitea, a custom OAuth provider needs to be used for basic Gitea authentication.
|
Because Gitea requires a server for authentication and Netlify doesn't support Gitea, a custom OAuth provider needs to be used for basic Gitea authentication.
|
||||||
|
|
||||||
To enable basic Gitea authentication:
|
To enable basic Gitea authentication:
|
||||||
|
|
||||||
1. Setup an own OAuth provider, for example with [scm-oauth](https://github.com/denyskon/scm-oauth-provider).
|
1. Setup an own OAuth provider, for example with [Teabag](https://github.com/denyskon/teabag).
|
||||||
2. Add the following lines to your Static CMS `config` file:
|
2. Add the following lines to your Static CMS `config` file:
|
||||||
|
|
||||||
<CodeTabs>
|
<CodeTabs>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user