Flutter插件vts_test_cicd_plugin的使用方法介绍
vts_test_cicd_plugin
本项目旨在为使用Gitlab CI/CD发布包提供指导。
简介
我们假设您已经为项目配置了Runner,因此我们将仅引导您完成.gitlab-ci.yml
文件的创建过程。
仓库变量
首先,您需要向您的仓库添加变量。这可以在设置 > CI/CD > 变量中完成。
[variables]
1. FLUTTER_IMAGE: Docker镜像用于Flutter,我们将使用cirrusci/flutter:stable。
2. GITLAB_API_TOKEN: 您的GitLab访问令牌。此令牌必须有效,否则您将无法在更改包版本时创建标签。
3. PUB_DEV变量: 这些变量对于最终的发布任务至关重要。我们将在发布阶段部分解释为什么以及如何获取它们。
.gitlab-ci.yml
重要提示:
如果您的包目录不在存储库的根目录下(例如images_utilities/cached_image
),则您需要对yml文件进行一些调整:
- 在任何作业中,您需要使用
before_script
来切换到您的包目录(例如cd cached_image
)。 - 您需要为您的工件提供相对路径(例如
coverage/
->cached_image/coverage/
)。
此项目的.gitlab-ci.yml
文件适用于大多数情况,但它非常简单,您可以根据自己的需求自由添加或修改任何阶段和作业。
我们将创建三个阶段:测试、发布前和发布。您可以跳过前两个阶段。
测试阶段
创建一个简单的作业来运行单元测试,检查并生成代码覆盖率的工件。您可以添加新的作业,如集成测试、冒烟测试等。
为了避免每次推送代码到GitLab时重复执行此作业,我们将使用only
和changes
关键字,以便只有在lib
或test
文件夹发生更改时触发此作业。
发布前阶段
在单元测试之后,我们有一个额外的阶段在发布包到Pub Dev之前。在这个阶段,我们有三个作业:dry-run
、dartdoc
和tag-version
。
dry-run
用于检查是否可以将此包发布到Pub Dev。例如,如果您更改了包的版本但忘记在CHANGE.md文件中添加新版本,此作业将失败。
dart-doc
将用于干运行Dart文档,以最大化我们的包在Pub Dev上的可用性。确保提供一个dartdoc_options.yml
文件(或使用此项目的文件),以便将警告转换为错误。
tag-version
作业只能在主分支上手动启动,当您的包版本更改时创建一个新的标签。此作业需要以下四个变量才能工作(如果您的包是私有的):
GITLAB_ACCESS_TOKEN
: 您对私有GitLab的访问令牌。GITLAB_HOST
,GITLAB_REPO_PATH
,GITLAB_USERNAME
: 您的仓库信息。
如果您的包是公开的,您可以删除所有这四个变量,并将以下命令从:
git push http://$GITBAB_USERNAME:$GITLAB_API_TOKEN@$GITLAB_HOST/$GITLAB_REPO_PATH.git
改为:
git push origin
发布阶段
最后,我们的发布阶段。在此阶段,我们将此包发布到Pub Dev。它只能在之前tag-version
作业推送的tags
上运行。
您需要上述提到的PUB_DEV
变量。这是因为自动发布时,文件credentials.json
必须存在于当前GitLab Runner服务器上当前存储库的Docker容器中。
这是棘手的部分,该文件将在您首次将包发布到Pub Dev时自动生成,并存储在您的机器中。因此,您需要先手动发布包,但不用担心,之后CI/CD流程将为您处理发布任务。
注意: 曾经有一种方法可以通过flutter pub uploader add some@email.org
在不实际发布的情况下检索PUB_DEV
变量,但这种方法已不再有效。因此,如果您有任何技巧可以检索这些变量,请告知我们。
示例代码
以下是使用vts_test_cicd_plugin
插件的示例代码:
// example/lib/main.dart
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:flutter/services.dart';
import 'package:vts_test_cicd_plugin/vts_test_cicd_plugin.dart'; // 引入插件
void main() {
runApp(const MyApp()); // 启动应用
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
[@override](/user/override)
State<MyApp> createState() => _MyAppState(); // 创建状态管理类
}
class _MyAppState extends State<MyApp> {
String _platformVersion = 'Unknown'; // 初始化平台版本
final _vtsTestCicdPlugin = VtsTestCicdPlugin(); // 初始化插件实例
[@override](/user/override)
void initState() {
super.initState();
initPlatformState(); // 初始化平台状态
}
// 异步初始化平台状态
Future<void> initPlatformState() async {
String platformVersion;
// 使用try/catch捕获可能的异常
try {
platformVersion = await _vtsTestCicdPlugin.getPlatformVersion() ?? 'Unknown platform version';
} on PlatformException {
platformVersion = 'Failed to get platform version.';
}
// 如果组件被移除但仍处于异步状态,则返回
if (!mounted) return;
// 更新UI
setState(() {
_platformVersion = platformVersion;
});
}
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('插件示例应用'), // 设置标题
),
body: Center(
child: Text('运行于: $_platformVersion\n'), // 显示平台版本
),
),
);
}
}