-
Notifications
You must be signed in to change notification settings - Fork 6
167 lines (148 loc) · 5.52 KB
/
deploy-example-apps.yml
File metadata and controls
167 lines (148 loc) · 5.52 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
name: Deploy example apps to GitHub Pages
# Manual-only trigger so forks never auto-publish. Forkers must (1) enable
# Pages with source "GitHub Actions" in repo Settings, then (2) run this
# workflow from the Actions tab. Every subdirectory under example-apps/
# that has a package.json with a "build" script is auto-discovered and
# deployed to:
# https://<owner>.github.io/<repo>/<app-name>/
# Adding a new app requires no workflow edits.
on:
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: pages-example-apps
cancel-in-progress: true
jobs:
discover:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set.outputs.matrix }}
apps: ${{ steps.set.outputs.apps }}
meta: ${{ steps.set.outputs.meta }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- id: set
name: Discover apps
run: |
set -euo pipefail
metas=()
for pkg in example-apps/*/package.json; do
[ -f "$pkg" ] || continue
dir="$(dirname "$pkg")"
name="$(basename "$dir")"
if jq -e '.scripts.build' "$pkg" >/dev/null; then
metas+=("$(jq --arg name "$name" -c \
'{name: $name, displayName: (.displayName // null), description: (.description // null)}' \
"$pkg")")
fi
done
if [ "${#metas[@]}" -eq 0 ]; then
echo "No deployable apps found under example-apps/." >&2
exit 1
fi
meta_json="$(printf '%s\n' "${metas[@]}" | jq -sc .)"
apps_json="$(echo "$meta_json" | jq -c '[.[].name]')"
echo "matrix={\"app\":$apps_json}" >> "$GITHUB_OUTPUT"
echo "apps=$apps_json" >> "$GITHUB_OUTPUT"
echo "meta=$meta_json" >> "$GITHUB_OUTPUT"
echo "Discovered: $apps_json"
build:
needs: discover
runs-on: ubuntu-latest
# An app's test or build failure is reported in the UI but doesn't fail
# the job, so the deploy step can still publish whichever apps passed.
continue-on-error: true
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.discover.outputs.matrix) }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: 20
cache: npm
cache-dependency-path: example-apps/${{ matrix.app }}/package-lock.json
- name: Install
run: npm ci
working-directory: example-apps/${{ matrix.app }}
- name: Test
run: |
if jq -e '.scripts.test' package.json >/dev/null; then
npm test
else
echo "No test script for ${{ matrix.app }} — skipping"
fi
working-directory: example-apps/${{ matrix.app }}
- name: Build
run: npm run build
working-directory: example-apps/${{ matrix.app }}
env:
# Self-configuring base path: resolves to /<repo>/<app>/ on any fork.
VITE_BASE_PATH: /${{ github.event.repository.name }}/${{ matrix.app }}/
- name: Upload built dist
uses: actions/upload-artifact@v4
with:
name: site-${{ matrix.app }}
path: example-apps/${{ matrix.app }}/dist
if-no-files-found: error
retention-days: 1
deploy:
needs: [discover, build]
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: 20
- name: Download all built apps
uses: actions/download-artifact@v4
with:
pattern: site-*
path: artifacts
- name: Assemble combined site
id: assemble
env:
APPS_JSON: ${{ needs.discover.outputs.apps }}
META_JSON: ${{ needs.discover.outputs.meta }}
run: |
set -euo pipefail
mkdir -p _site
deployed=()
mapfile -t apps < <(echo "$APPS_JSON" | jq -r '.[]')
for app in "${apps[@]}"; do
src="artifacts/site-$app"
if [ ! -d "$src" ]; then
echo "::warning::Skipping $app — no artifact (test or build failed)"
continue
fi
mkdir -p "_site/$app"
cp -r "$src/." "_site/$app/"
deployed+=("$app")
done
if [ "${#deployed[@]}" -eq 0 ]; then
echo "No apps passed tests + build; aborting deploy." >&2
exit 1
fi
deployed_json=$(printf '%s\n' "${deployed[@]}" | jq -R . | jq -sc .)
filtered_meta=$(echo "$META_JSON" | jq -c --argjson keep "$deployed_json" \
'[.[] | select(.name as $n | $keep | index($n))]')
{
echo "meta<<__META_EOF__"
echo "$filtered_meta"
echo "__META_EOF__"
} >> "$GITHUB_OUTPUT"
- name: Generate landing page
env:
META_JSON: ${{ steps.assemble.outputs.meta }}
run: node .github/scripts/build-landing-page.mjs "$META_JSON" _site/index.html
- uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0
with:
path: _site
- id: deployment
uses: actions/deploy-pages@cd2ce8fcbc39b97be8ca5fce6e763baed58fa128 # v5.0.0