如何在 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');
}
- 可以访问JSON的class:
环境配置
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(',')}';
}
}
- github 操作中的测试失败但不是本地测试
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);
});
}
- Github动作
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
在我的项目中,我有一些 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');
}
- 可以访问JSON的class:
环境配置
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(',')}';
}
}
- github 操作中的测试失败但不是本地测试
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);
});
}
- Github动作
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