This repository has been archived on 2026-06-02. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
FabledApp/.forgejo/workflows/ci.yml
T
bvandeusen cb5ce44bbe ci: gate on dev/main pushes, pin Flutter, extract release script
- trigger: add branches: [dev, main] so analyze+test run on every
  push, not just release tags. Build job stays tag-gated via
  if: startsWith(github.ref, 'refs/tags/')
- pin Flutter to 3.41.6 instead of floating :stable for reproducible
  release builds
- concurrency: cancel in-progress non-tag runs
- permissions: contents: read default, contents: write scoped to build
- extract release publish logic to scripts/publish_apk_release.sh so
  it's testable locally (bash -x with env vars) and the YAML stays
  readable. Adds set -euo pipefail + curl -f so failures surface
  instead of getting swallowed by || echo "skipped"
- drop the broken artifact upload step (silently swallowed errors)
2026-04-11 16:11:50 -04:00

112 lines
3.9 KiB
YAML

# CI runs first; build only proceeds if all checks pass.
#
# Push to dev or main: flutter analyze + flutter test
# Tag v* (release): gates + signed APK build + attach to Forgejo Release
#
# To cut a release:
# Create a release via the Forgejo UI on main with a v* tag name.
# The tag push triggers this workflow; the build job attaches the APK.
#
# Note: JavaScript actions (actions/checkout, actions/upload-artifact) cannot run
# inside the Flutter container because it has no Node.js. All steps use shell
# commands directly instead.
#
# Required secrets (repo → Settings → Secrets → Actions):
# RELEASE_TOKEN — Forgejo PAT with write:repository scope
# RELEASE_KEYSTORE_BASE64 — base64 of the signing keystore
# RELEASE_KEYSTORE_PASSWORD — keystore + key password
# RELEASE_KEY_ALIAS — key alias within the keystore
name: CI & Build
on:
push:
branches: [dev, main]
tags: ["v*"]
# Cancel older runs on the same branch when a newer push lands. Tag runs
# are never cancelled so a release build can't kill itself mid-flight.
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: ${{ !startsWith(github.ref, 'refs/tags/') }}
# Least-privilege default. The build job upgrades to contents: write
# so it can attach the APK to a Forgejo release.
permissions:
contents: read
jobs:
analyze:
name: Analyze & test
runs-on: py3.12-node22
container:
# Pinned to a specific Flutter version for reproducible builds.
# Floating :stable means a random Flutter minor bump could change
# analyzer output or break the build without any commit landing.
# Bump this line (and verify locally with `flutter --version`)
# when you intentionally want a newer Flutter.
image: ghcr.io/cirruslabs/flutter:3.41.6
steps:
- name: Checkout
run: |
git clone "$GITHUB_SERVER_URL/$GITHUB_REPOSITORY" .
git checkout "$GITHUB_SHA"
- name: Install dependencies
run: flutter pub get
- name: Analyze
run: flutter analyze
- name: Test
run: flutter test
build:
name: Build release APK
needs: [analyze]
# Only tag pushes produce a signed release build. dev/main pushes
# run the gates above and stop there.
if: startsWith(github.ref, 'refs/tags/')
runs-on: py3.12-node22
container:
image: ghcr.io/cirruslabs/flutter:3.41.6
permissions:
contents: write
steps:
- name: Checkout
run: |
git clone "$GITHUB_SERVER_URL/$GITHUB_REPOSITORY" .
git checkout "$GITHUB_SHA"
- name: Install dependencies
run: flutter pub get
- name: Set up release signing
env:
KEYSTORE_B64: ${{ secrets.RELEASE_KEYSTORE_BASE64 }}
STORE_PASSWORD: ${{ secrets.RELEASE_KEYSTORE_PASSWORD }}
KEY_ALIAS: ${{ secrets.RELEASE_KEY_ALIAS }}
run: |
echo "$KEYSTORE_B64" | base64 -d > android/app/release.jks
printf 'storePassword=%s\nkeyPassword=%s\nkeyAlias=%s\nstoreFile=release.jks\n' \
"$STORE_PASSWORD" "$STORE_PASSWORD" "$KEY_ALIAS" > android/key.properties
- name: Build release APK
run: |
# Derive version from the tag (e.g. v26.03.12 → name=26.03.12 number=260312)
TAG="${{ github.ref_name }}"
BUILD_NAME="${TAG#v}"
BUILD_NUMBER=$(echo "$BUILD_NAME" | tr -d '.')
flutter build apk --release \
--build-name="$BUILD_NAME" \
--build-number="$BUILD_NUMBER"
- name: Publish Forgejo release
# Release-publish logic lives in a shell script so it's
# testable locally (bash -x scripts/publish_apk_release.sh
# with env vars set) instead of trapped in YAML.
env:
RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }}
TAG: ${{ github.ref_name }}
APK: build/app/outputs/flutter-apk/app-release.apk
run: bash scripts/publish_apk_release.sh