Skip to content

Allow friends to see which server you are connected to #192

Allow friends to see which server you are connected to

Allow friends to see which server you are connected to #192

Workflow file for this run

name: Build & Release (dev)
on:
push:
branches:
- main
concurrency:
group: build-release-${{ github.ref }}
cancel-in-progress: true
jobs:
build-android:
name: Build Android APK
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/setup-java@v5
with:
distribution: temurin
java-version: '17'
cache: gradle
- uses: subosito/flutter-action@v2
with:
flutter-version: '3.44.0'
channel: stable
cache: true
- name: Cache pub dependencies
uses: actions/cache@v5
with:
path: ~/.pub-cache
key: ${{ runner.os }}-pub-${{ hashFiles('**/pubspec.lock') }}
restore-keys: |
${{ runner.os }}-pub-
- name: Prepare signing keystore
env:
ANDROID_KEYSTORE_BASE64: ${{ secrets.ANDROID_KEYSTORE_BASE64 }}
KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }}
KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
KEY_ALIAS: ${{ secrets.KEY_ALIAS || 'release' }}
run: |
if [ -z "$ANDROID_KEYSTORE_BASE64" ]; then
echo "Missing ANDROID_KEYSTORE_BASE64 in GitHub Secrets."
exit 1
fi
if [ -z "$KEYSTORE_PASSWORD" ] || [ -z "$KEY_PASSWORD" ]; then
echo "Missing KEYSTORE_PASSWORD or KEY_PASSWORD in GitHub Secrets."
exit 1
fi
TEMP_KEYSTORE_PATH="$(mktemp)"
trap 'rm -f "$TEMP_KEYSTORE_PATH"' EXIT
if ! echo "$ANDROID_KEYSTORE_BASE64" | base64 --decode > "$TEMP_KEYSTORE_PATH"; then
echo "Failed to decode ANDROID_KEYSTORE_BASE64. Verify it is valid base64 in GitHub Secrets."
exit 1
fi
if ! mv "$TEMP_KEYSTORE_PATH" android/app-release.jks; then
echo "Failed to write decoded keystore to android/app-release.jks. Verify the android directory is writable."
exit 1
fi
if ! printf '%s\n' "$KEYSTORE_PASSWORD" | keytool -list -keystore android/app-release.jks >/dev/null 2>&1; then
rm -f android/app-release.jks
echo "Keystore validation failed. Verify android/app-release.jks is a readable keystore file and KEYSTORE_PASSWORD is correct for it."
exit 1
fi
if ! printf '%s\n' "$KEYSTORE_PASSWORD" | keytool -list -keystore android/app-release.jks -alias "$KEY_ALIAS" >/dev/null 2>&1; then
rm -f android/app-release.jks
echo "Keystore alias validation failed. Verify KEY_ALIAS exists in the configured keystore."
exit 1
fi
chmod 600 android/app-release.jks
umask 077
printf 'storePassword=%s\nkeyPassword=%s\nkeyAlias=%s\nstoreFile=app-release.jks\n' \
"$KEYSTORE_PASSWORD" "$KEY_PASSWORD" "$KEY_ALIAS" > android/key.properties
chmod 600 android/key.properties
- name: Build APK
run: flutter build apk --release
- uses: actions/upload-artifact@v6
with:
name: android-apk
path: build/app/outputs/flutter-apk/app-release.apk
build-windows:
name: Build Windows EXE
runs-on: windows-latest
steps:
- uses: actions/checkout@v5
- uses: subosito/flutter-action@v2
with:
flutter-version: '3.44.0'
channel: stable
cache: false
- name: Cache pub dependencies
uses: actions/cache@v5
with:
path: ~/AppData/Local/Pub/Cache
key: ${{ runner.os }}-pub-${{ hashFiles('**/pubspec.lock') }}
restore-keys: |
${{ runner.os }}-pub-
- name: Setup CMake 3.x
uses: jwlawson/actions-setup-cmake@v2
with:
cmake-version: '3.31.6'
- name: Build Windows
run: flutter build windows --release
env:
CMAKE_POLICY_VERSION_MINIMUM: "3.5"
- name: Build MSIX
run: dart run msix:create
- name: Zip Windows build
shell: pwsh
run: |
Compress-Archive -Path build/windows/x64/runner/Release/* -DestinationPath MCCompanion-windows.zip
- uses: actions/upload-artifact@v6
with:
name: windows-zip
path: MCCompanion-windows.zip
- uses: actions/upload-artifact@v6
with:
name: windows-msix
path: build/windows/x64/runner/Release/MCCompanion.msix
build-macos:
name: Build macOS DMG
runs-on: macos-latest
steps:
- uses: actions/checkout@v5
- uses: subosito/flutter-action@v2
with:
flutter-version: '3.44.0'
channel: stable
cache: true
- name: Cache pub dependencies
uses: actions/cache@v5
with:
path: ~/.pub-cache
key: ${{ runner.os }}-pub-${{ hashFiles('**/pubspec.lock') }}
restore-keys: |
${{ runner.os }}-pub-
- name: Cache CocoaPods
uses: actions/cache@v5
with:
path: |
~/.cocoapods/repos
~/Library/Caches/CocoaPods
macos/Pods
key: ${{ runner.os }}-cocoapods-${{ hashFiles('macos/Podfile.lock') }}
restore-keys: |
${{ runner.os }}-cocoapods-
- name: Prepare macOS dependency overrides
run: |
cat > pubspec_overrides.yaml <<'EOF'
dependency_overrides:
connectivity_plus: 6.1.4
EOF
flutter pub get
- name: Build macOS
run: flutter build macos --release
env:
FLUTTER_XCODE_CODE_SIGNING_ALLOWED: "NO"
FLUTTER_XCODE_CODE_SIGN_IDENTITY: ""
FLUTTER_XCODE_CODE_SIGNING_REQUIRED: "NO"
- name: Ad-hoc sign macOS app
run: |
APP_PATH="build/macos/Build/Products/Release/MCCompanion.app"
codesign --force --deep --sign - "$APP_PATH"
codesign --verify --deep --strict "$APP_PATH"
- name: Create macOS DMG
run: |
STAGING_DIR="$RUNNER_TEMP/dmg-staging"
APP_PATH="build/macos/Build/Products/Release/MCCompanion.app"
rm -rf "$STAGING_DIR"
mkdir -p "$STAGING_DIR"
cp -R "$APP_PATH" "$STAGING_DIR/"
ln -s /Applications "$STAGING_DIR/Applications"
hdiutil create \
-volname "MCCompanion" \
-srcfolder "$STAGING_DIR" \
-ov \
-format UDZO \
"$GITHUB_WORKSPACE/MCCompanion-macos.dmg"
codesign --force --sign - "$GITHUB_WORKSPACE/MCCompanion-macos.dmg"
codesign --verify --strict "$GITHUB_WORKSPACE/MCCompanion-macos.dmg"
- uses: actions/upload-artifact@v6
with:
name: macos-dmg
path: MCCompanion-macos.dmg
release:
name: Create or Update dev Release
needs: [build-android, build-windows, build-macos]
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/download-artifact@v8
with:
name: android-apk
path: artifacts/
- uses: actions/download-artifact@v8
with:
name: windows-zip
path: artifacts/
- uses: actions/download-artifact@v8
with:
name: windows-msix
path: artifacts/
- uses: actions/download-artifact@v8
with:
name: macos-dmg
path: artifacts/
- name: Rename Android APK
run: mv artifacts/app-release.apk artifacts/MCCompanion-android.apk
- name: Create or update dev release
uses: softprops/action-gh-release@v3
with:
tag_name: dev
name: Development Build
prerelease: true
body: |
Automated development build from commit ${{ github.sha }} on branch `${{ github.ref_name }}`.
This is a development build. If you don't know what you are doing, please don't install it.
Warning: Google/Apple authentication won't work with dev builds.
files: |
artifacts/MCCompanion-android.apk
artifacts/MCCompanion-windows.zip
artifacts/MCCompanion-macos.dmg
artifacts/MCCompanion.msix
notify-discord:
name: Notify Discord
if: ${{ always() }}
needs: [build-android, build-windows, build-macos, release]
runs-on: ubuntu-latest
permissions: {}
steps:
- name: Send build status embed
env:
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
ANDROID_RESULT: ${{ needs.build-android.result }}
WINDOWS_RESULT: ${{ needs.build-windows.result }}
MACOS_RESULT: ${{ needs.build-macos.result }}
RELEASE_RESULT: ${{ needs.release.result }}
REPOSITORY: ${{ github.repository }}
BRANCH: ${{ github.ref_name }}
ACTOR: ${{ github.actor }}
SHA: ${{ github.sha }}
COMMIT_MESSAGE: ${{ github.event.head_commit.message }}
RUN_ID: ${{ github.run_id }}
SERVER_URL: ${{ github.server_url }}
RELEASES_URL: ${{ github.server_url }}/${{ github.repository }}/releases/tag/dev
run: |
if [ -z "$DISCORD_WEBHOOK_URL" ]; then
echo "DISCORD_WEBHOOK_URL is not configured. Skipping Discord notification."
exit 0
fi
OVERALL_STATUS="✅ Build Succeeded"
EMBED_COLOR=5763719
if [ "$ANDROID_RESULT" != "success" ] || [ "$WINDOWS_RESULT" != "success" ] || [ "$MACOS_RESULT" != "success" ] || [ "$RELEASE_RESULT" != "success" ]; then
OVERALL_STATUS="❌ Build Failed"
EMBED_COLOR=15548997
fi
RUN_URL="$SERVER_URL/$REPOSITORY/actions/runs/$RUN_ID"
COMMIT_URL="$SERVER_URL/$REPOSITORY/commit/$SHA"
COMMIT_SUBJECT="$(printf '%s' "$COMMIT_MESSAGE" | head -n 1)"
PAYLOAD="$(jq -n \
--arg overallStatus "$OVERALL_STATUS" \
--arg repository "$REPOSITORY" \
--arg branch "$BRANCH" \
--arg actor "$ACTOR" \
--arg runUrl "$RUN_URL" \
--arg commitUrl "$COMMIT_URL" \
--arg sha "$SHA" \
--arg commitSubject "$COMMIT_SUBJECT" \
--arg android "$ANDROID_RESULT" \
--arg windows "$WINDOWS_RESULT" \
--arg macos "$MACOS_RESULT" \
--arg release "$RELEASE_RESULT" \
--arg releasesUrl "$RELEASES_URL" \
--argjson color "$EMBED_COLOR" \
'{
username: "GitHub Actions",
avatar_url: "https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png",
embeds: [
{
title: $overallStatus,
color: $color,
description: ("**Repository:** `" + $repository + "`\n**Branch:** `" + $branch + "`\n**Triggered by:** `" + $actor + "`"),
author: {
name: "GitHub",
icon_url: "https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png"
},
fields: [
{ name: "Android", value: $android, inline: true },
{ name: "Windows", value: $windows, inline: true },
{ name: "macOS", value: $macos, inline: true },
{ name: "Release", value: $release, inline: true },
{ name: "Commit", value: ("[" + ($sha | .[0:7]) + "](" + $commitUrl + ")" + (if $commitSubject != "" then " " + $commitSubject else "" end)), inline: false },
{ name: "Releases Page", value: ("[View Releases](" + $releasesUrl + ")"), inline: false }
],
url: $runUrl,
timestamp: now | todateiso8601
}
]
}')"
RESPONSE_FILE="$(mktemp)"
HTTP_STATUS="$(curl -sS -o "$RESPONSE_FILE" -w "%{http_code}" -H "Content-Type: application/json" -d "$PAYLOAD" "$DISCORD_WEBHOOK_URL" || true)"
if [ "${HTTP_STATUS:-000}" -lt 200 ] || [ "${HTTP_STATUS:-000}" -ge 300 ]; then
echo "Failed to send Discord notification. HTTP status: ${HTTP_STATUS:-000}"
echo "Response body:"
cat "$RESPONSE_FILE"
exit 1
fi
rm -f "$RESPONSE_FILE"
release-beta:
name: Create or Update beta Release
needs: [build-android, build-windows, build-macos]
if: ${{ needs.build-android.result == 'success' && needs.build-windows.result == 'success' && needs.build-macos.result == 'success' && startsWith(github.event.head_commit.message, '[beta]') }}
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/download-artifact@v8
with:
name: android-apk
path: artifacts/
- uses: actions/download-artifact@v8
with:
name: windows-zip
path: artifacts/
- uses: actions/download-artifact@v8
with:
name: windows-msix
path: artifacts/
- uses: actions/download-artifact@v8
with:
name: macos-dmg
path: artifacts/
- name: Rename Android APK
run: mv artifacts/app-release.apk artifacts/MCCompanion-android.apk
- name: Create or update beta release
uses: softprops/action-gh-release@v3
with:
tag_name: beta
target_commitish: ${{ github.sha }}
name: Beta Build
prerelease: true
body: |
Automated beta build from commit ${{ github.sha }} on branch `${{ github.ref_name }}`.
This is a beta build intended for testing before wider release.
Warning: Google/Apple authentication won't work with beta builds.
files: |
artifacts/MCCompanion-android.apk
artifacts/MCCompanion-windows.zip
artifacts/MCCompanion-macos.dmg
artifacts/MCCompanion.msix
notify-discord-beta:
name: Notify Discord Beta Release
needs: [release-beta]
if: ${{ needs.release-beta.result == 'success' }}
runs-on: ubuntu-latest
permissions: {}
steps:
- name: Send beta release embed
env:
DISCORD_BETA_WEBHOOK_URL: ${{ secrets.DISCORD_BETA_WEBHOOK_URL }}
REPOSITORY: ${{ github.repository }}
ACTOR: ${{ github.actor }}
SHA: ${{ github.sha }}
COMMIT_MESSAGE: ${{ github.event.head_commit.message }}
RUN_ID: ${{ github.run_id }}
SERVER_URL: ${{ github.server_url }}
BETA_RELEASE_URL: ${{ github.server_url }}/${{ github.repository }}/releases/tag/beta
run: |
if [ -z "$DISCORD_BETA_WEBHOOK_URL" ]; then
echo "DISCORD_BETA_WEBHOOK_URL is not configured. Skipping Discord beta notification."
exit 0
fi
ROLE_ID="1485783465365344316"
RUN_URL="$SERVER_URL/$REPOSITORY/actions/runs/$RUN_ID"
COMMIT_URL="$SERVER_URL/$REPOSITORY/commit/$SHA"
COMMIT_SUBJECT="$(printf '%s' "$COMMIT_MESSAGE" | head -n 1)"
PAYLOAD="$(jq -n \
--arg roleId "$ROLE_ID" \
--arg betaReleaseUrl "$BETA_RELEASE_URL" \
--arg commitUrl "$COMMIT_URL" \
--arg sha "$SHA" \
--arg commitSubject "$COMMIT_SUBJECT" \
--arg runUrl "$RUN_URL" \
--arg actor "$ACTOR" \
'{
content: ("<@&" + $roleId + ">"),
allowed_mentions: {
roles: [$roleId]
},
username: "GitHub Actions",
avatar_url: "https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png",
embeds: [
{
title: "🚀 New Beta Release Available",
url: $betaReleaseUrl,
color: 5793266,
description: ("Hello, <@&" + $roleId + ">, we have a new beta release ready. Check it out on our [beta release](" + $betaReleaseUrl + ")."),
author: {
name: "MCCompanion Beta Releases",
icon_url: "https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png"
},
fields: [
{ name: "Commit", value: ("[" + ($sha | .[0:7]) + "](" + $commitUrl + ")" + (if $commitSubject != "" then " " + $commitSubject else "" end)), inline: false },
{ name: "Platforms", value: "Android • Windows • macOS", inline: true },
{ name: "Download links", value: ("[Beta release](" + $betaReleaseUrl + ")"), inline: true },
{ name: "Triggered by", value: $actor, inline: true },
{ name: "Workflow", value: ("[View run](" + $runUrl + ")"), inline: true }
],
footer: {
text: "MCCompanion beta release"
},
timestamp: now | todateiso8601
}
]
}')"
RESPONSE_FILE="$(mktemp)"
HTTP_STATUS="$(curl -sS -o "$RESPONSE_FILE" -w "%{http_code}" -H "Content-Type: application/json" -d "$PAYLOAD" "$DISCORD_BETA_WEBHOOK_URL")"
CURL_EXIT_CODE=$?
if [ "$CURL_EXIT_CODE" -ne 0 ]; then
echo "Failed to send Discord beta release notification with curl exit code: $CURL_EXIT_CODE"
exit "$CURL_EXIT_CODE"
fi
if [ "${HTTP_STATUS:-000}" -lt 200 ] || [ "${HTTP_STATUS:-000}" -ge 300 ]; then
echo "Failed to send Discord beta release notification. HTTP status: ${HTTP_STATUS:-000}"
echo "Response body:"
cat "$RESPONSE_FILE"
exit 1
fi
rm -f "$RESPONSE_FILE"