Skip to content

Commit

Permalink
feat: use PR + merge + delete branch instead of force push files
Browse files Browse the repository at this point in the history
  • Loading branch information
Mara-Li committed May 27, 2022
1 parent c3a250c commit ec8a367
Show file tree
Hide file tree
Showing 7 changed files with 616 additions and 480 deletions.
81 changes: 81 additions & 0 deletions mkdocsPublisher/githubInteraction/branch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { Octokit } from "@octokit/core";
import { MkdocsPublicationSettings } from "../settings/interface";

export class GithubBranch {
settings: MkdocsPublicationSettings;
octokit: Octokit;

constructor(settings: MkdocsPublicationSettings, octokit: Octokit) {
this.settings = settings;
this.octokit = octokit;
}

async newBranch(branchName: string) {
const allBranch = await this.octokit.request('GET' + ' /repos/{owner}/{repo}/branches', {
owner: this.settings.githubName,
repo: this.settings.githubRepo,
});
const mainBranch = allBranch.data.find((branch: { name: string; }) => branch.name === 'main' || branch.name === 'master');
const shaMainBranch = mainBranch.commit.sha;
console.log(mainBranch)
const branch = await this.octokit.request(
"POST" + " /repos/{owner}/{repo}/git/refs",
{
owner: this.settings.githubName,
repo: this.settings.githubRepo,
ref: "refs/heads/" + branchName,
sha: shaMainBranch,
}
);
return branch.status === 201;
}

async pullRequest(branchName: string) {
return await this.octokit.request('POST' +
' /repos/{owner}/{repo}/pulls', {
owner: this.settings.githubName,
repo: this.settings.githubRepo,
title: `PullRequest ${branchName} from Obsidian`,
body: "",
head: branchName,
base: "main",
});
}

async deleteBranch(branchName: string) {
const octokit = new Octokit({
auth: this.settings.GhToken,
});
const branch = await octokit.request(
"DELETE" + " /repos/{owner}/{repo}/git/refs/heads/" + branchName,
{
owner: this.settings.githubName,
repo: this.settings.githubRepo,
}
);
return branch.status === 200;
}


async mergePullRequest (branchName: string, silent = false, pullRequestNumber: number) {
const octokit = new Octokit({
auth: this.settings.GhToken,
});
const branch = await octokit.request(
"PUT" + " /repos/{owner}/{repo}/pulls/{pull_number}/merge",
{
owner: this.settings.githubName,
repo: this.settings.githubRepo,
pull_number: pullRequestNumber,
state: "closed",
}
);
return branch.status === 200;
}
async updateRepository(branchName: string) {
const pullRequest = await this.pullRequest(branchName);
// @ts-ignore
await this.mergePullRequest(branchName, true, pullRequest.data.number);
await this.deleteBranch(branchName);
}
}
139 changes: 139 additions & 0 deletions mkdocsPublisher/githubInteraction/delete.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
import { Octokit } from "@octokit/core";
import { Notice } from "obsidian";
import { MkdocsPublicationSettings } from "../settings/interface";
import { GetFiles } from "./getFiles";

export async function deleteFromGithub(silent = false, settings: MkdocsPublicationSettings, octokit: Octokit, branchName='main', GetFiles: GetFiles) {
const getAllFile = await getAllFileFromRepo(branchName, octokit, settings);
const filesInRepo = await filterGithubFile(getAllFile,
settings
);
if (!filesInRepo) {
let errorMsg = "";
if (settings.folderDefaultName.length > 0) {
if (settings.folderDefaultName.length > 0) {
errorMsg =
"You need to configure a" +
" default folder name in the" +
" settings to use this command.";
} else if (
settings.downloadedFolder === "yamlFrontmatter" &&
settings.rootFolder
) {
errorMsg =
"You need to configure a root folder in the settings to use this command.";
}
if (!silent) {
new Notice("Error : " + errorMsg);
}
}
return false;
}
const allSharedFiles = GetFiles.getAllFileWithPath();
let deletedSuccess = 0;
let deletedFailed = 0;
for (const file of filesInRepo) {
if (!allSharedFiles.includes(file.file)) {
try {
console.log('trying to delete file : ' + file.file);
const reponse = await octokit.request(
"DELETE" + " /repos/{owner}/{repo}/contents/{path}",
{
owner: settings.githubName,
repo: settings.githubRepo,
path: file.file,
message: "Delete file",
sha: file.sha,
branch: branchName
}
);
if (reponse.status === 200) {
deletedSuccess++;
} else {
deletedFailed++;
}
} catch (e) {
console.error(e);
}
}
}
let successMsg = 'No files have been deleted';
let failedMsg = '';
if (deletedSuccess > 0) {
successMsg = `Successfully deleted ${deletedSuccess} files`
}
if (deletedFailed > 0) {
failedMsg = `Failed to delete ${deletedFailed} files.`
}
if (!silent) {
new Notice(successMsg + failedMsg)
}
return true;
}

