From d8c30abf522c07fccd426c6eac9eeaf0897913d4 Mon Sep 17 00:00:00 2001 From: Anmol Baranwal Date: Tue, 5 Mar 2024 00:35:24 +0530 Subject: [PATCH] feat: add option to synchronize reading list from dev in readme --- action.yml | 6 +- dist/index.js | 103 +++++++++++++++++++++++++++ dist/utils/synchronizeReadingList.js | 86 ++++++++++++++++++++++ src/index.ts | 10 +++ src/utils/synchronizeReadingList.ts | 87 ++++++++++++++++++++++ 5 files changed, 291 insertions(+), 1 deletion(-) create mode 100644 dist/utils/synchronizeReadingList.js create mode 100644 src/utils/synchronizeReadingList.ts diff --git a/action.yml b/action.yml index f871d7b..27a3789 100644 --- a/action.yml +++ b/action.yml @@ -33,6 +33,10 @@ inputs: description: 'To create a reading list from DEV to include this tag at all costs.' default: '' required: false + synchronizeReadingList: + description: 'To synchronize reading list with dev.to' + default: 'false' + required: false saveArticles: description: 'To save all the articles with all the necessary information.' default: 'true' @@ -54,4 +58,4 @@ runs: main: 'dist/index.js' branding: icon: 'save' - color: 'gray-dark' \ No newline at end of file + color: 'gray-dark' diff --git a/dist/index.js b/dist/index.js index 302ebb2..98e06a6 100644 --- a/dist/index.js +++ b/dist/index.js @@ -35,6 +35,7 @@ const createMarkdownFile_1 = __nccwpck_require__(6034); const core = __importStar(__nccwpck_require__(2186)); const createReadingList_1 = __nccwpck_require__(8644); const fetchDevToReadingList_1 = __nccwpck_require__(3327); +const synchronizeReadingList_1 = __nccwpck_require__(4724); async function DevtoGitHub() { try { const apiKey = core.getInput("devApiKey"); @@ -43,6 +44,7 @@ async function DevtoGitHub() { const branch = core.getInput("branch") || "main"; const readingList = core.getInput("readingList") === "true" || false; const saveArticles = core.getInput("saveArticles") === "true" || false; + const synchronizeReadingListInput = core.getInput("synchronizeReadingList") === "true" || false; if (saveArticles === true) { const articles = await (0, fetchDevToArticles_1.fetchDevToArticles)(apiKey); (0, createMarkdownFile_1.createMarkdownFile)(articles, outputDir, branch, apiKey); @@ -54,6 +56,13 @@ async function DevtoGitHub() { if (readingList === true) { const readingListArticles = await (0, fetchDevToReadingList_1.fetchDevToReadingList)(apiKey); (0, createReadingList_1.createReadingList)(readingListArticles, outputDirReading, branch); + if (synchronizeReadingListInput === true) { + // synchronize reading list from DEV with readme + (0, synchronizeReadingList_1.synchronizeReadingList)(readingListArticles, outputDirReading, branch); + } + else { + core.notice(`skipping synchronization of reading list`); + } } else { core.notice(`skipping saving reading list`); @@ -652,6 +661,100 @@ const formatTimestamp = (timestamp) => { }; +/***/ }), + +/***/ 4724: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + +"use strict"; + +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.synchronizeReadingList = void 0; +const fs = __importStar(__nccwpck_require__(7147)); +const core = __importStar(__nccwpck_require__(2186)); +const git_1 = __nccwpck_require__(9556); +async function synchronizeReadingList(readingList, outputDir, branch) { + const readmePath = `./${outputDir}/README.md`; + let commitMessage = "synchronize reading list"; + const conventionalCommits = core.getInput("conventionalCommits") === "true" || true; + if (conventionalCommits) { + commitMessage = `chore: ${commitMessage.toLowerCase()}`; + } + try { + const existingContent = fs.readFileSync(readmePath, "utf8"); + // For logging names of removed articles + const removedArticles = []; + // Iterate each line in the readme + let updatedContent = existingContent + .split("\n") + .filter((line) => { + // Extract the URL from the line + const urlMatch = line.match(/\[.*\]\((.*)\)/); + if (urlMatch) { + const articleUrl = urlMatch[1]; + // Check if the article URL exists in the fetched reading list + const existsInReadingList = readingList.some((article) => article.article.url === articleUrl); + // If the article doesn't exist in the reading list, add it to removedArticles + if (!existsInReadingList) { + const titleMatch = line.match(/\[(.*)\]/); + if (titleMatch) { + const articleTitle = titleMatch[1]; + removedArticles.push(articleTitle); + } + } + return existsInReadingList; + } + // Preserve lines that are not article URLs + return true; + }) + .join("\n"); + // Log removed articles + if (removedArticles.length > 0) { + console.log(`Removed these articles from the reading list: ${removedArticles.join(", ")}`); + } + fs.writeFileSync(readmePath, updatedContent); + try { + await (0, git_1.gitConfig)(); + await (0, git_1.gitAdd)(readmePath); + await (0, git_1.gitCommit)(commitMessage, readmePath); + await (0, git_1.gitPull)(branch); + await (0, git_1.gitPush)(branch); + } + catch (error) { + core.setFailed(`Failed to commit and push changes: ${error.message}`); + } + core.notice(`Reading list synchronized successfully.`); + } + catch (error) { + core.setFailed(`Failed to synchronize reading list: ${error.message}`); + } +} +exports.synchronizeReadingList = synchronizeReadingList; + + /***/ }), /***/ 7351: diff --git a/dist/utils/synchronizeReadingList.js b/dist/utils/synchronizeReadingList.js new file mode 100644 index 0000000..e5b2a26 --- /dev/null +++ b/dist/utils/synchronizeReadingList.js @@ -0,0 +1,86 @@ +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.synchronizeReadingList = void 0; +const fs = __importStar(require("fs")); +const core = __importStar(require("@actions/core")); +const git_1 = require("./git"); +async function synchronizeReadingList(readingList, outputDir, branch) { + const readmePath = `./${outputDir}/README.md`; + let commitMessage = "synchronize reading list"; + const conventionalCommits = core.getInput("conventionalCommits") === "true" || true; + if (conventionalCommits) { + commitMessage = `chore: ${commitMessage.toLowerCase()}`; + } + try { + const existingContent = fs.readFileSync(readmePath, "utf8"); + // For logging names of removed articles + const removedArticles = []; + // Iterate each line in the readme + let updatedContent = existingContent + .split("\n") + .filter((line) => { + // Extract the URL from the line + const urlMatch = line.match(/\[.*\]\((.*)\)/); + if (urlMatch) { + const articleUrl = urlMatch[1]; + // Check if the article URL exists in the fetched reading list + const existsInReadingList = readingList.some((article) => article.article.url === articleUrl); + // If the article doesn't exist in the reading list, add it to removedArticles + if (!existsInReadingList) { + const titleMatch = line.match(/\[(.*)\]/); + if (titleMatch) { + const articleTitle = titleMatch[1]; + removedArticles.push(articleTitle); + } + } + return existsInReadingList; + } + // Preserve lines that are not article URLs + return true; + }) + .join("\n"); + // Log removed articles + if (removedArticles.length > 0) { + console.log(`Removed these articles from the reading list: ${removedArticles.join(", ")}`); + } + fs.writeFileSync(readmePath, updatedContent); + try { + await (0, git_1.gitConfig)(); + await (0, git_1.gitAdd)(readmePath); + await (0, git_1.gitCommit)(commitMessage, readmePath); + await (0, git_1.gitPull)(branch); + await (0, git_1.gitPush)(branch); + } + catch (error) { + core.setFailed(`Failed to commit and push changes: ${error.message}`); + } + core.notice(`Reading list synchronized successfully.`); + } + catch (error) { + core.setFailed(`Failed to synchronize reading list: ${error.message}`); + } +} +exports.synchronizeReadingList = synchronizeReadingList; diff --git a/src/index.ts b/src/index.ts index 0f3ad90..017f537 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,6 +3,7 @@ import { createMarkdownFile } from "./utils/createMarkdownFile" import * as core from "@actions/core" import { createReadingList } from "./utils/createReadingList" import { fetchDevToReadingList } from "./utils/fetchDevToReadingList" +import { synchronizeReadingList } from "./utils/synchronizeReadingList" async function DevtoGitHub() { try { @@ -12,6 +13,8 @@ async function DevtoGitHub() { const branch = core.getInput("branch") || "main" const readingList = core.getInput("readingList") === "true" || false const saveArticles = core.getInput("saveArticles") === "true" || false + const synchronizeReadingListInput = + core.getInput("synchronizeReadingList") === "true" || false if (saveArticles === true) { const articles = await fetchDevToArticles(apiKey) @@ -25,6 +28,13 @@ async function DevtoGitHub() { const readingListArticles = await fetchDevToReadingList(apiKey) createReadingList(readingListArticles, outputDirReading, branch) + + if (synchronizeReadingListInput === true) { + // synchronize reading list from DEV with readme + synchronizeReadingList(readingListArticles, outputDirReading, branch) + } else { + core.notice(`skipping synchronization of reading list`) + } } else { core.notice(`skipping saving reading list`) } diff --git a/src/utils/synchronizeReadingList.ts b/src/utils/synchronizeReadingList.ts new file mode 100644 index 0000000..342b8e8 --- /dev/null +++ b/src/utils/synchronizeReadingList.ts @@ -0,0 +1,87 @@ +import * as fs from "fs" +import { ReadingList } from "../types" +import * as core from "@actions/core" +import { gitAdd, gitCommit, gitConfig, gitPull, gitPush } from "./git" + +export async function synchronizeReadingList( + readingList: ReadingList[], + outputDir: string, + branch: string +): Promise { + const readmePath = `./${outputDir}/README.md` + + let commitMessage = "synchronize reading list" + + const conventionalCommits = + core.getInput("conventionalCommits") === "true" || true + + if (conventionalCommits) { + commitMessage = `chore: ${commitMessage.toLowerCase()}` + } + + try { + const existingContent = fs.readFileSync(readmePath, "utf8") + + // For logging names of removed articles + const removedArticles: string[] = [] + + // Iterate each line in the readme + let updatedContent = existingContent + .split("\n") + .filter((line) => { + // Extract the URL from the line + const urlMatch = line.match(/\[.*\]\((.*)\)/) + if (urlMatch) { + const articleUrl = urlMatch[1] + + // Check if the article URL exists in the fetched reading list + const existsInReadingList = readingList.some( + (article) => article.article.url === articleUrl + ) + + // If the article doesn't exist in the reading list, add it to removedArticles + if (!existsInReadingList) { + const titleMatch = line.match(/\[(.*)\]/) + if (titleMatch) { + const articleTitle = titleMatch[1] + removedArticles.push(articleTitle) + } + } + + return existsInReadingList + } + // Preserve lines that are not article URLs + return true + }) + .join("\n") + + // Log removed articles + if (removedArticles.length > 0) { + console.log( + `Removed these articles from the reading list: ${removedArticles.join( + ", " + )}` + ) + } + + fs.writeFileSync(readmePath, updatedContent) + + try { + await gitConfig() + await gitAdd(readmePath) + await gitCommit(commitMessage, readmePath) + await gitPull(branch) + await gitPush(branch) + } catch (error) { + core.setFailed( + `Failed to commit and push changes: ${(error as Error).message}` + ) + } + + core.notice(`Reading list synchronized successfully.`) + } catch (error) { + core.setFailed( + `Failed to synchronize reading list: ${(error as Error).message}` + ) + } +}