diff --git a/.github/actions/dart_package/action.yaml b/.github/actions/dart_package/action.yaml new file mode 100644 index 0000000..9d24059 --- /dev/null +++ b/.github/actions/dart_package/action.yaml @@ -0,0 +1,85 @@ +name: Dart Package Workflow +description: Build and test Dart packages. + +inputs: + concurrency: + required: false + default: "4" + description: The value of the concurrency flag (-j) used when running tests + coverage_excludes: + required: false + default: "" + description: Globs to exclude from coverage + dart_sdk: + required: false + default: "stable" + description: "The dart sdk version to use" + working_directory: + required: false + default: "." + description: The working directory for this workflow + min_coverage: + required: false + default: "100" + description: The minimum coverage percentage value + min_score: + required: false + default: "120" + description: The minimum pana score value + analyze_directories: + required: false + default: "lib test" + description: Directories to analyze + report_on: + required: false + default: "lib" + description: Directories to report on when collecting coverage + +runs: + using: "composite" + steps: + - name: ๐ŸŽฏ Setup Dart + uses: dart-lang/setup-dart@v1 + with: + sdk: ${{inputs.dart_sdk}} + + - name: ๐Ÿ“ฆ Install Dependencies + working-directory: ${{ inputs.working_directory }} + shell: ${{ inputs.shell }} + run: dart pub get + + - name: โœจ Format + working-directory: ${{ inputs.working_directory }} + shell: ${{ inputs.shell }} + run: dart format --set-exit-if-changed . + + - name: ๐Ÿ” Analyze + working-directory: ${{ inputs.working_directory }} + shell: ${{ inputs.shell }} + run: dart analyze --fatal-warnings ${{inputs.analyze_directories}} + + - name: ๐Ÿงช Test + working-directory: ${{ inputs.working_directory }} + shell: ${{ inputs.shell }} + run: | + dart pub global activate coverage + dart test -j ${{inputs.concurrency}} --coverage=coverage && dart pub global run coverage:format_coverage --lcov --in=coverage --out=coverage/lcov.info --packages=.dart_tool/package_config.json --report-on=${{inputs.report_on}} --check-ignore + + - name: ๐Ÿ“Š Verify Coverage + uses: VeryGoodOpenSource/very_good_coverage@v3 + with: + path: ${{inputs.working_directory}}/coverage/lcov.info + exclude: ${{inputs.coverage_excludes}} + min_coverage: ${{inputs.min_coverage}} + + - name: ๐Ÿ’ฏ Verify Pub Score + working-directory: ${{ inputs.working_directory }} + shell: ${{ inputs.shell }} + run: | + dart pub global activate pana 0.21.45 + sudo apt-get install webp + PANA=$(pana . --no-warning); PANA_SCORE=$(echo $PANA | sed -n "s/.*Points: \([0-9]*\)\/\([0-9]*\)./\1\/\2/p") + echo "score: $PANA_SCORE" + IFS='/'; read -a SCORE_ARR <<< "$PANA_SCORE"; SCORE=SCORE_ARR[0]; TOTAL=SCORE_ARR[1] + if [ -z "$1" ]; then MINIMUM_SCORE=TOTAL; else MINIMUM_SCORE=$1; fi + if (( $SCORE < $MINIMUM_SCORE )); then echo "minimum score $MINIMUM_SCORE was not met!"; exit 1; fi diff --git a/.github/actions/flutter_package/action.yaml b/.github/actions/flutter_package/action.yaml new file mode 100644 index 0000000..af43a95 --- /dev/null +++ b/.github/actions/flutter_package/action.yaml @@ -0,0 +1,82 @@ +name: Flutter Package Workflow +description: Build and test a Flutter package. + +inputs: + concurrency: + required: false + default: "4" + description: The value of the concurrency flag (-j) used when running tests + coverage_excludes: + required: false + default: "" + description: Globs to exclude from coverage + working_directory: + required: false + default: "." + description: The working directory for this workflow + min_coverage: + required: false + default: "100" + description: The minimum coverage percentage value + analyze_directories: + required: false + default: "lib test" + description: Directories to analyze + report_on: + required: false + default: "lib" + description: Directories to report on when collecting coverage + platform: + required: false + default: "vm" + description: Platform to use when running tests + +runs: + using: "composite" + steps: + - name: ๐Ÿฆ Setup Flutter + uses: subosito/flutter-action@v2 + + - name: ๐Ÿ“ฆ Install Dependencies + working-directory: ${{ inputs.working_directory }} + shell: ${{ inputs.shell }} + run: flutter pub get + + - name: โœจ Format + working-directory: ${{ inputs.working_directory }} + shell: ${{ inputs.shell }} + run: dart format --set-exit-if-changed . + + - name: ๐Ÿ” Analyze + working-directory: ${{ inputs.working_directory }} + shell: ${{ inputs.shell }} + run: dart analyze --fatal-warnings ${{inputs.analyze_directories}} + + - name: ๐Ÿงช Test + working-directory: ${{ inputs.working_directory }} + shell: ${{ inputs.shell }} + run: | + if [ -d "test" ]; then + flutter test --no-pub --test-randomize-ordering-seed random --coverage + fi + + - name: ๐Ÿ“Š Verify Coverage + if: inputs.collect_coverage == 'true' + uses: VeryGoodOpenSource/very_good_coverage@v3 + with: + path: ${{inputs.working_directory}}/coverage/lcov.info + exclude: ${{inputs.coverage_excludes}} + min_coverage: ${{inputs.min_coverage}} + + - name: ๐Ÿ’ฏ Verify Pub Score + if: inputs.collect_score == 'true' + working-directory: ${{ inputs.working_directory }} + shell: ${{ inputs.shell }} + run: | + dart pub global activate pana 0.21.45 + sudo apt-get install webp + PANA=$(pana . --no-warning); PANA_SCORE=$(echo $PANA | sed -n "s/.*Points: \([0-9]*\)\/\([0-9]*\)./\1\/\2/p") + echo "score: $PANA_SCORE" + IFS='/'; read -a SCORE_ARR <<< "$PANA_SCORE"; SCORE=SCORE_ARR[0]; TOTAL=SCORE_ARR[1] + if [ -z "$1" ]; then MINIMUM_SCORE=TOTAL; else MINIMUM_SCORE=$1; fi + if (( $SCORE < $MINIMUM_SCORE )); then echo "minimum score $MINIMUM_SCORE was not met!"; exit 1; fi diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml deleted file mode 100644 index d79185a..0000000 --- a/.github/workflows/ci.yaml +++ /dev/null @@ -1,19 +0,0 @@ -name: ci - -on: - pull_request: - paths: - - "!packages/fresh_dio/lib/**" - - "!packages/fresh_dio/test/**" - - "!packages/fresh_dio/example/**" - - "!packages/fresh/lib/**" - - "!packages/fresh/test/**" - branches: - - master - -jobs: - build: - runs-on: ubuntu-latest - steps: - - name: noop - run: echo 'noop' diff --git a/.github/workflows/fresh.yaml b/.github/workflows/fresh.yaml deleted file mode 100644 index 34f2e1f..0000000 --- a/.github/workflows/fresh.yaml +++ /dev/null @@ -1,25 +0,0 @@ -name: fresh - -on: - push: - branches: - - master - paths: - - ".github/workflows/fresh.yaml" - - "packages/fresh/pubspec.yaml" - - "packages/fresh/lib/**" - - "packages/fresh/test/**" - pull_request: - branches: - - master - paths: - - ".github/workflows/fresh.yaml" - - "packages/fresh/pubspec.yaml" - - "packages/fresh/lib/**" - - "packages/fresh/test/**" - -jobs: - build: - uses: VeryGoodOpenSource/very_good_workflows/.github/workflows/dart_package.yml@v1 - with: - working_directory: packages/fresh diff --git a/.github/workflows/fresh_dio.yaml b/.github/workflows/fresh_dio.yaml deleted file mode 100644 index db9dbe1..0000000 --- a/.github/workflows/fresh_dio.yaml +++ /dev/null @@ -1,25 +0,0 @@ -name: fresh_dio - -on: - push: - branches: - - master - paths: - - ".github/workflows/fresh_dio.yaml" - - "packages/fresh_dio/pubspec.yaml" - - "packages/fresh_dio/lib/**" - - "packages/fresh_dio/test/**" - pull_request: - branches: - - master - paths: - - ".github/workflows/fresh_dio.yaml" - - "packages/fresh_dio/pubspec.yaml" - - "packages/fresh_dio/lib/**" - - "packages/fresh_dio/test/**" - -jobs: - build: - uses: VeryGoodOpenSource/very_good_workflows/.github/workflows/flutter_package.yml@v1 - with: - working_directory: packages/fresh_dio diff --git a/.github/workflows/fresh_dio_example.yaml b/.github/workflows/fresh_dio_example.yaml deleted file mode 100644 index 28d0dbd..0000000 --- a/.github/workflows/fresh_dio_example.yaml +++ /dev/null @@ -1,36 +0,0 @@ -name: fresh_dio_example - -on: - push: - branches: - - master - paths: - - "packages/fresh_dio/example/**" - pull_request: - branches: - - master - paths: - - "packages/fresh_dio/example/**" - -jobs: - build: - defaults: - run: - working-directory: packages/fresh_dio/example - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - - uses: subosito/flutter-action@v2 - - - name: Install Dependencies - run: flutter packages get - - - name: Format - run: dart format --set-exit-if-changed lib test - - - name: Analyze - run: flutter analyze lib test - - - name: Run tests - run: flutter test --no-pub --coverage --test-randomize-ordering-seed random diff --git a/.github/workflows/fresh_graphql.yaml b/.github/workflows/fresh_graphql.yaml deleted file mode 100644 index b45f67c..0000000 --- a/.github/workflows/fresh_graphql.yaml +++ /dev/null @@ -1,25 +0,0 @@ -name: fresh_graphql - -on: - push: - branches: - - master - paths: - - ".github/workflows/fresh_graphql.yaml" - - "packages/fresh_graphql/pubspec.yaml" - - "packages/fresh_graphql/lib/**" - - "packages/fresh_graphql/test/**" - pull_request: - branches: - - master - paths: - - ".github/workflows/fresh_graphql.yaml" - - "packages/fresh_graphql/pubspec.yaml" - - "packages/fresh_graphql/lib/**" - - "packages/fresh_graphql/test/**" - -jobs: - build: - uses: VeryGoodOpenSource/very_good_workflows/.github/workflows/dart_package.yml@v1 - with: - working_directory: packages/fresh_graphql diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml new file mode 100644 index 0000000..bf42733 --- /dev/null +++ b/.github/workflows/main.yaml @@ -0,0 +1,121 @@ +name: build + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +on: + pull_request: + push: + branches: [master] + +permissions: + contents: read + pages: write + id-token: write + +jobs: + semantic_pull_request: + name: โœ… Semantic Pull Request + uses: VeryGoodOpenSource/very_good_workflows/.github/workflows/semantic_pull_request.yml@v1 + + changes: + runs-on: ubuntu-latest + + if: github.event.pull_request.draft == false + + outputs: + needs_dart_package_checks: ${{ steps.needs_dart_package_checks.outputs.changes }} + needs_flutter_package_checks: ${{ steps.needs_flutter_package_checks.outputs.changes }} + + name: ๐Ÿ‘€ Detect Changes + + steps: + - name: ๐Ÿ“š Git Checkout + uses: actions/checkout@v4 + + - uses: dorny/paths-filter@v3 + name: Dart Package Detection + id: needs_dart_package_checks + with: + filters: | + fresh: + - ./.github/workflows/main.yaml + - ./.github/actions/dart_package/action.yaml + - packages/fresh/** + fresh_graphql: + - ./.github/workflows/main.yaml + - ./.github/actions/dart_package/action.yaml + - packages/fresh_dio/** + + - uses: dorny/paths-filter@v3 + name: Flutter Package Detection + id: needs_flutter_package_checks + with: + filters: | + fresh_dio: + - ./.github/workflows/main.yaml + - ./.github/actions/dart_package/action.yaml + - packages/fresh_dio/** + fresh_dio/example: + - ./.github/workflows/main.yaml + - ./.github/actions/dart_package/action.yaml + - packages/fresh_dio/** + + dart_package_checks: + needs: changes + if: ${{ needs.changes.outputs.needs_dart_package_checks != '[]' }} + + strategy: + fail-fast: false + matrix: + package: ${{ fromJSON(needs.changes.outputs.needs_dart_package_checks) }} + + runs-on: ubuntu-latest + + name: ๐ŸŽฏ ${{ matrix.package }} + + steps: + - name: ๐Ÿ“š Git Checkout + uses: actions/checkout@v4 + + - name: ๐ŸŽฏ Build ${{ matrix.package }} + uses: ./.github/actions/dart_package + with: + working_directory: packages/${{ matrix.package }} + min_coverage: 100 + + flutter_package_checks: + needs: changes + if: ${{ needs.changes.outputs.needs_flutter_package_checks != '[]' }} + + strategy: + fail-fast: false + matrix: + package: ${{ fromJSON(needs.changes.outputs.needs_flutter_package_checks) }} + + runs-on: ubuntu-latest + + name: ๐Ÿฆ ${{ matrix.package }} + + steps: + - name: ๐Ÿ“š Git Checkout + uses: actions/checkout@v4 + + - name: ๐ŸŽฏ Build ${{ matrix.package }} + uses: ./.github/actions/flutter_package + with: + working_directory: packages/${{ matrix.package }} + min_coverage: 100 + + build: + needs: [semantic_pull_request, dart_package_checks, flutter_package_checks] + + if: ${{ always() }} + + runs-on: ubuntu-latest + + steps: + - name: โ›”๏ธ exit(1) on failure + if: ${{ contains(join(needs.*.result, ','), 'failure') }} + run: exit 1