Skip to content

Commit 76cd462

Browse files
d
1 parent a157bfe commit 76cd462

6 files changed

Lines changed: 183 additions & 23 deletions

File tree

.firebaserc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"projects": {
3+
"default": "holoui-editor"
4+
}
5+
}
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
name: Deploy Firebase Hosting
2+
3+
on:
4+
push:
5+
branches:
6+
- master
7+
workflow_dispatch:
8+
9+
permissions:
10+
contents: read
11+
12+
env:
13+
ARCANE_JASPR_REF: b896cdc28008ef56439f10670a177943c7aba69e
14+
FIREBASE_PROJECT_ID: holoui-editor
15+
FIREBASE_TOOLS_VERSION: 15.25.1
16+
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
17+
NODE_VERSION: 22.23.1
18+
19+
concurrency:
20+
group: firebase-hosting-${{ github.ref }}
21+
cancel-in-progress: true
22+
23+
jobs:
24+
deploy:
25+
name: Build, verify, and deploy
26+
runs-on: ubuntu-latest
27+
environment:
28+
name: production
29+
url: https://holoui-editor.web.app
30+
31+
steps:
32+
- name: Checkout repository
33+
uses: actions/checkout@v6
34+
35+
- name: Cache pinned Arcane Jaspr
36+
id: cache-arcane-jaspr
37+
uses: actions/cache@v5
38+
with:
39+
path: .deps/arcane_jaspr
40+
key: arcane-jaspr-${{ env.ARCANE_JASPR_REF }}
41+
42+
- name: Checkout pinned Arcane Jaspr
43+
if: steps.cache-arcane-jaspr.outputs.cache-hit != 'true'
44+
uses: actions/checkout@v6
45+
with:
46+
repository: ArcaneArts/arcane_jaspr
47+
ref: ${{ env.ARCANE_JASPR_REF }}
48+
path: .deps/arcane_jaspr
49+
50+
- name: Setup Dart
51+
uses: dart-lang/setup-dart@v1
52+
with:
53+
sdk: stable
54+
55+
- name: Setup Node
56+
uses: actions/setup-node@v6
57+
with:
58+
node-version: ${{ env.NODE_VERSION }}
59+
60+
- name: Get dependencies
61+
run: dart pub get
62+
63+
- name: Analyze
64+
run: dart analyze
65+
66+
- name: Test
67+
run: dart test
68+
69+
- name: Build
70+
run: dart run jaspr_cli:jaspr build
71+
72+
- name: Authenticate to Google Cloud
73+
uses: google-github-actions/auth@v3
74+
with:
75+
credentials_json: ${{ secrets.FIREBASE_SERVICE_ACCOUNT_HOLOUI_EDITOR }}
76+
77+
- name: Deploy Firebase Hosting
78+
run: |
79+
set -euo pipefail
80+
unset FIREBASE_TOKEN
81+
npx --yes "firebase-tools@$FIREBASE_TOOLS_VERSION" deploy \
82+
--only hosting \
83+
--project "$FIREBASE_PROJECT_ID" \
84+
--non-interactive
85+
86+
- name: Verify deployed bundle
87+
run: |
88+
set -euo pipefail
89+
expected_sha="$(sha256sum build/jaspr/main.client.dart.js | awk '{print $1}')"
90+
actual_sha=""
91+
for attempt in {1..12}; do
92+
if actual_sha="$(curl -fsS --max-time 30 \
93+
"https://holoui-editor.web.app/main.client.dart.js?release=$GITHUB_SHA" \
94+
| sha256sum | awk '{print $1}')" \
95+
&& [[ "$actual_sha" == "$expected_sha" ]]; then
96+
echo "Firebase is serving the client bundle built from $GITHUB_SHA."
97+
exit 0
98+
fi
99+
echo "Waiting for Firebase Hosting to converge (attempt $attempt/12)."
100+
sleep 5
101+
done
102+
echo "::error title=Stale Firebase client bundle::Expected $expected_sha but received $actual_sha."
103+
exit 1

.github/workflows/release.yml

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -10,22 +10,17 @@ on:
1010

1111
permissions:
1212
contents: write
13-
pages: write
14-
id-token: write
1513

1614
jobs:
1715
build:
1816
runs-on: ubuntu-latest
1917
steps:
2018
- uses: actions/checkout@v4
2119

22-
# arcane_jaspr is a path dependency at .deps/arcane_jaspr. Cross-org
23-
# checkout needs a PAT with read access to ArcaneArts/arcane_jaspr,
24-
# stored as the ARCANE_JASPR_TOKEN repository secret.
2520
- uses: actions/checkout@v4
2621
with:
2722
repository: ArcaneArts/arcane_jaspr
28-
token: ${{ secrets.ARCANE_JASPR_TOKEN }}
23+
ref: b896cdc28008ef56439f10670a177943c7aba69e
2924
path: .deps/arcane_jaspr
3025

