Skip to content

Commit 68df959

Browse files
authored
feat(changelog): added changelog and gh action to auto-release (#1423)
* feat(changelog): added changelog * finished changelog * updated metadata * reverted env * cleanup --------- Co-authored-by: waleed <waleed>
1 parent 760219d commit 68df959

File tree

14 files changed

+911
-9
lines changed

14 files changed

+911
-9
lines changed

apps/sim/app/(landing)/actions/github.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { createLogger } from '@/lib/logs/console/logger'
22

3-
const DEFAULT_STARS = '15k'
3+
const DEFAULT_STARS = '15.4k'
44

55
const logger = createLogger('GitHubStars')
66

apps/sim/app/(landing)/components/footer/footer.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,12 @@ export default function Footer({ fullWidth = false }: FooterProps) {
214214
>
215215
Enterprise
216216
</Link>
217+
<Link
218+
href='/changelog'
219+
className='text-[14px] text-muted-foreground transition-colors hover:text-foreground'
220+
>
221+
Changelog
222+
</Link>
217223
<Link
218224
href='/privacy'
219225
target='_blank'

apps/sim/app/(landing)/components/nav/nav.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ interface NavProps {
2020
}
2121

2222
export default function Nav({ hideAuthButtons = false, variant = 'landing' }: NavProps = {}) {
23-
const [githubStars, setGithubStars] = useState('15k')
23+
const [githubStars, setGithubStars] = useState('15.4k')
2424
const [isHovered, setIsHovered] = useState(false)
2525
const [isLoginHovered, setIsLoginHovered] = useState(false)
2626
const router = useRouter()
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import { NextResponse } from 'next/server'
2+
3+
export const dynamic = 'force-static'
4+
export const revalidate = 3600
5+
6+
interface Release {
7+
id: number
8+
tag_name: string
9+
name: string
10+
body: string
11+
html_url: string
12+
published_at: string
13+
prerelease: boolean
14+
}
15+
16+
function escapeXml(str: string) {
17+
return str
18+
.replace(/&/g, '&amp;')
19+
.replace(/</g, '&lt;')
20+
.replace(/>/g, '&gt;')
21+
.replace(/"/g, '&quot;')
22+
.replace(/'/g, '&apos;')
23+
}
24+
25+
export async function GET() {
26+
try {
27+
const res = await fetch('https://api.github.com/repos/simstudioai/sim/releases', {
28+
headers: { Accept: 'application/vnd.github+json' },
29+
next: { revalidate },
30+
})
31+
const releases: Release[] = await res.json()
32+
const items = (releases || [])
33+
.filter((r) => !r.prerelease)
34+
.map(
35+
(r) => `
36+
<item>
37+
<title>${escapeXml(r.name || r.tag_name)}</title>
38+
<link>${r.html_url}</link>
39+
<guid isPermaLink="true">${r.html_url}</guid>
40+
<pubDate>${new Date(r.published_at).toUTCString()}</pubDate>
41+
<description><![CDATA[${r.body || ''}]]></description>
42+
</item>
43+
`
44+
)
45+
.join('')
46+
47+
const xml = `<?xml version="1.0" encoding="UTF-8" ?>
48+
<rss version="2.0">
49+
<channel>
50+
<title>Sim Changelog</title>
51+
<link>https://sim.dev/changelog</link>
52+
<description>Latest changes, fixes and updates in Sim.</description>
53+
<language>en-us</language>
54+
${items}
55+
</channel>
56+
</rss>`
57+
58+
return new NextResponse(xml, {
59+
status: 200,
60+
headers: {
61+
'Content-Type': 'application/rss+xml; charset=utf-8',
62+
'Cache-Control': `public, s-maxage=${revalidate}, stale-while-revalidate=${revalidate}`,
63+
},
64+
})
65+
} catch {
66+
return new NextResponse('Service Unavailable', { status: 503 })
67+
}
68+
}
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
import { BookOpen, Github, Rss } from 'lucide-react'
2+
import Link from 'next/link'
3+
import { inter } from '@/app/fonts/inter'
4+
import { soehne } from '@/app/fonts/soehne/soehne'
5+
import ChangelogList from './timeline-list'
6+
7+
export interface ChangelogEntry {
8+
tag: string
9+
title: string
10+
content: string
11+
date: string
12+
url: string
13+
contributors?: string[]
14+
}
15+
16+
function extractMentions(body: string): string[] {
17+
const matches = body.match(/@([A-Za-z0-9-]+)/g) ?? []
18+
const uniq = Array.from(new Set(matches.map((m) => m.slice(1))))
19+
return uniq
20+
}
21+
22+
export default async function ChangelogContent() {
23+
let entries: ChangelogEntry[] = []
24+
25+
try {
26+
const res = await fetch(
27+
'https://api.github.com/repos/simstudioai/sim/releases?per_page=10&page=1',
28+
{
29+
headers: { Accept: 'application/vnd.github+json' },
30+
next: { revalidate: 3600 },
31+
}
32+
)
33+
const releases: any[] = await res.json()
34+
entries = (releases || [])
35+
.filter((r) => !r.prerelease)
36+
.map((r) => ({
37+
tag: r.tag_name,
38+
title: r.name || r.tag_name,
39+
content: String(r.body || ''),
40+
date: r.published_at,
41+
url: r.html_url,
42+
contributors: extractMentions(String(r.body || '')),
43+
}))
44+
} catch (err) {
45+
entries = []
46+
}
47+
48+
return (
49+
<div className='min-h-screen bg-background'>
50+
<div className='relative grid md:grid-cols-2'>
51+
{/* Left intro panel */}
52+
<div className='relative top-0 overflow-hidden border-border border-b px-6 py-16 sm:px-10 md:sticky md:h-dvh md:border-r md:border-b-0 md:px-12 md:py-24'>
53+
<div className='absolute inset-0 bg-grid-pattern opacity-[0.03] dark:opacity-[0.06]' />
54+
<div className='absolute inset-0 bg-gradient-to-tr from-background via-transparent to-background/60' />
55+
56+
<div className='relative mx-auto h-full max-w-xl md:flex md:flex-col md:justify-center'>
57+
<h1
58+
className={`${soehne.className} mt-6 font-semibold text-4xl tracking-tight sm:text-5xl`}
59+
>
60+
Changelog
61+
</h1>
62+
<p className={`${inter.className} mt-4 text-muted-foreground text-sm`}>
63+
Stay up-to-date with the latest features, improvements, and bug fixes in Sim. All
64+
changes are documented here with detailed release notes.
65+
</p>
66+
<hr className='mt-6 border-border' />
67+
68+
<div className='mt-6 flex flex-wrap items-center gap-3 text-sm'>
69+
<Link
70+
href='https://github.com/simstudioai/sim/releases'
71+
target='_blank'
72+
rel='noopener noreferrer'
73+
className='group inline-flex items-center justify-center gap-2 rounded-[10px] border border-[#6F3DFA] bg-gradient-to-b from-[#8357FF] to-[#6F3DFA] py-[6px] pr-[10px] pl-[12px] text-[14px] text-white shadow-[inset_0_2px_4px_0_#9B77FF] transition-all sm:text-[16px]'
74+
>
75+
<Github className='h-4 w-4' />
76+
View on GitHub
77+
</Link>
78+
<Link
79+
href='https://docs.sim.ai'
80+
className='inline-flex items-center gap-2 rounded-md border border-border px-3 py-1.5 hover:bg-muted'
81+
>
82+
<BookOpen className='h-4 w-4' />
83+
Documentation
84+
</Link>
85+
<Link
86+
href='/changelog.xml'
87+
className='inline-flex items-center gap-2 rounded-md border border-border px-3 py-1.5 hover:bg-muted'
88+
>
89+
<Rss className='h-4 w-4' />
90+
RSS Feed
91+
</Link>
92+
</div>
93+
</div>
94+
</div>
95+
96+
{/* Right timeline */}
97+
<div className='relative px-4 py-10 sm:px-6 md:px-8 md:py-12'>
98+
<div className='relative max-w-2xl pl-8'>
99+
<ChangelogList initialEntries={entries} />
100+
</div>
101+
</div>
102+
</div>
103+
</div>
104+
)
105+
}

0 commit comments

Comments
 (0)