Skip to content

Updates firmware and version in repository #160

Updates firmware and version in repository

Updates firmware and version in repository #160

Workflow file for this run

name: Build and Release Applications
on:
push:
branches:
- develop
workflow_dispatch:
env:
STRAVA_CLIENT_ID: ${{ secrets.STRAVA_CLIENT_ID }}
STRAVA_CLIENT_SECRET: ${{ secrets.STRAVA_CLIENT_SECRET }}
jobs:
prepare:
runs-on: ubuntu-latest
outputs:
version: ${{ steps.set_version.outputs.version }}
steps:
- uses: actions/checkout@v2
# Download and extract latest SmartSpin2k firmware.bin from GitHub release
- name: Download and extract latest SmartSpin2k firmware
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -e
mkdir -p assets
# Get latest release info
release_json=$(curl -s -H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/doudar/SmartSpin2k/releases/latest)
# Find .bin.zip asset URL
asset_url=$(echo "$release_json" | grep 'browser_download_url' | grep '.bin.zip' | head -n1 | cut -d '"' -f4)
if [ -z "$asset_url" ]; then
echo "No .bin.zip asset found in latest release!" >&2
exit 1
fi
echo "Downloading: $asset_url"
curl -L -o /tmp/firmware.zip "$asset_url"
unzip -o /tmp/firmware.zip -d /tmp/firmware_extracted
if [ ! -f /tmp/firmware_extracted/firmware.bin ]; then
echo "firmware.bin not found in zip!" >&2
exit 1
fi
mv /tmp/firmware_extracted/firmware.bin assets/firmware.bin
echo "Firmware placed at assets/firmware.bin"
# Extract version tag and write to assets/version.txt
version_tag=$(echo "$release_json" | grep '"tag_name"' | head -n1 | cut -d '"' -f4)
if [ -z "$version_tag" ]; then
echo "No version tag found in release!" >&2
exit 1
fi
echo "$version_tag" > assets/version.txt
echo "Version written to assets/version.txt: $version_tag"
# Commit and push firmware.bin and version.txt to the repository
- name: Commit and push updated firmware and version
if: github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/main'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -e
git config --global user.name "github-actions[bot]"
git config --global user.email "github-actions[bot]@users.noreply.github.com"
git fetch origin
git checkout ${{ github.ref_name }}
git add assets/firmware.bin assets/version.txt
if git diff --cached --quiet; then
echo "No changes to commit."
exit 0
fi
git commit -m "chore: update firmware.bin and version.txt from latest SmartSpin2k release"
git push origin HEAD:${{ github.ref_name }}
- name: Extract version from pubspec.yaml
id: extract_version
run: |
VERSION=$(grep 'version: ' pubspec.yaml | sed 's/version: //')
echo "VERSION=${VERSION}" >> $GITHUB_ENV
- name: Check if tag exists
id: check_tag
run: |
TAG_EXISTS=$(git tag -l "$VERSION")
if [[ "$TAG_EXISTS" == "$VERSION" ]]; then
SUFFIX=1
NEW_TAG="$VERSION-$SUFFIX"
while [[ $(git tag -l "$NEW_TAG") == "$NEW_TAG" ]]; do
SUFFIX=$((SUFFIX+1))
NEW_TAG="$VERSION-$SUFFIX"
done
echo "NEW_TAG=$NEW_TAG" >> $GITHUB_ENV
else
echo "NEW_TAG=$VERSION" >> $GITHUB_ENV
fi
- name: Set output
id: set_version
run: echo "::set-output name=version::$NEW_TAG"
build-android:
needs: prepare
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup Java
uses: actions/setup-java@v2
with:
java-version: '17'
distribution: 'temurin'
- name: Setup Flutter
uses: subosito/flutter-action@v1
with:
flutter-version: '3.22.3'
- name: Create env.local.dart
env:
STRAVA_CLIENT_ID: ${{ secrets.STRAVA_CLIENT_ID }}
STRAVA_CLIENT_SECRET: ${{ secrets.STRAVA_CLIENT_SECRET }}
run: |
mkdir -p lib/config
umask 077
cat > lib/config/env.local.dart <<EOL
class Environment {
static const String stravaClientId = '${STRAVA_CLIENT_ID}';
static const String stravaClientSecret = '${STRAVA_CLIENT_SECRET}';
static bool get hasStravaConfig =>
stravaClientId.isNotEmpty && stravaClientSecret.isNotEmpty;
}
EOL
# Replace environment variables
envsubst < lib/config/env.local.dart > lib/config/env.local.dart.tmp
mv lib/config/env.local.dart.tmp lib/config/env.local.dart
- name: Build Android APK
run: flutter build apk --no-tree-shake-icons
- name: Create artifacts
run: |
mkdir -p artifacts
mv build/app/outputs/flutter-apk/app-release.apk artifacts/ss2kconfigapp-${{ needs.prepare.outputs.version }}.apk
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: android-artifacts
path: artifacts/
build-macos:
needs: prepare
runs-on: macos-latest
steps:
- uses: actions/checkout@v2
- name: Setup Flutter
uses: subosito/flutter-action@v1
with:
flutter-version: '3.22.3'
# Debug environment variables
- name: Debug Environment Variables
run: |
echo "Checking environment variables (secrets will be masked):"
env | grep -i STRAVA || true
- name: Create env.local.dart
env:
STRAVA_CLIENT_ID: ${{ secrets.STRAVA_CLIENT_ID }}
STRAVA_CLIENT_SECRET: ${{ secrets.STRAVA_CLIENT_SECRET }}
run: |
mkdir -p lib/config
umask 077
cat > lib/config/env.local.dart << \EOL
class Environment {
static const String stravaClientId = '${STRAVA_CLIENT_ID}';
static const String stravaClientSecret = '${STRAVA_CLIENT_SECRET}';
static bool get hasStravaConfig =>
stravaClientId.isNotEmpty && stravaClientSecret.isNotEmpty;
}
EOL
# Replace environment variables
envsubst < lib/config/env.local.dart > lib/config/env.local.dart.tmp
mv lib/config/env.local.dart.tmp lib/config/env.local.dart
# Verify file exists but don't show contents
ls -l lib/config/env.local.dart
- name: Build iOS App
run: flutter build ios --release --no-codesign --no-tree-shake-icons
- name: Build macOS App
run: flutter build macos --release --no-tree-shake-icons
- name: Create artifacts
run: |
mkdir -p artifacts
zip -r artifacts/ss2kconfigapp-${{ needs.prepare.outputs.version }}.zip build/ios/iphoneos build/macos/Build/Products/Release
# Clean up sensitive files
- name: Clean up env.local.dart
if: always()
run: |
if [ -f lib/config/env.local.dart ]; then
rm lib/config/env.local.dart
echo "Cleaned up env.local.dart"
fi
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: macos-artifacts
path: artifacts/
build-linux:
needs: prepare
runs-on: ubuntu-latest
strategy:
matrix:
arch: [amd64, arm64]
steps:
- uses: actions/checkout@v2
- name: Setup Flutter
uses: subosito/flutter-action@v1
with:
flutter-version: '3.22.3'
- name: Create env.local.dart
env:
STRAVA_CLIENT_ID: ${{ secrets.STRAVA_CLIENT_ID }}
STRAVA_CLIENT_SECRET: ${{ secrets.STRAVA_CLIENT_SECRET }}
run: |
mkdir -p lib/config
umask 077
cat > lib/config/env.local.dart <<EOL
class Environment {
static const String stravaClientId = '${STRAVA_CLIENT_ID}';
static const String stravaClientSecret = '${STRAVA_CLIENT_SECRET}';
static bool get hasStravaConfig =>
stravaClientId.isNotEmpty && stravaClientSecret.isNotEmpty;
}
EOL
# Replace environment variables
envsubst < lib/config/env.local.dart > lib/config/env.local.dart.tmp
mv lib/config/env.local.dart.tmp lib/config/env.local.dart
- name: Set up QEMU
if: matrix.arch == 'arm64'
uses: docker/setup-qemu-action@v3
with:
platforms: arm64
- name: Install Linux dependencies
run: |
if [ "${{ matrix.arch }}" = "arm64" ]; then
# For arm64, use container-based build
docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
docker run --platform linux/arm64 --rm -v $(pwd):/work -w /work ubuntu:22.04 /bin/bash -c '
apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \
libgtk-3-dev libx11-dev pkg-config cmake ninja-build \
libblkid-dev liblzma-dev libsecret-1-dev libjsoncpp-dev \
libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libunwind-dev \
build-essential
'
else
# For amd64, install normally
sudo apt-get update
sudo apt-get install -y \
libgtk-3-dev libx11-dev pkg-config cmake ninja-build \
libblkid-dev liblzma-dev libsecret-1-dev libjsoncpp-dev \
libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libunwind-dev
fi
- name: Enable Linux Desktop
run: flutter config --enable-linux-desktop
- name: Build Linux App (AMD64)
if: matrix.arch == 'amd64'
run: |
# Install dependencies
sudo apt-get update
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y \
clang cmake ninja-build pkg-config libgtk-3-dev \
liblzma-dev libstdc++-12-dev \
libsecret-1-dev libjsoncpp-dev \
libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev \
libunwind-dev libglu1-mesa fontconfig libpulse0 libasound2t64
# Set environment variables
export CXX=clang++
# Configure Flutter
flutter config --no-analytics
# Get dependencies and build
flutter pub get
flutter build linux \
--release \
--no-tree-shake-icons \
-v
- name: Build Linux App (ARM64)
if: matrix.arch == 'arm64'
run: |
# Create Dockerfile
echo "FROM --platform=linux/arm64 ubuntu:22.04" > Dockerfile.arm64
echo "RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \\" >> Dockerfile.arm64
echo " curl git unzip xz-utils zip libglu1-mesa cmake ninja-build clang \\" >> Dockerfile.arm64
echo " libgtk-3-dev libx11-dev pkg-config \\" >> Dockerfile.arm64
echo " libblkid-dev liblzma-dev libsecret-1-dev libjsoncpp-dev \\" >> Dockerfile.arm64
echo " libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libunwind-dev \\" >> Dockerfile.arm64
echo " wget xz-utils libglu1-mesa \\" >> Dockerfile.arm64
echo " libgtk-3-0 libblkid1 liblzma5 libsecret-1-0 libjsoncpp25 \\" >> Dockerfile.arm64
echo " libgstreamer1.0-0 libgstreamer-plugins-base1.0-0 libunwind8 \\" >> Dockerfile.arm64
echo " fontconfig libpulse0 libasound2 gettext-base" >> Dockerfile.arm64
echo "RUN git clone https://github.com/flutter/flutter.git -b 3.22.3 /flutter" >> Dockerfile.arm64
echo "ENV PATH=\"/flutter/bin:$PATH\"" >> Dockerfile.arm64
echo "RUN flutter doctor" >> Dockerfile.arm64
echo "RUN flutter config --no-analytics" >> Dockerfile.arm64
echo "RUN flutter config --enable-linux-desktop" >> Dockerfile.arm64
echo "RUN flutter precache --linux" >> Dockerfile.arm64
echo "WORKDIR /work" >> Dockerfile.arm64
echo "ENV FLUTTER_ROOT=/flutter" >> Dockerfile.arm64
echo "ENV CXX=clang++" >> Dockerfile.arm64
# Build Docker image
docker build --platform linux/arm64 -t flutter-arm64-builder -f Dockerfile.arm64 .
# Run build in container
docker run --platform linux/arm64 --rm -v $(pwd):/work flutter-arm64-builder /bin/bash -c '
mkdir -p lib/config
if [ ! -f lib/config/env.local.dart ]; then
echo "Error: env.local.dart not found!"
exit 1
fi
flutter pub get
flutter build linux --release --no-tree-shake-icons --target-platform=linux-arm64 -v
if [ ! -d build/linux/arm64/release/bundle ]; then
echo "Error: Build output not found!"
exit 1
fi
'
# Organize build output
if [ -d build/linux/arm64/release/bundle ]; then
mkdir -p build/linux/arm64/release/
rm -rf build/linux/x64
fi
- name: Create Debian Package
run: |
# Create package directory structure
mkdir -p debian/DEBIAN
mkdir -p debian/usr/bin
mkdir -p debian/usr/share/applications
mkdir -p debian/usr/share/icons/hicolor/256x256/apps
# Create control file
cat > debian/DEBIAN/control <<EOL
Package: ss2kconfigapp
Version: ${{ needs.prepare.outputs.version }}
Section: utils
Priority: optional
Architecture: ${{ matrix.arch }}
Maintainer: SmartSpin2k Team
Description: SmartSpin2k Configuration Application
A Flutter application for configuring and controlling SmartSpin2k devices.
EOL
# Copy application files based on architecture
BUILD_PATH=""
if [ "${{ matrix.arch }}" = "arm64" ]; then
BUILD_PATH="build/linux/arm64/release/bundle"
else
BUILD_PATH="build/linux/x64/release/bundle"
fi
# Verify build path exists
if [ ! -d "$BUILD_PATH" ]; then
echo "Error: Build output not found at $BUILD_PATH"
ls -la build/linux/
exit 1
fi
# Copy files
echo "Copying files from $BUILD_PATH to debian/usr/bin/"
cp -rv "$BUILD_PATH"/* debian/usr/bin/
# Copy icon
cp assets/icons/ss2kv3.png debian/usr/share/icons/hicolor/256x256/apps/ss2kconfigapp.png
# Create desktop file
cat > debian/usr/share/applications/ss2kconfigapp.desktop <<EOL
[Desktop Entry]
Name=SmartSpin2k Config App
Exec=/usr/bin/ss2kconfigapp
Icon=ss2kconfigapp
Type=Application
Categories=Utility;
EOL
# Set permissions
chmod 755 debian/usr/bin/ss2kconfigapp
chmod -R 755 debian/DEBIAN
# Build the package with architecture in filename
dpkg-deb --build debian ss2kconfigapp-${{ matrix.arch }}.deb
- name: Create artifacts
run: |
mkdir -p artifacts
mv ss2kconfigapp-${{ matrix.arch }}.deb artifacts/
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: linux-artifacts-${{ matrix.arch }}
path: artifacts/
create-release:
needs: [prepare, build-android, build-macos, build-linux]
runs-on: ubuntu-latest
steps:
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: all-artifacts
- name: Prepare release bundle
run: |
mkdir -p release
cp all-artifacts/android-artifacts/ss2kconfigapp-${{ needs.prepare.outputs.version }}.apk release/ss2kconfigapp-${{ needs.prepare.outputs.version }}.apk
cp all-artifacts/macos-artifacts/ss2kconfigapp-${{ needs.prepare.outputs.version }}.zip release/
cp all-artifacts/linux-artifacts-amd64/ss2kconfigapp-amd64.deb release/ss2kconfigapp-${{ needs.prepare.outputs.version }}-amd64.deb
cp all-artifacts/linux-artifacts-arm64/ss2kconfigapp-arm64.deb release/ss2kconfigapp-${{ needs.prepare.outputs.version }}-arm64.deb
- name: Create release
uses: softprops/action-gh-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ needs.prepare.outputs.version }}
name: SmartSpin2kConfigApp ${{ needs.prepare.outputs.version }}
draft: false
prerelease: false
generate_release_notes: true
body: ${{ github.event.head_commit.message }}
files: |
release/ss2kconfigapp-${{ needs.prepare.outputs.version }}.apk
release/ss2kconfigapp${{ needs.prepare.outputs.version }}.zip
release/ss2kconfigapp-${{ needs.prepare.outputs.version }}-amd64.deb
release/ss2kconfigapp-${{ needs.prepare.outputs.version }}-arm64.deb