3126
- uses: dart-lang/setup-dart@v1
@@ -51,18 +46,3 @@ jobs:
5146
uses: softprops/action-gh-release@v2
5247
with:
5348
files: builder_static.zip
54-
55-
- name: Upload Pages artifact
56-
uses: actions/upload-pages-artifact@v3
57-
with:
58-
path: build/jaspr
59-
60-
deploy-pages:
61-
needs: build
62-
runs-on: ubuntu-latest
63-
environment:
64-
name: github-pages
65-
url: ${{ steps.deployment.outputs.page_url }}
66-
steps:
67-
- id: deployment
68-
uses: actions/deploy-pages@v4

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,10 @@ pubspec.lock
1111
# Packaging output
1212
builder_static.zip
1313

14+
# Firebase tooling
15+
.firebase/
16+
firebase-debug.log
17+
firebase-debug.*.log
18+
19+
# Local credentials
1420
service-account.json

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,12 @@ dart run jaspr_cli:jaspr build # static output in build/jaspr/
2929

3030
## Releasing
3131

32-
HoloUI self-hosts this editor: `/holoui builder start` downloads the **latest GitHub release** asset named exactly `builder_static.zip` (with `index.html` at the ZIP root) and serves it from the game server. The release tag must be **bare semver** (`3.0.0`, never `v3.0.0` — the plugin's semver parser rejects a `v` prefix).
32+
The hosted editor is deployed to [Firebase Hosting](https://holoui-editor.web.app/) by `.github/workflows/firebase-hosting.yml` after every push to `master`. The workflow analyzes and tests the project before building and deploying it. It requires the `FIREBASE_SERVICE_ACCOUNT_HOLOUI_EDITOR` repository secret.
33+
34+
HoloUI also self-hosts this editor: `/holoui builder start` downloads the **latest GitHub release** asset named exactly `builder_static.zip` (with `index.html` at the ZIP root) and serves it from the game server. The release tag must be **bare semver** (`3.0.0`, never `v3.0.0` — the plugin's semver parser rejects a `v` prefix).
3335

3436
- Locally: `tool/package_builder_static.sh` builds and packages the ZIP.
35-
- CI: pushing a bare-semver tag runs `.github/workflows/release.yml`, which builds, attaches `builder_static.zip` to the release, and deploys GitHub Pages (`https://holoui.volmit.com/`). The workflow needs an `ARCANE_JASPR_TOKEN` repository secret with read access to `ArcaneArts/arcane_jaspr`.
37+
- CI: pushing a bare-semver tag runs `.github/workflows/release.yml`, which builds and attaches `builder_static.zip` to the release.
3638

3739
## Architecture
3840

firebase.json

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
{
2+
"hosting": {
3+
"site": "holoui-editor",
4+
"public": "build/jaspr",
5+
"ignore": [
6+
"firebase.json",
7+
"**/.*",
8+
"**/node_modules/**"
9+
],
10+
"headers": [
11+
{
12+
"source": "/",
13+
"headers": [
14+
{
15+
"key": "Cache-Control",
16+
"value": "no-cache, no-store, must-revalidate, max-age=0"
17+
}
18+
]
19+
},
20+
{
21+
"source": "/index.html",
22+
"headers": [
23+
{
24+
"key": "Cache-Control",
25+
"value": "no-cache, no-store, must-revalidate, max-age=0"
26+
}
27+
]
28+
},
29+
{
30+
"source": "/main.client.dart.js",
31+
"headers": [
32+
{
33+
"key": "Cache-Control",
34+
"value": "no-cache, no-store, must-revalidate, max-age=0"
35+
}
36+
]
37+
},
38+
{
39+
"source": "**/*.@(woff|woff2|ttf)",
40+
"headers": [
41+
{
42+
"key": "Cache-Control",
43+
"value": "public, max-age=31536000, immutable"
44+
}
45+
]
46+
},
47+
{
48+
"source": "**/*.@(jpg|jpeg|png|webp|svg|ico)",
49+
"headers": [
50+
{
51+
"key": "Cache-Control",
52+
"value": "public, max-age=86400, stale-while-revalidate=604800"
53+
}
54+
]
55+
}
56+
],
57+
"rewrites": [
58+
{
59+
"source": "**",
60+
"destination": "/index.html"
61+
}
62+
]
63+
}
64+
}

0 commit comments

Comments
 (0)