Fix the build and update drone (#33)
continuous-integration/drone/push Build is passing Details

This commit is contained in:
konrad 2019-03-15 22:14:37 +00:00 committed by Gitea
parent 67e47b03cd
commit fa05e0e6a3
10 changed files with 544 additions and 257 deletions

View File

@ -1,58 +1,117 @@
kind: pipeline
name: testing
workspace:
base: /app
clone:
git:
image: plugins/git
depth: 50
tags: true
depth: 50
pipeline:
build:
image: jonasfranz/flutter:master
pull: true
commands:
- flutter packages get
- make format-check
- make build-all
- mkdir apks
- mv build/app/outputs/apk/*/*/*.apk apks
when:
event: [ push, tag ]
steps:
- name: build
image: adamantium/flutter
pull: true
commands:
- apt-get update && apt-get install make # We do this here to not have to deal with updating the image itself
- flutter packages get
- make format-check
- make build-debug
test:
image: jonasfranz/flutter:master
pull: true
commands:
- make test
when:
event: [ push, tag, pull_request ]
# Push the releases to our pseudo-s3-bucket
release:
- name: test
image: adamantium/flutter
pull: true
commands:
- apt-get update && apt-get install make # We do this here to not have to deal with updating the image itself
- flutter packages get
- make test
---
kind: pipeline
name: release-latest
depends_on:
- testing
trigger:
branch:
- master
event:
- push
workspace:
base: /app
clone:
depth: 50
steps:
# Because drone separates the pipelines, we have to add the build step to this pipeline. This is double code, we should change it at some point if possible.
- name: build
image: adamantium/flutter
pull: true
commands:
- apt-get update && apt-get install make # We do this here to not have to deal with updating the image itself
- flutter packages get
- make build-all
- mkdir apks
- mv build/app/outputs/apk/*/*/*.apk apks
# Push the releases to our pseudo-s3-bucket
- name: release
image: plugins/s3:1
pull: true
secrets: [ aws_access_key_id, aws_secret_access_key ]
bucket: vikunja-app
endpoint: https://storage.kolaente.de
path_style: true
strip_prefix: apks/
source: apks/*
target: /${DRONE_TAG##v}
when:
event: [ tag ]
settings:
bucket: vikunja-app
access_key:
from_secret: aws_access_key_id
secret_key:
from_secret: aws_secret_access_key
endpoint: https://storage.kolaente.de
path_style: true
strip_prefix: apks/
source: apks/*
target: /master
# Push the releases to our pseudo-s3-bucket
release:
---
kind: pipeline
name: release-version
depends_on:
- testing
trigger:
event:
- tag
workspace:
base: /app
clone:
depth: 50
steps:
# Because drone separates the pipelines, we have to add the build step to this pipeline. This is double code, we should change it at some point if possible.
- name: build
image: adamantium/flutter
pull: true
commands:
- apt-get update && apt-get install make # We do this here to not have to deal with updating the image itself
- flutter packages get
- make build-all
- mkdir apks
- mv build/app/outputs/apk/*/*/*.apk apks
# Push the releases to our pseudo-s3-bucket
- name: release
image: plugins/s3:1
pull: true
secrets: [ aws_access_key_id, aws_secret_access_key ]
bucket: vikunja-app
endpoint: https://storage.kolaente.de
path_style: true
strip_prefix: apks/
source: apks/*
target: /master
when:
event: [ push ]
branch: [ master ]
settings:
bucket: vikunja-app
access_key:
from_secret: aws_access_key_id
secret_key:
from_secret: aws_secret_access_key
endpoint: https://storage.kolaente.de
path_style: true
strip_prefix: apks/
source: apks/*
target: /${DRONE_TAG##v}

1
.gitignore vendored
View File

@ -27,6 +27,7 @@
.pub-cache/
.pub/
build/
!pubspec.lock
# Android related
**/android/**/gradle-wrapper.jar

View File

@ -1,6 +1,6 @@
# Vikunja Cross-Plattform app
[![Build Status](https://drone.kolaente.de/api/badges/vikunja/app/status.svg)](https://drone.kolaente.de/vikunja/app)
[![Build Status](https://drone1.kolaente.de/api/badges/vikunja/app/status.svg)](https://drone1.kolaente.de/vikunja/app)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
[![Download](https://img.shields.io/badge/download-v0.1-brightgreen.svg)](https://storage.kolaente.de/minio/vikunja-app/)

View File

@ -57,8 +57,8 @@ class _NamespaceFragmentState extends State<NamespaceFragment> {
: Center(child: CircularProgressIndicator()),
floatingActionButton: Builder(
builder: (context) => FloatingActionButton(
onPressed: () => _addListDialog(context), child: const Icon(Icons.add))
),
onPressed: () => _addListDialog(context),
child: const Icon(Icons.add))),
);
}
@ -102,16 +102,16 @@ class _NamespaceFragmentState extends State<NamespaceFragment> {
_addList(String name, BuildContext context) {
VikunjaGlobal.of(context)
.listService
.create(widget.namespace.id, TaskList(id: null, title: name, tasks: []))
.then((_) {
setState(() {});
_updateLists();
Scaffold.of(context).showSnackBar(
SnackBar(
content: Text('The list was successfully created!'),
),
);
.listService
.create(widget.namespace.id, TaskList(id: null, title: name, tasks: []))
.then((_) {
setState(() {});
_updateLists();
Scaffold.of(context).showSnackBar(
SnackBar(
content: Text('The list was successfully created!'),
),
);
});
}
}

View File

@ -51,10 +51,10 @@ class HomePageState extends State<HomePage> {
.namespaceService
.create(Namespace(id: null, name: name))
.then((_) {
_updateNamespaces();
Scaffold.of(context).showSnackBar(SnackBar(
content: Text('The namespace was created successfully!'),
));
_updateNamespaces();
Scaffold.of(context).showSnackBar(SnackBar(
content: Text('The namespace was created successfully!'),
));
});
}
@ -120,10 +120,10 @@ class HomePageState extends State<HomePage> {
alignment: FractionalOffset.bottomCenter,
child: Builder(
builder: (context) => ListTile(
leading: const Icon(Icons.add),
title: const Text('Add namespace...'),
onTap: () => _addNamespaceDialog(context),
),
leading: const Icon(Icons.add),
title: const Text('Add namespace...'),
onTap: () => _addNamespaceDialog(context),
),
),
),
])),

View File

@ -26,71 +26,68 @@ class _ListEditPageState extends State<ListEditPage> {
),
body: Builder(
builder: (BuildContext context) => SafeArea(
child: Form(
key: _formKey,
child: ListView(
padding: const EdgeInsets.all(16.0),
children: <Widget>[
Padding(
padding: EdgeInsets.symmetric(vertical: 10.0),
child: TextFormField(
maxLines: null,
keyboardType: TextInputType.multiline,
initialValue: widget.list.title,
onSaved: (title) => _title = title,
validator: (title) {
if (title.length < 3 || title.length > 250) {
return 'The title needs to have between 3 and 250 characters.';
}
return null;
},
decoration:
new InputDecoration(
labelText: 'Title',
border: OutlineInputBorder(),
child: Form(
key: _formKey,
child: ListView(
padding: const EdgeInsets.all(16.0),
children: <Widget>[
Padding(
padding: EdgeInsets.symmetric(vertical: 10.0),
child: TextFormField(
maxLines: null,
keyboardType: TextInputType.multiline,
initialValue: widget.list.title,
onSaved: (title) => _title = title,
validator: (title) {
if (title.length < 3 || title.length > 250) {
return 'The title needs to have between 3 and 250 characters.';
}
return null;
},
decoration: new InputDecoration(
labelText: 'Title',
border: OutlineInputBorder(),
),
),
),
),
),
Padding(
padding: EdgeInsets.symmetric(vertical: 10.0),
child: TextFormField(
maxLines: null,
keyboardType: TextInputType.multiline,
initialValue: widget.list.description,
onSaved: (description) => _description = description,
validator: (description) {
if (description.length > 1000) {
return 'The description can have a maximum of 1000 characters.';
}
return null;
},
decoration: new InputDecoration(
labelText: 'Description',
border: OutlineInputBorder(),
),
),
),
Builder(
builder: (context) => Padding(
padding: EdgeInsets.symmetric(vertical: 10.0),
child: FancyButton(
onPressed: !_loading ? () {
if (_formKey.currentState.validate()) {
Form.of(context).save();
_saveList(context);
}
}
: null,
child: _loading
? CircularProgressIndicator()
: VikunjaButtonText('Save'),
)
)
),
]
Padding(
padding: EdgeInsets.symmetric(vertical: 10.0),
child: TextFormField(
maxLines: null,
keyboardType: TextInputType.multiline,
initialValue: widget.list.description,
onSaved: (description) => _description = description,
validator: (description) {
if (description.length > 1000) {
return 'The description can have a maximum of 1000 characters.';
}
return null;
},
decoration: new InputDecoration(
labelText: 'Description',
border: OutlineInputBorder(),
),
),
),
Builder(
builder: (context) => Padding(
padding: EdgeInsets.symmetric(vertical: 10.0),
child: FancyButton(
onPressed: !_loading
? () {
if (_formKey.currentState.validate()) {
Form.of(context).save();
_saveList(context);
}
}
: null,
child: _loading
? CircularProgressIndicator()
: VikunjaButtonText('Save'),
))),
]),
),
),
),
),
),
);
}
@ -99,25 +96,24 @@ class _ListEditPageState extends State<ListEditPage> {
setState(() => _loading = true);
// FIXME: is there a way we can update the list without creating a new list object?
// aka updating the existing list we got from context (setters?)
TaskList updatedList = TaskList(
id: widget.list.id, title: _title, description: _description);
TaskList updatedList =
TaskList(id: widget.list.id, title: _title, description: _description);
VikunjaGlobal.of(context).listService.update(updatedList)
.then((_) {
setState(() => _loading = false);
Scaffold.of(context).showSnackBar(SnackBar(
content: Text('The list was updated successfully!'),
));
})
.catchError((err) {
setState(() => _loading = false);
Scaffold.of(context).showSnackBar(
SnackBar(
content: Text('Something went wrong: ' + err.toString()),
action: SnackBarAction(
label: 'CLOSE', onPressed: Scaffold.of(context).hideCurrentSnackBar),
),
);
});
VikunjaGlobal.of(context).listService.update(updatedList).then((_) {
setState(() => _loading = false);
Scaffold.of(context).showSnackBar(SnackBar(
content: Text('The list was updated successfully!'),
));
}).catchError((err) {
setState(() => _loading = false);
Scaffold.of(context).showSnackBar(
SnackBar(
content: Text('Something went wrong: ' + err.toString()),
action: SnackBarAction(
label: 'CLOSE',
onPressed: Scaffold.of(context).hideCurrentSnackBar),
),
);
});
}
}