export async function filterGithubFile(fileInRepo: { file: string; sha: string }[], settings: MkdocsPublicationSettings) {
const sharedFilesInRepo = [];
for (const file of fileInRepo) {
if (
(settings.downloadedFolder === "yamlFrontmatter" &&
settings.rootFolder.length === 0) ||
settings.folderDefaultName.length === 0
) {
return false;
}
if (
file.file.includes(settings.folderDefaultName) ||
(settings.downloadedFolder === "yamlFrontmatter" &&
file.file.includes(settings.rootFolder)) ||
(settings.defaultImageFolder.length > 0 &&
file.file.includes(settings.defaultImageFolder))
) {
sharedFilesInRepo.push(file);
}
}
return sharedFilesInRepo;
}

async function getAllFileFromRepo(ref="main", octokit: Octokit, settings: MkdocsPublicationSettings) {
const filesInRepo = [];
try {
const allBranch = await octokit.request('GET' +
' /repos/{owner}/{repo}/branches', {
owner: settings.githubName,
repo: settings.githubRepo,
});
const refBranch = allBranch.data.find((branch: { name: string; }) => branch.name === ref);
console.log(refBranch)
const repoContents = await octokit.request(
"GET" + " /repos/{owner}/{repo}/git/trees/{tree_sha}",
{
owner: settings.githubName,
repo: settings.githubRepo,
tree_sha: ref,
recursive: "true",
}
);

if (repoContents.status === 200) {
const files = repoContents.data.tree;
for (const file of files) {
const basename = (name: string) =>
/([^/\\.]*)(\..*)?$/.exec(name)[1]; //don't delete file starting with .
if (
file.type === "blob" &&
basename(file.path).length > 0 &&
basename(file.path) != 'vault_published'
) {
filesInRepo.push({
file: file.path,
sha: file.sha,
});
}
}
}
} catch (e) {
console.log(e)
}
return filesInRepo;
}

131 changes: 131 additions & 0 deletions mkdocsPublisher/githubInteraction/getFiles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
// Credit : https://github.com/oleeskild/obsidian-digital-garden @oleeskild

import {
MetadataCache,
TFile,
Vault,
} from "obsidian";
import { MkdocsPublicationSettings } from "../settings/interface";
import { Octokit } from "@octokit/core";

export class GetFiles {
vault: Vault;
metadataCache: MetadataCache;
settings: MkdocsPublicationSettings;
octokit: Octokit;

constructor(
vault: Vault,
metadataCache: MetadataCache,
settings: MkdocsPublicationSettings,
octokit: Octokit
) {
this.vault = vault;
this.metadataCache = metadataCache;
this.settings = settings;
this.octokit = octokit;
}

getSharedFiles() {
const files = this.vault.getMarkdownFiles();
const shared_File = [];
const sharedkey = this.settings.shareKey;
for (const file of files) {
try {
const frontMatter = this.metadataCache.getCache(
file.path
).frontmatter;
if (frontMatter && frontMatter[sharedkey] === true) {
shared_File.push(file);
}
} catch {
// ignore
}
}
return shared_File;
}

getAllFileWithPath() {
const files = this.vault.getFiles();
const allFileWithPath = [];
const shareKey = this.settings.shareKey;
for (const file of files) {
const fileExtension = file.extension;
if (fileExtension.match(/(png|jpe?g|svg|bmp|gif)$/i)) {
const filepath =
this.settings.defaultImageFolder.length > 0
? this.settings.defaultImageFolder + "/" + file.path
: this.settings.folderDefaultName.length > 0
? this.settings.folderDefaultName + "/" + file.path
: file.path;
allFileWithPath.push(filepath);
} else if (file.extension == "md") {
const frontMatter = this.metadataCache.getCache(
file.path
).frontmatter;
let filepath =
this.settings.folderDefaultName.length > 0
? this.settings.folderDefaultName + "/" + file.path
: file.path;
if (frontMatter && frontMatter[shareKey] === true) {
if (this.settings.downloadedFolder === "yamlFrontmatter") {
if (frontMatter[this.settings.yamlFolderKey]) {
filepath =
this.settings.rootFolder.length > 0
? this.settings.rootFolder + "/" + frontMatter[this.settings.yamlFolderKey] +
"/" + file.name : file.name;
}
} else if (
this.settings.downloadedFolder === "fixedFolder"
) {
filepath =
this.settings.folderDefaultName.length > 0
? this.settings.folderDefaultName + "/" + file.name : file.name;
}
allFileWithPath.push(filepath);
}
}
}
return allFileWithPath;
}

getLinkedImage(file: TFile) {
const embed_files = this.metadataCache.getCache(file.path).embeds;
const image_list = [];
if (embed_files != undefined) {
for (const embed_file of embed_files) {
try {
const imageLink = this.metadataCache.getFirstLinkpathDest(
embed_file.link,
file.path
);
const imgExt = imageLink.extension;
if (imgExt.match(/(png|jpe?g|svg|bmp|gif)$/i)) {
image_list.push(imageLink);
}
} catch (e) {
console.log("Error with this image : " + embed_file);
}
}
return image_list;
}
return [];
}

checkExcludedFolder(file: TFile) {
const excludedFolder = this.settings.ExcludedFolder.split(",").filter(
(x) => x != ""
);
if (excludedFolder.length > 0) {
for (let i = 0; i < excludedFolder.length; i++) {
if (file.path.contains(excludedFolder[i].trim())) {
return true;
}
}
}
return false;
}



}
Loading

0 comments on commit ec8a367

Please sign in to comment.