Skip to content

Commit b43b359

Browse files
authored
Merge pull request #388 from HyperloopUPV-H8/control-station/electron
feat: initial electron set up
2 parents 3d3fe29 + 509f5c7 commit b43b359

25 files changed

Lines changed: 6808 additions & 623 deletions
File renamed without changes.
File renamed without changes.

.github/ex_workflows/release.yaml

Lines changed: 595 additions & 0 deletions
Large diffs are not rendered by default.
File renamed without changes.

.github/new_unfinished_workflows/build.yaml

Lines changed: 495 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 331 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,331 @@
1+
name: Release Electron App
2+
3+
on:
4+
# Commented because provokes duplicated builds
5+
# push:
6+
# tags:
7+
# - "v*.*.*"
8+
workflow_dispatch:
9+
inputs:
10+
version:
11+
description: "Release version (e.g., 1.0.0)"
12+
required: true
13+
draft:
14+
description: "Create as draft release"
15+
type: boolean
16+
default: true
17+
18+
jobs:
19+
# Determine version once on Linux
20+
determine-version:
21+
name: Determine Version
22+
runs-on: ubuntu-latest
23+
outputs:
24+
version: ${{ steps.get_version.outputs.version }}
25+
is_draft: ${{ steps.get_version.outputs.is_draft }}
26+
steps:
27+
- name: Determine version
28+
id: get_version
29+
run: |
30+
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
31+
echo "version=${{ github.event.inputs.version }}" >> $GITHUB_OUTPUT
32+
echo "is_draft=${{ github.event.inputs.draft }}" >> $GITHUB_OUTPUT
33+
else
34+
echo "version=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT
35+
echo "is_draft=false" >> $GITHUB_OUTPUT
36+
fi
37+
echo "Version determined: $(cat $GITHUB_OUTPUT | grep version)"
38+
39+
# Verify that required artifacts exist from build.yaml workflow
40+
verify-artifacts:
41+
name: Verify Artifacts Exist
42+
needs: determine-version
43+
runs-on: ubuntu-latest
44+
outputs:
45+
artifacts_exist: ${{ steps.check.outputs.all_exist }}
46+
backend_linux_exists: ${{ steps.check.outputs.backend_linux }}
47+
backend_windows_exists: ${{ steps.check.outputs.backend_windows }}
48+
backend_macos_intel_exists: ${{ steps.check.outputs.backend_macos_intel }}
49+
backend_macos_arm64_exists: ${{ steps.check.outputs.backend_macos_arm64 }}
50+
control_station_exists: ${{ steps.check.outputs.control_station }}
51+
ethernet_view_exists: ${{ steps.check.outputs.ethernet_view }}
52+
steps:
53+
- name: Install jq
54+
run: sudo apt-get update && sudo apt-get install -y jq
55+
56+
- name: Get latest successful run from build.yaml
57+
id: get_run
58+
run: |
59+
echo "🧿 Looking up build.yaml workflow..."
60+
WORKFLOW_RESPONSE=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
61+
-H "Accept: application/vnd.github.v3+json" \
62+
"https://api.github.com/repos/${{ github.repository }}/actions/workflows/build.yaml")
63+
64+
echo "🧿 API Response:"
65+
echo "$WORKFLOW_RESPONSE" | jq '.'
66+
67+
WORKFLOW_ID=$(echo "$WORKFLOW_RESPONSE" | jq -r '.id // empty')
68+
69+
echo "🧿 Workflow ID: $WORKFLOW_ID"
70+
71+
echo "Finding latest successful run on production branch..."
72+
RUN_ID=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
73+
"https://api.github.com/repos/${{ github.repository }}/actions/workflows/$WORKFLOW_ID/runs?branch=production&status=success&per_page=1" | \
74+
jq -r '.workflow_runs[0].id // empty')
75+
76+
if [ -z "$RUN_ID" ]; then
77+
echo "✖ No successful workflow run found"
78+
else
79+
echo "✓ Found workflow run ID: $RUN_ID"
80+
fi
81+
82+
echo "run_id=$RUN_ID" >> $GITHUB_OUTPUT
83+
84+
- name: Check artifacts
85+
id: check
86+
run: |
87+
RUN_ID="${{ steps.get_run.outputs.run_id }}"
88+
89+
if [ -z "$RUN_ID" ]; then
90+
echo "✖ No workflow run found - all artifacts missing"
91+
echo "all_exist=false" >> $GITHUB_OUTPUT
92+
echo "backend_linux=false" >> $GITHUB_OUTPUT
93+
echo "backend_windows=false" >> $GITHUB_OUTPUT
94+
echo "backend_macos_intel=false" >> $GITHUB_OUTPUT
95+
echo "backend_macos_arm64=false" >> $GITHUB_OUTPUT
96+
echo "control_station=false" >> $GITHUB_OUTPUT
97+
echo "ethernet_view=false" >> $GITHUB_OUTPUT
98+
exit 0
99+
fi
100+
101+
echo "🧿 Fetching artifacts from run $RUN_ID..."
102+
ARTIFACTS=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
103+
"https://api.github.com/repos/${{ github.repository }}/actions/runs/$RUN_ID/artifacts" | \
104+
jq -r '.artifacts[].name')
105+
106+
echo "📦 Artifacts found in workflow run:"
107+
echo "$ARTIFACTS" | while read artifact; do
108+
echo " - $artifact"
109+
done
110+
111+
check() {
112+
if echo "$ARTIFACTS" | grep -q "^$1$"; then
113+
echo "true"
114+
else
115+
echo "false"
116+
fi
117+
}
118+
119+
echo ""
120+
echo "🧿 Verifying required artifacts:"
121+
BACKEND_LINUX=$(check backend-linux)
122+
echo "backend_linux=$BACKEND_LINUX" >> $GITHUB_OUTPUT
123+
124+
BACKEND_WINDOWS=$(check backend-windows)
125+
echo "backend_windows=$BACKEND_WINDOWS" >> $GITHUB_OUTPUT
126+
127+
BACKEND_MACOS_INTEL=$(check backend-macos-intel)
128+
echo "backend_macos_intel=$BACKEND_MACOS_INTEL" >> $GITHUB_OUTPUT
129+
130+
BACKEND_MACOS_ARM64=$(check backend-macos-arm64)
131+
echo "backend_macos_arm64=$BACKEND_MACOS_ARM64" >> $GITHUB_OUTPUT
132+
133+
CONTROL_STATION=$(check control-station)
134+
echo "control_station=$CONTROL_STATION" >> $GITHUB_OUTPUT
135+
136+
ETHERNET_VIEW=$(check ethernet-view)
137+
echo "ethernet_view=$ETHERNET_VIEW" >> $GITHUB_OUTPUT
138+
139+
COUNT=$(echo "$ARTIFACTS" | grep -cE "^(backend-linux|backend-windows|backend-macos-intel|backend-macos-arm64|control-station|ethernet-view)$" || echo "0")
140+
141+
echo " Required artifacts found: $COUNT/6"
142+
if [ "$COUNT" -eq 6 ]; then
143+
# ALL_EXIST="true"
144+
ALL_EXIST="true"
145+
echo "✓ All artifacts exist!"
146+
else
147+
# ALL_EXIST="false"
148+
ALL_EXIST="false"
149+
echo "✖ Some artifacts are missing"
150+
fi
151+
152+
echo "all_exist=$ALL_EXIST" >> $GITHUB_OUTPUT
153+
154+
# Build artifacts using reusable workflow (placeholder for now)
155+
build-artifacts:
156+
name: Build Artifacts
157+
needs: [determine-version, verify-artifacts]
158+
if: needs.verify-artifacts.outputs.artifacts_exist != 'true'
159+
uses: ./.github/workflows/build.yaml
160+
with:
161+
# prettier-ignore
162+
build-backend: ${{ needs.verify-artifacts.outputs.backend_linux_exists != 'true' ||
163+
needs.verify-artifacts.outputs.backend_windows_exists != 'true' ||
164+
needs.verify-artifacts.outputs.backend_macos_intel_exists != 'true' ||
165+
needs.verify-artifacts.outputs.backend_macos_arm64_exists != 'true' }}
166+
build-control-station: ${{ needs.verify-artifacts.outputs.control_station_exists != 'true' }}
167+
build-ethernet-view: ${{ needs.verify-artifacts.outputs.ethernet_view_exists != 'true' }}
168+
169+
build-electron:
170+
name: Build Electron App
171+
needs: [determine-version, verify-artifacts, build-artifacts]
172+
runs-on: ${{ matrix.os }}
173+
if: always() && needs.build-artifacts.result != 'failure'
174+
strategy:
175+
fail-fast: false
176+
matrix:
177+
os: [ubuntu-latest, windows-latest, macos-latest]
178+
steps:
179+
- name: Checkout repository
180+
uses: actions/checkout@v4
181+
182+
- name: Setup Node.js
183+
uses: actions/setup-node@v4
184+
with:
185+
node-version: "20"
186+
187+
# Update package.json with release version
188+
- name: Update version in package.json
189+
working-directory: electron-app
190+
shell: bash
191+
run: |
192+
npm version ${{ needs.determine-version.outputs.version }} --no-git-tag-version
193+
echo "Updated version to:"
194+
cat package.json | grep version
195+
196+
# Download ONLY the appropriate backend for this platform
197+
- name: Download Linux backend
198+
if: runner.os == 'Linux'
199+
uses: dawidd6/action-download-artifact@v3
200+
with:
201+
workflow: build.yaml
202+
branch: production
203+
workflow_conclusion: success
204+
name: backend-linux
205+
path: electron-app/binaries
206+
207+
- name: Download Windows backend
208+
if: runner.os == 'Windows'
209+
uses: dawidd6/action-download-artifact@v3
210+
with:
211+
workflow: build.yaml
212+
branch: production
213+
workflow_conclusion: success
214+
name: backend-windows
215+
path: electron-app/binaries
216+
217+
# macOS needs both Intel and ARM64 for universal support
218+
- name: Download macOS Intel backend
219+
if: runner.os == 'macOS'
220+
uses: dawidd6/action-download-artifact@v3
221+
with:
222+
workflow: build.yaml
223+
branch: production
224+
workflow_conclusion: success
225+
name: backend-macos-intel
226+
path: electron-app/binaries
227+
228+
- name: Download macOS ARM64 backend
229+
if: runner.os == 'macOS'
230+
uses: dawidd6/action-download-artifact@v3
231+
with:
232+
workflow: build.yaml
233+
branch: production
234+
workflow_conclusion: success
235+
name: backend-macos-arm64
236+
path: electron-app/binaries
237+
238+
# Download frontend builds from latest build
239+
- name: Download control-station
240+
uses: dawidd6/action-download-artifact@v3
241+
with:
242+
workflow: build.yaml
243+
branch: production
244+
workflow_conclusion: success
245+
name: control-station
246+
path: electron-app/renderer/control-station
247+
248+
- name: Download ethernet-view
249+
uses: dawidd6/action-download-artifact@v3
250+
with:
251+
workflow: build.yaml
252+
branch: production
253+
workflow_conclusion: success
254+
name: ethernet-view
255+
path: electron-app/renderer/ethernet-view
256+
257+
- name: Set executable permissions (Unix)
258+
if: runner.os != 'Windows'
259+
run: chmod +x electron-app/binaries/*
260+
261+
- name: Install Electron dependencies
262+
working-directory: electron-app
263+
run: npm ci
264+
265+
- name: Build Electron distribution
266+
working-directory: electron-app
267+
run: npm run dist
268+
env:
269+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
270+
CSC_IDENTITY_AUTO_DISCOVERY: false
271+
ELECTRON_BUILDER_PUBLISH: never
272+
273+
- name: Display structure (Windows)
274+
if: matrix.os == 'windows-latest'
275+
working-directory: electron-app
276+
shell: pwsh
277+
run: Get-ChildItem -Recurse dist/ | Select-Object FullName
278+
279+
- name: Display structure (Unix)
280+
if: matrix.os != 'windows-latest'
281+
working-directory: electron-app
282+
run: ls -laR dist/
283+
284+
- name: Upload electron artifacts
285+
uses: actions/upload-artifact@v4
286+
with:
287+
name: electron-${{ runner.os }}
288+
path: |
289+
electron-app/dist/*.exe
290+
electron-app/dist/*.AppImage
291+
electron-app/dist/*.deb
292+
electron-app/dist/*.dmg
293+
electron-app/dist/*.zip
294+
!electron-app/dist/*-unpacked
295+
!electron-app/dist/mac
296+
!electron-app/dist/win-unpacked
297+
!electron-app/dist/linux-unpacked
298+
if-no-files-found: error
299+
retention-days: 7
300+
301+
# Create GitHub Release
302+
create-release:
303+
name: Create GitHub Release
304+
needs: [build-electron, determine-version]
305+
if: always() && needs.build-electron.result == 'success'
306+
runs-on: ubuntu-latest
307+
308+
steps:
309+
- name: Checkout repository
310+
uses: actions/checkout@v4
311+
312+
- name: Download all electron artifacts
313+
uses: actions/download-artifact@v4
314+
with:
315+
pattern: electron-*
316+
path: dist
317+
merge-multiple: true
318+
319+
- name: Display structure
320+
run: ls -laR dist/
321+
322+
- name: Create Release
323+
uses: softprops/action-gh-release@v2
324+
with:
325+
tag_name: v${{ needs.determine-version.outputs.version }}
326+
name: Hyperloop Control Station v${{ needs.determine-version.outputs.version }}
327+
draft: ${{ needs.determine-version.outputs.is_draft }}
328+
generate_release_notes: true
329+
files: dist/**/*
330+
env:
331+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

0 commit comments

Comments
 (0)