Skip to content

Commit dba4fd2

Browse files
Set up Resource UI deployment to firebase (#1640)
1 parent dcc75fd commit dba4fd2

10 files changed

Lines changed: 150 additions & 16 deletions

File tree

.github/workflows/ci.yml

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,13 +87,13 @@ jobs:
8787
run: |
8888
sudo echo "127.0.0.1 navigate.lucuma.xyz" | sudo tee -a /etc/hosts
8989
- run: pnpm exec playwright install firefox --only-shell
90-
- run: pnpm --filter "...@gemini-hlsw/navigate-e2e[origin/main]..." --if-present build
91-
- run: pnpm --filter "...@gemini-hlsw/navigate-e2e[origin/main]..." --if-present e2e:docker-up
90+
- run: pnpm --filter "...navigate-e2e[origin/main]..." --if-present build
91+
- run: pnpm --filter "...navigate-e2e[origin/main]..." --if-present e2e:docker-up
9292
env:
9393
LUCUMA_REFRESH_TOKEN: ${{ secrets.LUCUMA_DEV_API_KEY }}
9494

9595
- name: Run Playwright tests
96-
run: pnpm --filter "...@gemini-hlsw/navigate-e2e[origin/main]..." --if-present test:e2e
96+
run: pnpm --filter "...navigate-e2e[origin/main]..." --if-present test:e2e
9797
env:
9898
LUCUMA_REFRESH_TOKEN: ${{ secrets.LUCUMA_DEV_API_KEY }}
9999
DATABASE_URL: 'postgresql://jimmy:banana@127.0.0.1:5432/configs'
@@ -265,3 +265,32 @@ jobs:
265265
env:
266266
HEROKU_API_KEY: ${{ secrets.HEROKU_API_KEY }}
267267
run: ./deploy/deploy-heroku.sh
268+
269+
deploy-resource:
270+
runs-on: ubuntu-latest
271+
if: (github.ref == 'refs/heads/main' && github.repository_owner == 'gemini-hlsw')
272+
timeout-minutes: 10
273+
environment:
274+
name: resource-ui-dev
275+
url: 'https://resource-dev.lucuma.xyz'
276+
steps:
277+
- uses: actions/checkout@v6
278+
- uses: ./.github/setup
279+
with:
280+
only-changed: true
281+
FONTAWESOME_NPM_AUTH_TOKEN: ${{ secrets.FONTAWESOME_NPM_AUTH_TOKEN }}
282+
- run: pnpm --filter "...resource-ui[origin/main]..." --if-present build
283+
284+
# Set env.DEPLOY_RESOURCE if there are changes
285+
- run: pnpm --filter "...resource-ui[origin/main]..." --if-present ci:set-deploy-flag
286+
287+
- name: Deploy staging app to Firebase
288+
if: env.DEPLOY_RESOURCE == 'true'
289+
uses: FirebaseExtended/action-hosting-deploy@v0
290+
with:
291+
repoToken: ${{ secrets.GITHUB_TOKEN }}
292+
firebaseServiceAccount: ${{ secrets.FIREBASE_SERVICE_ACCOUNT }}
293+
projectId: ${{ vars.FIREBASE_PROJECT_ID }}
294+
entryPoint: ./packages/resource-ui
295+
target: dev
296+
channelId: live

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,16 @@ yarn-debug.log*
77
yarn-error.log*
88
pnpm-debug.log*
99
lerna-debug.log*
10+
firebase-debug.log*
11+
firebase-debug.*.log*
1012

1113
node_modules
1214
dist
1315
dist-ssr
1416
*.tsbuildinfo
1517
*.local
1618
pruned
19+
.firebase/
1720

1821
# Editor directories and files
1922
.idea

packages/common-ui/src/functions.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,3 +99,13 @@ export function parseNumber<T extends number | string>(
9999
): T extends undefined ? number | undefined : number {
100100
return typeof value === 'string' ? parseFloat(value) : (value as T extends undefined ? number | undefined : number);
101101
}
102+
103+
/**
104+
* Converts a relative URI to an absolute URI based on the current window origin.
105+
*/
106+
export const withAbsoluteUri = (uri: string, isWs = false) => {
107+
if (!uri.startsWith('/')) return uri;
108+
109+
const newUri = window.location.origin + uri;
110+
return isWs ? newUri.replace(/^http/, 'ws') : newUri;
111+
};

packages/resource-ui/.firebaserc

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"projects": {
3+
"default": "resource-ae0b7"
4+
},
5+
"targets": {
6+
"resource-ae0b7": {
7+
"hosting": {
8+
"dev": ["resource-ae0b7-dev"],
9+
"staging": ["resource-ae0b7-staging"],
10+
"production": ["resource-ae0b7"]
11+
}
12+
}
13+
}
14+
}

