Skip to content
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
58 changes: 58 additions & 0 deletions .github/actions/setup-flutter-workspace/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
name: Setup Flutter workspace
description: Flutter toolchain, pub cache and melos bootstrap, optionally stamping the release version into app/pubspec.yaml.

inputs:
channel:
description: Flutter channel passed to subosito/flutter-action.
required: false
default: stable
version:
description: When set, writes this version into app/pubspec.yaml after bootstrap.
required: false
default: ""

runs:
using: composite
steps:
- uses: subosito/flutter-action@v2
with:
channel: ${{ inputs.channel }}
cache: true

- name: Cache pub dependencies
uses: actions/cache@v6
with:
# Windows keeps the pub cache under LOCALAPPDATA, not ~/.pub-cache.
path: |
~/.pub-cache
~/AppData/Local/Pub/Cache
key: ${{ runner.os }}-pub-${{ hashFiles('**/pubspec.yaml') }}
restore-keys: ${{ runner.os }}-pub-

- name: Install Melos
shell: bash
run: dart pub global activate melos

# Invoked through dart: on Windows the entry point is melos.bat, and
# git bash does not resolve .bat from PATH.
- name: Bootstrap workspace
shell: bash
run: dart pub global run melos:melos bootstrap

# Must run after the cache step: the cache key hashes every pubspec.yaml.
- name: Stamp version into app/pubspec.yaml
if: inputs.version != ''
shell: bash
env:
VERSION: ${{ inputs.version }}
run: |
set -euo pipefail
tmp="$(mktemp)"
sed "s/^version:.*/version: ${VERSION}/" app/pubspec.yaml > "$tmp"
mv "$tmp" app/pubspec.yaml
if [[ "$(grep -m1 '^version:' app/pubspec.yaml)" != "version: ${VERSION}" ]]; then
echo "::error::Failed to stamp version ${VERSION} into app/pubspec.yaml"
grep -m1 '^version:' app/pubspec.yaml
exit 1
fi
echo "app/pubspec.yaml -> version: ${VERSION}"
38 changes: 38 additions & 0 deletions .github/actions/setup-linux-build-deps/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: Setup Linux build dependencies
description: APT packages required to build and package CopyPaste on Linux, plus a toolchain preflight.

runs:
using: composite
steps:
- name: Install Linux build dependencies
shell: bash
run: |
set -euo pipefail
sudo apt-get update
sudo apt-get install -y \
clang \
cmake \
desktop-file-utils \
libayatana-appindicator3-dev \
libfuse2 \
libgtk-3-dev \
libkeybinder-3.0-dev \
liblzma-dev \
libx11-dev \
libxtst-dev \
lld-14 \
ninja-build \
patchelf \
pkg-config \
rpm

- name: Verify Linux toolchain preflight
shell: bash
run: |
set -euo pipefail
test -x /usr/lib/llvm-14/bin/ld.lld || test -x /usr/bin/ld.lld-14 || test -x /usr/bin/ld.lld
pkg-config --modversion gtk+-3.0
pkg-config --modversion keybinder-3.0
pkg-config --modversion ayatana-appindicator3-0.1
pkg-config --modversion x11
pkg-config --modversion xtst
141 changes: 28 additions & 113 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
name: Markdown Lint

steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7

- name: Lint Markdown files
uses: DavidAnson/markdownlint-cli2-action@v19
Expand All @@ -35,25 +35,9 @@ jobs:
name: Lint, Format & Test

steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7

- uses: subosito/flutter-action@v2
with:
channel: stable
cache: true

- name: Cache pub dependencies
uses: actions/cache@v5
with:
path: ~/.pub-cache
key: ${{ runner.os }}-pub-${{ hashFiles('**/pubspec.yaml') }}
restore-keys: ${{ runner.os }}-pub-

- name: Install Melos
run: dart pub global activate melos

- name: Bootstrap
run: melos bootstrap
- uses: ./.github/actions/setup-flutter-workspace

- name: Check formatting
run: dart format --output=none --set-exit-if-changed .
Expand Down Expand Up @@ -85,7 +69,7 @@ jobs:
run: melos run test:coverage

- name: Upload coverage artifacts
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@v7
if: always()
with:
name: coverage-reports
Expand All @@ -109,7 +93,7 @@ jobs:
name: Release Readiness

steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7

- name: Validate pubspec structure
run: |
Expand All @@ -130,7 +114,7 @@ jobs:
echo "::error::Missing name field in $pkg/pubspec.yaml"
errors=$((errors + 1))
fi
echo " $pkg: name=$name version=$version"
echo "OK $pkg: name=$name version=$version"
done
[ $errors -eq 0 ] || exit 1

