Skip to content

CI/CD

CI/CD #525

Workflow file for this run

---
name: CI/CD
on:
push:
branches:
- "main"
pull_request:
types:
- opened
- synchronize
merge_group:
schedule:
- cron: "0 14 * * 1" # every monday at 9 in the morning CST
workflow_dispatch:
env:
CI: true
FLUTTER_CHANNEL: stable
permissions:
contents: read
jobs:
setup:
name: Setup
timeout-minutes: 5
runs-on: ubuntu-latest
steps:
- name: πŸ“š Git checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
submodules: recursive
clean: true
persist-credentials: false
set-safe-directory: true
fetch-depth: 1
- name: 🐦 Set up Flutter
id: flutter
uses: subosito/flutter-action@f2c4f6686ca8e8d6e6d0f28410eeef506ed66aff # v2.18.0
with:
channel: ${{ env.FLUTTER_CHANNEL }}
flutter-version-file: pubspec.yaml
cache: true
- name: 🌐 Disable analytics
run: flutter --disable-analytics
- name: βš™οΈ Cache generated files
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with:
path: |
.dart_tool/
packages/*/lib/src/gen/*.gen.dart
packages/*/lib/src/**/*.g.dart
packages/*/lib/src/**/*.freezed.dart
packages/*/test/helpers/**/*.freezed.dart
packages/*/lib/src/app/*.gr.dart
packages/*/lib/src/app/*.gm.dart
packages/*/lib/src/l10n/app_localizations.dart
packages/*/lib/src/l10n/app_localizations_*.dart
key: generated-${{ steps.flutter.outputs.CHANNEL }}-${{ runner.os }}-${{ hashFiles('**/build.yaml') }}-${{ hashFiles('packages/*/lib/**.dart') }}
restore-keys: generated-${{ steps.flutter.outputs.CHANNEL }}-${{ runner.os }}-
- name: πŸ—„οΈ Environment
run: echo "${DOT_ENV}" > packages/app/.env
env:
DOT_ENV: |
PROJECT_ID=${{ secrets.PROJECT_ID }}
API_ENDPOINT=${{ secrets.API_ENDPOINT }}
DATABASE_ID=${{ secrets.DATABASE_ID }}
POSTS_COLLECTION_ID=${{ secrets.POSTS_COLLECTION_ID }}
- name: πŸ“¦ Install dependencies
uses: bluefireteam/melos-action@c7dcb921b23cc520cace360b95d02b37bf09cdaa # v3
with:
run-bootstrap: true
enforce-lockfile: true
build:
name: Build
needs: ["setup"]
timeout-minutes: ${{ (matrix.target == 'web') && 5 || 20 }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
target:
- web
- appbundle
# - ios
# - macos
# - windows
include:
- target: web
os: ubuntu-latest
flutter-flags: --release --wasm
- target: appbundle
os: ubuntu-latest
# This is the least optimized, but is significantly faster in CI.
# Android releases should be built locally on a beefy machine.
flutter-flags: --debug --no-tree-shake-icons --no-shrink
# - target: ios
# os: macos-latest
# flutter-flags: --debug --no-tree-shake-icons
# - target: macos
# os: macos-latest
# flutter-flags: --debug --no-tree-shake-icons
# - target: windows
# os: windows-latest
# flutter-flags: --debug --no-tree-shake-icons
steps:
- name: πŸ“š Git checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
submodules: recursive
clean: true
persist-credentials: false
set-safe-directory: true
fetch-depth: 1
- name: 🐦 Set up Flutter
id: flutter
uses: subosito/flutter-action@f2c4f6686ca8e8d6e6d0f28410eeef506ed66aff # v2.18.0
with:
channel: ${{ env.FLUTTER_CHANNEL }}
flutter-version-file: pubspec.yaml
cache: true
- name: β˜• Setup Java
if: ${{ matrix.target == 'appbundle' }}
uses: actions/setup-java@7a6d8a8234af8eb26422e24e3006232cccaa061b # v4.6.0
with:
distribution: "jetbrains"
java-version: "17"
cache: "gradle"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: 🌐 Disable analytics
run: flutter --disable-analytics
- name: βš™οΈ Cache generated files
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with:
path: |
.dart_tool/
packages/*/lib/src/gen/*.gen.dart
packages/*/lib/src/**/*.g.dart
packages/*/lib/src/**/*.freezed.dart
packages/*/test/helpers/**/*.freezed.dart
packages/*/lib/src/app/*.gr.dart
packages/*/lib/src/app/*.gm.dart
packages/*/lib/src/l10n/app_localizations.dart
packages/*/lib/src/l10n/app_localizations_*.dart
key: generated-${{ steps.flutter.outputs.CHANNEL }}-${{ runner.os }}-${{ hashFiles('**/build.yaml') }}-${{ hashFiles('packages/*/lib/**.dart') }}
restore-keys: generated-${{ steps.flutter.outputs.CHANNEL }}-${{ runner.os }}-
- name: πŸ“¦ Install dependencies
run: dart pub get --enforce-lockfile
- name: πŸ”§ Build
run: |
flutter build ${{ matrix.target }} --no-pub ${{ matrix.flutter-flags }}
working-directory: packages/app/
- name: βš™οΈ Upload build
if: ${{ matrix.target == 'web' }}
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: build-${{ matrix.target }}
path: "./packages/app/build/${{ matrix.target }}/"
if-no-files-found: error
lint:
name: Linting
needs: ["setup"]
timeout-minutes: 5
runs-on: ubuntu-latest
steps:
- name: πŸ“š Git checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
submodules: recursive
clean: true
persist-credentials: false
set-safe-directory: true
fetch-depth: 1
- name: 🐦 Set up Flutter
id: flutter
uses: subosito/flutter-action@f2c4f6686ca8e8d6e6d0f28410eeef506ed66aff # v2.18.0
with:
channel: ${{ env.FLUTTER_CHANNEL }}
flutter-version-file: pubspec.yaml
cache: true
- name: 🌐 Disable analytics
run: flutter --disable-analytics
- name: βš™οΈ Cache generated files
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with:
path: |
.dart_tool/
packages/*/lib/src/gen/*.gen.dart
packages/*/lib/src/**/*.g.dart
packages/*/lib/src/**/*.freezed.dart
packages/*/test/helpers/**/*.freezed.dart
packages/*/lib/src/app/*.gr.dart
packages/*/lib/src/app/*.gm.dart
packages/*/lib/src/l10n/app_localizations.dart
packages/*/lib/src/l10n/app_localizations_*.dart
key: generated-${{ steps.flutter.outputs.CHANNEL }}-${{ runner.os }}-${{ hashFiles('**/build.yaml') }}-${{ hashFiles('packages/*/lib/**.dart') }}
restore-keys: generated-${{ steps.flutter.outputs.CHANNEL }}-${{ runner.os }}-
- name: πŸŒ‹ Install Melos
uses: bluefireteam/melos-action@c7dcb921b23cc520cace360b95d02b37bf09cdaa # v3
with:
run-bootstrap: false
- name: πŸ“¦ Install dependencies
run: dart pub get --enforce-lockfile
- name: πŸ•΅οΈ Analyze project source
run: dart analyze --fatal-infos
- name: πŸ•΅οΈ Run Custom Lint Rules
run: melos run custom_lint
test:
name: Testing
needs: ["setup"]
timeout-minutes: 7
runs-on: ubuntu-latest
permissions:
id-token: write
steps:
- name: πŸ“š Git checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
submodules: recursive
clean: true
persist-credentials: false
set-safe-directory: true
fetch-depth: 1
- name: 🐦 Set up Flutter
id: flutter
uses: subosito/flutter-action@f2c4f6686ca8e8d6e6d0f28410eeef506ed66aff # v2.18.0
with:
channel: ${{ env.FLUTTER_CHANNEL }}
flutter-version-file: pubspec.yaml
cache: true
- name: 🌐 Disable analytics
run: flutter --disable-analytics
- name: βš™οΈ Cache generated files
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with:
path: |
.dart_tool/
packages/*/lib/src/gen/*.gen.dart
packages/*/lib/src/**/*.g.dart
packages/*/lib/src/**/*.freezed.dart
packages/*/test/helpers/**/*.freezed.dart
packages/*/lib/src/app/*.gr.dart
packages/*/lib/src/app/*.gm.dart
packages/*/lib/src/l10n/app_localizations.dart
packages/*/lib/src/l10n/app_localizations_*.dart
key: generated-${{ steps.flutter.outputs.CHANNEL }}-${{ runner.os }}-${{ hashFiles('**/build.yaml') }}-${{ hashFiles('packages/*/lib/**.dart') }}
restore-keys: generated-${{ steps.flutter.outputs.CHANNEL }}-${{ runner.os }}-
- name: πŸŒ‹ Install Melos
uses: bluefireteam/melos-action@c7dcb921b23cc520cace360b95d02b37bf09cdaa # v3
with:
run-bootstrap: false
- name: πŸ“¦ Install dependencies
run: dart pub get --enforce-lockfile
- name: πŸ§ͺ Run tests
run: melos run test
continue-on-error: true
- name: πŸ“Š Upload code coverage
if: ${{ !cancelled() }}
uses: codecov/codecov-action@18283e04ce6e62d37312384ff67231eb8fd56d24 # v5.4.3
with:
use_oidc: true
files: packages/app/coverage/lcov.info
fail_ci_if_error: true
verbose: true
format:
name: Formatting
needs: ["setup"]
timeout-minutes: 3
runs-on: ubuntu-latest
steps:
- name: πŸ“š Git checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
submodules: recursive
clean: true
persist-credentials: false
set-safe-directory: true
fetch-depth: 1
- name: 🐦 Set up Flutter
id: flutter
uses: subosito/flutter-action@f2c4f6686ca8e8d6e6d0f28410eeef506ed66aff # v2.18.0
with:
channel: ${{ env.FLUTTER_CHANNEL }}
flutter-version-file: pubspec.yaml
cache: true
- name: 🌐 Disable analytics
run: flutter --disable-analytics
- name: πŸ“¦ Install dependencies
run: dart pub get --enforce-lockfile
- name: ✨ Verify formatting
run: dart format . --output=none --set-exit-if-changed
deploy:
name: Deploy
needs: ["build"]
if: ${{ github.event_name != 'merge_group' }}
runs-on: ubuntu-latest
timeout-minutes: 2
permissions:
id-token: write # Needed to authenticate with Deno Deploy.
concurrency:
group: deploy-${{ github.ref }}
cancel-in-progress: true
steps:
- name: πŸ“š Git checkout
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
with:
submodules: recursive
clean: true
persist-credentials: false
set-safe-directory: true
fetch-depth: 1
sparse-checkout: packages/server
- name: βš™οΈ Download build
uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4
with:
name: build-web
path: "./packages/server/static"
- name: πŸ”§ Deploy
uses: denoland/deployctl@612f83df2b874c6908d68de5cf3f36a6538fa8f7 # 1.12.0
with:
project: "harvest-hub"
entrypoint: ./src/server.ts
root: packages/server
include: |
src/
static/
deno.json
deno.lock
spell-check:
name: Check Spelling
runs-on: ubuntu-latest
steps:
- name: πŸ“š Git checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
submodules: recursive
clean: true
persist-credentials: false
set-safe-directory: true
fetch-depth: 1
- name: πŸͺ„ Spell check
uses: streetsidesoftware/cspell-action@934c74da3775ac844ec89503f666f67efb427fed # v6.8.1
with:
files: |
**/*.md
**/*.dart
**/*.yaml
**/*.toml
**/*.json
incremental_files_only: false
link-check:
name: Check Links
timeout-minutes: 2
runs-on: ubuntu-latest
steps:
- name: πŸͺ„ Link check
uses: gaurav-nelson/github-action-markdown-link-check@d53a906aa6b22b8979d33bc86170567e619495ec # 1.0.15
with:
use-quiet-mode: "yes"
use-verbose-mode: "yes"
base-branch: "main"
markdownlint:
name: Lint Markdown
timeout-minutes: 4
runs-on: ubuntu-latest
steps:
- name: πŸ“š Git checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
submodules: recursive
clean: true
persist-credentials: false
set-safe-directory: true
fetch-depth: 1
- name: πŸ•΅οΈ Lint Markdown
uses: DavidAnson/markdownlint-cli2-action@db43aef879112c3119a410d69f66701e0d530809 # v17.0.0
id: markdownlint
with:
fix: true
# Surprisingly, the default is to only lint the project root.
globs: |
**/*.md
zizmor:
name: Run zizmor
timeout-minutes: 1
runs-on: ubuntu-latest
permissions:
contents: read
security-events: write
actions: read
steps:
- name: πŸ“š Git Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
submodules: recursive
clean: true
persist-credentials: false
set-safe-directory: true
- name: 🌈 Run zizmor
uses: zizmorcore/zizmor-action@2520132f44b3ed84916048d32e5c7153fc739fe7 # v0.0.3
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}