Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ci: add macOS + Windows + Linux build #15

Merged
merged 8 commits into from
Feb 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 74 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
name: Build Launcher
on:
pull_request:
push:
branches:
- "main"

jobs:
build:
# both Windows and Linux builds run on Ubuntu
runs-on: ${{ matrix.build == 'macos' && 'macos' || 'ubuntu' }}-latest
strategy:
fail-fast: false
matrix:
build: [macos, windows, linux]

steps:
- uses: actions/checkout@v3

- uses: chickensoft-games/setup-godot@v1
with:
version: 4.2.1
use-dotnet: false

- name: Verify Setup
run: |
godot --version

- name: Import certificate to Keychain
if: ${{ matrix.build == 'macos' }}
run: |
echo "${{ secrets.MACOS_CERTIFICATE }}" | base64 --decode > certificate.p12
KEYCHAIN_PASSWORD=$(uuidgen)
security create-keychain -p "$KEYCHAIN_PASSWORD" build.keychain
security default-keychain -s build.keychain
security unlock-keychain -p "$KEYCHAIN_PASSWORD" build.keychain
security import ./certificate.p12 -k ~/Library/Keychains/build.keychain -P ${{ secrets.MACOS_CERTIFICATE_PASSWORD }} -T /usr/bin/codesign
security set-key-partition-list -S apple-tool:,apple: -s -k "$KEYCHAIN_PASSWORD" ~/Library/Keychains/build.keychain
env:
MACOS_CERTIFICATE_PASSWORD: ${{ secrets.MACOS_CERTIFICATE_PASSWORD }}

- name: Setup notarization credentials
if: ${{ matrix.build == 'macos' }}
run: |
echo ${{ secrets.GODOT_MACOS_NOTARIZATION_API_KEY }} | base64 --decode > notarization_api_key.p8

- name: Export build
run: |
name="${{fromJSON('{"windows": "Windows Desktop", "macos": "macOS", "linux": "Linux/X11"}')[matrix.build] }}"
godot --headless --export-debug "$name" --verbose 2>&1 | tee build.log

env:
GODOT_MACOS_NOTARIZATION_API_KEY_ID:
${{ secrets.GODOT_MACOS_NOTARIZATION_API_KEY_ID }}
GODOT_MACOS_NOTARIZATION_API_KEY: ./notarization_api_key.p8
GODOT_MACOS_NOTARIZATION_API_UUID:
${{ secrets.GODOT_MACOS_NOTARIZATION_API_UUID }}

- name: Upload build
uses: actions/upload-artifact@v4
with:
name: drivechain_launcher_${{ matrix.build }}
if-no-files-found: error
path: build/drivechain_launcher-*

- name: Wait for notarization to finish
if: ${{ matrix.build == 'macos' }}
run: |
request_id=$(grep 'Notarization request UUID' build.log | rev | cut -d ' ' -f 1 | rev | tr -d '"')

xcrun notarytool wait $request_id \
--issuer ${{ secrets.GODOT_MACOS_NOTARIZATION_API_UUID }} \
--key-id ${{ secrets.GODOT_MACOS_NOTARIZATION_API_KEY_ID }} \
--key ./notarization_api_key.p8
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
# Godot 4+ specific ignores
.godot/

# Built artifacts go here
build
1 change: 1 addition & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"proseWrap": "always"}
162 changes: 128 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,61 +4,155 @@

