generated from nhcarrigan/template
feat: include all repositories in project data, test it
Node.js CI / Lint and Test (push) Failing after 24s
Node.js CI / Lint and Test (push) Failing after 24s
This commit is contained in:
+71
-1
@@ -161,7 +161,7 @@
|
|||||||
name: Lucinda
|
name: Lucinda
|
||||||
premium: false
|
premium: false
|
||||||
url: 'https://lucinda.nhcarrigan.com'
|
url: 'https://lucinda.nhcarrigan.com'
|
||||||
wip: false
|
wip: true
|
||||||
- avatar: null
|
- avatar: null
|
||||||
category: websites
|
category: websites
|
||||||
description: Our homepage and marketing landing.
|
description: Our homepage and marketing landing.
|
||||||
@@ -518,3 +518,73 @@
|
|||||||
premium: false
|
premium: false
|
||||||
url: null
|
url: null
|
||||||
wip: true
|
wip: true
|
||||||
|
- avatar: 'https://cdn.nhcarrigan.com/new-avatars/a4p.png'
|
||||||
|
category: community
|
||||||
|
description: A custom Discord bot for the Artists4Palestine charity initiative.
|
||||||
|
name: Artists4Palestine Bot
|
||||||
|
premium: false
|
||||||
|
url: null
|
||||||
|
wip: false
|
||||||
|
- avatar: null
|
||||||
|
category: community
|
||||||
|
description: A custom Discord bot for Caylus that removes our booster colour role when someone stops boosting.
|
||||||
|
name: Boost Monitor
|
||||||
|
premium: false
|
||||||
|
url: null
|
||||||
|
wip: false
|
||||||
|
- avatar: null
|
||||||
|
category: apps
|
||||||
|
description: Our custom ESLint rules.
|
||||||
|
name: ESLint Config
|
||||||
|
premium: false
|
||||||
|
url: "https://www.npmjs.com/package/@nhcarrigan/eslint-config"
|
||||||
|
wip: false
|
||||||
|
- avatar: "https://cdn.nhcarrigan.com/new-avatars/celestine.png"
|
||||||
|
category: community
|
||||||
|
description: A powerful moderation bot for Discord.
|
||||||
|
name: Celestine
|
||||||
|
premium: true
|
||||||
|
url: "https://celestine.nhcarrigan.com"
|
||||||
|
wip: false
|
||||||
|
- avatar: null
|
||||||
|
category: websites
|
||||||
|
description: Our custom script that injects our global styles and scripts into our websites.
|
||||||
|
name: Website Headers
|
||||||
|
premium: false
|
||||||
|
url: "https://cdn.nhcarrigan.com/headers/indexjs"
|
||||||
|
wip: false
|
||||||
|
- avatar: null
|
||||||
|
category: apps
|
||||||
|
description: Our custom TypeScript configuration.
|
||||||
|
name: TypeScript Config
|
||||||
|
premium: false
|
||||||
|
url: "https://www.npmjs.com/package/@nhcarrigan/typescript-config"
|
||||||
|
wip: false
|
||||||
|
- avatar: null
|
||||||
|
category: apps
|
||||||
|
description: Our custom logger library.
|
||||||
|
name: Logger
|
||||||
|
premium: false
|
||||||
|
url: "https://www.npmjs.com/package/@nhcarrigan/logger"
|
||||||
|
wip: false
|
||||||
|
- avatar: null
|
||||||
|
category: websites
|
||||||
|
description: A collection of static pages bundled via custom scripts.
|
||||||
|
name: Static Pages
|
||||||
|
premium: false
|
||||||
|
url: null
|
||||||
|
wip: false
|
||||||
|
- avatar: null
|
||||||
|
category: websites
|
||||||
|
description: A printable web version of our resume.
|
||||||
|
name: Resume
|
||||||
|
premium: false
|
||||||
|
url: "https://resume.nhcarrigan.com"
|
||||||
|
wip: false
|
||||||
|
- avatar: null
|
||||||
|
category: apps
|
||||||
|
description: An Isekai story, and our first paid game.
|
||||||
|
name: "Naomi's Adventure I: An Isekai Story"
|
||||||
|
premium: true
|
||||||
|
url: null
|
||||||
|
wip: true
|
||||||
@@ -0,0 +1,174 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/naming-convention -- We are dealing with repository names, which are in kebab-case */
|
||||||
|
/**
|
||||||
|
* @copyright NHCarrigan
|
||||||
|
* @license Naomi's Public License
|
||||||
|
* @author Naomi Carrigan
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { readFile } from "node:fs/promises";
|
||||||
|
import { join } from "node:path";
|
||||||
|
import { describe, expect, it } from "vitest";
|
||||||
|
import { parse } from "yaml";
|
||||||
|
import type { Projects } from "../src/interfaces/projects.js";
|
||||||
|
|
||||||
|
interface Repository {
|
||||||
|
id: number;
|
||||||
|
owner: {
|
||||||
|
id: number;
|
||||||
|
login: string;
|
||||||
|
login_name: string;
|
||||||
|
source_id: number;
|
||||||
|
full_name: string;
|
||||||
|
email: string;
|
||||||
|
avatar_url: string;
|
||||||
|
html_url: string;
|
||||||
|
language: string;
|
||||||
|
is_admin: boolean;
|
||||||
|
last_login: string;
|
||||||
|
created: string;
|
||||||
|
restricted: boolean;
|
||||||
|
active: boolean;
|
||||||
|
prohibit_login: boolean;
|
||||||
|
location: string;
|
||||||
|
website: string;
|
||||||
|
description: string;
|
||||||
|
visibility: string;
|
||||||
|
followers_count: number;
|
||||||
|
following_count: number;
|
||||||
|
starred_repos_count: number;
|
||||||
|
username: string;
|
||||||
|
};
|
||||||
|
name: string;
|
||||||
|
full_name: string;
|
||||||
|
description: string;
|
||||||
|
empty: boolean;
|
||||||
|
private: boolean;
|
||||||
|
fork: boolean;
|
||||||
|
template: boolean;
|
||||||
|
mirror: boolean;
|
||||||
|
size: number;
|
||||||
|
language: string;
|
||||||
|
languages_url: string;
|
||||||
|
html_url: string;
|
||||||
|
url: string;
|
||||||
|
link: string;
|
||||||
|
ssh_url: string;
|
||||||
|
clone_url: string;
|
||||||
|
original_url: string;
|
||||||
|
website: string;
|
||||||
|
stars_count: number;
|
||||||
|
forks_count: number;
|
||||||
|
watchers_count: number;
|
||||||
|
open_issues_count: number;
|
||||||
|
open_pr_counter: number;
|
||||||
|
release_counter: number;
|
||||||
|
default_branch: string;
|
||||||
|
archived: boolean;
|
||||||
|
created_at: string;
|
||||||
|
updated_at: string;
|
||||||
|
archived_at: string;
|
||||||
|
permissions: {
|
||||||
|
admin: boolean;
|
||||||
|
push: boolean;
|
||||||
|
pull: boolean;
|
||||||
|
};
|
||||||
|
has_issues: boolean;
|
||||||
|
internal_tracker: {
|
||||||
|
enable_time_tracker: boolean;
|
||||||
|
allow_only_contributors_to_track_time: boolean;
|
||||||
|
enable_issue_dependencies: boolean;
|
||||||
|
};
|
||||||
|
has_wiki: boolean;
|
||||||
|
has_pull_requests: boolean;
|
||||||
|
has_projects: boolean;
|
||||||
|
projects_mode: string;
|
||||||
|
has_releases: boolean;
|
||||||
|
has_packages: boolean;
|
||||||
|
has_actions: boolean;
|
||||||
|
ignore_whitespace_conflicts: boolean;
|
||||||
|
allow_merge_commits: boolean;
|
||||||
|
allow_rebase: boolean;
|
||||||
|
allow_rebase_explicit: boolean;
|
||||||
|
allow_squash_merge: boolean;
|
||||||
|
allow_fast_forward_only_merge: boolean;
|
||||||
|
allow_rebase_update: boolean;
|
||||||
|
default_delete_branch_after_merge: boolean;
|
||||||
|
default_merge_style: string;
|
||||||
|
default_allow_maintainer_edit: boolean;
|
||||||
|
avatar_url: string;
|
||||||
|
internal: boolean;
|
||||||
|
mirror_interval: string;
|
||||||
|
object_format_name: string;
|
||||||
|
mirror_updated: string;
|
||||||
|
topics: Array<unknown>;
|
||||||
|
licenses: Array<unknown>;
|
||||||
|
}
|
||||||
|
const getRepositories = async(): Promise<Array<Repository>> => {
|
||||||
|
const repos: Array<Repository> = [];
|
||||||
|
const orgs = [
|
||||||
|
"nhcarrigan",
|
||||||
|
"nhcarrigan-games",
|
||||||
|
];
|
||||||
|
for (const org of orgs) {
|
||||||
|
const response = await fetch(`https://git.nhcarrigan.com/api/v1/orgs/${org}/repos`);
|
||||||
|
const data = await response.json();
|
||||||
|
repos.push(...data);
|
||||||
|
}
|
||||||
|
return repos;
|
||||||
|
};
|
||||||
|
|
||||||
|
const repoNameMap = {
|
||||||
|
"a4p-bot": "Artists4Palestine Bot",
|
||||||
|
"beccalia-origins": "Beccalia: Origins",
|
||||||
|
"beccalia-prologue": "Beccalia: Prologue",
|
||||||
|
"blog": "Naomi's Blog",
|
||||||
|
"docs": "NHCarrigan Documentation",
|
||||||
|
"eslint-config": "ESLint Config",
|
||||||
|
"life-of-a-naomi": "Life of a Naomi",
|
||||||
|
"naomis-adventure-1": "Naomi's Adventure I: An Isekai Story",
|
||||||
|
"ruu-goblin-quest": "Ruu's Goblin Quest",
|
||||||
|
"typescript-config": "TypeScript Config",
|
||||||
|
"vscode-themes": "Naomi's VSCode Themes",
|
||||||
|
};
|
||||||
|
|
||||||
|
const excludedRepos = new Set<string>([
|
||||||
|
"template",
|
||||||
|
"espanso",
|
||||||
|
"rig-task-bot",
|
||||||
|
"security",
|
||||||
|
"nginx-configs",
|
||||||
|
".profile",
|
||||||
|
".gitea",
|
||||||
|
]);
|
||||||
|
|
||||||
|
const convertKebabCaseToTitleCase = (string_: string): string => {
|
||||||
|
return string_.replaceAll("-", " ").replaceAll(/\b\w/g, (char) => {
|
||||||
|
return char.toUpperCase();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
describe("projects data", () => {
|
||||||
|
it("should include all repositories", async() => {
|
||||||
|
expect.hasAssertions();
|
||||||
|
const repos = await getRepositories();
|
||||||
|
const data = await readFile(
|
||||||
|
join(import.meta.dirname, "..", "data", "projects.yml"),
|
||||||
|
"utf8",
|
||||||
|
);
|
||||||
|
const parsed = parse(data) as Projects;
|
||||||
|
expect(parsed, `Parsed projects data should be defined`).toBeDefined();
|
||||||
|
expect(Array.isArray(parsed), `Parsed projects data should be an array`).toBeTruthy();
|
||||||
|
expect(parsed.length, `There should be at least one project`).toBeGreaterThan(0);
|
||||||
|
for (const repo of repos) {
|
||||||
|
if (excludedRepos.has(repo.name)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const project = parsed.find((p) => {
|
||||||
|
return repo.name in repoNameMap
|
||||||
|
? p.name === repoNameMap[repo.name]
|
||||||
|
: p.name === convertKebabCaseToTitleCase(repo.name);
|
||||||
|
});
|
||||||
|
expect(project, `Project should be defined for repository ${convertKebabCaseToTitleCase(repo.name)}`).toBeDefined();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user