packages/resource-ui/firebase.json

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
{
2+
"hosting": [
3+
{
4+
"target": "dev",
5+
"public": "dist",
6+
"ignore": ["firebase.json", "**/.*", "**/node_modules/**"],
7+
"rewrites": [
8+
{
9+
"source": "**",
10+
"destination": "/index.html"
11+
}
12+
]
13+
},
14+
{
15+
"target": "staging",
16+
"public": "dist",
17+
"ignore": ["firebase.json", "**/.*", "**/node_modules/**"],
18+
"rewrites": [
19+
{
20+
"source": "**",
21+
"destination": "/index.html"
22+
}
23+
]
24+
},
25+
{
26+
"target": "production",
27+
"public": "dist",
28+
"ignore": ["firebase.json", "**/.*", "**/node_modules/**"],
29+
"rewrites": [
30+
{
31+
"source": "**",
32+
"destination": "/index.html"
33+
}
34+
]
35+
}
36+
]
37+
}

packages/resource-ui/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
"dev:mock-server": "node --watch --enable-source-maps ./mock-server/server.ts",
1515
"codegen": "graphql-codegen --config tasks/codegen.ts",
1616
"codegen:mock": "graphql-codegen --config tasks/codegen.mock.ts",
17+
"ci:set-deploy-flag": "echo \"DEPLOY_RESOURCE=true\" >> \"$GITHUB_ENV\"",
1718
"prebuild": "pnpm run codegen",
1819
"test": "vitest run",
1920
"build": "tsc -b && vite build",
Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,28 @@
11
import { ApolloClient, HttpLink, InMemoryCache } from '@apollo/client';
2+
import { withAbsoluteUri } from '@gemini-hlsw/lucuma-common-ui';
3+
4+
const graphqlEndpoints = {
5+
'resource-ae0b7-dev.web.app': 'https://lucuma-resource-dev.lucuma.xyz/resource/graphql',
6+
'resource-dev.lucuma.xyz': 'https://lucuma-resource-dev.lucuma.xyz/resource/graphql',
7+
localhost: '/resource/graphql',
8+
9+
'resource-ae0b7-staging.web.app': 'https://lucuma-resource-staging.lucuma.xyz/resource/graphql',
10+
'resource-staging.lucuma.xyz': 'https://lucuma-resource-staging.lucuma.xyz/resource/graphql',
11+
12+
'resource-ae0b7.web.app': 'https://lucuma-resource-dev.lucuma.xyz/resource/graphql',
13+
'resource.gemini.edu': 'https://lucuma-resource-dev.lucuma.xyz/resource/graphql',
14+
} satisfies Record<string, string>;
15+
16+
const defaultGraphqlEndpoint = graphqlEndpoints.localhost;
17+
18+
const uri = graphqlEndpoints[window.location.hostname as keyof typeof graphqlEndpoints] ?? defaultGraphqlEndpoint;
219