This application is built using [Godot](https://github.com/godotengine/godot).

Godot may seem like an odd choice at first glance, but with its cross-platform abilities and an amazing set of GUI & IO features, it makes it very capable for this application.
Godot may seem like an odd choice at first glance, but with its cross-platform
abilities and an amazing set of GUI & IO features, it makes it very capable for
this application.

We can currently run on Mac, Windows, and Linux.

If you'd like to build from source, check below.

## Development Environment Prerequisites

- Godot 4.1.1 [Download Page](https://godotengine.org/download)
- Godot 4.2.1 [Download Page](https://godotengine.org/download)

Currently only scripted in GDScript, but we could use the .NET version of Godot which brings C# support.
```bash
# macOS
$ brew install godot

Once you've gotten your development environment set up:
# Ubuntu/Debian
$ snap install godot-4 # note: this gets installed as godot-4, not godot

- Clone repo
- Open the project and run
# Windows
$ choco install godot
```

### Important
## Getting started

The app relies on external binaries to be downloaded from a specific GitHub release. This is a bit cumbersome,
but was the best we could come up with for now.
Ensure that `godot` is installed such that is in on your `$PATH`.

- chain_providers.cfg are where each of the sidechain configs starts.
The hash and file size for each platform binary is manually generated and added to the config
for the release if it has changed.
- version.cfg is where you would update the version and base GitHub release URL.
Sometimes you may need to create a pre-release, upload all the binaries there and point to that
as you are developing.
- Currently, each platform version is built on its respective platform. So build the launcher for Linux on Linux,
Mac on Mac, and Windows on Windows.
- Mac is a bit different as you need to have a developer ID certificate so that Godot can request a signature and
notarization. Whoever does this will need to create a signing certificate request and have Paul then create a
new developer ID certificate with that request. Then you would install that into your Mac keychain.
More info here: https://developer.apple.com/help/account/create-certificates/create-developer-id-certificates
For building releases, so-called "export templates" has to be downloaded. These
are available from the official
[website](https://github.com/godotengine/godot/releases/download/4.2.1-stable/Godot_v4.2.1-stable_export_templates.tpz).
Note that these are unique per version of Godot, but _not_ unique per platform
we're exporting for.

From the GUI, these templates can be downloaded like this:

1. "Project" menu in the toolbar
2. "Export" item within the "Project" menu
3. "Download and install"

### LICENSE
## Important

The app relies on external binaries to be downloaded from a specific GitHub
release. This is a bit cumbersome, but was the best we could come up with for
now.

- chain_providers.cfg are where each of the sidechain configs starts. The hash
and file size for each platform binary is manually generated and added to the
config for the release if it has changed.
- version.cfg is where you would update the version and base GitHub release URL.
Sometimes you may need to create a pre-release, upload all the binaries there
and point to that as you are developing.
- Currently, each platform version is built on its respective platform. So build
the launcher for Linux on Linux, Mac on Mac, and Windows on Windows.
- Mac is a bit different as you need to have a developer ID certificate so that
Godot can request a signature and notarization. Whoever does this will need to
create a signing certificate request and have Paul then create a new developer
ID certificate with that request. Then you would install that into your Mac
keychain. More info here:
https://developer.apple.com/help/account/create-certificates/create-developer-id-certificates

## Export preset notes

The file `export_presets.cfg` controls the export (i.e. build) process for the
Launcher. It is controlled through the Godot GUI. If you write comments in the
file, they will get **erased** once the file is saved. Furthermore, enums are
represented as numbers, not strings...

`export_presets.cfg` is kept in Git. This file does not contain anything
sensitive. It is _merged_ with `.godot/export_credentials.cfg`, which _does_
contain sensitive information. This file is also merged with certain environment
variables, such that this can be done on CI without fiddling around with files.

### macOS

Signing (and therefore also notarizing) the application requires having the
correct set of certificates + private keys on the machine doing the export.
Certificates can be viewed using `Keychain Access.app`. Seeing certificates
capable of signing (i.e. certificates with private keys):

```bash
$ security find-identity -v -p codesigning | grep LayerTwo`
```

Notarizing the app requires an App Store Connect API key. Docs for generating
this can be found
[here](https://developer.apple.com/documentation/appstoreconnectapi/creating_api_keys_for_app_store_connect_api).
There's three components to this key, which should go into
`.godot/export_credentials.cfg` before exporting:

1. Issuer ID (`notarization/api_uuid`). This is an UUID indicating which
organization the key belongs to. This is available over the
[list of active keys](https://appstoreconnect.apple.com/access/integrations/api).
2. The key itself (`notarization/api_key`). This is a path to a `.p8` file, and
can only be obtained when creating the key.
3. Key ID (`notarization/api_key_id`). This is available in the
[list of active keys](https://appstoreconnect.apple.com/access/integrations/api).

Explanation of export config file options:

```
export/distribution_type
0=testing ?
1=distribution
2=app store

codesign/codesign
0=disabled
1=built-in ad-hoc
2=rcodesign ruby tool for exporting from Linux
3=Xcode codesign

notarization/notarization
0=disabled
2=xcrun notarytool
```

Generate App Store Connect API keys:

Download the key somewhere

Docs on macOS:
https://docs.godotengine.org/en/stable/tutorials/export/exporting_for_macos.html

### Windows

Signing (is that the correct Windows nomenclature?) of the build artifacts does
not happen in our pipeline. This leads to a scary pop-up warning the user when
they try and launch the app. This could probably be set up, somehow. Left as an
exercise to the reader!

## LICENSE

MIT License

Copyright (c) 2023 Layer Two Labs

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Empty file added build/.gitkeep
Empty file.
10 changes: 5 additions & 5 deletions export_presets.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ custom_features=""
export_filter="all_resources"
include_filter="*.cfg"
exclude_filter=""
export_path="../../../../../Desktop/drivechain_launcher-linux-1.2.0.x86_64"
export_path="build/drivechain_launcher-linux-1.2.0.x86_64"
encryption_include_filters=""
encryption_exclude_filters=""
encrypt_pck=false
Expand Down Expand Up @@ -48,7 +48,7 @@ custom_features=""
export_filter="all_resources"
include_filter="*.cfg"
exclude_filter=""
export_path="../../../../../Desktop/windows-drivenet-launcher-1.2.0.exe"
export_path="./build/drivechain_launcher-windows-1.2.0.exe"
encryption_include_filters=""
encryption_exclude_filters=""
encrypt_pck=false
Expand Down Expand Up @@ -111,7 +111,7 @@ custom_features=""
export_filter="all_resources"
include_filter="*.cfg"
exclude_filter=""
export_path="../../../Desktop/drivechain_launcher-osx64-1.2.0.dmg"
export_path="build/drivechain_launcher-osx64-1.2.0.dmg"
encryption_include_filters=""
encryption_exclude_filters=""
encrypt_pck=false
Expand Down Expand Up @@ -142,7 +142,7 @@ xcode/sdk_build="22C55"
xcode/sdk_name="macosx13.1"
xcode/xcode_version="1420"
xcode/xcode_build="14C18"
codesign/codesign=2
codesign/codesign=3
codesign/installer_identity=""
codesign/apple_team_id="6AXPP357T2"
codesign/identity="Developer ID Application: LayerTwo Labs, Inc. (6AXPP357T2)"
Expand Down Expand Up @@ -171,7 +171,7 @@ codesign/entitlements/app_sandbox/files_movies=0
codesign/entitlements/app_sandbox/files_user_selected=0
codesign/entitlements/app_sandbox/helper_executables=[]
codesign/custom_options=PackedStringArray()
notarization/notarization=1
notarization/notarization=2
privacy/microphone_usage_description=""
privacy/microphone_usage_description_localized={}
privacy/camera_usage_description=""
Expand Down
Loading