chore: auto-fix lint & formatting [skip ci]

This commit is contained in:
github-actions[bot] 2026-08-14 00:51:23 +00:00
parent 3f6f7f17b5
commit c58b800987
6 changed files with 112 additions and 77 deletions

View file

@ -72,7 +72,11 @@
<option value="github">GitHub</option> <option value="github">GitHub</option>
<option value="gitea">Gitea</option> <option value="gitea">Gitea</option>
</select> </select>
<button type="button" class="icon-btn danger" @click="form.forgeSources.splice(i, 1)"> <button
type="button"
class="icon-btn danger"
@click="form.forgeSources.splice(i, 1)"
>
</button> </button>
<input <input

View file

@ -62,11 +62,13 @@ A group may set `logTarget` to a Discord channel/thread or Telegram chat/topic.
A group defines the forges it receives events from via `forgeSources`, a list of `{ host, type, name? }` entries (`type` is `github` or `gitea`). Every message this group's routes send carries the footer label of the **first entry whose type matches the event's provider and whose host matches the repository URL's hostname** (GitHub events match `github.com`). The label is the entry's optional `name` — falling back to the host — so two self-hosted Gitea instances can be shown as "内网 Gitea" / "Git2 仓库" while matched by their distinct hosts: A group defines the forges it receives events from via `forgeSources`, a list of `{ host, type, name? }` entries (`type` is `github` or `gitea`). Every message this group's routes send carries the footer label of the **first entry whose type matches the event's provider and whose host matches the repository URL's hostname** (GitHub events match `github.com`). The label is the entry's optional `name` — falling back to the host — so two self-hosted Gitea instances can be shown as "内网 Gitea" / "Git2 仓库" while matched by their distinct hosts:
```json ```json
{ "forgeSources": [ {
"forgeSources": [
{ "host": "github.com", "type": "github", "name": "GitHub 主站" }, { "host": "github.com", "type": "github", "name": "GitHub 主站" },
{ "host": "git1.example.com", "type": "gitea", "name": "内网 Gitea" }, { "host": "git1.example.com", "type": "gitea", "name": "内网 Gitea" },
{ "host": "git2.example.com", "type": "gitea" } { "host": "git2.example.com", "type": "gitea" }
] } ]
}
``` ```
- **Discord** — the embed footer shows the label next to the repo (`内网 Gitea · acme/widget`) with the site's favicon as the footer icon (derived from the repository URL). - **Discord** — the embed footer shows the label next to the repo (`内网 Gitea · acme/widget`) with the site's favicon as the footer icon (derived from the repository URL).

View file

@ -62,11 +62,13 @@
分组通过 `forgeSources` 定义自己接收事件的 forge即一组 `{ host, type, name? }` 条目(`type``github``gitea`)。该分组路由发出的每条消息都会使用**与事件来源类型匹配、且 host 与仓库 URL 主机名一致的第一条**配置作为底部标识GitHub 事件匹配 `github.com`)。标识文本为条目的可选 `name`——未填则回退为 host——因此两个自建 Gitea 实例可以显示为「内网 Gitea」/「Git2 仓库」,同时通过各自主机名完成匹配: 分组通过 `forgeSources` 定义自己接收事件的 forge即一组 `{ host, type, name? }` 条目(`type``github``gitea`)。该分组路由发出的每条消息都会使用**与事件来源类型匹配、且 host 与仓库 URL 主机名一致的第一条**配置作为底部标识GitHub 事件匹配 `github.com`)。标识文本为条目的可选 `name`——未填则回退为 host——因此两个自建 Gitea 实例可以显示为「内网 Gitea」/「Git2 仓库」,同时通过各自主机名完成匹配:
```json ```json
{ "forgeSources": [ {
"forgeSources": [
{ "host": "github.com", "type": "github", "name": "GitHub 主站" }, { "host": "github.com", "type": "github", "name": "GitHub 主站" },
{ "host": "git1.example.com", "type": "gitea", "name": "内网 Gitea" }, { "host": "git1.example.com", "type": "gitea", "name": "内网 Gitea" },
{ "host": "git2.example.com", "type": "gitea" } { "host": "git2.example.com", "type": "gitea" }
] } ]
}
``` ```
- **Discord** — embed 底部在仓库名旁显示标识(`内网 Gitea · acme/widget`),并以按仓库 URL 推导的站点 favicon 作为底部图标。 - **Discord** — embed 底部在仓库名旁显示标识(`内网 Gitea · acme/widget`),并以按仓库 URL 推导的站点 favicon 作为底部图标。