View File

@ -38,34 +38,34 @@ class _ListPageState extends State<ListPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: new Text(_list.title),
actions: <Widget>[
IconButton(
icon: Icon(Icons.edit),
onPressed: () => Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ListEditPage(
list: _list,
))))
],
),
body: !this._loading
? RefreshIndicator(
child: ListView(
padding: EdgeInsets.symmetric(vertical: 8.0),
children:
ListTile.divideTiles(context: context, tiles: _listTasks())
.toList(),
),
onRefresh: _loadList,
)
: Center(child: CircularProgressIndicator()),
floatingActionButton: Builder(
builder: (context) => FloatingActionButton(
onPressed: () => _addItemDialog(context), child: Icon(Icons.add)),
));
appBar: AppBar(
title: new Text(_list.title),
actions: <Widget>[
IconButton(
icon: Icon(Icons.edit),
onPressed: () => Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ListEditPage(
list: _list,
))))
],
),
body: !this._loading
? RefreshIndicator(
child: ListView(
padding: EdgeInsets.symmetric(vertical: 8.0),
children: ListTile.divideTiles(
context: context, tiles: _listTasks())
.toList(),
),
onRefresh: _loadList,
)
: Center(child: CircularProgressIndicator()),
floatingActionButton: Builder(
builder: (context) => FloatingActionButton(
onPressed: () => _addItemDialog(context), child: Icon(Icons.add)),
));
}
List<Widget> _listTasks() {

View File

@ -24,86 +24,83 @@ class _LoginPageState extends State<LoginPage> {
padding: const EdgeInsets.all(16.0),
child: Builder(
builder: (BuildContext context) => Form(
autovalidate: true,
key: _formKey,
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Padding(
padding: EdgeInsets.symmetric(vertical: 30),
child: Image(
image: AssetImage('assets/vikunja_logo_full.png'),
height: 85.0,
semanticLabel: 'Vikunja Logo',
),
autovalidate: true,
key: _formKey,
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Padding(
padding: EdgeInsets.symmetric(vertical: 30),
child: Image(
image: AssetImage('assets/vikunja_logo_full.png'),
height: 85.0,
semanticLabel: 'Vikunja Logo',
),
),
Padding(
padding: vStandardVerticalPadding,
child: TextFormField(
enabled: !_loading,
onSaved: (serverAddress) => _server = serverAddress,
validator: (address) {
return isUrl(address) ? null : 'Invalid URL';
},
decoration: new InputDecoration(
border: OutlineInputBorder(),
labelText: 'Server Address'),
),
),
Padding(
padding: vStandardVerticalPadding,
child: TextFormField(
enabled: !_loading,
onSaved: (username) => _username = username,
decoration: new InputDecoration(
border: OutlineInputBorder(),
labelText: 'Username'),
),
),
Padding(
padding: vStandardVerticalPadding,
child: TextFormField(
enabled: !_loading,
onSaved: (password) => _password = password,
decoration: new InputDecoration(
border: OutlineInputBorder(),
labelText: 'Password'),
obscureText: true,
),
),
Builder(
builder: (context) => FancyButton(
onPressed: !_loading
? () {
if (_formKey.currentState
.validate()) {
Form.of(context).save();
_loginUser(context);
}
}
: null,
child: _loading
? CircularProgressIndicator()
: VikunjaButtonText('Login'),
)),
Builder(
builder: (context) => FancyButton(
onPressed: () => Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
RegisterPage())),
child: VikunjaButtonText('Register'),
)),
],
),
Padding(
padding: vStandardVerticalPadding,
child: TextFormField(
enabled: !_loading,
onSaved: (serverAddress) =>
_server = serverAddress,
validator: (address) {
return isUrl(address)
? null
: 'Invalid URL';
},
decoration: new InputDecoration(
border: OutlineInputBorder(),
labelText: 'Server Address'),
),
),
Padding(
padding: vStandardVerticalPadding,
child: TextFormField(
enabled: !_loading,
onSaved: (username) => _username = username,
decoration: new InputDecoration(
border: OutlineInputBorder(),
labelText: 'Username'),
),
),
Padding(
padding: vStandardVerticalPadding,
child: TextFormField(
enabled: !_loading,
onSaved: (password) => _password = password,
decoration: new InputDecoration(
border: OutlineInputBorder(),
labelText: 'Password'),
obscureText: true,
),
),
Builder(
builder: (context) => FancyButton(
onPressed: !_loading
? () {
if (_formKey.currentState
.validate()) {
Form.of(context).save();
_loginUser(context);
}
}
: null,
child: _loading
? CircularProgressIndicator()
: VikunjaButtonText('Login'),
)),
Builder(
builder: (context) => FancyButton(
onPressed: () => Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
RegisterPage())),
child: VikunjaButtonText('Register'),
)),
],
),
),
),
),
),
),
),

