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: workspace:
base: /app base: /app
clone: clone:
git: depth: 50
image: plugins/git
depth: 50
tags: true
pipeline: steps:
build: - name: build
image: jonasfranz/flutter:master image: adamantium/flutter
pull: true pull: true
commands: commands:
- flutter packages get - apt-get update && apt-get install make # We do this here to not have to deal with updating the image itself
- make format-check - flutter packages get
- make build-all - make format-check
- mkdir apks - make build-debug
- mv build/app/outputs/apk/*/*/*.apk apks
when:
event: [ push, tag ]
test: - name: test
image: jonasfranz/flutter:master image: adamantium/flutter
pull: true pull: true
commands: commands:
- make test - apt-get update && apt-get install make # We do this here to not have to deal with updating the image itself
when: - flutter packages get
event: [ push, tag, pull_request ] - make test
# Push the releases to our pseudo-s3-bucket ---
release: 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 image: plugins/s3:1
pull: true pull: true
secrets: [ aws_access_key_id, aws_secret_access_key ] settings:
bucket: vikunja-app bucket: vikunja-app
endpoint: https://storage.kolaente.de access_key:
path_style: true from_secret: aws_access_key_id
strip_prefix: apks/ secret_key:
source: apks/* from_secret: aws_secret_access_key
target: /${DRONE_TAG##v} endpoint: https://storage.kolaente.de
when: path_style: true
event: [ tag ] 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 image: plugins/s3:1
pull: true pull: true
secrets: [ aws_access_key_id, aws_secret_access_key ] settings:
bucket: vikunja-app bucket: vikunja-app
endpoint: https://storage.kolaente.de access_key:
path_style: true from_secret: aws_access_key_id
strip_prefix: apks/ secret_key:
source: apks/* from_secret: aws_secret_access_key
target: /master endpoint: https://storage.kolaente.de
when: path_style: true
event: [ push ] strip_prefix: apks/
branch: [ master ] source: apks/*
target: /${DRONE_TAG##v}

1
.gitignore vendored
View File

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

View File

@ -1,6 +1,6 @@
# Vikunja Cross-Plattform app # 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) [![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/) [![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()), : Center(child: CircularProgressIndicator()),
floatingActionButton: Builder( floatingActionButton: Builder(
builder: (context) => FloatingActionButton( 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) { _addList(String name, BuildContext context) {
VikunjaGlobal.of(context) VikunjaGlobal.of(context)
.listService .listService
.create(widget.namespace.id, TaskList(id: null, title: name, tasks: [])) .create(widget.namespace.id, TaskList(id: null, title: name, tasks: []))
.then((_) { .then((_) {
setState(() {}); setState(() {});
_updateLists(); _updateLists();
Scaffold.of(context).showSnackBar( Scaffold.of(context).showSnackBar(
SnackBar( SnackBar(
content: Text('The list was successfully created!'), content: Text('The list was successfully created!'),
), ),
); );
}); });
} }
} }

View File

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

View File

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

View File

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

View File

@ -24,86 +24,83 @@ class _LoginPageState extends State<LoginPage> {
padding: const EdgeInsets.all(16.0), padding: const EdgeInsets.all(16.0),
child: Builder( child: Builder(
builder: (BuildContext context) => Form( builder: (BuildContext context) => Form(
autovalidate: true, autovalidate: true,
key: _formKey, key: _formKey,
child: Center( child: Center(
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[ children: <Widget>[
Padding( Padding(
padding: EdgeInsets.symmetric(vertical: 30), padding: EdgeInsets.symmetric(vertical: 30),
child: Image( child: Image(
image: AssetImage('assets/vikunja_logo_full.png'), image: AssetImage('assets/vikunja_logo_full.png'),
height: 85.0, height: 85.0,
semanticLabel: 'Vikunja Logo', 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( showDialog(
context: context, context: context,
builder: (context) => new AlertDialog( 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>[ actions: <Widget>[
FlatButton( FlatButton(
onPressed: () => Navigator.pop(context), 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"