View file

@ -169,10 +169,7 @@ export function senderProfileUrl(repoUrl: string | undefined, login: string): st
* entry's display `name` (or its host when no name is set). Link/favicon are * entry's display `name` (or its host when no name is set). Link/favicon are
* derived from the repository URL. * derived from the repository URL.
*/ */
export function forgeInfo( export function forgeInfo(event: WebhookEvent, sources?: ForgeSource[]): NeutralForge | undefined {
event: WebhookEvent,
sources?: ForgeSource[],
): NeutralForge | undefined {
const repoUrl = (event.payload.repository as { html_url?: string } | undefined)?.html_url; const repoUrl = (event.payload.repository as { html_url?: string } | undefined)?.html_url;
let host: string | undefined; let host: string | undefined;
if (repoUrl) { if (repoUrl) {
@ -186,9 +183,7 @@ export function forgeInfo(
if (!host && event.provider === "github") host = "github.com"; if (!host && event.provider === "github") host = "github.com";
if (!host) return undefined; if (!host) return undefined;
const source = sources?.find( const source = sources?.find((s) => s.type === event.provider && s.host.toLowerCase() === host);
(s) => s.type === event.provider && s.host.toLowerCase() === host,
);
if (!source) return undefined; if (!source) return undefined;
const label = source.name?.trim() || source.host; const label = source.name?.trim() || source.host;

View file

@ -36,7 +36,8 @@ import { log } from "../lib/log";
const VALID_FILTER_TYPES = new Set(["event", "repo", "actor", "action", "branch", "keyword"]); const VALID_FILTER_TYPES = new Set(["event", "repo", "actor", "action", "branch", "keyword"]);
const ID_RE = /^[a-z0-9][a-z0-9-]*$/; const ID_RE = /^[a-z0-9][a-z0-9-]*$/;
const HOST_RE = /^[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?)*$/; const HOST_RE =
/^[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?)*$/;
function isValidMatch(match: unknown): match is string | string[] { function isValidMatch(match: unknown): match is string | string[] {
if (typeof match === "string") return match.trim().length > 0; if (typeof match === "string") return match.trim().length > 0;
@ -328,10 +329,7 @@ export function validateGroups(
error: `group "${g.id}".forgeSources[${i}].type must be "github" | "gitea"`, error: `group "${g.id}".forgeSources[${i}].type must be "github" | "gitea"`,
}; };
} }
if ( if (s.name !== undefined && (typeof s.name !== "string" || s.name.length > 50)) {
s.name !== undefined &&
(typeof s.name !== "string" || s.name.length > 50)
) {
return { return {
ok: false, ok: false,
error: `group "${g.id}".forgeSources[${i}].name must be a string`, error: `group "${g.id}".forgeSources[${i}].name must be a string`,

View file

@ -525,7 +525,11 @@ describe("forge source branding", () => {
it("labels github events with the configured host and the github favicon", () => { it("labels github events with the configured host and the github favicon", () => {
expect( expect(
forgeInfo( forgeInfo(
{ event: "push", provider: "github", payload: { repository: { html_url: "https://github.com/org/repo" } } }, {
event: "push",
provider: "github",
payload: { repository: { html_url: "https://github.com/org/repo" } },
},
[ghHost], [ghHost],
), ),
).toEqual({ ).toEqual({
@ -536,9 +540,7 @@ describe("forge source branding", () => {
}); });
it("labels github events without a repository (ping) via the github.com fallback", () => { it("labels github events without a repository (ping) via the github.com fallback", () => {
expect( expect(forgeInfo({ event: "ping", provider: "github", payload: {} }, [ghHost])).toEqual({
forgeInfo({ event: "ping", provider: "github", payload: {} }, [ghHost]),
).toEqual({
name: "github.com", name: "github.com",
url: "https://github.com", url: "https://github.com",
iconUrl: "https://github.com/favicon.ico", iconUrl: "https://github.com/favicon.ico",
@ -552,7 +554,11 @@ describe("forge source branding", () => {
]; ];
expect( expect(
forgeInfo( forgeInfo(
{ event: "push", provider: "gitea", payload: { repository: { html_url: "https://git1.example.com/org/a" } } }, {
event: "push",
provider: "gitea",
payload: { repository: { html_url: "https://git1.example.com/org/a" } },
},
sources, sources,
), ),
).toEqual({ ).toEqual({
@ -562,7 +568,11 @@ describe("forge source branding", () => {
}); });
expect( expect(
forgeInfo( forgeInfo(
{ event: "push", provider: "gitea", payload: { repository: { html_url: "https://git2.example.com/org/b" } } }, {
event: "push",
provider: "gitea",
payload: { repository: { html_url: "https://git2.example.com/org/b" } },
},
sources, sources,
), ),
).toEqual({ ).toEqual({
@ -579,7 +589,11 @@ describe("forge source branding", () => {
]; ];
expect( expect(
forgeInfo( forgeInfo(
{ event: "push", provider: "gitea", payload: { repository: { html_url: "https://git1.example.com/org/a" } } }, {
event: "push",
provider: "gitea",
payload: { repository: { html_url: "https://git1.example.com/org/a" } },
},
sources, sources,
), ),
).toEqual({ ).toEqual({
@ -589,7 +603,11 @@ describe("forge source branding", () => {
}); });
expect( expect(
forgeInfo( forgeInfo(
{ event: "push", provider: "gitea", payload: { repository: { html_url: "https://git2.example.com/org/b" } } }, {
event: "push",
provider: "gitea",
payload: { repository: { html_url: "https://git2.example.com/org/b" } },
},
sources, sources,
), ),
).toEqual({ ).toEqual({
@ -599,7 +617,11 @@ describe("forge source branding", () => {
}); });
expect( expect(
forgeInfo( forgeInfo(
{ event: "push", provider: "gitea", payload: { repository: { html_url: "https://git1.example.com/org/a" } } }, {
event: "push",
provider: "gitea",
payload: { repository: { html_url: "https://git1.example.com/org/a" } },
},
[{ host: "git1.example.com", type: "gitea", name: " " }], [{ host: "git1.example.com", type: "gitea", name: " " }],
), ),
).toEqual({ ).toEqual({
@ -612,7 +634,11 @@ describe("forge source branding", () => {
it("matches hosts case-insensitively", () => { it("matches hosts case-insensitively", () => {
expect( expect(
forgeInfo( forgeInfo(
{ event: "push", provider: "gitea", payload: { repository: { html_url: "https://GIT1.Example.COM/org/a" } } }, {
event: "push",
provider: "gitea",
payload: { repository: { html_url: "https://GIT1.Example.COM/org/a" } },
},
[{ host: "Git1.Example.com", type: "gitea" }], [{ host: "Git1.Example.com", type: "gitea" }],
), ),
).toEqual({ ).toEqual({
@ -624,7 +650,9 @@ describe("forge source branding", () => {
it("returns no label when the gitea repo url is missing or unparseable", () => { it("returns no label when the gitea repo url is missing or unparseable", () => {
expect( expect(
forgeInfo({ event: "push", provider: "gitea", payload: {} }, [{ host: "git1.example.com", type: "gitea" }]), forgeInfo({ event: "push", provider: "gitea", payload: {} }, [
{ host: "git1.example.com", type: "gitea" },
]),
).toBeUndefined(); ).toBeUndefined();
expect( expect(
forgeInfo( forgeInfo(
@ -635,10 +663,16 @@ describe("forge source branding", () => {
}); });
it("returns undefined when no source matches the provider or host", () => { it("returns undefined when no source matches the provider or host", () => {
expect(forgeInfo({ event: "custom", provider: "custom", payload: {} }, [ghHost])).toBeUndefined(); expect(
forgeInfo({ event: "custom", provider: "custom", payload: {} }, [ghHost]),
).toBeUndefined();
expect( expect(
forgeInfo( forgeInfo(
{ event: "push", provider: "gitea", payload: { repository: { html_url: "https://other.example.com/org/a" } } }, {
event: "push",
provider: "gitea",
payload: { repository: { html_url: "https://other.example.com/org/a" } },
},
[ghHost], [ghHost],
), ),
).toBeUndefined(); ).toBeUndefined();