scaffolder-backend: refactor actions to use serializeDirectoryContents
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
@@ -154,6 +154,7 @@ export function createFetchTemplateAction(options: {
|
||||
dot: true,
|
||||
onlyFiles: false,
|
||||
markDirectories: true,
|
||||
followSymbolicLinks: false,
|
||||
});
|
||||
|
||||
const nonTemplatedEntries = new Set(
|
||||
@@ -165,6 +166,7 @@ export function createFetchTemplateAction(options: {
|
||||
dot: true,
|
||||
onlyFiles: false,
|
||||
markDirectories: true,
|
||||
followSymbolicLinks: false,
|
||||
}),
|
||||
),
|
||||
)
|
||||
|
||||
+27
-46
@@ -14,21 +14,19 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import fs from 'fs-extra';
|
||||
import { parseRepoUrl, isExecutable } from './util';
|
||||
|
||||
import path from 'path';
|
||||
import { parseRepoUrl } from './util';
|
||||
import {
|
||||
GithubCredentialsProvider,
|
||||
ScmIntegrationRegistry,
|
||||
} from '@backstage/integration';
|
||||
import { zipObject } from 'lodash';
|
||||
import { createTemplateAction } from '../../createTemplateAction';
|
||||
import { Octokit } from 'octokit';
|
||||
import { InputError, CustomErrorBase } from '@backstage/errors';
|
||||
import { createPullRequest } from 'octokit-plugin-create-pull-request';
|
||||
import globby from 'globby';
|
||||
import { resolveSafeChildPath } from '@backstage/backend-common';
|
||||
import { getOctokitOptions } from '../github/helpers';
|
||||
import { serializeDirectoryContents } from '../../../../lib/files';
|
||||
|
||||
export type Encoding = 'utf-8' | 'base64';
|
||||
|
||||
@@ -219,56 +217,39 @@ export const createPublishGithubPullRequestAction = ({
|
||||
? resolveSafeChildPath(ctx.workspacePath, sourcePath)
|
||||
: ctx.workspacePath;
|
||||
|
||||
const localFilePaths = await globby(['./**', './**/.*', '!.git'], {
|
||||
cwd: fileRoot,
|
||||
const directoryContents = await serializeDirectoryContents(fileRoot, {
|
||||
gitignore: true,
|
||||
dot: true,
|
||||
});
|
||||
|
||||
const fileContents = await Promise.all(
|
||||
localFilePaths.map(filePath => {
|
||||
const absPath = resolveSafeChildPath(fileRoot, filePath);
|
||||
const base64EncodedContent = fs
|
||||
.readFileSync(absPath)
|
||||
.toString('base64');
|
||||
const fileStat = fs.statSync(absPath);
|
||||
// See the properties of tree items
|
||||
// in https://docs.github.com/en/rest/reference/git#trees
|
||||
const githubTreeItemMode = isExecutable(fileStat.mode)
|
||||
? '100755'
|
||||
: '100644';
|
||||
// Always use base64 encoding to avoid doubling a binary file in size
|
||||
// due to interpreting a binary file as utf-8 and sending github
|
||||
// the utf-8 encoded content.
|
||||
//
|
||||
// For example, the original gradle-wrapper.jar is 57.8k in https://github.com/kennethzfeng/pull-request-test/pull/5/files.
|
||||
// Its size could be doubled to 98.3K (See https://github.com/kennethzfeng/pull-request-test/pull/4/files)
|
||||
const encoding: Encoding = 'base64';
|
||||
return {
|
||||
encoding: encoding,
|
||||
content: base64EncodedContent,
|
||||
mode: githubTreeItemMode,
|
||||
};
|
||||
}),
|
||||
const files = Object.fromEntries(
|
||||
directoryContents.map(file => [
|
||||
targetPath ? path.posix.join(targetPath, file.path) : file.path,
|
||||
{
|
||||
// See the properties of tree items
|
||||
// in https://docs.github.com/en/rest/reference/git#trees
|
||||
mode: file.executable ? '100755' : '100644',
|
||||
// Always use base64 encoding to avoid doubling a binary file in size
|
||||
// due to interpreting a binary file as utf-8 and sending github
|
||||
// the utf-8 encoded content.
|
||||
//
|
||||
// For example, the original gradle-wrapper.jar is 57.8k in https://github.com/kennethzfeng/pull-request-test/pull/5/files.
|
||||
// Its size could be doubled to 98.3K (See https://github.com/kennethzfeng/pull-request-test/pull/4/files)
|
||||
encoding: 'base64' as const,
|
||||
content: file.content.toString('base64'),
|
||||
},
|
||||
]),
|
||||
);
|
||||
|
||||
const repoFilePaths = localFilePaths.map(repoFilePath => {
|
||||
return targetPath ? `${targetPath}/${repoFilePath}` : repoFilePath;
|
||||
});
|
||||
|
||||
const changes = [
|
||||
{
|
||||
files: zipObject(repoFilePaths, fileContents),
|
||||
commit: title,
|
||||
},
|
||||
];
|
||||
|
||||
try {
|
||||
const response = await client.createPullRequest({
|
||||
owner,
|
||||
repo,
|
||||
title,
|
||||
changes,
|
||||
changes: [
|
||||
{
|
||||
files,
|
||||
commit: title,
|
||||
},
|
||||
],
|
||||
body: description,
|
||||
head: branchName,
|
||||
draft,
|
||||
|
||||
+14
-24
@@ -14,15 +14,14 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { createTemplateAction } from '../../createTemplateAction';
|
||||
import { readFile } from 'fs-extra';
|
||||
import { Gitlab } from '@gitbeaker/node';
|
||||
import globby from 'globby';
|
||||
import { Types } from '@gitbeaker/core';
|
||||
|
||||
import path from 'path';
|
||||
import { ScmIntegrationRegistry } from '@backstage/integration';
|
||||
import { InputError } from '@backstage/errors';
|
||||
import { parseRepoUrl } from './util';
|
||||
import { resolveSafeChildPath } from '@backstage/backend-common';
|
||||
import { serializeDirectoryContents } from '../../../../lib/files';
|
||||
|
||||
/**
|
||||
* Create a new action that creates a gitlab merge request.
|
||||
@@ -106,8 +105,6 @@ export const createPublishGitlabMergeRequestAction = (options: {
|
||||
const { host } = parseRepoUrl(repoUrl, integrations);
|
||||
const integrationConfig = integrations.gitlab.byHost(host);
|
||||
|
||||
const actions: Types.CommitAction[] = [];
|
||||
|
||||
const destinationBranch = ctx.input.branchName;
|
||||
|
||||
if (!integrationConfig) {
|
||||
@@ -128,28 +125,21 @@ export const createPublishGitlabMergeRequestAction = (options: {
|
||||
[tokenType]: token,
|
||||
});
|
||||
|
||||
const fileRoot = ctx.workspacePath;
|
||||
const localFilePaths = await globby([`${ctx.input.targetPath}/**`], {
|
||||
cwd: fileRoot,
|
||||
gitignore: true,
|
||||
dot: true,
|
||||
});
|
||||
|
||||
const fileContents = await Promise.all(
|
||||
localFilePaths.map(p => readFile(resolveSafeChildPath(fileRoot, p))),
|
||||
const targetPath = resolveSafeChildPath(
|
||||
ctx.workspacePath,
|
||||
ctx.input.targetPath,
|
||||
);
|
||||
|
||||
const repoFilePaths = localFilePaths.map(repoFilePath => {
|
||||
return repoFilePath;
|
||||
const fileContents = await serializeDirectoryContents(targetPath, {
|
||||
gitignore: true,
|
||||
});
|
||||
|
||||
for (let i = 0; i < repoFilePaths.length; i++) {
|
||||
actions.push({
|
||||
action: 'create',
|
||||
filePath: repoFilePaths[i],
|
||||
content: fileContents[i].toString(),
|
||||
});
|
||||
}
|
||||
const actions: Types.CommitAction[] = fileContents.map(file => ({
|
||||
action: 'create',
|
||||
filePath: path.posix.join(ctx.input.targetPath, file.path),
|
||||
encoding: 'base64',
|
||||
content: file.content.toString('base64'),
|
||||
execute_filemode: file.executable,
|
||||
}));
|
||||
|
||||
const projects = await api.Projects.show(ctx.input.projectid);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user