generated from nhcarrigan/template
feat: script to post technical breakdowns
I use this for sprint initiatives very helpful
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
/**
|
||||
* @copyright NHCarrigan
|
||||
* @license Naomi's Public License
|
||||
* @author Naomi Carrigan
|
||||
*/
|
||||
|
||||
import { readFile, readdir } from "node:fs/promises";
|
||||
import { join } from "node:path";
|
||||
import { Octokit } from "@octokit/rest";
|
||||
|
||||
if (process.env.GITHUB_TOKEN === undefined) {
|
||||
throw new Error("Missing Github Token - did you run this with `op`?");
|
||||
}
|
||||
|
||||
/**
|
||||
* Change this to the desired organization name.
|
||||
*/
|
||||
const orgName = "freeCodeCamp-Alpha-and-Omega";
|
||||
|
||||
const gh = new Octokit({
|
||||
auth: process.env.GITHUB_TOKEN,
|
||||
});
|
||||
|
||||
const storiesDirectory = join(
|
||||
import.meta.dirname,
|
||||
"..",
|
||||
"..",
|
||||
"data",
|
||||
"stories",
|
||||
);
|
||||
|
||||
// Read all markdown files from the stories directory
|
||||
const files = await readdir(storiesDirectory);
|
||||
const markdownFiles = files.filter((file) => {
|
||||
return file.endsWith(".md");
|
||||
});
|
||||
|
||||
console.log(`Found ${markdownFiles.length.toString()} story files to process.`);
|
||||
|
||||
let successCount = 0;
|
||||
let errorCount = 0;
|
||||
|
||||
for (const file of markdownFiles) {
|
||||
// Parse filename: format is "{repo-name}-{issue-number}.md"
|
||||
const filenameRegex = /^(?<repoName>.+)-(?<issueNumber>\d+)\.md$/u;
|
||||
const match = filenameRegex.exec(file);
|
||||
const groups = match?.groups;
|
||||
if (!groups) {
|
||||
console.error(`Skipping ${file}: filename format not recognized (expected: repo-name-issue-number.md)`);
|
||||
errorCount = errorCount + 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
const { issueNumber: issueNumberString, repoName } = groups;
|
||||
if (
|
||||
repoName === undefined
|
||||
|| issueNumberString === undefined
|
||||
|| repoName === ""
|
||||
|| issueNumberString === ""
|
||||
) {
|
||||
console.error(`Skipping ${file}: failed to extract repo name or issue number`);
|
||||
errorCount = errorCount + 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
const issueNumber = Number.parseInt(issueNumberString, 10);
|
||||
|
||||
if (Number.isNaN(issueNumber)) {
|
||||
console.error(`Skipping ${file}: invalid issue number ${issueNumberString}`);
|
||||
errorCount = errorCount + 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Read the file content
|
||||
const filePath = join(storiesDirectory, file);
|
||||
const content = await readFile(filePath, "utf-8");
|
||||
|
||||
try {
|
||||
console.log(`Updating issue #${issueNumber.toString()} in ${orgName}/${repoName}...`);
|
||||
|
||||
await gh.rest.issues.update({
|
||||
body: content,
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention -- API parameter name.
|
||||
issue_number: issueNumber,
|
||||
owner: orgName,
|
||||
repo: repoName,
|
||||
});
|
||||
|
||||
console.log(`✓ Successfully updated issue #${issueNumber.toString()} in ${orgName}/${repoName}`);
|
||||
successCount = successCount + 1;
|
||||
} catch (error) {
|
||||
console.error(`✗ Failed to update issue #${issueNumber.toString()} in ${orgName}/${repoName}:`, error);
|
||||
errorCount = errorCount + 1;
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`\n=== Summary ===`);
|
||||
console.log(`Total files processed: ${markdownFiles.length.toString()}`);
|
||||
console.log(`Successful updates: ${successCount.toString()}`);
|
||||
console.log(`Errors: ${errorCount.toString()}`);
|
||||
|
||||
+10
-3
@@ -4,6 +4,7 @@
|
||||
* @author Naomi Carrigan
|
||||
*/
|
||||
import { readFile } from "node:fs/promises";
|
||||
import { join } from "node:path";
|
||||
import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";
|
||||
import { input } from "@inquirer/prompts";
|
||||
|
||||
@@ -15,16 +16,22 @@ if (accessKeyId === undefined || secretAccessKey === undefined) {
|
||||
}
|
||||
|
||||
const fileName = await input({
|
||||
message: "Enter the ABSOLUTE PATH of the file to upload, including leading slash:",
|
||||
message:
|
||||
// eslint-disable-next-line stylistic/max-len -- Big boi string.
|
||||
"Enter the name of the file to upload. Your file MUST be in the `data` directory in this repository. WITHOUT leading slash. Example: 'naomi.png' or 'img/naomi.png'",
|
||||
});
|
||||
if (fileName === "") {
|
||||
throw new Error("File name is not set");
|
||||
}
|
||||
|
||||
const file = await readFile(fileName);
|
||||
const file = await readFile(
|
||||
join(import.meta.dirname, "..", "..", "data", fileName),
|
||||
);
|
||||
|
||||
const uploadPath = await input({
|
||||
message: "Enter the PATH to upload the file to, WITHOUT leading slash:",
|
||||
message:
|
||||
// eslint-disable-next-line stylistic/max-len -- Big boi string.
|
||||
"Enter the PATH to upload the file to, WITHOUT leading slash. Example: 'img/naomi.png' or 'naomi.png':",
|
||||
});
|
||||
if (uploadPath === "") {
|
||||
throw new Error("Upload path is not set");
|
||||
|
||||
Reference in New Issue
Block a user