Skip to content

Commit ae7577d

Browse files
updates
1 parent 6b424ba commit ae7577d

2 files changed

Lines changed: 145 additions & 97 deletions

File tree

.github/workflows/preview-deploy.yml

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,22 @@ jobs:
111111
if: steps.pr-metadata.outputs.deploy_storybook == 'true'
112112
run: yarn nx run storybook:build
113113

114-
# Build selector page (BEFORE checking out gh-pages)
114+
# Check if selector has changes
115+
- name: Check selector changes
116+
id: check-selector
117+
run: |
118+
# Check if any files in apps/preview-selector/ changed
119+
if git diff --name-only ${{ github.event.pull_request.base.sha || 'origin/master' }} HEAD | grep -q '^apps/preview-selector/'; then
120+
echo "selector_changed=true" >> $GITHUB_OUTPUT
121+
echo "✅ Selector has changes, will rebuild"
122+
else
123+
echo "selector_changed=false" >> $GITHUB_OUTPUT
124+
echo "⏭️ Selector unchanged, will skip rebuild"
125+
fi
126+
127+
# Build selector page (only if it has changes)
115128
- name: Build selector page
129+
if: steps.check-selector.outputs.selector_changed == 'true'
116130
run: yarn nx run preview-selector:build
117131

118132
# Checkout gh-pages branch to separate directory
@@ -145,12 +159,18 @@ jobs:
145159
echo "✅ Storybook copied"
146160
fi
147161
148-
cp -r apps/preview-selector/dist/* gh-pages-checkout/
162+
# Copy selector if it was rebuilt
163+
if [ "${{ steps.check-selector.outputs.selector_changed }}" = "true" ]; then
164+
echo "Updating selector..."
165+
cp -r apps/preview-selector/dist/* gh-pages-checkout/
166+
echo "✅ Selector updated"
167+
else
168+
echo "⏭️ Selector unchanged, keeping existing version"
169+
fi
149170
150171
if [ ! -f "gh-pages-checkout/manifest.json" ]; then
151172
echo '{"previews":[],"lastUpdated":"'$(date -u +%Y-%m-%dT%H:%M:%S.000Z)'"}' > gh-pages-checkout/manifest.json
152173
fi
153-
echo "✅ Selector deployed"
154174
155175
# Update manifest
156176
- name: Update manifest
@@ -198,33 +218,33 @@ jobs:
198218
const prNumber = ${{ steps.pr-metadata.outputs.pr_number }};
199219
const deployDocs = '${{ steps.pr-metadata.outputs.deploy_docs }}' === 'true';
200220
const deployStorybook = '${{ steps.pr-metadata.outputs.deploy_storybook }}' === 'true';
201-
221+
202222
const docsUrl = `https://coinbase.github.io/cds/pr-${prNumber}/docs/`;
203223
const storybookUrl = `https://coinbase.github.io/cds/pr-${prNumber}/storybook/`;
204-
224+
205225
let previewLinks = '';
206226
if (deployDocs) {
207227
previewLinks += `\n📄 **Documentation:** [View Docs →](${docsUrl})`;
208228
}
209229
if (deployStorybook) {
210230
previewLinks += `\n📚 **Storybook:** [View Storybook →](${storybookUrl})`;
211231
}
212-
232+
213233
if (!deployDocs && !deployStorybook) {
214234
console.log('No previews deployed, skipping comment');
215235
return;
216236
}
217-
237+
218238
const comment = `## 🚀 Preview${deployDocs && deployStorybook ? 's' : ''} Deployed
219-
239+
220240
Your preview${deployDocs && deployStorybook ? 's are' : ' is'} ready!
221241
${previewLinks}
222-
242+
223243
---
224-
244+
225245
📝 Updated: \`${new Date().toISOString()}\`
226246
🔨 Commit: \`${{ steps.pr-metadata.outputs.pr_commit }}\`
227-
247+
228248
> Preview${deployDocs && deployStorybook ? 's' : ''} will be automatically removed when the PR is closed.
229249
> To change what's deployed, edit the checkboxes in the PR description.`;
230250

apps/preview-selector/src/App.tsx

Lines changed: 114 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import { SelectChip } from '@coinbase/cds-web/alpha/select-chip';
1010
import { formatRelativeTime } from './utils';
1111
import { MediaQueryProvider } from '@coinbase/cds-web/system';
1212
import { Icon } from '@coinbase/cds-web/icons/Icon';
13+
import { Tag } from '@coinbase/cds-web/tag';
14+
import { Tooltip } from '@coinbase/cds-web/overlays/tooltip/Tooltip';
1315

1416
function App() {
1517
const [manifest, setManifest] = useState<Manifest | null>(null);
@@ -74,52 +76,50 @@ function App() {
7476
return (
7577
<MediaQueryProvider>
7678
<ThemeProvider theme={defaultTheme} activeColorScheme="light">
77-
<VStack width="100%" padding={{ base: 6, phone: 4 }} gap={6}>
78-
<VStack gap={6} width="100%" maxWidth={800} style={{ margin: '0 auto'}}>
79-
<Header />
79+
<VStack width="100%" padding={{ base: 6, phone: 4 }} gap={6}>
80+
<VStack gap={6} width="100%" maxWidth={800} style={{ margin: '0 auto' }}>
81+
<Header />
8082

81-
{loading && <LoadingState />}
82-
{error && <ErrorState />}
83-
{!loading && !error && (!manifest || manifest.previews.length === 0) && (
84-
<EmptyState />
85-
)}
83+
{loading && <LoadingState />}
84+
{error && <ErrorState />}
85+
{!loading && !error && (!manifest || manifest.previews.length === 0) && <EmptyState />}
8686

87-
{!loading && !error && manifest && manifest.previews.length > 0 && (
88-
<VStack gap={4} width="100%">
89-
<VStack gap={2}>
90-
<SearchInput
91-
placeholder="Search by PR number, title, branch, or author..."
92-
value={searchQuery}
93-
onChangeText={setSearchQuery}
94-
aria-label="Search previews"
95-
/>
96-
<SelectChip
97-
value={sortOption}
98-
onChange={(value) => setSortOption(value as SortOption)}
99-
label="Sort by"
100-
options={[
101-
{ label: 'Recently Updated', value: 'updated-desc' },
102-
{ label: 'Oldest Updated', value: 'updated-asc' },
103-
{ label: 'PR Number (High to Low)', value: 'pr-desc' },
104-
{ label: 'PR Number (Low to High)', value: 'pr-asc' },
105-
]}
106-
/>
107-
</VStack>
108-
109-
{filteredAndSortedPreviews.length === 0 ? (
110-
<EmptySearchState />
111-
) : (
112-
<VStack gap={4} width="100%">
113-
{filteredAndSortedPreviews.map((preview) => (
114-
<PreviewCard key={preview.pr} preview={preview} />
115-
))}
116-
</VStack>
117-
)}
87+
{!loading && !error && manifest && manifest.previews.length > 0 && (
88+
<VStack gap={4} width="100%">
89+
<VStack gap={2}>
90+
<SearchInput
91+
placeholder="Search by PR number, title, branch, or author..."
92+
value={searchQuery}
93+
onChangeText={setSearchQuery}
94+
aria-label="Search previews"
95+
/>
96+
<SelectChip
97+
value={sortOption}
98+
onChange={(value) => setSortOption(value as SortOption)}
99+
label="Sort by"
100+
options={[
101+
{ label: 'Recently Updated', value: 'updated-desc' },
102+
{ label: 'Oldest Updated', value: 'updated-asc' },
103+
{ label: 'PR Number (High to Low)', value: 'pr-desc' },
104+
{ label: 'PR Number (Low to High)', value: 'pr-asc' },
105+
]}
106+
/>
118107
</VStack>
119-
)}
120108

121-
{manifest && <Footer lastUpdated={manifest.lastUpdated} />}
122-
</VStack>
109+
{filteredAndSortedPreviews.length === 0 ? (
110+
<EmptySearchState />
111+
) : (
112+
<VStack gap={2} width="100%">
113+
{filteredAndSortedPreviews.map((preview) => (
114+
<PreviewCard key={preview.pr} preview={preview} />
115+
))}
116+
</VStack>
117+
)}
118+
</VStack>
119+
)}
120+
121+
{manifest && <Footer lastUpdated={manifest.lastUpdated} />}
122+
</VStack>
123123
</VStack>
124124
</ThemeProvider>
125125
</MediaQueryProvider>
@@ -129,10 +129,7 @@ function App() {
129129
function Header() {
130130
return (
131131
<VStack gap={2} alignItems="center">
132-
<Text
133-
as="h1"
134-
font={{ base: 'display3', phone: 'title1' }}
135-
>
132+
<Text as="h1" font={{ base: 'display3', phone: 'title1' }}>
136133
🚀 CDS PR Previews
137134
</Text>
138135
<Text color="fgMuted" font="body" textAlign="center">
@@ -179,58 +176,89 @@ function EmptySearchState() {
179176
}
180177

181178
function PreviewCard({ preview }: { preview: Preview }) {
182-
183179
return (
184-
<VStack bordered borderRadius={400} padding={2} gap={2}>
185-
<Text as="h3" font="title3">
186-
PR #{preview.pr}: {preview.title}
187-
</Text>
188-
180+
<VStack bordered borderRadius={400} padding={2} gap={1}>
181+
<HStack gap={1} alignItems="baseline">
182+
<Tag intent="informational" colorScheme="blue">
183+
<Link
184+
href={`https://github.com/coinbase/cds/pull/${preview.pr}`}
185+
target="_blank"
186+
rel="noopener noreferrer"
187+
>
188+
PR #{preview.pr}
189+
</Link>
190+
</Tag>
191+
<Text font="headline">{preview.title}</Text>
192+
</HStack>
189193
<HStack gap={4} flexWrap="wrap">
190-
<HStack gap={1} alignItems="center">
191-
<Icon name="fork" size="s" color="fgMuted" />
192-
<Text color="fgMuted" font="label2">
193-
{preview.branch}
194-
</Text>
195-
</HStack>
196194
<HStack gap={1} alignItems="center">
197195
<Icon name="account" size="s" color="fgMuted" />
198196
<Text color="fgMuted" font="label2">
199197
{preview.author}
200198
</Text>
201199
</HStack>
202-
<HStack gap={1} alignItems="center">
200+
<HStack gap={1} alignItems="center" className="meta-link">
201+
<Icon name="fork" size="s" color="fgMuted" />
202+
<Tooltip content="Click to view branch on GitHub">
203+
<Link
204+
color="fgMuted"
205+
font="label2"
206+
href={`https://github.com/coinbase/cds/tree/${preview.branch}`}
207+
target="_blank"
208+
rel="noopener noreferrer"
209+
>
210+
{preview.branch}
211+
</Link>
212+
</Tooltip>
213+
</HStack>
214+
215+
<HStack gap={1} alignItems="center" className="meta-link">
203216
<Icon name="chainLink" size="s" color="fgMuted" />
204-
<Text color="fgMuted" font="label2" mono>
205-
{preview.commit.substring(0, 7)}
206-
</Text>
217+
<Tooltip content="Click to view commit on GitHub">
218+
<Link
219+
href={`https://github.com/coinbase/cds/commit/${preview.commit}`}
220+
target="_blank"
221+
rel="noopener noreferrer"
222+
color="fgMuted"
223+
font="label2"
224+
mono
225+
>
226+
{preview.commit.substring(0, 7)}
227+
</Link>
228+
</Tooltip>
207229
</HStack>
208230
</HStack>
209-
210-
<HStack justifyContent="space-between" alignItems="center" flexWrap="wrap" gap={3}>
211-
<HStack gap={2} flexWrap="wrap">
212-
{preview.previews.docs && (
213-
<Button startIcon="document" variant="secondary" as="a" href={preview.previews.docs} target="_blank" compact>
214-
Docs
215-
</Button>
216-
)}
217-
{preview.previews.storybook && (
218-
<Button
219-
variant="secondary"
220-
as="a"
221-
href={preview.previews.storybook}
222-
target="_blank"
223-
compact
224-
startIcon="book"
225-
>
226-
Storybook
227-
</Button>
228-
)}
229-
</HStack>
230-
<Text color="fgMuted" font="label2" title={new Date(preview.updatedAt).toLocaleString()}>
231-
Updated {formatRelativeTime(new Date(preview.updatedAt))}
232-
</Text>
231+
<HStack justifyContent="space-between" alignItems="baseline" flexWrap="wrap" gap={3} paddingTop={2}>
232+
<HStack gap={2} flexWrap="wrap">
233+
{preview.previews.docs && (
234+
<Button
235+
startIcon="document"
236+
variant="secondary"
237+
as="a"
238+
href={preview.previews.docs}
239+
target="_blank"
240+
compact
241+
>
242+
Docs
243+
</Button>
244+
)}
245+
{preview.previews.storybook && (
246+
<Button
247+
variant="secondary"
248+
as="a"
249+
href={preview.previews.storybook}
250+
target="_blank"
251+
compact
252+
startIcon="book"
253+
>
254+
Storybook
255+
</Button>
256+
)}
233257
</HStack>
258+
<Text color="fgMuted" font="label2" title={new Date(preview.updatedAt).toLocaleString()}>
259+
Updated {formatRelativeTime(new Date(preview.updatedAt))}
260+
</Text>
261+
</HStack>
234262
</VStack>
235263
);
236264
}

0 commit comments

Comments
 (0)