320
// Create an Apollo Client instance with the specified GraphQL endpoint and cache configuration.
421
export const client = new ApolloClient({
5-
link: new HttpLink({
6-
uri: '/resource/graphql',
7-
}),
22+
clientAwareness: {
23+
name: 'resource-ui',
24+
version: import.meta.env.FRONTEND_VERSION,
25+
},
26+
link: new HttpLink({ uri: withAbsoluteUri(uri) }),
827
cache: new InMemoryCache(),
928
});
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/// <reference types="vite/client" />
2+
3+
// Extra variables that will be replaced by Vite in the build process, defined in vite.config.ts
4+
interface ImportMetaEnv {
5+
readonly FRONTEND_VERSION: string;
6+
}
7+
8+
interface ImportMeta {
9+
readonly env: ImportMetaEnv;
10+
}

packages/resource-ui/vite.config.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,29 @@ import babel from '@rolldown/plugin-babel';
22
import tailwindcss from '@tailwindcss/vite';
33
import react, { reactCompilerPreset } from '@vitejs/plugin-react';
44
import { playwright } from '@vitest/browser-playwright';
5+
import { execSync } from 'child_process';
56
import { defineConfig } from 'vitest/config';
67

8+
import pkgJson from './package.json' with { type: 'json' };
9+
10+
const version = (process.env.GITHUB_REF_NAME || `v${pkgJson.version}`).trim();
11+
const commitHash = (process.env.GITHUB_SHA || execSync('git rev-parse --short HEAD').toString()).trim().slice(0, 7);
12+
13+
const buildTime = new Date();
14+
function formatDate(date: Date) {
15+
const years = date.getFullYear();
16+
// Months are 0-indexed
17+
const months = date.getMonth() + 1;
18+
const days = date.getDate();
19+
return `${years}${months.toString().padStart(2, '0')}${days.toString().padStart(2, '0')}`;
20+
}
21+
const frontendVersion = `${version}+${formatDate(buildTime)}.${commitHash}`;
22+
723
// https://vite.dev/config/
824
export default defineConfig({
25+
define: {
26+
'import.meta.env.FRONTEND_VERSION': JSON.stringify(frontendVersion),
27+
},
928
css: {
1029
transformer: 'lightningcss',
1130
lightningcss: {
@@ -28,6 +47,7 @@ export default defineConfig({
2847
tailwindcss(),
2948
],
3049
server: {
50+
allowedHosts: ['localhost', '.lucuma.xyz', '.gemini.edu'],
3151
proxy: {
3252
'/resource/graphql': {
3353
target: 'https://lucuma-resource-dev.lucuma.xyz',

packages/ui/src/gql/ApolloConfigs.ts

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
import { SetContextLink } from '@apollo/client/link/context';
1212
import { ErrorLink } from '@apollo/client/link/error';
1313
import { GraphQLWsLink } from '@apollo/client/link/subscriptions';
14+
import { withAbsoluteUri } from '@gemini-hlsw/lucuma-common-ui';
1415
import { OperationTypeNode } from 'graphql/language';
1516
import { createClient as createWsClient } from 'graphql-ws';
1617

@@ -20,16 +21,6 @@ import { wsIsConnectedAtom } from '@/components/atoms/connection';
2021
import { store } from '@/components/atoms/store';
2122
import { toastAtom } from '@/Helpers/toast';
2223

23-
/**
24-
* Converts a relative URI to an absolute URI based on the current window origin.
25-
*/
26-
const withAbsoluteUri = (uri: string, isWs = false) => {
27-
if (!uri.startsWith('/')) return uri;
28-
29-
const newUri = window.location.origin + uri;
30-
return isWs ? newUri.replace(/^http/, 'ws') : newUri;
31-
};
32-
3324
const navigateServerURI = withAbsoluteUri('/navigate/graphql');
3425
const navigateServerWsURI = withAbsoluteUri('/navigate/ws', true);
3526
const navigateConfigsURI = withAbsoluteUri('/db');

0 commit comments

Comments
 (0)