View File

@ -137,7 +137,9 @@ class _RegisterPageState extends State<RegisterPage> {
showDialog(
context: context,
builder: (context) => new AlertDialog(
title: Text('Registration failed! Please check your server url and credentials. ' + ex.toString()),
title: Text(
'Registration failed! Please check your server url and credentials. ' +
ex.toString()),
actions: <Widget>[
FlatButton(
onPressed: () => Navigator.pop(context),

232
pubspec.lock Normal file
View File

@ -0,0 +1,232 @@
# Generated by pub
# See https://www.dartlang.org/tools/pub/glossary#lockfile
packages:
archive:
dependency: transitive
description:
name: archive
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.8"
args:
dependency: transitive
description:
name: args
url: "https://pub.dartlang.org"
source: hosted
version: "1.5.1"
async:
dependency: transitive
description:
name: async
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.8"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.4"
charcode:
dependency: transitive
description:
name: charcode
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.2"
collection:
dependency: transitive
description:
name: collection
url: "https://pub.dartlang.org"
source: hosted
version: "1.14.11"
convert:
dependency: transitive
description:
name: convert
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.1"
crypto:
dependency: transitive
description:
name: crypto
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.6"
cupertino_icons:
dependency: "direct main"
description:
name: cupertino_icons
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.2"
dart_config:
dependency: transitive
description:
path: "."
ref: HEAD
resolved-ref: a7ed88a4793e094a4d5d5c2d88a89e55510accde
url: "https://github.com/MarkOSullivan94/dart_config.git"
source: git
version: "0.5.0"
flutter:
dependency: "direct main"
description: flutter
source: sdk
version: "0.0.0"
flutter_launcher_icons:
dependency: "direct dev"
description:
name: flutter_launcher_icons
url: "https://pub.dartlang.org"
source: hosted
version: "0.6.1"
flutter_secure_storage:
dependency: "direct main"
description:
name: flutter_secure_storage
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.1"
flutter_test:
dependency: "direct dev"
description: flutter
source: sdk
version: "0.0.0"
http:
dependency: "direct main"
description:
name: http
url: "https://pub.dartlang.org"
source: hosted
version: "0.12.0"
http_parser:
dependency: transitive
description:
name: http_parser
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.3"
image:
dependency: transitive
description:
name: image
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.7"
matcher:
dependency: transitive
description:
name: matcher
url: "https://pub.dartlang.org"
source: hosted
version: "0.12.3+1"
meta:
dependency: transitive
description:
name: meta
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.6"
path:
dependency: transitive
description:
name: path
url: "https://pub.dartlang.org"
source: hosted
version: "1.6.2"
petitparser:
dependency: transitive
description:
name: petitparser
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.1"
quiver:
dependency: transitive
description:
name: quiver
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.1"
sky_engine:
dependency: transitive
description: flutter
source: sdk
version: "0.0.99"
source_span:
dependency: transitive
description:
name: source_span
url: "https://pub.dartlang.org"
source: hosted
version: "1.4.1"
stack_trace:
dependency: transitive
description:
name: stack_trace
url: "https://pub.dartlang.org"
source: hosted
version: "1.9.3"
stream_channel:
dependency: transitive
description:
name: stream_channel
url: "https://pub.dartlang.org"
source: hosted
version: "1.6.8"
string_scanner:
dependency: transitive
description:
name: string_scanner
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.4"
term_glyph:
dependency: transitive
description:
name: term_glyph
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.1"
test_api:
dependency: transitive
description:
name: test_api
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.1"
typed_data:
dependency: transitive
description:
name: typed_data
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.6"
vector_math:
dependency: transitive
description:
name: vector_math
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.8"
xml:
dependency: transitive
description:
name: xml
url: "https://pub.dartlang.org"
source: hosted
version: "3.3.1"
yaml:
dependency: transitive
description:
name: yaml
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.15"
sdks:
dart: ">=2.0.0 <3.0.0"