如何在 git 集线器操作中包含 git 被忽略的文件?

How to include git ignored file in github actions with flutter?

在我的项目中,我有一些 JSON 文件用于在 运行 时间通过主 dart 文件的入口点获取环境配置,它们保存敏感数据,所以我将它们的包含文件夹在 .gitignore 文件中。

我写了一个测试,当我在本地 运行 时它通过了,但由于这个错误而被 github 操作触发时失败了:

The following assertion was thrown running a test:
Unable to load asset: assets/config/dev.json

有没有办法在执行操作时以某种方式注入此 JSON?非常感谢任何帮助,我唯一担心的是私有数据未存储在 github 存储库中并让操作通过。

这是我的代码:

dev_run.dart

import 'package:gitgo/main.dart' as App;

void main() {
  App.main('dev');
}

环境配置

import 'dart:convert';
import 'package:flutter/services.dart';

class EnvironmentConfig {
  final Map<String, String> environment;

  EnvironmentConfig({this.environment});

  static Future<EnvironmentConfig> forEnvironment(String env) async {
    env = env ?? 'dev';

    final contents = await rootBundle.loadString(
      'assets/config/$env.json',
    );

    final Map<String, String> json = Map.castFrom(jsonDecode(contents));
    return EnvironmentConfig(environment: json);
  }
}

pubspec.yaml

name: gitgo
description: Git on the go.

version: 1.0.0+1

environment:
  sdk: ">=2.7.0 <3.0.0"

dependencies:
  flutter:
    sdk: flutter
  http: ^0.12.1
  oauth2: ^1.6.1
  url_launcher: ^5.4.10
  flutter_config: ^1.0.8
  gql: ^0.12.3               
  gql_exec: ^0.2.4           
  gql_link: ^0.3.0           
  gql_http_link: ^0.3.2      


dev_dependencies:
  flutter_test:
    sdk: flutter
  build_runner: ^1.11.1     
  gql_build: ^0.0.11         
  pedantic: ^1.9.0

# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec

# The following section is specific to Flutter.
flutter:

  # The following line ensures that the Material Icons font is
  # included with your application, so that you can use the icons in
  # the material Icons class.
  uses-material-design: true

  # To add assets to your application, add an assets section, like this:
  assets:
    - assets/config/

main.dart

import 'package:flutter/material.dart';
import 'package:gitgo/inbound/configuration/config_environment_widget.dart';
import 'package:gitgo/outbound/api/viewer.req.gql.dart';

import 'package:gql_exec/gql_exec.dart';
import 'package:gql_link/gql_link.dart';
import 'package:gitgo/outbound/api/viewer.data.gql.dart';
import 'package:gitgo/outbound/auth.dart';
import 'package:gql_http_link/gql_http_link.dart';

import 'inbound/configuration/environment_config.dart';

Future main(String env) async {
  WidgetsFlutterBinding.ensureInitialized();
  final config = await EnvironmentConfig.forEnvironment(env);
  print("starting app in $env mode");
  runApp(MyApp(config));
}

class MyApp extends StatelessWidget {
  final EnvironmentConfig config;

  MyApp(this.config);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'GitGo Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: EnvironmentConfigWidget(
          config: config, child: MyHomePage(title: 'GitGo Demo Home Page')),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState(title: "GitHub login");
}

class _MyHomePageState extends State<MyHomePage> {
  _MyHomePageState({this.title});

  EnvironmentConfigWidget environmentConfigWidget;

  String title;

  @override
  Widget build(BuildContext context) {
    return GithubLoginWidget(
        builder: (context, httpClient) {
          final link = HttpLink(
            'https://api.github.com/graphql',
            httpClient: httpClient,
          );
          return FutureBuilder<$ViewerDetail$viewer>(
            future: viewerDetail(link),
            builder: (context, snapshot) {
              return Scaffold(
                appBar: AppBar(
                  title: Text(title),
                ),
                body: Center(
                  child: Text(
                    snapshot.hasData
                        ? 'Hello ${snapshot.data?.login}!'
                        : 'Retrieving viewer login details...',
                  ),
                ),
              );
            },
          );
        },
        githubClientId: EnvironmentConfigWidget.of(context)
            .config
            .environment['githubClientId'],
        githubClientSecret: EnvironmentConfigWidget.of(context)
            .config
            .environment['githubClientSecret'],
        githubScopes: EnvironmentConfigWidget.of(context)
            .config
            .environment['githubScopes']
            .split(","));
  }
}

Future<$ViewerDetail$viewer> viewerDetail(Link link) async {
  var result = await link.request(ViewerDetail((b) => b)).first;
  if (result.errors != null && result.errors.isNotEmpty) {
    throw QueryException(result.errors);
  }
  return $ViewerDetail(result.data).viewer;
}

class QueryException implements Exception {
  QueryException(this.errors);

  List<GraphQLError> errors;

  @override
  String toString() {
    return 'Query Exception: ${errors.map((err) => '$err').join(',')}';
  }
}

widget_dart.test

import 'package:flutter_test/flutter_test.dart';
import 'package:gitgo/inbound/configuration/environment_config.dart';
import 'package:gitgo/main.dart';

void main() {
  testWidgets('Smoke test', (WidgetTester tester) async {
    // Build our app and trigger a frame.

    var env = await EnvironmentConfig.forEnvironment('dev');
    await tester.pumpWidget(MyApp(env));

    // Verify that our counter starts at 0.
    expect(find.text('Log into Github'), findsOneWidget);
    expect(find.text('1'), findsNothing);
  });
}

ci.yml

name: ci

jobs:

  ci:
    name: ci
    runs-on: macos-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v2

      - name: Flutter test
        uses: subosito/flutter-action@v1.4.0
        with:
          flutter-version: '1.26.0-17.2.pre'
          channel: dev
      - run: flutter pub get
      - run: flutter  analyze
      - run: flutter test --no-sound-null-safety

      - name : Clean merged branches
        run: |
          git fetch -p && for branch in $(git branch -vv | grep ': gone]' | awk '{print }'); do git branch -D $branch; done
          echo "Finished cleaning"
        

您可以使用 GitHub Action secrets.

把你的dev.json内容保密(比如DEV_JSON_CONTENTS),然后用命令写到正确的位置。

- name: Write dev.json
  run: echo '{{ secrets.DEV_JSON_CONTENTS }}' > assets/config/dev.json

建议的解决方案对我不起作用,但正如 hacker1024 指出的那样:

Put your dev.json contents in a secret (for example, DEV_JSON_CONTENTS), and write it to the correct location with a command.

所以在我的案例中起作用的是添加 github secret DEV_JSON 和原始文件的内容,然后 我通过在工作流中添加秘密作为环境变量来修改工作流文件:

 env:
  DEV_JSON : ${{ secrets.DEV_JSON }}

我添加了这一步将内容写入新文件:

 - name: Write dev.json
    run: |
      touch assets/config/dev.json
      echo $DEV_JSON >> assets/config/dev.json
      cat  assets/config/dev.json