Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add link and slack badges #37

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions projects-dashboard/src/components/ProjectBadge.astro
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,9 @@ type Props = {
badge: Badge;
};

const {
repo,
badge: { type, label, value },
} = Astro.props;
const { repo, badge } = Astro.props;

const [badgeSrc, href] = getBadgeInfo(repo, type, label, value);
const [badgeSrc, href] = getBadgeInfo(repo, badge);
---

<div class="project-badge">
Expand Down
22 changes: 13 additions & 9 deletions projects-dashboard/src/components/ProjectDetails.astro
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ const {

<div class="project-details">
<div class="project-details-header">
<h3 id={`${repo.owner}_${repo.name}`}>{title ?? repo.name}</h3>
<h3 id={`${repo.owner}_${repo.name}_${repo.subPath ?? ""}`}>
{title ?? repo.name}
</h3>
<BrandingLogo branding={branding} />
</div>
<div class="project-details-header-badges">
Expand Down Expand Up @@ -56,14 +58,16 @@ const {
</div>
<p>
{description}
{website && (
<>
<br />
<a href={website} target="_blank">
<small>{website}</small>
</a>
</>
)}
{
website && (
<>
<br />
<a href={website} target="_blank">
<small>{website}</small>
</a>
</>
)
}
</p>
<div class="project-details-cards-grid">
{
Expand Down
4 changes: 4 additions & 0 deletions projects-dashboard/src/content/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const repoSchema = z.object({
owner: z.string(),
name: z.string(),
mainBranch: z.string().optional(),
subPath: z.string().optional(),
});

export type Repo = z.infer<typeof repoSchema>;
Expand Down Expand Up @@ -68,13 +69,16 @@ const badgeTypeSchema = z.enum([
"discord",
"mailing-list",
"github-discussions",
"slack",
"link",
]);

export type BadgeType = z.infer<typeof badgeTypeSchema>;
const badgeSchema = z.object({
type: badgeTypeSchema,
label: z.string().optional(),
value: z.string().optional(),
token: z.string().optional(),
});

export type Badge = z.infer<typeof badgeSchema>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ securityScans:
- type: "fossa-security"
tests:
- type: "codecov"
token: "YI87CKF1LI"
packages:
- packageName: "xyz.block.tbdex"
repoPath: "bound/kt"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ scoreCards:
- type: "ossf"
tests:
- type: "codecov"
token: "YI87CKF1LI"
- type: "tbd-vectors"
contributing:
- type: "code-of-conduct"
Expand Down
104 changes: 81 additions & 23 deletions projects-dashboard/src/lib/badge.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
import type { BadgeType } from "../content/config";
import type { Badge, Repo } from "../content/config";

interface Repo {
owner: string;
name: string;
mainBranch?: string;
interface DefaultBadgeOptions {
label: string;
value?: string;
logo?: string;
color?: string;
}

function getDefaultBadgeSource(
type: string,
label: string,
value: string
): string {
return `https://img.shields.io/${type}/${label}-${value}-purple?style=flat-square`;
function getDefaultBadgeSource({
label,
value,
logo,
color = "purple",
}: DefaultBadgeOptions): string {
const cleanLabel = label.replaceAll("-", "--");
const cleanValue = value?.replaceAll("-", "--");
const valueParam = cleanValue ? `-${cleanValue}` : "";
const logoParam = logo ? `&logo=${logo}` : "";
return `https://img.shields.io/badge/${cleanLabel}${valueParam}-${color}?style=flat-square${logoParam}`;
}

function getGithubActionsBadge(
Expand Down Expand Up @@ -53,9 +59,9 @@ function getOssfBadge(repo: Repo): [string, string] {
return [badgeSrc, href];
}

function getCodecovBadge(repo: Repo): [string, string] {
function getCodecovBadge(repo: Repo, token?: string): [string, string] {
const branch = repo.mainBranch ?? "main";
const badgeSrc = `https://img.shields.io/codecov/c/gh/${repo.owner}/${repo.name}/${branch}?label=codecov&style=flat-square&token=YI87CKF1LI`;
const badgeSrc = `https://img.shields.io/codecov/c/gh/${repo.owner}/${repo.name}/${branch}?label=codecov&style=flat-square&token=${token}`;
const href = `https://codecov.io/github/${repo.owner}/${repo.name}`;
return [badgeSrc, href];
}
Expand Down Expand Up @@ -177,10 +183,16 @@ function getLifeCycleStatusBadge(value?: string): [string, string] {
}

function getGithubRepoBadge(repo: Repo): [string, string] {
const badgeValue = `${repo.owner}/${repo.name.replaceAll("-", "--")}`;
const cleanName = repo.name.replaceAll("-", "--");
const cleanSubPath = repo.subPath ? `/${repo.subPath.replaceAll("-", "--")}` : "";
const badgeValue = `${repo.owner}/${cleanName}${cleanSubPath}`;
const badgeColor = "gray";
const badgeSrc = `https://img.shields.io/badge/-${badgeValue}-${badgeColor}?style=flat-square&logo=github`;
const href = `https://github.com/${repo.owner}/${repo.name}`;

const branch = repo.mainBranch ?? "main";
const subPathUrlSuffix = repo.subPath ? `/tree/${branch}/${repo.subPath}` : "";
const href = `https://github.com/${repo.owner}/${repo.name}${subPathUrlSuffix}`;

return [badgeSrc, href];
}

Expand All @@ -196,12 +208,57 @@ function getIssuesBadge(repo: Repo): [string, string] {
return [badgeSrc, href];
}

function getSlackBadge(label?: string, value?: string): [string, string] {
if (!value) {
throw new Error("Slack URL is required for badge");
}

if (!label) {
throw new Error("Slack channel is required for badge");
}

if (!label.startsWith("#")) {
throw new Error("Slack channel, in the label field, must start with '#' for badge");
}

const channel = `%23${label.slice(1)}`;

const badgeSrc = getDefaultBadgeSource({
label: "slack",
value: channel,
color: "blue",
logo: "slack",
});

const href = value;
return [badgeSrc, href];
}

function getLinkBadge(label?: string, value?: string): [string, string] {
if (!value) {
throw new Error("Link URL is required for badge");
}

if (!label) {
throw new Error("Link label is required for badge");
}

const badgeSrc = getDefaultBadgeSource({
label,
color: "purple",
});
const href = value;
return [badgeSrc, href];
}

export function getBadgeInfo(
repo: Repo,
type: BadgeType,
label?: string,
value?: string
badge: Badge,
): [string, string] {
let { type, label, value, token } = badge;

// cleanup invalid badge characters

switch (type) {
case "github-actions":
return getGithubActionsBadge(repo, value, label);
Expand All @@ -216,7 +273,7 @@ export function getBadgeInfo(
case "ossf":
return getOssfBadge(repo);
case "codecov":
return getCodecovBadge(repo);
return getCodecovBadge(repo, token);
case "tbd-vectors":
return getTbdVectorsBadge(repo);
case "npm":
Expand Down Expand Up @@ -245,10 +302,11 @@ export function getBadgeInfo(
return getIssuesBadge(repo);
case "github-discussions":
return getGithubDiscussionsBadge(repo);
case "slack":
return getSlackBadge(label, value);
case "link":
return getLinkBadge(label, value);
default:
return [
getDefaultBadgeSource(type, label ?? "badge", value ?? "value"),
"",
];
throw new Error(`Unknown badge type: ${type}`);
}
}
2 changes: 1 addition & 1 deletion projects-dashboard/src/pages/index.astro
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ projects.sort((a, b) => {
<ul class="projects-list">
{projects.filter(project => project.data.repo.owner === org).map(({data: project}) => (
<li>
<a href={`#${project.repo.owner}_${project.repo.name}`}>
<a href={`#${project.repo.owner}_${project.repo.name}_${project.repo.subPath ?? ""}`}>
{project.title ?? project.repo.name}
</a>
</li>
Expand Down
Loading