Expand All @@ -142,7 +126,15 @@ jobs:
echo "::error::Missing .github/workflows/$wf (referenced by release.yml)"
errors=$((errors + 1))
else
echo "✓ .github/workflows/$wf"
echo "OK .github/workflows/$wf"
fi
done
for act in setup-flutter-workspace setup-linux-build-deps; do
if [ ! -f ".github/actions/$act/action.yml" ]; then
echo "::error::Missing .github/actions/$act/action.yml (referenced by the build jobs)"
errors=$((errors + 1))
else
echo "OK .github/actions/$act/action.yml"
fi
done
[ $errors -eq 0 ] || exit 1
Expand All @@ -155,15 +147,15 @@ jobs:
echo "::error::Missing required directory: $dir"
errors=$((errors + 1))
else
echo " $dir/"
echo "OK $dir/"
fi
done
for file in app/l10n.yaml app/pubspec.yaml core/pubspec.yaml listener/pubspec.yaml; do
if [ ! -f "$file" ]; then
echo "::error::Missing required file: $file"
errors=$((errors + 1))
else
echo " $file"
echo "OK $file"
fi
done
[ $errors -eq 0 ] || exit 1
Expand All @@ -175,12 +167,11 @@ jobs:
ref="refs/tags/$tag"
if [[ "$ref" =~ refs/tags/v(.+) ]]; then
VERSION="${BASH_REMATCH[1]}"
# Validate version format (semver)
if [[ ! "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+ ]]; then
if [[ ! "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?$ ]]; then
echo "::error::Tag $tag produces invalid version: $VERSION"
exit 1
fi
echo " $tag $VERSION"
echo "OK $tag -> $VERSION"
else
echo "::error::Tag $tag would fail version extraction in release.yml"
exit 1
Expand All @@ -193,25 +184,9 @@ jobs:
name: Build Verification (Windows)

steps:
- uses: actions/checkout@v6

- uses: subosito/flutter-action@v2
with:
channel: stable
cache: true

- name: Cache pub dependencies
uses: actions/cache@v5
with:
path: ~/.pub-cache
key: ${{ runner.os }}-pub-${{ hashFiles('**/pubspec.yaml') }}
restore-keys: ${{ runner.os }}-pub-

- name: Install Melos
run: dart pub global activate melos
- uses: actions/checkout@v7

- name: Get dependencies
run: melos bootstrap
- uses: ./.github/actions/setup-flutter-workspace

- name: Build Windows release
run: cd app; flutter build windows --release
Expand All @@ -222,54 +197,11 @@ jobs:
name: Build Verification (Linux)

steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7

- uses: subosito/flutter-action@v2
with:
channel: stable
cache: true

- name: Cache pub dependencies
uses: actions/cache@v5
with:
path: ~/.pub-cache
key: ${{ runner.os }}-pub-${{ hashFiles('**/pubspec.yaml') }}
restore-keys: ${{ runner.os }}-pub-

- name: Install Linux build dependencies
run: |
sudo apt-get update
sudo apt-get install -y \
clang \
cmake \
desktop-file-utils \
libayatana-appindicator3-dev \
libfuse2 \
libgtk-3-dev \
libkeybinder-3.0-dev \
liblzma-dev \
libx11-dev \
libxtst-dev \
lld-14 \
ninja-build \
patchelf \
pkg-config

- name: Verify Linux toolchain preflight
run: |
set -euo pipefail
test -x /usr/lib/llvm-14/bin/ld.lld || test -x /usr/bin/ld.lld-14 || test -x /usr/bin/ld.lld
pkg-config --modversion gtk+-3.0
pkg-config --modversion keybinder-3.0
pkg-config --modversion ayatana-appindicator3-0.1
pkg-config --modversion x11
pkg-config --modversion xtst

- name: Install Melos
run: dart pub global activate melos
- uses: ./.github/actions/setup-linux-build-deps

- name: Get dependencies
run: melos bootstrap
- uses: ./.github/actions/setup-flutter-workspace

- name: Build Linux release
run: cd app && flutter build linux --release
Expand All @@ -280,25 +212,9 @@ jobs:
name: Build Verification (macOS)

steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7

- uses: subosito/flutter-action@v2
with:
channel: stable
cache: true

- name: Cache pub dependencies
uses: actions/cache@v5
with:
path: ~/.pub-cache
key: ${{ runner.os }}-pub-${{ hashFiles('**/pubspec.yaml') }}
restore-keys: ${{ runner.os }}-pub-

- name: Install Melos
run: dart pub global activate melos

- name: Get dependencies
run: melos bootstrap
- uses: ./.github/actions/setup-flutter-workspace

- name: Build macOS release
run: cd app && flutter build macos --release
Expand All @@ -310,12 +226,12 @@ jobs:
if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository

steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7
with:
fetch-depth: 0

- name: Download coverage reports
uses: actions/download-artifact@v6
uses: actions/download-artifact@v7
with:
name: coverage-reports
path: .
Expand All @@ -335,4 +251,3 @@ jobs:
-Dsonar.coverage.exclusions=**/main.dart,**/shell/**,**/services/auto_update_service.dart,**/windows_clipboard_listener.dart,**/l10n/**,**/*.g.dart,**/*.freezed.dart,**/core.dart,**/screens/settings_screen.dart
-Dsonar.qualitygate.wait=true
-Dsonar.qualitygate.timeout=300

Loading
Loading