diff --git a/.github/workflows/pre-merge-checks.yml b/.github/workflows/pre-merge-checks.yml new file mode 100644 index 0000000..8df74ce --- /dev/null +++ b/.github/workflows/pre-merge-checks.yml @@ -0,0 +1,62 @@ +name: Pre-merge checks + +on: + pull_request: + branches: + - main + - master + push: + branches: + - main + - master + +jobs: + test-publish: + runs-on: ubuntu-latest + + steps: + # Checkout repository + - name: Checkout code + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + # Set up Flutter + - name: Set up Flutter + uses: subosito/flutter-action@v2 + with: + flutter-version: '3.29.0' # Specify exact version instead of just 'stable' + channel: 'stable' + + # Cache Flutter dependencies to speed up workflow + - name: Cache Flutter dependencies + uses: actions/cache@v3 + with: + path: ~/.pub-cache + key: ${{ runner.os }}-pub-${{ hashFiles('**/pubspec.yaml') }} + restore-keys: | + ${{ runner.os }}-pub- + + # Install dependencies + - name: Install dependencies + run: flutter pub get + + # Run tests + - name: Run tests + run: flutter test + + # Static code analysis + - name: Analyze code + run: flutter analyze --no-fatal-warnings + + # Verify package format is correct + - name: Format check + run: dart format --set-exit-if-changed . + + # Verify package + - name: Verify package + run: flutter pub publish --dry-run + + # Check if package can be published + - name: Check publication readiness + run: flutter pub publish --dry-run \ No newline at end of file diff --git a/.github/workflows/publish-to-pubdev.yml b/.github/workflows/publish-to-pubdev.yml new file mode 100644 index 0000000..e61b590 --- /dev/null +++ b/.github/workflows/publish-to-pubdev.yml @@ -0,0 +1,69 @@ +name: Publish to Pub.dev + +on: + push: + tags: + - 'v*.*.*' # This triggers the action for tags like v1.0.0, v2.3.4, etc. + +jobs: + build: + runs-on: ubuntu-latest + + steps: + # Checkout repository + - name: Checkout code + uses: actions/checkout@v3 + with: + fetch-depth: 0 # Fetches all history for all tags and branches + + # Set up Flutter + - name: Set up Flutter + uses: subosito/flutter-action@v2 + with: + flutter-version: '3.29.0' # Specify exact version instead of just 'stable' + channel: 'stable' + + # Cache Flutter dependencies to speed up workflow + - name: Cache Flutter dependencies + uses: actions/cache@v3 + with: + path: ~/.pub-cache + key: ${{ runner.os }}-pub-${{ hashFiles('**/pubspec.yaml') }} + restore-keys: | + ${{ runner.os }}-pub- + + # Install dependencies + - name: Install dependencies + run: flutter pub get + + # Parse the tag to get the version without 'v' prefix + - name: Extract version from tag + id: get_version + run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_ENV + + # Verify the pubspec version matches the tag + - name: Verify version + run: | + echo "Tag version: $VERSION" + PUBSPEC_VERSION=$(grep -m 1 'version:' pubspec.yaml | awk '{print $2}') + echo "Pubspec version: $PUBSPEC_VERSION" + if [ "$VERSION" != "$PUBSPEC_VERSION" ]; then + echo "Error: The version in pubspec.yaml ($PUBSPEC_VERSION) does not match the tag version ($VERSION)" + exit 1 + fi + + # Publish to pub.dev + - name: Publish to Pub.dev + env: + PUB_DEV_TOKEN: ${{ secrets.PUB_DEV_TOKEN }} + run: | + # Configure Pub credentials + mkdir -p ~/.pub-cache + echo "$PUB_DEV_TOKEN" > ~/.pub-cache/credentials.json + # Publish the package + flutter pub publish --force + + # Clean up after publish + - name: Clean up + run: | + rm -f ~/.pub-cache/credentials.json \ No newline at end of file diff --git a/.idea/codeStyleConfig.xml b/.idea/codeStyleConfig.xml deleted file mode 100644 index 673acd8..0000000 --- a/.idea/codeStyleConfig.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/.pubignore b/.pubignore new file mode 100644 index 0000000..a664257 --- /dev/null +++ b/.pubignore @@ -0,0 +1,23 @@ +.dart_tool/ +.idea/ +.vscode/ +build/ +.packages +pubspec.lock +.DS_Store +.pub/ +.git/ +.github/ +.gitignore +.travis/ +.travis.yml +test/ +android/.idea +example/build/ +example/.dart_tool/ +example/.packages +example/pubspec.lock + +# Don't exclude these files even though they are in .gitignore +!.idea/codeStyleConfig.xml +!.vscode/settings.json \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 391e560..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "[dart]": { - "editor.rulers": [ - 100 - ], - "editor.formatOnSave": true - }, - "dart.lineLength": 100 -} \ No newline at end of file diff --git a/example/analysis_options.yaml b/example/analysis_options.yaml index fac60e2..0caccc8 100644 --- a/example/analysis_options.yaml +++ b/example/analysis_options.yaml @@ -1 +1 @@ -include: ../../analysis_options.yaml \ No newline at end of file +include: ../analysis_options.yaml \ No newline at end of file diff --git a/example/lib/main.dart b/example/lib/main.dart index 3b200a7..5df3952 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -1,5 +1,4 @@ // ignore_for_file: unused_local_variable - import 'package:flutter/material.dart'; import 'package:native_flutter_proxy/native_flutter_proxy.dart'; @@ -12,13 +11,15 @@ void main() async { var enabled = false; String? host; int? port; + try { final settings = await NativeProxyReader.proxySetting; enabled = settings.enabled; host = settings.host; port = settings.port; } catch (e) { - print(e); + // Using debugPrint instead of print for production code + debugPrint('Error fetching proxy settings: $e'); } // Enable the proxy if it is enabled and the host is not null. @@ -27,22 +28,36 @@ void main() async { debugPrint('proxy enabled'); } - runApp(MyApp()); + runApp(const MyApp()); } +/// The main application widget. +/// +/// This widget is the root of the application. class MyApp extends StatelessWidget { + /// Creates a new instance of [MyApp]. + const MyApp({super.key}); + @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData(primarySwatch: Colors.blue), - home: MyHomePage(title: 'Flutter Demo Home Page'), + home: const MyHomePage(title: 'Flutter Demo Home Page'), ); } } +/// A widget that displays the home page of the application. +/// +/// This widget is stateful and keeps track of a counter value. class MyHomePage extends StatefulWidget { - MyHomePage({super.key, required this.title}); + /// Creates a new instance of [MyHomePage]. + /// + /// The [title] parameter is required and displayed in the app bar. + const MyHomePage({required this.title, super.key}); + + /// The title displayed in the app bar. final String title; @override @@ -52,6 +67,7 @@ class MyHomePage extends StatefulWidget { class _MyHomePageState extends State { int counter = 0; + /// Increments the counter value. void _incrementCounter() => setState(() => counter++); @override @@ -62,7 +78,7 @@ class _MyHomePageState extends State { child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - Text('You have pushed the button this many times:'), + const Text('You have pushed the button this many times:'), Text( '$counter', style: Theme.of(context).textTheme.headlineMedium, @@ -73,7 +89,7 @@ class _MyHomePageState extends State { floatingActionButton: FloatingActionButton( onPressed: _incrementCounter, tooltip: 'Increment', - child: Icon(Icons.add), + child: const Icon(Icons.add), ), ); } diff --git a/example/pubspec.lock b/example/pubspec.lock index 3d9ddb2..8cfd740 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -58,5 +58,13 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.4" + very_good_analysis: + dependency: "direct dev" + description: + name: very_good_analysis + sha256: "9ae7f3a3bd5764fb021b335ca28a34f040cd0ab6eec00a1b213b445dae58a4b8" + url: "https://pub.dev" + source: hosted + version: "5.1.0" sdks: dart: ">=3.7.0-0 <4.0.0" diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 680bb4d..9539dc3 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -11,5 +11,8 @@ dependencies: sdk: flutter native_flutter_proxy: ^0.2.0 +dev_dependencies: + very_good_analysis: ^5.1.0 + flutter: uses-material-design: true diff --git a/lib/src/custom_proxy.dart b/lib/src/custom_proxy.dart index de5391a..a22590e 100644 --- a/lib/src/custom_proxy.dart +++ b/lib/src/custom_proxy.dart @@ -61,8 +61,10 @@ class CustomProxy { static CustomProxy? fromString({required String proxy}) { // Check if the proxy string is empty if (proxy.isEmpty) { - assert(false, 'Proxy string passed to CustomProxy.fromString() is invalid.'); - + assert( + false, + 'Proxy string passed to CustomProxy.fromString() is invalid.', + ); return null; } diff --git a/lib/src/custom_proxy_override.dart b/lib/src/custom_proxy_override.dart index 2ba572a..2058bbf 100644 --- a/lib/src/custom_proxy_override.dart +++ b/lib/src/custom_proxy_override.dart @@ -45,13 +45,15 @@ final class CustomProxyHttpOverride extends HttpOverrides { HttpClient createHttpClient(SecurityContext? context) { final client = super.createHttpClient(context) ..findProxy = (uri) { - assert(proxyString.isNotEmpty, 'You must set a valid proxy if you enable it!'); - + assert( + proxyString.isNotEmpty, + 'You must set a valid proxy if you enable it!', + ); return 'PROXY $proxyString;'; }; - - if (allowBadCertificates) client.badCertificateCallback = (cert, host, port) => true; - + if (allowBadCertificates) { + client.badCertificateCallback = (cert, host, port) => true; + } return client; } }