Skip to content

Commit 261278c

Browse files
authored
Add automatic release through workflow (#1175)
* Add automatic release through workflow * Remove linux from electron builder * Address copilot review comments
1 parent 0ae980a commit 261278c

6 files changed

Lines changed: 254 additions & 26 deletions

File tree

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
name: Desktop Release
2+
3+
permissions:
4+
contents: write
5+
6+
on:
7+
push:
8+
tags:
9+
- 'v*'
10+
11+
env:
12+
RELEASE_ALLOWED_OWNER: 1Blademaster
13+
RELEASE_ALLOWED_ACTOR: 1Blademaster
14+
15+
concurrency:
16+
group: release-${{ github.ref }}
17+
cancel-in-progress: false
18+
19+
jobs:
20+
authorize:
21+
name: Authorize Release Actor
22+
runs-on: ubuntu-latest
23+
steps:
24+
- name: Validate release owner and actor
25+
shell: bash
26+
run: |
27+
if [[ "${GITHUB_REPOSITORY_OWNER}" != "${RELEASE_ALLOWED_OWNER}" ]]; then
28+
echo "Release blocked: repository owner '${GITHUB_REPOSITORY_OWNER}' is not '${RELEASE_ALLOWED_OWNER}'."
29+
exit 1
30+
fi
31+
32+
if [[ "${GITHUB_ACTOR}" != "${RELEASE_ALLOWED_ACTOR}" ]]; then
33+
echo "Release blocked: actor '${GITHUB_ACTOR}' is not '${RELEASE_ALLOWED_ACTOR}'."
34+
exit 1
35+
fi
36+
37+
echo "Release authorized for ${GITHUB_ACTOR} on ${GITHUB_REPOSITORY}."
38+
39+
prepare:
40+
name: Prepare Release Metadata
41+
needs: authorize
42+
runs-on: ubuntu-latest
43+
outputs:
44+
tag: ${{ steps.meta.outputs.tag }}
45+
version: ${{ steps.meta.outputs.version }}
46+
prerelease: ${{ steps.meta.outputs.prerelease }}
47+
steps:
48+
- name: Validate tag and extract version
49+
id: meta
50+
shell: bash
51+
run: |
52+
TAG="${GITHUB_REF_NAME}"
53+
VERSION="${TAG#v}"
54+
55+
if [[ ! "$TAG" =~ ^v[0-9]+\.[0-9]+\.[0-9]+([.-][0-9A-Za-z.-]+)?$ ]]; then
56+
echo "Invalid release tag: $TAG"
57+
echo "Expected format: vX.Y.Z or vX.Y.Z-suffix"
58+
exit 1
59+
fi
60+
61+
PRERELEASE="false"
62+
# if [[ "$VERSION" == *-* ]] || [[ "$VERSION" == *alpha* ]] || [[ "$VERSION" == *beta* ]] || [[ "$VERSION" == *rc* ]]; then
63+
# PRERELEASE="true"
64+
# fi
65+
66+
echo "tag=$TAG" >> "$GITHUB_OUTPUT"
67+
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
68+
echo "prerelease=$PRERELEASE" >> "$GITHUB_OUTPUT"
69+
70+
- name: Create draft release
71+
uses: softprops/action-gh-release@v3
72+
with:
73+
tag_name: ${{ steps.meta.outputs.tag }}
74+
name: FGCS ${{ steps.meta.outputs.tag }}
75+
draft: true
76+
prerelease: ${{ steps.meta.outputs.prerelease == 'true' }}
77+
generate_release_notes: true
78+
env:
79+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
80+
81+
build:
82+
name: Build ${{ matrix.name }}
83+
needs: prepare
84+
runs-on: ${{ matrix.os }}
85+
strategy:
86+
fail-fast: false
87+
matrix:
88+
include:
89+
- name: Windows x64
90+
os: windows-latest
91+
platform: windows
92+
arch: x64
93+
- name: macOS x64
94+
os: macos-13
95+
platform: mac
96+
arch: x64
97+
- name: macOS arm64
98+
os: macos-latest
99+
platform: mac
100+
arch: arm64
101+
env:
102+
VERSION: ${{ needs.prepare.outputs.version }}
103+
RELEASE_TAG: ${{ needs.prepare.outputs.tag }}
104+
105+
steps:
106+
- name: Check out Git repository
107+
uses: actions/checkout@v6
108+
109+
- name: Set up Node.js
110+
uses: actions/setup-node@v6
111+
with:
112+
node-version: 22
113+
114+
- name: Set up Python 3.11
115+
uses: actions/setup-python@v5
116+
with:
117+
python-version: '3.11'
118+
119+
- name: Build on Windows
120+
if: matrix.platform == 'windows'
121+
shell: pwsh
122+
working-directory: building/windows
123+
run: |
124+
python -m venv radio\venv
125+
.\radio\venv\Scripts\Activate.ps1
126+
python -m pip install --upgrade pip
127+
pip install -r radio\requirements.txt
128+
.\building\windows\build.ps1 -Version "$env:VERSION" -Arch "${{ matrix.arch }}"
129+
130+
- name: Build on macOS
131+
if: matrix.platform == 'mac'
132+
shell: bash
133+
working-directory: building/macos
134+
run: |
135+
python3 -m venv radio/venv
136+
source radio/venv/bin/activate
137+
python3 -m pip install --upgrade pip
138+
pip install -r radio/requirements.txt
139+
chmod +x building/macos/build.sh
140+
./building/macos/build.sh "$VERSION" "${{ matrix.arch }}"
141+
142+
- name: Upload Windows installer
143+
if: matrix.platform == 'windows'
144+
uses: softprops/action-gh-release@v3
145+
with:
146+
tag_name: ${{ env.RELEASE_TAG }}
147+
draft: true
148+
files: |
149+
gcs/release/${{ env.VERSION }}/FGCS-Windows-${{ env.VERSION }}-Setup.exe
150+
env:
151+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
152+
153+
- name: Upload macOS installer
154+
if: matrix.platform == 'mac'
155+
uses: softprops/action-gh-release@v3
156+
with:
157+
tag_name: ${{ env.RELEASE_TAG }}
158+
draft: true
159+
files: |
160+
gcs/release/${{ env.VERSION }}/FGCS-Mac-${{ env.VERSION }}-Installer-${{ matrix.arch }}.dmg
161+
env:
162+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

building/macos/build.sh

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
#!/usr/bin/env bash
22
set -euo pipefail
33

4-
# Build FGCS for macOS (arm64 by default). Run from any directory.
5-
# Usage: ./build.sh [version]
6-
# If no version is provided, the script will show current version and prompt for new one
4+
# Build FGCS for macOS. Run from any directory.
5+
# Usage: ./build.sh [version] [arch]
6+
# version: optional, will prompt if not provided
7+
# arch: optional (x64 or arm64), defaults to host architecture if not specified
78

89
VERSION="${1:-}"
10+
ARCH="${2:-}"
911

1012
echo "Assuming location is FGCS/building/macos"
1113
cd ../../
@@ -78,6 +80,14 @@ echo "Generated log message descriptions"
7880
cd ../
7981
yarn
8082
yarn version --new-version "$VERSION" --no-git-tag-version --no-commit-hooks
81-
yarn build
83+
84+
# Build with optional arch specification
85+
if [[ -n "$ARCH" ]]; then
86+
echo "Building for architecture: $ARCH"
87+
yarn build --arch="$ARCH"
88+
else
89+
echo "Building for host architecture"
90+
yarn build
91+
fi
8292

8393
echo "Build finished, check gcs/release/${VERSION} for output."

building/windows/build.ps1

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@
1111

1212
Param (
1313
[Parameter(Mandatory = $false)]
14-
[string]$Version
14+
[string]$Version,
15+
[Parameter(Mandatory = $false)]
16+
[string]$Arch
1517
)
1618

1719
Write-Output "Assuming location is FGCS\building\windows"
@@ -98,6 +100,11 @@ if ($LASTEXITCODE -ne 0) {
98100
Write-Error "Failed to generate param definitions"
99101
exit $LASTEXITCODE
100102
}
103+
104+
# Check for second argument (arch) via $Arch parameter
105+
if (-not $Arch) {
106+
$Arch = ""
107+
}
101108
Write-Output "Generated param definitions"
102109

103110
python generate_log_message_descriptions.py
@@ -110,7 +117,15 @@ Write-Output "Generated log message descriptions"
110117
Set-Location ../
111118
yarn
112119
yarn version --new-version $Version --no-git-tag-version --no-commit-hooks
113-
yarn build
120+
121+
# Build with optional arch specification
122+
if ($Arch) {
123+
Write-Output "Building for architecture: $Arch"
124+
yarn build --arch=$Arch
125+
} else {
126+
Write-Output "Building for host architecture"
127+
yarn build
128+
}
114129

115130
if ($LASTEXITCODE -ne 0) {
116131
Write-Error "Yarn build failed with exit code $LASTEXITCODE"

docs/DEVELOPMENT_GUIDE.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,3 +303,48 @@ If you want to re-run the tests without re-building:
303303
```bash
304304
yarn test:nobuild
305305
```
306+
307+
## Automated Desktop Releases
308+
309+
Desktop release artifacts are built automatically when a version tag is pushed.
310+
311+
### Trigger
312+
313+
Push a tag in semver format prefixed with `v`:
314+
315+
```bash
316+
git tag v0.2.8-alpha.1
317+
git push origin v0.2.8-alpha.1
318+
```
319+
320+
The workflow creates or updates a draft GitHub Release and uploads installers.
321+
322+
### Restrict Who Can Release
323+
324+
The workflow enforces two checks before building:
325+
326+
- `RELEASE_ALLOWED_OWNER` must match the repository owner.
327+
- `RELEASE_ALLOWED_ACTOR` must match the GitHub username that pushed the tag.
328+
329+
### Produced Artifacts
330+
331+
- Windows x64: `FGCS-Windows-<version>-Setup.exe`
332+
- macOS x64: `FGCS-Mac-<version>-Installer-x64.dmg`
333+
- macOS arm64: `FGCS-Mac-<version>-Installer-arm64.dmg`
334+
335+
### Publishing
336+
337+
Releases are uploaded as drafts. After validating artifacts, publish the draft release in GitHub.
338+
339+
### Rollback
340+
341+
If a tagged release fails:
342+
343+
1. Delete the tag locally and remotely.
344+
2. Fix the issue.
345+
3. Recreate and push the tag.
346+
347+
```bash
348+
git tag -d v0.2.8-alpha.1
349+
git push origin :refs/tags/v0.2.8-alpha.1
350+
```

gcs/electron-builder.json5

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,43 +2,39 @@
22
* @see https://www.electron.build/configuration/configuration
33
*/
44
{
5-
$schema: 'https://raw.githubusercontent.com/electron-userland/electron-builder/master/packages/app-builder-lib/scheme.json',
6-
appId: 'FGCS',
5+
$schema: "https://raw.githubusercontent.com/electron-userland/electron-builder/master/packages/app-builder-lib/scheme.json",
6+
appId: "FGCS",
77
asar: true,
8-
productName: 'FGCS',
8+
productName: "FGCS",
99
directories: {
10-
output: 'release/${version}',
10+
output: "release/${version}",
1111
},
12-
files: ['dist', 'dist-electron'],
12+
files: ["dist", "dist-electron"],
1313
mac: {
14-
target: ['dmg'],
15-
artifactName: '${productName}-Mac-${version}-Installer.${ext}',
16-
icon: 'build/app_icon.icns'
14+
target: ["dmg"],
15+
artifactName: "${productName}-Mac-${version}-Installer-${arch}.${ext}",
16+
icon: "build/app_icon.icns",
1717
},
1818
win: {
1919
target: [
2020
{
21-
target: 'nsis',
22-
arch: ['x64'],
21+
target: "nsis",
22+
arch: ["x64"],
2323
},
2424
],
25-
artifactName: '${productName}-Windows-${version}-Setup.${ext}',
25+
artifactName: "${productName}-Windows-${version}-Setup.${ext}",
2626
},
2727
nsis: {
2828
oneClick: false,
2929
perMachine: false,
3030
allowToChangeInstallationDirectory: true,
3131
deleteAppDataOnUninstall: false,
3232
},
33-
linux: {
34-
target: ['AppImage'],
35-
artifactName: '${productName}-Linux-${version}.${ext}',
36-
},
3733
extraFiles: [
3834
{
39-
from: 'extras',
40-
to: 'extras',
41-
filter: ['**/*'],
35+
from: "extras",
36+
to: "extras",
37+
filter: ["**/*"],
4238
},
4339
],
4440
}

gcs/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@
99
"version": "0.2.7-alpha",
1010
"license": "GPL-3.0-only",
1111
"homepage": "https://fgcs.projectfalcon.uk",
12-
"githubLink": "https://github.com/Avis-Drone-Labs/FGCS",
12+
"githubLink": "https://github.com/1Blademaster/FGCS",
1313
"bugs": {
14-
"url": "https://github.com/Avis-Drone-Labs/FGCS/issues/new/choose"
14+
"url": "https://github.com/1Blademaster/FGCS/issues/new/choose"
1515
},
1616
"scripts": {
1717
"test": "tsc && vite build && xvfb-maybe yarn playwright test",

0 commit comments

Comments
 (0)