Diffinery

codician/diffinerypublic

Open-source, agent-first GitHub and GitHub Actions alternative that runs on your own Cloudflare account: git hosting, pull requests, code review and drop-in GitHub Actions YAML on Workers, Durable Objects, R2 and Containers.

89 lines · 9.2 KBRaw History
1import type { MailJob, Recipient, ThreadData } from "./types.js";
2
3/**
4 * One example of every email Diffinery sends, for the template gallery in site
5 * administration, the "send me every email" check and the template tests.
6 */
7export function sampleJobs(pub: string, to: Recipient, me: string, repo = "acme/website"): Array<{ id: string; label: string; job: MailJob }> {
8 const at = new Date().toISOString();
9 const repoId = "sample";
10 const thread = (over: Partial<ThreadData>): ThreadData => ({
11 repo,
12 repoId,
13 number: 42,
14 kind: "pull",
15 title: "Cache build artifacts between workflow runs",
16 event: "opened",
17 actor: "diffy-dev",
18 url: `${pub}/${repo}/pull/42`,
19 base: "main",
20 head: "cache-artifacts",
21 ...over,
22 });
23 const body = "This keeps `node_modules` and the build output in the Actions cache, keyed on the lockfile.\n\n- Cold build: **3m 40s**\n- Warm build: **48s**\n\nCloses #37. cc @" + me;
24 const item = (id: string, label: string, j: Omit<MailJob, "to" | "at">) => ({ id, label, job: { ...j, to, at } as MailJob });
25 const exp = new Date(Date.now() + 6 * 86400_000).toISOString();
26 return [
27 item("pr-opened", "Pull request opened", { kind: "thread", reason: "review_requested", data: thread({ body, intent: "Make CI twice as fast without changing what it tests.", reviewers: [me], commits: [{ sha: "3f9c2a1d8e7b6c5a4f3e2d1c0b9a8f7e6d5c4b3a", message: "Cache node_modules on the lockfile hash" }, { sha: "8a7b6c5d4e3f2a1b0c9d8e7f6a5b4c3d2e1f0a9b", message: "Cache the build output too" }] }) }),
28 item("issue-opened", "Issue opened (watching)", { kind: "thread", reason: "subscribed", data: thread({ kind: "issue", number: 37, title: "CI takes almost four minutes on every push", url: `${pub}/${repo}/issues/37`, body: "Every push reinstalls all dependencies. Could we cache them?", base: undefined, head: undefined }) }),
29 item("comment", "New comment (mention)", { kind: "thread", reason: "mention", data: thread({ event: "comment", actor: "rivera", body: `Looks good to me. @${me}, can you double-check the cache key on Windows runners?`, url: `${pub}/${repo}/pull/42#c-sample` }) }),
30 item("review-approved", "Review: approved", { kind: "thread", reason: "author", data: thread({ event: "review", state: "APPROVED", actor: "rivera", body: "Nice speed-up. Ship it." }) }),
31 item("review-changes", "Review: changes requested", { kind: "thread", reason: "author", data: thread({ event: "review", state: "CHANGES_REQUESTED", actor: "kim", body: "**.github/workflows/ci.yml:18**\n\nThe key should include the runner OS, or Linux and macOS caches will collide." }) }),
32 item("review-requested", "Review requested", { kind: "thread", reason: "review_requested", data: thread({ event: "review_requested", reviewers: [me], intent: "Make CI twice as fast without changing what it tests." }) }),
33 item("assigned", "Assigned", { kind: "thread", reason: "assign", data: thread({ kind: "issue", number: 37, title: "CI takes almost four minutes on every push", event: "assigned", assignees: [me], url: `${pub}/${repo}/issues/37` }) }),
34 item("pushed", "New commits pushed", { kind: "thread", reason: "comment", data: thread({ event: "pushed", commits: [{ sha: "c0ffee1d8e7b6c5a4f3e2d1c0b9a8f7e6d5c4b3a", message: "Include the runner OS in the cache key" }] }) }),
35 item("merged", "Pull request merged", { kind: "thread", reason: "author", data: thread({ event: "merged", actor: "kim" }) }),
36 item("closed", "Issue closed", { kind: "thread", reason: "author", data: thread({ kind: "issue", number: 37, title: "CI takes almost four minutes on every push", event: "closed", stateReason: "completed", url: `${pub}/${repo}/issues/37` }) }),
37 item("reopened", "Issue reopened", { kind: "thread", reason: "comment", data: thread({ kind: "issue", number: 37, title: "CI takes almost four minutes on every push", event: "reopened", url: `${pub}/${repo}/issues/37` }) }),
38 item("run-failed", "Workflow run failed", {
39 kind: "run",
40 reason: "ci_activity",
41 data: {
42 repo,
43 repoId,
44 runId: "sample",
45 runNumber: 318,
46 workflow: "CI",
47 title: "Cache node_modules on the lockfile hash",
48 conclusion: "failure",
49 event: "push",
50 branch: "main",
51 sha: "3f9c2a1d8e7b6c5a4f3e2d1c0b9a8f7e6d5c4b3a",
52 actor: me,
53 url: `${pub}/${repo}/actions/runs/sample`,
54 jobs: [
55 { name: "Typecheck and test", conclusion: "failure", url: `${pub}/${repo}/actions/runs/sample/job/1`, failure: "Process completed with exit code 1 (step: Unit tests)" },
56 { name: "Lint", conclusion: "success", url: `${pub}/${repo}/actions/runs/sample/job/2` },
57 { name: "Deploy", conclusion: "skipped", url: `${pub}/${repo}/actions/runs/sample/job/3` },
58 ],
59 },
60 }),
61 item("signin", "New sign-in", { kind: "signin_new", reason: "security_alert", data: { method: "passkey", device: "Safari on macOS", ip: "203.0.113.24", location: "Istanbul, TR", passkey: "MacBook Touch ID" } }),
62 item("passkey-added", "Passkey added", { kind: "passkey_added", reason: "security_alert", data: { name: "iPhone", via: "settings" } }),
63 item("passkey-removed", "Passkey removed", { kind: "passkey_removed", reason: "security_alert", data: { name: "Old YubiKey" } }),
64 item("token-created", "Access token created", { kind: "token_created", reason: "security_alert", data: { name: "laptop", scopes: ["write"] } }),
65 item("token-expiring", "Access token expiring", { kind: "token_expiring", reason: "security_alert", data: { name: "ci-deploy", prefix: "dfy_Ab12Cd", expiresAt: exp } }),
66 item("agent-created", "Agent added", { kind: "agent_created", reason: "security_alert", data: { agent: "review-bot" } }),
67 item("model-key-added", "Model key added", { kind: "model_key_added", reason: "security_alert", data: { provider: "Anthropic", hint: "x7Qa" } }),
68 item("deployment-review", "Deployment waiting for review", { kind: "deployment_review_requested", reason: "review_requested", data: { repo, environment: "production", workflow: "Deploy", runNumber: 128, title: "Release 2.4", branch: "main", sha: "4f1c2e9d0b7a6c5e3f2d1c0b9a8e7d6c5b4a3f2e", requestor: me, url: `${pub}/${repo}/actions/runs/sample` } }),
69 item("review-limit", "Agent review limit reached", { kind: "review_limit_reached", reason: "your_activity", data: { repo, limit: 50, pr: 42 } }),
70 item("push-bypassed", "Push protection bypassed", { kind: "push_bypassed", reason: "security_alert", data: { repo, pusher: me, kinds: ["AWS access key"], reason: "Fake key used by a test fixture", refs: ["refs/heads/main"] } }),
71 item("push-blocked", "Push blocked", { kind: "push_blocked", reason: "security_alert", data: { repo, kinds: ["GitHub token"], refs: ["refs/heads/feature"] } }),
72 item("commit-blocked", "Commit blocked", { kind: "push_blocked", reason: "security_alert", data: { repo, kinds: ["AWS access key"], paths: ["config.env"] } }),
73 item("account-disabled", "Account disabled", { kind: "account_status", reason: "account", data: { status: "disabled" } }),
74 item("account-enabled", "Account enabled", { kind: "account_status", reason: "account", data: { status: "active" } }),
75 item("invite-org", "Invitation (organization)", { kind: "invite", reason: "invitation", data: { inviter: me, url: `${pub}/invite/sample`, org: repo.split("/")[0], role: "member", expiresAt: exp } }),
76 item("invite-repo", "Invitation (repository)", { kind: "invite", reason: "invitation", data: { inviter: me, url: `${pub}/invite/sample`, repo, role: "write", expiresAt: exp } }),
77 item("invite-account", "Invitation (by username)", { kind: "invite", reason: "invitation", data: { inviter: me, url: `${pub}/settings/invitations`, repo, role: "write", expiresAt: exp, existing: true } }),
78 item("invite-accepted", "Invitation accepted", { kind: "invite_accepted", reason: "account", data: { login: "rivera", email: "rivera@example.com", org: repo.split("/")[0] } }),
79 item("welcome", "Welcome", { kind: "welcome", reason: "account", data: { login: me } }),
80 item("signin-link", "Sign-in link", { kind: "signin_link", reason: "account", data: { url: `${pub}/signin/sample`, admin: "admin", expiresAt: new Date(Date.now() + 86400_000).toISOString() } }),
81 item("access-request", "Access request", { kind: "access_request", reason: "admin", data: { email: "newcomer@example.com", login: "newcomer", note: "I'm joining the platform team next week." } }),
82 item("org-member", "Organization membership", { kind: "org_membership", reason: "account", data: { org: repo.split("/")[0]!, role: "admin", previous: "member", by: "diffy-dev" } }),
83 item("repo-access", "Repository access", { kind: "repo_access", reason: "account", data: { repo, role: "write", previous: null } }),
84 item("repo-created", "Repository created", { kind: "repo_created", reason: "your_activity", data: { repo, creator: me, visibility: "private", defaultBranch: "main", description: "Marketing site" } }),
85 item("repo-deleted", "Repository deleted", { kind: "repo_deleted", reason: "admin", data: { repo, actor: "kim" } }),
86 item("repo-transferred", "Repository transferred", { kind: "repo_transferred", reason: "admin", data: { from: `${me}/${repo.split("/")[1]}`, to: repo, actor: "kim" } }),
87 item("test", "Test email", { kind: "test", reason: "account", data: { by: me } }),
88 ];
89}